ntdll: Get the unix tid on DragonFly BSD.
[wine/multimedia.git] / dlls / windowscodecs / regsvr.c
blobb3c1f1ba19380dc7425594ad0ced077301d11eef
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define NONAMELESSUNION
20 #define NONAMELESSSTRUCT
21 #define COBJMACROS
22 #include <stdarg.h>
23 #include <string.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "winerror.h"
32 #include "objbase.h"
33 #include "ocidl.h"
34 #include "wincodec.h"
36 #include "wine/debug.h"
37 #include "wine/unicode.h"
39 #include "wincodecs_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
43 /***********************************************************************
44 * interface for self-registering
46 struct decoder_pattern
48 DWORD length; /* 0 for end of list */
49 DWORD position;
50 const BYTE *pattern;
51 const BYTE *mask;
52 DWORD endofstream;
55 struct regsvr_decoder
57 CLSID const *clsid; /* NULL for end of list */
58 LPCSTR author;
59 LPCSTR friendlyname;
60 LPCSTR version;
61 GUID const *vendor;
62 GUID const *container_format;
63 LPCSTR mimetypes;
64 LPCSTR extensions;
65 GUID const * const *formats;
66 const struct decoder_pattern *patterns;
69 static HRESULT register_decoders(struct regsvr_decoder const *list);
70 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
72 struct regsvr_encoder
74 CLSID const *clsid; /* NULL for end of list */
75 LPCSTR author;
76 LPCSTR friendlyname;
77 LPCSTR version;
78 GUID const *vendor;
79 GUID const *container_format;
80 LPCSTR mimetypes;
81 LPCSTR extensions;
82 GUID const * const *formats;
85 static HRESULT register_encoders(struct regsvr_encoder const *list);
86 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
88 struct regsvr_converter
90 CLSID const *clsid; /* NULL for end of list */
91 LPCSTR author;
92 LPCSTR friendlyname;
93 LPCSTR version;
94 GUID const *vendor;
95 GUID const * const *formats;
98 static HRESULT register_converters(struct regsvr_converter const *list);
99 static HRESULT unregister_converters(struct regsvr_converter const *list);
101 /***********************************************************************
102 * static string constants
104 static const WCHAR clsid_keyname[] = {
105 'C', 'L', 'S', 'I', 'D', 0 };
106 static const WCHAR curver_keyname[] = {
107 'C', 'u', 'r', 'V', 'e', 'r', 0 };
108 static const WCHAR ips_keyname[] = {
109 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
110 0 };
111 static const WCHAR ips32_keyname[] = {
112 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
113 '3', '2', 0 };
114 static const WCHAR progid_keyname[] = {
115 'P', 'r', 'o', 'g', 'I', 'D', 0 };
116 static const WCHAR viprogid_keyname[] = {
117 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
118 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
119 0 };
120 static const char tmodel_valuename[] = "ThreadingModel";
121 static const char author_valuename[] = "Author";
122 static const char friendlyname_valuename[] = "FriendlyName";
123 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
124 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
125 static const char version_valuename[] = "Version";
126 static const char mimetypes_valuename[] = "MimeTypes";
127 static const char extensions_valuename[] = "FileExtensions";
128 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
129 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
130 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
131 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0};
132 static const char length_valuename[] = "Length";
133 static const char position_valuename[] = "Position";
134 static const char pattern_valuename[] = "Pattern";
135 static const char mask_valuename[] = "Mask";
136 static const char endofstream_valuename[] = "EndOfStream";
137 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
139 /***********************************************************************
140 * register_decoders
142 static HRESULT register_decoders(struct regsvr_decoder const *list)
144 LONG res = ERROR_SUCCESS;
145 HKEY coclass_key;
146 WCHAR buf[39];
147 HKEY decoders_key;
148 HKEY instance_key;
150 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
151 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
152 if (res == ERROR_SUCCESS) {
153 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
154 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
155 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
156 if (res == ERROR_SUCCESS)
158 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
159 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
160 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
162 if (res != ERROR_SUCCESS)
163 RegCloseKey(coclass_key);
165 if (res != ERROR_SUCCESS) goto error_return;
167 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
168 HKEY clsid_key;
169 HKEY instance_clsid_key;
171 StringFromGUID2(list->clsid, buf, 39);
172 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
173 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
174 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
176 StringFromGUID2(list->clsid, buf, 39);
177 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
178 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
179 if (res == ERROR_SUCCESS) {
180 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
181 (CONST BYTE*)(buf), 78);
182 RegCloseKey(instance_clsid_key);
184 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
186 if (list->author) {
187 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
188 (CONST BYTE*)(list->author),
189 strlen(list->author) + 1);
190 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
193 if (list->friendlyname) {
194 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
195 (CONST BYTE*)(list->friendlyname),
196 strlen(list->friendlyname) + 1);
197 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
200 if (list->vendor) {
201 StringFromGUID2(list->vendor, buf, 39);
202 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
203 (CONST BYTE*)(buf), 78);
204 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
207 if (list->container_format) {
208 StringFromGUID2(list->container_format, buf, 39);
209 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
210 (CONST BYTE*)(buf), 78);
211 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
214 if (list->version) {
215 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
216 (CONST BYTE*)(list->version),
217 strlen(list->version) + 1);
218 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
221 if (list->mimetypes) {
222 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
223 (CONST BYTE*)(list->mimetypes),
224 strlen(list->mimetypes) + 1);
225 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
228 if (list->extensions) {
229 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
230 (CONST BYTE*)(list->extensions),
231 strlen(list->extensions) + 1);
232 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
235 if (list->formats) {
236 HKEY formats_key;
237 GUID const * const *format;
239 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
240 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
241 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
242 for (format=list->formats; *format; ++format)
244 HKEY format_key;
245 StringFromGUID2(*format, buf, 39);
246 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
247 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
248 if (res != ERROR_SUCCESS) break;
249 RegCloseKey(format_key);
251 RegCloseKey(formats_key);
252 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
255 if (list->patterns) {
256 HKEY patterns_key;
257 int i;
259 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
260 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
261 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
262 for (i=0; list->patterns[i].length; i++)
264 HKEY pattern_key;
265 static const WCHAR int_format[] = {'%','i',0};
266 snprintfW(buf, 39, int_format, i);
267 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
268 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
269 if (res != ERROR_SUCCESS) break;
270 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
271 (CONST BYTE*)(&list->patterns[i].length), 4);
272 if (res == ERROR_SUCCESS)
273 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
274 (CONST BYTE*)(&list->patterns[i].position), 4);
275 if (res == ERROR_SUCCESS)
276 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
277 list->patterns[i].pattern,
278 list->patterns[i].length);
279 if (res == ERROR_SUCCESS)
280 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
281 list->patterns[i].mask,
282 list->patterns[i].length);
283 if (res == ERROR_SUCCESS)
284 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
285 (CONST BYTE*)&(list->patterns[i].endofstream), 4);
286 RegCloseKey(pattern_key);
288 RegCloseKey(patterns_key);
289 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
292 error_close_clsid_key:
293 RegCloseKey(clsid_key);
296 error_close_coclass_key:
297 RegCloseKey(instance_key);
298 RegCloseKey(decoders_key);
299 RegCloseKey(coclass_key);
300 error_return:
301 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
304 /***********************************************************************
305 * unregister_decoders
307 static HRESULT unregister_decoders(struct regsvr_decoder const *list)
309 LONG res = ERROR_SUCCESS;
310 HKEY coclass_key;
311 WCHAR buf[39];
312 HKEY decoders_key;
313 HKEY instance_key;
315 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
316 KEY_READ | KEY_WRITE, &coclass_key);
317 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
319 if (res == ERROR_SUCCESS) {
320 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
321 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
322 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
323 if (res == ERROR_SUCCESS)
325 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
326 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
327 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
329 if (res != ERROR_SUCCESS)
330 RegCloseKey(coclass_key);
332 if (res != ERROR_SUCCESS) goto error_return;
334 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
335 StringFromGUID2(list->clsid, buf, 39);
337 res = RegDeleteTreeW(coclass_key, buf);
338 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
339 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
341 res = RegDeleteTreeW(instance_key, buf);
342 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
343 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
346 error_close_coclass_key:
347 RegCloseKey(instance_key);
348 RegCloseKey(decoders_key);
349 RegCloseKey(coclass_key);
350 error_return:
351 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
354 /***********************************************************************
355 * register_encoders
357 static HRESULT register_encoders(struct regsvr_encoder const *list)
359 LONG res = ERROR_SUCCESS;
360 HKEY coclass_key;
361 WCHAR buf[39];
362 HKEY encoders_key;
363 HKEY instance_key;
365 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
366 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
367 if (res == ERROR_SUCCESS) {
368 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
369 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
370 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
371 if (res == ERROR_SUCCESS)
373 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
374 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
375 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
377 if (res != ERROR_SUCCESS)
378 RegCloseKey(coclass_key);
380 if (res != ERROR_SUCCESS) goto error_return;
382 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
383 HKEY clsid_key;
384 HKEY instance_clsid_key;
386 StringFromGUID2(list->clsid, buf, 39);
387 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
388 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
389 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
391 StringFromGUID2(list->clsid, buf, 39);
392 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
393 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
394 if (res == ERROR_SUCCESS) {
395 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
396 (CONST BYTE*)(buf), 78);
397 RegCloseKey(instance_clsid_key);
399 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
401 if (list->author) {
402 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
403 (CONST BYTE*)(list->author),
404 strlen(list->author) + 1);
405 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
408 if (list->friendlyname) {
409 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
410 (CONST BYTE*)(list->friendlyname),
411 strlen(list->friendlyname) + 1);
412 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
415 if (list->vendor) {
416 StringFromGUID2(list->vendor, buf, 39);
417 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
418 (CONST BYTE*)(buf), 78);
419 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
422 if (list->container_format) {
423 StringFromGUID2(list->container_format, buf, 39);
424 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
425 (CONST BYTE*)(buf), 78);
426 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
429 if (list->version) {
430 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
431 (CONST BYTE*)(list->version),
432 strlen(list->version) + 1);
433 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
436 if (list->mimetypes) {
437 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
438 (CONST BYTE*)(list->mimetypes),
439 strlen(list->mimetypes) + 1);
440 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
443 if (list->extensions) {
444 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
445 (CONST BYTE*)(list->extensions),
446 strlen(list->extensions) + 1);
447 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
450 if (list->formats) {
451 HKEY formats_key;
452 GUID const * const *format;
454 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
455 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
456 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
457 for (format=list->formats; *format; ++format)
459 HKEY format_key;
460 StringFromGUID2(*format, buf, 39);
461 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
462 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
463 if (res != ERROR_SUCCESS) break;
464 RegCloseKey(format_key);
466 RegCloseKey(formats_key);
467 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
470 error_close_clsid_key:
471 RegCloseKey(clsid_key);
474 error_close_coclass_key:
475 RegCloseKey(instance_key);
476 RegCloseKey(encoders_key);
477 RegCloseKey(coclass_key);
478 error_return:
479 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
482 /***********************************************************************
483 * unregister_encoders
485 static HRESULT unregister_encoders(struct regsvr_encoder const *list)
487 LONG res = ERROR_SUCCESS;
488 HKEY coclass_key;
489 WCHAR buf[39];
490 HKEY encoders_key;
491 HKEY instance_key;
493 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
494 KEY_READ | KEY_WRITE, &coclass_key);
495 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
497 if (res == ERROR_SUCCESS) {
498 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
499 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
500 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
501 if (res == ERROR_SUCCESS)
503 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
504 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
505 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
507 if (res != ERROR_SUCCESS)
508 RegCloseKey(coclass_key);
510 if (res != ERROR_SUCCESS) goto error_return;
512 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
513 StringFromGUID2(list->clsid, buf, 39);
515 res = RegDeleteTreeW(coclass_key, buf);
516 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
517 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
519 res = RegDeleteTreeW(instance_key, buf);
520 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
521 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
524 error_close_coclass_key:
525 RegCloseKey(instance_key);
526 RegCloseKey(encoders_key);
527 RegCloseKey(coclass_key);
528 error_return:
529 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
532 /***********************************************************************
533 * register_converters
535 static HRESULT register_converters(struct regsvr_converter const *list)
537 LONG res = ERROR_SUCCESS;
538 HKEY coclass_key;
539 WCHAR buf[39];
540 HKEY converters_key;
541 HKEY instance_key;
543 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
544 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
545 if (res == ERROR_SUCCESS) {
546 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
547 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
548 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
549 if (res == ERROR_SUCCESS)
551 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
552 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
553 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
555 if (res != ERROR_SUCCESS)
556 RegCloseKey(coclass_key);
558 if (res != ERROR_SUCCESS) goto error_return;
560 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
561 HKEY clsid_key;
562 HKEY instance_clsid_key;
564 StringFromGUID2(list->clsid, buf, 39);
565 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
566 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
567 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
569 StringFromGUID2(list->clsid, buf, 39);
570 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
571 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
572 if (res == ERROR_SUCCESS) {
573 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
574 (CONST BYTE*)(buf), 78);
575 RegCloseKey(instance_clsid_key);
577 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
579 if (list->author) {
580 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
581 (CONST BYTE*)(list->author),
582 strlen(list->author) + 1);
583 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
586 if (list->friendlyname) {
587 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
588 (CONST BYTE*)(list->friendlyname),
589 strlen(list->friendlyname) + 1);
590 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
593 if (list->vendor) {
594 StringFromGUID2(list->vendor, buf, 39);
595 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
596 (CONST BYTE*)(buf), 78);
597 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
600 if (list->version) {
601 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
602 (CONST BYTE*)(list->version),
603 strlen(list->version) + 1);
604 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
607 if (list->formats) {
608 HKEY formats_key;
609 GUID const * const *format;
611 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
612 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
613 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
614 for (format=list->formats; *format; ++format)
616 HKEY format_key;
617 StringFromGUID2(*format, buf, 39);
618 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
619 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
620 if (res != ERROR_SUCCESS) break;
621 RegCloseKey(format_key);
623 RegCloseKey(formats_key);
624 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
627 error_close_clsid_key:
628 RegCloseKey(clsid_key);
631 error_close_coclass_key:
632 RegCloseKey(instance_key);
633 RegCloseKey(converters_key);
634 RegCloseKey(coclass_key);
635 error_return:
636 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
639 /***********************************************************************
640 * unregister_converters
642 static HRESULT unregister_converters(struct regsvr_converter const *list)
644 LONG res = ERROR_SUCCESS;
645 HKEY coclass_key;
646 WCHAR buf[39];
647 HKEY converters_key;
648 HKEY instance_key;
650 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
651 KEY_READ | KEY_WRITE, &coclass_key);
652 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
654 if (res == ERROR_SUCCESS) {
655 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
656 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
657 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
658 if (res == ERROR_SUCCESS)
660 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
661 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
662 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
664 if (res != ERROR_SUCCESS)
665 RegCloseKey(coclass_key);
667 if (res != ERROR_SUCCESS) goto error_return;
669 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
670 StringFromGUID2(list->clsid, buf, 39);
672 res = RegDeleteTreeW(coclass_key, buf);
673 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
674 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
676 res = RegDeleteTreeW(instance_key, buf);
677 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
678 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
681 error_close_coclass_key:
682 RegCloseKey(instance_key);
683 RegCloseKey(converters_key);
684 RegCloseKey(coclass_key);
685 error_return:
686 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
689 /***********************************************************************
690 * decoder list
692 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
694 static const BYTE bmp_magic[] = {0x42,0x4d};
696 static GUID const * const bmp_formats[] = {
697 &GUID_WICPixelFormat1bppIndexed,
698 &GUID_WICPixelFormat2bppIndexed,
699 &GUID_WICPixelFormat4bppIndexed,
700 &GUID_WICPixelFormat8bppIndexed,
701 &GUID_WICPixelFormat16bppBGR555,
702 &GUID_WICPixelFormat16bppBGR565,
703 &GUID_WICPixelFormat24bppBGR,
704 &GUID_WICPixelFormat32bppBGR,
705 &GUID_WICPixelFormat32bppBGRA,
706 NULL
709 static struct decoder_pattern const bmp_patterns[] = {
710 {2,0,bmp_magic,mask_all,0},
714 static const BYTE gif87a_magic[6] = "GIF87a";
715 static const BYTE gif89a_magic[6] = "GIF89a";
717 static GUID const * const gif_formats[] = {
718 &GUID_WICPixelFormat8bppIndexed,
719 NULL
722 static struct decoder_pattern const gif_patterns[] = {
723 {6,0,gif87a_magic,mask_all,0},
724 {6,0,gif89a_magic,mask_all,0},
728 static const BYTE ico_magic[] = {00,00,01,00};
730 static GUID const * const ico_formats[] = {
731 &GUID_WICPixelFormat32bppBGRA,
732 NULL
735 static struct decoder_pattern const ico_patterns[] = {
736 {4,0,ico_magic,mask_all,0},
740 static const BYTE jpeg_magic[] = {0xff, 0xd8};
742 static GUID const * const jpeg_formats[] = {
743 &GUID_WICPixelFormat24bppBGR,
744 &GUID_WICPixelFormat32bppCMYK,
745 &GUID_WICPixelFormat8bppGray,
746 NULL
749 static struct decoder_pattern const jpeg_patterns[] = {
750 {2,0,jpeg_magic,mask_all,0},
754 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
756 static GUID const * const png_formats[] = {
757 &GUID_WICPixelFormatBlackWhite,
758 &GUID_WICPixelFormat2bppGray,
759 &GUID_WICPixelFormat4bppGray,
760 &GUID_WICPixelFormat8bppGray,
761 &GUID_WICPixelFormat16bppGray,
762 &GUID_WICPixelFormat32bppBGRA,
763 &GUID_WICPixelFormat64bppRGBA,
764 &GUID_WICPixelFormat1bppIndexed,
765 &GUID_WICPixelFormat2bppIndexed,
766 &GUID_WICPixelFormat4bppIndexed,
767 &GUID_WICPixelFormat8bppIndexed,
768 &GUID_WICPixelFormat24bppBGR,
769 &GUID_WICPixelFormat48bppRGB,
770 NULL
773 static struct decoder_pattern const png_patterns[] = {
774 {8,0,png_magic,mask_all,0},
778 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
779 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
781 static GUID const * const tiff_decode_formats[] = {
782 &GUID_WICPixelFormatBlackWhite,
783 &GUID_WICPixelFormat4bppGray,
784 &GUID_WICPixelFormat8bppGray,
785 &GUID_WICPixelFormat4bppIndexed,
786 &GUID_WICPixelFormat8bppIndexed,
787 &GUID_WICPixelFormat24bppBGR,
788 &GUID_WICPixelFormat32bppBGR,
789 &GUID_WICPixelFormat32bppBGRA,
790 &GUID_WICPixelFormat32bppPBGRA,
791 &GUID_WICPixelFormat48bppRGB,
792 &GUID_WICPixelFormat64bppRGBA,
793 &GUID_WICPixelFormat64bppPRGBA,
794 NULL
797 static struct decoder_pattern const tiff_patterns[] = {
798 {4,0,tiff_magic_le,mask_all,0},
799 {4,0,tiff_magic_be,mask_all,0},
803 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
805 static const BYTE tga_indexed_magic[18] = {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
806 static const BYTE tga_indexed_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
808 static const BYTE tga_truecolor_magic[18] = {0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
809 static const BYTE tga_truecolor_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0x87,0xc0};
811 static const BYTE tga_grayscale_magic[18] = {0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
812 static const BYTE tga_grayscale_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
814 static GUID const * const tga_formats[] = {
815 &GUID_WICPixelFormat8bppGray,
816 &GUID_WICPixelFormat8bppIndexed,
817 &GUID_WICPixelFormat16bppGray,
818 &GUID_WICPixelFormat16bppBGR555,
819 &GUID_WICPixelFormat24bppBGR,
820 &GUID_WICPixelFormat32bppBGRA,
821 &GUID_WICPixelFormat32bppPBGRA,
822 NULL
825 static struct decoder_pattern const tga_patterns[] = {
826 {18,18,tga_footer_magic,mask_all,1},
827 {18,0,tga_indexed_magic,tga_indexed_mask,0},
828 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
829 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
833 static struct regsvr_decoder const decoder_list[] = {
834 { &CLSID_WICBmpDecoder,
835 "The Wine Project",
836 "BMP Decoder",
837 "1.0.0.0",
838 &GUID_VendorMicrosoft,
839 &GUID_ContainerFormatBmp,
840 "image/bmp",
841 ".bmp,.dib,.rle",
842 bmp_formats,
843 bmp_patterns
845 { &CLSID_WICGifDecoder,
846 "The Wine Project",
847 "GIF Decoder",
848 "1.0.0.0",
849 &GUID_VendorMicrosoft,
850 &GUID_ContainerFormatGif,
851 "image/gif",
852 ".gif",
853 gif_formats,
854 gif_patterns
856 { &CLSID_WICIcoDecoder,
857 "The Wine Project",
858 "ICO Decoder",
859 "1.0.0.0",
860 &GUID_VendorMicrosoft,
861 &GUID_ContainerFormatIco,
862 "image/vnd.microsoft.icon",
863 ".ico",
864 ico_formats,
865 ico_patterns
867 { &CLSID_WICJpegDecoder,
868 "The Wine Project",
869 "JPEG Decoder",
870 "1.0.0.0",
871 &GUID_VendorMicrosoft,
872 &GUID_ContainerFormatJpeg,
873 "image/jpeg",
874 ".jpg;.jpeg;.jfif",
875 jpeg_formats,
876 jpeg_patterns
878 { &CLSID_WICPngDecoder,
879 "The Wine Project",
880 "PNG Decoder",
881 "1.0.0.0",
882 &GUID_VendorMicrosoft,
883 &GUID_ContainerFormatPng,
884 "image/png",
885 ".png",
886 png_formats,
887 png_patterns
889 { &CLSID_WICTiffDecoder,
890 "The Wine Project",
891 "TIFF Decoder",
892 "1.0.0.0",
893 &GUID_VendorMicrosoft,
894 &GUID_ContainerFormatTiff,
895 "image/tiff",
896 ".tif;.tiff",
897 tiff_decode_formats,
898 tiff_patterns
900 { &CLSID_WineTgaDecoder,
901 "The Wine Project",
902 "TGA Decoder",
903 "1.0.0.0",
904 &GUID_VendorWine,
905 &GUID_WineContainerFormatTga,
906 "image/x-targa",
907 ".tga;.tpic",
908 tga_formats,
909 tga_patterns
911 { NULL } /* list terminator */
914 static GUID const * const bmp_encode_formats[] = {
915 &GUID_WICPixelFormat16bppBGR555,
916 &GUID_WICPixelFormat16bppBGR565,
917 &GUID_WICPixelFormat24bppBGR,
918 &GUID_WICPixelFormat32bppBGR,
919 NULL
922 static GUID const * const png_encode_formats[] = {
923 &GUID_WICPixelFormat24bppBGR,
924 &GUID_WICPixelFormatBlackWhite,
925 &GUID_WICPixelFormat2bppGray,
926 &GUID_WICPixelFormat4bppGray,
927 &GUID_WICPixelFormat8bppGray,
928 &GUID_WICPixelFormat16bppGray,
929 &GUID_WICPixelFormat32bppBGR,
930 &GUID_WICPixelFormat32bppBGRA,
931 &GUID_WICPixelFormat48bppRGB,
932 &GUID_WICPixelFormat64bppRGBA,
933 NULL
936 static GUID const * const tiff_encode_formats[] = {
937 &GUID_WICPixelFormatBlackWhite,
938 &GUID_WICPixelFormat4bppGray,
939 &GUID_WICPixelFormat8bppGray,
940 &GUID_WICPixelFormat24bppBGR,
941 &GUID_WICPixelFormat32bppBGRA,
942 &GUID_WICPixelFormat32bppPBGRA,
943 &GUID_WICPixelFormat48bppRGB,
944 &GUID_WICPixelFormat64bppRGBA,
945 &GUID_WICPixelFormat64bppPRGBA,
946 NULL
949 static GUID const * const icns_encode_formats[] = {
950 &GUID_WICPixelFormat32bppBGRA,
951 NULL
954 static struct regsvr_encoder const encoder_list[] = {
955 { &CLSID_WICBmpEncoder,
956 "The Wine Project",
957 "BMP Encoder",
958 "1.0.0.0",
959 &GUID_VendorMicrosoft,
960 &GUID_ContainerFormatBmp,
961 "image/bmp",
962 ".bmp,.dib,.rle",
963 bmp_encode_formats
965 { &CLSID_WICJpegEncoder,
966 "The Wine Project",
967 "JPEG Encoder",
968 "1.0.0.0",
969 &GUID_VendorMicrosoft,
970 &GUID_ContainerFormatJpeg,
971 "image/jpeg",
972 ".jpg;.jpeg;.jfif",
973 jpeg_formats
975 { &CLSID_WICPngEncoder,
976 "The Wine Project",
977 "PNG Encoder",
978 "1.0.0.0",
979 &GUID_VendorMicrosoft,
980 &GUID_ContainerFormatPng,
981 "image/png",
982 ".png",
983 png_encode_formats
985 { &CLSID_WICTiffEncoder,
986 "The Wine Project",
987 "TIFF Encoder",
988 "1.0.0.0",
989 &GUID_VendorMicrosoft,
990 &GUID_ContainerFormatTiff,
991 "image/tiff",
992 ".tif;.tiff",
993 tiff_encode_formats
995 { &CLSID_WICIcnsEncoder,
996 "The Wine Project",
997 "ICNS Encoder",
998 "1.0.0.0",
999 &GUID_VendorWine,
1000 NULL, /* no container format guid */
1001 "image/icns",
1002 ".icns",
1003 icns_encode_formats
1005 { NULL } /* list terminator */
1008 static GUID const * const converter_formats[] = {
1009 &GUID_WICPixelFormat1bppIndexed,
1010 &GUID_WICPixelFormat2bppIndexed,
1011 &GUID_WICPixelFormat4bppIndexed,
1012 &GUID_WICPixelFormat8bppIndexed,
1013 &GUID_WICPixelFormatBlackWhite,
1014 &GUID_WICPixelFormat2bppGray,
1015 &GUID_WICPixelFormat4bppGray,
1016 &GUID_WICPixelFormat8bppGray,
1017 &GUID_WICPixelFormat16bppGray,
1018 &GUID_WICPixelFormat16bppBGR555,
1019 &GUID_WICPixelFormat16bppBGR565,
1020 &GUID_WICPixelFormat16bppBGRA5551,
1021 &GUID_WICPixelFormat24bppBGR,
1022 &GUID_WICPixelFormat32bppBGR,
1023 &GUID_WICPixelFormat32bppBGRA,
1024 &GUID_WICPixelFormat32bppPBGRA,
1025 &GUID_WICPixelFormat48bppRGB,
1026 &GUID_WICPixelFormat64bppRGBA,
1027 &GUID_WICPixelFormat32bppCMYK,
1028 NULL
1031 static struct regsvr_converter const converter_list[] = {
1032 { &CLSID_WICDefaultFormatConverter,
1033 "The Wine Project",
1034 "Default Pixel Format Converter",
1035 "1.0.0.0",
1036 &GUID_VendorMicrosoft,
1037 converter_formats
1039 { NULL } /* list terminator */
1042 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
1043 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
1045 HRESULT WINAPI DllRegisterServer(void)
1047 HRESULT hr;
1049 TRACE("\n");
1051 hr = WIC_DllRegisterServer();
1052 if (SUCCEEDED(hr))
1053 register_decoders(decoder_list);
1054 if (SUCCEEDED(hr))
1055 register_encoders(encoder_list);
1056 if (SUCCEEDED(hr))
1057 register_converters(converter_list);
1058 return hr;
1061 HRESULT WINAPI DllUnregisterServer(void)
1063 HRESULT hr;
1065 TRACE("\n");
1067 hr = WIC_DllUnregisterServer();
1068 if (SUCCEEDED(hr))
1069 unregister_decoders(decoder_list);
1070 if (SUCCEEDED(hr))
1071 unregister_encoders(encoder_list);
1072 if (SUCCEEDED(hr))
1073 unregister_converters(converter_list);
1074 return hr;