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 char author_valuename
[] = "Author";
158 static const char friendlyname_valuename
[] = "FriendlyName";
159 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
160 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
161 static const char version_valuename
[] = "Version";
162 static const char mimetypes_valuename
[] = "MimeTypes";
163 static const char extensions_valuename
[] = "FileExtensions";
164 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
165 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
166 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
167 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
168 static const char length_valuename
[] = "Length";
169 static const char position_valuename
[] = "Position";
170 static const char pattern_valuename
[] = "Pattern";
171 static const char mask_valuename
[] = "Mask";
172 static const char endofstream_valuename
[] = "EndOfStream";
173 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
174 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
175 static const char specversion_valuename
[] = "SpecVersion";
176 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
177 static const char supportspadding_valuename
[] = "SupportsPadding";
178 static const char requiresfixedsize_valuename
[] = "FixedSize";
179 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
180 static const char dataoffset_valuename
[] = "DataOffset";
181 static const char bitsperpixel_valuename
[] = "BitLength";
182 static const char channelcount_valuename
[] = "ChannelCount";
183 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
184 static const char supportstransparency_valuename
[] = "SupportsTransparency";
185 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
187 /***********************************************************************
190 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
192 LONG res
= ERROR_SUCCESS
;
198 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
199 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
200 if (res
== ERROR_SUCCESS
) {
201 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
202 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
203 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
204 if (res
== ERROR_SUCCESS
)
206 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
207 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
208 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
210 if (res
!= ERROR_SUCCESS
)
211 RegCloseKey(coclass_key
);
213 if (res
!= ERROR_SUCCESS
) goto error_return
;
215 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
217 HKEY instance_clsid_key
;
219 StringFromGUID2(list
->clsid
, buf
, 39);
220 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
221 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
222 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
224 StringFromGUID2(list
->clsid
, buf
, 39);
225 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
226 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
227 if (res
== ERROR_SUCCESS
) {
228 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
229 (const BYTE
*)buf
, 78);
230 RegCloseKey(instance_clsid_key
);
232 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
235 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
236 (const BYTE
*)list
->author
,
237 strlen(list
->author
) + 1);
238 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
241 if (list
->friendlyname
) {
242 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
243 (const BYTE
*)list
->friendlyname
,
244 strlen(list
->friendlyname
) + 1);
245 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
249 StringFromGUID2(list
->vendor
, buf
, 39);
250 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
251 (const BYTE
*)buf
, 78);
252 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
255 if (list
->container_format
) {
256 StringFromGUID2(list
->container_format
, buf
, 39);
257 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
258 (const BYTE
*)buf
, 78);
259 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
263 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
264 (const BYTE
*)list
->version
,
265 strlen(list
->version
) + 1);
266 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
269 if (list
->mimetypes
) {
270 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
271 (const BYTE
*)list
->mimetypes
,
272 strlen(list
->mimetypes
) + 1);
273 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
276 if (list
->extensions
) {
277 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
278 (const BYTE
*)list
->extensions
,
279 strlen(list
->extensions
) + 1);
280 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
285 GUID
const * const *format
;
287 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
288 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
289 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
290 for (format
=list
->formats
; *format
; ++format
)
293 StringFromGUID2(*format
, buf
, 39);
294 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
295 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
296 if (res
!= ERROR_SUCCESS
) break;
297 RegCloseKey(format_key
);
299 RegCloseKey(formats_key
);
300 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
303 if (list
->patterns
) {
307 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
308 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
309 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
310 for (i
=0; list
->patterns
[i
].length
; i
++)
313 static const WCHAR int_format
[] = {'%','i',0};
314 snprintfW(buf
, 39, int_format
, i
);
315 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
316 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
317 if (res
!= ERROR_SUCCESS
) break;
318 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
319 (const BYTE
*)&list
->patterns
[i
].length
, 4);
320 if (res
== ERROR_SUCCESS
)
321 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
322 (const BYTE
*)&list
->patterns
[i
].position
, 4);
323 if (res
== ERROR_SUCCESS
)
324 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
325 list
->patterns
[i
].pattern
,
326 list
->patterns
[i
].length
);
327 if (res
== ERROR_SUCCESS
)
328 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
329 list
->patterns
[i
].mask
,
330 list
->patterns
[i
].length
);
331 if (res
== ERROR_SUCCESS
)
332 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
333 (const BYTE
*)&list
->patterns
[i
].endofstream
, 4);
334 RegCloseKey(pattern_key
);
336 RegCloseKey(patterns_key
);
337 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
340 error_close_clsid_key
:
341 RegCloseKey(clsid_key
);
344 error_close_coclass_key
:
345 RegCloseKey(instance_key
);
346 RegCloseKey(decoders_key
);
347 RegCloseKey(coclass_key
);
349 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
352 /***********************************************************************
353 * unregister_decoders
355 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
357 LONG res
= ERROR_SUCCESS
;
363 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
364 KEY_READ
| KEY_WRITE
, &coclass_key
);
365 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
367 if (res
== ERROR_SUCCESS
) {
368 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
369 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
370 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
371 if (res
== ERROR_SUCCESS
)
373 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
374 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
375 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
377 if (res
!= ERROR_SUCCESS
)
378 RegCloseKey(coclass_key
);
380 if (res
!= ERROR_SUCCESS
) goto error_return
;
382 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
383 StringFromGUID2(list
->clsid
, buf
, 39);
385 res
= RegDeleteTreeW(coclass_key
, buf
);
386 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
387 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
389 res
= RegDeleteTreeW(instance_key
, buf
);
390 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
391 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
394 error_close_coclass_key
:
395 RegCloseKey(instance_key
);
396 RegCloseKey(decoders_key
);
397 RegCloseKey(coclass_key
);
399 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
402 /***********************************************************************
405 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
407 LONG res
= ERROR_SUCCESS
;
413 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
414 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
415 if (res
== ERROR_SUCCESS
) {
416 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
417 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
418 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
419 if (res
== ERROR_SUCCESS
)
421 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
422 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
423 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
425 if (res
!= ERROR_SUCCESS
)
426 RegCloseKey(coclass_key
);
428 if (res
!= ERROR_SUCCESS
) goto error_return
;
430 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
432 HKEY instance_clsid_key
;
434 StringFromGUID2(list
->clsid
, buf
, 39);
435 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
436 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
437 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
439 StringFromGUID2(list
->clsid
, buf
, 39);
440 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
441 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
442 if (res
== ERROR_SUCCESS
) {
443 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
444 (const BYTE
*)buf
, 78);
445 RegCloseKey(instance_clsid_key
);
447 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
450 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
451 (const BYTE
*)list
->author
,
452 strlen(list
->author
) + 1);
453 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
456 if (list
->friendlyname
) {
457 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
458 (const BYTE
*)list
->friendlyname
,
459 strlen(list
->friendlyname
) + 1);
460 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
464 StringFromGUID2(list
->vendor
, buf
, 39);
465 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
466 (const BYTE
*)buf
, 78);
467 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
470 if (list
->container_format
) {
471 StringFromGUID2(list
->container_format
, buf
, 39);
472 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
473 (const BYTE
*)buf
, 78);
474 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
478 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
479 (const BYTE
*)list
->version
,
480 strlen(list
->version
) + 1);
481 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
484 if (list
->mimetypes
) {
485 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
486 (const BYTE
*)list
->mimetypes
,
487 strlen(list
->mimetypes
) + 1);
488 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
491 if (list
->extensions
) {
492 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
493 (const BYTE
*)list
->extensions
,
494 strlen(list
->extensions
) + 1);
495 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
500 GUID
const * const *format
;
502 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
503 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
504 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
505 for (format
=list
->formats
; *format
; ++format
)
508 StringFromGUID2(*format
, buf
, 39);
509 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
510 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
511 if (res
!= ERROR_SUCCESS
) break;
512 RegCloseKey(format_key
);
514 RegCloseKey(formats_key
);
515 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
518 error_close_clsid_key
:
519 RegCloseKey(clsid_key
);
522 error_close_coclass_key
:
523 RegCloseKey(instance_key
);
524 RegCloseKey(encoders_key
);
525 RegCloseKey(coclass_key
);
527 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
530 /***********************************************************************
531 * unregister_encoders
533 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
535 LONG res
= ERROR_SUCCESS
;
541 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
542 KEY_READ
| KEY_WRITE
, &coclass_key
);
543 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
545 if (res
== ERROR_SUCCESS
) {
546 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
547 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
548 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
549 if (res
== ERROR_SUCCESS
)
551 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
552 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
553 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
555 if (res
!= ERROR_SUCCESS
)
556 RegCloseKey(coclass_key
);
558 if (res
!= ERROR_SUCCESS
) goto error_return
;
560 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
561 StringFromGUID2(list
->clsid
, buf
, 39);
563 res
= RegDeleteTreeW(coclass_key
, buf
);
564 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
565 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
567 res
= RegDeleteTreeW(instance_key
, buf
);
568 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
569 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
572 error_close_coclass_key
:
573 RegCloseKey(instance_key
);
574 RegCloseKey(encoders_key
);
575 RegCloseKey(coclass_key
);
577 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
580 /***********************************************************************
581 * register_converters
583 static HRESULT
register_converters(struct regsvr_converter
const *list
)
585 LONG res
= ERROR_SUCCESS
;
591 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
592 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
593 if (res
== ERROR_SUCCESS
) {
594 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
595 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
596 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
597 if (res
== ERROR_SUCCESS
)
599 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
600 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
601 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
603 if (res
!= ERROR_SUCCESS
)
604 RegCloseKey(coclass_key
);
606 if (res
!= ERROR_SUCCESS
) goto error_return
;
608 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
610 HKEY instance_clsid_key
;
612 StringFromGUID2(list
->clsid
, buf
, 39);
613 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
614 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
615 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
617 StringFromGUID2(list
->clsid
, buf
, 39);
618 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
619 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
620 if (res
== ERROR_SUCCESS
) {
621 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
622 (const BYTE
*)buf
, 78);
623 RegCloseKey(instance_clsid_key
);
625 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
628 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
629 (const BYTE
*)list
->author
,
630 strlen(list
->author
) + 1);
631 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
634 if (list
->friendlyname
) {
635 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
636 (const BYTE
*)list
->friendlyname
,
637 strlen(list
->friendlyname
) + 1);
638 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
642 StringFromGUID2(list
->vendor
, buf
, 39);
643 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
644 (const BYTE
*)buf
, 78);
645 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
649 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
650 (const BYTE
*)list
->version
,
651 strlen(list
->version
) + 1);
652 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
657 GUID
const * const *format
;
659 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
660 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
661 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
662 for (format
=list
->formats
; *format
; ++format
)
665 StringFromGUID2(*format
, buf
, 39);
666 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
667 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
668 if (res
!= ERROR_SUCCESS
) break;
669 RegCloseKey(format_key
);
671 RegCloseKey(formats_key
);
672 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
675 error_close_clsid_key
:
676 RegCloseKey(clsid_key
);
679 error_close_coclass_key
:
680 RegCloseKey(instance_key
);
681 RegCloseKey(converters_key
);
682 RegCloseKey(coclass_key
);
684 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
687 /***********************************************************************
688 * unregister_converters
690 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
692 LONG res
= ERROR_SUCCESS
;
698 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
699 KEY_READ
| KEY_WRITE
, &coclass_key
);
700 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
702 if (res
== ERROR_SUCCESS
) {
703 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
704 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
705 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
706 if (res
== ERROR_SUCCESS
)
708 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
709 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
710 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
712 if (res
!= ERROR_SUCCESS
)
713 RegCloseKey(coclass_key
);
715 if (res
!= ERROR_SUCCESS
) goto error_return
;
717 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
718 StringFromGUID2(list
->clsid
, buf
, 39);
720 res
= RegDeleteTreeW(coclass_key
, buf
);
721 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
722 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
724 res
= RegDeleteTreeW(instance_key
, buf
);
725 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
726 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
729 error_close_coclass_key
:
730 RegCloseKey(instance_key
);
731 RegCloseKey(converters_key
);
732 RegCloseKey(coclass_key
);
734 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
737 /***********************************************************************
738 * register_metadatareaders
740 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
742 LONG res
= ERROR_SUCCESS
;
748 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
749 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
750 if (res
== ERROR_SUCCESS
) {
751 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
752 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
753 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
754 if (res
== ERROR_SUCCESS
)
756 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
757 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
758 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
760 if (res
!= ERROR_SUCCESS
)
761 RegCloseKey(coclass_key
);
763 if (res
!= ERROR_SUCCESS
) goto error_return
;
765 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
767 HKEY instance_clsid_key
;
769 StringFromGUID2(list
->clsid
, buf
, 39);
770 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
771 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
772 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
774 StringFromGUID2(list
->clsid
, buf
, 39);
775 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
776 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
777 if (res
== ERROR_SUCCESS
) {
778 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
779 (const BYTE
*)buf
, 78);
780 RegCloseKey(instance_clsid_key
);
782 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
785 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
786 (const BYTE
*)list
->author
,
787 strlen(list
->author
) + 1);
788 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
791 if (list
->friendlyname
) {
792 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
793 (const BYTE
*)list
->friendlyname
,
794 strlen(list
->friendlyname
) + 1);
795 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
799 StringFromGUID2(list
->vendor
, buf
, 39);
800 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
801 (const BYTE
*)buf
, 78);
802 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
805 if (list
->metadata_format
) {
806 StringFromGUID2(list
->metadata_format
, buf
, 39);
807 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
808 (const BYTE
*)buf
, 78);
809 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
813 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
814 (const BYTE
*)list
->version
,
815 strlen(list
->version
) + 1);
816 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
819 if (list
->specversion
) {
820 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
821 (const BYTE
*)list
->version
,
822 strlen(list
->version
) + 1);
823 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
826 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
827 (const BYTE
*)&list
->requires_fullstream
, 4);
828 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
830 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
831 (const BYTE
*)&list
->supports_padding
, 4);
832 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
834 if (list
->requires_fixedsize
) {
835 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
836 (const BYTE
*)&list
->requires_fixedsize
, 4);
837 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
840 if (list
->containers
) {
842 const struct reader_containers
*container
;
844 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
845 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
846 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
847 for (container
=list
->containers
; container
->format
; ++container
)
851 StringFromGUID2(container
->format
, buf
, 39);
852 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
853 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
854 if (res
!= ERROR_SUCCESS
) break;
856 for (i
=0; container
->patterns
[i
].length
; i
++)
859 static const WCHAR int_format
[] = {'%','i',0};
860 snprintfW(buf
, 39, int_format
, i
);
861 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
862 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
863 if (res
!= ERROR_SUCCESS
) break;
864 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
865 (const BYTE
*)&container
->patterns
[i
].position
, 4);
866 if (res
== ERROR_SUCCESS
)
867 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
868 container
->patterns
[i
].pattern
,
869 container
->patterns
[i
].length
);
870 if (res
== ERROR_SUCCESS
)
871 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
872 container
->patterns
[i
].mask
,
873 container
->patterns
[i
].length
);
874 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
875 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
876 (const BYTE
*)&container
->patterns
[i
].data_offset
, 4);
877 RegCloseKey(pattern_key
);
880 RegCloseKey(format_key
);
882 RegCloseKey(containers_key
);
885 error_close_clsid_key
:
886 RegCloseKey(clsid_key
);
889 error_close_coclass_key
:
890 RegCloseKey(instance_key
);
891 RegCloseKey(readers_key
);
892 RegCloseKey(coclass_key
);
894 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
897 /***********************************************************************
898 * unregister_metadatareaders
900 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
902 LONG res
= ERROR_SUCCESS
;
908 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
909 KEY_READ
| KEY_WRITE
, &coclass_key
);
910 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
912 if (res
== ERROR_SUCCESS
) {
913 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
914 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
915 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
916 if (res
== ERROR_SUCCESS
)
918 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
919 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
920 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
922 if (res
!= ERROR_SUCCESS
)
923 RegCloseKey(coclass_key
);
925 if (res
!= ERROR_SUCCESS
) goto error_return
;
927 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
928 StringFromGUID2(list
->clsid
, buf
, 39);
930 res
= RegDeleteTreeW(coclass_key
, buf
);
931 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
932 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
934 res
= RegDeleteTreeW(instance_key
, buf
);
935 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
936 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
939 error_close_coclass_key
:
940 RegCloseKey(instance_key
);
941 RegCloseKey(readers_key
);
942 RegCloseKey(coclass_key
);
944 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
947 /***********************************************************************
948 * register_pixelformats
950 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
952 LONG res
= ERROR_SUCCESS
;
958 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
959 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
960 if (res
== ERROR_SUCCESS
) {
961 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
962 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
963 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
964 if (res
== ERROR_SUCCESS
)
966 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
967 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
968 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
970 if (res
!= ERROR_SUCCESS
)
971 RegCloseKey(coclass_key
);
973 if (res
!= ERROR_SUCCESS
) goto error_return
;
975 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
977 HKEY instance_clsid_key
;
979 StringFromGUID2(list
->clsid
, buf
, 39);
980 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
981 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
982 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
984 StringFromGUID2(list
->clsid
, buf
, 39);
985 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
986 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
987 if (res
== ERROR_SUCCESS
) {
988 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
989 (const BYTE
*)buf
, 78);
990 RegCloseKey(instance_clsid_key
);
992 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
995 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
996 (const BYTE
*)list
->author
,
997 strlen(list
->author
) + 1);
998 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1001 if (list
->friendlyname
) {
1002 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
1003 (const BYTE
*)list
->friendlyname
,
1004 strlen(list
->friendlyname
) + 1);
1005 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1009 StringFromGUID2(list
->vendor
, buf
, 39);
1010 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
1011 (const BYTE
*)buf
, 78);
1012 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1015 if (list
->version
) {
1016 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
1017 (const BYTE
*)list
->version
,
1018 strlen(list
->version
) + 1);
1019 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1022 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1023 (const BYTE
*)&list
->bitsperpixel
, 4);
1024 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1026 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1027 (const BYTE
*)&list
->channelcount
, 4);
1028 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1030 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1031 (const BYTE
*)&list
->numericrepresentation
, 4);
1032 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1034 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1035 (const BYTE
*)&list
->supportsalpha
, 4);
1036 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1038 if (list
->channelmasks
) {
1041 WCHAR mask_valuename
[11];
1042 const WCHAR valuename_format
[] = {'%','d',0};
1044 mask_size
= (list
->bitsperpixel
+ 7)/8;
1046 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1047 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1048 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1049 for (i
=0; i
< list
->channelcount
; i
++)
1051 sprintfW(mask_valuename
, valuename_format
, i
);
1052 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1053 list
->channelmasks
[i
], mask_size
);
1054 if (res
!= ERROR_SUCCESS
) break;
1056 RegCloseKey(masks_key
);
1057 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1060 error_close_clsid_key
:
1061 RegCloseKey(clsid_key
);
1064 error_close_coclass_key
:
1065 RegCloseKey(instance_key
);
1066 RegCloseKey(formats_key
);
1067 RegCloseKey(coclass_key
);
1069 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1072 /***********************************************************************
1073 * unregister_pixelformats
1075 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1077 LONG res
= ERROR_SUCCESS
;
1083 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1084 KEY_READ
| KEY_WRITE
, &coclass_key
);
1085 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1087 if (res
== ERROR_SUCCESS
) {
1088 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1089 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1090 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1091 if (res
== ERROR_SUCCESS
)
1093 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1094 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1095 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1097 if (res
!= ERROR_SUCCESS
)
1098 RegCloseKey(coclass_key
);
1100 if (res
!= ERROR_SUCCESS
) goto error_return
;
1102 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1103 StringFromGUID2(list
->clsid
, buf
, 39);
1105 res
= RegDeleteTreeW(coclass_key
, buf
);
1106 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1107 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1109 res
= RegDeleteTreeW(instance_key
, buf
);
1110 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1111 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1114 error_close_coclass_key
:
1115 RegCloseKey(instance_key
);
1116 RegCloseKey(formats_key
);
1117 RegCloseKey(coclass_key
);
1119 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1122 /***********************************************************************
1125 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1127 static const BYTE bmp_magic
[] = {0x42,0x4d};
1129 static GUID
const * const bmp_formats
[] = {
1130 &GUID_WICPixelFormat1bppIndexed
,
1131 &GUID_WICPixelFormat2bppIndexed
,
1132 &GUID_WICPixelFormat4bppIndexed
,
1133 &GUID_WICPixelFormat8bppIndexed
,
1134 &GUID_WICPixelFormat16bppBGR555
,
1135 &GUID_WICPixelFormat16bppBGR565
,
1136 &GUID_WICPixelFormat24bppBGR
,
1137 &GUID_WICPixelFormat32bppBGR
,
1138 &GUID_WICPixelFormat32bppBGRA
,
1142 static struct decoder_pattern
const bmp_patterns
[] = {
1143 {2,0,bmp_magic
,mask_all
,0},
1147 static const BYTE gif87a_magic
[6] = "GIF87a";
1148 static const BYTE gif89a_magic
[6] = "GIF89a";
1150 static GUID
const * const gif_formats
[] = {
1151 &GUID_WICPixelFormat8bppIndexed
,
1155 static struct decoder_pattern
const gif_patterns
[] = {
1156 {6,0,gif87a_magic
,mask_all
,0},
1157 {6,0,gif89a_magic
,mask_all
,0},
1161 static const BYTE ico_magic
[] = {00,00,01,00};
1163 static GUID
const * const ico_formats
[] = {
1164 &GUID_WICPixelFormat32bppBGRA
,
1168 static struct decoder_pattern
const ico_patterns
[] = {
1169 {4,0,ico_magic
,mask_all
,0},
1173 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1175 static GUID
const * const jpeg_formats
[] = {
1176 &GUID_WICPixelFormat24bppBGR
,
1177 &GUID_WICPixelFormat32bppCMYK
,
1178 &GUID_WICPixelFormat8bppGray
,
1182 static struct decoder_pattern
const jpeg_patterns
[] = {
1183 {2,0,jpeg_magic
,mask_all
,0},
1187 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1189 static GUID
const * const png_formats
[] = {
1190 &GUID_WICPixelFormatBlackWhite
,
1191 &GUID_WICPixelFormat2bppGray
,
1192 &GUID_WICPixelFormat4bppGray
,
1193 &GUID_WICPixelFormat8bppGray
,
1194 &GUID_WICPixelFormat16bppGray
,
1195 &GUID_WICPixelFormat32bppBGRA
,
1196 &GUID_WICPixelFormat64bppRGBA
,
1197 &GUID_WICPixelFormat1bppIndexed
,
1198 &GUID_WICPixelFormat2bppIndexed
,
1199 &GUID_WICPixelFormat4bppIndexed
,
1200 &GUID_WICPixelFormat8bppIndexed
,
1201 &GUID_WICPixelFormat24bppBGR
,
1202 &GUID_WICPixelFormat48bppRGB
,
1206 static struct decoder_pattern
const png_patterns
[] = {
1207 {8,0,png_magic
,mask_all
,0},
1211 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1212 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1214 static GUID
const * const tiff_decode_formats
[] = {
1215 &GUID_WICPixelFormatBlackWhite
,
1216 &GUID_WICPixelFormat4bppGray
,
1217 &GUID_WICPixelFormat8bppGray
,
1218 &GUID_WICPixelFormat4bppIndexed
,
1219 &GUID_WICPixelFormat8bppIndexed
,
1220 &GUID_WICPixelFormat24bppBGR
,
1221 &GUID_WICPixelFormat32bppBGR
,
1222 &GUID_WICPixelFormat32bppBGRA
,
1223 &GUID_WICPixelFormat32bppPBGRA
,
1224 &GUID_WICPixelFormat48bppRGB
,
1225 &GUID_WICPixelFormat64bppRGBA
,
1226 &GUID_WICPixelFormat64bppPRGBA
,
1230 static struct decoder_pattern
const tiff_patterns
[] = {
1231 {4,0,tiff_magic_le
,mask_all
,0},
1232 {4,0,tiff_magic_be
,mask_all
,0},
1236 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1238 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};
1239 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};
1241 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};
1242 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};
1244 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};
1245 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};
1247 static GUID
const * const tga_formats
[] = {
1248 &GUID_WICPixelFormat8bppGray
,
1249 &GUID_WICPixelFormat8bppIndexed
,
1250 &GUID_WICPixelFormat16bppGray
,
1251 &GUID_WICPixelFormat16bppBGR555
,
1252 &GUID_WICPixelFormat24bppBGR
,
1253 &GUID_WICPixelFormat32bppBGRA
,
1254 &GUID_WICPixelFormat32bppPBGRA
,
1258 static struct decoder_pattern
const tga_patterns
[] = {
1259 {18,18,tga_footer_magic
,mask_all
,1},
1260 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1261 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1262 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1266 static struct regsvr_decoder
const decoder_list
[] = {
1267 { &CLSID_WICBmpDecoder
,
1271 &GUID_VendorMicrosoft
,
1272 &GUID_ContainerFormatBmp
,
1278 { &CLSID_WICGifDecoder
,
1282 &GUID_VendorMicrosoft
,
1283 &GUID_ContainerFormatGif
,
1289 { &CLSID_WICIcoDecoder
,
1293 &GUID_VendorMicrosoft
,
1294 &GUID_ContainerFormatIco
,
1295 "image/vnd.microsoft.icon",
1300 { &CLSID_WICJpegDecoder
,
1304 &GUID_VendorMicrosoft
,
1305 &GUID_ContainerFormatJpeg
,
1311 { &CLSID_WICPngDecoder
,
1315 &GUID_VendorMicrosoft
,
1316 &GUID_ContainerFormatPng
,
1322 { &CLSID_WICTiffDecoder
,
1326 &GUID_VendorMicrosoft
,
1327 &GUID_ContainerFormatTiff
,
1330 tiff_decode_formats
,
1333 { &CLSID_WineTgaDecoder
,
1338 &GUID_WineContainerFormatTga
,
1344 { NULL
} /* list terminator */
1347 static GUID
const * const bmp_encode_formats
[] = {
1348 &GUID_WICPixelFormat16bppBGR555
,
1349 &GUID_WICPixelFormat16bppBGR565
,
1350 &GUID_WICPixelFormat24bppBGR
,
1351 &GUID_WICPixelFormat32bppBGR
,
1355 static GUID
const * const png_encode_formats
[] = {
1356 &GUID_WICPixelFormat24bppBGR
,
1357 &GUID_WICPixelFormatBlackWhite
,
1358 &GUID_WICPixelFormat2bppGray
,
1359 &GUID_WICPixelFormat4bppGray
,
1360 &GUID_WICPixelFormat8bppGray
,
1361 &GUID_WICPixelFormat16bppGray
,
1362 &GUID_WICPixelFormat32bppBGR
,
1363 &GUID_WICPixelFormat32bppBGRA
,
1364 &GUID_WICPixelFormat48bppRGB
,
1365 &GUID_WICPixelFormat64bppRGBA
,
1369 static GUID
const * const tiff_encode_formats
[] = {
1370 &GUID_WICPixelFormatBlackWhite
,
1371 &GUID_WICPixelFormat4bppGray
,
1372 &GUID_WICPixelFormat8bppGray
,
1373 &GUID_WICPixelFormat24bppBGR
,
1374 &GUID_WICPixelFormat32bppBGRA
,
1375 &GUID_WICPixelFormat32bppPBGRA
,
1376 &GUID_WICPixelFormat48bppRGB
,
1377 &GUID_WICPixelFormat64bppRGBA
,
1378 &GUID_WICPixelFormat64bppPRGBA
,
1382 static GUID
const * const icns_encode_formats
[] = {
1383 &GUID_WICPixelFormat32bppBGRA
,
1387 static struct regsvr_encoder
const encoder_list
[] = {
1388 { &CLSID_WICBmpEncoder
,
1392 &GUID_VendorMicrosoft
,
1393 &GUID_ContainerFormatBmp
,
1398 { &CLSID_WICJpegEncoder
,
1402 &GUID_VendorMicrosoft
,
1403 &GUID_ContainerFormatJpeg
,
1408 { &CLSID_WICPngEncoder
,
1412 &GUID_VendorMicrosoft
,
1413 &GUID_ContainerFormatPng
,
1418 { &CLSID_WICTiffEncoder
,
1422 &GUID_VendorMicrosoft
,
1423 &GUID_ContainerFormatTiff
,
1428 { &CLSID_WICIcnsEncoder
,
1433 NULL
, /* no container format guid */
1438 { NULL
} /* list terminator */
1441 static GUID
const * const converter_formats
[] = {
1442 &GUID_WICPixelFormat1bppIndexed
,
1443 &GUID_WICPixelFormat2bppIndexed
,
1444 &GUID_WICPixelFormat4bppIndexed
,
1445 &GUID_WICPixelFormat8bppIndexed
,
1446 &GUID_WICPixelFormatBlackWhite
,
1447 &GUID_WICPixelFormat2bppGray
,
1448 &GUID_WICPixelFormat4bppGray
,
1449 &GUID_WICPixelFormat8bppGray
,
1450 &GUID_WICPixelFormat16bppGray
,
1451 &GUID_WICPixelFormat16bppBGR555
,
1452 &GUID_WICPixelFormat16bppBGR565
,
1453 &GUID_WICPixelFormat16bppBGRA5551
,
1454 &GUID_WICPixelFormat24bppBGR
,
1455 &GUID_WICPixelFormat24bppRGB
,
1456 &GUID_WICPixelFormat32bppBGR
,
1457 &GUID_WICPixelFormat32bppBGRA
,
1458 &GUID_WICPixelFormat32bppPBGRA
,
1459 &GUID_WICPixelFormat48bppRGB
,
1460 &GUID_WICPixelFormat64bppRGBA
,
1461 &GUID_WICPixelFormat32bppCMYK
,
1465 static struct regsvr_converter
const converter_list
[] = {
1466 { &CLSID_WICDefaultFormatConverter
,
1468 "Default Pixel Format Converter",
1470 &GUID_VendorMicrosoft
,
1473 { NULL
} /* list terminator */
1476 static const BYTE no_magic
[1] = { 0 };
1477 static const BYTE no_mask
[1] = { 0 };
1479 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1480 { 0, 1, no_magic
, no_mask
, 0 },
1484 static const struct reader_containers ifd_containers
[] = {
1486 &GUID_ContainerFormatTiff
,
1487 ifd_metadata_pattern
1489 { NULL
} /* list terminator */
1492 static const BYTE tEXt
[] = "tEXt";
1494 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1495 { 4, 4, tEXt
, mask_all
, 4 },
1499 static const struct reader_containers pngtext_containers
[] = {
1501 &GUID_ContainerFormatPng
,
1502 pngtext_metadata_pattern
1504 { NULL
} /* list terminator */
1507 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1508 { 0, 6, gif87a_magic
, mask_all
, 0 },
1509 { 0, 6, gif89a_magic
, mask_all
, 0 },
1513 static const struct reader_containers lsd_containers
[] = {
1515 &GUID_ContainerFormatGif
,
1516 lsd_metadata_patterns
1518 { NULL
} /* list terminator */
1521 static const BYTE imd_magic
[] = { 0x2c };
1523 static const struct metadata_pattern imd_metadata_pattern
[] = {
1524 { 0, 1, imd_magic
, mask_all
, 1 },
1528 static const struct reader_containers imd_containers
[] = {
1530 &GUID_ContainerFormatGif
,
1531 imd_metadata_pattern
1533 { NULL
} /* list terminator */
1536 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1538 static const struct metadata_pattern gce_metadata_pattern
[] = {
1539 { 0, 3, gce_magic
, mask_all
, 3 },
1543 static const struct reader_containers gce_containers
[] = {
1545 &GUID_ContainerFormatGif
,
1546 gce_metadata_pattern
1548 { NULL
} /* list terminator */
1551 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1553 static const struct metadata_pattern ape_metadata_pattern
[] = {
1554 { 0, 3, ape_magic
, mask_all
, 0 },
1558 static const struct reader_containers ape_containers
[] = {
1560 &GUID_ContainerFormatGif
,
1561 ape_metadata_pattern
1563 { NULL
} /* list terminator */
1566 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1568 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1569 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1573 static const struct reader_containers gif_comment_containers
[] = {
1575 &GUID_ContainerFormatGif
,
1576 gif_comment_metadata_pattern
1578 { NULL
} /* list terminator */
1581 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1582 { &CLSID_WICUnknownMetadataReader
,
1584 "Unknown Metadata Reader",
1587 &GUID_VendorMicrosoft
,
1588 &GUID_MetadataFormatUnknown
,
1592 { &CLSID_WICIfdMetadataReader
,
1597 &GUID_VendorMicrosoft
,
1598 &GUID_MetadataFormatIfd
,
1602 { &CLSID_WICPngTextMetadataReader
,
1604 "Chunk tEXt Reader",
1607 &GUID_VendorMicrosoft
,
1608 &GUID_MetadataFormatChunktEXt
,
1612 { &CLSID_WICLSDMetadataReader
,
1614 "Logical Screen Descriptor Reader",
1617 &GUID_VendorMicrosoft
,
1618 &GUID_MetadataFormatLSD
,
1622 { &CLSID_WICIMDMetadataReader
,
1624 "Image Descriptor Reader",
1627 &GUID_VendorMicrosoft
,
1628 &GUID_MetadataFormatIMD
,
1632 { &CLSID_WICGCEMetadataReader
,
1634 "Graphic Control Extension Reader",
1637 &GUID_VendorMicrosoft
,
1638 &GUID_MetadataFormatGCE
,
1642 { &CLSID_WICAPEMetadataReader
,
1644 "Application Extension Reader",
1647 &GUID_VendorMicrosoft
,
1648 &GUID_MetadataFormatAPE
,
1652 { &CLSID_WICGifCommentMetadataReader
,
1654 "Comment Extension Reader",
1657 &GUID_VendorMicrosoft
,
1658 &GUID_MetadataFormatGifComment
,
1660 gif_comment_containers
1662 { NULL
} /* list terminator */
1665 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1666 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1667 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1669 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1670 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1671 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1672 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1674 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1675 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1676 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1677 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1679 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1680 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1681 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1682 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1684 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1685 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1687 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1688 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1689 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1690 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1691 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1692 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1693 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1695 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1696 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1698 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1699 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1701 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1702 { &GUID_WICPixelFormat1bppIndexed
,
1705 NULL
, /* no version */
1706 &GUID_VendorMicrosoft
,
1707 1, /* bitsperpixel */
1708 1, /* channel count */
1710 WICPixelFormatNumericRepresentationIndexed
,
1713 { &GUID_WICPixelFormat2bppIndexed
,
1716 NULL
, /* no version */
1717 &GUID_VendorMicrosoft
,
1718 2, /* bitsperpixel */
1719 1, /* channel count */
1721 WICPixelFormatNumericRepresentationIndexed
,
1724 { &GUID_WICPixelFormat4bppIndexed
,
1727 NULL
, /* no version */
1728 &GUID_VendorMicrosoft
,
1729 4, /* bitsperpixel */
1730 1, /* channel count */
1732 WICPixelFormatNumericRepresentationIndexed
,
1735 { &GUID_WICPixelFormat8bppIndexed
,
1738 NULL
, /* no version */
1739 &GUID_VendorMicrosoft
,
1740 8, /* bitsperpixel */
1741 1, /* channel count */
1743 WICPixelFormatNumericRepresentationIndexed
,
1746 { &GUID_WICPixelFormatBlackWhite
,
1749 NULL
, /* no version */
1750 &GUID_VendorMicrosoft
,
1751 1, /* bitsperpixel */
1752 1, /* channel count */
1754 WICPixelFormatNumericRepresentationUnsignedInteger
,
1757 { &GUID_WICPixelFormat2bppGray
,
1760 NULL
, /* no version */
1761 &GUID_VendorMicrosoft
,
1762 2, /* bitsperpixel */
1763 1, /* channel count */
1765 WICPixelFormatNumericRepresentationUnsignedInteger
,
1768 { &GUID_WICPixelFormat4bppGray
,
1771 NULL
, /* no version */
1772 &GUID_VendorMicrosoft
,
1773 4, /* bitsperpixel */
1774 1, /* channel count */
1776 WICPixelFormatNumericRepresentationUnsignedInteger
,
1779 { &GUID_WICPixelFormat8bppGray
,
1782 NULL
, /* no version */
1783 &GUID_VendorMicrosoft
,
1784 8, /* bitsperpixel */
1785 1, /* channel count */
1787 WICPixelFormatNumericRepresentationUnsignedInteger
,
1790 { &GUID_WICPixelFormat16bppGray
,
1793 NULL
, /* no version */
1794 &GUID_VendorMicrosoft
,
1795 16, /* bitsperpixel */
1796 1, /* channel count */
1797 channel_masks_16bit
,
1798 WICPixelFormatNumericRepresentationUnsignedInteger
,
1801 { &GUID_WICPixelFormat16bppBGR555
,
1804 NULL
, /* no version */
1805 &GUID_VendorMicrosoft
,
1806 16, /* bitsperpixel */
1807 3, /* channel count */
1808 channel_masks_BGRA5551
,
1809 WICPixelFormatNumericRepresentationUnsignedInteger
,
1812 { &GUID_WICPixelFormat16bppBGR565
,
1815 NULL
, /* no version */
1816 &GUID_VendorMicrosoft
,
1817 16, /* bitsperpixel */
1818 3, /* channel count */
1819 channel_masks_BGR565
,
1820 WICPixelFormatNumericRepresentationUnsignedInteger
,
1823 { &GUID_WICPixelFormat16bppBGRA5551
,
1826 NULL
, /* no version */
1827 &GUID_VendorMicrosoft
,
1828 16, /* bitsperpixel */
1829 4, /* channel count */
1830 channel_masks_BGRA5551
,
1831 WICPixelFormatNumericRepresentationUnsignedInteger
,
1834 { &GUID_WICPixelFormat24bppBGR
,
1837 NULL
, /* no version */
1838 &GUID_VendorMicrosoft
,
1839 24, /* bitsperpixel */
1840 3, /* channel count */
1842 WICPixelFormatNumericRepresentationUnsignedInteger
,
1845 { &GUID_WICPixelFormat24bppRGB
,
1848 NULL
, /* no version */
1849 &GUID_VendorMicrosoft
,
1850 24, /* bitsperpixel */
1851 3, /* channel count */
1853 WICPixelFormatNumericRepresentationUnsignedInteger
,
1856 { &GUID_WICPixelFormat32bppBGR
,
1859 NULL
, /* no version */
1860 &GUID_VendorMicrosoft
,
1861 32, /* bitsperpixel */
1862 3, /* channel count */
1864 WICPixelFormatNumericRepresentationUnsignedInteger
,
1867 { &GUID_WICPixelFormat32bppBGRA
,
1870 NULL
, /* no version */
1871 &GUID_VendorMicrosoft
,
1872 32, /* bitsperpixel */
1873 4, /* channel count */
1875 WICPixelFormatNumericRepresentationUnsignedInteger
,
1878 { &GUID_WICPixelFormat32bppPBGRA
,
1881 NULL
, /* no version */
1882 &GUID_VendorMicrosoft
,
1883 32, /* bitsperpixel */
1884 4, /* channel count */
1886 WICPixelFormatNumericRepresentationUnsignedInteger
,
1889 { &GUID_WICPixelFormat48bppRGB
,
1892 NULL
, /* no version */
1893 &GUID_VendorMicrosoft
,
1894 48, /* bitsperpixel */
1895 3, /* channel count */
1896 channel_masks_16bit
,
1897 WICPixelFormatNumericRepresentationUnsignedInteger
,
1900 { &GUID_WICPixelFormat64bppRGBA
,
1903 NULL
, /* no version */
1904 &GUID_VendorMicrosoft
,
1905 64, /* bitsperpixel */
1906 4, /* channel count */
1907 channel_masks_16bit
,
1908 WICPixelFormatNumericRepresentationUnsignedInteger
,
1911 { &GUID_WICPixelFormat64bppPRGBA
,
1914 NULL
, /* no version */
1915 &GUID_VendorMicrosoft
,
1916 64, /* bitsperpixel */
1917 4, /* channel count */
1918 channel_masks_16bit
,
1919 WICPixelFormatNumericRepresentationUnsignedInteger
,
1922 { &GUID_WICPixelFormat32bppCMYK
,
1925 NULL
, /* no version */
1926 &GUID_VendorMicrosoft
,
1927 32, /* bitsperpixel */
1928 4, /* channel count */
1930 WICPixelFormatNumericRepresentationUnsignedInteger
,
1933 { NULL
} /* list terminator */
1936 struct regsvr_category
1938 const CLSID
*clsid
; /* NULL for end of list */
1941 static const struct regsvr_category category_list
[] = {
1942 { &CATID_WICBitmapDecoders
},
1943 { &CATID_WICBitmapEncoders
},
1944 { &CATID_WICFormatConverters
},
1945 { &CATID_WICMetadataReader
},
1946 { &CATID_WICPixelFormats
},
1950 static HRESULT
register_categories(const struct regsvr_category
*list
)
1954 HKEY coclass_key
, categories_key
, instance_key
;
1956 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
1957 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
1958 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1960 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1961 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1962 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
1963 if (res
!= ERROR_SUCCESS
)
1965 RegCloseKey(coclass_key
);
1966 return HRESULT_FROM_WIN32(res
);
1969 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
1970 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1972 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
1974 HKEY instance_clsid_key
;
1976 StringFromGUID2(list
->clsid
, buf
, 39);
1977 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
1978 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
1979 if (res
== ERROR_SUCCESS
)
1981 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
1982 (const BYTE
*)buf
, 78);
1983 RegCloseKey(instance_clsid_key
);
1987 RegCloseKey(instance_key
);
1988 RegCloseKey(categories_key
);
1989 RegCloseKey(coclass_key
);
1991 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1994 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
1998 HKEY coclass_key
, categories_key
, instance_key
;
2000 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
2001 KEY_READ
| KEY_WRITE
, &coclass_key
);
2002 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2004 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2005 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
2006 KEY_READ
| KEY_WRITE
, &categories_key
);
2007 if (res
!= ERROR_SUCCESS
)
2009 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2010 RegCloseKey(coclass_key
);
2011 return HRESULT_FROM_WIN32(res
);
2014 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2015 KEY_READ
| KEY_WRITE
, &instance_key
);
2017 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2019 StringFromGUID2(list
->clsid
, buf
, 39);
2020 res
= RegDeleteTreeW(instance_key
, buf
);
2023 RegCloseKey(instance_key
);
2024 RegCloseKey(categories_key
);
2026 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2027 res
= RegDeleteTreeW(coclass_key
, buf
);
2029 RegCloseKey(coclass_key
);
2031 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2034 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2035 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2037 HRESULT WINAPI
DllRegisterServer(void)
2043 hr
= WIC_DllRegisterServer();
2045 hr
= register_categories(category_list
);
2047 hr
= register_decoders(decoder_list
);
2049 hr
= register_encoders(encoder_list
);
2051 hr
= register_converters(converter_list
);
2053 hr
= register_metadatareaders(metadatareader_list
);
2055 hr
= register_pixelformats(pixelformat_list
);
2059 HRESULT WINAPI
DllUnregisterServer(void)
2065 hr
= WIC_DllUnregisterServer();
2067 hr
= unregister_categories(category_list
);
2069 hr
= unregister_decoders(decoder_list
);
2071 hr
= unregister_encoders(encoder_list
);
2073 hr
= unregister_converters(converter_list
);
2075 hr
= unregister_metadatareaders(metadatareader_list
);
2077 hr
= unregister_pixelformats(pixelformat_list
);