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
);
36 static const WCHAR szDMORootKey
[] =
38 'D','i','r','e','c','t','S','h','o','w','\\',
39 'M','e','d','i','a','O','b','j','e','c','t','s',0
42 static const WCHAR szDMOInputType
[] =
44 'I','n','p','u','t','T','y','p','e','s',0
47 static const WCHAR szDMOOutputType
[] =
49 'O','u','t','p','u','t','T','y','p','e','s',0
52 static const WCHAR szDMOKeyed
[] =
57 static const WCHAR szDMOCategories
[] =
59 'C','a','t','e','g','o','r','i','e','s',0
62 static const WCHAR szGUIDFmt
[] =
64 '%','0','8','X','-','%','0','4','X','-','%','0','4','X','-','%','0',
65 '2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2',
66 'X','%','0','2','X','%','0','2','X','%','0','2','X',0
69 static const WCHAR szCat3Fmt
[] =
71 '%','s','\\','%','s','\\','%','s',0
74 static const WCHAR szCat2Fmt
[] =
76 '%','s','\\','%','s',0
81 const IEnumDMOVtbl
*lpVtbl
;
84 const GUID
* guidCategory
;
87 DMO_PARTIAL_MEDIATYPE
*pInTypes
;
89 DMO_PARTIAL_MEDIATYPE
*pOutTypes
;
93 static const IEnumDMOVtbl edmovt
;
95 static LPWSTR
GUIDToString(LPWSTR lpwstr
, REFGUID lpcguid
)
97 wsprintfW(lpwstr
, szGUIDFmt
, lpcguid
->Data1
, lpcguid
->Data2
,
98 lpcguid
->Data3
, lpcguid
->Data4
[0], lpcguid
->Data4
[1],
99 lpcguid
->Data4
[2], lpcguid
->Data4
[3], lpcguid
->Data4
[4],
100 lpcguid
->Data4
[5], lpcguid
->Data4
[6], lpcguid
->Data4
[7]);
105 static BOOL
IsMediaTypeEqual(const DMO_PARTIAL_MEDIATYPE
* mt1
, const DMO_PARTIAL_MEDIATYPE
* mt2
)
108 return (IsEqualCLSID(&mt1
->type
, &mt2
->type
) ||
109 IsEqualCLSID(&mt2
->type
, &GUID_NULL
) ||
110 IsEqualCLSID(&mt1
->type
, &GUID_NULL
)) &&
111 (IsEqualCLSID(&mt1
->subtype
, &mt2
->subtype
) ||
112 IsEqualCLSID(&mt2
->subtype
, &GUID_NULL
) ||
113 IsEqualCLSID(&mt1
->subtype
, &GUID_NULL
));
116 /***************************************************************
119 * Register a DirectX Media Object.
121 HRESULT WINAPI
DMORegister(
124 REFGUID guidCategory
,
127 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
129 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
139 TRACE("%s\n", debugstr_w(szName
));
141 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_WRITE
, &hrkey
);
142 if (ERROR_SUCCESS
!= hres
)
145 /* Create clsidDMO key under MediaObjects */
146 hres
= RegCreateKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
147 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hkey
, NULL
);
148 if (ERROR_SUCCESS
!= hres
)
151 /* Set default Name value */
152 hres
= RegSetValueExW(hkey
, NULL
, 0, REG_SZ
, (const BYTE
*) szName
,
153 (strlenW(szName
) + 1)) * sizeof(WCHAR
);
155 hres
= RegSetValueExW(hkey
, szDMOInputType
, 0, REG_BINARY
,
156 (const BYTE
*) pInTypes
, cInTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
));
157 /* Set OutputTypes */
158 hres
= RegSetValueExW(hkey
, szDMOOutputType
, 0, REG_BINARY
,
159 (const BYTE
*) pOutTypes
, cOutTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
));
161 if (dwFlags
& DMO_REGISTERF_IS_KEYED
)
163 /* Create Keyed key */
164 hres
= RegCreateKeyExW(hkey
, szDMOKeyed
, 0, NULL
,
165 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hckey
, NULL
);
166 if (ERROR_SUCCESS
!= hres
)
171 /* Register the category */
172 hres
= RegOpenKeyExW(hrkey
, szDMOCategories
, 0, KEY_WRITE
, &hckey
);
173 if (ERROR_SUCCESS
!= hres
)
178 hres
= RegOpenKeyExW(hckey
, GUIDToString(szguid
, guidCategory
), 0, KEY_WRITE
, &hkey
);
179 if (ERROR_SUCCESS
!= hres
)
181 hres
= RegCreateKeyExW(hkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
182 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hclskey
, NULL
);
183 if (ERROR_SUCCESS
!= hres
)
192 RegCloseKey(hclskey
);
196 TRACE(" hresult=0x%08x\n", hres
);
201 /***************************************************************
204 * Unregister a DirectX Media Object.
206 HRESULT WINAPI
DMOUnregister(REFCLSID clsidDMO
, REFGUID guidCategory
)
213 GUIDToString(szguid
, clsidDMO
);
215 TRACE("%s %p\n", debugstr_w(szguid
), guidCategory
);
217 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_WRITE
, &hrkey
);
218 if (ERROR_SUCCESS
!= hres
)
221 hres
= RegDeleteKeyW(hrkey
, szguid
);
222 if (ERROR_SUCCESS
!= hres
)
225 hres
= RegOpenKeyExW(hrkey
, szDMOCategories
, 0, KEY_WRITE
, &hckey
);
226 if (ERROR_SUCCESS
!= hres
)
229 hres
= RegDeleteKeyW(hckey
, szguid
);
230 if (ERROR_SUCCESS
!= hres
)
243 /***************************************************************
246 * Get DMP Name from the registry
248 HRESULT WINAPI
DMOGetName(REFCLSID clsidDMO
, WCHAR
* szName
)
256 TRACE("%s\n", debugstr_guid(clsidDMO
));
258 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
,
259 0, KEY_READ
, &hrkey
);
260 if (ERROR_SUCCESS
!= hres
)
263 hres
= RegOpenKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
),
265 if (ERROR_SUCCESS
!= hres
)
268 count
= 80 * sizeof(WCHAR
); /* 80 by API definition */
269 hres
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
,
270 (LPBYTE
) szName
, &count
);
272 TRACE(" szName=%s\n", debugstr_w(szName
));
283 /**************************************************************************
284 * IEnumDMO_Destructor
286 static BOOL
IEnumDMO_Destructor(IEnumDMO
* iface
)
288 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
293 RegCloseKey(This
->hkey
);
295 HeapFree(GetProcessHeap(), 0, This
->pInTypes
);
296 HeapFree(GetProcessHeap(), 0, This
->pOutTypes
);
302 /**************************************************************************
303 * IEnumDMO_Constructor
305 static IEnumDMO
* IEnumDMO_Constructor(
306 REFGUID guidCategory
,
309 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
311 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
)
314 IEnumDMOImpl
* lpedmo
;
317 lpedmo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IEnumDMOImpl
));
322 lpedmo
->lpVtbl
= &edmovt
;
324 lpedmo
->guidCategory
= guidCategory
;
325 lpedmo
->dwFlags
= dwFlags
;
327 size
= cInTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
328 lpedmo
->pInTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
329 if (!lpedmo
->pInTypes
)
331 memcpy(lpedmo
->pInTypes
, pInTypes
, size
);
332 lpedmo
->cInTypes
= cInTypes
;
334 size
= cOutTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
335 lpedmo
->pOutTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
336 if (!lpedmo
->pOutTypes
)
338 memcpy(lpedmo
->pOutTypes
, pOutTypes
, size
);
339 lpedmo
->cOutTypes
= cOutTypes
;
341 /* If not filtering by category enum from media objects root */
342 if (IsEqualGUID(guidCategory
, &GUID_NULL
))
344 if (ERROR_SUCCESS
== RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
,
345 0, KEY_READ
, &lpedmo
->hkey
))
351 WCHAR szKey
[MAX_PATH
];
353 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szDMOCategories
,
354 GUIDToString(szguid
, guidCategory
));
355 if (ERROR_SUCCESS
== RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
,
356 0, KEY_READ
, &lpedmo
->hkey
))
363 IEnumDMO_Destructor((IEnumDMO
*)lpedmo
);
364 HeapFree(GetProcessHeap(),0,lpedmo
);
369 TRACE("returning %p\n", lpedmo
);
371 return (IEnumDMO
*)lpedmo
;
375 /******************************************************************************
378 static ULONG WINAPI
IEnumDMO_fnAddRef(IEnumDMO
* iface
)
380 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
381 return InterlockedIncrement(&This
->ref
);
385 /**************************************************************************
386 * EnumDMO_QueryInterface
388 static HRESULT WINAPI
IEnumDMO_fnQueryInterface(
393 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
397 if(IsEqualIID(riid
, &IID_IUnknown
))
399 else if(IsEqualIID(riid
, &IID_IEnumDMO
))
400 *ppvObj
= (IEnumDMO
*)This
;
404 IEnumDMO_fnAddRef((IEnumDMO
*)*ppvObj
);
408 return E_NOINTERFACE
;
412 /******************************************************************************
415 static ULONG WINAPI
IEnumDMO_fnRelease(IEnumDMO
* iface
)
417 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
418 ULONG refCount
= InterlockedDecrement(&This
->ref
);
422 IEnumDMO_Destructor((IEnumDMO
*)This
);
423 HeapFree(GetProcessHeap(),0,This
);
429 /******************************************************************************
432 static HRESULT WINAPI
IEnumDMO_fnNext(
437 DWORD
* pcItemsFetched
)
441 WCHAR szNextKey
[MAX_PATH
];
442 WCHAR szKey
[MAX_PATH
];
443 WCHAR szValue
[MAX_PATH
];
448 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
450 TRACE("%d\n", cItemsToFetch
);
452 if (!pCLSID
|| !Names
|| !pcItemsFetched
)
455 while (count
< cItemsToFetch
)
459 hres
= RegEnumKeyExW(This
->hkey
, This
->index
, szNextKey
, &len
, NULL
, NULL
, NULL
, &ft
);
460 if (hres
!= ERROR_SUCCESS
)
463 TRACE("found %s\n", debugstr_w(szNextKey
));
465 if (This
->dwFlags
& DMO_REGISTERF_IS_KEYED
)
467 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szNextKey
, szDMOKeyed
);
468 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
469 if (ERROR_SUCCESS
!= hres
)
474 wsprintfW(szKey
, szCat2Fmt
, szDMORootKey
, szNextKey
);
475 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
481 DMO_PARTIAL_MEDIATYPE
* pInTypes
;
483 len
= MAX_PATH
* sizeof(WCHAR
);
484 hres
= RegQueryValueExW(hkey
, szDMOInputType
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
485 if (ERROR_SUCCESS
!= hres
)
491 cInTypes
= len
/ sizeof(DMO_PARTIAL_MEDIATYPE
);
492 pInTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
494 for (i
= 0; i
< This
->cInTypes
; i
++)
496 for (j
= 0; j
< cInTypes
; j
++)
498 if (IsMediaTypeEqual(&pInTypes
[j
], &This
->pInTypes
[i
]))
506 if (i
< This
->cInTypes
)
517 DMO_PARTIAL_MEDIATYPE
* pOutTypes
;
519 len
= MAX_PATH
* sizeof(WCHAR
);
520 hres
= RegQueryValueExW(hkey
, szDMOOutputType
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
521 if (ERROR_SUCCESS
!= hres
)
527 cOutTypes
= len
/ sizeof(DMO_PARTIAL_MEDIATYPE
);
528 pOutTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
530 for (i
= 0; i
< This
->cOutTypes
; i
++)
532 for (j
= 0; j
< cOutTypes
; j
++)
534 if (IsMediaTypeEqual(&pOutTypes
[j
], &This
->pOutTypes
[i
]))
542 if (i
< This
->cOutTypes
)
549 /* Media object wasn't filtered so add it to return list */
551 len
= MAX_PATH
* sizeof(WCHAR
);
552 hres
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
553 if (ERROR_SUCCESS
== hres
)
555 Names
[count
] = HeapAlloc(GetProcessHeap(), 0, strlenW(szValue
) + 1);
557 strcmpW(Names
[count
], szValue
);
559 CLSIDFromString(szNextKey
, &pCLSID
[count
]);
561 TRACE("found match %s %s\n", debugstr_w(szValue
), debugstr_w(szNextKey
));
566 *pcItemsFetched
= count
;
567 if (*pcItemsFetched
< cItemsToFetch
)
574 /******************************************************************************
577 static HRESULT WINAPI
IEnumDMO_fnSkip(IEnumDMO
* iface
, DWORD cItemsToSkip
)
579 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
581 This
->index
+= cItemsToSkip
;
587 /******************************************************************************
590 static HRESULT WINAPI
IEnumDMO_fnReset(IEnumDMO
* iface
)
592 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
600 /******************************************************************************
603 static HRESULT WINAPI
IEnumDMO_fnClone(IEnumDMO
* iface
, IEnumDMO
**ppEnum
)
605 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
607 FIXME("(%p)->() to (%p)->() E_NOTIMPL\n", This
, ppEnum
);
613 /***************************************************************
616 * Enumerate DirectX Media Objects in the registry.
618 HRESULT WINAPI
DMOEnum(
619 REFGUID guidCategory
,
622 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
624 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
,
627 HRESULT hres
= E_FAIL
;
629 TRACE("guidCategory=%p dwFlags=0x%08x cInTypes=%d cOutTypes=%d\n",
630 guidCategory
, dwFlags
, cInTypes
, cOutTypes
);
632 *ppEnum
= IEnumDMO_Constructor(guidCategory
, dwFlags
, cInTypes
,
633 pInTypes
, cOutTypes
, pOutTypes
);
641 static const IEnumDMOVtbl edmovt
=
643 IEnumDMO_fnQueryInterface
,
653 HRESULT WINAPI
DMOGetTypes(REFCLSID a
, ULONG b
, ULONG
* c
,
654 DMO_PARTIAL_MEDIATYPE
* d
, ULONG e
,
655 ULONG
* f
, DMO_PARTIAL_MEDIATYPE
* g
)
657 FIXME("(%p,%u,%p,%p,%u,%p,%p),stub!\n",a
,b
,c
,d
,e
,f
,g
);