2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define NONAMELESSUNION
20 #define NONAMELESSSTRUCT
35 #include "wincodecsdk.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 #include "wincodecs_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
44 /***********************************************************************
45 * interface for self-registering
47 struct decoder_pattern
49 DWORD length
; /* 0 for end of list */
58 CLSID
const *clsid
; /* NULL for end of list */
63 GUID
const *container_format
;
66 GUID
const * const *formats
;
67 const struct decoder_pattern
*patterns
;
70 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
71 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
75 CLSID
const *clsid
; /* NULL for end of list */
80 GUID
const *container_format
;
83 GUID
const * const *formats
;
86 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
87 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
89 struct regsvr_converter
91 CLSID
const *clsid
; /* NULL for end of list */
96 GUID
const * const *formats
;
99 static HRESULT
register_converters(struct regsvr_converter
const *list
);
100 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
102 struct metadata_pattern
111 struct reader_containers
114 const struct metadata_pattern
*patterns
;
117 struct regsvr_metadatareader
119 CLSID
const *clsid
; /* NULL for end of list */
125 GUID
const *metadata_format
;
126 DWORD requires_fullstream
;
127 DWORD supports_padding
;
128 DWORD requires_fixedsize
;
129 const struct reader_containers
*containers
;
132 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
133 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
135 struct regsvr_pixelformat
137 CLSID
const *clsid
; /* NULL for end of list */
144 BYTE
const * const *channelmasks
;
145 WICPixelFormatNumericRepresentation numericrepresentation
;
149 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
);
150 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
);
152 /***********************************************************************
153 * static string constants
155 static const WCHAR clsid_keyname
[] = {
156 'C', 'L', 'S', 'I', 'D', 0 };
157 static const WCHAR curver_keyname
[] = {
158 'C', 'u', 'r', 'V', 'e', 'r', 0 };
159 static const WCHAR ips_keyname
[] = {
160 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
162 static const WCHAR ips32_keyname
[] = {
163 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
165 static const WCHAR progid_keyname
[] = {
166 'P', 'r', 'o', 'g', 'I', 'D', 0 };
167 static const WCHAR viprogid_keyname
[] = {
168 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
169 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
171 static const char tmodel_valuename
[] = "ThreadingModel";
172 static const char author_valuename
[] = "Author";
173 static const char friendlyname_valuename
[] = "FriendlyName";
174 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
175 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
176 static const char version_valuename
[] = "Version";
177 static const char mimetypes_valuename
[] = "MimeTypes";
178 static const char extensions_valuename
[] = "FileExtensions";
179 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
180 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
181 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
182 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
183 static const char length_valuename
[] = "Length";
184 static const char position_valuename
[] = "Position";
185 static const char pattern_valuename
[] = "Pattern";
186 static const char mask_valuename
[] = "Mask";
187 static const char endofstream_valuename
[] = "EndOfStream";
188 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
189 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
190 static const char specversion_valuename
[] = "SpecVersion";
191 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
192 static const char supportspadding_valuename
[] = "SupportsPadding";
193 static const char requiresfixedsize_valuename
[] = "FixedSize";
194 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
195 static const char dataoffset_valuename
[] = "DataOffset";
196 static const char bitsperpixel_valuename
[] = "BitLength";
197 static const char channelcount_valuename
[] = "ChannelCount";
198 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
199 static const char supportstransparency_valuename
[] = "SupportsTransparency";
200 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
202 /***********************************************************************
205 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
207 LONG res
= ERROR_SUCCESS
;
213 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
214 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
215 if (res
== ERROR_SUCCESS
) {
216 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
217 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
218 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
219 if (res
== ERROR_SUCCESS
)
221 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
222 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
223 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
225 if (res
!= ERROR_SUCCESS
)
226 RegCloseKey(coclass_key
);
228 if (res
!= ERROR_SUCCESS
) goto error_return
;
230 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
232 HKEY instance_clsid_key
;
234 StringFromGUID2(list
->clsid
, buf
, 39);
235 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
236 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
237 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
239 StringFromGUID2(list
->clsid
, buf
, 39);
240 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
241 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
242 if (res
== ERROR_SUCCESS
) {
243 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
244 (CONST BYTE
*)(buf
), 78);
245 RegCloseKey(instance_clsid_key
);
247 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
250 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
251 (CONST BYTE
*)(list
->author
),
252 strlen(list
->author
) + 1);
253 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
256 if (list
->friendlyname
) {
257 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
258 (CONST BYTE
*)(list
->friendlyname
),
259 strlen(list
->friendlyname
) + 1);
260 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
264 StringFromGUID2(list
->vendor
, buf
, 39);
265 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
266 (CONST BYTE
*)(buf
), 78);
267 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
270 if (list
->container_format
) {
271 StringFromGUID2(list
->container_format
, buf
, 39);
272 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
273 (CONST BYTE
*)(buf
), 78);
274 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
278 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
279 (CONST BYTE
*)(list
->version
),
280 strlen(list
->version
) + 1);
281 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
284 if (list
->mimetypes
) {
285 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
286 (CONST BYTE
*)(list
->mimetypes
),
287 strlen(list
->mimetypes
) + 1);
288 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
291 if (list
->extensions
) {
292 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
293 (CONST BYTE
*)(list
->extensions
),
294 strlen(list
->extensions
) + 1);
295 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
300 GUID
const * const *format
;
302 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
303 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
304 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
305 for (format
=list
->formats
; *format
; ++format
)
308 StringFromGUID2(*format
, buf
, 39);
309 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
310 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
311 if (res
!= ERROR_SUCCESS
) break;
312 RegCloseKey(format_key
);
314 RegCloseKey(formats_key
);
315 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
318 if (list
->patterns
) {
322 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
323 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
324 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
325 for (i
=0; list
->patterns
[i
].length
; i
++)
328 static const WCHAR int_format
[] = {'%','i',0};
329 snprintfW(buf
, 39, int_format
, i
);
330 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
331 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
332 if (res
!= ERROR_SUCCESS
) break;
333 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
334 (CONST BYTE
*)(&list
->patterns
[i
].length
), 4);
335 if (res
== ERROR_SUCCESS
)
336 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
337 (CONST BYTE
*)(&list
->patterns
[i
].position
), 4);
338 if (res
== ERROR_SUCCESS
)
339 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
340 list
->patterns
[i
].pattern
,
341 list
->patterns
[i
].length
);
342 if (res
== ERROR_SUCCESS
)
343 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
344 list
->patterns
[i
].mask
,
345 list
->patterns
[i
].length
);
346 if (res
== ERROR_SUCCESS
)
347 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
348 (CONST BYTE
*)&(list
->patterns
[i
].endofstream
), 4);
349 RegCloseKey(pattern_key
);
351 RegCloseKey(patterns_key
);
352 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
355 error_close_clsid_key
:
356 RegCloseKey(clsid_key
);
359 error_close_coclass_key
:
360 RegCloseKey(instance_key
);
361 RegCloseKey(decoders_key
);
362 RegCloseKey(coclass_key
);
364 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
367 /***********************************************************************
368 * unregister_decoders
370 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
372 LONG res
= ERROR_SUCCESS
;
378 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
379 KEY_READ
| KEY_WRITE
, &coclass_key
);
380 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
382 if (res
== ERROR_SUCCESS
) {
383 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
384 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
385 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
386 if (res
== ERROR_SUCCESS
)
388 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
389 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
390 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
392 if (res
!= ERROR_SUCCESS
)
393 RegCloseKey(coclass_key
);
395 if (res
!= ERROR_SUCCESS
) goto error_return
;
397 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
398 StringFromGUID2(list
->clsid
, buf
, 39);
400 res
= RegDeleteTreeW(coclass_key
, buf
);
401 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
402 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
404 res
= RegDeleteTreeW(instance_key
, buf
);
405 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
406 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
409 error_close_coclass_key
:
410 RegCloseKey(instance_key
);
411 RegCloseKey(decoders_key
);
412 RegCloseKey(coclass_key
);
414 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
417 /***********************************************************************
420 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
422 LONG res
= ERROR_SUCCESS
;
428 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
429 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
430 if (res
== ERROR_SUCCESS
) {
431 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
432 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
433 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
434 if (res
== ERROR_SUCCESS
)
436 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
437 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
438 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
440 if (res
!= ERROR_SUCCESS
)
441 RegCloseKey(coclass_key
);
443 if (res
!= ERROR_SUCCESS
) goto error_return
;
445 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
447 HKEY instance_clsid_key
;
449 StringFromGUID2(list
->clsid
, buf
, 39);
450 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
451 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
452 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
454 StringFromGUID2(list
->clsid
, buf
, 39);
455 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
456 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
457 if (res
== ERROR_SUCCESS
) {
458 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
459 (CONST BYTE
*)(buf
), 78);
460 RegCloseKey(instance_clsid_key
);
462 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
465 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
466 (CONST BYTE
*)(list
->author
),
467 strlen(list
->author
) + 1);
468 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
471 if (list
->friendlyname
) {
472 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
473 (CONST BYTE
*)(list
->friendlyname
),
474 strlen(list
->friendlyname
) + 1);
475 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
479 StringFromGUID2(list
->vendor
, buf
, 39);
480 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
481 (CONST BYTE
*)(buf
), 78);
482 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
485 if (list
->container_format
) {
486 StringFromGUID2(list
->container_format
, buf
, 39);
487 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
488 (CONST BYTE
*)(buf
), 78);
489 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
493 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
494 (CONST BYTE
*)(list
->version
),
495 strlen(list
->version
) + 1);
496 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
499 if (list
->mimetypes
) {
500 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
501 (CONST BYTE
*)(list
->mimetypes
),
502 strlen(list
->mimetypes
) + 1);
503 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
506 if (list
->extensions
) {
507 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
508 (CONST BYTE
*)(list
->extensions
),
509 strlen(list
->extensions
) + 1);
510 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
515 GUID
const * const *format
;
517 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
518 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
519 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
520 for (format
=list
->formats
; *format
; ++format
)
523 StringFromGUID2(*format
, buf
, 39);
524 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
525 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
526 if (res
!= ERROR_SUCCESS
) break;
527 RegCloseKey(format_key
);
529 RegCloseKey(formats_key
);
530 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
533 error_close_clsid_key
:
534 RegCloseKey(clsid_key
);
537 error_close_coclass_key
:
538 RegCloseKey(instance_key
);
539 RegCloseKey(encoders_key
);
540 RegCloseKey(coclass_key
);
542 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
545 /***********************************************************************
546 * unregister_encoders
548 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
550 LONG res
= ERROR_SUCCESS
;
556 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
557 KEY_READ
| KEY_WRITE
, &coclass_key
);
558 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
560 if (res
== ERROR_SUCCESS
) {
561 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
562 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
563 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
564 if (res
== ERROR_SUCCESS
)
566 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
567 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
568 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
570 if (res
!= ERROR_SUCCESS
)
571 RegCloseKey(coclass_key
);
573 if (res
!= ERROR_SUCCESS
) goto error_return
;
575 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
576 StringFromGUID2(list
->clsid
, buf
, 39);
578 res
= RegDeleteTreeW(coclass_key
, buf
);
579 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
580 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
582 res
= RegDeleteTreeW(instance_key
, buf
);
583 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
584 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
587 error_close_coclass_key
:
588 RegCloseKey(instance_key
);
589 RegCloseKey(encoders_key
);
590 RegCloseKey(coclass_key
);
592 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
595 /***********************************************************************
596 * register_converters
598 static HRESULT
register_converters(struct regsvr_converter
const *list
)
600 LONG res
= ERROR_SUCCESS
;
606 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
607 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
608 if (res
== ERROR_SUCCESS
) {
609 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
610 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
611 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
612 if (res
== ERROR_SUCCESS
)
614 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
615 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
616 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
618 if (res
!= ERROR_SUCCESS
)
619 RegCloseKey(coclass_key
);
621 if (res
!= ERROR_SUCCESS
) goto error_return
;
623 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
625 HKEY instance_clsid_key
;
627 StringFromGUID2(list
->clsid
, buf
, 39);
628 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
629 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
630 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
632 StringFromGUID2(list
->clsid
, buf
, 39);
633 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
634 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
635 if (res
== ERROR_SUCCESS
) {
636 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
637 (CONST BYTE
*)(buf
), 78);
638 RegCloseKey(instance_clsid_key
);
640 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
643 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
644 (CONST BYTE
*)(list
->author
),
645 strlen(list
->author
) + 1);
646 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
649 if (list
->friendlyname
) {
650 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
651 (CONST BYTE
*)(list
->friendlyname
),
652 strlen(list
->friendlyname
) + 1);
653 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
657 StringFromGUID2(list
->vendor
, buf
, 39);
658 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
659 (CONST BYTE
*)(buf
), 78);
660 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
664 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
665 (CONST BYTE
*)(list
->version
),
666 strlen(list
->version
) + 1);
667 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
672 GUID
const * const *format
;
674 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
675 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
676 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
677 for (format
=list
->formats
; *format
; ++format
)
680 StringFromGUID2(*format
, buf
, 39);
681 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
682 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
683 if (res
!= ERROR_SUCCESS
) break;
684 RegCloseKey(format_key
);
686 RegCloseKey(formats_key
);
687 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
690 error_close_clsid_key
:
691 RegCloseKey(clsid_key
);
694 error_close_coclass_key
:
695 RegCloseKey(instance_key
);
696 RegCloseKey(converters_key
);
697 RegCloseKey(coclass_key
);
699 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
702 /***********************************************************************
703 * unregister_converters
705 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
707 LONG res
= ERROR_SUCCESS
;
713 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
714 KEY_READ
| KEY_WRITE
, &coclass_key
);
715 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
717 if (res
== ERROR_SUCCESS
) {
718 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
719 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
720 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
721 if (res
== ERROR_SUCCESS
)
723 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
724 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
725 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
727 if (res
!= ERROR_SUCCESS
)
728 RegCloseKey(coclass_key
);
730 if (res
!= ERROR_SUCCESS
) goto error_return
;
732 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
733 StringFromGUID2(list
->clsid
, buf
, 39);
735 res
= RegDeleteTreeW(coclass_key
, buf
);
736 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
737 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
739 res
= RegDeleteTreeW(instance_key
, buf
);
740 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
741 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
744 error_close_coclass_key
:
745 RegCloseKey(instance_key
);
746 RegCloseKey(converters_key
);
747 RegCloseKey(coclass_key
);
749 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
752 /***********************************************************************
753 * register_metadatareaders
755 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
757 LONG res
= ERROR_SUCCESS
;
763 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
764 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
765 if (res
== ERROR_SUCCESS
) {
766 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
767 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
768 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
769 if (res
== ERROR_SUCCESS
)
771 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
772 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
773 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
775 if (res
!= ERROR_SUCCESS
)
776 RegCloseKey(coclass_key
);
778 if (res
!= ERROR_SUCCESS
) goto error_return
;
780 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
782 HKEY instance_clsid_key
;
784 StringFromGUID2(list
->clsid
, buf
, 39);
785 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
786 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
787 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
789 StringFromGUID2(list
->clsid
, buf
, 39);
790 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
791 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
792 if (res
== ERROR_SUCCESS
) {
793 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
794 (CONST BYTE
*)(buf
), 78);
795 RegCloseKey(instance_clsid_key
);
797 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
800 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
801 (CONST BYTE
*)(list
->author
),
802 strlen(list
->author
) + 1);
803 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
806 if (list
->friendlyname
) {
807 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
808 (CONST BYTE
*)(list
->friendlyname
),
809 strlen(list
->friendlyname
) + 1);
810 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
814 StringFromGUID2(list
->vendor
, buf
, 39);
815 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
816 (CONST BYTE
*)(buf
), 78);
817 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
821 StringFromGUID2(list
->metadata_format
, buf
, 39);
822 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
823 (CONST BYTE
*)(buf
), 78);
824 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
828 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
829 (CONST BYTE
*)(list
->version
),
830 strlen(list
->version
) + 1);
831 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
834 if (list
->specversion
) {
835 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
836 (CONST BYTE
*)(list
->version
),
837 strlen(list
->version
) + 1);
838 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
841 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
842 (CONST BYTE
*)(&list
->requires_fullstream
), 4);
843 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
845 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
846 (CONST BYTE
*)(&list
->supports_padding
), 4);
847 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
849 if (list
->requires_fixedsize
) {
850 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
851 (CONST BYTE
*)(&list
->requires_fixedsize
), 4);
852 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
855 if (list
->containers
) {
857 const struct reader_containers
*container
;
859 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
860 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
861 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
862 for (container
=list
->containers
; container
->format
; ++container
)
866 StringFromGUID2(container
->format
, buf
, 39);
867 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
868 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
869 if (res
!= ERROR_SUCCESS
) break;
871 for (i
=0; container
->patterns
[i
].length
; i
++)
874 static const WCHAR int_format
[] = {'%','i',0};
875 snprintfW(buf
, 39, int_format
, i
);
876 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
877 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
878 if (res
!= ERROR_SUCCESS
) break;
879 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
880 (CONST BYTE
*)(&container
->patterns
[i
].position
), 4);
881 if (res
== ERROR_SUCCESS
)
882 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
883 container
->patterns
[i
].pattern
,
884 container
->patterns
[i
].length
);
885 if (res
== ERROR_SUCCESS
)
886 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
887 container
->patterns
[i
].mask
,
888 container
->patterns
[i
].length
);
889 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
890 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
891 (CONST BYTE
*)&(container
->patterns
[i
].data_offset
), 4);
892 RegCloseKey(pattern_key
);
895 RegCloseKey(format_key
);
897 RegCloseKey(containers_key
);
900 error_close_clsid_key
:
901 RegCloseKey(clsid_key
);
904 error_close_coclass_key
:
905 RegCloseKey(instance_key
);
906 RegCloseKey(readers_key
);
907 RegCloseKey(coclass_key
);
909 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
912 /***********************************************************************
913 * unregister_metadatareaders
915 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
917 LONG res
= ERROR_SUCCESS
;
923 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
924 KEY_READ
| KEY_WRITE
, &coclass_key
);
925 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
927 if (res
== ERROR_SUCCESS
) {
928 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
929 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
930 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
931 if (res
== ERROR_SUCCESS
)
933 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
934 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
935 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
937 if (res
!= ERROR_SUCCESS
)
938 RegCloseKey(coclass_key
);
940 if (res
!= ERROR_SUCCESS
) goto error_return
;
942 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
943 StringFromGUID2(list
->clsid
, buf
, 39);
945 res
= RegDeleteTreeW(coclass_key
, buf
);
946 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
947 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
949 res
= RegDeleteTreeW(instance_key
, buf
);
950 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
951 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
954 error_close_coclass_key
:
955 RegCloseKey(instance_key
);
956 RegCloseKey(readers_key
);
957 RegCloseKey(coclass_key
);
959 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
962 /***********************************************************************
963 * register_pixelformats
965 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
967 LONG res
= ERROR_SUCCESS
;
973 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
974 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
975 if (res
== ERROR_SUCCESS
) {
976 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
977 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
978 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
979 if (res
== ERROR_SUCCESS
)
981 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
982 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
983 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
985 if (res
!= ERROR_SUCCESS
)
986 RegCloseKey(coclass_key
);
988 if (res
!= ERROR_SUCCESS
) goto error_return
;
990 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
992 HKEY instance_clsid_key
;
994 StringFromGUID2(list
->clsid
, buf
, 39);
995 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
996 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
997 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
999 StringFromGUID2(list
->clsid
, buf
, 39);
1000 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
1001 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
1002 if (res
== ERROR_SUCCESS
) {
1003 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
1004 (CONST BYTE
*)(buf
), 78);
1005 RegCloseKey(instance_clsid_key
);
1007 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1010 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
1011 (CONST BYTE
*)(list
->author
),
1012 strlen(list
->author
) + 1);
1013 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1016 if (list
->friendlyname
) {
1017 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
1018 (CONST BYTE
*)(list
->friendlyname
),
1019 strlen(list
->friendlyname
) + 1);
1020 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1024 StringFromGUID2(list
->vendor
, buf
, 39);
1025 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
1026 (CONST BYTE
*)(buf
), 78);
1027 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1030 if (list
->version
) {
1031 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
1032 (CONST BYTE
*)(list
->version
),
1033 strlen(list
->version
) + 1);
1034 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1037 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1038 (CONST BYTE
*)(&list
->bitsperpixel
), 4);
1039 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1041 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1042 (CONST BYTE
*)(&list
->channelcount
), 4);
1043 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1045 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1046 (CONST BYTE
*)(&list
->numericrepresentation
), 4);
1047 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1049 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1050 (CONST BYTE
*)(&list
->supportsalpha
), 4);
1051 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1053 if (list
->channelmasks
) {
1056 WCHAR mask_valuename
[11];
1057 const WCHAR valuename_format
[] = {'%','d',0};
1059 mask_size
= (list
->bitsperpixel
+ 7)/8;
1061 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1062 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1063 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1064 for (i
=0; i
< list
->channelcount
; i
++)
1066 sprintfW(mask_valuename
, valuename_format
, i
);
1067 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1068 list
->channelmasks
[i
], mask_size
);
1069 if (res
!= ERROR_SUCCESS
) break;
1071 RegCloseKey(masks_key
);
1072 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1075 error_close_clsid_key
:
1076 RegCloseKey(clsid_key
);
1079 error_close_coclass_key
:
1080 RegCloseKey(instance_key
);
1081 RegCloseKey(formats_key
);
1082 RegCloseKey(coclass_key
);
1084 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1087 /***********************************************************************
1088 * unregister_pixelformats
1090 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1092 LONG res
= ERROR_SUCCESS
;
1098 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1099 KEY_READ
| KEY_WRITE
, &coclass_key
);
1100 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1102 if (res
== ERROR_SUCCESS
) {
1103 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1104 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1105 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1106 if (res
== ERROR_SUCCESS
)
1108 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1109 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1110 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1112 if (res
!= ERROR_SUCCESS
)
1113 RegCloseKey(coclass_key
);
1115 if (res
!= ERROR_SUCCESS
) goto error_return
;
1117 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1118 StringFromGUID2(list
->clsid
, buf
, 39);
1120 res
= RegDeleteTreeW(coclass_key
, buf
);
1121 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1122 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1124 res
= RegDeleteTreeW(instance_key
, buf
);
1125 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1126 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1129 error_close_coclass_key
:
1130 RegCloseKey(instance_key
);
1131 RegCloseKey(formats_key
);
1132 RegCloseKey(coclass_key
);
1134 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1137 /***********************************************************************
1140 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1142 static const BYTE bmp_magic
[] = {0x42,0x4d};
1144 static GUID
const * const bmp_formats
[] = {
1145 &GUID_WICPixelFormat1bppIndexed
,
1146 &GUID_WICPixelFormat2bppIndexed
,
1147 &GUID_WICPixelFormat4bppIndexed
,
1148 &GUID_WICPixelFormat8bppIndexed
,
1149 &GUID_WICPixelFormat16bppBGR555
,
1150 &GUID_WICPixelFormat16bppBGR565
,
1151 &GUID_WICPixelFormat24bppBGR
,
1152 &GUID_WICPixelFormat32bppBGR
,
1153 &GUID_WICPixelFormat32bppBGRA
,
1157 static struct decoder_pattern
const bmp_patterns
[] = {
1158 {2,0,bmp_magic
,mask_all
,0},
1162 static const BYTE gif87a_magic
[6] = "GIF87a";
1163 static const BYTE gif89a_magic
[6] = "GIF89a";
1165 static GUID
const * const gif_formats
[] = {
1166 &GUID_WICPixelFormat8bppIndexed
,
1170 static struct decoder_pattern
const gif_patterns
[] = {
1171 {6,0,gif87a_magic
,mask_all
,0},
1172 {6,0,gif89a_magic
,mask_all
,0},
1176 static const BYTE ico_magic
[] = {00,00,01,00};
1178 static GUID
const * const ico_formats
[] = {
1179 &GUID_WICPixelFormat32bppBGRA
,
1183 static struct decoder_pattern
const ico_patterns
[] = {
1184 {4,0,ico_magic
,mask_all
,0},
1188 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1190 static GUID
const * const jpeg_formats
[] = {
1191 &GUID_WICPixelFormat24bppBGR
,
1192 &GUID_WICPixelFormat32bppCMYK
,
1193 &GUID_WICPixelFormat8bppGray
,
1197 static struct decoder_pattern
const jpeg_patterns
[] = {
1198 {2,0,jpeg_magic
,mask_all
,0},
1202 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1204 static GUID
const * const png_formats
[] = {
1205 &GUID_WICPixelFormatBlackWhite
,
1206 &GUID_WICPixelFormat2bppGray
,
1207 &GUID_WICPixelFormat4bppGray
,
1208 &GUID_WICPixelFormat8bppGray
,
1209 &GUID_WICPixelFormat16bppGray
,
1210 &GUID_WICPixelFormat32bppBGRA
,
1211 &GUID_WICPixelFormat64bppRGBA
,
1212 &GUID_WICPixelFormat1bppIndexed
,
1213 &GUID_WICPixelFormat2bppIndexed
,
1214 &GUID_WICPixelFormat4bppIndexed
,
1215 &GUID_WICPixelFormat8bppIndexed
,
1216 &GUID_WICPixelFormat24bppBGR
,
1217 &GUID_WICPixelFormat48bppRGB
,
1221 static struct decoder_pattern
const png_patterns
[] = {
1222 {8,0,png_magic
,mask_all
,0},
1226 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1227 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1229 static GUID
const * const tiff_decode_formats
[] = {
1230 &GUID_WICPixelFormatBlackWhite
,
1231 &GUID_WICPixelFormat4bppGray
,
1232 &GUID_WICPixelFormat8bppGray
,
1233 &GUID_WICPixelFormat4bppIndexed
,
1234 &GUID_WICPixelFormat8bppIndexed
,
1235 &GUID_WICPixelFormat24bppBGR
,
1236 &GUID_WICPixelFormat32bppBGR
,
1237 &GUID_WICPixelFormat32bppBGRA
,
1238 &GUID_WICPixelFormat32bppPBGRA
,
1239 &GUID_WICPixelFormat48bppRGB
,
1240 &GUID_WICPixelFormat64bppRGBA
,
1241 &GUID_WICPixelFormat64bppPRGBA
,
1245 static struct decoder_pattern
const tiff_patterns
[] = {
1246 {4,0,tiff_magic_le
,mask_all
,0},
1247 {4,0,tiff_magic_be
,mask_all
,0},
1251 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1253 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};
1254 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};
1256 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};
1257 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};
1259 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};
1260 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};
1262 static GUID
const * const tga_formats
[] = {
1263 &GUID_WICPixelFormat8bppGray
,
1264 &GUID_WICPixelFormat8bppIndexed
,
1265 &GUID_WICPixelFormat16bppGray
,
1266 &GUID_WICPixelFormat16bppBGR555
,
1267 &GUID_WICPixelFormat24bppBGR
,
1268 &GUID_WICPixelFormat32bppBGRA
,
1269 &GUID_WICPixelFormat32bppPBGRA
,
1273 static struct decoder_pattern
const tga_patterns
[] = {
1274 {18,18,tga_footer_magic
,mask_all
,1},
1275 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1276 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1277 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1281 static struct regsvr_decoder
const decoder_list
[] = {
1282 { &CLSID_WICBmpDecoder
,
1286 &GUID_VendorMicrosoft
,
1287 &GUID_ContainerFormatBmp
,
1293 { &CLSID_WICGifDecoder
,
1297 &GUID_VendorMicrosoft
,
1298 &GUID_ContainerFormatGif
,
1304 { &CLSID_WICIcoDecoder
,
1308 &GUID_VendorMicrosoft
,
1309 &GUID_ContainerFormatIco
,
1310 "image/vnd.microsoft.icon",
1315 { &CLSID_WICJpegDecoder
,
1319 &GUID_VendorMicrosoft
,
1320 &GUID_ContainerFormatJpeg
,
1326 { &CLSID_WICPngDecoder
,
1330 &GUID_VendorMicrosoft
,
1331 &GUID_ContainerFormatPng
,
1337 { &CLSID_WICTiffDecoder
,
1341 &GUID_VendorMicrosoft
,
1342 &GUID_ContainerFormatTiff
,
1345 tiff_decode_formats
,
1348 { &CLSID_WineTgaDecoder
,
1353 &GUID_WineContainerFormatTga
,
1359 { NULL
} /* list terminator */
1362 static GUID
const * const bmp_encode_formats
[] = {
1363 &GUID_WICPixelFormat16bppBGR555
,
1364 &GUID_WICPixelFormat16bppBGR565
,
1365 &GUID_WICPixelFormat24bppBGR
,
1366 &GUID_WICPixelFormat32bppBGR
,
1370 static GUID
const * const png_encode_formats
[] = {
1371 &GUID_WICPixelFormat24bppBGR
,
1372 &GUID_WICPixelFormatBlackWhite
,
1373 &GUID_WICPixelFormat2bppGray
,
1374 &GUID_WICPixelFormat4bppGray
,
1375 &GUID_WICPixelFormat8bppGray
,
1376 &GUID_WICPixelFormat16bppGray
,
1377 &GUID_WICPixelFormat32bppBGR
,
1378 &GUID_WICPixelFormat32bppBGRA
,
1379 &GUID_WICPixelFormat48bppRGB
,
1380 &GUID_WICPixelFormat64bppRGBA
,
1384 static GUID
const * const tiff_encode_formats
[] = {
1385 &GUID_WICPixelFormatBlackWhite
,
1386 &GUID_WICPixelFormat4bppGray
,
1387 &GUID_WICPixelFormat8bppGray
,
1388 &GUID_WICPixelFormat24bppBGR
,
1389 &GUID_WICPixelFormat32bppBGRA
,
1390 &GUID_WICPixelFormat32bppPBGRA
,
1391 &GUID_WICPixelFormat48bppRGB
,
1392 &GUID_WICPixelFormat64bppRGBA
,
1393 &GUID_WICPixelFormat64bppPRGBA
,
1397 static GUID
const * const icns_encode_formats
[] = {
1398 &GUID_WICPixelFormat32bppBGRA
,
1402 static struct regsvr_encoder
const encoder_list
[] = {
1403 { &CLSID_WICBmpEncoder
,
1407 &GUID_VendorMicrosoft
,
1408 &GUID_ContainerFormatBmp
,
1413 { &CLSID_WICJpegEncoder
,
1417 &GUID_VendorMicrosoft
,
1418 &GUID_ContainerFormatJpeg
,
1423 { &CLSID_WICPngEncoder
,
1427 &GUID_VendorMicrosoft
,
1428 &GUID_ContainerFormatPng
,
1433 { &CLSID_WICTiffEncoder
,
1437 &GUID_VendorMicrosoft
,
1438 &GUID_ContainerFormatTiff
,
1443 { &CLSID_WICIcnsEncoder
,
1448 NULL
, /* no container format guid */
1453 { NULL
} /* list terminator */
1456 static GUID
const * const converter_formats
[] = {
1457 &GUID_WICPixelFormat1bppIndexed
,
1458 &GUID_WICPixelFormat2bppIndexed
,
1459 &GUID_WICPixelFormat4bppIndexed
,
1460 &GUID_WICPixelFormat8bppIndexed
,
1461 &GUID_WICPixelFormatBlackWhite
,
1462 &GUID_WICPixelFormat2bppGray
,
1463 &GUID_WICPixelFormat4bppGray
,
1464 &GUID_WICPixelFormat8bppGray
,
1465 &GUID_WICPixelFormat16bppGray
,
1466 &GUID_WICPixelFormat16bppBGR555
,
1467 &GUID_WICPixelFormat16bppBGR565
,
1468 &GUID_WICPixelFormat16bppBGRA5551
,
1469 &GUID_WICPixelFormat24bppBGR
,
1470 &GUID_WICPixelFormat32bppBGR
,
1471 &GUID_WICPixelFormat32bppBGRA
,
1472 &GUID_WICPixelFormat32bppPBGRA
,
1473 &GUID_WICPixelFormat48bppRGB
,
1474 &GUID_WICPixelFormat64bppRGBA
,
1475 &GUID_WICPixelFormat32bppCMYK
,
1479 static struct regsvr_converter
const converter_list
[] = {
1480 { &CLSID_WICDefaultFormatConverter
,
1482 "Default Pixel Format Converter",
1484 &GUID_VendorMicrosoft
,
1487 { NULL
} /* list terminator */
1490 static const BYTE no_magic
[1] = { 0 };
1491 static const BYTE no_mask
[1] = { 0 };
1493 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1494 { 0, 1, no_magic
, no_mask
, 0 },
1498 static const struct reader_containers ifd_containers
[] = {
1500 &GUID_ContainerFormatTiff
,
1501 ifd_metadata_pattern
1503 { NULL
} /* list terminator */
1506 static const BYTE tEXt
[] = "tEXt";
1508 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1509 { 4, 4, tEXt
, mask_all
, 4 },
1513 static const struct reader_containers pngtext_containers
[] = {
1515 &GUID_ContainerFormatPng
,
1516 pngtext_metadata_pattern
1518 { NULL
} /* list terminator */
1521 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1522 { &CLSID_WICUnknownMetadataReader
,
1524 "Unknown Metadata Reader",
1527 &GUID_VendorMicrosoft
,
1528 &GUID_MetadataFormatUnknown
,
1533 &CLSID_WICIfdMetadataReader
,
1538 &GUID_VendorMicrosoft
,
1539 &GUID_MetadataFormatIfd
,
1543 { &CLSID_WICPngTextMetadataReader
,
1545 "Unknown Metadata Reader",
1548 &GUID_VendorMicrosoft
,
1549 &GUID_MetadataFormatChunktEXt
,
1553 { NULL
} /* list terminator */
1556 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1557 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1558 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1560 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1561 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1562 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1563 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1565 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1566 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1567 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1568 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1570 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1571 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1572 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1573 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1575 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1576 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1578 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1579 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1580 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1581 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1582 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1583 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1584 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1586 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1587 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1589 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1590 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1592 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1593 { &GUID_WICPixelFormat1bppIndexed
,
1596 NULL
, /* no version */
1597 &GUID_VendorMicrosoft
,
1598 1, /* bitsperpixel */
1599 1, /* channel count */
1601 WICPixelFormatNumericRepresentationIndexed
,
1604 { &GUID_WICPixelFormat2bppIndexed
,
1607 NULL
, /* no version */
1608 &GUID_VendorMicrosoft
,
1609 2, /* bitsperpixel */
1610 1, /* channel count */
1612 WICPixelFormatNumericRepresentationIndexed
,
1615 { &GUID_WICPixelFormat4bppIndexed
,
1618 NULL
, /* no version */
1619 &GUID_VendorMicrosoft
,
1620 4, /* bitsperpixel */
1621 1, /* channel count */
1623 WICPixelFormatNumericRepresentationIndexed
,
1626 { &GUID_WICPixelFormat8bppIndexed
,
1629 NULL
, /* no version */
1630 &GUID_VendorMicrosoft
,
1631 8, /* bitsperpixel */
1632 1, /* channel count */
1634 WICPixelFormatNumericRepresentationIndexed
,
1637 { &GUID_WICPixelFormatBlackWhite
,
1640 NULL
, /* no version */
1641 &GUID_VendorMicrosoft
,
1642 1, /* bitsperpixel */
1643 1, /* channel count */
1645 WICPixelFormatNumericRepresentationUnsignedInteger
,
1648 { &GUID_WICPixelFormat2bppGray
,
1651 NULL
, /* no version */
1652 &GUID_VendorMicrosoft
,
1653 2, /* bitsperpixel */
1654 1, /* channel count */
1656 WICPixelFormatNumericRepresentationUnsignedInteger
,
1659 { &GUID_WICPixelFormat4bppGray
,
1662 NULL
, /* no version */
1663 &GUID_VendorMicrosoft
,
1664 4, /* bitsperpixel */
1665 1, /* channel count */
1667 WICPixelFormatNumericRepresentationUnsignedInteger
,
1670 { &GUID_WICPixelFormat8bppGray
,
1673 NULL
, /* no version */
1674 &GUID_VendorMicrosoft
,
1675 8, /* bitsperpixel */
1676 1, /* channel count */
1678 WICPixelFormatNumericRepresentationUnsignedInteger
,
1681 { &GUID_WICPixelFormat16bppGray
,
1684 NULL
, /* no version */
1685 &GUID_VendorMicrosoft
,
1686 16, /* bitsperpixel */
1687 1, /* channel count */
1688 channel_masks_16bit
,
1689 WICPixelFormatNumericRepresentationUnsignedInteger
,
1692 { &GUID_WICPixelFormat16bppBGR555
,
1695 NULL
, /* no version */
1696 &GUID_VendorMicrosoft
,
1697 16, /* bitsperpixel */
1698 3, /* channel count */
1699 channel_masks_BGRA5551
,
1700 WICPixelFormatNumericRepresentationUnsignedInteger
,
1703 { &GUID_WICPixelFormat16bppBGR565
,
1706 NULL
, /* no version */
1707 &GUID_VendorMicrosoft
,
1708 16, /* bitsperpixel */
1709 3, /* channel count */
1710 channel_masks_BGR565
,
1711 WICPixelFormatNumericRepresentationUnsignedInteger
,
1714 { &GUID_WICPixelFormat16bppBGRA5551
,
1717 NULL
, /* no version */
1718 &GUID_VendorMicrosoft
,
1719 16, /* bitsperpixel */
1720 4, /* channel count */
1721 channel_masks_BGRA5551
,
1722 WICPixelFormatNumericRepresentationUnsignedInteger
,
1725 { &GUID_WICPixelFormat24bppBGR
,
1728 NULL
, /* no version */
1729 &GUID_VendorMicrosoft
,
1730 24, /* bitsperpixel */
1731 3, /* channel count */
1733 WICPixelFormatNumericRepresentationUnsignedInteger
,
1736 { &GUID_WICPixelFormat32bppBGR
,
1739 NULL
, /* no version */
1740 &GUID_VendorMicrosoft
,
1741 32, /* bitsperpixel */
1742 3, /* channel count */
1744 WICPixelFormatNumericRepresentationUnsignedInteger
,
1747 { &GUID_WICPixelFormat32bppBGRA
,
1750 NULL
, /* no version */
1751 &GUID_VendorMicrosoft
,
1752 32, /* bitsperpixel */
1753 4, /* channel count */
1755 WICPixelFormatNumericRepresentationUnsignedInteger
,
1758 { &GUID_WICPixelFormat32bppPBGRA
,
1761 NULL
, /* no version */
1762 &GUID_VendorMicrosoft
,
1763 32, /* bitsperpixel */
1764 4, /* channel count */
1766 WICPixelFormatNumericRepresentationUnsignedInteger
,
1769 { &GUID_WICPixelFormat48bppRGB
,
1772 NULL
, /* no version */
1773 &GUID_VendorMicrosoft
,
1774 48, /* bitsperpixel */
1775 3, /* channel count */
1776 channel_masks_16bit
,
1777 WICPixelFormatNumericRepresentationUnsignedInteger
,
1780 { &GUID_WICPixelFormat64bppRGBA
,
1783 NULL
, /* no version */
1784 &GUID_VendorMicrosoft
,
1785 64, /* bitsperpixel */
1786 4, /* channel count */
1787 channel_masks_16bit
,
1788 WICPixelFormatNumericRepresentationUnsignedInteger
,
1791 { &GUID_WICPixelFormat64bppPRGBA
,
1794 NULL
, /* no version */
1795 &GUID_VendorMicrosoft
,
1796 64, /* bitsperpixel */
1797 4, /* channel count */
1798 channel_masks_16bit
,
1799 WICPixelFormatNumericRepresentationUnsignedInteger
,
1802 { &GUID_WICPixelFormat32bppCMYK
,
1805 NULL
, /* no version */
1806 &GUID_VendorMicrosoft
,
1807 32, /* bitsperpixel */
1808 4, /* channel count */
1810 WICPixelFormatNumericRepresentationUnsignedInteger
,
1813 { NULL
} /* list terminator */
1816 struct regsvr_category
1818 const CLSID
*clsid
; /* NULL for end of list */
1821 static const struct regsvr_category category_list
[] = {
1822 { &CATID_WICBitmapDecoders
},
1823 { &CATID_WICBitmapEncoders
},
1824 { &CATID_WICFormatConverters
},
1825 { &CATID_WICMetadataReader
},
1826 { &CATID_WICPixelFormats
},
1830 static HRESULT
register_categories(const struct regsvr_category
*list
)
1834 HKEY coclass_key
, categories_key
, instance_key
;
1836 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
1837 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
1838 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1840 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1841 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1842 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
1843 if (res
!= ERROR_SUCCESS
)
1845 RegCloseKey(coclass_key
);
1846 return HRESULT_FROM_WIN32(res
);
1849 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
1850 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1852 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
1854 HKEY instance_clsid_key
;
1856 StringFromGUID2(list
->clsid
, buf
, 39);
1857 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
1858 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
1859 if (res
== ERROR_SUCCESS
)
1861 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
1862 (const BYTE
*)buf
, 78);
1863 RegCloseKey(instance_clsid_key
);
1867 RegCloseKey(instance_key
);
1868 RegCloseKey(categories_key
);
1869 RegCloseKey(coclass_key
);
1871 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1874 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
1878 HKEY coclass_key
, categories_key
, instance_key
;
1880 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1881 KEY_READ
| KEY_WRITE
, &coclass_key
);
1882 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1884 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1885 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
1886 KEY_READ
| KEY_WRITE
, &categories_key
);
1887 if (res
!= ERROR_SUCCESS
)
1889 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1890 RegCloseKey(coclass_key
);
1891 return HRESULT_FROM_WIN32(res
);
1894 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
1895 KEY_READ
| KEY_WRITE
, &instance_key
);
1897 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
1899 StringFromGUID2(list
->clsid
, buf
, 39);
1900 res
= RegDeleteTreeW(instance_key
, buf
);
1903 RegCloseKey(instance_key
);
1904 RegCloseKey(categories_key
);
1906 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1907 res
= RegDeleteTreeW(coclass_key
, buf
);
1909 RegCloseKey(coclass_key
);
1911 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1914 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
1915 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
1917 HRESULT WINAPI
DllRegisterServer(void)
1923 hr
= WIC_DllRegisterServer();
1925 hr
= register_categories(category_list
);
1927 hr
= register_decoders(decoder_list
);
1929 hr
= register_encoders(encoder_list
);
1931 hr
= register_converters(converter_list
);
1933 hr
= register_metadatareaders(metadatareader_list
);
1935 hr
= register_pixelformats(pixelformat_list
);
1939 HRESULT WINAPI
DllUnregisterServer(void)
1945 hr
= WIC_DllUnregisterServer();
1947 hr
= unregister_categories(category_list
);
1949 hr
= unregister_decoders(decoder_list
);
1951 hr
= unregister_encoders(encoder_list
);
1953 hr
= unregister_converters(converter_list
);
1955 hr
= unregister_metadatareaders(metadatareader_list
);
1957 hr
= unregister_pixelformats(pixelformat_list
);