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
31 #include "wine/unicode.h"
32 #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 ICOM_VFIELD(IEnumDMO
);
85 const GUID
* guidCategory
;
88 DMO_PARTIAL_MEDIATYPE
*pInTypes
;
90 DMO_PARTIAL_MEDIATYPE
*pOutTypes
;
94 const GUID IID_IEnumDMO
= { 0x2c3cd98a, 0x2bfa, 0x4a53,
95 { 0x9c, 0x27, 0x52, 0x49, 0xba, 0x64, 0xba, 0x0f}};
97 static struct ICOM_VTABLE(IEnumDMO
) edmovt
;
99 static LPWSTR
GUIDToString(LPWSTR lpwstr
, REFGUID lpcguid
)
101 wsprintfW(lpwstr
, szGUIDFmt
, lpcguid
->Data1
, lpcguid
->Data2
,
102 lpcguid
->Data3
, lpcguid
->Data4
[0], lpcguid
->Data4
[1],
103 lpcguid
->Data4
[2], lpcguid
->Data4
[3], lpcguid
->Data4
[4],
104 lpcguid
->Data4
[5], lpcguid
->Data4
[6], lpcguid
->Data4
[7]);
109 static BOOL
IsMediaTypeEqual(DMO_PARTIAL_MEDIATYPE
* mt1
, DMO_PARTIAL_MEDIATYPE
* mt2
)
112 return (IsEqualCLSID(&mt1
->type
, &mt2
->type
) ||
113 IsEqualCLSID(&mt2
->type
, &GUID_NULL
) ||
114 IsEqualCLSID(&mt1
->type
, &GUID_NULL
)) &&
115 (IsEqualCLSID(&mt1
->subtype
, &mt2
->subtype
) ||
116 IsEqualCLSID(&mt2
->subtype
, &GUID_NULL
) ||
117 IsEqualCLSID(&mt1
->subtype
, &GUID_NULL
));
120 /***************************************************************
123 * Register a DirectX Media Object.
125 HRESULT WINAPI
DMORegister(
128 REFGUID guidCategory
,
131 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
133 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
143 TRACE("%s\n", debugstr_w(szName
));
145 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_WRITE
, &hrkey
);
146 if (ERROR_SUCCESS
!= hres
)
149 /* Create clsidDMO key under MediaObjects */
150 hres
= RegCreateKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
151 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hkey
, NULL
);
152 if (ERROR_SUCCESS
!= hres
)
155 /* Set default Name value */
156 hres
= RegSetValueExW(hkey
, NULL
, 0, REG_SZ
, (LPBYTE
) szName
,
157 (strlenW(szName
) + 1)) * sizeof(WCHAR
);
159 hres
= RegSetValueExW(hkey
, szDMOInputType
, 0, REG_BINARY
,
160 (LPBYTE
) pInTypes
, cInTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
));
161 /* Set OutputTypes */
162 hres
= RegSetValueExW(hkey
, szDMOOutputType
, 0, REG_BINARY
,
163 (LPBYTE
) pOutTypes
, cOutTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
));
165 if (dwFlags
& DMO_REGISTERF_IS_KEYED
)
167 /* Create Keyed key */
168 hres
= RegCreateKeyExW(hkey
, szDMOKeyed
, 0, NULL
,
169 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hckey
, NULL
);
170 if (ERROR_SUCCESS
!= hres
)
175 /* Register the category */
176 hres
= RegOpenKeyExW(hrkey
, szDMOCategories
, 0, KEY_WRITE
, &hckey
);
177 if (ERROR_SUCCESS
!= hres
)
182 hres
= RegOpenKeyExW(hckey
, GUIDToString(szguid
, guidCategory
), 0, KEY_WRITE
, &hkey
);
183 if (ERROR_SUCCESS
!= hres
)
185 hres
= RegCreateKeyExW(hkey
, GUIDToString(szguid
, clsidDMO
), 0, NULL
,
186 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hclskey
, NULL
);
187 if (ERROR_SUCCESS
!= hres
)
196 RegCloseKey(hclskey
);
200 TRACE(" hresult=0x%08lx\n", hres
);
205 /***************************************************************
208 * Unregister a DirectX Media Object.
210 HRESULT WINAPI
DMOUnregister(REFCLSID clsidDMO
, REFGUID guidCategory
)
217 GUIDToString(szguid
, clsidDMO
);
219 TRACE("%s %p\n", debugstr_w(szguid
), guidCategory
);
221 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
, 0, KEY_WRITE
, &hrkey
);
222 if (ERROR_SUCCESS
!= hres
)
225 hres
= RegDeleteKeyW(hrkey
, szguid
);
226 if (ERROR_SUCCESS
!= hres
)
229 hres
= RegOpenKeyExW(hrkey
, szDMOCategories
, 0, KEY_WRITE
, &hckey
);
230 if (ERROR_SUCCESS
!= hres
)
233 hres
= RegDeleteKeyW(hckey
, szguid
);
234 if (ERROR_SUCCESS
!= hres
)
247 /***************************************************************
250 * Get DMP Name from the registry
252 HRESULT WINAPI
DMOGetName(REFCLSID clsidDMO
, WCHAR
* szName
)
260 TRACE("%s\n", debugstr_guid(clsidDMO
));
262 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
,
263 0, KEY_READ
, &hrkey
);
264 if (ERROR_SUCCESS
!= hres
)
267 hres
= RegOpenKeyExW(hrkey
, GUIDToString(szguid
, clsidDMO
),
269 if (ERROR_SUCCESS
!= hres
)
272 count
= 80 * sizeof(WCHAR
); /* 80 by API definition */
273 hres
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
,
274 (LPBYTE
) szName
, &count
);
276 TRACE(" szName=%s\n", debugstr_w(szName
));
287 /**************************************************************************
288 * IEnumDMO_Destructor
290 static BOOL
IEnumDMO_Destructor(IEnumDMO
* iface
)
292 ICOM_THIS(IEnumDMOImpl
,iface
);
297 RegCloseKey(This
->hkey
);
300 HeapFree(GetProcessHeap(), 0, This
->pInTypes
);
303 HeapFree(GetProcessHeap(), 0, This
->pOutTypes
);
309 /**************************************************************************
310 * IEnumDMO_Constructor
312 IEnumDMO
* IEnumDMO_Constructor(
313 REFGUID guidCategory
,
316 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
318 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
)
321 IEnumDMOImpl
* lpedmo
;
324 lpedmo
= (IEnumDMOImpl
*)HeapAlloc(GetProcessHeap(),
325 HEAP_ZERO_MEMORY
, sizeof(IEnumDMOImpl
));
330 lpedmo
->lpVtbl
= &edmovt
;
332 lpedmo
->guidCategory
= guidCategory
;
333 lpedmo
->dwFlags
= dwFlags
;
335 size
= cInTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
336 lpedmo
->pInTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
337 if (!lpedmo
->pInTypes
)
339 memcpy(lpedmo
->pInTypes
, pInTypes
, size
);
340 lpedmo
->cInTypes
= cInTypes
;
342 size
= cOutTypes
* sizeof(DMO_PARTIAL_MEDIATYPE
);
343 lpedmo
->pOutTypes
= HeapAlloc(GetProcessHeap(), 0, size
);
344 if (!lpedmo
->pOutTypes
)
346 memcpy(lpedmo
->pOutTypes
, pOutTypes
, size
);
347 lpedmo
->cOutTypes
= cOutTypes
;
349 /* If not filtering by category enum from media objects root */
350 if (IsEqualGUID(guidCategory
, &GUID_NULL
))
352 if (ERROR_SUCCESS
== RegOpenKeyExW(HKEY_CLASSES_ROOT
, szDMORootKey
,
353 0, KEY_READ
, &lpedmo
->hkey
))
359 WCHAR szKey
[MAX_PATH
];
361 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szDMOCategories
,
362 GUIDToString(szguid
, guidCategory
));
363 if (ERROR_SUCCESS
== RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
,
364 0, KEY_READ
, &lpedmo
->hkey
))
371 IEnumDMO_Destructor((IEnumDMO
*)lpedmo
);
372 HeapFree(GetProcessHeap(),0,lpedmo
);
377 TRACE("returning %p\n", lpedmo
);
379 return (IEnumDMO
*)lpedmo
;
383 /******************************************************************************
386 static ULONG WINAPI
IEnumDMO_fnAddRef(IEnumDMO
* iface
)
388 ICOM_THIS(IEnumDMOImpl
,iface
);
389 return ++(This
->ref
);
393 /**************************************************************************
394 * EnumDMO_QueryInterface
396 static HRESULT WINAPI
IEnumDMO_fnQueryInterface(
401 ICOM_THIS(IEnumDMOImpl
,iface
);
405 if(IsEqualIID(riid
, &IID_IUnknown
))
407 else if(IsEqualIID(riid
, &IID_IEnumDMO
))
408 *ppvObj
= (IEnumDMO
*)This
;
412 IEnumDMO_fnAddRef((IEnumDMO
*)*ppvObj
);
416 return E_NOINTERFACE
;
420 /******************************************************************************
423 static ULONG WINAPI
IEnumDMO_fnRelease(IEnumDMO
* iface
)
425 ICOM_THIS(IEnumDMOImpl
,iface
);
429 IEnumDMO_Destructor((IEnumDMO
*)This
);
430 HeapFree(GetProcessHeap(),0,This
);
438 /******************************************************************************
441 static HRESULT WINAPI
IEnumDMO_fnNext(
446 DWORD
* pcItemsFetched
)
450 WCHAR szNextKey
[MAX_PATH
];
451 WCHAR szKey
[MAX_PATH
];
452 WCHAR szValue
[MAX_PATH
];
457 ICOM_THIS(IEnumDMOImpl
,iface
);
459 TRACE("%ld\n", cItemsToFetch
);
461 if (!pCLSID
|| !Names
|| !pcItemsFetched
)
464 while (count
< (INT
)cItemsToFetch
)
468 hres
= RegEnumKeyExW(This
->hkey
, This
->index
, szNextKey
, &len
, NULL
, NULL
, NULL
, &ft
);
469 if (hres
!= ERROR_SUCCESS
)
472 TRACE("found %s\n", debugstr_w(szNextKey
));
474 if (This
->dwFlags
& DMO_REGISTERF_IS_KEYED
)
476 wsprintfW(szKey
, szCat3Fmt
, szDMORootKey
, szNextKey
, szDMOKeyed
);
477 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
478 if (ERROR_SUCCESS
!= hres
)
483 wsprintfW(szKey
, szCat2Fmt
, szDMORootKey
, szNextKey
);
484 hres
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, szKey
, 0, KEY_READ
, &hkey
);
490 DMO_PARTIAL_MEDIATYPE
* pInTypes
;
492 len
= MAX_PATH
* sizeof(WCHAR
);
493 hres
= RegQueryValueExW(hkey
, szDMOInputType
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
494 if (ERROR_SUCCESS
!= hres
)
500 cInTypes
= len
/ sizeof(DMO_PARTIAL_MEDIATYPE
);
501 pInTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
503 for (i
= 0; i
< This
->cInTypes
; i
++)
505 for (j
= 0; j
< cInTypes
; j
++)
507 if (IsMediaTypeEqual(&pInTypes
[j
], &This
->pInTypes
[i
]))
515 if (i
< This
->cInTypes
)
526 DMO_PARTIAL_MEDIATYPE
* pOutTypes
;
528 len
= MAX_PATH
* sizeof(WCHAR
);
529 hres
= RegQueryValueExW(hkey
, szDMOOutputType
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
530 if (ERROR_SUCCESS
!= hres
)
536 cOutTypes
= len
/ sizeof(DMO_PARTIAL_MEDIATYPE
);
537 pOutTypes
= (DMO_PARTIAL_MEDIATYPE
*) szValue
;
539 for (i
= 0; i
< This
->cOutTypes
; i
++)
541 for (j
= 0; j
< cOutTypes
; j
++)
543 if (IsMediaTypeEqual(&pOutTypes
[j
], &This
->pOutTypes
[i
]))
551 if (i
< This
->cOutTypes
)
558 /* Media object wasn't filtered so add it to return list */
560 len
= MAX_PATH
* sizeof(WCHAR
);
561 hres
= RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, (LPBYTE
) szValue
, &len
);
562 if (ERROR_SUCCESS
== hres
)
564 Names
[count
] = HeapAlloc(GetProcessHeap(), 0, strlenW(szValue
) + 1);
566 strcmpW(Names
[count
], szValue
);
568 CLSIDFromString(szNextKey
, &pCLSID
[count
]);
570 TRACE("found match %s %s\n", debugstr_w(szValue
), debugstr_w(szNextKey
));
575 *pcItemsFetched
= count
;
576 if (*pcItemsFetched
< cItemsToFetch
)
583 /******************************************************************************
586 static HRESULT WINAPI
IEnumDMO_fnSkip(IEnumDMO
* iface
, DWORD cItemsToSkip
)
588 ICOM_THIS(IEnumDMOImpl
,iface
);
590 This
->index
+= cItemsToSkip
;
596 /******************************************************************************
599 static HRESULT WINAPI
IEnumDMO_fnReset(IEnumDMO
* iface
)
601 ICOM_THIS(IEnumDMOImpl
,iface
);
609 /******************************************************************************
612 static HRESULT WINAPI
IEnumDMO_fnClone(IEnumDMO
* iface
, IEnumDMO
**ppEnum
)
614 ICOM_THIS(IEnumDMOImpl
,iface
);
616 FIXME("(%p)->() to (%p)->() E_NOTIMPL\n", This
, ppEnum
);
622 /***************************************************************
625 * Enumerate DirectX Media Objects in the registry.
627 HRESULT WINAPI
DMOEnum(
628 REFGUID guidCategory
,
631 const DMO_PARTIAL_MEDIATYPE
*pInTypes
,
633 const DMO_PARTIAL_MEDIATYPE
*pOutTypes
,
636 HRESULT hres
= E_FAIL
;
638 TRACE("guidCategory=%p dwFlags=0x%08lx cInTypes=%ld cOutTypes=%ld\n",
639 guidCategory
, dwFlags
, cInTypes
, cOutTypes
);
641 *ppEnum
= IEnumDMO_Constructor(guidCategory
, dwFlags
, cInTypes
,
642 pInTypes
, cOutTypes
, pOutTypes
);
650 static ICOM_VTABLE (IEnumDMO
) edmovt
=
652 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
653 IEnumDMO_fnQueryInterface
,
663 HRESULT WINAPI
DMOGetTypes(REFCLSID a
, unsigned long b
, unsigned long* c
,
664 DMO_PARTIAL_MEDIATYPE
* d
, unsigned long e
,
665 unsigned long* f
, DMO_PARTIAL_MEDIATYPE
* g
)
667 FIXME("(%p,%lu,%p,%p,%lu,%p,%p),stub!\n",a
,b
,c
,d
,e
,f
,g
);