Synchronize with trunk r58457.
[reactos.git] / dll / win32 / windowscodecs / regsvr.c
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #define WIN32_NO_STATUS
20 #define _INC_WINDOWS
21 #define COM_NO_WINDOWS_H
22
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25 #define COBJMACROS
26 #include <stdarg.h>
27 //#include <string.h>
28
29 #include <windef.h>
30 #include <winbase.h>
31 //#include "wingdi.h"
32 //#include "winuser.h"
33 #include <winreg.h>
34 //#include "winerror.h"
35
36 #include <objbase.h>
37 //#include "ocidl.h"
38 //#include "wincodec.h"
39 #include <wincodecsdk.h>
40
41 #include <wine/debug.h>
42 #include <wine/unicode.h>
43
44 #include "wincodecs_private.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
47
48 /***********************************************************************
49 * interface for self-registering
50 */
51 struct decoder_pattern
52 {
53 DWORD length; /* 0 for end of list */
54 DWORD position;
55 const BYTE *pattern;
56 const BYTE *mask;
57 DWORD endofstream;
58 };
59
60 struct regsvr_decoder
61 {
62 CLSID const *clsid; /* NULL for end of list */
63 LPCSTR author;
64 LPCSTR friendlyname;
65 LPCSTR version;
66 GUID const *vendor;
67 GUID const *container_format;
68 LPCSTR mimetypes;
69 LPCSTR extensions;
70 GUID const * const *formats;
71 const struct decoder_pattern *patterns;
72 };
73
74 static HRESULT register_decoders(struct regsvr_decoder const *list);
75 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
76
77 struct regsvr_encoder
78 {
79 CLSID const *clsid; /* NULL for end of list */
80 LPCSTR author;
81 LPCSTR friendlyname;
82 LPCSTR version;
83 GUID const *vendor;
84 GUID const *container_format;
85 LPCSTR mimetypes;
86 LPCSTR extensions;
87 GUID const * const *formats;
88 };
89
90 static HRESULT register_encoders(struct regsvr_encoder const *list);
91 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
92
93 struct regsvr_converter
94 {
95 CLSID const *clsid; /* NULL for end of list */
96 LPCSTR author;
97 LPCSTR friendlyname;
98 LPCSTR version;
99 GUID const *vendor;
100 GUID const * const *formats;
101 };
102
103 static HRESULT register_converters(struct regsvr_converter const *list);
104 static HRESULT unregister_converters(struct regsvr_converter const *list);
105
106 struct metadata_pattern
107 {
108 DWORD position;
109 DWORD length;
110 const BYTE *pattern;
111 const BYTE *mask;
112 DWORD data_offset;
113 };
114
115 struct reader_containers
116 {
117 GUID const *format;
118 const struct metadata_pattern *patterns;
119 };
120
121 struct regsvr_metadatareader
122 {
123 CLSID const *clsid; /* NULL for end of list */
124 LPCSTR author;
125 LPCSTR friendlyname;
126 LPCSTR version;
127 LPCSTR specversion;
128 GUID const *vendor;
129 GUID const *metadata_format;
130 DWORD requires_fullstream;
131 DWORD supports_padding;
132 DWORD requires_fixedsize;
133 const struct reader_containers *containers;
134 };
135
136 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list);
137 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
138
139 struct regsvr_pixelformat
140 {
141 CLSID const *clsid; /* NULL for end of list */
142 LPCSTR author;
143 LPCSTR friendlyname;
144 LPCSTR version;
145 GUID const *vendor;
146 UINT bitsperpixel;
147 UINT channelcount;
148 BYTE const * const *channelmasks;
149 WICPixelFormatNumericRepresentation numericrepresentation;
150 UINT supportsalpha;
151 };
152
153 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list);
154 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list);
155
156 /***********************************************************************
157 * static string constants
158 */
159 static const WCHAR clsid_keyname[] = {
160 'C', 'L', 'S', 'I', 'D', 0 };
161 static const WCHAR curver_keyname[] = {
162 'C', 'u', 'r', 'V', 'e', 'r', 0 };
163 static const WCHAR ips_keyname[] = {
164 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
165 0 };
166 static const WCHAR ips32_keyname[] = {
167 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
168 '3', '2', 0 };
169 static const WCHAR progid_keyname[] = {
170 'P', 'r', 'o', 'g', 'I', 'D', 0 };
171 static const WCHAR viprogid_keyname[] = {
172 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
173 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
174 0 };
175 static const char tmodel_valuename[] = "ThreadingModel";
176 static const char author_valuename[] = "Author";
177 static const char friendlyname_valuename[] = "FriendlyName";
178 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
179 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
180 static const char version_valuename[] = "Version";
181 static const char mimetypes_valuename[] = "MimeTypes";
182 static const char extensions_valuename[] = "FileExtensions";
183 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
184 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
185 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
186 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0};
187 static const char length_valuename[] = "Length";
188 static const char position_valuename[] = "Position";
189 static const char pattern_valuename[] = "Pattern";
190 static const char mask_valuename[] = "Mask";
191 static const char endofstream_valuename[] = "EndOfStream";
192 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
193 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
194 static const char specversion_valuename[] = "SpecVersion";
195 static const char requiresfullstream_valuename[] = "RequiresFullStream";
196 static const char supportspadding_valuename[] = "SupportsPadding";
197 static const char requiresfixedsize_valuename[] = "FixedSize";
198 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
199 static const char dataoffset_valuename[] = "DataOffset";
200 static const char bitsperpixel_valuename[] = "BitLength";
201 static const char channelcount_valuename[] = "ChannelCount";
202 static const char numericrepresentation_valuename[] = "NumericRepresentation";
203 static const char supportstransparency_valuename[] = "SupportsTransparency";
204 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
205
206 /***********************************************************************
207 * register_decoders
208 */
209 static HRESULT register_decoders(struct regsvr_decoder const *list)
210 {
211 LONG res = ERROR_SUCCESS;
212 HKEY coclass_key;
213 WCHAR buf[39];
214 HKEY decoders_key;
215 HKEY instance_key;
216
217 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
218 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
219 if (res == ERROR_SUCCESS) {
220 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
221 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
222 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
223 if (res == ERROR_SUCCESS)
224 {
225 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
226 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
227 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
228 }
229 if (res != ERROR_SUCCESS)
230 RegCloseKey(coclass_key);
231 }
232 if (res != ERROR_SUCCESS) goto error_return;
233
234 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
235 HKEY clsid_key;
236 HKEY instance_clsid_key;
237
238 StringFromGUID2(list->clsid, buf, 39);
239 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
240 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
241 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
242
243 StringFromGUID2(list->clsid, buf, 39);
244 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
245 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
246 if (res == ERROR_SUCCESS) {
247 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
248 (CONST BYTE*)(buf), 78);
249 RegCloseKey(instance_clsid_key);
250 }
251 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
252
253 if (list->author) {
254 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
255 (CONST BYTE*)(list->author),
256 strlen(list->author) + 1);
257 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
258 }
259
260 if (list->friendlyname) {
261 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
262 (CONST BYTE*)(list->friendlyname),
263 strlen(list->friendlyname) + 1);
264 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
265 }
266
267 if (list->vendor) {
268 StringFromGUID2(list->vendor, buf, 39);
269 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
270 (CONST BYTE*)(buf), 78);
271 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
272 }
273
274 if (list->container_format) {
275 StringFromGUID2(list->container_format, buf, 39);
276 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
277 (CONST BYTE*)(buf), 78);
278 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
279 }
280
281 if (list->version) {
282 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
283 (CONST BYTE*)(list->version),
284 strlen(list->version) + 1);
285 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
286 }
287
288 if (list->mimetypes) {
289 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
290 (CONST BYTE*)(list->mimetypes),
291 strlen(list->mimetypes) + 1);
292 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
293 }
294
295 if (list->extensions) {
296 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
297 (CONST BYTE*)(list->extensions),
298 strlen(list->extensions) + 1);
299 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
300 }
301
302 if (list->formats) {
303 HKEY formats_key;
304 GUID const * const *format;
305
306 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
307 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
308 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
309 for (format=list->formats; *format; ++format)
310 {
311 HKEY format_key;
312 StringFromGUID2(*format, buf, 39);
313 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
314 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
315 if (res != ERROR_SUCCESS) break;
316 RegCloseKey(format_key);
317 }
318 RegCloseKey(formats_key);
319 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
320 }
321
322 if (list->patterns) {
323 HKEY patterns_key;
324 int i;
325
326 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
327 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
328 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
329 for (i=0; list->patterns[i].length; i++)
330 {
331 HKEY pattern_key;
332 static const WCHAR int_format[] = {'%','i',0};
333 snprintfW(buf, 39, int_format, i);
334 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
335 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
336 if (res != ERROR_SUCCESS) break;
337 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
338 (CONST BYTE*)(&list->patterns[i].length), 4);
339 if (res == ERROR_SUCCESS)
340 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
341 (CONST BYTE*)(&list->patterns[i].position), 4);
342 if (res == ERROR_SUCCESS)
343 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
344 list->patterns[i].pattern,
345 list->patterns[i].length);
346 if (res == ERROR_SUCCESS)
347 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
348 list->patterns[i].mask,
349 list->patterns[i].length);
350 if (res == ERROR_SUCCESS)
351 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
352 (CONST BYTE*)&(list->patterns[i].endofstream), 4);
353 RegCloseKey(pattern_key);
354 }
355 RegCloseKey(patterns_key);
356 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
357 }
358
359 error_close_clsid_key:
360 RegCloseKey(clsid_key);
361 }
362
363 error_close_coclass_key:
364 RegCloseKey(instance_key);
365 RegCloseKey(decoders_key);
366 RegCloseKey(coclass_key);
367 error_return:
368 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
369 }
370
371 /***********************************************************************
372 * unregister_decoders
373 */
374 static HRESULT unregister_decoders(struct regsvr_decoder const *list)
375 {
376 LONG res = ERROR_SUCCESS;
377 HKEY coclass_key;
378 WCHAR buf[39];
379 HKEY decoders_key;
380 HKEY instance_key;
381
382 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
383 KEY_READ | KEY_WRITE, &coclass_key);
384 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
385
386 if (res == ERROR_SUCCESS) {
387 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
388 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
389 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
390 if (res == ERROR_SUCCESS)
391 {
392 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
393 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
394 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
395 }
396 if (res != ERROR_SUCCESS)
397 RegCloseKey(coclass_key);
398 }
399 if (res != ERROR_SUCCESS) goto error_return;
400
401 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
402 StringFromGUID2(list->clsid, buf, 39);
403
404 res = RegDeleteTreeW(coclass_key, buf);
405 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
406 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
407
408 res = RegDeleteTreeW(instance_key, buf);
409 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
410 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
411 }
412
413 error_close_coclass_key:
414 RegCloseKey(instance_key);
415 RegCloseKey(decoders_key);
416 RegCloseKey(coclass_key);
417 error_return:
418 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
419 }
420
421 /***********************************************************************
422 * register_encoders
423 */
424 static HRESULT register_encoders(struct regsvr_encoder const *list)
425 {
426 LONG res = ERROR_SUCCESS;
427 HKEY coclass_key;
428 WCHAR buf[39];
429 HKEY encoders_key;
430 HKEY instance_key;
431
432 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
433 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
434 if (res == ERROR_SUCCESS) {
435 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
436 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
437 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
438 if (res == ERROR_SUCCESS)
439 {
440 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
441 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
442 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
443 }
444 if (res != ERROR_SUCCESS)
445 RegCloseKey(coclass_key);
446 }
447 if (res != ERROR_SUCCESS) goto error_return;
448
449 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
450 HKEY clsid_key;
451 HKEY instance_clsid_key;
452
453 StringFromGUID2(list->clsid, buf, 39);
454 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
455 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
456 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
457
458 StringFromGUID2(list->clsid, buf, 39);
459 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
460 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
461 if (res == ERROR_SUCCESS) {
462 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
463 (CONST BYTE*)(buf), 78);
464 RegCloseKey(instance_clsid_key);
465 }
466 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
467
468 if (list->author) {
469 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
470 (CONST BYTE*)(list->author),
471 strlen(list->author) + 1);
472 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
473 }
474
475 if (list->friendlyname) {
476 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
477 (CONST BYTE*)(list->friendlyname),
478 strlen(list->friendlyname) + 1);
479 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
480 }
481
482 if (list->vendor) {
483 StringFromGUID2(list->vendor, buf, 39);
484 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
485 (CONST BYTE*)(buf), 78);
486 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
487 }
488
489 if (list->container_format) {
490 StringFromGUID2(list->container_format, buf, 39);
491 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
492 (CONST BYTE*)(buf), 78);
493 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
494 }
495
496 if (list->version) {
497 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
498 (CONST BYTE*)(list->version),
499 strlen(list->version) + 1);
500 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
501 }
502
503 if (list->mimetypes) {
504 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
505 (CONST BYTE*)(list->mimetypes),
506 strlen(list->mimetypes) + 1);
507 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
508 }
509
510 if (list->extensions) {
511 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
512 (CONST BYTE*)(list->extensions),
513 strlen(list->extensions) + 1);
514 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
515 }
516
517 if (list->formats) {
518 HKEY formats_key;
519 GUID const * const *format;
520
521 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
522 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
523 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
524 for (format=list->formats; *format; ++format)
525 {
526 HKEY format_key;
527 StringFromGUID2(*format, buf, 39);
528 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
529 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
530 if (res != ERROR_SUCCESS) break;
531 RegCloseKey(format_key);
532 }
533 RegCloseKey(formats_key);
534 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
535 }
536
537 error_close_clsid_key:
538 RegCloseKey(clsid_key);
539 }
540
541 error_close_coclass_key:
542 RegCloseKey(instance_key);
543 RegCloseKey(encoders_key);
544 RegCloseKey(coclass_key);
545 error_return:
546 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
547 }
548
549 /***********************************************************************
550 * unregister_encoders
551 */
552 static HRESULT unregister_encoders(struct regsvr_encoder const *list)
553 {
554 LONG res = ERROR_SUCCESS;
555 HKEY coclass_key;
556 WCHAR buf[39];
557 HKEY encoders_key;
558 HKEY instance_key;
559
560 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
561 KEY_READ | KEY_WRITE, &coclass_key);
562 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
563
564 if (res == ERROR_SUCCESS) {
565 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
566 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
567 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
568 if (res == ERROR_SUCCESS)
569 {
570 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
571 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
572 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
573 }
574 if (res != ERROR_SUCCESS)
575 RegCloseKey(coclass_key);
576 }
577 if (res != ERROR_SUCCESS) goto error_return;
578
579 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
580 StringFromGUID2(list->clsid, buf, 39);
581
582 res = RegDeleteTreeW(coclass_key, buf);
583 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
584 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
585
586 res = RegDeleteTreeW(instance_key, buf);
587 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
588 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
589 }
590
591 error_close_coclass_key:
592 RegCloseKey(instance_key);
593 RegCloseKey(encoders_key);
594 RegCloseKey(coclass_key);
595 error_return:
596 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
597 }
598
599 /***********************************************************************
600 * register_converters
601 */
602 static HRESULT register_converters(struct regsvr_converter const *list)
603 {
604 LONG res = ERROR_SUCCESS;
605 HKEY coclass_key;
606 WCHAR buf[39];
607 HKEY converters_key;
608 HKEY instance_key;
609
610 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
611 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
612 if (res == ERROR_SUCCESS) {
613 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
614 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
615 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
616 if (res == ERROR_SUCCESS)
617 {
618 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
619 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
620 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
621 }
622 if (res != ERROR_SUCCESS)
623 RegCloseKey(coclass_key);
624 }
625 if (res != ERROR_SUCCESS) goto error_return;
626
627 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
628 HKEY clsid_key;
629 HKEY instance_clsid_key;
630
631 StringFromGUID2(list->clsid, buf, 39);
632 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
633 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
634 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
635
636 StringFromGUID2(list->clsid, buf, 39);
637 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
638 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
639 if (res == ERROR_SUCCESS) {
640 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
641 (CONST BYTE*)(buf), 78);
642 RegCloseKey(instance_clsid_key);
643 }
644 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
645
646 if (list->author) {
647 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
648 (CONST BYTE*)(list->author),
649 strlen(list->author) + 1);
650 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
651 }
652
653 if (list->friendlyname) {
654 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
655 (CONST BYTE*)(list->friendlyname),
656 strlen(list->friendlyname) + 1);
657 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
658 }
659
660 if (list->vendor) {
661 StringFromGUID2(list->vendor, buf, 39);
662 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
663 (CONST BYTE*)(buf), 78);
664 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
665 }
666
667 if (list->version) {
668 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
669 (CONST BYTE*)(list->version),
670 strlen(list->version) + 1);
671 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
672 }
673
674 if (list->formats) {
675 HKEY formats_key;
676 GUID const * const *format;
677
678 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
679 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
680 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
681 for (format=list->formats; *format; ++format)
682 {
683 HKEY format_key;
684 StringFromGUID2(*format, buf, 39);
685 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
686 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
687 if (res != ERROR_SUCCESS) break;
688 RegCloseKey(format_key);
689 }
690 RegCloseKey(formats_key);
691 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
692 }
693
694 error_close_clsid_key:
695 RegCloseKey(clsid_key);
696 }
697
698 error_close_coclass_key:
699 RegCloseKey(instance_key);
700 RegCloseKey(converters_key);
701 RegCloseKey(coclass_key);
702 error_return:
703 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
704 }
705
706 /***********************************************************************
707 * unregister_converters
708 */
709 static HRESULT unregister_converters(struct regsvr_converter const *list)
710 {
711 LONG res = ERROR_SUCCESS;
712 HKEY coclass_key;
713 WCHAR buf[39];
714 HKEY converters_key;
715 HKEY instance_key;
716
717 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
718 KEY_READ | KEY_WRITE, &coclass_key);
719 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
720
721 if (res == ERROR_SUCCESS) {
722 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
723 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
724 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
725 if (res == ERROR_SUCCESS)
726 {
727 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
728 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
729 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
730 }
731 if (res != ERROR_SUCCESS)
732 RegCloseKey(coclass_key);
733 }
734 if (res != ERROR_SUCCESS) goto error_return;
735
736 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
737 StringFromGUID2(list->clsid, buf, 39);
738
739 res = RegDeleteTreeW(coclass_key, buf);
740 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
741 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
742
743 res = RegDeleteTreeW(instance_key, buf);
744 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
745 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
746 }
747
748 error_close_coclass_key:
749 RegCloseKey(instance_key);
750 RegCloseKey(converters_key);
751 RegCloseKey(coclass_key);
752 error_return:
753 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
754 }
755
756 /***********************************************************************
757 * register_metadatareaders
758 */
759 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list)
760 {
761 LONG res = ERROR_SUCCESS;
762 HKEY coclass_key;
763 WCHAR buf[39];
764 HKEY readers_key;
765 HKEY instance_key;
766
767 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
768 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
769 if (res == ERROR_SUCCESS) {
770 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
771 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
772 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
773 if (res == ERROR_SUCCESS)
774 {
775 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
776 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
777 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
778 }
779 if (res != ERROR_SUCCESS)
780 RegCloseKey(coclass_key);
781 }
782 if (res != ERROR_SUCCESS) goto error_return;
783
784 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
785 HKEY clsid_key;
786 HKEY instance_clsid_key;
787
788 StringFromGUID2(list->clsid, buf, 39);
789 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
790 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
791 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
792
793 StringFromGUID2(list->clsid, buf, 39);
794 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
795 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
796 if (res == ERROR_SUCCESS) {
797 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
798 (CONST BYTE*)(buf), 78);
799 RegCloseKey(instance_clsid_key);
800 }
801 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
802
803 if (list->author) {
804 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
805 (CONST BYTE*)(list->author),
806 strlen(list->author) + 1);
807 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
808 }
809
810 if (list->friendlyname) {
811 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
812 (CONST BYTE*)(list->friendlyname),
813 strlen(list->friendlyname) + 1);
814 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
815 }
816
817 if (list->vendor) {
818 StringFromGUID2(list->vendor, buf, 39);
819 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
820 (CONST BYTE*)(buf), 78);
821 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
822 }
823
824 if (list->metadata_format) {
825 StringFromGUID2(list->metadata_format, buf, 39);
826 res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ,
827 (CONST BYTE*)(buf), 78);
828 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
829 }
830
831 if (list->version) {
832 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
833 (CONST BYTE*)(list->version),
834 strlen(list->version) + 1);
835 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
836 }
837
838 if (list->specversion) {
839 res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ,
840 (CONST BYTE*)(list->version),
841 strlen(list->version) + 1);
842 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
843 }
844
845 res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD,
846 (CONST BYTE*)(&list->requires_fullstream), 4);
847 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
848
849 res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD,
850 (CONST BYTE*)(&list->supports_padding), 4);
851 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
852
853 if (list->requires_fixedsize) {
854 res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD,
855 (CONST BYTE*)(&list->requires_fixedsize), 4);
856 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
857 }
858
859 if (list->containers) {
860 HKEY containers_key;
861 const struct reader_containers *container;
862
863 res = RegCreateKeyExW(clsid_key, containers_keyname, 0, NULL, 0,
864 KEY_READ | KEY_WRITE, NULL, &containers_key, NULL);
865 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
866 for (container=list->containers; container->format; ++container)
867 {
868 HKEY format_key;
869 int i;
870 StringFromGUID2(container->format, buf, 39);
871 res = RegCreateKeyExW(containers_key, buf, 0, NULL, 0,
872 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
873 if (res != ERROR_SUCCESS) break;
874
875 for (i=0; container->patterns[i].length; i++)
876 {
877 HKEY pattern_key;
878 static const WCHAR int_format[] = {'%','i',0};
879 snprintfW(buf, 39, int_format, i);
880 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0,
881 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
882 if (res != ERROR_SUCCESS) break;
883 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
884 (CONST BYTE*)(&container->patterns[i].position), 4);
885 if (res == ERROR_SUCCESS)
886 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
887 container->patterns[i].pattern,
888 container->patterns[i].length);
889 if (res == ERROR_SUCCESS)
890 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
891 container->patterns[i].mask,
892 container->patterns[i].length);
893 if (res == ERROR_SUCCESS && container->patterns[i].data_offset)
894 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD,
895 (CONST BYTE*)&(container->patterns[i].data_offset), 4);
896 RegCloseKey(pattern_key);
897 }
898
899 RegCloseKey(format_key);
900 }
901 RegCloseKey(containers_key);
902 }
903
904 error_close_clsid_key:
905 RegCloseKey(clsid_key);
906 }
907
908 error_close_coclass_key:
909 RegCloseKey(instance_key);
910 RegCloseKey(readers_key);
911 RegCloseKey(coclass_key);
912 error_return:
913 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
914 }
915
916 /***********************************************************************
917 * unregister_metadatareaders
918 */
919 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list)
920 {
921 LONG res = ERROR_SUCCESS;
922 HKEY coclass_key;
923 WCHAR buf[39];
924 HKEY readers_key;
925 HKEY instance_key;
926
927 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
928 KEY_READ | KEY_WRITE, &coclass_key);
929 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
930
931 if (res == ERROR_SUCCESS) {
932 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
933 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
934 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
935 if (res == ERROR_SUCCESS)
936 {
937 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
938 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
939 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
940 }
941 if (res != ERROR_SUCCESS)
942 RegCloseKey(coclass_key);
943 }
944 if (res != ERROR_SUCCESS) goto error_return;
945
946 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
947 StringFromGUID2(list->clsid, buf, 39);
948
949 res = RegDeleteTreeW(coclass_key, buf);
950 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
951 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
952
953 res = RegDeleteTreeW(instance_key, buf);
954 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
955 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
956 }
957
958 error_close_coclass_key:
959 RegCloseKey(instance_key);
960 RegCloseKey(readers_key);
961 RegCloseKey(coclass_key);
962 error_return:
963 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
964 }
965
966 /***********************************************************************
967 * register_pixelformats
968 */
969 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list)
970 {
971 LONG res = ERROR_SUCCESS;
972 HKEY coclass_key;
973 WCHAR buf[39];
974 HKEY formats_key;
975 HKEY instance_key;
976
977 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
978 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
979 if (res == ERROR_SUCCESS) {
980 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
981 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
982 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
983 if (res == ERROR_SUCCESS)
984 {
985 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
986 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
987 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
988 }
989 if (res != ERROR_SUCCESS)
990 RegCloseKey(coclass_key);
991 }
992 if (res != ERROR_SUCCESS) goto error_return;
993
994 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
995 HKEY clsid_key;
996 HKEY instance_clsid_key;
997
998 StringFromGUID2(list->clsid, buf, 39);
999 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1000 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
1001 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1002
1003 StringFromGUID2(list->clsid, buf, 39);
1004 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
1005 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
1006 if (res == ERROR_SUCCESS) {
1007 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
1008 (CONST BYTE*)(buf), 78);
1009 RegCloseKey(instance_clsid_key);
1010 }
1011 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1012
1013 if (list->author) {
1014 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
1015 (CONST BYTE*)(list->author),
1016 strlen(list->author) + 1);
1017 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1018 }
1019
1020 if (list->friendlyname) {
1021 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
1022 (CONST BYTE*)(list->friendlyname),
1023 strlen(list->friendlyname) + 1);
1024 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1025 }
1026
1027 if (list->vendor) {
1028 StringFromGUID2(list->vendor, buf, 39);
1029 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
1030 (CONST BYTE*)(buf), 78);
1031 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1032 }
1033
1034 if (list->version) {
1035 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
1036 (CONST BYTE*)(list->version),
1037 strlen(list->version) + 1);
1038 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1039 }
1040
1041 res = RegSetValueExA(clsid_key, bitsperpixel_valuename, 0, REG_DWORD,
1042 (CONST BYTE*)(&list->bitsperpixel), 4);
1043 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1044
1045 res = RegSetValueExA(clsid_key, channelcount_valuename, 0, REG_DWORD,
1046 (CONST BYTE*)(&list->channelcount), 4);
1047 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1048
1049 res = RegSetValueExA(clsid_key, numericrepresentation_valuename, 0, REG_DWORD,
1050 (CONST BYTE*)(&list->numericrepresentation), 4);
1051 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1052
1053 res = RegSetValueExA(clsid_key, supportstransparency_valuename, 0, REG_DWORD,
1054 (CONST BYTE*)(&list->supportsalpha), 4);
1055 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1056
1057 if (list->channelmasks) {
1058 HKEY masks_key;
1059 UINT i, mask_size;
1060 WCHAR mask_valuename[11];
1061 const WCHAR valuename_format[] = {'%','d',0};
1062
1063 mask_size = (list->bitsperpixel + 7)/8;
1064
1065 res = RegCreateKeyExW(clsid_key, channelmasks_keyname, 0, NULL, 0,
1066 KEY_READ | KEY_WRITE, NULL, &masks_key, NULL);
1067 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1068 for (i=0; i < list->channelcount; i++)
1069 {
1070 sprintfW(mask_valuename, valuename_format, i);
1071 res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY,
1072 list->channelmasks[i], mask_size);
1073 if (res != ERROR_SUCCESS) break;
1074 }
1075 RegCloseKey(masks_key);
1076 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1077 }
1078
1079 error_close_clsid_key:
1080 RegCloseKey(clsid_key);
1081 }
1082
1083 error_close_coclass_key:
1084 RegCloseKey(instance_key);
1085 RegCloseKey(formats_key);
1086 RegCloseKey(coclass_key);
1087 error_return:
1088 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1089 }
1090
1091 /***********************************************************************
1092 * unregister_pixelformats
1093 */
1094 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list)
1095 {
1096 LONG res = ERROR_SUCCESS;
1097 HKEY coclass_key;
1098 WCHAR buf[39];
1099 HKEY formats_key;
1100 HKEY instance_key;
1101
1102 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
1103 KEY_READ | KEY_WRITE, &coclass_key);
1104 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
1105
1106 if (res == ERROR_SUCCESS) {
1107 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
1108 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1109 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
1110 if (res == ERROR_SUCCESS)
1111 {
1112 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
1113 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1114 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1115 }
1116 if (res != ERROR_SUCCESS)
1117 RegCloseKey(coclass_key);
1118 }
1119 if (res != ERROR_SUCCESS) goto error_return;
1120
1121 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
1122 StringFromGUID2(list->clsid, buf, 39);
1123
1124 res = RegDeleteTreeW(coclass_key, buf);
1125 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1126 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1127
1128 res = RegDeleteTreeW(instance_key, buf);
1129 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1130 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1131 }
1132
1133 error_close_coclass_key:
1134 RegCloseKey(instance_key);
1135 RegCloseKey(formats_key);
1136 RegCloseKey(coclass_key);
1137 error_return:
1138 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1139 }
1140
1141 /***********************************************************************
1142 * decoder list
1143 */
1144 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1145
1146 static const BYTE bmp_magic[] = {0x42,0x4d};
1147
1148 static GUID const * const bmp_formats[] = {
1149 &GUID_WICPixelFormat1bppIndexed,
1150 &GUID_WICPixelFormat2bppIndexed,
1151 &GUID_WICPixelFormat4bppIndexed,
1152 &GUID_WICPixelFormat8bppIndexed,
1153 &GUID_WICPixelFormat16bppBGR555,
1154 &GUID_WICPixelFormat16bppBGR565,
1155 &GUID_WICPixelFormat24bppBGR,
1156 &GUID_WICPixelFormat32bppBGR,
1157 &GUID_WICPixelFormat32bppBGRA,
1158 NULL
1159 };
1160
1161 static struct decoder_pattern const bmp_patterns[] = {
1162 {2,0,bmp_magic,mask_all,0},
1163 {0}
1164 };
1165
1166 static const BYTE gif87a_magic[6] = "GIF87a";
1167 static const BYTE gif89a_magic[6] = "GIF89a";
1168
1169 static GUID const * const gif_formats[] = {
1170 &GUID_WICPixelFormat8bppIndexed,
1171 NULL
1172 };
1173
1174 static struct decoder_pattern const gif_patterns[] = {
1175 {6,0,gif87a_magic,mask_all,0},
1176 {6,0,gif89a_magic,mask_all,0},
1177 {0}
1178 };
1179
1180 static const BYTE ico_magic[] = {00,00,01,00};
1181
1182 static GUID const * const ico_formats[] = {
1183 &GUID_WICPixelFormat32bppBGRA,
1184 NULL
1185 };
1186
1187 static struct decoder_pattern const ico_patterns[] = {
1188 {4,0,ico_magic,mask_all,0},
1189 {0}
1190 };
1191
1192 static const BYTE jpeg_magic[] = {0xff, 0xd8};
1193
1194 static GUID const * const jpeg_formats[] = {
1195 &GUID_WICPixelFormat24bppBGR,
1196 &GUID_WICPixelFormat32bppCMYK,
1197 &GUID_WICPixelFormat8bppGray,
1198 NULL
1199 };
1200
1201 static struct decoder_pattern const jpeg_patterns[] = {
1202 {2,0,jpeg_magic,mask_all,0},
1203 {0}
1204 };
1205
1206 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
1207
1208 static GUID const * const png_formats[] = {
1209 &GUID_WICPixelFormatBlackWhite,
1210 &GUID_WICPixelFormat2bppGray,
1211 &GUID_WICPixelFormat4bppGray,
1212 &GUID_WICPixelFormat8bppGray,
1213 &GUID_WICPixelFormat16bppGray,
1214 &GUID_WICPixelFormat32bppBGRA,
1215 &GUID_WICPixelFormat64bppRGBA,
1216 &GUID_WICPixelFormat1bppIndexed,
1217 &GUID_WICPixelFormat2bppIndexed,
1218 &GUID_WICPixelFormat4bppIndexed,
1219 &GUID_WICPixelFormat8bppIndexed,
1220 &GUID_WICPixelFormat24bppBGR,
1221 &GUID_WICPixelFormat48bppRGB,
1222 NULL
1223 };
1224
1225 static struct decoder_pattern const png_patterns[] = {
1226 {8,0,png_magic,mask_all,0},
1227 {0}
1228 };
1229
1230 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
1231 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
1232
1233 static GUID const * const tiff_decode_formats[] = {
1234 &GUID_WICPixelFormatBlackWhite,
1235 &GUID_WICPixelFormat4bppGray,
1236 &GUID_WICPixelFormat8bppGray,
1237 &GUID_WICPixelFormat4bppIndexed,
1238 &GUID_WICPixelFormat8bppIndexed,
1239 &GUID_WICPixelFormat24bppBGR,
1240 &GUID_WICPixelFormat32bppBGR,
1241 &GUID_WICPixelFormat32bppBGRA,
1242 &GUID_WICPixelFormat32bppPBGRA,
1243 &GUID_WICPixelFormat48bppRGB,
1244 &GUID_WICPixelFormat64bppRGBA,
1245 &GUID_WICPixelFormat64bppPRGBA,
1246 NULL
1247 };
1248
1249 static struct decoder_pattern const tiff_patterns[] = {
1250 {4,0,tiff_magic_le,mask_all,0},
1251 {4,0,tiff_magic_be,mask_all,0},
1252 {0}
1253 };
1254
1255 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
1256
1257 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};
1258 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};
1259
1260 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};
1261 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};
1262
1263 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};
1264 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};
1265
1266 static GUID const * const tga_formats[] = {
1267 &GUID_WICPixelFormat8bppGray,
1268 &GUID_WICPixelFormat8bppIndexed,
1269 &GUID_WICPixelFormat16bppGray,
1270 &GUID_WICPixelFormat16bppBGR555,
1271 &GUID_WICPixelFormat24bppBGR,
1272 &GUID_WICPixelFormat32bppBGRA,
1273 &GUID_WICPixelFormat32bppPBGRA,
1274 NULL
1275 };
1276
1277 static struct decoder_pattern const tga_patterns[] = {
1278 {18,18,tga_footer_magic,mask_all,1},
1279 {18,0,tga_indexed_magic,tga_indexed_mask,0},
1280 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
1281 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
1282 {0}
1283 };
1284
1285 static struct regsvr_decoder const decoder_list[] = {
1286 { &CLSID_WICBmpDecoder,
1287 "The Wine Project",
1288 "BMP Decoder",
1289 "1.0.0.0",
1290 &GUID_VendorMicrosoft,
1291 &GUID_ContainerFormatBmp,
1292 "image/bmp",
1293 ".bmp,.dib,.rle",
1294 bmp_formats,
1295 bmp_patterns
1296 },
1297 { &CLSID_WICGifDecoder,
1298 "The Wine Project",
1299 "GIF Decoder",
1300 "1.0.0.0",
1301 &GUID_VendorMicrosoft,
1302 &GUID_ContainerFormatGif,
1303 "image/gif",
1304 ".gif",
1305 gif_formats,
1306 gif_patterns
1307 },
1308 { &CLSID_WICIcoDecoder,
1309 "The Wine Project",
1310 "ICO Decoder",
1311 "1.0.0.0",
1312 &GUID_VendorMicrosoft,
1313 &GUID_ContainerFormatIco,
1314 "image/vnd.microsoft.icon",
1315 ".ico",
1316 ico_formats,
1317 ico_patterns
1318 },
1319 { &CLSID_WICJpegDecoder,
1320 "The Wine Project",
1321 "JPEG Decoder",
1322 "1.0.0.0",
1323 &GUID_VendorMicrosoft,
1324 &GUID_ContainerFormatJpeg,
1325 "image/jpeg",
1326 ".jpg;.jpeg;.jfif",
1327 jpeg_formats,
1328 jpeg_patterns
1329 },
1330 { &CLSID_WICPngDecoder,
1331 "The Wine Project",
1332 "PNG Decoder",
1333 "1.0.0.0",
1334 &GUID_VendorMicrosoft,
1335 &GUID_ContainerFormatPng,
1336 "image/png",
1337 ".png",
1338 png_formats,
1339 png_patterns
1340 },
1341 { &CLSID_WICTiffDecoder,
1342 "The Wine Project",
1343 "TIFF Decoder",
1344 "1.0.0.0",
1345 &GUID_VendorMicrosoft,
1346 &GUID_ContainerFormatTiff,
1347 "image/tiff",
1348 ".tif;.tiff",
1349 tiff_decode_formats,
1350 tiff_patterns
1351 },
1352 { &CLSID_WineTgaDecoder,
1353 "The Wine Project",
1354 "TGA Decoder",
1355 "1.0.0.0",
1356 &GUID_VendorWine,
1357 &GUID_WineContainerFormatTga,
1358 "image/x-targa",
1359 ".tga;.tpic",
1360 tga_formats,
1361 tga_patterns
1362 },
1363 { NULL } /* list terminator */
1364 };
1365
1366 static GUID const * const bmp_encode_formats[] = {
1367 &GUID_WICPixelFormat16bppBGR555,
1368 &GUID_WICPixelFormat16bppBGR565,
1369 &GUID_WICPixelFormat24bppBGR,
1370 &GUID_WICPixelFormat32bppBGR,
1371 NULL
1372 };
1373
1374 static GUID const * const png_encode_formats[] = {
1375 &GUID_WICPixelFormat24bppBGR,
1376 &GUID_WICPixelFormatBlackWhite,
1377 &GUID_WICPixelFormat2bppGray,
1378 &GUID_WICPixelFormat4bppGray,
1379 &GUID_WICPixelFormat8bppGray,
1380 &GUID_WICPixelFormat16bppGray,
1381 &GUID_WICPixelFormat32bppBGR,
1382 &GUID_WICPixelFormat32bppBGRA,
1383 &GUID_WICPixelFormat48bppRGB,
1384 &GUID_WICPixelFormat64bppRGBA,
1385 NULL
1386 };
1387
1388 static GUID const * const tiff_encode_formats[] = {
1389 &GUID_WICPixelFormatBlackWhite,
1390 &GUID_WICPixelFormat4bppGray,
1391 &GUID_WICPixelFormat8bppGray,
1392 &GUID_WICPixelFormat24bppBGR,
1393 &GUID_WICPixelFormat32bppBGRA,
1394 &GUID_WICPixelFormat32bppPBGRA,
1395 &GUID_WICPixelFormat48bppRGB,
1396 &GUID_WICPixelFormat64bppRGBA,
1397 &GUID_WICPixelFormat64bppPRGBA,
1398 NULL
1399 };
1400
1401 static GUID const * const icns_encode_formats[] = {
1402 &GUID_WICPixelFormat32bppBGRA,
1403 NULL
1404 };
1405
1406 static struct regsvr_encoder const encoder_list[] = {
1407 { &CLSID_WICBmpEncoder,
1408 "The Wine Project",
1409 "BMP Encoder",
1410 "1.0.0.0",
1411 &GUID_VendorMicrosoft,
1412 &GUID_ContainerFormatBmp,
1413 "image/bmp",
1414 ".bmp,.dib,.rle",
1415 bmp_encode_formats
1416 },
1417 { &CLSID_WICJpegEncoder,
1418 "The Wine Project",
1419 "JPEG Encoder",
1420 "1.0.0.0",
1421 &GUID_VendorMicrosoft,
1422 &GUID_ContainerFormatJpeg,
1423 "image/jpeg",
1424 ".jpg;.jpeg;.jfif",
1425 jpeg_formats
1426 },
1427 { &CLSID_WICPngEncoder,
1428 "The Wine Project",
1429 "PNG Encoder",
1430 "1.0.0.0",
1431 &GUID_VendorMicrosoft,
1432 &GUID_ContainerFormatPng,
1433 "image/png",
1434 ".png",
1435 png_encode_formats
1436 },
1437 { &CLSID_WICTiffEncoder,
1438 "The Wine Project",
1439 "TIFF Encoder",
1440 "1.0.0.0",
1441 &GUID_VendorMicrosoft,
1442 &GUID_ContainerFormatTiff,
1443 "image/tiff",
1444 ".tif;.tiff",
1445 tiff_encode_formats
1446 },
1447 { &CLSID_WICIcnsEncoder,
1448 "The Wine Project",
1449 "ICNS Encoder",
1450 "1.0.0.0",
1451 &GUID_VendorWine,
1452 NULL, /* no container format guid */
1453 "image/icns",
1454 ".icns",
1455 icns_encode_formats
1456 },
1457 { NULL } /* list terminator */
1458 };
1459
1460 static GUID const * const converter_formats[] = {
1461 &GUID_WICPixelFormat1bppIndexed,
1462 &GUID_WICPixelFormat2bppIndexed,
1463 &GUID_WICPixelFormat4bppIndexed,
1464 &GUID_WICPixelFormat8bppIndexed,
1465 &GUID_WICPixelFormatBlackWhite,
1466 &GUID_WICPixelFormat2bppGray,
1467 &GUID_WICPixelFormat4bppGray,
1468 &GUID_WICPixelFormat8bppGray,
1469 &GUID_WICPixelFormat16bppGray,
1470 &GUID_WICPixelFormat16bppBGR555,
1471 &GUID_WICPixelFormat16bppBGR565,
1472 &GUID_WICPixelFormat16bppBGRA5551,
1473 &GUID_WICPixelFormat24bppBGR,
1474 &GUID_WICPixelFormat32bppBGR,
1475 &GUID_WICPixelFormat32bppBGRA,
1476 &GUID_WICPixelFormat32bppPBGRA,
1477 &GUID_WICPixelFormat48bppRGB,
1478 &GUID_WICPixelFormat64bppRGBA,
1479 &GUID_WICPixelFormat32bppCMYK,
1480 NULL
1481 };
1482
1483 static struct regsvr_converter const converter_list[] = {
1484 { &CLSID_WICDefaultFormatConverter,
1485 "The Wine Project",
1486 "Default Pixel Format Converter",
1487 "1.0.0.0",
1488 &GUID_VendorMicrosoft,
1489 converter_formats
1490 },
1491 { NULL } /* list terminator */
1492 };
1493
1494 static const BYTE no_magic[1] = { 0 };
1495 static const BYTE no_mask[1] = { 0 };
1496
1497 static const struct metadata_pattern ifd_metadata_pattern[] = {
1498 { 0, 1, no_magic, no_mask, 0 },
1499 { 0 }
1500 };
1501
1502 static const struct reader_containers ifd_containers[] = {
1503 {
1504 &GUID_ContainerFormatTiff,
1505 ifd_metadata_pattern
1506 },
1507 { NULL } /* list terminator */
1508 };
1509
1510 static const BYTE tEXt[] = "tEXt";
1511
1512 static const struct metadata_pattern pngtext_metadata_pattern[] = {
1513 { 4, 4, tEXt, mask_all, 4 },
1514 { 0 }
1515 };
1516
1517 static const struct reader_containers pngtext_containers[] = {
1518 {
1519 &GUID_ContainerFormatPng,
1520 pngtext_metadata_pattern
1521 },
1522 { NULL } /* list terminator */
1523 };
1524
1525 static const struct metadata_pattern lsd_metadata_patterns[] = {
1526 { 0, 6, gif87a_magic, mask_all, 0 },
1527 { 0, 6, gif89a_magic, mask_all, 0 },
1528 { 0 }
1529 };
1530
1531 static const struct reader_containers lsd_containers[] = {
1532 {
1533 &GUID_ContainerFormatGif,
1534 lsd_metadata_patterns
1535 },
1536 { NULL } /* list terminator */
1537 };
1538
1539 static const BYTE imd_magic[] = { 0x2c };
1540
1541 static const struct metadata_pattern imd_metadata_pattern[] = {
1542 { 0, 1, imd_magic, mask_all, 1 },
1543 { 0 }
1544 };
1545
1546 static const struct reader_containers imd_containers[] = {
1547 {
1548 &GUID_ContainerFormatGif,
1549 imd_metadata_pattern
1550 },
1551 { NULL } /* list terminator */
1552 };
1553
1554 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 };
1555
1556 static const struct metadata_pattern gce_metadata_pattern[] = {
1557 { 0, 3, gce_magic, mask_all, 3 },
1558 { 0 }
1559 };
1560
1561 static const struct reader_containers gce_containers[] = {
1562 {
1563 &GUID_ContainerFormatGif,
1564 gce_metadata_pattern
1565 },
1566 { NULL } /* list terminator */
1567 };
1568
1569 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b };
1570
1571 static const struct metadata_pattern ape_metadata_pattern[] = {
1572 { 0, 3, ape_magic, mask_all, 0 },
1573 { 0 }
1574 };
1575
1576 static const struct reader_containers ape_containers[] = {
1577 {
1578 &GUID_ContainerFormatGif,
1579 ape_metadata_pattern
1580 },
1581 { NULL } /* list terminator */
1582 };
1583
1584 static const BYTE gif_comment_magic[] = { 0x21, 0xfe };
1585
1586 static const struct metadata_pattern gif_comment_metadata_pattern[] = {
1587 { 0, 2, gif_comment_magic, mask_all, 0 },
1588 { 0 }
1589 };
1590
1591 static const struct reader_containers gif_comment_containers[] = {
1592 {
1593 &GUID_ContainerFormatGif,
1594 gif_comment_metadata_pattern
1595 },
1596 { NULL } /* list terminator */
1597 };
1598
1599 static struct regsvr_metadatareader const metadatareader_list[] = {
1600 { &CLSID_WICUnknownMetadataReader,
1601 "The Wine Project",
1602 "Unknown Metadata Reader",
1603 "1.0.0.0",
1604 "1.0.0.0",
1605 &GUID_VendorMicrosoft,
1606 &GUID_MetadataFormatUnknown,
1607 0, 0, 0,
1608 NULL
1609 },
1610 { &CLSID_WICIfdMetadataReader,
1611 "The Wine Project",
1612 "Ifd Reader",
1613 "1.0.0.0",
1614 "1.0.0.0",
1615 &GUID_VendorMicrosoft,
1616 &GUID_MetadataFormatIfd,
1617 1, 1, 0,
1618 ifd_containers
1619 },
1620 { &CLSID_WICPngTextMetadataReader,
1621 "The Wine Project",
1622 "Chunk tEXt Reader",
1623 "1.0.0.0",
1624 "1.0.0.0",
1625 &GUID_VendorMicrosoft,
1626 &GUID_MetadataFormatChunktEXt,
1627 0, 0, 0,
1628 pngtext_containers
1629 },
1630 { &CLSID_WICLSDMetadataReader,
1631 "The Wine Project",
1632 "Logical Screen Descriptor Reader",
1633 "1.0.0.0",
1634 "1.0.0.0",
1635 &GUID_VendorMicrosoft,
1636 &GUID_MetadataFormatLSD,
1637 0, 0, 0,
1638 lsd_containers
1639 },
1640 { &CLSID_WICIMDMetadataReader,
1641 "The Wine Project",
1642 "Image Descriptor Reader",
1643 "1.0.0.0",
1644 "1.0.0.0",
1645 &GUID_VendorMicrosoft,
1646 &GUID_MetadataFormatIMD,
1647 0, 0, 0,
1648 imd_containers
1649 },
1650 { &CLSID_WICGCEMetadataReader,
1651 "The Wine Project",
1652 "Graphic Control Extension Reader",
1653 "1.0.0.0",
1654 "1.0.0.0",
1655 &GUID_VendorMicrosoft,
1656 &GUID_MetadataFormatGCE,
1657 0, 0, 0,
1658 gce_containers
1659 },
1660 { &CLSID_WICAPEMetadataReader,
1661 "The Wine Project",
1662 "Application Extension Reader",
1663 "1.0.0.0",
1664 "1.0.0.0",
1665 &GUID_VendorMicrosoft,
1666 &GUID_MetadataFormatAPE,
1667 0, 0, 0,
1668 ape_containers
1669 },
1670 { &CLSID_WICGifCommentMetadataReader,
1671 "The Wine Project",
1672 "Comment Extension Reader",
1673 "1.0.0.0",
1674 "1.0.0.0",
1675 &GUID_VendorMicrosoft,
1676 &GUID_MetadataFormatGifComment,
1677 0, 0, 0,
1678 gif_comment_containers
1679 },
1680 { NULL } /* list terminator */
1681 };
1682
1683 static BYTE const channel_mask_1bit[] = { 0x01 };
1684 static BYTE const channel_mask_2bit[] = { 0x03 };
1685 static BYTE const channel_mask_4bit[] = { 0x0f };
1686
1687 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 };
1688 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 };
1689 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 };
1690 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff };
1691
1692 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1693 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1694 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1695 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1696
1697 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
1698 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
1699 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
1700 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 };
1701
1702 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 };
1703 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 };
1704
1705 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit };
1706 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit };
1707 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit };
1708 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
1709 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 };
1710 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
1711 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
1712
1713 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
1714 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
1715
1716 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit,
1717 channel_mask_BGR565_2, channel_mask_BGR565_3 };
1718
1719 static struct regsvr_pixelformat const pixelformat_list[] = {
1720 { &GUID_WICPixelFormat1bppIndexed,
1721 "The Wine Project",
1722 "1bpp Indexed",
1723 NULL, /* no version */
1724 &GUID_VendorMicrosoft,
1725 1, /* bitsperpixel */
1726 1, /* channel count */
1727 channel_masks_1bit,
1728 WICPixelFormatNumericRepresentationIndexed,
1729 1
1730 },
1731 { &GUID_WICPixelFormat2bppIndexed,
1732 "The Wine Project",
1733 "2bpp Indexed",
1734 NULL, /* no version */
1735 &GUID_VendorMicrosoft,
1736 2, /* bitsperpixel */
1737 1, /* channel count */
1738 channel_masks_2bit,
1739 WICPixelFormatNumericRepresentationIndexed,
1740 1
1741 },
1742 { &GUID_WICPixelFormat4bppIndexed,
1743 "The Wine Project",
1744 "4bpp Indexed",
1745 NULL, /* no version */
1746 &GUID_VendorMicrosoft,
1747 4, /* bitsperpixel */
1748 1, /* channel count */
1749 channel_masks_4bit,
1750 WICPixelFormatNumericRepresentationIndexed,
1751 1
1752 },
1753 { &GUID_WICPixelFormat8bppIndexed,
1754 "The Wine Project",
1755 "8bpp Indexed",
1756 NULL, /* no version */
1757 &GUID_VendorMicrosoft,
1758 8, /* bitsperpixel */
1759 1, /* channel count */
1760 channel_masks_8bit,
1761 WICPixelFormatNumericRepresentationIndexed,
1762 1
1763 },
1764 { &GUID_WICPixelFormatBlackWhite,
1765 "The Wine Project",
1766 "Black and White",
1767 NULL, /* no version */
1768 &GUID_VendorMicrosoft,
1769 1, /* bitsperpixel */
1770 1, /* channel count */
1771 channel_masks_1bit,
1772 WICPixelFormatNumericRepresentationUnsignedInteger,
1773 0
1774 },
1775 { &GUID_WICPixelFormat2bppGray,
1776 "The Wine Project",
1777 "2bpp Grayscale",
1778 NULL, /* no version */
1779 &GUID_VendorMicrosoft,
1780 2, /* bitsperpixel */
1781 1, /* channel count */
1782 channel_masks_2bit,
1783 WICPixelFormatNumericRepresentationUnsignedInteger,
1784 0
1785 },
1786 { &GUID_WICPixelFormat4bppGray,
1787 "The Wine Project",
1788 "4bpp Grayscale",
1789 NULL, /* no version */
1790 &GUID_VendorMicrosoft,
1791 4, /* bitsperpixel */
1792 1, /* channel count */
1793 channel_masks_4bit,
1794 WICPixelFormatNumericRepresentationUnsignedInteger,
1795 0
1796 },
1797 { &GUID_WICPixelFormat8bppGray,
1798 "The Wine Project",
1799 "8bpp Grayscale",
1800 NULL, /* no version */
1801 &GUID_VendorMicrosoft,
1802 8, /* bitsperpixel */
1803 1, /* channel count */
1804 channel_masks_8bit,
1805 WICPixelFormatNumericRepresentationUnsignedInteger,
1806 0
1807 },
1808 { &GUID_WICPixelFormat16bppGray,
1809 "The Wine Project",
1810 "16bpp Grayscale",
1811 NULL, /* no version */
1812 &GUID_VendorMicrosoft,
1813 16, /* bitsperpixel */
1814 1, /* channel count */
1815 channel_masks_16bit,
1816 WICPixelFormatNumericRepresentationUnsignedInteger,
1817 0
1818 },
1819 { &GUID_WICPixelFormat16bppBGR555,
1820 "The Wine Project",
1821 "16bpp BGR555",
1822 NULL, /* no version */
1823 &GUID_VendorMicrosoft,
1824 16, /* bitsperpixel */
1825 3, /* channel count */
1826 channel_masks_BGRA5551,
1827 WICPixelFormatNumericRepresentationUnsignedInteger,
1828 0
1829 },
1830 { &GUID_WICPixelFormat16bppBGR565,
1831 "The Wine Project",
1832 "16bpp BGR565",
1833 NULL, /* no version */
1834 &GUID_VendorMicrosoft,
1835 16, /* bitsperpixel */
1836 3, /* channel count */
1837 channel_masks_BGR565,
1838 WICPixelFormatNumericRepresentationUnsignedInteger,
1839 0
1840 },
1841 { &GUID_WICPixelFormat16bppBGRA5551,
1842 "The Wine Project",
1843 "16bpp BGRA5551",
1844 NULL, /* no version */
1845 &GUID_VendorMicrosoft,
1846 16, /* bitsperpixel */
1847 4, /* channel count */
1848 channel_masks_BGRA5551,
1849 WICPixelFormatNumericRepresentationUnsignedInteger,
1850 1
1851 },
1852 { &GUID_WICPixelFormat24bppBGR,
1853 "The Wine Project",
1854 "24bpp BGR",
1855 NULL, /* no version */
1856 &GUID_VendorMicrosoft,
1857 24, /* bitsperpixel */
1858 3, /* channel count */
1859 channel_masks_8bit,
1860 WICPixelFormatNumericRepresentationUnsignedInteger,
1861 0
1862 },
1863 { &GUID_WICPixelFormat32bppBGR,
1864 "The Wine Project",
1865 "32bpp BGR",
1866 NULL, /* no version */
1867 &GUID_VendorMicrosoft,
1868 32, /* bitsperpixel */
1869 3, /* channel count */
1870 channel_masks_8bit,
1871 WICPixelFormatNumericRepresentationUnsignedInteger,
1872 0
1873 },
1874 { &GUID_WICPixelFormat32bppBGRA,
1875 "The Wine Project",
1876 "32bpp BGRA",
1877 NULL, /* no version */
1878 &GUID_VendorMicrosoft,
1879 32, /* bitsperpixel */
1880 4, /* channel count */
1881 channel_masks_8bit,
1882 WICPixelFormatNumericRepresentationUnsignedInteger,
1883 1
1884 },
1885 { &GUID_WICPixelFormat32bppPBGRA,
1886 "The Wine Project",
1887 "32bpp PBGRA",
1888 NULL, /* no version */
1889 &GUID_VendorMicrosoft,
1890 32, /* bitsperpixel */
1891 4, /* channel count */
1892 channel_masks_8bit,
1893 WICPixelFormatNumericRepresentationUnsignedInteger,
1894 1
1895 },
1896 { &GUID_WICPixelFormat48bppRGB,
1897 "The Wine Project",
1898 "48bpp RGB",
1899 NULL, /* no version */
1900 &GUID_VendorMicrosoft,
1901 48, /* bitsperpixel */
1902 3, /* channel count */
1903 channel_masks_16bit,
1904 WICPixelFormatNumericRepresentationUnsignedInteger,
1905 0
1906 },
1907 { &GUID_WICPixelFormat64bppRGBA,
1908 "The Wine Project",
1909 "64bpp RGBA",
1910 NULL, /* no version */
1911 &GUID_VendorMicrosoft,
1912 64, /* bitsperpixel */
1913 4, /* channel count */
1914 channel_masks_16bit,
1915 WICPixelFormatNumericRepresentationUnsignedInteger,
1916 1
1917 },
1918 { &GUID_WICPixelFormat64bppPRGBA,
1919 "The Wine Project",
1920 "64bpp PRGBA",
1921 NULL, /* no version */
1922 &GUID_VendorMicrosoft,
1923 64, /* bitsperpixel */
1924 4, /* channel count */
1925 channel_masks_16bit,
1926 WICPixelFormatNumericRepresentationUnsignedInteger,
1927 1
1928 },
1929 { &GUID_WICPixelFormat32bppCMYK,
1930 "The Wine Project",
1931 "32bpp CMYK",
1932 NULL, /* no version */
1933 &GUID_VendorMicrosoft,
1934 32, /* bitsperpixel */
1935 4, /* channel count */
1936 channel_masks_8bit,
1937 WICPixelFormatNumericRepresentationUnsignedInteger,
1938 0
1939 },
1940 { NULL } /* list terminator */
1941 };
1942
1943 struct regsvr_category
1944 {
1945 const CLSID *clsid; /* NULL for end of list */
1946 };
1947
1948 static const struct regsvr_category category_list[] = {
1949 { &CATID_WICBitmapDecoders },
1950 { &CATID_WICBitmapEncoders },
1951 { &CATID_WICFormatConverters },
1952 { &CATID_WICMetadataReader },
1953 { &CATID_WICPixelFormats },
1954 { NULL }
1955 };
1956
1957 static HRESULT register_categories(const struct regsvr_category *list)
1958 {
1959 LONG res;
1960 WCHAR buf[39];
1961 HKEY coclass_key, categories_key, instance_key;
1962
1963 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
1964 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
1965 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
1966
1967 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
1968 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1969 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL);
1970 if (res != ERROR_SUCCESS)
1971 {
1972 RegCloseKey(coclass_key);
1973 return HRESULT_FROM_WIN32(res);
1974 }
1975
1976 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0,
1977 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1978
1979 for (; res == ERROR_SUCCESS && list->clsid; list++)
1980 {
1981 HKEY instance_clsid_key;
1982
1983 StringFromGUID2(list->clsid, buf, 39);
1984 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
1985 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
1986 if (res == ERROR_SUCCESS)
1987 {
1988 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
1989 (const BYTE *)buf, 78);
1990 RegCloseKey(instance_clsid_key);
1991 }
1992 }
1993
1994 RegCloseKey(instance_key);
1995 RegCloseKey(categories_key);
1996 RegCloseKey(coclass_key);
1997
1998 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1999 }
2000
2001 static HRESULT unregister_categories(const struct regsvr_category *list)
2002 {
2003 LONG res;
2004 WCHAR buf[39];
2005 HKEY coclass_key, categories_key, instance_key;
2006
2007 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
2008 KEY_READ | KEY_WRITE, &coclass_key);
2009 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2010
2011 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2012 res = RegOpenKeyExW(coclass_key, buf, 0,
2013 KEY_READ | KEY_WRITE, &categories_key);
2014 if (res != ERROR_SUCCESS)
2015 {
2016 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
2017 RegCloseKey(coclass_key);
2018 return HRESULT_FROM_WIN32(res);
2019 }
2020
2021 res = RegOpenKeyExW(categories_key, instance_keyname, 0,
2022 KEY_READ | KEY_WRITE, &instance_key);
2023
2024 for (; res == ERROR_SUCCESS && list->clsid; list++)
2025 {
2026 StringFromGUID2(list->clsid, buf, 39);
2027 res = RegDeleteTreeW(instance_key, buf);
2028 }
2029
2030 RegCloseKey(instance_key);
2031 RegCloseKey(categories_key);
2032
2033 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2034 res = RegDeleteTreeW(coclass_key, buf);
2035
2036 RegCloseKey(coclass_key);
2037
2038 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2039 }
2040
2041 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
2042 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
2043
2044 HRESULT WINAPI DllRegisterServer(void)
2045 {
2046 HRESULT hr;
2047
2048 TRACE("\n");
2049
2050 hr = WIC_DllRegisterServer();
2051 if (SUCCEEDED(hr))
2052 hr = register_categories(category_list);
2053 if (SUCCEEDED(hr))
2054 hr = register_decoders(decoder_list);
2055 if (SUCCEEDED(hr))
2056 hr = register_encoders(encoder_list);
2057 if (SUCCEEDED(hr))
2058 hr = register_converters(converter_list);
2059 if (SUCCEEDED(hr))
2060 hr = register_metadatareaders(metadatareader_list);
2061 if (SUCCEEDED(hr))
2062 hr = register_pixelformats(pixelformat_list);
2063 return hr;
2064 }
2065
2066 HRESULT WINAPI DllUnregisterServer(void)
2067 {
2068 HRESULT hr;
2069
2070 TRACE("\n");
2071
2072 hr = WIC_DllUnregisterServer();
2073 if (SUCCEEDED(hr))
2074 hr = unregister_categories(category_list);
2075 if (SUCCEEDED(hr))
2076 hr = unregister_decoders(decoder_list);
2077 if (SUCCEEDED(hr))
2078 hr = unregister_encoders(encoder_list);
2079 if (SUCCEEDED(hr))
2080 hr = unregister_converters(converter_list);
2081 if (SUCCEEDED(hr))
2082 hr = unregister_metadatareaders(metadatareader_list);
2083 if (SUCCEEDED(hr))
2084 hr = unregister_pixelformats(pixelformat_list);
2085 return hr;
2086 }