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
31 #include "wincodecs_private.h"
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35 #include "wine/list.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
40 const IWICBitmapDecoderInfoVtbl *lpIWICBitmapDecoderInfoVtbl;
46 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
49 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface;
50 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
52 if (!ppv) return E_INVALIDARG;
54 if (IsEqualIID(&IID_IUnknown, iid) ||
55 IsEqualIID(&IID_IWICComponentInfo, iid) ||
56 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
57 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
67 IUnknown_AddRef((IUnknown*)*ppv);
71 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
73 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface;
74 ULONG ref = InterlockedIncrement(&This->ref);
76 TRACE("(%p) refcount=%u\n", iface, ref);
81 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
83 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface;
84 ULONG ref = InterlockedDecrement(&This->ref);
86 TRACE("(%p) refcount=%u\n", iface, ref);
90 RegCloseKey(This->classkey);
91 HeapFree(GetProcessHeap(), 0, This);
97 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
98 WICComponentType *pType)
100 TRACE("(%p,%p)\n", iface, pType);
105 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
107 FIXME("(%p,%p): stub\n", iface, pclsid);
111 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
113 FIXME("(%p,%p): stub\n", iface, pStatus);
117 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
118 WCHAR *wzAuthor, UINT *pcchActual)
120 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
124 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
126 FIXME("(%p,%p): stub\n", iface, pguidVendor);
130 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
131 WCHAR *wzVersion, UINT *pcchActual)
133 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
137 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
138 WCHAR *wzSpecVersion, UINT *pcchActual)
140 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
144 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
145 WCHAR *wzFriendlyName, UINT *pcchActual)
147 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
151 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
152 GUID *pguidContainerFormat)
154 FIXME("(%p,%p): stub\n", iface, pguidContainerFormat);
158 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
159 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
161 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
165 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
166 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
168 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
172 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
173 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
175 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
179 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
180 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
182 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
186 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
187 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
189 FIXME("(%p,%u,%p,%p): stub\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
193 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
194 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
196 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
200 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
201 BOOL *pfSupportAnimation)
203 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
207 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
208 BOOL *pfSupportChromaKey)
210 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
214 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
215 BOOL *pfSupportLossless)
217 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
221 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
222 BOOL *pfSupportMultiframe)
224 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
228 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
229 LPCWSTR wzMimeType, BOOL *pfMatches)
231 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
235 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
236 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
238 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface;
239 UINT pattern_count=0, patterns_size=0;
240 WCHAR subkeyname[11];
242 HKEY patternskey, patternkey;
243 static const WCHAR uintformatW[] = {'%','u',0};
244 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
245 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
246 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
247 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
248 static const WCHAR maskW[] = {'M','a','s','k',0};
249 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
252 BYTE *bPatterns=(BYTE*)pPatterns;
253 DWORD length, valuesize;
255 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
257 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
258 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
260 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
261 if (res == ERROR_SUCCESS)
263 patterns_size = pattern_count * sizeof(WICBitmapPattern);
265 for (i=0; i<pattern_count; i++)
267 snprintfW(subkeyname, 11, uintformatW, i);
268 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
269 if (res == ERROR_SUCCESS)
271 valuesize = sizeof(ULONG);
272 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
273 &length, &valuesize);
274 patterns_size += length*2;
276 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
278 pPatterns[i].Length = length;
280 pPatterns[i].EndOfStream = 0;
281 valuesize = sizeof(BOOL);
282 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
283 &pPatterns[i].EndOfStream, &valuesize);
285 pPatterns[i].Position.QuadPart = 0;
286 valuesize = sizeof(ULARGE_INTEGER);
287 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
288 &pPatterns[i].Position, &valuesize);
290 if (res == ERROR_SUCCESS)
292 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
294 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
295 pPatterns[i].Pattern, &valuesize);
298 if (res == ERROR_SUCCESS)
300 pPatterns[i].Mask = bPatterns+patterns_size-length;
302 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
303 pPatterns[i].Mask, &valuesize);
307 RegCloseKey(patternkey);
309 if (res != ERROR_SUCCESS)
311 hr = HRESULT_FROM_WIN32(res);
316 else hr = HRESULT_FROM_WIN32(res);
318 RegCloseKey(patternskey);
322 *pcPatterns = pattern_count;
323 *pcbPatternsActual = patterns_size;
324 if (pPatterns && cbSizePatterns < patterns_size)
325 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
331 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
332 IStream *pIStream, BOOL *pfMatches)
334 WICBitmapPattern *patterns;
335 UINT pattern_count=0, patterns_size=0;
341 LARGE_INTEGER seekpos;
343 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
345 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
346 if (FAILED(hr)) return hr;
348 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
349 if (!patterns) return E_OUTOFMEMORY;
351 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
352 if (FAILED(hr)) goto end;
354 for (i=0; i<pattern_count; i++)
356 if (datasize < patterns[i].Length)
358 HeapFree(GetProcessHeap(), 0, data);
359 datasize = patterns[i].Length;
360 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
368 if (patterns[i].EndOfStream)
369 seekpos.QuadPart = -patterns[i].Position.QuadPart;
371 seekpos.QuadPart = patterns[i].Position.QuadPart;
372 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
373 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
374 if (FAILED(hr)) break;
376 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
377 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
379 if (FAILED(hr)) break;
381 for (pos=0; pos<patterns[i].Length; pos++)
383 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
386 if (pos == patterns[i].Length) /* matches pattern */
394 if (i == pattern_count) /* does not match any pattern */
401 HeapFree(GetProcessHeap(), 0, patterns);
402 HeapFree(GetProcessHeap(), 0, data);
407 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
408 IWICBitmapDecoder **ppIBitmapDecoder)
410 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface;
412 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
414 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
415 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
418 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
419 BitmapDecoderInfo_QueryInterface,
420 BitmapDecoderInfo_AddRef,
421 BitmapDecoderInfo_Release,
422 BitmapDecoderInfo_GetComponentType,
423 BitmapDecoderInfo_GetCLSID,
424 BitmapDecoderInfo_GetSigningStatus,
425 BitmapDecoderInfo_GetAuthor,
426 BitmapDecoderInfo_GetVendorGUID,
427 BitmapDecoderInfo_GetVersion,
428 BitmapDecoderInfo_GetSpecVersion,
429 BitmapDecoderInfo_GetFriendlyName,
430 BitmapDecoderInfo_GetContainerFormat,
431 BitmapDecoderInfo_GetPixelFormats,
432 BitmapDecoderInfo_GetColorManagementVersion,
433 BitmapDecoderInfo_GetDeviceManufacturer,
434 BitmapDecoderInfo_GetDeviceModels,
435 BitmapDecoderInfo_GetMimeTypes,
436 BitmapDecoderInfo_GetFileExtensions,
437 BitmapDecoderInfo_DoesSupportAnimation,
438 BitmapDecoderInfo_DoesSupportChromaKey,
439 BitmapDecoderInfo_DoesSupportLossless,
440 BitmapDecoderInfo_DoesSupportMultiframe,
441 BitmapDecoderInfo_MatchesMimeType,
442 BitmapDecoderInfo_GetPatterns,
443 BitmapDecoderInfo_MatchesPattern,
444 BitmapDecoderInfo_CreateInstance
447 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
449 BitmapDecoderInfo *This;
451 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
454 RegCloseKey(classkey);
455 return E_OUTOFMEMORY;
458 This->lpIWICBitmapDecoderInfoVtbl = &BitmapDecoderInfo_Vtbl;
460 This->classkey = classkey;
461 memcpy(&This->clsid, clsid, sizeof(CLSID));
463 *ppIInfo = (IWICComponentInfo*)This;
467 static WCHAR const clsid_keyname[] = {'C','L','S','I','D',0};
468 static WCHAR const instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
471 WICComponentType type;
473 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
476 static const struct category categories[] = {
477 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
481 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
487 WCHAR guidstring[39];
489 const struct category *category;
493 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
494 if (res != ERROR_SUCCESS)
495 return HRESULT_FROM_WIN32(res);
497 for (category=categories; category->type; category++)
499 StringFromGUID2(category->catid, guidstring, 39);
500 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
501 if (res == ERROR_SUCCESS)
503 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
504 if (res == ERROR_SUCCESS)
506 StringFromGUID2(clsid, guidstring, 39);
507 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
508 if (res == ERROR_SUCCESS)
510 RegCloseKey(classkey);
513 RegCloseKey(instancekey);
515 RegCloseKey(catidkey);
522 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
523 if (res == ERROR_SUCCESS)
524 hr = category->constructor(classkey, clsid, ppIInfo);
526 hr = HRESULT_FROM_WIN32(res);
531 RegCloseKey(clsidkey);
537 const IEnumUnknownVtbl *IEnumUnknown_Vtbl;
548 static const IEnumUnknownVtbl ComponentEnumVtbl;
550 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
553 ComponentEnum *This = (ComponentEnum*)iface;
554 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
556 if (!ppv) return E_INVALIDARG;
558 if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IEnumUnknown, iid))
565 return E_NOINTERFACE;
568 IUnknown_AddRef((IUnknown*)*ppv);
572 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
574 ComponentEnum *This = (ComponentEnum*)iface;
575 ULONG ref = InterlockedIncrement(&This->ref);
577 TRACE("(%p) refcount=%u\n", iface, ref);
582 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
584 ComponentEnum *This = (ComponentEnum*)iface;
585 ULONG ref = InterlockedDecrement(&This->ref);
586 ComponentEnumItem *cursor, *cursor2;
588 TRACE("(%p) refcount=%u\n", iface, ref);
592 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
594 IUnknown_Release(cursor->unk);
595 list_remove(&cursor->entry);
596 HeapFree(GetProcessHeap(), 0, cursor);
598 HeapFree(GetProcessHeap(), 0, This);
604 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
605 IUnknown **rgelt, ULONG *pceltFetched)
607 ComponentEnum *This = (ComponentEnum*)iface;
609 ComponentEnumItem *item;
611 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
613 while (num_fetched<celt)
617 *pceltFetched = num_fetched;
620 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
621 IUnknown_AddRef(item->unk);
622 rgelt[num_fetched] = item->unk;
624 This->cursor = list_next(&This->objects, This->cursor);
626 *pceltFetched = num_fetched;
630 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
632 ComponentEnum *This = (ComponentEnum*)iface;
635 TRACE("(%p,%u)\n", iface, celt);
637 for (i=0; i<celt; i++)
641 This->cursor = list_next(&This->objects, This->cursor);
646 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
648 ComponentEnum *This = (ComponentEnum*)iface;
650 TRACE("(%p)\n", iface);
652 This->cursor = list_head(&This->objects);
656 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
658 ComponentEnum *This = (ComponentEnum*)iface;
659 ComponentEnum *new_enum;
660 ComponentEnumItem *old_item, *new_item;
663 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
667 return E_OUTOFMEMORY;
670 new_enum->IEnumUnknown_Vtbl = &ComponentEnumVtbl;
672 new_enum->cursor = NULL;
674 list_init(&new_enum->objects);
675 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
677 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
683 new_item->unk = old_item->unk;
684 list_add_tail(&new_enum->objects, &new_item->entry);
685 IUnknown_AddRef(new_item->unk);
686 if (&old_item->entry == This->cursor) new_enum->cursor = &new_item->entry;
691 IUnknown_Release((IUnknown*)new_enum);
695 *ppenum = (IEnumUnknown*)new_enum;
700 static const IEnumUnknownVtbl ComponentEnumVtbl = {
701 ComponentEnum_QueryInterface,
702 ComponentEnum_AddRef,
703 ComponentEnum_Release,
710 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
713 ComponentEnumItem *item;
714 const struct category *category;
715 HKEY clsidkey, catidkey, instancekey;
716 WCHAR guidstring[39];
722 if (options) FIXME("ignoring flags %x\n", options);
724 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
725 if (res != ERROR_SUCCESS)
726 return HRESULT_FROM_WIN32(res);
728 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
731 RegCloseKey(clsidkey);
732 return E_OUTOFMEMORY;
735 This->IEnumUnknown_Vtbl = &ComponentEnumVtbl;
737 list_init(&This->objects);
739 for (category=categories; category->type && hr == S_OK; category++)
741 if ((category->type & componentTypes) == 0) continue;
742 StringFromGUID2(category->catid, guidstring, 39);
743 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
744 if (res == ERROR_SUCCESS)
746 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
747 if (res == ERROR_SUCCESS)
752 DWORD guidstring_size = 39;
753 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
754 if (res != ERROR_SUCCESS) break;
756 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
757 if (!item) { hr = E_OUTOFMEMORY; break; }
759 hr = CLSIDFromString(guidstring, &clsid);
762 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
764 list_add_tail(&This->objects, &item->entry);
769 HeapFree(GetProcessHeap(), 0, item);
773 RegCloseKey(instancekey);
775 RegCloseKey(catidkey);
777 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
778 hr = HRESULT_FROM_WIN32(res);
780 RegCloseKey(clsidkey);
784 IEnumUnknown_Reset((IEnumUnknown*)This);
785 *ppIEnumUnknown = (IEnumUnknown*)This;
789 *ppIEnumUnknown = NULL;
790 IUnknown_Release((IUnknown*)This);