ntoskrnl: Flesh out IoBuildSynchronousFsdRequest implementation.
[wine.git] / dlls / msdmo / dmoreg.c
blob67ba498bc41b17ee9603f651a208ec15a0a05368
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 "initguid.h"
33 #include "dmo.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msdmo);
37 #define MSDMO_MAJOR_VERSION 6
39 static const WCHAR szDMORootKey[] =
41 'D','i','r','e','c','t','S','h','o','w','\\',
42 'M','e','d','i','a','O','b','j','e','c','t','s',0
43 };
45 static const WCHAR szDMOInputType[] =
47 'I','n','p','u','t','T','y','p','e','s',0
50 static const WCHAR szDMOOutputType[] =
52 'O','u','t','p','u','t','T','y','p','e','s',0
55 static const WCHAR szDMOKeyed[] =
57 'K','e','y','e','d',0
60 static const WCHAR szDMOCategories[] =
62 'C','a','t','e','g','o','r','i','e','s',0
65 static const WCHAR szGUIDFmt[] =
67 '%','0','8','X','-','%','0','4','X','-','%','0','4','X','-','%','0',
68 '2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2',
69 'X','%','0','2','X','%','0','2','X','%','0','2','X',0
72 static const WCHAR szCat3Fmt[] =
74 '%','s','\\','%','s','\\','%','s',0
77 static const WCHAR szCat2Fmt[] =
79 '%','s','\\','%','s',0
82 static const WCHAR szToGuidFmt[] =
84 '{','%','s','}',0
88 typedef struct
90 IEnumDMO IEnumDMO_iface;
91 LONG ref;
92 DWORD index;
93 GUID category;
94 DWORD dwFlags;
95 DWORD cInTypes;
96 DMO_PARTIAL_MEDIATYPE *pInTypes;
97 DWORD cOutTypes;
98 DMO_PARTIAL_MEDIATYPE *pOutTypes;
99 HKEY hkey;
100 } IEnumDMOImpl;
102 static inline IEnumDMOImpl *impl_from_IEnumDMO(IEnumDMO *iface)
104 return CONTAINING_RECORD(iface, IEnumDMOImpl, IEnumDMO_iface);
107 static HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types);
109 static const IEnumDMOVtbl edmovt;
111 static LPWSTR GUIDToString(LPWSTR lpwstr, REFGUID lpcguid)
113 wsprintfW(lpwstr, szGUIDFmt, lpcguid->Data1, lpcguid->Data2,
114 lpcguid->Data3, lpcguid->Data4[0], lpcguid->Data4[1],
115 lpcguid->Data4[2], lpcguid->Data4[3], lpcguid->Data4[4],
116 lpcguid->Data4[5], lpcguid->Data4[6], lpcguid->Data4[7]);
118 return lpwstr;
121 static BOOL IsMediaTypeEqual(const DMO_PARTIAL_MEDIATYPE* mt1, const DMO_PARTIAL_MEDIATYPE* mt2)
124 return (IsEqualCLSID(&mt1->type, &mt2->type) ||
125 IsEqualCLSID(&mt2->type, &GUID_NULL) ||
126 IsEqualCLSID(&mt1->type, &GUID_NULL)) &&
127 (IsEqualCLSID(&mt1->subtype, &mt2->subtype) ||
128 IsEqualCLSID(&mt2->subtype, &GUID_NULL) ||
129 IsEqualCLSID(&mt1->subtype, &GUID_NULL));
132 static HRESULT write_types(HKEY hkey, LPCWSTR name, const DMO_PARTIAL_MEDIATYPE* types, DWORD count)
134 LONG ret;
136 if (MSDMO_MAJOR_VERSION > 5)
138 ret = RegSetValueExW(hkey, name, 0, REG_BINARY, (const BYTE*) types,
139 count* sizeof(DMO_PARTIAL_MEDIATYPE));
141 else
143 HKEY skey1,skey2,skey3;
144 DWORD index = 0;
145 WCHAR szGuidKey[64];
147 ret = RegCreateKeyExW(hkey, name, 0, NULL, REG_OPTION_NON_VOLATILE,
148 KEY_WRITE, NULL, &skey1, NULL);
149 if (ret)
150 return HRESULT_FROM_WIN32(ret);
152 while (index < count)
154 GUIDToString(szGuidKey,&types[index].type);
155 ret = RegCreateKeyExW(skey1, szGuidKey, 0, NULL,
156 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey2, NULL);
157 GUIDToString(szGuidKey,&types[index].subtype);
158 ret = RegCreateKeyExW(skey2, szGuidKey, 0, NULL,
159 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey3, NULL);
160 RegCloseKey(skey3);
161 RegCloseKey(skey2);
162 index ++;
164 RegCloseKey(skey1);
167 return HRESULT_FROM_WIN32(ret);
170 /***************************************************************
171 * DMORegister (MSDMO.@)
173 * Register a DirectX Media Object.
175 HRESULT WINAPI DMORegister(
176 LPCWSTR szName,
177 REFCLSID clsidDMO,
178 REFGUID guidCategory,
179 DWORD dwFlags,
180 DWORD cInTypes,
181 const DMO_PARTIAL_MEDIATYPE *pInTypes,
182 DWORD cOutTypes,
183 const DMO_PARTIAL_MEDIATYPE *pOutTypes
186 WCHAR szguid[64];
187 HRESULT hres;
188 HKEY hrkey = 0;
189 HKEY hkey = 0;
190 HKEY hckey = 0;
191 HKEY hclskey = 0;
192 LONG ret;
194 TRACE("%s %s %s\n", debugstr_w(szName), debugstr_guid(clsidDMO), debugstr_guid(guidCategory));
196 if (IsEqualGUID(guidCategory, &GUID_NULL))
197 return E_INVALIDARG;
199 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, NULL,
200 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hrkey, NULL);
201 if (ret)
202 return HRESULT_FROM_WIN32(ret);
204 /* Create clsidDMO key under MediaObjects */
205 ret = RegCreateKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, NULL,
206 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
207 if (ret)
208 goto lend;
210 /* Set default Name value */
211 ret = RegSetValueExW(hkey, NULL, 0, REG_SZ, (const BYTE*) szName,
212 (strlenW(szName) + 1) * sizeof(WCHAR));
214 /* Set InputTypes */
215 hres = write_types(hkey, szDMOInputType, pInTypes, cInTypes);
217 /* Set OutputTypes */
218 hres = write_types(hkey, szDMOOutputType, pOutTypes, cOutTypes);
220 if (dwFlags & DMO_REGISTERF_IS_KEYED)
222 /* Create Keyed key */
223 ret = RegCreateKeyExW(hkey, szDMOKeyed, 0, NULL,
224 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
225 if (ret)
226 goto lend;
227 RegCloseKey(hckey);
230 /* Register the category */
231 ret = RegCreateKeyExW(hrkey, szDMOCategories, 0, NULL,
232 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
233 if (ret)
234 goto lend;
236 RegCloseKey(hkey);
238 ret = RegCreateKeyExW(hckey, GUIDToString(szguid, guidCategory), 0, NULL,
239 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
240 if (ret)
241 goto lend;
242 ret = RegCreateKeyExW(hkey, GUIDToString(szguid, clsidDMO), 0, NULL,
243 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hclskey, NULL);
244 if (ret)
245 goto lend;
247 lend:
248 if (hkey)
249 RegCloseKey(hkey);
250 if (hckey)
251 RegCloseKey(hckey);
252 if (hclskey)
253 RegCloseKey(hclskey);
254 if (hrkey)
255 RegCloseKey(hrkey);
257 hres = HRESULT_FROM_WIN32(ret);
258 TRACE(" hresult=0x%08x\n", hres);
259 return hres;
262 static HRESULT unregister_dmo_from_category(const WCHAR *dmoW, const WCHAR *catW, HKEY categories)
264 HKEY catkey;
265 LONG ret;
267 ret = RegOpenKeyExW(categories, catW, 0, KEY_WRITE, &catkey);
268 if (!ret)
270 ret = RegDeleteKeyW(catkey, dmoW);
271 RegCloseKey(catkey);
274 return !ret ? S_OK : S_FALSE;
277 /***************************************************************
278 * DMOUnregister (MSDMO.@)
280 * Unregister a DirectX Media Object.
282 HRESULT WINAPI DMOUnregister(REFCLSID dmo, REFGUID category)
284 HKEY rootkey = 0, categorieskey = 0;
285 WCHAR dmoW[64], catW[64];
286 HRESULT hr = S_FALSE;
287 LONG ret;
289 TRACE("%s %s\n", debugstr_guid(dmo), debugstr_guid(category));
291 ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_WRITE, &rootkey);
292 if (ret)
293 return S_FALSE;
295 GUIDToString(dmoW, dmo);
296 RegDeleteKeyW(rootkey, dmoW);
298 /* open 'Categories' */
299 ret = RegOpenKeyExW(rootkey, szDMOCategories, 0, KEY_WRITE|KEY_ENUMERATE_SUB_KEYS, &categorieskey);
300 RegCloseKey(rootkey);
301 if (ret)
303 hr = HRESULT_FROM_WIN32(ret);
304 goto lend;
307 /* remove from all categories */
308 if (IsEqualGUID(category, &GUID_NULL))
310 DWORD index = 0, len = sizeof(catW)/sizeof(WCHAR);
312 while (!RegEnumKeyExW(categorieskey, index++, catW, &len, NULL, NULL, NULL, NULL))
313 hr = unregister_dmo_from_category(dmoW, catW, categorieskey);
315 else
317 GUIDToString(catW, category);
318 hr = unregister_dmo_from_category(dmoW, catW, categorieskey);
321 lend:
322 if (categorieskey)
323 RegCloseKey(categorieskey);
325 return hr;
329 /***************************************************************
330 * DMOGetName (MSDMO.@)
332 * Get DMO Name from the registry
334 HRESULT WINAPI DMOGetName(REFCLSID clsidDMO, WCHAR name[])
336 static const INT max_name_len = 80*sizeof(WCHAR);
337 DWORD count = max_name_len;
338 WCHAR szguid[64];
339 HKEY hrkey, hkey;
340 LONG ret;
342 TRACE("%s %p\n", debugstr_guid(clsidDMO), name);
344 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_READ, &hrkey))
345 return E_FAIL;
347 ret = RegOpenKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, KEY_READ, &hkey);
348 RegCloseKey(hrkey);
349 if (ret)
350 return E_FAIL;
352 ret = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)name, &count);
353 RegCloseKey(hkey);
355 if (!ret && count > 1)
357 TRACE("name=%s\n", debugstr_w(name));
358 return S_OK;
361 name[0] = 0;
362 return S_FALSE;
365 static HRESULT dup_partial_mediatype(const DMO_PARTIAL_MEDIATYPE *types, DWORD count, DMO_PARTIAL_MEDIATYPE **ret)
367 *ret = NULL;
369 if (count == 0)
370 return S_OK;
372 *ret = HeapAlloc(GetProcessHeap(), 0, count*sizeof(*types));
373 if (!*ret)
374 return E_OUTOFMEMORY;
376 memcpy(*ret, types, count*sizeof(*types));
377 return S_OK;
380 /**************************************************************************
381 * IEnumDMO_Constructor
383 static HRESULT IEnumDMO_Constructor(
384 REFGUID guidCategory,
385 DWORD dwFlags,
386 DWORD cInTypes,
387 const DMO_PARTIAL_MEDIATYPE *pInTypes,
388 DWORD cOutTypes,
389 const DMO_PARTIAL_MEDIATYPE *pOutTypes,
390 IEnumDMO **obj)
392 IEnumDMOImpl* lpedmo;
393 HRESULT hr;
394 LONG ret;
396 *obj = NULL;
398 lpedmo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumDMOImpl));
399 if (!lpedmo)
400 return E_OUTOFMEMORY;
402 lpedmo->IEnumDMO_iface.lpVtbl = &edmovt;
403 lpedmo->ref = 1;
404 lpedmo->index = -1;
405 lpedmo->category = *guidCategory;
406 lpedmo->dwFlags = dwFlags;
407 lpedmo->cInTypes = cInTypes;
408 lpedmo->cOutTypes = cOutTypes;
410 hr = dup_partial_mediatype(pInTypes, cInTypes, &lpedmo->pInTypes);
411 if (FAILED(hr))
412 goto lerr;
414 hr = dup_partial_mediatype(pOutTypes, cOutTypes, &lpedmo->pOutTypes);
415 if (FAILED(hr))
416 goto lerr;
418 /* If not filtering by category enum from media objects root */
419 if (IsEqualGUID(guidCategory, &GUID_NULL))
421 if ((ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_READ, &lpedmo->hkey)))
422 hr = HRESULT_FROM_WIN32(ret);
424 else
426 WCHAR szguid[64];
427 WCHAR szKey[MAX_PATH];
429 wsprintfW(szKey, szCat3Fmt, szDMORootKey, szDMOCategories, GUIDToString(szguid, guidCategory));
430 if ((ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &lpedmo->hkey)))
431 hr = HRESULT_FROM_WIN32(ret);
434 lerr:
436 if (FAILED(hr))
437 IEnumDMO_Release(&lpedmo->IEnumDMO_iface);
438 else
440 TRACE("returning %p\n", lpedmo);
441 *obj = &lpedmo->IEnumDMO_iface;
444 return hr;
447 /******************************************************************************
448 * IEnumDMO_fnAddRef
450 static ULONG WINAPI IEnumDMO_fnAddRef(IEnumDMO * iface)
452 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
453 ULONG refCount = InterlockedIncrement(&This->ref);
454 TRACE("(%p)->(%d)\n", This, refCount);
455 return refCount;
458 /**************************************************************************
459 * EnumDMO_QueryInterface
461 static HRESULT WINAPI IEnumDMO_fnQueryInterface(IEnumDMO* iface, REFIID riid, void **ppvObj)
463 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
465 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObj);
467 *ppvObj = NULL;
469 if (IsEqualIID(riid, &IID_IEnumDMO) ||
470 IsEqualIID(riid, &IID_IUnknown))
472 *ppvObj = iface;
473 IEnumDMO_AddRef(iface);
476 return *ppvObj ? S_OK : E_NOINTERFACE;
479 /******************************************************************************
480 * IEnumDMO_fnRelease
482 static ULONG WINAPI IEnumDMO_fnRelease(IEnumDMO * iface)
484 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
485 ULONG refCount = InterlockedDecrement(&This->ref);
487 TRACE("(%p)->(%d)\n", This, refCount);
489 if (!refCount)
491 if (This->hkey)
492 RegCloseKey(This->hkey);
493 HeapFree(GetProcessHeap(), 0, This->pInTypes);
494 HeapFree(GetProcessHeap(), 0, This->pOutTypes);
495 HeapFree(GetProcessHeap(), 0, This);
497 return refCount;
501 /******************************************************************************
502 * IEnumDMO_fnNext
504 static HRESULT WINAPI IEnumDMO_fnNext(
505 IEnumDMO * iface,
506 DWORD cItemsToFetch,
507 CLSID * pCLSID,
508 WCHAR ** Names,
509 DWORD * pcItemsFetched)
511 HKEY hkey;
512 WCHAR szNextKey[MAX_PATH];
513 WCHAR szGuidKey[64];
514 WCHAR szKey[MAX_PATH];
515 WCHAR szValue[MAX_PATH];
516 DWORD len;
517 UINT count = 0;
518 HRESULT hres = S_OK;
519 LONG ret;
521 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
523 TRACE("(%p)->(%d %p %p %p)\n", This, cItemsToFetch, pCLSID, Names, pcItemsFetched);
525 if (!pCLSID || !Names || !pcItemsFetched)
526 return E_POINTER;
528 while (count < cItemsToFetch)
530 This->index++;
532 len = MAX_PATH;
533 ret = RegEnumKeyExW(This->hkey, This->index, szNextKey, &len, NULL, NULL, NULL, NULL);
534 if (ret != ERROR_SUCCESS)
536 hres = HRESULT_FROM_WIN32(ret);
537 break;
540 TRACE("found %s\n", debugstr_w(szNextKey));
542 if (!(This->dwFlags & DMO_ENUMF_INCLUDE_KEYED))
544 wsprintfW(szKey, szCat3Fmt, szDMORootKey, szNextKey, szDMOKeyed);
545 ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
546 if (ERROR_SUCCESS == ret)
548 RegCloseKey(hkey);
549 /* Skip Keyed entries */
550 continue;
554 wsprintfW(szKey, szCat2Fmt, szDMORootKey, szNextKey);
555 ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
556 TRACE("testing %s\n", debugstr_w(szKey));
558 if (This->pInTypes)
560 UINT i, j;
561 DWORD cInTypes;
562 DMO_PARTIAL_MEDIATYPE* pInTypes;
564 hres = read_types(hkey, szDMOInputType, &cInTypes,
565 sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
566 (DMO_PARTIAL_MEDIATYPE*)szValue);
568 if (FAILED(hres))
570 RegCloseKey(hkey);
571 continue;
574 pInTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;
576 TRACE("read %d intypes for %s:\n", cInTypes, debugstr_w(szKey));
577 for (i = 0; i < cInTypes; i++) {
578 TRACE("intype %d: type %s, subtype %s\n", i, debugstr_guid(&pInTypes[i].type),
579 debugstr_guid(&pInTypes[i].subtype));
582 for (i = 0; i < This->cInTypes; i++)
584 for (j = 0; j < cInTypes; j++)
586 if (IsMediaTypeEqual(&pInTypes[j], &This->pInTypes[i]))
587 break;
590 if (j >= cInTypes)
591 break;
594 if (i < This->cInTypes)
596 RegCloseKey(hkey);
597 continue;
601 if (This->pOutTypes)
603 UINT i, j;
604 DWORD cOutTypes;
605 DMO_PARTIAL_MEDIATYPE* pOutTypes;
607 hres = read_types(hkey, szDMOOutputType, &cOutTypes,
608 sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
609 (DMO_PARTIAL_MEDIATYPE*)szValue);
611 if (FAILED(hres))
613 RegCloseKey(hkey);
614 continue;
617 pOutTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;
619 TRACE("read %d outtypes for %s:\n", cOutTypes, debugstr_w(szKey));
620 for (i = 0; i < cOutTypes; i++) {
621 TRACE("outtype %d: type %s, subtype %s\n", i, debugstr_guid(&pOutTypes[i].type),
622 debugstr_guid(&pOutTypes[i].subtype));
625 for (i = 0; i < This->cOutTypes; i++)
627 for (j = 0; j < cOutTypes; j++)
629 if (IsMediaTypeEqual(&pOutTypes[j], &This->pOutTypes[i]))
630 break;
633 if (j >= cOutTypes)
634 break;
637 if (i < This->cOutTypes)
639 RegCloseKey(hkey);
640 continue;
644 /* Media object wasn't filtered so add it to return list */
645 Names[count] = NULL;
646 len = MAX_PATH * sizeof(WCHAR);
647 ret = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)szValue, &len);
648 if (ERROR_SUCCESS == ret)
650 Names[count] = CoTaskMemAlloc((strlenW(szValue) + 1) * sizeof(WCHAR));
651 if (Names[count])
652 strcpyW(Names[count], szValue);
654 wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
655 CLSIDFromString(szGuidKey, &pCLSID[count]);
657 TRACE("found match %s %s\n", debugstr_w(szValue), debugstr_w(szNextKey));
658 RegCloseKey(hkey);
659 count++;
662 *pcItemsFetched = count;
663 if (*pcItemsFetched < cItemsToFetch)
664 hres = S_FALSE;
666 TRACE("<-- %i found\n",count);
667 return hres;
671 /******************************************************************************
672 * IEnumDMO_fnSkip
674 static HRESULT WINAPI IEnumDMO_fnSkip(IEnumDMO * iface, DWORD cItemsToSkip)
676 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
678 TRACE("(%p)->(%d)\n", This, cItemsToSkip);
679 This->index += cItemsToSkip;
681 return S_OK;
685 /******************************************************************************
686 * IEnumDMO_fnReset
688 static HRESULT WINAPI IEnumDMO_fnReset(IEnumDMO * iface)
690 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
692 TRACE("(%p)\n", This);
693 This->index = -1;
695 return S_OK;
699 /******************************************************************************
700 * IEnumDMO_fnClone
702 static HRESULT WINAPI IEnumDMO_fnClone(IEnumDMO *iface, IEnumDMO **ppEnum)
704 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
705 TRACE("(%p)->(%p)\n", This, ppEnum);
706 return IEnumDMO_Constructor(&This->category, This->dwFlags, This->cInTypes, This->pInTypes,
707 This->cOutTypes, This->pOutTypes, ppEnum);
711 /***************************************************************
712 * DMOEnum (MSDMO.@)
714 * Enumerate DirectX Media Objects in the registry.
716 HRESULT WINAPI DMOEnum(
717 REFGUID category,
718 DWORD flags,
719 DWORD cInTypes,
720 const DMO_PARTIAL_MEDIATYPE *pInTypes,
721 DWORD cOutTypes,
722 const DMO_PARTIAL_MEDIATYPE *pOutTypes,
723 IEnumDMO **ppEnum)
725 TRACE("%s 0x%08x %d %p %d %p %p\n", debugstr_guid(category), flags, cInTypes, pInTypes,
726 cOutTypes, pOutTypes, ppEnum);
728 if (TRACE_ON(msdmo))
730 DWORD i;
731 if (cInTypes)
733 for (i = 0; i < cInTypes; i++)
734 TRACE("intype %d - type %s, subtype %s\n", i, debugstr_guid(&pInTypes[i].type),
735 debugstr_guid(&pInTypes[i].subtype));
738 if (cOutTypes) {
739 for (i = 0; i < cOutTypes; i++)
740 TRACE("outtype %d - type %s, subtype %s\n", i, debugstr_guid(&pOutTypes[i].type),
741 debugstr_guid(&pOutTypes[i].subtype));
745 return IEnumDMO_Constructor(category, flags, cInTypes,
746 pInTypes, cOutTypes, pOutTypes, ppEnum);
750 static const IEnumDMOVtbl edmovt =
752 IEnumDMO_fnQueryInterface,
753 IEnumDMO_fnAddRef,
754 IEnumDMO_fnRelease,
755 IEnumDMO_fnNext,
756 IEnumDMO_fnSkip,
757 IEnumDMO_fnReset,
758 IEnumDMO_fnClone,
762 HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types )
764 HRESULT ret = S_OK;
766 if (MSDMO_MAJOR_VERSION > 5)
768 DWORD len;
769 LONG rc;
771 len = requested * sizeof(DMO_PARTIAL_MEDIATYPE);
772 rc = RegQueryValueExW(root, key, NULL, NULL, (LPBYTE) types, &len);
773 ret = HRESULT_FROM_WIN32(rc);
775 *supplied = len / sizeof(DMO_PARTIAL_MEDIATYPE);
777 else
779 HKEY hkey;
780 WCHAR szGuidKey[64];
782 *supplied = 0;
783 if (ERROR_SUCCESS == RegOpenKeyExW(root, key, 0, KEY_READ, &hkey))
785 int index = 0;
786 WCHAR szNextKey[MAX_PATH];
787 DWORD len;
788 LONG rc = ERROR_SUCCESS;
790 while (rc == ERROR_SUCCESS)
792 len = MAX_PATH;
793 rc = RegEnumKeyExW(hkey, index, szNextKey, &len, NULL, NULL, NULL, NULL);
794 if (rc == ERROR_SUCCESS)
796 HKEY subk;
797 int sub_index = 0;
798 LONG rcs = ERROR_SUCCESS;
799 WCHAR szSubKey[MAX_PATH];
801 RegOpenKeyExW(hkey, szNextKey, 0, KEY_READ, &subk);
802 while (rcs == ERROR_SUCCESS)
804 len = MAX_PATH;
805 rcs = RegEnumKeyExW(subk, sub_index, szSubKey, &len, NULL, NULL, NULL, NULL);
806 if (rcs == ERROR_SUCCESS)
808 if (*supplied >= requested)
810 /* Bailing */
811 ret = S_FALSE;
812 rc = ERROR_MORE_DATA;
813 rcs = ERROR_MORE_DATA;
814 break;
817 wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
818 CLSIDFromString(szGuidKey, &types[*supplied].type);
819 wsprintfW(szGuidKey,szToGuidFmt,szSubKey);
820 CLSIDFromString(szGuidKey, &types[*supplied].subtype);
821 TRACE("Adding type %s subtype %s at index %i\n",
822 debugstr_guid(&types[*supplied].type),
823 debugstr_guid(&types[*supplied].subtype),
824 *supplied);
825 (*supplied)++;
827 sub_index++;
829 index++;
832 RegCloseKey(hkey);
835 return ret;
838 /***************************************************************
839 * DMOGetTypes (MSDMO.@)
841 HRESULT WINAPI DMOGetTypes(REFCLSID clsidDMO,
842 ULONG ulInputTypesRequested,
843 ULONG* pulInputTypesSupplied,
844 DMO_PARTIAL_MEDIATYPE* pInputTypes,
845 ULONG ulOutputTypesRequested,
846 ULONG* pulOutputTypesSupplied,
847 DMO_PARTIAL_MEDIATYPE* pOutputTypes)
849 HKEY root,hkey;
850 HRESULT ret = S_OK;
851 WCHAR szguid[64];
853 TRACE ("(%s,%u,%p,%p,%u,%p,%p)\n", debugstr_guid(clsidDMO), ulInputTypesRequested,
854 pulInputTypesSupplied, pInputTypes, ulOutputTypesRequested, pulOutputTypesSupplied,
855 pOutputTypes);
857 if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0,
858 KEY_READ, &root))
859 return E_FAIL;
861 if (ERROR_SUCCESS != RegOpenKeyExW(root,GUIDToString(szguid,clsidDMO) , 0,
862 KEY_READ, &hkey))
864 RegCloseKey(root);
865 return E_FAIL;
868 if (ulInputTypesRequested > 0)
870 ret = read_types(hkey, szDMOInputType, pulInputTypesSupplied, ulInputTypesRequested, pInputTypes );
872 else
873 *pulInputTypesSupplied = 0;
875 if (ulOutputTypesRequested > 0)
877 HRESULT ret2;
878 ret2 = read_types(hkey, szDMOOutputType, pulOutputTypesSupplied, ulOutputTypesRequested, pOutputTypes );
880 if (ret == S_OK)
881 ret = ret2;
883 else
884 *pulOutputTypesSupplied = 0;
886 return ret;