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 #include "wincodecs_private.h"
23 /***********************************************************************
24 * interface for self-registering
26 struct decoder_pattern
28 DWORD length
; /* 0 for end of list */
37 CLSID
const *clsid
; /* NULL for end of list */
42 GUID
const *container_format
;
45 GUID
const * const *formats
;
46 const struct decoder_pattern
*patterns
;
49 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
50 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
54 CLSID
const *clsid
; /* NULL for end of list */
59 GUID
const *container_format
;
62 GUID
const * const *formats
;
65 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
66 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
68 struct regsvr_converter
70 CLSID
const *clsid
; /* NULL for end of list */
75 GUID
const * const *formats
;
78 static HRESULT
register_converters(struct regsvr_converter
const *list
);
79 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
81 struct metadata_pattern
90 struct reader_containers
93 const struct metadata_pattern
*patterns
;
96 struct regsvr_metadatareader
98 CLSID
const *clsid
; /* NULL for end of list */
104 GUID
const *metadata_format
;
105 DWORD requires_fullstream
;
106 DWORD supports_padding
;
107 DWORD requires_fixedsize
;
108 const struct reader_containers
*containers
;
111 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
112 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
114 struct regsvr_pixelformat
116 CLSID
const *clsid
; /* NULL for end of list */
123 BYTE
const * const *channelmasks
;
124 WICPixelFormatNumericRepresentation numericrepresentation
;
128 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
);
129 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
);
131 /***********************************************************************
132 * static string constants
134 static const WCHAR clsid_keyname
[] = {
135 'C', 'L', 'S', 'I', 'D', 0 };
136 static const char author_valuename
[] = "Author";
137 static const char friendlyname_valuename
[] = "FriendlyName";
138 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
139 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
140 static const char version_valuename
[] = "Version";
141 static const char mimetypes_valuename
[] = "MimeTypes";
142 static const char extensions_valuename
[] = "FileExtensions";
143 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
144 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
145 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
146 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
147 static const char length_valuename
[] = "Length";
148 static const char position_valuename
[] = "Position";
149 static const char pattern_valuename
[] = "Pattern";
150 static const char mask_valuename
[] = "Mask";
151 static const char endofstream_valuename
[] = "EndOfStream";
152 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
153 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
154 static const char specversion_valuename
[] = "SpecVersion";
155 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
156 static const char supportspadding_valuename
[] = "SupportsPadding";
157 static const char requiresfixedsize_valuename
[] = "FixedSize";
158 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
159 static const char dataoffset_valuename
[] = "DataOffset";
160 static const char bitsperpixel_valuename
[] = "BitLength";
161 static const char channelcount_valuename
[] = "ChannelCount";
162 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
163 static const char supportstransparency_valuename
[] = "SupportsTransparency";
164 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
166 /***********************************************************************
169 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
171 LONG res
= ERROR_SUCCESS
;
177 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
178 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
179 if (res
== ERROR_SUCCESS
) {
180 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
181 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
182 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
183 if (res
== ERROR_SUCCESS
)
185 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
186 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
187 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
189 if (res
!= ERROR_SUCCESS
)
190 RegCloseKey(coclass_key
);
192 if (res
!= ERROR_SUCCESS
) goto error_return
;
194 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
196 HKEY instance_clsid_key
;
198 StringFromGUID2(list
->clsid
, buf
, 39);
199 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
200 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
201 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
203 StringFromGUID2(list
->clsid
, buf
, 39);
204 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
205 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
206 if (res
== ERROR_SUCCESS
) {
207 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
208 (const BYTE
*)buf
, 78);
209 RegCloseKey(instance_clsid_key
);
211 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
214 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
215 (const BYTE
*)list
->author
,
216 strlen(list
->author
) + 1);
217 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
220 if (list
->friendlyname
) {
221 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
222 (const BYTE
*)list
->friendlyname
,
223 strlen(list
->friendlyname
) + 1);
224 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
228 StringFromGUID2(list
->vendor
, buf
, 39);
229 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
230 (const BYTE
*)buf
, 78);
231 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
234 if (list
->container_format
) {
235 StringFromGUID2(list
->container_format
, buf
, 39);
236 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
237 (const BYTE
*)buf
, 78);
238 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
242 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
243 (const BYTE
*)list
->version
,
244 strlen(list
->version
) + 1);
245 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
248 if (list
->mimetypes
) {
249 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
250 (const BYTE
*)list
->mimetypes
,
251 strlen(list
->mimetypes
) + 1);
252 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
255 if (list
->extensions
) {
256 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
257 (const BYTE
*)list
->extensions
,
258 strlen(list
->extensions
) + 1);
259 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
264 GUID
const * const *format
;
266 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
267 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
268 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
269 for (format
=list
->formats
; *format
; ++format
)
272 StringFromGUID2(*format
, buf
, 39);
273 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
274 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
275 if (res
!= ERROR_SUCCESS
) break;
276 RegCloseKey(format_key
);
278 RegCloseKey(formats_key
);
279 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
282 if (list
->patterns
) {
286 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
287 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
288 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
289 for (i
=0; list
->patterns
[i
].length
; i
++)
292 static const WCHAR int_format
[] = {'%','i',0};
293 snprintfW(buf
, 39, int_format
, i
);
294 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
295 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
296 if (res
!= ERROR_SUCCESS
) break;
297 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
298 (const BYTE
*)&list
->patterns
[i
].length
, 4);
299 if (res
== ERROR_SUCCESS
)
300 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
301 (const BYTE
*)&list
->patterns
[i
].position
, 4);
302 if (res
== ERROR_SUCCESS
)
303 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
304 list
->patterns
[i
].pattern
,
305 list
->patterns
[i
].length
);
306 if (res
== ERROR_SUCCESS
)
307 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
308 list
->patterns
[i
].mask
,
309 list
->patterns
[i
].length
);
310 if (res
== ERROR_SUCCESS
)
311 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
312 (const BYTE
*)&list
->patterns
[i
].endofstream
, 4);
313 RegCloseKey(pattern_key
);
315 RegCloseKey(patterns_key
);
316 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
319 error_close_clsid_key
:
320 RegCloseKey(clsid_key
);
323 error_close_coclass_key
:
324 RegCloseKey(instance_key
);
325 RegCloseKey(decoders_key
);
326 RegCloseKey(coclass_key
);
328 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
331 /***********************************************************************
332 * unregister_decoders
334 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
336 LONG res
= ERROR_SUCCESS
;
342 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
343 KEY_READ
| KEY_WRITE
, &coclass_key
);
344 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
346 if (res
== ERROR_SUCCESS
) {
347 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
348 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
349 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
350 if (res
== ERROR_SUCCESS
)
352 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
353 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
354 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
356 if (res
!= ERROR_SUCCESS
)
357 RegCloseKey(coclass_key
);
359 if (res
!= ERROR_SUCCESS
) goto error_return
;
361 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
362 StringFromGUID2(list
->clsid
, buf
, 39);
364 res
= RegDeleteTreeW(coclass_key
, buf
);
365 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
366 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
368 res
= RegDeleteTreeW(instance_key
, buf
);
369 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
370 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
373 error_close_coclass_key
:
374 RegCloseKey(instance_key
);
375 RegCloseKey(decoders_key
);
376 RegCloseKey(coclass_key
);
378 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
381 /***********************************************************************
384 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
386 LONG res
= ERROR_SUCCESS
;
392 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
393 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
394 if (res
== ERROR_SUCCESS
) {
395 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
396 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
397 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
398 if (res
== ERROR_SUCCESS
)
400 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
401 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
402 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
404 if (res
!= ERROR_SUCCESS
)
405 RegCloseKey(coclass_key
);
407 if (res
!= ERROR_SUCCESS
) goto error_return
;
409 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
411 HKEY instance_clsid_key
;
413 StringFromGUID2(list
->clsid
, buf
, 39);
414 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
415 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
416 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
418 StringFromGUID2(list
->clsid
, buf
, 39);
419 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
420 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
421 if (res
== ERROR_SUCCESS
) {
422 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
423 (const BYTE
*)buf
, 78);
424 RegCloseKey(instance_clsid_key
);
426 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
429 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
430 (const BYTE
*)list
->author
,
431 strlen(list
->author
) + 1);
432 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
435 if (list
->friendlyname
) {
436 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
437 (const BYTE
*)list
->friendlyname
,
438 strlen(list
->friendlyname
) + 1);
439 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
443 StringFromGUID2(list
->vendor
, buf
, 39);
444 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
445 (const BYTE
*)buf
, 78);
446 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
449 if (list
->container_format
) {
450 StringFromGUID2(list
->container_format
, buf
, 39);
451 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
452 (const BYTE
*)buf
, 78);
453 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
457 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
458 (const BYTE
*)list
->version
,
459 strlen(list
->version
) + 1);
460 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
463 if (list
->mimetypes
) {
464 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
465 (const BYTE
*)list
->mimetypes
,
466 strlen(list
->mimetypes
) + 1);
467 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
470 if (list
->extensions
) {
471 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
472 (const BYTE
*)list
->extensions
,
473 strlen(list
->extensions
) + 1);
474 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
479 GUID
const * const *format
;
481 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
482 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
483 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
484 for (format
=list
->formats
; *format
; ++format
)
487 StringFromGUID2(*format
, buf
, 39);
488 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
489 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
490 if (res
!= ERROR_SUCCESS
) break;
491 RegCloseKey(format_key
);
493 RegCloseKey(formats_key
);
494 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
497 error_close_clsid_key
:
498 RegCloseKey(clsid_key
);
501 error_close_coclass_key
:
502 RegCloseKey(instance_key
);
503 RegCloseKey(encoders_key
);
504 RegCloseKey(coclass_key
);
506 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
509 /***********************************************************************
510 * unregister_encoders
512 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
514 LONG res
= ERROR_SUCCESS
;
520 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
521 KEY_READ
| KEY_WRITE
, &coclass_key
);
522 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
524 if (res
== ERROR_SUCCESS
) {
525 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
526 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
527 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
528 if (res
== ERROR_SUCCESS
)
530 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
531 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
532 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
534 if (res
!= ERROR_SUCCESS
)
535 RegCloseKey(coclass_key
);
537 if (res
!= ERROR_SUCCESS
) goto error_return
;
539 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
540 StringFromGUID2(list
->clsid
, buf
, 39);
542 res
= RegDeleteTreeW(coclass_key
, buf
);
543 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
544 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
546 res
= RegDeleteTreeW(instance_key
, buf
);
547 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
548 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
551 error_close_coclass_key
:
552 RegCloseKey(instance_key
);
553 RegCloseKey(encoders_key
);
554 RegCloseKey(coclass_key
);
556 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
559 /***********************************************************************
560 * register_converters
562 static HRESULT
register_converters(struct regsvr_converter
const *list
)
564 LONG res
= ERROR_SUCCESS
;
570 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
571 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
572 if (res
== ERROR_SUCCESS
) {
573 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
574 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
575 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
576 if (res
== ERROR_SUCCESS
)
578 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
579 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
580 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
582 if (res
!= ERROR_SUCCESS
)
583 RegCloseKey(coclass_key
);
585 if (res
!= ERROR_SUCCESS
) goto error_return
;
587 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
589 HKEY instance_clsid_key
;
591 StringFromGUID2(list
->clsid
, buf
, 39);
592 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
593 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
594 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
596 StringFromGUID2(list
->clsid
, buf
, 39);
597 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
598 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
599 if (res
== ERROR_SUCCESS
) {
600 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
601 (const BYTE
*)buf
, 78);
602 RegCloseKey(instance_clsid_key
);
604 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
607 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
608 (const BYTE
*)list
->author
,
609 strlen(list
->author
) + 1);
610 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
613 if (list
->friendlyname
) {
614 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
615 (const BYTE
*)list
->friendlyname
,
616 strlen(list
->friendlyname
) + 1);
617 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
621 StringFromGUID2(list
->vendor
, buf
, 39);
622 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
623 (const BYTE
*)buf
, 78);
624 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
628 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
629 (const BYTE
*)list
->version
,
630 strlen(list
->version
) + 1);
631 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
636 GUID
const * const *format
;
638 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
639 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
640 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
641 for (format
=list
->formats
; *format
; ++format
)
644 StringFromGUID2(*format
, buf
, 39);
645 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
646 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
647 if (res
!= ERROR_SUCCESS
) break;
648 RegCloseKey(format_key
);
650 RegCloseKey(formats_key
);
651 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
654 error_close_clsid_key
:
655 RegCloseKey(clsid_key
);
658 error_close_coclass_key
:
659 RegCloseKey(instance_key
);
660 RegCloseKey(converters_key
);
661 RegCloseKey(coclass_key
);
663 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
666 /***********************************************************************
667 * unregister_converters
669 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
671 LONG res
= ERROR_SUCCESS
;
677 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
678 KEY_READ
| KEY_WRITE
, &coclass_key
);
679 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
681 if (res
== ERROR_SUCCESS
) {
682 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
683 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
684 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
685 if (res
== ERROR_SUCCESS
)
687 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
688 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
689 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
691 if (res
!= ERROR_SUCCESS
)
692 RegCloseKey(coclass_key
);
694 if (res
!= ERROR_SUCCESS
) goto error_return
;
696 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
697 StringFromGUID2(list
->clsid
, buf
, 39);
699 res
= RegDeleteTreeW(coclass_key
, buf
);
700 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
701 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
703 res
= RegDeleteTreeW(instance_key
, buf
);
704 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
705 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
708 error_close_coclass_key
:
709 RegCloseKey(instance_key
);
710 RegCloseKey(converters_key
);
711 RegCloseKey(coclass_key
);
713 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
716 /***********************************************************************
717 * register_metadatareaders
719 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
721 LONG res
= ERROR_SUCCESS
;
727 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
728 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
729 if (res
== ERROR_SUCCESS
) {
730 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
731 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
732 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
733 if (res
== ERROR_SUCCESS
)
735 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
736 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
737 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
739 if (res
!= ERROR_SUCCESS
)
740 RegCloseKey(coclass_key
);
742 if (res
!= ERROR_SUCCESS
) goto error_return
;
744 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
746 HKEY instance_clsid_key
;
748 StringFromGUID2(list
->clsid
, buf
, 39);
749 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
750 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
751 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
753 StringFromGUID2(list
->clsid
, buf
, 39);
754 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
755 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
756 if (res
== ERROR_SUCCESS
) {
757 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
758 (const BYTE
*)buf
, 78);
759 RegCloseKey(instance_clsid_key
);
761 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
764 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
765 (const BYTE
*)list
->author
,
766 strlen(list
->author
) + 1);
767 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
770 if (list
->friendlyname
) {
771 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
772 (const BYTE
*)list
->friendlyname
,
773 strlen(list
->friendlyname
) + 1);
774 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
778 StringFromGUID2(list
->vendor
, buf
, 39);
779 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
780 (const BYTE
*)buf
, 78);
781 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
784 if (list
->metadata_format
) {
785 StringFromGUID2(list
->metadata_format
, buf
, 39);
786 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
787 (const BYTE
*)buf
, 78);
788 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
792 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
793 (const BYTE
*)list
->version
,
794 strlen(list
->version
) + 1);
795 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
798 if (list
->specversion
) {
799 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
800 (const BYTE
*)list
->version
,
801 strlen(list
->version
) + 1);
802 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
805 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
806 (const BYTE
*)&list
->requires_fullstream
, 4);
807 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
809 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
810 (const BYTE
*)&list
->supports_padding
, 4);
811 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
813 if (list
->requires_fixedsize
) {
814 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
815 (const BYTE
*)&list
->requires_fixedsize
, 4);
816 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
819 if (list
->containers
) {
821 const struct reader_containers
*container
;
823 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
824 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
825 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
826 for (container
=list
->containers
; container
->format
; ++container
)
830 StringFromGUID2(container
->format
, buf
, 39);
831 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
832 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
833 if (res
!= ERROR_SUCCESS
) break;
835 for (i
=0; container
->patterns
[i
].length
; i
++)
838 static const WCHAR int_format
[] = {'%','i',0};
839 snprintfW(buf
, 39, int_format
, i
);
840 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
841 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
842 if (res
!= ERROR_SUCCESS
) break;
843 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
844 (const BYTE
*)&container
->patterns
[i
].position
, 4);
845 if (res
== ERROR_SUCCESS
)
846 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
847 container
->patterns
[i
].pattern
,
848 container
->patterns
[i
].length
);
849 if (res
== ERROR_SUCCESS
)
850 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
851 container
->patterns
[i
].mask
,
852 container
->patterns
[i
].length
);
853 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
854 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
855 (const BYTE
*)&container
->patterns
[i
].data_offset
, 4);
856 RegCloseKey(pattern_key
);
859 RegCloseKey(format_key
);
861 RegCloseKey(containers_key
);
864 error_close_clsid_key
:
865 RegCloseKey(clsid_key
);
868 error_close_coclass_key
:
869 RegCloseKey(instance_key
);
870 RegCloseKey(readers_key
);
871 RegCloseKey(coclass_key
);
873 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
876 /***********************************************************************
877 * unregister_metadatareaders
879 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
881 LONG res
= ERROR_SUCCESS
;
887 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
888 KEY_READ
| KEY_WRITE
, &coclass_key
);
889 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
891 if (res
== ERROR_SUCCESS
) {
892 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
893 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
894 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
895 if (res
== ERROR_SUCCESS
)
897 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
898 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
899 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
901 if (res
!= ERROR_SUCCESS
)
902 RegCloseKey(coclass_key
);
904 if (res
!= ERROR_SUCCESS
) goto error_return
;
906 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
907 StringFromGUID2(list
->clsid
, buf
, 39);
909 res
= RegDeleteTreeW(coclass_key
, buf
);
910 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
911 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
913 res
= RegDeleteTreeW(instance_key
, buf
);
914 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
915 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
918 error_close_coclass_key
:
919 RegCloseKey(instance_key
);
920 RegCloseKey(readers_key
);
921 RegCloseKey(coclass_key
);
923 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
926 /***********************************************************************
927 * register_pixelformats
929 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
931 LONG res
= ERROR_SUCCESS
;
937 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
938 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
939 if (res
== ERROR_SUCCESS
) {
940 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
941 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
942 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
943 if (res
== ERROR_SUCCESS
)
945 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
946 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
947 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
949 if (res
!= ERROR_SUCCESS
)
950 RegCloseKey(coclass_key
);
952 if (res
!= ERROR_SUCCESS
) goto error_return
;
954 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
956 HKEY instance_clsid_key
;
958 StringFromGUID2(list
->clsid
, buf
, 39);
959 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
960 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
961 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
963 StringFromGUID2(list
->clsid
, buf
, 39);
964 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
965 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
966 if (res
== ERROR_SUCCESS
) {
967 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
968 (const BYTE
*)buf
, 78);
969 RegCloseKey(instance_clsid_key
);
971 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
974 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
975 (const BYTE
*)list
->author
,
976 strlen(list
->author
) + 1);
977 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
980 if (list
->friendlyname
) {
981 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
982 (const BYTE
*)list
->friendlyname
,
983 strlen(list
->friendlyname
) + 1);
984 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
988 StringFromGUID2(list
->vendor
, buf
, 39);
989 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
990 (const BYTE
*)buf
, 78);
991 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
995 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
996 (const BYTE
*)list
->version
,
997 strlen(list
->version
) + 1);
998 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1001 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1002 (const BYTE
*)&list
->bitsperpixel
, 4);
1003 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1005 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1006 (const BYTE
*)&list
->channelcount
, 4);
1007 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1009 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1010 (const BYTE
*)&list
->numericrepresentation
, 4);
1011 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1013 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1014 (const BYTE
*)&list
->supportsalpha
, 4);
1015 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1017 if (list
->channelmasks
) {
1020 WCHAR mask_valuename
[11];
1021 const WCHAR valuename_format
[] = {'%','d',0};
1023 mask_size
= (list
->bitsperpixel
+ 7)/8;
1025 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1026 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1027 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1028 for (i
=0; i
< list
->channelcount
; i
++)
1030 sprintfW(mask_valuename
, valuename_format
, i
);
1031 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1032 list
->channelmasks
[i
], mask_size
);
1033 if (res
!= ERROR_SUCCESS
) break;
1035 RegCloseKey(masks_key
);
1036 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1039 error_close_clsid_key
:
1040 RegCloseKey(clsid_key
);
1043 error_close_coclass_key
:
1044 RegCloseKey(instance_key
);
1045 RegCloseKey(formats_key
);
1046 RegCloseKey(coclass_key
);
1048 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1051 /***********************************************************************
1052 * unregister_pixelformats
1054 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1056 LONG res
= ERROR_SUCCESS
;
1062 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1063 KEY_READ
| KEY_WRITE
, &coclass_key
);
1064 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1066 if (res
== ERROR_SUCCESS
) {
1067 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1068 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1069 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1070 if (res
== ERROR_SUCCESS
)
1072 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1073 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1074 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1076 if (res
!= ERROR_SUCCESS
)
1077 RegCloseKey(coclass_key
);
1079 if (res
!= ERROR_SUCCESS
) goto error_return
;
1081 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1082 StringFromGUID2(list
->clsid
, buf
, 39);
1084 res
= RegDeleteTreeW(coclass_key
, buf
);
1085 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1086 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1088 res
= RegDeleteTreeW(instance_key
, buf
);
1089 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1090 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1093 error_close_coclass_key
:
1094 RegCloseKey(instance_key
);
1095 RegCloseKey(formats_key
);
1096 RegCloseKey(coclass_key
);
1098 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1101 /***********************************************************************
1104 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1106 static const BYTE bmp_magic
[] = {0x42,0x4d};
1108 static GUID
const * const bmp_formats
[] = {
1109 &GUID_WICPixelFormat1bppIndexed
,
1110 &GUID_WICPixelFormat2bppIndexed
,
1111 &GUID_WICPixelFormat4bppIndexed
,
1112 &GUID_WICPixelFormat8bppIndexed
,
1113 &GUID_WICPixelFormat16bppBGR555
,
1114 &GUID_WICPixelFormat16bppBGR565
,
1115 &GUID_WICPixelFormat24bppBGR
,
1116 &GUID_WICPixelFormat32bppBGR
,
1117 &GUID_WICPixelFormat32bppBGRA
,
1121 static struct decoder_pattern
const bmp_patterns
[] = {
1122 {2,0,bmp_magic
,mask_all
,0},
1126 static const BYTE gif87a_magic
[6] = "GIF87a";
1127 static const BYTE gif89a_magic
[6] = "GIF89a";
1129 static GUID
const * const gif_formats
[] = {
1130 &GUID_WICPixelFormat8bppIndexed
,
1134 static struct decoder_pattern
const gif_patterns
[] = {
1135 {6,0,gif87a_magic
,mask_all
,0},
1136 {6,0,gif89a_magic
,mask_all
,0},
1140 static const BYTE ico_magic
[] = {00,00,01,00};
1142 static GUID
const * const ico_formats
[] = {
1143 &GUID_WICPixelFormat32bppBGRA
,
1147 static struct decoder_pattern
const ico_patterns
[] = {
1148 {4,0,ico_magic
,mask_all
,0},
1152 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1154 static GUID
const * const jpeg_formats
[] = {
1155 &GUID_WICPixelFormat24bppBGR
,
1156 &GUID_WICPixelFormat32bppCMYK
,
1157 &GUID_WICPixelFormat8bppGray
,
1161 static struct decoder_pattern
const jpeg_patterns
[] = {
1162 {2,0,jpeg_magic
,mask_all
,0},
1166 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1168 static GUID
const * const png_formats
[] = {
1169 &GUID_WICPixelFormatBlackWhite
,
1170 &GUID_WICPixelFormat2bppGray
,
1171 &GUID_WICPixelFormat4bppGray
,
1172 &GUID_WICPixelFormat8bppGray
,
1173 &GUID_WICPixelFormat16bppGray
,
1174 &GUID_WICPixelFormat32bppBGRA
,
1175 &GUID_WICPixelFormat64bppRGBA
,
1176 &GUID_WICPixelFormat1bppIndexed
,
1177 &GUID_WICPixelFormat2bppIndexed
,
1178 &GUID_WICPixelFormat4bppIndexed
,
1179 &GUID_WICPixelFormat8bppIndexed
,
1180 &GUID_WICPixelFormat24bppBGR
,
1181 &GUID_WICPixelFormat48bppRGB
,
1185 static struct decoder_pattern
const png_patterns
[] = {
1186 {8,0,png_magic
,mask_all
,0},
1190 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1191 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1193 static GUID
const * const tiff_decode_formats
[] = {
1194 &GUID_WICPixelFormatBlackWhite
,
1195 &GUID_WICPixelFormat4bppGray
,
1196 &GUID_WICPixelFormat8bppGray
,
1197 &GUID_WICPixelFormat4bppIndexed
,
1198 &GUID_WICPixelFormat8bppIndexed
,
1199 &GUID_WICPixelFormat24bppBGR
,
1200 &GUID_WICPixelFormat32bppBGR
,
1201 &GUID_WICPixelFormat32bppBGRA
,
1202 &GUID_WICPixelFormat32bppPBGRA
,
1203 &GUID_WICPixelFormat48bppRGB
,
1204 &GUID_WICPixelFormat64bppRGBA
,
1205 &GUID_WICPixelFormat64bppPRGBA
,
1209 static struct decoder_pattern
const tiff_patterns
[] = {
1210 {4,0,tiff_magic_le
,mask_all
,0},
1211 {4,0,tiff_magic_be
,mask_all
,0},
1215 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1217 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};
1218 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};
1220 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};
1221 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};
1223 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};
1224 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};
1226 static GUID
const * const tga_formats
[] = {
1227 &GUID_WICPixelFormat8bppGray
,
1228 &GUID_WICPixelFormat8bppIndexed
,
1229 &GUID_WICPixelFormat16bppGray
,
1230 &GUID_WICPixelFormat16bppBGR555
,
1231 &GUID_WICPixelFormat24bppBGR
,
1232 &GUID_WICPixelFormat32bppBGRA
,
1233 &GUID_WICPixelFormat32bppPBGRA
,
1237 static struct decoder_pattern
const tga_patterns
[] = {
1238 {18,18,tga_footer_magic
,mask_all
,1},
1239 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1240 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1241 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1245 static struct regsvr_decoder
const decoder_list
[] = {
1246 { &CLSID_WICBmpDecoder
,
1250 &GUID_VendorMicrosoft
,
1251 &GUID_ContainerFormatBmp
,
1257 { &CLSID_WICGifDecoder
,
1261 &GUID_VendorMicrosoft
,
1262 &GUID_ContainerFormatGif
,
1268 { &CLSID_WICIcoDecoder
,
1272 &GUID_VendorMicrosoft
,
1273 &GUID_ContainerFormatIco
,
1274 "image/vnd.microsoft.icon",
1279 { &CLSID_WICJpegDecoder
,
1283 &GUID_VendorMicrosoft
,
1284 &GUID_ContainerFormatJpeg
,
1290 { &CLSID_WICPngDecoder
,
1294 &GUID_VendorMicrosoft
,
1295 &GUID_ContainerFormatPng
,
1301 { &CLSID_WICTiffDecoder
,
1305 &GUID_VendorMicrosoft
,
1306 &GUID_ContainerFormatTiff
,
1309 tiff_decode_formats
,
1312 { &CLSID_WineTgaDecoder
,
1317 &GUID_WineContainerFormatTga
,
1323 { NULL
} /* list terminator */
1326 static GUID
const * const bmp_encode_formats
[] = {
1327 &GUID_WICPixelFormat16bppBGR555
,
1328 &GUID_WICPixelFormat16bppBGR565
,
1329 &GUID_WICPixelFormat24bppBGR
,
1330 &GUID_WICPixelFormat32bppBGR
,
1334 static GUID
const * const png_encode_formats
[] = {
1335 &GUID_WICPixelFormat24bppBGR
,
1336 &GUID_WICPixelFormatBlackWhite
,
1337 &GUID_WICPixelFormat2bppGray
,
1338 &GUID_WICPixelFormat4bppGray
,
1339 &GUID_WICPixelFormat8bppGray
,
1340 &GUID_WICPixelFormat16bppGray
,
1341 &GUID_WICPixelFormat32bppBGR
,
1342 &GUID_WICPixelFormat32bppBGRA
,
1343 &GUID_WICPixelFormat48bppRGB
,
1344 &GUID_WICPixelFormat64bppRGBA
,
1348 static GUID
const * const tiff_encode_formats
[] = {
1349 &GUID_WICPixelFormatBlackWhite
,
1350 &GUID_WICPixelFormat4bppGray
,
1351 &GUID_WICPixelFormat8bppGray
,
1352 &GUID_WICPixelFormat24bppBGR
,
1353 &GUID_WICPixelFormat32bppBGRA
,
1354 &GUID_WICPixelFormat32bppPBGRA
,
1355 &GUID_WICPixelFormat48bppRGB
,
1356 &GUID_WICPixelFormat64bppRGBA
,
1357 &GUID_WICPixelFormat64bppPRGBA
,
1361 static GUID
const * const icns_encode_formats
[] = {
1362 &GUID_WICPixelFormat32bppBGRA
,
1366 static struct regsvr_encoder
const encoder_list
[] = {
1367 { &CLSID_WICBmpEncoder
,
1371 &GUID_VendorMicrosoft
,
1372 &GUID_ContainerFormatBmp
,
1377 { &CLSID_WICJpegEncoder
,
1381 &GUID_VendorMicrosoft
,
1382 &GUID_ContainerFormatJpeg
,
1387 { &CLSID_WICPngEncoder
,
1391 &GUID_VendorMicrosoft
,
1392 &GUID_ContainerFormatPng
,
1397 { &CLSID_WICTiffEncoder
,
1401 &GUID_VendorMicrosoft
,
1402 &GUID_ContainerFormatTiff
,
1407 { &CLSID_WICIcnsEncoder
,
1412 NULL
, /* no container format guid */
1417 { NULL
} /* list terminator */
1420 static GUID
const * const converter_formats
[] = {
1421 &GUID_WICPixelFormat1bppIndexed
,
1422 &GUID_WICPixelFormat2bppIndexed
,
1423 &GUID_WICPixelFormat4bppIndexed
,
1424 &GUID_WICPixelFormat8bppIndexed
,
1425 &GUID_WICPixelFormatBlackWhite
,
1426 &GUID_WICPixelFormat2bppGray
,
1427 &GUID_WICPixelFormat4bppGray
,
1428 &GUID_WICPixelFormat8bppGray
,
1429 &GUID_WICPixelFormat16bppGray
,
1430 &GUID_WICPixelFormat16bppBGR555
,
1431 &GUID_WICPixelFormat16bppBGR565
,
1432 &GUID_WICPixelFormat16bppBGRA5551
,
1433 &GUID_WICPixelFormat24bppBGR
,
1434 &GUID_WICPixelFormat24bppRGB
,
1435 &GUID_WICPixelFormat32bppBGR
,
1436 &GUID_WICPixelFormat32bppBGRA
,
1437 &GUID_WICPixelFormat32bppPBGRA
,
1438 &GUID_WICPixelFormat48bppRGB
,
1439 &GUID_WICPixelFormat64bppRGBA
,
1440 &GUID_WICPixelFormat32bppCMYK
,
1444 static struct regsvr_converter
const converter_list
[] = {
1445 { &CLSID_WICDefaultFormatConverter
,
1447 "Default Pixel Format Converter",
1449 &GUID_VendorMicrosoft
,
1452 { NULL
} /* list terminator */
1455 static const BYTE no_magic
[1] = { 0 };
1456 static const BYTE no_mask
[1] = { 0 };
1458 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1459 { 0, 1, no_magic
, no_mask
, 0 },
1463 static const struct reader_containers ifd_containers
[] = {
1465 &GUID_ContainerFormatTiff
,
1466 ifd_metadata_pattern
1468 { NULL
} /* list terminator */
1471 static const BYTE tEXt
[] = "tEXt";
1473 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1474 { 4, 4, tEXt
, mask_all
, 4 },
1478 static const struct reader_containers pngtext_containers
[] = {
1480 &GUID_ContainerFormatPng
,
1481 pngtext_metadata_pattern
1483 { NULL
} /* list terminator */
1486 static const BYTE gAMA
[] = "gAMA";
1488 static const struct metadata_pattern pnggama_metadata_pattern
[] = {
1489 { 4, 4, gAMA
, mask_all
, 4 },
1493 static const struct reader_containers pnggama_containers
[] = {
1495 &GUID_ContainerFormatPng
,
1496 pnggama_metadata_pattern
1498 { NULL
} /* list terminator */
1501 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1502 { 0, 6, gif87a_magic
, mask_all
, 0 },
1503 { 0, 6, gif89a_magic
, mask_all
, 0 },
1507 static const struct reader_containers lsd_containers
[] = {
1509 &GUID_ContainerFormatGif
,
1510 lsd_metadata_patterns
1512 { NULL
} /* list terminator */
1515 static const BYTE imd_magic
[] = { 0x2c };
1517 static const struct metadata_pattern imd_metadata_pattern
[] = {
1518 { 0, 1, imd_magic
, mask_all
, 1 },
1522 static const struct reader_containers imd_containers
[] = {
1524 &GUID_ContainerFormatGif
,
1525 imd_metadata_pattern
1527 { NULL
} /* list terminator */
1530 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1532 static const struct metadata_pattern gce_metadata_pattern
[] = {
1533 { 0, 3, gce_magic
, mask_all
, 3 },
1537 static const struct reader_containers gce_containers
[] = {
1539 &GUID_ContainerFormatGif
,
1540 gce_metadata_pattern
1542 { NULL
} /* list terminator */
1545 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1547 static const struct metadata_pattern ape_metadata_pattern
[] = {
1548 { 0, 3, ape_magic
, mask_all
, 0 },
1552 static const struct reader_containers ape_containers
[] = {
1554 &GUID_ContainerFormatGif
,
1555 ape_metadata_pattern
1557 { NULL
} /* list terminator */
1560 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1562 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1563 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1567 static const struct reader_containers gif_comment_containers
[] = {
1569 &GUID_ContainerFormatGif
,
1570 gif_comment_metadata_pattern
1572 { NULL
} /* list terminator */
1575 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1576 { &CLSID_WICUnknownMetadataReader
,
1578 "Unknown Metadata Reader",
1581 &GUID_VendorMicrosoft
,
1582 &GUID_MetadataFormatUnknown
,
1586 { &CLSID_WICIfdMetadataReader
,
1591 &GUID_VendorMicrosoft
,
1592 &GUID_MetadataFormatIfd
,
1596 { &CLSID_WICPngGamaMetadataReader
,
1598 "Chunk gAMA Reader",
1601 &GUID_VendorMicrosoft
,
1602 &GUID_MetadataFormatChunkgAMA
,
1606 { &CLSID_WICPngTextMetadataReader
,
1608 "Chunk tEXt Reader",
1611 &GUID_VendorMicrosoft
,
1612 &GUID_MetadataFormatChunktEXt
,
1616 { &CLSID_WICLSDMetadataReader
,
1618 "Logical Screen Descriptor Reader",
1621 &GUID_VendorMicrosoft
,
1622 &GUID_MetadataFormatLSD
,
1626 { &CLSID_WICIMDMetadataReader
,
1628 "Image Descriptor Reader",
1631 &GUID_VendorMicrosoft
,
1632 &GUID_MetadataFormatIMD
,
1636 { &CLSID_WICGCEMetadataReader
,
1638 "Graphic Control Extension Reader",
1641 &GUID_VendorMicrosoft
,
1642 &GUID_MetadataFormatGCE
,
1646 { &CLSID_WICAPEMetadataReader
,
1648 "Application Extension Reader",
1651 &GUID_VendorMicrosoft
,
1652 &GUID_MetadataFormatAPE
,
1656 { &CLSID_WICGifCommentMetadataReader
,
1658 "Comment Extension Reader",
1661 &GUID_VendorMicrosoft
,
1662 &GUID_MetadataFormatGifComment
,
1664 gif_comment_containers
1666 { NULL
} /* list terminator */
1669 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1670 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1671 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1673 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1674 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1675 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1676 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1678 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1679 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1680 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1681 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1683 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1684 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1685 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1686 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1688 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1689 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1691 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1692 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1693 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1694 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1695 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1696 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1697 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1699 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1700 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1702 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1703 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1705 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1706 { &GUID_WICPixelFormat1bppIndexed
,
1709 NULL
, /* no version */
1710 &GUID_VendorMicrosoft
,
1711 1, /* bitsperpixel */
1712 1, /* channel count */
1714 WICPixelFormatNumericRepresentationIndexed
,
1717 { &GUID_WICPixelFormat2bppIndexed
,
1720 NULL
, /* no version */
1721 &GUID_VendorMicrosoft
,
1722 2, /* bitsperpixel */
1723 1, /* channel count */
1725 WICPixelFormatNumericRepresentationIndexed
,
1728 { &GUID_WICPixelFormat4bppIndexed
,
1731 NULL
, /* no version */
1732 &GUID_VendorMicrosoft
,
1733 4, /* bitsperpixel */
1734 1, /* channel count */
1736 WICPixelFormatNumericRepresentationIndexed
,
1739 { &GUID_WICPixelFormat8bppIndexed
,
1742 NULL
, /* no version */
1743 &GUID_VendorMicrosoft
,
1744 8, /* bitsperpixel */
1745 1, /* channel count */
1747 WICPixelFormatNumericRepresentationIndexed
,
1750 { &GUID_WICPixelFormatBlackWhite
,
1753 NULL
, /* no version */
1754 &GUID_VendorMicrosoft
,
1755 1, /* bitsperpixel */
1756 1, /* channel count */
1758 WICPixelFormatNumericRepresentationUnsignedInteger
,
1761 { &GUID_WICPixelFormat2bppGray
,
1764 NULL
, /* no version */
1765 &GUID_VendorMicrosoft
,
1766 2, /* bitsperpixel */
1767 1, /* channel count */
1769 WICPixelFormatNumericRepresentationUnsignedInteger
,
1772 { &GUID_WICPixelFormat4bppGray
,
1775 NULL
, /* no version */
1776 &GUID_VendorMicrosoft
,
1777 4, /* bitsperpixel */
1778 1, /* channel count */
1780 WICPixelFormatNumericRepresentationUnsignedInteger
,
1783 { &GUID_WICPixelFormat8bppGray
,
1786 NULL
, /* no version */
1787 &GUID_VendorMicrosoft
,
1788 8, /* bitsperpixel */
1789 1, /* channel count */
1791 WICPixelFormatNumericRepresentationUnsignedInteger
,
1794 { &GUID_WICPixelFormat16bppGray
,
1797 NULL
, /* no version */
1798 &GUID_VendorMicrosoft
,
1799 16, /* bitsperpixel */
1800 1, /* channel count */
1801 channel_masks_16bit
,
1802 WICPixelFormatNumericRepresentationUnsignedInteger
,
1805 { &GUID_WICPixelFormat16bppBGR555
,
1808 NULL
, /* no version */
1809 &GUID_VendorMicrosoft
,
1810 16, /* bitsperpixel */
1811 3, /* channel count */
1812 channel_masks_BGRA5551
,
1813 WICPixelFormatNumericRepresentationUnsignedInteger
,
1816 { &GUID_WICPixelFormat16bppBGR565
,
1819 NULL
, /* no version */
1820 &GUID_VendorMicrosoft
,
1821 16, /* bitsperpixel */
1822 3, /* channel count */
1823 channel_masks_BGR565
,
1824 WICPixelFormatNumericRepresentationUnsignedInteger
,
1827 { &GUID_WICPixelFormat16bppBGRA5551
,
1830 NULL
, /* no version */
1831 &GUID_VendorMicrosoft
,
1832 16, /* bitsperpixel */
1833 4, /* channel count */
1834 channel_masks_BGRA5551
,
1835 WICPixelFormatNumericRepresentationUnsignedInteger
,
1838 { &GUID_WICPixelFormat24bppBGR
,
1841 NULL
, /* no version */
1842 &GUID_VendorMicrosoft
,
1843 24, /* bitsperpixel */
1844 3, /* channel count */
1846 WICPixelFormatNumericRepresentationUnsignedInteger
,
1849 { &GUID_WICPixelFormat24bppRGB
,
1852 NULL
, /* no version */
1853 &GUID_VendorMicrosoft
,
1854 24, /* bitsperpixel */
1855 3, /* channel count */
1857 WICPixelFormatNumericRepresentationUnsignedInteger
,
1860 { &GUID_WICPixelFormat32bppBGR
,
1863 NULL
, /* no version */
1864 &GUID_VendorMicrosoft
,
1865 32, /* bitsperpixel */
1866 3, /* channel count */
1868 WICPixelFormatNumericRepresentationUnsignedInteger
,
1871 { &GUID_WICPixelFormat32bppBGRA
,
1874 NULL
, /* no version */
1875 &GUID_VendorMicrosoft
,
1876 32, /* bitsperpixel */
1877 4, /* channel count */
1879 WICPixelFormatNumericRepresentationUnsignedInteger
,
1882 { &GUID_WICPixelFormat32bppPBGRA
,
1885 NULL
, /* no version */
1886 &GUID_VendorMicrosoft
,
1887 32, /* bitsperpixel */
1888 4, /* channel count */
1890 WICPixelFormatNumericRepresentationUnsignedInteger
,
1893 { &GUID_WICPixelFormat48bppRGB
,
1896 NULL
, /* no version */
1897 &GUID_VendorMicrosoft
,
1898 48, /* bitsperpixel */
1899 3, /* channel count */
1900 channel_masks_16bit
,
1901 WICPixelFormatNumericRepresentationUnsignedInteger
,
1904 { &GUID_WICPixelFormat64bppRGBA
,
1907 NULL
, /* no version */
1908 &GUID_VendorMicrosoft
,
1909 64, /* bitsperpixel */
1910 4, /* channel count */
1911 channel_masks_16bit
,
1912 WICPixelFormatNumericRepresentationUnsignedInteger
,
1915 { &GUID_WICPixelFormat64bppPRGBA
,
1918 NULL
, /* no version */
1919 &GUID_VendorMicrosoft
,
1920 64, /* bitsperpixel */
1921 4, /* channel count */
1922 channel_masks_16bit
,
1923 WICPixelFormatNumericRepresentationUnsignedInteger
,
1926 { &GUID_WICPixelFormat32bppCMYK
,
1929 NULL
, /* no version */
1930 &GUID_VendorMicrosoft
,
1931 32, /* bitsperpixel */
1932 4, /* channel count */
1934 WICPixelFormatNumericRepresentationUnsignedInteger
,
1937 { NULL
} /* list terminator */
1940 struct regsvr_category
1942 const CLSID
*clsid
; /* NULL for end of list */
1945 static const struct regsvr_category category_list
[] = {
1946 { &CATID_WICBitmapDecoders
},
1947 { &CATID_WICBitmapEncoders
},
1948 { &CATID_WICFormatConverters
},
1949 { &CATID_WICMetadataReader
},
1950 { &CATID_WICPixelFormats
},
1954 static HRESULT
register_categories(const struct regsvr_category
*list
)
1958 HKEY coclass_key
, categories_key
, instance_key
;
1960 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
1961 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
1962 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1964 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1965 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1966 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
1967 if (res
!= ERROR_SUCCESS
)
1969 RegCloseKey(coclass_key
);
1970 return HRESULT_FROM_WIN32(res
);
1973 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
1974 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1976 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
1978 HKEY instance_clsid_key
;
1980 StringFromGUID2(list
->clsid
, buf
, 39);
1981 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
1982 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
1983 if (res
== ERROR_SUCCESS
)
1985 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
1986 (const BYTE
*)buf
, 78);
1987 RegCloseKey(instance_clsid_key
);
1991 RegCloseKey(instance_key
);
1992 RegCloseKey(categories_key
);
1993 RegCloseKey(coclass_key
);
1995 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1998 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
2002 HKEY coclass_key
, categories_key
, instance_key
;
2004 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
2005 KEY_READ
| KEY_WRITE
, &coclass_key
);
2006 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2008 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2009 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
2010 KEY_READ
| KEY_WRITE
, &categories_key
);
2011 if (res
!= ERROR_SUCCESS
)
2013 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2014 RegCloseKey(coclass_key
);
2015 return HRESULT_FROM_WIN32(res
);
2018 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2019 KEY_READ
| KEY_WRITE
, &instance_key
);
2021 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2023 StringFromGUID2(list
->clsid
, buf
, 39);
2024 res
= RegDeleteTreeW(instance_key
, buf
);
2027 RegCloseKey(instance_key
);
2028 RegCloseKey(categories_key
);
2030 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2031 res
= RegDeleteTreeW(coclass_key
, buf
);
2033 RegCloseKey(coclass_key
);
2035 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2038 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2039 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2041 HRESULT WINAPI
DllRegisterServer(void)
2047 hr
= WIC_DllRegisterServer();
2049 hr
= register_categories(category_list
);
2051 hr
= register_decoders(decoder_list
);
2053 hr
= register_encoders(encoder_list
);
2055 hr
= register_converters(converter_list
);
2057 hr
= register_metadatareaders(metadatareader_list
);
2059 hr
= register_pixelformats(pixelformat_list
);
2063 HRESULT WINAPI
DllUnregisterServer(void)
2069 hr
= WIC_DllUnregisterServer();
2071 hr
= unregister_categories(category_list
);
2073 hr
= unregister_decoders(decoder_list
);
2075 hr
= unregister_encoders(encoder_list
);
2077 hr
= unregister_converters(converter_list
);
2079 hr
= unregister_metadatareaders(metadatareader_list
);
2081 hr
= unregister_pixelformats(pixelformat_list
);