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