wbemprox: Prefer the standard ARRAY_SIZE macro.
[wine.git] / dlls / msdmo / dmoreg.c
blob864cb859e60b923ebadd6a550f49ca44f25c3085
1 /*
2 * Copyright (C) 2003 Michael Günnewig
3 * Copyright (C) 2003 CodeWeavers Inc. (Ulrich Czekalla)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winerror.h"
28 #include "winreg.h"
29 #include "objbase.h"
30 #include "wine/unicode.h"
31 #include "wine/debug.h"
32 #include "dmo.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(msdmo);
36 #define MSDMO_MAJOR_VERSION 6
38 static const WCHAR szDMORootKey[] =
40 'D','i','r','e','c','t','S','h','o','w','\\',
41 'M','e','d','i','a','O','b','j','e','c','t','s',0
42 };
44 static const WCHAR szDMOInputType[] =
46 'I','n','p','u','t','T','y','p','e','s',0
49 static const WCHAR szDMOOutputType[] =
51 'O','u','t','p','u','t','T','y','p','e','s',0
54 static const WCHAR szDMOKeyed[] =
56 'K','e','y','e','d',0
59 static const WCHAR szDMOCategories[] =
61 'C','a','t','e','g','o','r','i','e','s',0
64 static const WCHAR szGUIDFmt[] =
66 '%','0','8','X','-','%','0','4','X','-','%','0','4','X','-','%','0',
67 '2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2',
68 'X','%','0','2','X','%','0','2','X','%','0','2','X',0
71 static const WCHAR szCat3Fmt[] =
73 '%','s','\\','%','s','\\','%','s',0
76 static const WCHAR szCat2Fmt[] =
78 '%','s','\\','%','s',0
81 static const WCHAR szToGuidFmt[] =
83 '{','%','s','}',0
87 typedef struct
89 IEnumDMO IEnumDMO_iface;
90 LONG ref;
91 DWORD index;
92 GUID category;
93 DWORD dwFlags;
94 DWORD cInTypes;
95 DMO_PARTIAL_MEDIATYPE *pInTypes;
96 DWORD cOutTypes;
97 DMO_PARTIAL_MEDIATYPE *pOutTypes;
98 HKEY hkey;
99 } IEnumDMOImpl;
101 static inline IEnumDMOImpl *impl_from_IEnumDMO(IEnumDMO *iface)
103 return CONTAINING_RECORD(iface, IEnumDMOImpl, IEnumDMO_iface);
106 static HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types);
108 static const IEnumDMOVtbl edmovt;
110 static LPWSTR GUIDToString(LPWSTR lpwstr, REFGUID lpcguid)
112 wsprintfW(lpwstr, szGUIDFmt, lpcguid->Data1, lpcguid->Data2,
113 lpcguid->Data3, lpcguid->Data4[0], lpcguid->Data4[1],
114 lpcguid->Data4[2], lpcguid->Data4[3], lpcguid->Data4[4],
115 lpcguid->Data4[5], lpcguid->Data4[6], lpcguid->Data4[7]);
117 return lpwstr;
120 static HRESULT string_to_guid(const WCHAR *string, GUID *guid)
122 WCHAR buffer[39];
123 buffer[0] = '{';
124 strcpyW(buffer + 1, string);
125 buffer[37] = '}';
126 buffer[38] = 0;
127 return CLSIDFromString(buffer, guid);
130 static BOOL IsMediaTypeEqual(const DMO_PARTIAL_MEDIATYPE* mt1, const DMO_PARTIAL_MEDIATYPE* mt2)
133 return (IsEqualCLSID(&mt1->type, &mt2->type) ||
134 IsEqualCLSID(&mt2->type, &GUID_NULL) ||
135 IsEqualCLSID(&mt1->type, &GUID_NULL)) &&
136 (IsEqualCLSID(&mt1->subtype, &mt2->subtype) ||
137 IsEqualCLSID(&mt2->subtype, &GUID_NULL) ||
138 IsEqualCLSID(&mt1->subtype, &GUID_NULL));
141 static HRESULT write_types(HKEY hkey, LPCWSTR name, const DMO_PARTIAL_MEDIATYPE* types, DWORD count)
143 LONG ret;
145 if (MSDMO_MAJOR_VERSION > 5)
147 ret = RegSetValueExW(hkey, name, 0, REG_BINARY, (const BYTE*) types,
148 count* sizeof(DMO_PARTIAL_MEDIATYPE));
150 else
152 HKEY skey1,skey2,skey3;
153 DWORD index = 0;
154 WCHAR szGuidKey[64];
156 ret = RegCreateKeyExW(hkey, name, 0, NULL, REG_OPTION_NON_VOLATILE,
157 KEY_WRITE, NULL, &skey1, NULL);
158 if (ret)
159 return HRESULT_FROM_WIN32(ret);
161 while (index < count)
163 GUIDToString(szGuidKey,&types[index].type);
164 ret = RegCreateKeyExW(skey1, szGuidKey, 0, NULL,
165 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey2, NULL);
166 GUIDToString(szGuidKey,&types[index].subtype);
167 ret = RegCreateKeyExW(skey2, szGuidKey, 0, NULL,
168 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey3, NULL);
169 RegCloseKey(skey3);
170 RegCloseKey(skey2);
171 index ++;
173 RegCloseKey(skey1);
176 return HRESULT_FROM_WIN32(ret);
179 /***************************************************************
180 * DMORegister (MSDMO.@)
182 * Register a DirectX Media Object.
184 HRESULT WINAPI DMORegister(
185 LPCWSTR szName,
186 REFCLSID clsidDMO,
187 REFGUID guidCategory,
188 DWORD dwFlags,
189 DWORD cInTypes,
190 const DMO_PARTIAL_MEDIATYPE *pInTypes,
191 DWORD cOutTypes,
192 const DMO_PARTIAL_MEDIATYPE *pOutTypes
195 WCHAR szguid[64];
196 HRESULT hres;
197 HKEY hrkey = 0;
198 HKEY hkey = 0;
199 HKEY hckey = 0;
200 HKEY hclskey = 0;
201 LONG ret;
203 TRACE("%s %s %s\n", debugstr_w(szName), debugstr_guid(clsidDMO), debugstr_guid(guidCategory));
205 if (IsEqualGUID(guidCategory, &GUID_NULL))
206 return E_INVALIDARG;
208 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, NULL,
209 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hrkey, NULL);
210 if (ret)
211 return E_FAIL;
213 /* Create clsidDMO key under MediaObjects */
214 ret = RegCreateKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, NULL,
215 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
216 if (ret)
217 goto lend;
219 /* Set default Name value */
220 ret = RegSetValueExW(hkey, NULL, 0, REG_SZ, (const BYTE*) szName,
221 (strlenW(szName) + 1) * sizeof(WCHAR));
223 /* Set InputTypes */
224 hres = write_types(hkey, szDMOInputType, pInTypes, cInTypes);
226 /* Set OutputTypes */
227 hres = write_types(hkey, szDMOOutputType, pOutTypes, cOutTypes);
229 if (dwFlags & DMO_REGISTERF_IS_KEYED)
231 /* Create Keyed key */
232 ret = RegCreateKeyExW(hkey, szDMOKeyed, 0, NULL,
233 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
234 if (ret)
235 goto lend;
236 RegCloseKey(hckey);
239 /* Register the category */
240 ret = RegCreateKeyExW(hrkey, szDMOCategories, 0, NULL,
241 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
242 if (ret)
243 goto lend;
245 RegCloseKey(hkey);
247 ret = RegCreateKeyExW(hckey, GUIDToString(szguid, guidCategory), 0, NULL,
248 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
249 if (ret)
250 goto lend;
251 ret = RegCreateKeyExW(hkey, GUIDToString(szguid, clsidDMO), 0, NULL,
252 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hclskey, NULL);
253 if (ret)
254 goto lend;
256 lend:
257 if (hkey)
258 RegCloseKey(hkey);
259 if (hckey)
260 RegCloseKey(hckey);
261 if (hclskey)
262 RegCloseKey(hclskey);
263 if (hrkey)
264 RegCloseKey(hrkey);
266 hres = HRESULT_FROM_WIN32(ret);
267 TRACE(" hresult=0x%08x\n", hres);
268 return hres;
271 static HRESULT unregister_dmo_from_category(const WCHAR *dmoW, const WCHAR *catW, HKEY categories)
273 HKEY catkey;
274 LONG ret;
276 ret = RegOpenKeyExW(categories, catW, 0, KEY_WRITE, &catkey);
277 if (!ret)
279 ret = RegDeleteKeyW(catkey, dmoW);
280 RegCloseKey(catkey);
283 return !ret ? S_OK : S_FALSE;
286 /***************************************************************
287 * DMOUnregister (MSDMO.@)
289 * Unregister a DirectX Media Object.
291 HRESULT WINAPI DMOUnregister(REFCLSID dmo, REFGUID category)
293 HKEY rootkey = 0, categorieskey = 0;
294 WCHAR dmoW[64], catW[64];
295 HRESULT hr = S_FALSE;
296 LONG ret;
298 TRACE("%s %s\n", debugstr_guid(dmo), debugstr_guid(category));
300 ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_WRITE, &rootkey);
301 if (ret)
302 return S_FALSE;
304 GUIDToString(dmoW, dmo);
305 RegDeleteKeyW(rootkey, dmoW);
307 /* open 'Categories' */
308 ret = RegOpenKeyExW(rootkey, szDMOCategories, 0, KEY_WRITE|KEY_ENUMERATE_SUB_KEYS, &categorieskey);
309 RegCloseKey(rootkey);
310 if (ret)
312 hr = HRESULT_FROM_WIN32(ret);
313 goto lend;
316 /* remove from all categories */
317 if (IsEqualGUID(category, &GUID_NULL))
319 DWORD index = 0, len = ARRAY_SIZE(catW);
321 while (!RegEnumKeyExW(categorieskey, index++, catW, &len, NULL, NULL, NULL, NULL))
322 hr = unregister_dmo_from_category(dmoW, catW, categorieskey);
324 else
326 GUIDToString(catW, category);
327 hr = unregister_dmo_from_category(dmoW, catW, categorieskey);
330 lend:
331 if (categorieskey)
332 RegCloseKey(categorieskey);
334 return hr;
338 /***************************************************************
339 * DMOGetName (MSDMO.@)
341 * Get DMO Name from the registry
343 HRESULT WINAPI DMOGetName(REFCLSID clsidDMO, WCHAR name[])
345 static const INT max_name_len = 80*sizeof(WCHAR);
346 DWORD count = max_name_len;
347 WCHAR szguid[64];
348 HKEY hrkey, hkey;
349 LONG ret;
351 TRACE("%s %p\n", debugstr_guid(clsidDMO), name);
353 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_READ, &hrkey))
354 return E_FAIL;
356 ret = RegOpenKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, KEY_READ, &hkey);
357 RegCloseKey(hrkey);
358 if (ret)
359 return E_FAIL;
361 ret = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)name, &count);
362 RegCloseKey(hkey);
364 if (!ret && count > 1)
366 TRACE("name=%s\n", debugstr_w(name));
367 return S_OK;
370 name[0] = 0;
371 return S_FALSE;
374 static HRESULT dup_partial_mediatype(const DMO_PARTIAL_MEDIATYPE *types, DWORD count, DMO_PARTIAL_MEDIATYPE **ret)
376 *ret = NULL;
378 if (count == 0)
379 return S_OK;
381 *ret = HeapAlloc(GetProcessHeap(), 0, count*sizeof(*types));
382 if (!*ret)
383 return E_OUTOFMEMORY;
385 memcpy(*ret, types, count*sizeof(*types));
386 return S_OK;
389 /**************************************************************************
390 * IEnumDMO_Constructor
392 static HRESULT IEnumDMO_Constructor(
393 REFGUID guidCategory,
394 DWORD dwFlags,
395 DWORD cInTypes,
396 const DMO_PARTIAL_MEDIATYPE *pInTypes,
397 DWORD cOutTypes,
398 const DMO_PARTIAL_MEDIATYPE *pOutTypes,
399 IEnumDMO **obj)
401 IEnumDMOImpl* lpedmo;
402 HRESULT hr;
404 *obj = NULL;
406 lpedmo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumDMOImpl));
407 if (!lpedmo)
408 return E_OUTOFMEMORY;
410 lpedmo->IEnumDMO_iface.lpVtbl = &edmovt;
411 lpedmo->ref = 1;
412 lpedmo->index = -1;
413 lpedmo->category = *guidCategory;
414 lpedmo->dwFlags = dwFlags;
415 lpedmo->cInTypes = cInTypes;
416 lpedmo->cOutTypes = cOutTypes;
417 lpedmo->hkey = NULL;
419 hr = dup_partial_mediatype(pInTypes, cInTypes, &lpedmo->pInTypes);
420 if (FAILED(hr))
421 goto lerr;
423 hr = dup_partial_mediatype(pOutTypes, cOutTypes, &lpedmo->pOutTypes);
424 if (FAILED(hr))
425 goto lerr;
427 /* If not filtering by category enum from media objects root */
428 if (IsEqualGUID(guidCategory, &GUID_NULL))
430 RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_READ, &lpedmo->hkey);
432 else
434 WCHAR szguid[64];
435 WCHAR szKey[MAX_PATH];
437 wsprintfW(szKey, szCat3Fmt, szDMORootKey, szDMOCategories, GUIDToString(szguid, guidCategory));
438 RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &lpedmo->hkey);
441 lerr:
443 if (FAILED(hr))
444 IEnumDMO_Release(&lpedmo->IEnumDMO_iface);
445 else
447 TRACE("returning %p\n", lpedmo);
448 *obj = &lpedmo->IEnumDMO_iface;
451 return hr;
454 /******************************************************************************
455 * IEnumDMO_fnAddRef
457 static ULONG WINAPI IEnumDMO_fnAddRef(IEnumDMO * iface)
459 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
460 ULONG refCount = InterlockedIncrement(&This->ref);
461 TRACE("(%p)->(%d)\n", This, refCount);
462 return refCount;
465 /**************************************************************************
466 * EnumDMO_QueryInterface
468 static HRESULT WINAPI IEnumDMO_fnQueryInterface(IEnumDMO* iface, REFIID riid, void **ppvObj)
470 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
472 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObj);
474 *ppvObj = NULL;
476 if (IsEqualIID(riid, &IID_IEnumDMO) ||
477 IsEqualIID(riid, &IID_IUnknown))
479 *ppvObj = iface;
480 IEnumDMO_AddRef(iface);
483 return *ppvObj ? S_OK : E_NOINTERFACE;
486 /******************************************************************************
487 * IEnumDMO_fnRelease
489 static ULONG WINAPI IEnumDMO_fnRelease(IEnumDMO * iface)
491 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
492 ULONG refCount = InterlockedDecrement(&This->ref);
494 TRACE("(%p)->(%d)\n", This, refCount);
496 if (!refCount)
498 if (This->hkey)
499 RegCloseKey(This->hkey);
500 HeapFree(GetProcessHeap(), 0, This->pInTypes);
501 HeapFree(GetProcessHeap(), 0, This->pOutTypes);
502 HeapFree(GetProcessHeap(), 0, This);
504 return refCount;
508 /******************************************************************************
509 * IEnumDMO_fnNext
511 static HRESULT WINAPI IEnumDMO_fnNext(
512 IEnumDMO * iface,
513 DWORD cItemsToFetch,
514 CLSID * pCLSID,
515 WCHAR ** Names,
516 DWORD * pcItemsFetched)
518 HKEY hkey;
519 WCHAR szNextKey[MAX_PATH];
520 WCHAR szGuidKey[64];
521 WCHAR szKey[MAX_PATH];
522 WCHAR szValue[MAX_PATH];
523 DWORD len;
524 UINT count = 0;
525 HRESULT hres = S_OK;
526 LONG ret;
527 GUID guid;
529 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
531 TRACE("(%p)->(%d %p %p %p)\n", This, cItemsToFetch, pCLSID, Names, pcItemsFetched);
533 if (!pCLSID || !Names)
534 return E_POINTER;
536 if (!pcItemsFetched && cItemsToFetch > 1)
537 return E_INVALIDARG;
539 while (count < cItemsToFetch)
541 This->index++;
543 len = MAX_PATH;
544 ret = RegEnumKeyExW(This->hkey, This->index, szNextKey, &len, NULL, NULL, NULL, NULL);
545 if (ret != ERROR_SUCCESS)
547 hres = HRESULT_FROM_WIN32(ret);
548 break;
551 if (string_to_guid(szNextKey, &guid) != S_OK)
552 continue;
554 TRACE("found %s\n", debugstr_w(szNextKey));
556 if (!(This->dwFlags & DMO_ENUMF_INCLUDE_KEYED))
558 wsprintfW(szKey, szCat3Fmt, szDMORootKey, szNextKey, szDMOKeyed);
559 ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
560 if (ERROR_SUCCESS == ret)
562 RegCloseKey(hkey);
563 /* Skip Keyed entries */
564 continue;
568 wsprintfW(szKey, szCat2Fmt, szDMORootKey, szNextKey);
569 ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
570 TRACE("testing %s\n", debugstr_w(szKey));
572 if (This->pInTypes)
574 UINT i, j;
575 DWORD cInTypes;
576 DMO_PARTIAL_MEDIATYPE* pInTypes;
578 hres = read_types(hkey, szDMOInputType, &cInTypes,
579 sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
580 (DMO_PARTIAL_MEDIATYPE*)szValue);
582 if (FAILED(hres))
584 RegCloseKey(hkey);
585 continue;
588 pInTypes = (DMO_PARTIAL_MEDIATYPE *)szValue;
590 TRACE("read %d intypes for %s:\n", cInTypes, debugstr_w(szKey));
591 for (i = 0; i < cInTypes; i++) {
592 TRACE("intype %d: type %s, subtype %s\n", i, debugstr_guid(&pInTypes[i].type),
593 debugstr_guid(&pInTypes[i].subtype));
596 for (i = 0; i < This->cInTypes; i++)
598 for (j = 0; j < cInTypes; j++)
600 if (IsMediaTypeEqual(&pInTypes[j], &This->pInTypes[i]))
601 break;
604 if (j >= cInTypes)
605 break;
608 if (i < This->cInTypes)
610 RegCloseKey(hkey);
611 continue;
615 if (This->pOutTypes)
617 UINT i, j;
618 DWORD cOutTypes;
619 DMO_PARTIAL_MEDIATYPE* pOutTypes;
621 hres = read_types(hkey, szDMOOutputType, &cOutTypes,
622 sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
623 (DMO_PARTIAL_MEDIATYPE*)szValue);
625 if (FAILED(hres))
627 RegCloseKey(hkey);
628 continue;
631 pOutTypes = (DMO_PARTIAL_MEDIATYPE *)szValue;
633 TRACE("read %d outtypes for %s:\n", cOutTypes, debugstr_w(szKey));
634 for (i = 0; i < cOutTypes; i++) {
635 TRACE("outtype %d: type %s, subtype %s\n", i, debugstr_guid(&pOutTypes[i].type),
636 debugstr_guid(&pOutTypes[i].subtype));
639 for (i = 0; i < This->cOutTypes; i++)
641 for (j = 0; j < cOutTypes; j++)
643 if (IsMediaTypeEqual(&pOutTypes[j], &This->pOutTypes[i]))
644 break;
647 if (j >= cOutTypes)
648 break;
651 if (i < This->cOutTypes)
653 RegCloseKey(hkey);
654 continue;
658 /* Media object wasn't filtered so add it to return list */
659 Names[count] = NULL;
660 len = MAX_PATH * sizeof(WCHAR);
661 ret = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)szValue, &len);
662 if (ERROR_SUCCESS == ret)
664 Names[count] = CoTaskMemAlloc((strlenW(szValue) + 1) * sizeof(WCHAR));
665 if (Names[count])
666 strcpyW(Names[count], szValue);
668 wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
669 CLSIDFromString(szGuidKey, &pCLSID[count]);
671 TRACE("found match %s %s\n", debugstr_w(szValue), debugstr_w(szNextKey));
672 RegCloseKey(hkey);
673 count++;
676 if (pcItemsFetched) *pcItemsFetched = count;
677 if (count < cItemsToFetch)
678 hres = S_FALSE;
680 TRACE("<-- %i found\n",count);
681 return hres;
685 /******************************************************************************
686 * IEnumDMO_fnSkip
688 static HRESULT WINAPI IEnumDMO_fnSkip(IEnumDMO * iface, DWORD cItemsToSkip)
690 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
692 TRACE("(%p)->(%d)\n", This, cItemsToSkip);
693 This->index += cItemsToSkip;
695 return S_OK;
699 /******************************************************************************
700 * IEnumDMO_fnReset
702 static HRESULT WINAPI IEnumDMO_fnReset(IEnumDMO * iface)
704 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
706 TRACE("(%p)\n", This);
707 This->index = -1;
709 return S_OK;
713 /******************************************************************************
714 * IEnumDMO_fnClone
716 static HRESULT WINAPI IEnumDMO_fnClone(IEnumDMO *iface, IEnumDMO **ppEnum)
718 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
719 TRACE("(%p)->(%p)\n", This, ppEnum);
720 return IEnumDMO_Constructor(&This->category, This->dwFlags, This->cInTypes, This->pInTypes,
721 This->cOutTypes, This->pOutTypes, ppEnum);
725 /***************************************************************
726 * DMOEnum (MSDMO.@)
728 * Enumerate DirectX Media Objects in the registry.
730 HRESULT WINAPI DMOEnum(
731 REFGUID category,
732 DWORD flags,
733 DWORD cInTypes,
734 const DMO_PARTIAL_MEDIATYPE *pInTypes,
735 DWORD cOutTypes,
736 const DMO_PARTIAL_MEDIATYPE *pOutTypes,
737 IEnumDMO **ppEnum)
739 TRACE("%s 0x%08x %d %p %d %p %p\n", debugstr_guid(category), flags, cInTypes, pInTypes,
740 cOutTypes, pOutTypes, ppEnum);
742 if (TRACE_ON(msdmo))
744 DWORD i;
745 if (cInTypes)
747 for (i = 0; i < cInTypes; i++)
748 TRACE("intype %d - type %s, subtype %s\n", i, debugstr_guid(&pInTypes[i].type),
749 debugstr_guid(&pInTypes[i].subtype));
752 if (cOutTypes) {
753 for (i = 0; i < cOutTypes; i++)
754 TRACE("outtype %d - type %s, subtype %s\n", i, debugstr_guid(&pOutTypes[i].type),
755 debugstr_guid(&pOutTypes[i].subtype));
759 return IEnumDMO_Constructor(category, flags, cInTypes,
760 pInTypes, cOutTypes, pOutTypes, ppEnum);
764 static const IEnumDMOVtbl edmovt =
766 IEnumDMO_fnQueryInterface,
767 IEnumDMO_fnAddRef,
768 IEnumDMO_fnRelease,
769 IEnumDMO_fnNext,
770 IEnumDMO_fnSkip,
771 IEnumDMO_fnReset,
772 IEnumDMO_fnClone,
776 HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types )
778 HRESULT ret = S_OK;
780 if (MSDMO_MAJOR_VERSION > 5)
782 DWORD len;
783 LONG rc;
785 len = requested * sizeof(DMO_PARTIAL_MEDIATYPE);
786 rc = RegQueryValueExW(root, key, NULL, NULL, (LPBYTE) types, &len);
787 ret = HRESULT_FROM_WIN32(rc);
789 *supplied = len / sizeof(DMO_PARTIAL_MEDIATYPE);
791 else
793 HKEY hkey;
794 WCHAR szGuidKey[64];
796 *supplied = 0;
797 if (ERROR_SUCCESS == RegOpenKeyExW(root, key, 0, KEY_READ, &hkey))
799 int index = 0;
800 WCHAR szNextKey[MAX_PATH];
801 DWORD len;
802 LONG rc = ERROR_SUCCESS;
804 while (rc == ERROR_SUCCESS)
806 len = MAX_PATH;
807 rc = RegEnumKeyExW(hkey, index, szNextKey, &len, NULL, NULL, NULL, NULL);
808 if (rc == ERROR_SUCCESS)
810 HKEY subk;
811 int sub_index = 0;
812 LONG rcs = ERROR_SUCCESS;
813 WCHAR szSubKey[MAX_PATH];
815 RegOpenKeyExW(hkey, szNextKey, 0, KEY_READ, &subk);
816 while (rcs == ERROR_SUCCESS)
818 len = MAX_PATH;
819 rcs = RegEnumKeyExW(subk, sub_index, szSubKey, &len, NULL, NULL, NULL, NULL);
820 if (rcs == ERROR_SUCCESS)
822 if (*supplied >= requested)
824 /* Bailing */
825 ret = S_FALSE;
826 rc = ERROR_MORE_DATA;
827 rcs = ERROR_MORE_DATA;
828 break;
831 wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
832 CLSIDFromString(szGuidKey, &types[*supplied].type);
833 wsprintfW(szGuidKey,szToGuidFmt,szSubKey);
834 CLSIDFromString(szGuidKey, &types[*supplied].subtype);
835 TRACE("Adding type %s subtype %s at index %i\n",
836 debugstr_guid(&types[*supplied].type),
837 debugstr_guid(&types[*supplied].subtype),
838 *supplied);
839 (*supplied)++;
841 sub_index++;
843 index++;
846 RegCloseKey(hkey);
849 return ret;
852 /***************************************************************
853 * DMOGetTypes (MSDMO.@)
855 HRESULT WINAPI DMOGetTypes(REFCLSID clsidDMO,
856 ULONG ulInputTypesRequested,
857 ULONG* pulInputTypesSupplied,
858 DMO_PARTIAL_MEDIATYPE* pInputTypes,
859 ULONG ulOutputTypesRequested,
860 ULONG* pulOutputTypesSupplied,
861 DMO_PARTIAL_MEDIATYPE* pOutputTypes)
863 HKEY root,hkey;
864 HRESULT ret = S_OK;
865 WCHAR szguid[64];
867 TRACE ("(%s,%u,%p,%p,%u,%p,%p)\n", debugstr_guid(clsidDMO), ulInputTypesRequested,
868 pulInputTypesSupplied, pInputTypes, ulOutputTypesRequested, pulOutputTypesSupplied,
869 pOutputTypes);
871 if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0,
872 KEY_READ, &root))
873 return E_FAIL;
875 if (ERROR_SUCCESS != RegOpenKeyExW(root,GUIDToString(szguid,clsidDMO) , 0,
876 KEY_READ, &hkey))
878 RegCloseKey(root);
879 return E_FAIL;
882 if (ulInputTypesRequested > 0)
884 ret = read_types(hkey, szDMOInputType, pulInputTypesSupplied, ulInputTypesRequested, pInputTypes );
886 else
887 *pulInputTypesSupplied = 0;
889 if (ulOutputTypesRequested > 0)
891 HRESULT ret2;
892 ret2 = read_types(hkey, szDMOOutputType, pulOutputTypesSupplied, ulOutputTypesRequested, pOutputTypes );
894 if (ret == S_OK)
895 ret = ret2;
897 else
898 *pulOutputTypesSupplied = 0;
900 return ret;