967acd01b957a402b39c1326cc18b3bb92b2c78d
[reactos.git] / reactos / dll / directx / wine / msdmo / dmoreg.c
1 /*
2 * Copyright (C) 2003 Michael G├╝nnewig
3 * Copyright (C) 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 *
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.
9 *
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.
14 *
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
18 */
19
20 #define WIN32_NO_STATUS
21 #define _INC_WINDOWS
22 #define COM_NO_WINDOWS_H
23
24 #include <stdarg.h>
25
26 #include <windef.h>
27 #include <winbase.h>
28 #include <winuser.h>
29 //#include "winerror.h"
30 #include <winreg.h>
31 #include <objbase.h>
32 #include <wine/unicode.h>
33 #include <wine/debug.h>
34 //#include "initguid.h"
35 #include <dmo.h>
36
37 WINE_DEFAULT_DEBUG_CHANNEL(msdmo);
38
39 #define MSDMO_MAJOR_VERSION 6
40
41 static const WCHAR szDMORootKey[] =
42 {
43 'D','i','r','e','c','t','S','h','o','w','\\',
44 'M','e','d','i','a','O','b','j','e','c','t','s',0
45 };
46
47 static const WCHAR szDMOInputType[] =
48 {
49 'I','n','p','u','t','T','y','p','e','s',0
50 };
51
52 static const WCHAR szDMOOutputType[] =
53 {
54 'O','u','t','p','u','t','T','y','p','e','s',0
55 };
56
57 static const WCHAR szDMOKeyed[] =
58 {
59 'K','e','y','e','d',0
60 };
61
62 static const WCHAR szDMOCategories[] =
63 {
64 'C','a','t','e','g','o','r','i','e','s',0
65 };
66
67 static const WCHAR szGUIDFmt[] =
68 {
69 '%','0','8','X','-','%','0','4','X','-','%','0','4','X','-','%','0',
70 '2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2',
71 'X','%','0','2','X','%','0','2','X','%','0','2','X',0
72 };
73
74 static const WCHAR szCat3Fmt[] =
75 {
76 '%','s','\\','%','s','\\','%','s',0
77 };
78
79 static const WCHAR szCat2Fmt[] =
80 {
81 '%','s','\\','%','s',0
82 };
83
84 static const WCHAR szToGuidFmt[] =
85 {
86 '{','%','s','}',0
87 };
88
89
90 typedef struct
91 {
92 IEnumDMO IEnumDMO_iface;
93 LONG ref;
94 DWORD index;
95 const GUID* guidCategory;
96 DWORD dwFlags;
97 DWORD cInTypes;
98 DMO_PARTIAL_MEDIATYPE *pInTypes;
99 DWORD cOutTypes;
100 DMO_PARTIAL_MEDIATYPE *pOutTypes;
101 HKEY hkey;
102 } IEnumDMOImpl;
103
104 static inline IEnumDMOImpl *impl_from_IEnumDMO(IEnumDMO *iface)
105 {
106 return CONTAINING_RECORD(iface, IEnumDMOImpl, IEnumDMO_iface);
107 }
108
109 static HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types);
110
111 static const IEnumDMOVtbl edmovt;
112
113 static LPWSTR GUIDToString(LPWSTR lpwstr, REFGUID lpcguid)
114 {
115 wsprintfW(lpwstr, szGUIDFmt, lpcguid->Data1, lpcguid->Data2,
116 lpcguid->Data3, lpcguid->Data4[0], lpcguid->Data4[1],
117 lpcguid->Data4[2], lpcguid->Data4[3], lpcguid->Data4[4],
118 lpcguid->Data4[5], lpcguid->Data4[6], lpcguid->Data4[7]);
119
120 return lpwstr;
121 }
122
123 static BOOL IsMediaTypeEqual(const DMO_PARTIAL_MEDIATYPE* mt1, const DMO_PARTIAL_MEDIATYPE* mt2)
124 {
125
126 return (IsEqualCLSID(&mt1->type, &mt2->type) ||
127 IsEqualCLSID(&mt2->type, &GUID_NULL) ||
128 IsEqualCLSID(&mt1->type, &GUID_NULL)) &&
129 (IsEqualCLSID(&mt1->subtype, &mt2->subtype) ||
130 IsEqualCLSID(&mt2->subtype, &GUID_NULL) ||
131 IsEqualCLSID(&mt1->subtype, &GUID_NULL));
132 }
133
134 static HRESULT write_types(HKEY hkey, LPCWSTR name, const DMO_PARTIAL_MEDIATYPE* types, DWORD count)
135 {
136 HRESULT hres = S_OK;
137 if (MSDMO_MAJOR_VERSION > 5)
138 {
139 hres = RegSetValueExW(hkey, name, 0, REG_BINARY, (const BYTE*) types,
140 count* sizeof(DMO_PARTIAL_MEDIATYPE));
141 }
142 else
143 {
144 HKEY skey1,skey2,skey3;
145 DWORD index = 0;
146 WCHAR szGuidKey[64];
147
148 hres = RegCreateKeyExW(hkey, name, 0, NULL, REG_OPTION_NON_VOLATILE,
149 KEY_WRITE, NULL, &skey1, NULL);
150 while (index < count)
151 {
152 GUIDToString(szGuidKey,&types[index].type);
153 hres = RegCreateKeyExW(skey1, szGuidKey, 0, NULL,
154 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey2, NULL);
155 GUIDToString(szGuidKey,&types[index].subtype);
156 hres = RegCreateKeyExW(skey2, szGuidKey, 0, NULL,
157 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey3, NULL);
158 RegCloseKey(skey3);
159 RegCloseKey(skey2);
160 index ++;
161 }
162 RegCloseKey(skey1);
163 }
164
165 return hres;
166 }
167
168 /***************************************************************
169 * DMORegister (MSDMO.@)
170 *
171 * Register a DirectX Media Object.
172 */
173 HRESULT WINAPI DMORegister(
174 LPCWSTR szName,
175 REFCLSID clsidDMO,
176 REFGUID guidCategory,
177 DWORD dwFlags,
178 DWORD cInTypes,
179 const DMO_PARTIAL_MEDIATYPE *pInTypes,
180 DWORD cOutTypes,
181 const DMO_PARTIAL_MEDIATYPE *pOutTypes
182 )
183 {
184 WCHAR szguid[64];
185 HRESULT hres;
186 HKEY hrkey = 0;
187 HKEY hkey = 0;
188 HKEY hckey = 0;
189 HKEY hclskey = 0;
190
191 TRACE("%s\n", debugstr_w(szName));
192
193 hres = RegCreateKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, NULL,
194 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hrkey, NULL);
195 if (ERROR_SUCCESS != hres)
196 goto lend;
197
198 /* Create clsidDMO key under MediaObjects */
199 hres = RegCreateKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, NULL,
200 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
201 if (ERROR_SUCCESS != hres)
202 goto lend;
203
204 /* Set default Name value */
205 hres = RegSetValueExW(hkey, NULL, 0, REG_SZ, (const BYTE*) szName,
206 (strlenW(szName) + 1) * sizeof(WCHAR));
207
208 /* Set InputTypes */
209 hres = write_types(hkey, szDMOInputType, pInTypes, cInTypes);
210
211 /* Set OutputTypes */
212 hres = write_types(hkey, szDMOOutputType, pOutTypes, cOutTypes);
213
214 if (dwFlags & DMO_REGISTERF_IS_KEYED)
215 {
216 /* Create Keyed key */
217 hres = RegCreateKeyExW(hkey, szDMOKeyed, 0, NULL,
218 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
219 if (ERROR_SUCCESS != hres)
220 goto lend;
221 RegCloseKey(hckey);
222 }
223
224 /* Register the category */
225 hres = RegCreateKeyExW(hrkey, szDMOCategories, 0, NULL,
226 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
227 if (ERROR_SUCCESS != hres)
228 goto lend;
229
230 RegCloseKey(hkey);
231
232 hres = RegCreateKeyExW(hckey, GUIDToString(szguid, guidCategory), 0, NULL,
233 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
234 if (ERROR_SUCCESS != hres)
235 goto lend;
236 hres = RegCreateKeyExW(hkey, GUIDToString(szguid, clsidDMO), 0, NULL,
237 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hclskey, NULL);
238 if (ERROR_SUCCESS != hres)
239 goto lend;
240
241 lend:
242 if (hkey)
243 RegCloseKey(hkey);
244 if (hckey)
245 RegCloseKey(hckey);
246 if (hclskey)
247 RegCloseKey(hclskey);
248 if (hrkey)
249 RegCloseKey(hrkey);
250
251 TRACE(" hresult=0x%08x\n", hres);
252 return hres;
253 }
254
255
256 /***************************************************************
257 * DMOUnregister (MSDMO.@)
258 *
259 * Unregister a DirectX Media Object.
260 */
261 HRESULT WINAPI DMOUnregister(REFCLSID clsidDMO, REFGUID guidCategory)
262 {
263 HRESULT hres;
264 WCHAR szguid[64];
265 HKEY hrkey = 0;
266 HKEY hckey = 0;
267
268 GUIDToString(szguid, clsidDMO);
269
270 TRACE("%s %p\n", debugstr_w(szguid), guidCategory);
271
272 hres = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_WRITE, &hrkey);
273 if (ERROR_SUCCESS != hres)
274 goto lend;
275
276 hres = RegDeleteKeyW(hrkey, szguid);
277 if (ERROR_SUCCESS != hres)
278 goto lend;
279
280 hres = RegOpenKeyExW(hrkey, szDMOCategories, 0, KEY_WRITE, &hckey);
281 if (ERROR_SUCCESS != hres)
282 goto lend;
283
284 hres = RegDeleteKeyW(hckey, szguid);
285 if (ERROR_SUCCESS != hres)
286 goto lend;
287
288 lend:
289 if (hckey)
290 RegCloseKey(hckey);
291 if (hrkey)
292 RegCloseKey(hrkey);
293
294 return hres;
295 }
296
297
298 /***************************************************************
299 * DMOGetName (MSDMO.@)
300 *
301 * Get DMP Name from the registry
302 */
303 HRESULT WINAPI DMOGetName(REFCLSID clsidDMO, WCHAR szName[])
304 {
305 WCHAR szguid[64];
306 HRESULT hres;
307 HKEY hrkey = 0;
308 HKEY hkey = 0;
309 static const INT max_name_len = 80;
310 DWORD count;
311
312 TRACE("%s\n", debugstr_guid(clsidDMO));
313
314 hres = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey,
315 0, KEY_READ, &hrkey);
316 if (ERROR_SUCCESS != hres)
317 goto lend;
318
319 hres = RegOpenKeyExW(hrkey, GUIDToString(szguid, clsidDMO),
320 0, KEY_READ, &hkey);
321 if (ERROR_SUCCESS != hres)
322 goto lend;
323
324 count = max_name_len * sizeof(WCHAR);
325 hres = RegQueryValueExW(hkey, NULL, NULL, NULL,
326 (LPBYTE) szName, &count);
327
328 TRACE(" szName=%s\n", debugstr_w(szName));
329 lend:
330 if (hkey)
331 RegCloseKey(hrkey);
332 if (hkey)
333 RegCloseKey(hkey);
334
335 return hres;
336 }
337
338
339 /**************************************************************************
340 * IEnumDMOImpl_Destructor
341 */
342 static BOOL IEnumDMOImpl_Destructor(IEnumDMOImpl* This)
343 {
344 TRACE("%p\n", This);
345
346 if (This->hkey)
347 RegCloseKey(This->hkey);
348
349 HeapFree(GetProcessHeap(), 0, This->pInTypes);
350 HeapFree(GetProcessHeap(), 0, This->pOutTypes);
351
352 return TRUE;
353 }
354
355
356 /**************************************************************************
357 * IEnumDMO_Constructor
358 */
359 static IEnumDMO * IEnumDMO_Constructor(
360 REFGUID guidCategory,
361 DWORD dwFlags,
362 DWORD cInTypes,
363 const DMO_PARTIAL_MEDIATYPE *pInTypes,
364 DWORD cOutTypes,
365 const DMO_PARTIAL_MEDIATYPE *pOutTypes)
366 {
367 UINT size;
368 IEnumDMOImpl* lpedmo;
369 BOOL ret = FALSE;
370
371 lpedmo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumDMOImpl));
372
373 if (lpedmo)
374 {
375 lpedmo->ref = 1;
376 lpedmo->IEnumDMO_iface.lpVtbl = &edmovt;
377 lpedmo->index = -1;
378 lpedmo->guidCategory = guidCategory;
379 lpedmo->dwFlags = dwFlags;
380
381 if (cInTypes > 0)
382 {
383 size = cInTypes * sizeof(DMO_PARTIAL_MEDIATYPE);
384 lpedmo->pInTypes = HeapAlloc(GetProcessHeap(), 0, size);
385 if (!lpedmo->pInTypes)
386 goto lerr;
387 memcpy(lpedmo->pInTypes, pInTypes, size);
388 lpedmo->cInTypes = cInTypes;
389 }
390
391 if (cOutTypes > 0)
392 {
393 size = cOutTypes * sizeof(DMO_PARTIAL_MEDIATYPE);
394 lpedmo->pOutTypes = HeapAlloc(GetProcessHeap(), 0, size);
395 if (!lpedmo->pOutTypes)
396 goto lerr;
397 memcpy(lpedmo->pOutTypes, pOutTypes, size);
398 lpedmo->cOutTypes = cOutTypes;
399 }
400
401 /* If not filtering by category enum from media objects root */
402 if (IsEqualGUID(guidCategory, &GUID_NULL))
403 {
404 if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey,
405 0, KEY_READ, &lpedmo->hkey))
406 ret = TRUE;
407 }
408 else
409 {
410 WCHAR szguid[64];
411 WCHAR szKey[MAX_PATH];
412
413 wsprintfW(szKey, szCat3Fmt, szDMORootKey, szDMOCategories,
414 GUIDToString(szguid, guidCategory));
415 if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey,
416 0, KEY_READ, &lpedmo->hkey))
417 ret = TRUE;
418 }
419
420 lerr:
421 if(!ret)
422 {
423 IEnumDMOImpl_Destructor(lpedmo);
424 HeapFree(GetProcessHeap(),0,lpedmo);
425 lpedmo = NULL;
426 }
427 }
428
429 TRACE("returning %p\n", lpedmo);
430
431 return (IEnumDMO*)lpedmo;
432 }
433
434
435 /******************************************************************************
436 * IEnumDMO_fnAddRef
437 */
438 static ULONG WINAPI IEnumDMO_fnAddRef(IEnumDMO * iface)
439 {
440 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
441 return InterlockedIncrement(&This->ref);
442 }
443
444
445 /**************************************************************************
446 * EnumDMO_QueryInterface
447 */
448 static HRESULT WINAPI IEnumDMO_fnQueryInterface(
449 IEnumDMO* iface,
450 REFIID riid,
451 LPVOID *ppvObj)
452 {
453 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
454
455 *ppvObj = NULL;
456
457 if(IsEqualIID(riid, &IID_IUnknown))
458 *ppvObj = This;
459 else if(IsEqualIID(riid, &IID_IEnumDMO))
460 *ppvObj = This;
461
462 if(*ppvObj)
463 {
464 IEnumDMO_fnAddRef(*ppvObj);
465 return S_OK;
466 }
467
468 return E_NOINTERFACE;
469 }
470
471
472 /******************************************************************************
473 * IEnumDMO_fnRelease
474 */
475 static ULONG WINAPI IEnumDMO_fnRelease(IEnumDMO * iface)
476 {
477 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
478 ULONG refCount = InterlockedDecrement(&This->ref);
479
480 if (!refCount)
481 {
482 IEnumDMOImpl_Destructor(This);
483 HeapFree(GetProcessHeap(),0,This);
484 }
485 return refCount;
486 }
487
488
489 /******************************************************************************
490 * IEnumDMO_fnNext
491 */
492 static HRESULT WINAPI IEnumDMO_fnNext(
493 IEnumDMO * iface,
494 DWORD cItemsToFetch,
495 CLSID * pCLSID,
496 WCHAR ** Names,
497 DWORD * pcItemsFetched)
498 {
499 FILETIME ft;
500 HKEY hkey;
501 WCHAR szNextKey[MAX_PATH];
502 WCHAR szGuidKey[64];
503 WCHAR szKey[MAX_PATH];
504 WCHAR szValue[MAX_PATH];
505 DWORD len;
506 UINT count = 0;
507 HRESULT hres = S_OK;
508
509 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
510
511 TRACE("--> (%p) %d %p %p %p\n", iface, cItemsToFetch, pCLSID, Names, pcItemsFetched);
512
513 if (!pCLSID || !Names || !pcItemsFetched)
514 return E_POINTER;
515
516 while (count < cItemsToFetch)
517 {
518 This->index++;
519
520 len = MAX_PATH;
521 hres = RegEnumKeyExW(This->hkey, This->index, szNextKey, &len, NULL, NULL, NULL, &ft);
522 if (hres != ERROR_SUCCESS)
523 break;
524
525 TRACE("found %s\n", debugstr_w(szNextKey));
526
527 if (!(This->dwFlags & DMO_ENUMF_INCLUDE_KEYED))
528 {
529 wsprintfW(szKey, szCat3Fmt, szDMORootKey, szNextKey, szDMOKeyed);
530 hres = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
531 if (ERROR_SUCCESS == hres)
532 {
533 RegCloseKey(hkey);
534 /* Skip Keyed entries */
535 continue;
536 }
537 }
538
539 wsprintfW(szKey, szCat2Fmt, szDMORootKey, szNextKey);
540 hres = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
541
542 if (This->pInTypes)
543 {
544 UINT i, j;
545 DWORD cInTypes;
546 DMO_PARTIAL_MEDIATYPE* pInTypes;
547
548 hres = read_types(hkey, szDMOInputType, &cInTypes,
549 sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
550 (DMO_PARTIAL_MEDIATYPE*)szValue);
551
552 if (ERROR_SUCCESS != hres)
553 {
554 RegCloseKey(hkey);
555 continue;
556 }
557
558 pInTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;
559
560 for (i = 0; i < This->cInTypes; i++)
561 {
562 for (j = 0; j < cInTypes; j++)
563 {
564 if (IsMediaTypeEqual(&pInTypes[j], &This->pInTypes[i]))
565 break;
566 }
567
568 if (j >= cInTypes)
569 break;
570 }
571
572 if (i < This->cInTypes)
573 {
574 RegCloseKey(hkey);
575 continue;
576 }
577 }
578
579 if (This->pOutTypes)
580 {
581 UINT i, j;
582 DWORD cOutTypes;
583 DMO_PARTIAL_MEDIATYPE* pOutTypes;
584
585 hres = read_types(hkey, szDMOOutputType, &cOutTypes,
586 sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
587 (DMO_PARTIAL_MEDIATYPE*)szValue);
588
589 if (ERROR_SUCCESS != hres)
590 {
591 RegCloseKey(hkey);
592 continue;
593 }
594
595 pOutTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;
596
597 for (i = 0; i < This->cOutTypes; i++)
598 {
599 for (j = 0; j < cOutTypes; j++)
600 {
601 if (IsMediaTypeEqual(&pOutTypes[j], &This->pOutTypes[i]))
602 break;
603 }
604
605 if (j >= cOutTypes)
606 break;
607 }
608
609 if (i < This->cOutTypes)
610 {
611 RegCloseKey(hkey);
612 continue;
613 }
614 }
615
616 /* Media object wasn't filtered so add it to return list */
617 Names[count] = NULL;
618 len = MAX_PATH * sizeof(WCHAR);
619 hres = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE) szValue, &len);
620 if (ERROR_SUCCESS == hres)
621 {
622 Names[count] = HeapAlloc(GetProcessHeap(), 0, strlenW(szValue) + 1);
623 if (Names[count])
624 strcmpW(Names[count], szValue);
625 }
626 wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
627 CLSIDFromString(szGuidKey, &pCLSID[count]);
628
629 TRACE("found match %s %s\n", debugstr_w(szValue), debugstr_w(szNextKey));
630 RegCloseKey(hkey);
631 count++;
632 }
633
634 *pcItemsFetched = count;
635 if (*pcItemsFetched < cItemsToFetch)
636 hres = S_FALSE;
637
638 TRACE("<-- %i found\n",count);
639 return hres;
640 }
641
642
643 /******************************************************************************
644 * IEnumDMO_fnSkip
645 */
646 static HRESULT WINAPI IEnumDMO_fnSkip(IEnumDMO * iface, DWORD cItemsToSkip)
647 {
648 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
649
650 This->index += cItemsToSkip;
651
652 return S_OK;
653 }
654
655
656 /******************************************************************************
657 * IEnumDMO_fnReset
658 */
659 static HRESULT WINAPI IEnumDMO_fnReset(IEnumDMO * iface)
660 {
661 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
662
663 This->index = -1;
664
665 return S_OK;
666 }
667
668
669 /******************************************************************************
670 * IEnumDMO_fnClone
671 */
672 static HRESULT WINAPI IEnumDMO_fnClone(IEnumDMO * iface, IEnumDMO **ppEnum)
673 {
674 IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
675
676 FIXME("(%p)->() to (%p)->() E_NOTIMPL\n", This, ppEnum);
677
678 return E_NOTIMPL;
679 }
680
681
682 /***************************************************************
683 * DMOEnum (MSDMO.@)
684 *
685 * Enumerate DirectX Media Objects in the registry.
686 */
687 HRESULT WINAPI DMOEnum(
688 REFGUID guidCategory,
689 DWORD dwFlags,
690 DWORD cInTypes,
691 const DMO_PARTIAL_MEDIATYPE *pInTypes,
692 DWORD cOutTypes,
693 const DMO_PARTIAL_MEDIATYPE *pOutTypes,
694 IEnumDMO **ppEnum)
695 {
696 HRESULT hres = E_FAIL;
697
698 TRACE("guidCategory=%p dwFlags=0x%08x cInTypes=%d cOutTypes=%d\n",
699 guidCategory, dwFlags, cInTypes, cOutTypes);
700
701 *ppEnum = IEnumDMO_Constructor(guidCategory, dwFlags, cInTypes,
702 pInTypes, cOutTypes, pOutTypes);
703 if (*ppEnum)
704 hres = S_OK;
705
706 return hres;
707 }
708
709
710 static const IEnumDMOVtbl edmovt =
711 {
712 IEnumDMO_fnQueryInterface,
713 IEnumDMO_fnAddRef,
714 IEnumDMO_fnRelease,
715 IEnumDMO_fnNext,
716 IEnumDMO_fnSkip,
717 IEnumDMO_fnReset,
718 IEnumDMO_fnClone,
719 };
720
721
722 HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types )
723 {
724 HRESULT ret = S_OK;
725 if (MSDMO_MAJOR_VERSION > 5)
726 {
727 DWORD len;
728 len = requested * sizeof(DMO_PARTIAL_MEDIATYPE);
729 ret = RegQueryValueExW(root, key, NULL, NULL, (LPBYTE) types, &len);
730 *supplied = len / sizeof(DMO_PARTIAL_MEDIATYPE);
731 }
732 else
733 {
734 HKEY hkey;
735 WCHAR szGuidKey[64];
736
737 *supplied = 0;
738 if (ERROR_SUCCESS == RegOpenKeyExW(root, key, 0, KEY_READ, &hkey))
739 {
740 int index = 0;
741 WCHAR szNextKey[MAX_PATH];
742 DWORD len;
743 LONG rc = ERROR_SUCCESS;
744
745 while (rc == ERROR_SUCCESS)
746 {
747 len = MAX_PATH;
748 rc = RegEnumKeyExW(hkey, index, szNextKey, &len, NULL, NULL, NULL, NULL);
749 if (rc == ERROR_SUCCESS)
750 {
751 HKEY subk;
752 int sub_index = 0;
753 LONG rcs = ERROR_SUCCESS;
754 WCHAR szSubKey[MAX_PATH];
755
756 RegOpenKeyExW(hkey, szNextKey, 0, KEY_READ, &subk);
757 while (rcs == ERROR_SUCCESS)
758 {
759 len = MAX_PATH;
760 rcs = RegEnumKeyExW(subk, sub_index, szSubKey, &len, NULL, NULL, NULL, NULL);
761 if (rcs == ERROR_SUCCESS)
762 {
763 if (*supplied >= requested)
764 {
765 /* Bailing */
766 ret = S_FALSE;
767 rc = ERROR_MORE_DATA;
768 rcs = ERROR_MORE_DATA;
769 break;
770 }
771
772 wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
773 CLSIDFromString(szGuidKey, &types[*supplied].type);
774 wsprintfW(szGuidKey,szToGuidFmt,szSubKey);
775 CLSIDFromString(szGuidKey, &types[*supplied].subtype);
776 TRACE("Adding type %s subtype %s at index %i\n",
777 debugstr_guid(&types[*supplied].type),
778 debugstr_guid(&types[*supplied].subtype),
779 *supplied);
780 (*supplied)++;
781 }
782 sub_index++;
783 }
784 index++;
785 }
786 }
787 RegCloseKey(hkey);
788 }
789 }
790 return ret;
791 }
792
793 /***************************************************************
794 * DMOGetTypes (MSDMO.@)
795 */
796 HRESULT WINAPI DMOGetTypes(REFCLSID clsidDMO,
797 ULONG ulInputTypesRequested,
798 ULONG* pulInputTypesSupplied,
799 DMO_PARTIAL_MEDIATYPE* pInputTypes,
800 ULONG ulOutputTypesRequested,
801 ULONG* pulOutputTypesSupplied,
802 DMO_PARTIAL_MEDIATYPE* pOutputTypes)
803 {
804 HKEY root,hkey;
805 HRESULT ret = S_OK;
806 WCHAR szguid[64];
807
808 TRACE ("(%s,%u,%p,%p,%u,%p,%p)\n", debugstr_guid(clsidDMO), ulInputTypesRequested,
809 pulInputTypesSupplied, pInputTypes, ulOutputTypesRequested, pulOutputTypesSupplied,
810 pOutputTypes);
811
812 if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0,
813 KEY_READ, &root))
814 return E_FAIL;
815
816 if (ERROR_SUCCESS != RegOpenKeyExW(root,GUIDToString(szguid,clsidDMO) , 0,
817 KEY_READ, &hkey))
818 {
819 RegCloseKey(root);
820 return E_FAIL;
821 }
822
823 if (ulInputTypesRequested > 0)
824 {
825 ret = read_types(hkey, szDMOInputType, pulInputTypesSupplied, ulInputTypesRequested, pInputTypes );
826 }
827 else
828 *pulInputTypesSupplied = 0;
829
830 if (ulOutputTypesRequested > 0)
831 {
832 HRESULT ret2;
833 ret2 = read_types(hkey, szDMOOutputType, pulOutputTypesSupplied, ulOutputTypesRequested, pOutputTypes );
834
835 if (ret == S_OK)
836 ret = ret2;
837 }
838 else
839 *pulOutputTypesSupplied = 0;
840
841 return ret;
842 }