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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #define COM_NO_WINDOWS_H
29 #include "wine/unicode.h"
30 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(msdmo
);
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
82 const IEnumDMOVtbl
*lpVtbl
;
85 const GUID
* guidCategory
;
88 DMO_PARTIAL_MEDIATYPE
*pInTypes
;
90 DMO_PARTIAL_MEDIATYPE
*pOutTypes
;
94 static const IEnumDMOVtbl edmovt
;
96 static LPWSTR
GUIDToString(LPWSTR lpwstr
, REFGUID lpcguid
)
98 wsprintfW(lpwstr
, szGUIDFmt
, lpcguid
->Data1
, lpcguid
->Data2
,
99 lpcguid
->Data3
, lpcguid
->Data4
[0], lpcguid
->Data4
[1],
100 lpcguid
->Data4
[2], lpcguid
->Data4
[3], lpcguid
->Data4
[4],
101 lpcguid
->Data4
[5], lpcguid
->Data4
[6], lpcguid
->Data4
[7]);
106 static BOOL
IsMediaTypeEqual(DMO_PARTIAL_MEDIATYPE
* mt1
, DMO_PARTIAL_MEDIATYPE
* mt2
)
109 return (IsEqualCLSID(&mt1
->type
, &mt2
->type
) ||
110 IsEqualCLSID(&mt2
->type
, &GUID_NULL
) ||
111 IsEqualCLSID(&mt1
->type
, &GUID_NULL
)) &&
112 (IsEqualCLSID(&mt1
->subtype
, &mt2
->subtype
) ||
113 IsEqualCLSID(&mt2
->subtype
, &GUID_NULL
) ||
114 IsEqualCLSID(&mt1
->subtype
, &GUID_NULL
));
117 /***************************************************************
120 * Register a DirectX Media Object.
122 HRESULT WINAPI
DMORegister(
125 REFGUID guidCategory
,
128 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
130 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
140 TRACE("%s\n", debugstr_w(szName
));
142 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_WRITE
, &hrkey
);
143 if (ERROR_SUCCESS
!= hres
)
146 /* Create clsidDMO key under MediaObjects */
147 hres
= RegCreateKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
148 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hkey
, NULL
);
149 if (ERROR_SUCCESS
!= hres
)
152 /* Set default Name value */
153 hres
= RegSetValueExW(hkey
, NULL
, 0, REG_SZ
, (const BYTE
*) szName
,
154 (strlenW(szName
) + 1)) * sizeof(WCHAR
);
156 hres
= RegSetValueExW(hkey
, szDMOInputType
, 0, REG_BINARY
,
157 (const BYTE
*) pInTypes
, cInTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
));
158 /* Set OutputTypes */
159 hres
= RegSetValueExW(hkey
, szDMOOutputType
, 0, REG_BINARY
,
160 (const BYTE
*) pOutTypes
, cOutTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
));
162 if (dwFlags
& DMO_REGISTERF_IS_KEYED
)
164 /* Create Keyed key */
165 hres
= RegCreateKeyExW(hkey
, szDMOKeyed
, 0, NULL
,
166 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hckey
, NULL
);
167 if (ERROR_SUCCESS
!= hres
)
172 /* Register the category */
173 hres
= RegOpenKeyExW(hrkey
, szDMOCategories
, 0, KEY_WRITE
, &hckey
);
174 if (ERROR_SUCCESS
!= hres
)
179 hres
= RegOpenKeyExW(hckey
, GUIDToString(szguid
, guidCategory
), 0, KEY_WRITE
, &hkey
);
180 if (ERROR_SUCCESS
!= hres
)
182 hres
= RegCreateKeyExW(hkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
183 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hclskey
, NULL
);
184 if (ERROR_SUCCESS
!= hres
)
193 RegCloseKey(hclskey
);
197 TRACE(" hresult=0x%08lx\n", hres
);
202 /***************************************************************
205 * Unregister a DirectX Media Object.
207 HRESULT WINAPI
DMOUnregister(REFCLSID clsidDMO
, REFGUID guidCategory
)
214 GUIDToString(szguid
, clsidDMO
);
216 TRACE("%s %p\n", debugstr_w(szguid
), guidCategory
);
218 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_WRITE
, &hrkey
);
219 if (ERROR_SUCCESS
!= hres
)
222 hres
= RegDeleteKeyW(hrkey
, szguid
);
223 if (ERROR_SUCCESS
!= hres
)
226 hres
= RegOpenKeyExW(hrkey
, szDMOCategories
, 0, KEY_WRITE
, &hckey
);
227 if (ERROR_SUCCESS
!= hres
)
230 hres
= RegDeleteKeyW(hckey
, szguid
);
231 if (ERROR_SUCCESS
!= hres
)
244 /***************************************************************
247 * Get DMP Name from the registry
249 HRESULT WINAPI
DMOGetName(REFCLSID clsidDMO
, WCHAR
* szName
)
257 TRACE("%s\n", debugstr_guid(clsidDMO
));
259 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
,
260 0, KEY_READ
, &hrkey
);
261 if (ERROR_SUCCESS
!= hres
)
264 hres
= RegOpenKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
),
266 if (ERROR_SUCCESS
!= hres
)
269 count
= 80 * sizeof(WCHAR
); /* 80 by API definition */
270 hres
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
,
271 (LPBYTE
) szName
, &count
);
273 TRACE(" szName=%s\n", debugstr_w(szName
));
284 /**************************************************************************
285 * IEnumDMO_Destructor
287 static BOOL
IEnumDMO_Destructor(IEnumDMO
* iface
)
289 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
294 RegCloseKey(This
->hkey
);
296 HeapFree(GetProcessHeap(), 0, This
->pInTypes
);
297 HeapFree(GetProcessHeap(), 0, This
->pOutTypes
);
303 /**************************************************************************
304 * IEnumDMO_Constructor
306 IEnumDMO
* IEnumDMO_Constructor(
307 REFGUID guidCategory
,
310 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
312 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
)
315 IEnumDMOImpl
* lpedmo
;
318 lpedmo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IEnumDMOImpl
));
323 lpedmo
->lpVtbl
= &edmovt
;
325 lpedmo
->guidCategory
= guidCategory
;
326 lpedmo
->dwFlags
= dwFlags
;
328 size
= cInTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
329 lpedmo
->pInTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
330 if (!lpedmo
->pInTypes
)
332 memcpy(lpedmo
->pInTypes
, pInTypes
, size
);
333 lpedmo
->cInTypes
= cInTypes
;
335 size
= cOutTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
336 lpedmo
->pOutTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
337 if (!lpedmo
->pOutTypes
)
339 memcpy(lpedmo
->pOutTypes
, pOutTypes
, size
);
340 lpedmo
->cOutTypes
= cOutTypes
;
342 /* If not filtering by category enum from media objects root */
343 if (IsEqualGUID(guidCategory
, &GUID_NULL
))
345 if (ERROR_SUCCESS
== RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
,
346 0, KEY_READ
, &lpedmo
->hkey
))
352 WCHAR szKey
[MAX_PATH
];
354 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szDMOCategories
,
355 GUIDToString(szguid
, guidCategory
));
356 if (ERROR_SUCCESS
== RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
,
357 0, KEY_READ
, &lpedmo
->hkey
))
364 IEnumDMO_Destructor((IEnumDMO
*)lpedmo
);
365 HeapFree(GetProcessHeap(),0,lpedmo
);
370 TRACE("returning %p\n", lpedmo
);
372 return (IEnumDMO
*)lpedmo
;
376 /******************************************************************************
379 static ULONG WINAPI
IEnumDMO_fnAddRef(IEnumDMO
* iface
)
381 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
382 return InterlockedIncrement(&This
->ref
);
386 /**************************************************************************
387 * EnumDMO_QueryInterface
389 static HRESULT WINAPI
IEnumDMO_fnQueryInterface(
394 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
398 if(IsEqualIID(riid
, &IID_IUnknown
))
400 else if(IsEqualIID(riid
, &IID_IEnumDMO
))
401 *ppvObj
= (IEnumDMO
*)This
;
405 IEnumDMO_fnAddRef((IEnumDMO
*)*ppvObj
);
409 return E_NOINTERFACE
;
413 /******************************************************************************
416 static ULONG WINAPI
IEnumDMO_fnRelease(IEnumDMO
* iface
)
418 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
419 ULONG refCount
= InterlockedDecrement(&This
->ref
);
423 IEnumDMO_Destructor((IEnumDMO
*)This
);
424 HeapFree(GetProcessHeap(),0,This
);
430 /******************************************************************************
433 static HRESULT WINAPI
IEnumDMO_fnNext(
438 DWORD
* pcItemsFetched
)
442 WCHAR szNextKey
[MAX_PATH
];
443 WCHAR szKey
[MAX_PATH
];
444 WCHAR szValue
[MAX_PATH
];
449 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
451 TRACE("%ld\n", cItemsToFetch
);
453 if (!pCLSID
|| !Names
|| !pcItemsFetched
)
456 while (count
< cItemsToFetch
)
460 hres
= RegEnumKeyExW(This
->hkey
, This
->index
, szNextKey
, &len
, NULL
, NULL
, NULL
, &ft
);
461 if (hres
!= ERROR_SUCCESS
)
464 TRACE("found %s\n", debugstr_w(szNextKey
));
466 if (This
->dwFlags
& DMO_REGISTERF_IS_KEYED
)
468 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szNextKey
, szDMOKeyed
);
469 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
470 if (ERROR_SUCCESS
!= hres
)
475 wsprintfW(szKey
, szCat2Fmt
, szDMORootKey
, szNextKey
);
476 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
482 DMO_PARTIAL_MEDIATYPE
* pInTypes
;
484 len
= MAX_PATH
* sizeof(WCHAR
);
485 hres
= RegQueryValueExW(hkey
, szDMOInputType
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
486 if (ERROR_SUCCESS
!= hres
)
492 cInTypes
= len
/ sizeof(DMO_PARTIAL_MEDIATYPE
);
493 pInTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
495 for (i
= 0; i
< This
->cInTypes
; i
++)
497 for (j
= 0; j
< cInTypes
; j
++)
499 if (IsMediaTypeEqual(&pInTypes
[j
], &This
->pInTypes
[i
]))
507 if (i
< This
->cInTypes
)
518 DMO_PARTIAL_MEDIATYPE
* pOutTypes
;
520 len
= MAX_PATH
* sizeof(WCHAR
);
521 hres
= RegQueryValueExW(hkey
, szDMOOutputType
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
522 if (ERROR_SUCCESS
!= hres
)
528 cOutTypes
= len
/ sizeof(DMO_PARTIAL_MEDIATYPE
);
529 pOutTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
531 for (i
= 0; i
< This
->cOutTypes
; i
++)
533 for (j
= 0; j
< cOutTypes
; j
++)
535 if (IsMediaTypeEqual(&pOutTypes
[j
], &This
->pOutTypes
[i
]))
543 if (i
< This
->cOutTypes
)
550 /* Media object wasn't filtered so add it to return list */
552 len
= MAX_PATH
* sizeof(WCHAR
);
553 hres
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
554 if (ERROR_SUCCESS
== hres
)
556 Names
[count
] = HeapAlloc(GetProcessHeap(), 0, strlenW(szValue
) + 1);
558 strcmpW(Names
[count
], szValue
);
560 CLSIDFromString(szNextKey
, &pCLSID
[count
]);
562 TRACE("found match %s %s\n", debugstr_w(szValue
), debugstr_w(szNextKey
));
567 *pcItemsFetched
= count
;
568 if (*pcItemsFetched
< cItemsToFetch
)
575 /******************************************************************************
578 static HRESULT WINAPI
IEnumDMO_fnSkip(IEnumDMO
* iface
, DWORD cItemsToSkip
)
580 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
582 This
->index
+= cItemsToSkip
;
588 /******************************************************************************
591 static HRESULT WINAPI
IEnumDMO_fnReset(IEnumDMO
* iface
)
593 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
601 /******************************************************************************
604 static HRESULT WINAPI
IEnumDMO_fnClone(IEnumDMO
* iface
, IEnumDMO
**ppEnum
)
606 IEnumDMOImpl
*This
= (IEnumDMOImpl
*)iface
;
608 FIXME("(%p)->() to (%p)->() E_NOTIMPL\n", This
, ppEnum
);
614 /***************************************************************
617 * Enumerate DirectX Media Objects in the registry.
619 HRESULT WINAPI
DMOEnum(
620 REFGUID guidCategory
,
623 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
625 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
,
628 HRESULT hres
= E_FAIL
;
630 TRACE("guidCategory=%p dwFlags=0x%08lx cInTypes=%ld cOutTypes=%ld\n",
631 guidCategory
, dwFlags
, cInTypes
, cOutTypes
);
633 *ppEnum
= IEnumDMO_Constructor(guidCategory
, dwFlags
, cInTypes
,
634 pInTypes
, cOutTypes
, pOutTypes
);
642 static const IEnumDMOVtbl edmovt
=
644 IEnumDMO_fnQueryInterface
,
654 HRESULT WINAPI
DMOGetTypes(REFCLSID a
, unsigned long b
, unsigned long* c
,
655 DMO_PARTIAL_MEDIATYPE
* d
, unsigned long e
,
656 unsigned long* f
, DMO_PARTIAL_MEDIATYPE
* g
)
658 FIXME("(%p,%lu,%p,%p,%lu,%p,%p),stub!\n",a
,b
,c
,d
,e
,f
,g
);