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