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
36 #include "wine/debug.h"
37 #include "wine/unicode.h"
39 #include "wincodecs_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
43 /***********************************************************************
44 * interface for self-registering
46 struct decoder_pattern
48 DWORD length
; /* 0 for end of list */
57 CLSID
const *clsid
; /* NULL for end of list */
62 GUID
const *container_format
;
65 GUID
const * const *formats
;
66 const struct decoder_pattern
*patterns
;
69 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
70 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
74 CLSID
const *clsid
; /* NULL for end of list */
79 GUID
const *container_format
;
82 GUID
const * const *formats
;
85 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
86 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
88 struct regsvr_converter
90 CLSID
const *clsid
; /* NULL for end of list */
95 GUID
const * const *formats
;
98 static HRESULT
register_converters(struct regsvr_converter
const *list
);
99 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
101 /***********************************************************************
102 * static string constants
104 static const WCHAR clsid_keyname
[] = {
105 'C', 'L', 'S', 'I', 'D', 0 };
106 static const WCHAR curver_keyname
[] = {
107 'C', 'u', 'r', 'V', 'e', 'r', 0 };
108 static const WCHAR ips_keyname
[] = {
109 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
111 static const WCHAR ips32_keyname
[] = {
112 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
114 static const WCHAR progid_keyname
[] = {
115 'P', 'r', 'o', 'g', 'I', 'D', 0 };
116 static const WCHAR viprogid_keyname
[] = {
117 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
118 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
120 static const char tmodel_valuename
[] = "ThreadingModel";
121 static const char author_valuename
[] = "Author";
122 static const char friendlyname_valuename
[] = "FriendlyName";
123 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
124 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
125 static const char version_valuename
[] = "Version";
126 static const char mimetypes_valuename
[] = "MimeTypes";
127 static const char extensions_valuename
[] = "FileExtensions";
128 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
129 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
130 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
131 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
132 static const char length_valuename
[] = "Length";
133 static const char position_valuename
[] = "Position";
134 static const char pattern_valuename
[] = "Pattern";
135 static const char mask_valuename
[] = "Mask";
136 static const char endofstream_valuename
[] = "EndOfStream";
137 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
139 /***********************************************************************
142 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
144 LONG res
= ERROR_SUCCESS
;
150 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
151 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
152 if (res
== ERROR_SUCCESS
) {
153 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
154 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
155 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
156 if (res
== ERROR_SUCCESS
)
158 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
159 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
160 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
162 if (res
!= ERROR_SUCCESS
)
163 RegCloseKey(coclass_key
);
165 if (res
!= ERROR_SUCCESS
) goto error_return
;
167 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
169 HKEY instance_clsid_key
;
171 StringFromGUID2(list
->clsid
, buf
, 39);
172 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
173 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
174 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
176 StringFromGUID2(list
->clsid
, buf
, 39);
177 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
178 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
179 if (res
== ERROR_SUCCESS
) {
180 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
181 (CONST BYTE
*)(buf
), 78);
182 RegCloseKey(instance_clsid_key
);
184 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
187 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
188 (CONST BYTE
*)(list
->author
),
189 strlen(list
->author
) + 1);
190 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
193 if (list
->friendlyname
) {
194 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
195 (CONST BYTE
*)(list
->friendlyname
),
196 strlen(list
->friendlyname
) + 1);
197 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
201 StringFromGUID2(list
->vendor
, buf
, 39);
202 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
203 (CONST BYTE
*)(buf
), 78);
204 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
207 if (list
->container_format
) {
208 StringFromGUID2(list
->container_format
, buf
, 39);
209 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
210 (CONST BYTE
*)(buf
), 78);
211 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
215 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
216 (CONST BYTE
*)(list
->version
),
217 strlen(list
->version
) + 1);
218 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
221 if (list
->mimetypes
) {
222 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
223 (CONST BYTE
*)(list
->mimetypes
),
224 strlen(list
->mimetypes
) + 1);
225 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
228 if (list
->extensions
) {
229 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
230 (CONST BYTE
*)(list
->extensions
),
231 strlen(list
->extensions
) + 1);
232 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
237 GUID
const * const *format
;
239 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
240 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
241 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
242 for (format
=list
->formats
; *format
; ++format
)
245 StringFromGUID2(*format
, buf
, 39);
246 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
247 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
248 if (res
!= ERROR_SUCCESS
) break;
249 RegCloseKey(format_key
);
251 RegCloseKey(formats_key
);
252 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
255 if (list
->patterns
) {
259 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
260 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
261 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
262 for (i
=0; list
->patterns
[i
].length
; i
++)
265 static const WCHAR int_format
[] = {'%','i',0};
266 snprintfW(buf
, 39, int_format
, i
);
267 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
268 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
269 if (res
!= ERROR_SUCCESS
) break;
270 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
271 (CONST BYTE
*)(&list
->patterns
[i
].length
), 4);
272 if (res
== ERROR_SUCCESS
)
273 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
274 (CONST BYTE
*)(&list
->patterns
[i
].position
), 4);
275 if (res
== ERROR_SUCCESS
)
276 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
277 list
->patterns
[i
].pattern
,
278 list
->patterns
[i
].length
);
279 if (res
== ERROR_SUCCESS
)
280 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
281 list
->patterns
[i
].mask
,
282 list
->patterns
[i
].length
);
283 if (res
== ERROR_SUCCESS
)
284 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
285 (CONST BYTE
*)&(list
->patterns
[i
].endofstream
), 4);
286 RegCloseKey(pattern_key
);
288 RegCloseKey(patterns_key
);
289 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
292 error_close_clsid_key
:
293 RegCloseKey(clsid_key
);
296 error_close_coclass_key
:
297 RegCloseKey(instance_key
);
298 RegCloseKey(decoders_key
);
299 RegCloseKey(coclass_key
);
301 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
304 /***********************************************************************
305 * unregister_decoders
307 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
309 LONG res
= ERROR_SUCCESS
;
315 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
316 KEY_READ
| KEY_WRITE
, &coclass_key
);
317 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
319 if (res
== ERROR_SUCCESS
) {
320 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
321 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
322 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
323 if (res
== ERROR_SUCCESS
)
325 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
326 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
327 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
329 if (res
!= ERROR_SUCCESS
)
330 RegCloseKey(coclass_key
);
332 if (res
!= ERROR_SUCCESS
) goto error_return
;
334 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
335 StringFromGUID2(list
->clsid
, buf
, 39);
337 res
= RegDeleteTreeW(coclass_key
, buf
);
338 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
339 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
341 res
= RegDeleteTreeW(instance_key
, buf
);
342 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
343 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
346 error_close_coclass_key
:
347 RegCloseKey(instance_key
);
348 RegCloseKey(decoders_key
);
349 RegCloseKey(coclass_key
);
351 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
354 /***********************************************************************
357 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
359 LONG res
= ERROR_SUCCESS
;
365 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
366 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
367 if (res
== ERROR_SUCCESS
) {
368 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
369 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
370 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
371 if (res
== ERROR_SUCCESS
)
373 res
= RegCreateKeyExW(encoders_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
) {
384 HKEY instance_clsid_key
;
386 StringFromGUID2(list
->clsid
, buf
, 39);
387 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
388 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
389 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
391 StringFromGUID2(list
->clsid
, buf
, 39);
392 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
393 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
394 if (res
== ERROR_SUCCESS
) {
395 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
396 (CONST BYTE
*)(buf
), 78);
397 RegCloseKey(instance_clsid_key
);
399 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
402 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
403 (CONST BYTE
*)(list
->author
),
404 strlen(list
->author
) + 1);
405 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
408 if (list
->friendlyname
) {
409 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
410 (CONST BYTE
*)(list
->friendlyname
),
411 strlen(list
->friendlyname
) + 1);
412 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
416 StringFromGUID2(list
->vendor
, buf
, 39);
417 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
418 (CONST BYTE
*)(buf
), 78);
419 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
422 if (list
->container_format
) {
423 StringFromGUID2(list
->container_format
, buf
, 39);
424 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
425 (CONST BYTE
*)(buf
), 78);
426 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
430 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
431 (CONST BYTE
*)(list
->version
),
432 strlen(list
->version
) + 1);
433 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
436 if (list
->mimetypes
) {
437 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
438 (CONST BYTE
*)(list
->mimetypes
),
439 strlen(list
->mimetypes
) + 1);
440 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
443 if (list
->extensions
) {
444 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
445 (CONST BYTE
*)(list
->extensions
),
446 strlen(list
->extensions
) + 1);
447 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
452 GUID
const * const *format
;
454 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
455 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
456 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
457 for (format
=list
->formats
; *format
; ++format
)
460 StringFromGUID2(*format
, buf
, 39);
461 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
462 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
463 if (res
!= ERROR_SUCCESS
) break;
464 RegCloseKey(format_key
);
466 RegCloseKey(formats_key
);
467 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
470 error_close_clsid_key
:
471 RegCloseKey(clsid_key
);
474 error_close_coclass_key
:
475 RegCloseKey(instance_key
);
476 RegCloseKey(encoders_key
);
477 RegCloseKey(coclass_key
);
479 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
482 /***********************************************************************
483 * unregister_encoders
485 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
487 LONG res
= ERROR_SUCCESS
;
493 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
494 KEY_READ
| KEY_WRITE
, &coclass_key
);
495 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
497 if (res
== ERROR_SUCCESS
) {
498 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
499 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
500 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
501 if (res
== ERROR_SUCCESS
)
503 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
504 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
505 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
507 if (res
!= ERROR_SUCCESS
)
508 RegCloseKey(coclass_key
);
510 if (res
!= ERROR_SUCCESS
) goto error_return
;
512 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
513 StringFromGUID2(list
->clsid
, buf
, 39);
515 res
= RegDeleteTreeW(coclass_key
, buf
);
516 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
517 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
519 res
= RegDeleteTreeW(instance_key
, buf
);
520 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
521 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
524 error_close_coclass_key
:
525 RegCloseKey(instance_key
);
526 RegCloseKey(encoders_key
);
527 RegCloseKey(coclass_key
);
529 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
532 /***********************************************************************
533 * register_converters
535 static HRESULT
register_converters(struct regsvr_converter
const *list
)
537 LONG res
= ERROR_SUCCESS
;
543 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
544 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
545 if (res
== ERROR_SUCCESS
) {
546 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
547 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
548 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
549 if (res
== ERROR_SUCCESS
)
551 res
= RegCreateKeyExW(converters_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
) {
562 HKEY instance_clsid_key
;
564 StringFromGUID2(list
->clsid
, buf
, 39);
565 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
566 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
567 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
569 StringFromGUID2(list
->clsid
, buf
, 39);
570 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
571 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
572 if (res
== ERROR_SUCCESS
) {
573 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
574 (CONST BYTE
*)(buf
), 78);
575 RegCloseKey(instance_clsid_key
);
577 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
580 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
581 (CONST BYTE
*)(list
->author
),
582 strlen(list
->author
) + 1);
583 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
586 if (list
->friendlyname
) {
587 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
588 (CONST BYTE
*)(list
->friendlyname
),
589 strlen(list
->friendlyname
) + 1);
590 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
594 StringFromGUID2(list
->vendor
, buf
, 39);
595 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
596 (CONST BYTE
*)(buf
), 78);
597 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
601 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
602 (CONST BYTE
*)(list
->version
),
603 strlen(list
->version
) + 1);
604 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
609 GUID
const * const *format
;
611 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
612 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
613 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
614 for (format
=list
->formats
; *format
; ++format
)
617 StringFromGUID2(*format
, buf
, 39);
618 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
619 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
620 if (res
!= ERROR_SUCCESS
) break;
621 RegCloseKey(format_key
);
623 RegCloseKey(formats_key
);
624 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
627 error_close_clsid_key
:
628 RegCloseKey(clsid_key
);
631 error_close_coclass_key
:
632 RegCloseKey(instance_key
);
633 RegCloseKey(converters_key
);
634 RegCloseKey(coclass_key
);
636 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
639 /***********************************************************************
640 * unregister_converters
642 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
644 LONG res
= ERROR_SUCCESS
;
650 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
651 KEY_READ
| KEY_WRITE
, &coclass_key
);
652 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
654 if (res
== ERROR_SUCCESS
) {
655 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
656 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
657 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
658 if (res
== ERROR_SUCCESS
)
660 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
661 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
662 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
664 if (res
!= ERROR_SUCCESS
)
665 RegCloseKey(coclass_key
);
667 if (res
!= ERROR_SUCCESS
) goto error_return
;
669 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
670 StringFromGUID2(list
->clsid
, buf
, 39);
672 res
= RegDeleteTreeW(coclass_key
, buf
);
673 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
674 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
676 res
= RegDeleteTreeW(instance_key
, buf
);
677 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
678 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
681 error_close_coclass_key
:
682 RegCloseKey(instance_key
);
683 RegCloseKey(converters_key
);
684 RegCloseKey(coclass_key
);
686 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
689 /***********************************************************************
692 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
694 static const BYTE bmp_magic
[] = {0x42,0x4d};
696 static GUID
const * const bmp_formats
[] = {
697 &GUID_WICPixelFormat1bppIndexed
,
698 &GUID_WICPixelFormat2bppIndexed
,
699 &GUID_WICPixelFormat4bppIndexed
,
700 &GUID_WICPixelFormat8bppIndexed
,
701 &GUID_WICPixelFormat16bppBGR555
,
702 &GUID_WICPixelFormat16bppBGR565
,
703 &GUID_WICPixelFormat24bppBGR
,
704 &GUID_WICPixelFormat32bppBGR
,
705 &GUID_WICPixelFormat32bppBGRA
,
709 static struct decoder_pattern
const bmp_patterns
[] = {
710 {2,0,bmp_magic
,mask_all
,0},
714 static const BYTE gif87a_magic
[6] = "GIF87a";
715 static const BYTE gif89a_magic
[6] = "GIF89a";
717 static GUID
const * const gif_formats
[] = {
718 &GUID_WICPixelFormat8bppIndexed
,
722 static struct decoder_pattern
const gif_patterns
[] = {
723 {6,0,gif87a_magic
,mask_all
,0},
724 {6,0,gif89a_magic
,mask_all
,0},
728 static const BYTE ico_magic
[] = {00,00,01,00};
730 static GUID
const * const ico_formats
[] = {
731 &GUID_WICPixelFormat32bppBGRA
,
735 static struct decoder_pattern
const ico_patterns
[] = {
736 {4,0,ico_magic
,mask_all
,0},
740 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
742 static GUID
const * const jpeg_formats
[] = {
743 &GUID_WICPixelFormat24bppBGR
,
744 &GUID_WICPixelFormat32bppCMYK
,
745 &GUID_WICPixelFormat8bppGray
,
749 static struct decoder_pattern
const jpeg_patterns
[] = {
750 {2,0,jpeg_magic
,mask_all
,0},
754 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
756 static GUID
const * const png_formats
[] = {
757 &GUID_WICPixelFormatBlackWhite
,
758 &GUID_WICPixelFormat2bppGray
,
759 &GUID_WICPixelFormat4bppGray
,
760 &GUID_WICPixelFormat8bppGray
,
761 &GUID_WICPixelFormat16bppGray
,
762 &GUID_WICPixelFormat32bppBGRA
,
763 &GUID_WICPixelFormat64bppRGBA
,
764 &GUID_WICPixelFormat1bppIndexed
,
765 &GUID_WICPixelFormat2bppIndexed
,
766 &GUID_WICPixelFormat4bppIndexed
,
767 &GUID_WICPixelFormat8bppIndexed
,
768 &GUID_WICPixelFormat24bppBGR
,
769 &GUID_WICPixelFormat48bppRGB
,
773 static struct decoder_pattern
const png_patterns
[] = {
774 {8,0,png_magic
,mask_all
,0},
778 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
779 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
781 static GUID
const * const tiff_decode_formats
[] = {
782 &GUID_WICPixelFormatBlackWhite
,
783 &GUID_WICPixelFormat4bppGray
,
784 &GUID_WICPixelFormat8bppGray
,
785 &GUID_WICPixelFormat4bppIndexed
,
786 &GUID_WICPixelFormat8bppIndexed
,
787 &GUID_WICPixelFormat24bppBGR
,
788 &GUID_WICPixelFormat32bppBGR
,
789 &GUID_WICPixelFormat32bppBGRA
,
790 &GUID_WICPixelFormat32bppPBGRA
,
791 &GUID_WICPixelFormat48bppRGB
,
792 &GUID_WICPixelFormat64bppRGBA
,
793 &GUID_WICPixelFormat64bppPRGBA
,
797 static struct decoder_pattern
const tiff_patterns
[] = {
798 {4,0,tiff_magic_le
,mask_all
,0},
799 {4,0,tiff_magic_be
,mask_all
,0},
803 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
805 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};
806 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};
808 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};
809 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};
811 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};
812 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};
814 static GUID
const * const tga_formats
[] = {
815 &GUID_WICPixelFormat8bppGray
,
816 &GUID_WICPixelFormat8bppIndexed
,
817 &GUID_WICPixelFormat16bppGray
,
818 &GUID_WICPixelFormat16bppBGR555
,
819 &GUID_WICPixelFormat24bppBGR
,
820 &GUID_WICPixelFormat32bppBGRA
,
821 &GUID_WICPixelFormat32bppPBGRA
,
825 static struct decoder_pattern
const tga_patterns
[] = {
826 {18,18,tga_footer_magic
,mask_all
,1},
827 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
828 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
829 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
833 static struct regsvr_decoder
const decoder_list
[] = {
834 { &CLSID_WICBmpDecoder
,
838 &GUID_VendorMicrosoft
,
839 &GUID_ContainerFormatBmp
,
845 { &CLSID_WICGifDecoder
,
849 &GUID_VendorMicrosoft
,
850 &GUID_ContainerFormatGif
,
856 { &CLSID_WICIcoDecoder
,
860 &GUID_VendorMicrosoft
,
861 &GUID_ContainerFormatIco
,
862 "image/vnd.microsoft.icon",
867 { &CLSID_WICJpegDecoder
,
871 &GUID_VendorMicrosoft
,
872 &GUID_ContainerFormatJpeg
,
878 { &CLSID_WICPngDecoder
,
882 &GUID_VendorMicrosoft
,
883 &GUID_ContainerFormatPng
,
889 { &CLSID_WICTiffDecoder
,
893 &GUID_VendorMicrosoft
,
894 &GUID_ContainerFormatTiff
,
900 { &CLSID_WineTgaDecoder
,
905 &GUID_WineContainerFormatTga
,
911 { NULL
} /* list terminator */
914 static GUID
const * const bmp_encode_formats
[] = {
915 &GUID_WICPixelFormat16bppBGR555
,
916 &GUID_WICPixelFormat16bppBGR565
,
917 &GUID_WICPixelFormat24bppBGR
,
918 &GUID_WICPixelFormat32bppBGR
,
922 static GUID
const * const png_encode_formats
[] = {
923 &GUID_WICPixelFormat24bppBGR
,
924 &GUID_WICPixelFormatBlackWhite
,
925 &GUID_WICPixelFormat2bppGray
,
926 &GUID_WICPixelFormat4bppGray
,
927 &GUID_WICPixelFormat8bppGray
,
928 &GUID_WICPixelFormat16bppGray
,
929 &GUID_WICPixelFormat32bppBGR
,
930 &GUID_WICPixelFormat32bppBGRA
,
931 &GUID_WICPixelFormat48bppRGB
,
932 &GUID_WICPixelFormat64bppRGBA
,
936 static GUID
const * const tiff_encode_formats
[] = {
937 &GUID_WICPixelFormatBlackWhite
,
938 &GUID_WICPixelFormat4bppGray
,
939 &GUID_WICPixelFormat8bppGray
,
940 &GUID_WICPixelFormat24bppBGR
,
941 &GUID_WICPixelFormat32bppBGRA
,
942 &GUID_WICPixelFormat32bppPBGRA
,
943 &GUID_WICPixelFormat48bppRGB
,
944 &GUID_WICPixelFormat64bppRGBA
,
945 &GUID_WICPixelFormat64bppPRGBA
,
949 static GUID
const * const icns_encode_formats
[] = {
950 &GUID_WICPixelFormat32bppBGRA
,
954 static struct regsvr_encoder
const encoder_list
[] = {
955 { &CLSID_WICBmpEncoder
,
959 &GUID_VendorMicrosoft
,
960 &GUID_ContainerFormatBmp
,
965 { &CLSID_WICJpegEncoder
,
969 &GUID_VendorMicrosoft
,
970 &GUID_ContainerFormatJpeg
,
975 { &CLSID_WICPngEncoder
,
979 &GUID_VendorMicrosoft
,
980 &GUID_ContainerFormatPng
,
985 { &CLSID_WICTiffEncoder
,
989 &GUID_VendorMicrosoft
,
990 &GUID_ContainerFormatTiff
,
995 { &CLSID_WICIcnsEncoder
,
1000 NULL
, /* no container format guid */
1005 { NULL
} /* list terminator */
1008 static GUID
const * const converter_formats
[] = {
1009 &GUID_WICPixelFormat1bppIndexed
,
1010 &GUID_WICPixelFormat2bppIndexed
,
1011 &GUID_WICPixelFormat4bppIndexed
,
1012 &GUID_WICPixelFormat8bppIndexed
,
1013 &GUID_WICPixelFormatBlackWhite
,
1014 &GUID_WICPixelFormat2bppGray
,
1015 &GUID_WICPixelFormat4bppGray
,
1016 &GUID_WICPixelFormat8bppGray
,
1017 &GUID_WICPixelFormat16bppGray
,
1018 &GUID_WICPixelFormat16bppBGR555
,
1019 &GUID_WICPixelFormat16bppBGR565
,
1020 &GUID_WICPixelFormat16bppBGRA5551
,
1021 &GUID_WICPixelFormat24bppBGR
,
1022 &GUID_WICPixelFormat32bppBGR
,
1023 &GUID_WICPixelFormat32bppBGRA
,
1024 &GUID_WICPixelFormat32bppPBGRA
,
1025 &GUID_WICPixelFormat48bppRGB
,
1026 &GUID_WICPixelFormat64bppRGBA
,
1027 &GUID_WICPixelFormat32bppCMYK
,
1031 static struct regsvr_converter
const converter_list
[] = {
1032 { &CLSID_WICDefaultFormatConverter
,
1034 "Default Pixel Format Converter",
1036 &GUID_VendorMicrosoft
,
1039 { NULL
} /* list terminator */
1042 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
1043 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
1045 HRESULT WINAPI
DllRegisterServer(void)
1051 hr
= WIC_DllRegisterServer();
1053 register_decoders(decoder_list
);
1055 register_encoders(encoder_list
);
1057 register_converters(converter_list
);
1061 HRESULT WINAPI
DllUnregisterServer(void)
1067 hr
= WIC_DllUnregisterServer();
1069 unregister_decoders(decoder_list
);
1071 unregister_encoders(encoder_list
);
1073 unregister_converters(converter_list
);