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
28 #include "wine/unicode.h"
29 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(msdmo
);
35 #define MSDMO_MAJOR_VERSION 6
37 static const WCHAR szDMORootKey
[] =
39 'D','i','r','e','c','t','S','h','o','w','\\',
40 'M','e','d','i','a','O','b','j','e','c','t','s',0
43 static const WCHAR szDMOInputType
[] =
45 'I','n','p','u','t','T','y','p','e','s',0
48 static const WCHAR szDMOOutputType
[] =
50 'O','u','t','p','u','t','T','y','p','e','s',0
53 static const WCHAR szDMOKeyed
[] =
58 static const WCHAR szDMOCategories
[] =
60 'C','a','t','e','g','o','r','i','e','s',0
63 static const WCHAR szGUIDFmt
[] =
65 '%','0','8','X','-','%','0','4','X','-','%','0','4','X','-','%','0',
66 '2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2',
67 'X','%','0','2','X','%','0','2','X','%','0','2','X',0
70 static const WCHAR szCat3Fmt
[] =
72 '%','s','\\','%','s','\\','%','s',0
75 static const WCHAR szCat2Fmt
[] =
77 '%','s','\\','%','s',0
80 static const WCHAR szToGuidFmt
[] =
88 IEnumDMO IEnumDMO_iface
;
91 const GUID
* guidCategory
;
94 DMO_PARTIAL_MEDIATYPE
*pInTypes
;
96 DMO_PARTIAL_MEDIATYPE
*pOutTypes
;
100 static inline IEnumDMOImpl
*impl_from_IEnumDMO(IEnumDMO
*iface
)
102 return CONTAINING_RECORD(iface
, IEnumDMOImpl
, IEnumDMO_iface
);
105 static HRESULT
read_types(HKEY root
, LPCWSTR key
, ULONG
*supplied
, ULONG requested
, DMO_PARTIAL_MEDIATYPE
* types
);
107 static const IEnumDMOVtbl edmovt
;
109 static LPWSTR
GUIDToString(LPWSTR lpwstr
, REFGUID lpcguid
)
111 wsprintfW(lpwstr
, szGUIDFmt
, lpcguid
->Data1
, lpcguid
->Data2
,
112 lpcguid
->Data3
, lpcguid
->Data4
[0], lpcguid
->Data4
[1],
113 lpcguid
->Data4
[2], lpcguid
->Data4
[3], lpcguid
->Data4
[4],
114 lpcguid
->Data4
[5], lpcguid
->Data4
[6], lpcguid
->Data4
[7]);
119 static BOOL
IsMediaTypeEqual(const DMO_PARTIAL_MEDIATYPE
* mt1
, const DMO_PARTIAL_MEDIATYPE
* mt2
)
122 return (IsEqualCLSID(&mt1
->type
, &mt2
->type
) ||
123 IsEqualCLSID(&mt2
->type
, &GUID_NULL
) ||
124 IsEqualCLSID(&mt1
->type
, &GUID_NULL
)) &&
125 (IsEqualCLSID(&mt1
->subtype
, &mt2
->subtype
) ||
126 IsEqualCLSID(&mt2
->subtype
, &GUID_NULL
) ||
127 IsEqualCLSID(&mt1
->subtype
, &GUID_NULL
));
130 static HRESULT
write_types(HKEY hkey
, LPCWSTR name
, const DMO_PARTIAL_MEDIATYPE
* types
, DWORD count
)
134 if (MSDMO_MAJOR_VERSION
> 5)
136 ret
= RegSetValueExW(hkey
, name
, 0, REG_BINARY
, (const BYTE
*) types
,
137 count
* sizeof(DMO_PARTIAL_MEDIATYPE
));
141 HKEY skey1
,skey2
,skey3
;
145 ret
= RegCreateKeyExW(hkey
, name
, 0, NULL
, REG_OPTION_NON_VOLATILE
,
146 KEY_WRITE
, NULL
, &skey1
, NULL
);
148 return HRESULT_FROM_WIN32(ret
);
150 while (index
< count
)
152 GUIDToString(szGuidKey
,&types
[index
].type
);
153 ret
= RegCreateKeyExW(skey1
, szGuidKey
, 0, NULL
,
154 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &skey2
, NULL
);
155 GUIDToString(szGuidKey
,&types
[index
].subtype
);
156 ret
= RegCreateKeyExW(skey2
, szGuidKey
, 0, NULL
,
157 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &skey3
, NULL
);
165 return HRESULT_FROM_WIN32(ret
);
168 /***************************************************************
169 * DMORegister (MSDMO.@)
171 * Register a DirectX Media Object.
173 HRESULT WINAPI
DMORegister(
176 REFGUID guidCategory
,
179 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
181 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
191 TRACE("%s %s %s\n", debugstr_w(szName
), debugstr_guid(clsidDMO
), debugstr_guid(guidCategory
));
193 if (IsEqualGUID(guidCategory
, &GUID_NULL
))
196 hres
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, NULL
,
197 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hrkey
, NULL
);
198 if (ERROR_SUCCESS
!= hres
)
201 /* Create clsidDMO key under MediaObjects */
202 hres
= RegCreateKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
203 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hkey
, NULL
);
204 if (ERROR_SUCCESS
!= hres
)
207 /* Set default Name value */
208 hres
= RegSetValueExW(hkey
, NULL
, 0, REG_SZ
, (const BYTE
*) szName
,
209 (strlenW(szName
) + 1) * sizeof(WCHAR
));
212 hres
= write_types(hkey
, szDMOInputType
, pInTypes
, cInTypes
);
214 /* Set OutputTypes */
215 hres
= write_types(hkey
, szDMOOutputType
, pOutTypes
, cOutTypes
);
217 if (dwFlags
& DMO_REGISTERF_IS_KEYED
)
219 /* Create Keyed key */
220 hres
= RegCreateKeyExW(hkey
, szDMOKeyed
, 0, NULL
,
221 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hckey
, NULL
);
222 if (ERROR_SUCCESS
!= hres
)
227 /* Register the category */
228 hres
= RegCreateKeyExW(hrkey
, szDMOCategories
, 0, NULL
,
229 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hckey
, NULL
);
230 if (ERROR_SUCCESS
!= hres
)
235 hres
= RegCreateKeyExW(hckey
, GUIDToString(szguid
, guidCategory
), 0, NULL
,
236 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hkey
, NULL
);
237 if (ERROR_SUCCESS
!= hres
)
239 hres
= RegCreateKeyExW(hkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
240 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hclskey
, NULL
);
241 if (ERROR_SUCCESS
!= hres
)
250 RegCloseKey(hclskey
);
254 TRACE(" hresult=0x%08x\n", hres
);
258 static HRESULT
unregister_dmo_from_category(const WCHAR
*dmoW
, const WCHAR
*catW
, HKEY categories
)
263 ret
= RegOpenKeyExW(categories
, catW
, 0, KEY_WRITE
, &catkey
);
266 ret
= RegDeleteKeyW(catkey
, dmoW
);
270 return !ret
? S_OK
: S_FALSE
;
273 /***************************************************************
274 * DMOUnregister (MSDMO.@)
276 * Unregister a DirectX Media Object.
278 HRESULT WINAPI
DMOUnregister(REFCLSID dmo
, REFGUID category
)
280 HKEY rootkey
= 0, categorieskey
= 0;
281 WCHAR dmoW
[64], catW
[64];
282 HRESULT hr
= S_FALSE
;
285 TRACE("%s %s\n", debugstr_guid(dmo
), debugstr_guid(category
));
287 ret
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_WRITE
, &rootkey
);
291 GUIDToString(dmoW
, dmo
);
292 RegDeleteKeyW(rootkey
, dmoW
);
294 /* open 'Categories' */
295 ret
= RegOpenKeyExW(rootkey
, szDMOCategories
, 0, KEY_WRITE
|KEY_ENUMERATE_SUB_KEYS
, &categorieskey
);
296 RegCloseKey(rootkey
);
299 hr
= HRESULT_FROM_WIN32(ret
);
303 /* remove from all categories */
304 if (IsEqualGUID(category
, &GUID_NULL
))
306 DWORD index
= 0, len
= sizeof(catW
)/sizeof(WCHAR
);
308 while (!RegEnumKeyExW(categorieskey
, index
++, catW
, &len
, NULL
, NULL
, NULL
, NULL
))
309 hr
= unregister_dmo_from_category(dmoW
, catW
, categorieskey
);
313 GUIDToString(catW
, category
);
314 hr
= unregister_dmo_from_category(dmoW
, catW
, categorieskey
);
319 RegCloseKey(categorieskey
);
325 /***************************************************************
326 * DMOGetName (MSDMO.@)
328 * Get DMP Name from the registry
330 HRESULT WINAPI
DMOGetName(REFCLSID clsidDMO
, WCHAR szName
[])
335 static const INT max_name_len
= 80;
339 TRACE("%s\n", debugstr_guid(clsidDMO
));
341 ret
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_READ
, &hrkey
);
342 if (ERROR_SUCCESS
!= ret
)
345 ret
= RegOpenKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
), 0, KEY_READ
, &hkey
);
346 if (ERROR_SUCCESS
!= ret
)
349 count
= max_name_len
* sizeof(WCHAR
);
350 ret
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, (LPBYTE
) szName
, &count
);
352 TRACE(" szName=%s\n", debugstr_w(szName
));
359 return HRESULT_FROM_WIN32(ret
);
362 /**************************************************************************
363 * IEnumDMOImpl_Destructor
365 static BOOL
IEnumDMOImpl_Destructor(IEnumDMOImpl
* This
)
370 RegCloseKey(This
->hkey
);
372 HeapFree(GetProcessHeap(), 0, This
->pInTypes
);
373 HeapFree(GetProcessHeap(), 0, This
->pOutTypes
);
379 /**************************************************************************
380 * IEnumDMO_Constructor
382 static HRESULT
IEnumDMO_Constructor(
383 REFGUID guidCategory
,
386 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
388 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
,
391 IEnumDMOImpl
* lpedmo
;
398 lpedmo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IEnumDMOImpl
));
400 return E_OUTOFMEMORY
;
402 lpedmo
->IEnumDMO_iface
.lpVtbl
= &edmovt
;
405 lpedmo
->guidCategory
= guidCategory
;
406 lpedmo
->dwFlags
= dwFlags
;
410 size
= cInTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
411 lpedmo
->pInTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
412 if (!lpedmo
->pInTypes
)
417 memcpy(lpedmo
->pInTypes
, pInTypes
, size
);
418 lpedmo
->cInTypes
= cInTypes
;
423 size
= cOutTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
424 lpedmo
->pOutTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
425 if (!lpedmo
->pOutTypes
)
430 memcpy(lpedmo
->pOutTypes
, pOutTypes
, size
);
431 lpedmo
->cOutTypes
= cOutTypes
;
434 /* If not filtering by category enum from media objects root */
435 if (IsEqualGUID(guidCategory
, &GUID_NULL
))
437 if ((ret
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_READ
, &lpedmo
->hkey
)))
438 hr
= HRESULT_FROM_WIN32(ret
);
443 WCHAR szKey
[MAX_PATH
];
445 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szDMOCategories
,
446 GUIDToString(szguid
, guidCategory
));
447 if ((ret
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &lpedmo
->hkey
)))
448 hr
= HRESULT_FROM_WIN32(ret
);
455 IEnumDMOImpl_Destructor(lpedmo
);
456 HeapFree(GetProcessHeap(), 0, lpedmo
);
460 TRACE("returning %p\n", lpedmo
);
461 *obj
= &lpedmo
->IEnumDMO_iface
;
467 /******************************************************************************
470 static ULONG WINAPI
IEnumDMO_fnAddRef(IEnumDMO
* iface
)
472 IEnumDMOImpl
*This
= impl_from_IEnumDMO(iface
);
473 ULONG refCount
= InterlockedIncrement(&This
->ref
);
474 TRACE("(%p)->(%d)\n", This
, refCount
);
478 /**************************************************************************
479 * EnumDMO_QueryInterface
481 static HRESULT WINAPI
IEnumDMO_fnQueryInterface(IEnumDMO
* iface
, REFIID riid
, void **ppvObj
)
483 IEnumDMOImpl
*This
= impl_from_IEnumDMO(iface
);
485 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObj
);
489 if (IsEqualIID(riid
, &IID_IEnumDMO
) ||
490 IsEqualIID(riid
, &IID_IUnknown
))
493 IEnumDMO_fnAddRef(iface
);
496 return *ppvObj
? S_OK
: E_NOINTERFACE
;
499 /******************************************************************************
502 static ULONG WINAPI
IEnumDMO_fnRelease(IEnumDMO
* iface
)
504 IEnumDMOImpl
*This
= impl_from_IEnumDMO(iface
);
505 ULONG refCount
= InterlockedDecrement(&This
->ref
);
507 TRACE("(%p)->(%d)\n", This
, refCount
);
511 IEnumDMOImpl_Destructor(This
);
512 HeapFree(GetProcessHeap(),0,This
);
518 /******************************************************************************
521 static HRESULT WINAPI
IEnumDMO_fnNext(
526 DWORD
* pcItemsFetched
)
530 WCHAR szNextKey
[MAX_PATH
];
532 WCHAR szKey
[MAX_PATH
];
533 WCHAR szValue
[MAX_PATH
];
539 IEnumDMOImpl
*This
= impl_from_IEnumDMO(iface
);
541 TRACE("(%p)->(%d %p %p %p)\n", This
, cItemsToFetch
, pCLSID
, Names
, pcItemsFetched
);
543 if (!pCLSID
|| !Names
|| !pcItemsFetched
)
546 while (count
< cItemsToFetch
)
551 ret
= RegEnumKeyExW(This
->hkey
, This
->index
, szNextKey
, &len
, NULL
, NULL
, NULL
, &ft
);
552 if (ret
!= ERROR_SUCCESS
)
554 hres
= HRESULT_FROM_WIN32(ret
);
558 TRACE("found %s\n", debugstr_w(szNextKey
));
560 if (!(This
->dwFlags
& DMO_ENUMF_INCLUDE_KEYED
))
562 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szNextKey
, szDMOKeyed
);
563 ret
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
564 if (ERROR_SUCCESS
== ret
)
567 /* Skip Keyed entries */
572 wsprintfW(szKey
, szCat2Fmt
, szDMORootKey
, szNextKey
);
573 ret
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
579 DMO_PARTIAL_MEDIATYPE
* pInTypes
;
581 hres
= read_types(hkey
, szDMOInputType
, &cInTypes
,
582 sizeof(szValue
)/sizeof(DMO_PARTIAL_MEDIATYPE
),
583 (DMO_PARTIAL_MEDIATYPE
*)szValue
);
591 pInTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
593 for (i
= 0; i
< This
->cInTypes
; i
++)
595 for (j
= 0; j
< cInTypes
; j
++)
597 if (IsMediaTypeEqual(&pInTypes
[j
], &This
->pInTypes
[i
]))
605 if (i
< This
->cInTypes
)
616 DMO_PARTIAL_MEDIATYPE
* pOutTypes
;
618 hres
= read_types(hkey
, szDMOOutputType
, &cOutTypes
,
619 sizeof(szValue
)/sizeof(DMO_PARTIAL_MEDIATYPE
),
620 (DMO_PARTIAL_MEDIATYPE
*)szValue
);
628 pOutTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
630 for (i
= 0; i
< This
->cOutTypes
; i
++)
632 for (j
= 0; j
< cOutTypes
; j
++)
634 if (IsMediaTypeEqual(&pOutTypes
[j
], &This
->pOutTypes
[i
]))
642 if (i
< This
->cOutTypes
)
649 /* Media object wasn't filtered so add it to return list */
651 len
= MAX_PATH
* sizeof(WCHAR
);
652 ret
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, (LPBYTE
)szValue
, &len
);
653 if (ERROR_SUCCESS
== ret
)
655 Names
[count
] = HeapAlloc(GetProcessHeap(), 0, (strlenW(szValue
) + 1) * sizeof(WCHAR
));
657 strcpyW(Names
[count
], szValue
);
659 wsprintfW(szGuidKey
,szToGuidFmt
,szNextKey
);
660 CLSIDFromString(szGuidKey
, &pCLSID
[count
]);
662 TRACE("found match %s %s\n", debugstr_w(szValue
), debugstr_w(szNextKey
));
667 *pcItemsFetched
= count
;
668 if (*pcItemsFetched
< cItemsToFetch
)
671 TRACE("<-- %i found\n",count
);
676 /******************************************************************************
679 static HRESULT WINAPI
IEnumDMO_fnSkip(IEnumDMO
* iface
, DWORD cItemsToSkip
)
681 IEnumDMOImpl
*This
= impl_from_IEnumDMO(iface
);
683 TRACE("(%p)->(%d)\n", This
, cItemsToSkip
);
684 This
->index
+= cItemsToSkip
;
690 /******************************************************************************
693 static HRESULT WINAPI
IEnumDMO_fnReset(IEnumDMO
* iface
)
695 IEnumDMOImpl
*This
= impl_from_IEnumDMO(iface
);
697 TRACE("(%p)\n", This
);
704 /******************************************************************************
707 static HRESULT WINAPI
IEnumDMO_fnClone(IEnumDMO
*iface
, IEnumDMO
**ppEnum
)
709 IEnumDMOImpl
*This
= impl_from_IEnumDMO(iface
);
710 TRACE("(%p)->(%p)\n", This
, ppEnum
);
711 return IEnumDMO_Constructor(This
->guidCategory
, This
->dwFlags
, This
->cInTypes
, This
->pInTypes
,
712 This
->cOutTypes
, This
->pOutTypes
, ppEnum
);
716 /***************************************************************
719 * Enumerate DirectX Media Objects in the registry.
721 HRESULT WINAPI
DMOEnum(
722 REFGUID guidCategory
,
725 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
727 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
,
730 TRACE("guidCategory=%p dwFlags=0x%08x cInTypes=%d cOutTypes=%d\n",
731 guidCategory
, dwFlags
, cInTypes
, cOutTypes
);
733 return IEnumDMO_Constructor(guidCategory
, dwFlags
, cInTypes
,
734 pInTypes
, cOutTypes
, pOutTypes
, ppEnum
);
738 static const IEnumDMOVtbl edmovt
=
740 IEnumDMO_fnQueryInterface
,
750 HRESULT
read_types(HKEY root
, LPCWSTR key
, ULONG
*supplied
, ULONG requested
, DMO_PARTIAL_MEDIATYPE
* types
)
754 if (MSDMO_MAJOR_VERSION
> 5)
759 len
= requested
* sizeof(DMO_PARTIAL_MEDIATYPE
);
760 rc
= RegQueryValueExW(root
, key
, NULL
, NULL
, (LPBYTE
) types
, &len
);
761 ret
= HRESULT_FROM_WIN32(rc
);
763 *supplied
= len
/ sizeof(DMO_PARTIAL_MEDIATYPE
);
771 if (ERROR_SUCCESS
== RegOpenKeyExW(root
, key
, 0, KEY_READ
, &hkey
))
774 WCHAR szNextKey
[MAX_PATH
];
776 LONG rc
= ERROR_SUCCESS
;
778 while (rc
== ERROR_SUCCESS
)
781 rc
= RegEnumKeyExW(hkey
, index
, szNextKey
, &len
, NULL
, NULL
, NULL
, NULL
);
782 if (rc
== ERROR_SUCCESS
)
786 LONG rcs
= ERROR_SUCCESS
;
787 WCHAR szSubKey
[MAX_PATH
];
789 RegOpenKeyExW(hkey
, szNextKey
, 0, KEY_READ
, &subk
);
790 while (rcs
== ERROR_SUCCESS
)
793 rcs
= RegEnumKeyExW(subk
, sub_index
, szSubKey
, &len
, NULL
, NULL
, NULL
, NULL
);
794 if (rcs
== ERROR_SUCCESS
)
796 if (*supplied
>= requested
)
800 rc
= ERROR_MORE_DATA
;
801 rcs
= ERROR_MORE_DATA
;
805 wsprintfW(szGuidKey
,szToGuidFmt
,szNextKey
);
806 CLSIDFromString(szGuidKey
, &types
[*supplied
].type
);
807 wsprintfW(szGuidKey
,szToGuidFmt
,szSubKey
);
808 CLSIDFromString(szGuidKey
, &types
[*supplied
].subtype
);
809 TRACE("Adding type %s subtype %s at index %i\n",
810 debugstr_guid(&types
[*supplied
].type
),
811 debugstr_guid(&types
[*supplied
].subtype
),
826 /***************************************************************
827 * DMOGetTypes (MSDMO.@)
829 HRESULT WINAPI
DMOGetTypes(REFCLSID clsidDMO
,
830 ULONG ulInputTypesRequested
,
831 ULONG
* pulInputTypesSupplied
,
832 DMO_PARTIAL_MEDIATYPE
* pInputTypes
,
833 ULONG ulOutputTypesRequested
,
834 ULONG
* pulOutputTypesSupplied
,
835 DMO_PARTIAL_MEDIATYPE
* pOutputTypes
)
841 TRACE ("(%s,%u,%p,%p,%u,%p,%p)\n", debugstr_guid(clsidDMO
), ulInputTypesRequested
,
842 pulInputTypesSupplied
, pInputTypes
, ulOutputTypesRequested
, pulOutputTypesSupplied
,
845 if (ERROR_SUCCESS
!= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0,
849 if (ERROR_SUCCESS
!= RegOpenKeyExW(root
,GUIDToString(szguid
,clsidDMO
) , 0,
856 if (ulInputTypesRequested
> 0)
858 ret
= read_types(hkey
, szDMOInputType
, pulInputTypesSupplied
, ulInputTypesRequested
, pInputTypes
);
861 *pulInputTypesSupplied
= 0;
863 if (ulOutputTypesRequested
> 0)
866 ret2
= read_types(hkey
, szDMOOutputType
, pulOutputTypesSupplied
, ulOutputTypesRequested
, pOutputTypes
);
872 *pulOutputTypesSupplied
= 0;