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