https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c1585bb868c74c267d9a6…
commit c1585bb868c74c267d9a66e0ca8daedc51f7b772
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Sun Oct 20 18:56:05 2019 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Sun Oct 20 18:56:05 2019 +0100
[DEVENUM] Sync with Wine Staging 4.18. CORE-16441
---
dll/directx/wine/devenum/CMakeLists.txt | 6 +-
dll/directx/wine/devenum/createdevenum.c | 568 ++++++++-------------
dll/directx/wine/devenum/devenum_main.c | 112 +++-
dll/directx/wine/devenum/devenum_private.h | 28 +-
dll/directx/wine/devenum/factory.c | 134 -----
dll/directx/wine/devenum/mediacatenum.c | 171 +++++--
dll/directx/wine/devenum/parsedisplayname.c | 56 +-
media/doc/README.WINE | 2 +-
sdk/include/reactos/wine/CMakeLists.txt | 2 +-
.../include/reactos/wine}/fil_data.idl | 19 +-
10 files changed, 484 insertions(+), 614 deletions(-)
diff --git a/dll/directx/wine/devenum/CMakeLists.txt
b/dll/directx/wine/devenum/CMakeLists.txt
index 671921748a7..d147a1b006a 100644
--- a/dll/directx/wine/devenum/CMakeLists.txt
+++ b/dll/directx/wine/devenum/CMakeLists.txt
@@ -4,13 +4,11 @@ add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600)
add_definitions(-D__WINESRC__)
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
-add_idl_headers(devenum_fil_data_header fil_data.idl)
spec2def(devenum.dll devenum.spec)
list(APPEND SOURCE
createdevenum.c
devenum_main.c
- factory.c
mediacatenum.c
parsedisplayname.c
precomp.h)
@@ -24,7 +22,7 @@ set_source_files_properties(devenum.rc PROPERTIES OBJECT_DEPENDS
${CMAKE_CURRENT
set_module_type(devenum win32dll UNICODE)
target_link_libraries(devenum strmiids uuid wine)
add_delay_importlibs(devenum msvfw32)
-add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32
msacm32 dsound msvcrt kernel32 ntdll)
-add_dependencies(devenum devenum_fil_data_header)
+add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32
msacm32 dsound msdmo msvcrt kernel32 ntdll)
+add_dependencies(devenum wineheaders)
add_pch(devenum precomp.h SOURCE)
add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all)
diff --git a/dll/directx/wine/devenum/createdevenum.c
b/dll/directx/wine/devenum/createdevenum.c
index 1f0005049bd..be6a814fc7d 100644
--- a/dll/directx/wine/devenum/createdevenum.c
+++ b/dll/directx/wine/devenum/createdevenum.c
@@ -32,17 +32,14 @@
#include "dsound.h"
#include "wine/debug.h"
-#include "wine/unicode.h"
#include "wine/heap.h"
#include "mmddk.h"
#include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
-extern HINSTANCE DEVENUM_hInstance;
-
static const WCHAR wszFilterKeyName[] =
{'F','i','l','t','e','r',0};
static const WCHAR wszMeritName[] =
{'M','e','r','i','t',0};
static const WCHAR wszPins[] = {'P','i','n','s',0};
@@ -55,7 +52,6 @@ static const WCHAR wszFriendlyName[] =
{'F','r','i','e','n','d','l','y','N','a',
static const WCHAR wszFilterData[] =
{'F','i','l','t','e','r','D','a','t','a',0};
static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface);
-static HRESULT register_codecs(void);
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
/**********************************************************************
@@ -106,11 +102,16 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum *
iface)
return 1; /* non-heap based object */
}
-static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **ret)
+static HRESULT register_codec(const GUID *class, const WCHAR *name,
+ const GUID *clsid, const WCHAR *friendly_name, IPropertyBag **ret)
{
static const WCHAR deviceW[] =
{'@','d','e','v','i','c','e',':','c','m',':',0};
+ WCHAR guidstr[CHARS_IN_GUID];
IParseDisplayName *parser;
+ IPropertyBag *propbag;
+ IMoniker *mon;
WCHAR *buffer;
+ VARIANT var;
ULONG eaten;
HRESULT hr;
@@ -118,22 +119,48 @@ static HRESULT register_codec(const CLSID *class, const WCHAR *name,
IMoniker **
if (FAILED(hr))
return hr;
- buffer = heap_alloc((strlenW(deviceW) + CHARS_IN_GUID + strlenW(name) + 1) *
sizeof(WCHAR));
+ buffer = heap_alloc((lstrlenW(deviceW) + CHARS_IN_GUID + lstrlenW(name) + 1) *
sizeof(WCHAR));
if (!buffer)
{
IParseDisplayName_Release(parser);
return E_OUTOFMEMORY;
}
- strcpyW(buffer, deviceW);
- StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
- strcatW(buffer, backslashW);
- strcatW(buffer, name);
+ lstrcpyW(buffer, deviceW);
+ StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+ lstrcatW(buffer, backslashW);
+ lstrcatW(buffer, name);
- hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, ret);
+ IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
IParseDisplayName_Release(parser);
heap_free(buffer);
- return hr;
+
+ IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void
**)&propbag);
+ IMoniker_Release(mon);
+
+ V_VT(&var) = VT_BSTR;
+ V_BSTR(&var) = SysAllocString(friendly_name);
+ hr = IPropertyBag_Write(propbag, wszFriendlyName, &var);
+ VariantClear(&var);
+ if (FAILED(hr))
+ {
+ IPropertyBag_Release(propbag);
+ return hr;
+ }
+
+ V_VT(&var) = VT_BSTR;
+ StringFromGUID2(clsid, guidstr, ARRAY_SIZE(guidstr));
+ V_BSTR(&var) = SysAllocString(guidstr);
+ hr = IPropertyBag_Write(propbag, clsidW, &var);
+ VariantClear(&var);
+ if (FAILED(hr))
+ {
+ IPropertyBag_Release(propbag);
+ return hr;
+ }
+
+ *ret = propbag;
+ return S_OK;
}
static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
@@ -157,7 +184,7 @@ static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2
*rgPin)
{
HKEY hkeyMajorType = NULL;
WCHAR wszMajorTypeName[64];
- DWORD cName = sizeof(wszMajorTypeName) / sizeof(WCHAR);
+ DWORD cName = ARRAY_SIZE(wszMajorTypeName);
DWORD dwMinorTypes, i1;
if (RegEnumKeyExW(hkeyTypes, i, wszMajorTypeName, &cName, NULL, NULL, NULL,
NULL) != ERROR_SUCCESS) continue;
@@ -177,7 +204,7 @@ static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2
*rgPin)
CLSID *clsMajorType = NULL, *clsMinorType = NULL;
HRESULT hr;
- cName = sizeof(wszMinorTypeName) / sizeof(WCHAR);
+ cName = ARRAY_SIZE(wszMinorTypeName);
if (RegEnumKeyExW(hkeyMajorType, i1, wszMinorTypeName, &cName, NULL,
NULL, NULL, NULL) != ERROR_SUCCESS) continue;
clsMinorType = CoTaskMemAlloc(sizeof(CLSID));
@@ -263,7 +290,7 @@ static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2)
{
HKEY hkeyPinKey = NULL;
WCHAR wszPinName[MAX_PATH];
- DWORD cName = sizeof(wszPinName) / sizeof(WCHAR);
+ DWORD cName = ARRAY_SIZE(wszPinName);
REGFILTERPINS2 *rgPin = &rgPins[rgf2->u.s2.cPins2];
DWORD value, size, Type;
LONG lRet;
@@ -352,9 +379,9 @@ static void free_regfilter2(REGFILTER2 *rgf)
static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
{
+ BYTE *data = NULL, *array;
IAMFilterData *fildata;
SAFEARRAYBOUND sabound;
- BYTE *data, *array;
VARIANT var;
ULONG size;
HRESULT hr;
@@ -410,59 +437,53 @@ static void register_legacy_filters(void)
for (i = 0; i < dwFilterSubkeys; i++)
{
WCHAR wszFilterSubkeyName[64];
- DWORD cName = sizeof(wszFilterSubkeyName) / sizeof(WCHAR);
+ DWORD cName = ARRAY_SIZE(wszFilterSubkeyName);
IPropertyBag *prop_bag = NULL;
WCHAR wszRegKey[MAX_PATH];
HKEY classkey = NULL;
- IMoniker *mon = NULL;
- VARIANT var;
REGFILTER2 rgf2;
DWORD Type, len;
+ GUID clsid;
if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL,
NULL, NULL) != ERROR_SUCCESS) continue;
TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
- strcpyW(wszRegKey, clsidW);
- strcatW(wszRegKey, wszFilterSubkeyName);
-
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey)
!= ERROR_SUCCESS)
+ hr = CLSIDFromString(wszFilterSubkeyName, &clsid);
+ if (FAILED(hr))
continue;
- hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
&mon);
- if (FAILED(hr)) goto cleanup;
+ lstrcpyW(wszRegKey, clsidW);
+ lstrcatW(wszRegKey, backslashW);
+ lstrcatW(wszRegKey, wszFilterSubkeyName);
- hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void
**)&prop_bag);
- if (FAILED(hr)) goto cleanup;
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey)
!= ERROR_SUCCESS)
+ continue;
- /* write friendly name */
len = 0;
- V_VT(&var) = VT_BSTR;
if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len))
{
WCHAR *friendlyname = heap_alloc(len);
if (!friendlyname)
- goto cleanup;
+ {
+ RegCloseKey(classkey);
+ continue;
+ }
RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname,
&len);
- V_BSTR(&var) = SysAllocStringLen(friendlyname, len/sizeof(WCHAR));
+
+ hr = register_codec(&CLSID_LegacyAmFilterCategory,
wszFilterSubkeyName,
+ &clsid, friendlyname, &prop_bag);
+
heap_free(friendlyname);
}
else
- V_BSTR(&var) = SysAllocString(wszFilterSubkeyName);
-
- if (!V_BSTR(&var))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
-
- /* write clsid */
- V_VT(&var) = VT_BSTR;
- if (!(V_BSTR(&var) = SysAllocString(wszFilterSubkeyName)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
+ hr = register_codec(&CLSID_LegacyAmFilterCategory,
wszFilterSubkeyName,
+ &clsid, wszFilterSubkeyName, &prop_bag);
+ if (FAILED(hr))
+ {
+ RegCloseKey(classkey);
+ continue;
+ }
/* write filter data */
rgf2.dwMerit = MERIT_NORMAL;
@@ -474,11 +495,8 @@ static void register_legacy_filters(void)
write_filter_data(prop_bag, &rgf2);
-cleanup:
- if (prop_bag) IPropertyBag_Release(prop_bag);
- if (mon) IMoniker_Release(mon);
+ IPropertyBag_Release(prop_bag);
RegCloseKey(classkey);
- VariantClear(&var);
free_regfilter2(&rgf2);
}
}
@@ -496,50 +514,30 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR
*desc, cons
REGPINTYPES rgtypes = {0};
REGFILTER2 rgf = {0};
WCHAR clsid[CHARS_IN_GUID];
- IMoniker *mon = NULL;
VARIANT var;
HRESULT hr;
hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
- if (FAILED(hr)) goto cleanup;
+ if (FAILED(hr))
+ return FALSE;
- V_VT(&var) = VT_BSTR;
if (guid)
{
- WCHAR *name = heap_alloc(sizeof(defaultW) + strlenW(desc) * sizeof(WCHAR));
+ WCHAR *name = heap_alloc(sizeof(defaultW) + lstrlenW(desc) * sizeof(WCHAR));
if (!name)
- goto cleanup;
- strcpyW(name, directsoundW);
- strcatW(name, desc);
+ return FALSE;
+ lstrcpyW(name, directsoundW);
+ lstrcatW(name, desc);
- V_BSTR(&var) = SysAllocString(name);
+ hr = register_codec(&CLSID_AudioRendererCategory, name,
+ &CLSID_DSoundRender, name, &prop_bag);
heap_free(name);
}
else
- V_BSTR(&var) = SysAllocString(defaultW);
-
- if (!V_BSTR(&var))
- goto cleanup;
-
- hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon);
- if (FAILED(hr)) goto cleanup;
-
- hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void
**)&prop_bag);
- if (FAILED(hr)) goto cleanup;
-
- /* write friendly name */
- hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
-
- /* write clsid */
- V_VT(&var) = VT_BSTR;
- StringFromGUID2(&CLSID_DSoundRender, clsid, CHARS_IN_GUID);
- if (!(V_BSTR(&var) = SysAllocString(clsid)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
+ hr = register_codec(&CLSID_AudioRendererCategory, defaultW,
+ &CLSID_DSoundRender, defaultW, &prop_bag);
+ if (FAILED(hr))
+ return FALSE;
/* write filter data */
rgf.dwVersion = 2;
@@ -558,16 +556,11 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR
*desc, cons
/* write DSound guid */
V_VT(&var) = VT_BSTR;
StringFromGUID2(guid ? guid : &GUID_NULL, clsid, CHARS_IN_GUID);
- if (!(V_BSTR(&var) = SysAllocString(clsid)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
- if (FAILED(hr)) goto cleanup;
+ if ((V_BSTR(&var) = SysAllocString(clsid)))
+ hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
-cleanup:
VariantClear(&var);
- if (prop_bag) IPropertyBag_Release(prop_bag);
- if (mon) IMoniker_Release(mon);
-
+ IPropertyBag_Release(prop_bag);
return TRUE;
}
@@ -579,9 +572,8 @@ static void register_waveout_devices(void)
REGFILTERPINS2 rgpins = {0};
REGPINTYPES rgtypes = {0};
REGFILTER2 rgf = {0};
- WCHAR clsid[CHARS_IN_GUID];
- IMoniker *mon = NULL;
WAVEOUTCAPSW caps;
+ const WCHAR *name;
int i, count;
VARIANT var;
HRESULT hr;
@@ -595,34 +587,12 @@ static void register_waveout_devices(void)
{
waveOutGetDevCapsW(i, &caps, sizeof(caps));
- V_VT(&var) = VT_BSTR;
-
- if (i == -1) /* WAVE_MAPPER */
- V_BSTR(&var) = SysAllocString(defaultW);
- else
- V_BSTR(&var) = SysAllocString(caps.szPname);
- if (!(V_BSTR(&var)))
- goto cleanup;
+ name = (i == -1) ? defaultW : caps.szPname;
- hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var),
&mon);
- if (FAILED(hr)) goto cleanup;
-
- hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void
**)&prop_bag);
- if (FAILED(hr)) goto cleanup;
-
- /* write friendly name */
- hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
-
- /* write clsid */
- V_VT(&var) = VT_BSTR;
- StringFromGUID2(&CLSID_AudioRender, clsid, CHARS_IN_GUID);
- if (!(V_BSTR(&var) = SysAllocString(clsid)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
+ hr = register_codec(&CLSID_AudioRendererCategory, name,
+ &CLSID_AudioRender, name, &prop_bag);
+ if (FAILED(hr))
+ continue;
/* write filter data */
rgf.dwVersion = 2;
@@ -640,13 +610,10 @@ static void register_waveout_devices(void)
/* write WaveOutId */
V_VT(&var) = VT_I4;
V_I4(&var) = i;
- hr = IPropertyBag_Write(prop_bag, waveoutidW, &var);
- if (FAILED(hr)) goto cleanup;
+ IPropertyBag_Write(prop_bag, waveoutidW, &var);
-cleanup:
VariantClear(&var);
if (prop_bag) IPropertyBag_Release(prop_bag);
- if (mon) IMoniker_Release(mon);
}
}
@@ -655,8 +622,6 @@ static void register_wavein_devices(void)
static const WCHAR waveinidW[] =
{'W','a','v','e','I','n','I','d',0};
IPropertyBag *prop_bag = NULL;
REGFILTER2 rgf = {0};
- WCHAR clsid[CHARS_IN_GUID];
- IMoniker *mon = NULL;
WAVEINCAPSW caps;
int i, count;
VARIANT var;
@@ -671,31 +636,10 @@ static void register_wavein_devices(void)
{
waveInGetDevCapsW(i, &caps, sizeof(caps));
- V_VT(&var) = VT_BSTR;
-
- V_BSTR(&var) = SysAllocString(caps.szPname);
- if (!(V_BSTR(&var)))
- goto cleanup;
-
- hr = register_codec(&CLSID_AudioInputDeviceCategory, V_BSTR(&var),
&mon);
- if (FAILED(hr)) goto cleanup;
-
- hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void
**)&prop_bag);
- if (FAILED(hr)) goto cleanup;
-
- /* write friendly name */
- hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
-
- /* write clsid */
- V_VT(&var) = VT_BSTR;
- StringFromGUID2(&CLSID_AudioRecord, clsid, CHARS_IN_GUID);
- if (!(V_BSTR(&var) = SysAllocString(clsid)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
+ hr = register_codec(&CLSID_AudioInputDeviceCategory, caps.szPname,
+ &CLSID_AudioRecord, caps.szPname, &prop_bag);
+ if (FAILED(hr))
+ continue;
/* write filter data */
rgf.dwVersion = 2;
@@ -706,13 +650,10 @@ static void register_wavein_devices(void)
/* write WaveInId */
V_VT(&var) = VT_I4;
V_I4(&var) = i;
- hr = IPropertyBag_Write(prop_bag, waveinidW, &var);
- if (FAILED(hr)) goto cleanup;
+ IPropertyBag_Write(prop_bag, waveinidW, &var);
-cleanup:
VariantClear(&var);
- if (prop_bag) IPropertyBag_Release(prop_bag);
- if (mon) IMoniker_Release(mon);
+ IPropertyBag_Release(prop_bag);
}
}
@@ -724,9 +665,8 @@ static void register_midiout_devices(void)
REGFILTERPINS2 rgpins = {0};
REGPINTYPES rgtypes = {0};
REGFILTER2 rgf = {0};
- WCHAR clsid[CHARS_IN_GUID];
- IMoniker *mon = NULL;
MIDIOUTCAPSW caps;
+ const WCHAR *name;
int i, count;
VARIANT var;
HRESULT hr;
@@ -740,34 +680,12 @@ static void register_midiout_devices(void)
{
midiOutGetDevCapsW(i, &caps, sizeof(caps));
- V_VT(&var) = VT_BSTR;
-
- if (i == -1) /* MIDI_MAPPER */
- V_BSTR(&var) = SysAllocString(defaultW);
- else
- V_BSTR(&var) = SysAllocString(caps.szPname);
- if (!(V_BSTR(&var)))
- goto cleanup;
+ name = (i == -1) ? defaultW : caps.szPname;
- hr = register_codec(&CLSID_MidiRendererCategory, V_BSTR(&var),
&mon);
- if (FAILED(hr)) goto cleanup;
-
- hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void
**)&prop_bag);
- if (FAILED(hr)) goto cleanup;
-
- /* write friendly name */
- hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
-
- /* write clsid */
- V_VT(&var) = VT_BSTR;
- StringFromGUID2(&CLSID_AVIMIDIRender, clsid, CHARS_IN_GUID);
- if (!(V_BSTR(&var) = SysAllocString(clsid)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
+ hr = register_codec(&CLSID_MidiRendererCategory, name,
+ &CLSID_AVIMIDIRender, name, &prop_bag);
+ if (FAILED(hr))
+ continue;
/* write filter data */
rgf.dwVersion = 2;
@@ -785,13 +703,10 @@ static void register_midiout_devices(void)
/* write MidiOutId */
V_VT(&var) = VT_I4;
V_I4(&var) = i;
- hr = IPropertyBag_Write(prop_bag, midioutidW, &var);
- if (FAILED(hr)) goto cleanup;
+ IPropertyBag_Write(prop_bag, midioutidW, &var);
-cleanup:
VariantClear(&var);
- if (prop_bag) IPropertyBag_Release(prop_bag);
- if (mon) IMoniker_Release(mon);
+ IPropertyBag_Release(prop_bag);
}
}
@@ -802,8 +717,6 @@ static void register_vfw_codecs(void)
IPropertyBag *prop_bag = NULL;
REGPINTYPES rgtypes[2];
REGFILTER2 rgf;
- WCHAR clsid[CHARS_IN_GUID];
- IMoniker *mon = NULL;
GUID typeguid;
ICINFO info;
VARIANT var;
@@ -823,40 +736,10 @@ static void register_vfw_codecs(void)
ICGetInfo(hic, &info, sizeof(info));
ICClose(hic);
- V_VT(&var) = VT_BSTR;
-
- V_BSTR(&var) = SysAllocString(name);
- if (!(V_BSTR(&var)))
- goto cleanup;
-
- hr = register_codec(&CLSID_VideoCompressorCategory, V_BSTR(&var),
&mon);
- if (FAILED(hr)) goto cleanup;
-
- hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void
**)&prop_bag);
- if (FAILED(hr)) goto cleanup;
-
- /* write WaveInId */
- hr = IPropertyBag_Write(prop_bag, fcchandlerW, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
-
- /* write friendly name */
- V_VT(&var) = VT_BSTR;
- if (!(V_BSTR(&var) = SysAllocString(info.szDescription)))
- goto cleanup;
-
- hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
-
- /* write clsid */
- V_VT(&var) = VT_BSTR;
- StringFromGUID2(&CLSID_AVICo, clsid, CHARS_IN_GUID);
- if (!(V_BSTR(&var) = SysAllocString(clsid)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
- if (FAILED(hr)) goto cleanup;
- VariantClear(&var);
+ hr = register_codec(&CLSID_VideoCompressorCategory, name,
+ &CLSID_AVICo, info.szDescription, &prop_bag);
+ if (FAILED(hr))
+ continue;
/* write filter data */
rgf.dwVersion = 2;
@@ -878,10 +761,65 @@ static void register_vfw_codecs(void)
write_filter_data(prop_bag, &rgf);
-cleanup:
+ /* write WaveInId */
+ V_VT(&var) = VT_BSTR;
+ V_BSTR(&var) = SysAllocString(name);
+ IPropertyBag_Write(prop_bag, fcchandlerW, &var);
+
VariantClear(&var);
- if (prop_bag) IPropertyBag_Release(prop_bag);
- if (mon) IMoniker_Release(mon);
+ IPropertyBag_Release(prop_bag);
+ }
+}
+
+static void register_avicap_devices(void)
+{
+ static const WCHAR vfwindexW[] =
{'V','F','W','I','n','d','e','x',0};
+ WCHAR name[] =
{'v','i','d','e','o','0',0};
+ WCHAR friendlyname[32], version[32];
+ IPropertyBag *prop_bag = NULL;
+ REGFILTERPINS2 rgpins = {0};
+ REGPINTYPES rgtypes;
+ REGFILTER2 rgf;
+ VARIANT var;
+ HRESULT hr;
+ int i = 0;
+
+ hr = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
+ if (FAILED(hr))
+ return;
+
+ for (i = 0; i < 10; ++i)
+ {
+ if (!capGetDriverDescriptionW(i, friendlyname, ARRAY_SIZE(friendlyname),
+ version, ARRAY_SIZE(version)))
+ continue;
+
+ name[5] = '0' + i;
+
+ hr = register_codec(&CLSID_VideoInputDeviceCategory, name,
+ &CLSID_VfwCapture, friendlyname, &prop_bag);
+ if (FAILED(hr))
+ continue;
+
+ rgf.dwVersion = 2;
+ rgf.dwMerit = MERIT_DO_NOT_USE;
+ rgf.u.s2.cPins2 = 1;
+ rgf.u.s2.rgPins2 = &rgpins;
+ rgpins.dwFlags = 0;
+ rgpins.nMediaTypes = 1;
+ rgpins.lpMediaType = &rgtypes;
+ rgtypes.clsMajorType = &MEDIATYPE_Video;
+ rgtypes.clsMinorType = &MEDIASUBTYPE_None;
+
+ write_filter_data(prop_bag, &rgf);
+
+ /* write VFWIndex */
+ V_VT(&var) = VT_I4;
+ V_I4(&var) = i;
+ IPropertyBag_Write(prop_bag, vfwindexW, &var);
+
+ VariantClear(&var);
+ IPropertyBag_Release(prop_bag);
}
}
@@ -889,30 +827,58 @@ cleanup:
* DEVENUM_ICreateDevEnum_CreateClassEnumerator
*/
static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
- ICreateDevEnum * iface,
- REFCLSID clsidDeviceClass,
- IEnumMoniker **ppEnumMoniker,
- DWORD dwFlags)
+ ICreateDevEnum *iface, REFCLSID class, IEnumMoniker **out, DWORD flags)
{
+ WCHAR guidstr[CHARS_IN_GUID];
HRESULT hr;
+ HKEY key;
- TRACE("(%p)->(%s, %p, %x)\n", iface, debugstr_guid(clsidDeviceClass),
ppEnumMoniker, dwFlags);
+ TRACE("iface %p, class %s, out %p, flags %#x.\n", iface,
debugstr_guid(class), out, flags);
- if (!ppEnumMoniker)
+ if (!out)
return E_POINTER;
- *ppEnumMoniker = NULL;
+ *out = NULL;
- register_codecs();
- register_legacy_filters();
- hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL);
- if (FAILED(hr)) return hr;
- register_waveout_devices();
- register_wavein_devices();
- register_midiout_devices();
- register_vfw_codecs();
+ if (!RegOpenKeyW(HKEY_CURRENT_USER, wszActiveMovieKey, &key))
+ {
+ StringFromGUID2(class, guidstr, ARRAY_SIZE(guidstr));
+ RegDeleteTreeW(key, guidstr);
+ }
- return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker);
+ if (IsEqualGUID(class, &CLSID_LegacyAmFilterCategory))
+ register_legacy_filters();
+ else if (IsEqualGUID(class, &CLSID_AudioRendererCategory))
+ {
+ hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL);
+ if (FAILED(hr)) return hr;
+ register_waveout_devices();
+ register_midiout_devices();
+ }
+ else if (IsEqualGUID(class, &CLSID_AudioInputDeviceCategory))
+ register_wavein_devices();
+ else if (IsEqualGUID(class, &CLSID_VideoCompressorCategory))
+ register_vfw_codecs();
+ else if (IsEqualGUID(class, &CLSID_VideoInputDeviceCategory))
+ register_avicap_devices();
+
+ if (SUCCEEDED(hr = create_EnumMoniker(class, out)))
+ {
+ IMoniker *mon;
+ hr = IEnumMoniker_Next(*out, 1, &mon, NULL);
+ if (hr == S_OK)
+ {
+ IMoniker_Release(mon);
+ IEnumMoniker_Reset(*out);
+ }
+ else
+ {
+ IEnumMoniker_Release(*out);
+ *out = NULL;
+ }
+ }
+
+ return hr;
}
/**********************************************************************
@@ -943,9 +909,9 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID *
clsidCategory)
HRESULT res = S_OK;
HKEY hkeyDummy = NULL;
- strcpyW(wszRegKey, wszActiveMovieKey);
+ lstrcpyW(wszRegKey, wszActiveMovieKey);
- if (!StringFromGUID2(clsidCategory, wszRegKey + strlenW(wszRegKey),
sizeof(wszRegKey)/sizeof(wszRegKey[0]) - strlenW(wszRegKey)))
+ if (!StringFromGUID2(clsidCategory, wszRegKey + lstrlenW(wszRegKey),
ARRAY_SIZE(wszRegKey) - lstrlenW(wszRegKey)))
res = E_INVALIDARG;
if (SUCCEEDED(res))
@@ -962,111 +928,3 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID *
clsidCategory)
return res;
}
-
-static HRESULT register_codecs(void)
-{
- HRESULT res;
- WCHAR class[CHARS_IN_GUID];
- DWORD iDefaultDevice = -1;
- IFilterMapper2 * pMapper = NULL;
- REGFILTER2 rf2;
- REGFILTERPINS2 rfp2;
- HKEY basekey;
-
- /* Since devices can change between session, for example because you just plugged in
a webcam
- * or switched from pulseaudio to alsa, delete all old devices first
- */
- RegOpenKeyW(HKEY_CURRENT_USER, wszActiveMovieKey, &basekey);
- StringFromGUID2(&CLSID_LegacyAmFilterCategory, class, CHARS_IN_GUID);
- RegDeleteTreeW(basekey, class);
- StringFromGUID2(&CLSID_AudioRendererCategory, class, CHARS_IN_GUID);
- RegDeleteTreeW(basekey, class);
- StringFromGUID2(&CLSID_AudioInputDeviceCategory, class, CHARS_IN_GUID);
- RegDeleteTreeW(basekey, class);
- StringFromGUID2(&CLSID_VideoInputDeviceCategory, class, CHARS_IN_GUID);
- RegDeleteTreeW(basekey, class);
- StringFromGUID2(&CLSID_MidiRendererCategory, class, CHARS_IN_GUID);
- RegDeleteTreeW(basekey, class);
- StringFromGUID2(&CLSID_VideoCompressorCategory, class, CHARS_IN_GUID);
- RegDeleteTreeW(basekey, class);
- RegCloseKey(basekey);
-
- rf2.dwVersion = 2;
- rf2.dwMerit = MERIT_PREFERRED;
- rf2.u.s2.cPins2 = 1;
- rf2.u.s2.rgPins2 = &rfp2;
- rfp2.cInstances = 1;
- rfp2.nMediums = 0;
- rfp2.lpMedium = NULL;
- rfp2.clsPinCategory = &IID_NULL;
-
- res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
- &IID_IFilterMapper2, (void **) &pMapper);
- /*
- * Fill in info for devices
- */
- if (SUCCEEDED(res))
- {
- UINT i;
- REGPINTYPES * pTypes;
- IPropertyBag * pPropBag = NULL;
-
- res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
- if (SUCCEEDED(res))
- for (i = 0; i < 10; i++)
- {
- WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10];
-
- if (capGetDriverDescriptionW ((WORD) i,
- szDeviceName,
sizeof(szDeviceName)/sizeof(WCHAR),
- szDeviceVersion,
sizeof(szDeviceVersion)/sizeof(WCHAR)))
- {
- IMoniker * pMoniker = NULL;
- WCHAR dprintf[] = {
'v','i','d','e','o','%','d',0 };
- snprintfW(szDevicePath, sizeof(szDevicePath)/sizeof(WCHAR), dprintf,
i);
- /* The above code prevents 1 device with a different ID overwriting
another */
-
- rfp2.nMediaTypes = 1;
- pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
- if (!pTypes) {
- IFilterMapper2_Release(pMapper);
- return E_OUTOFMEMORY;
- }
-
- pTypes[0].clsMajorType = &MEDIATYPE_Video;
- pTypes[0].clsMinorType = &MEDIASUBTYPE_None;
-
- rfp2.lpMediaType = pTypes;
-
- res = IFilterMapper2_RegisterFilter(pMapper,
- &CLSID_VfwCapture,
- szDeviceName,
- &pMoniker,
-
&CLSID_VideoInputDeviceCategory,
- szDevicePath,
- &rf2);
-
- if (pMoniker) {
- OLECHAR wszVfwIndex[] = {
'V','F','W','I','n','d','e','x',0
};
- VARIANT var;
- V_VT(&var) = VT_I4;
- V_I4(&var) = i;
- res = IMoniker_BindToStorage(pMoniker, NULL, NULL,
&IID_IPropertyBag, (LPVOID)&pPropBag);
- if (SUCCEEDED(res)) {
- res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var);
- IPropertyBag_Release(pPropBag);
- }
- IMoniker_Release(pMoniker);
- }
-
- if (i == iDefaultDevice) FIXME("Default device\n");
- CoTaskMemFree(pTypes);
- }
- }
- }
-
- if (pMapper)
- IFilterMapper2_Release(pMapper);
-
- return res;
-}
diff --git a/dll/directx/wine/devenum/devenum_main.c
b/dll/directx/wine/devenum/devenum_main.c
index 55963581176..3f60c2906f7 100644
--- a/dll/directx/wine/devenum/devenum_main.c
+++ b/dll/directx/wine/devenum/devenum_main.c
@@ -1,5 +1,5 @@
/*
- * exported dll functions for devenum.dll
+ * Device Enumeration
*
* Copyright (C) 2002 John K. Hohm
* Copyright (C) 2002 Robert Shearman
@@ -26,24 +26,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
DECLSPEC_HIDDEN LONG dll_refs;
-DECLSPEC_HIDDEN HINSTANCE DEVENUM_hInstance;
-
-typedef struct
-{
- REFCLSID clsid;
- LPCWSTR friendly_name;
- BOOL instance;
-} register_info;
+static HINSTANCE devenum_instance;
#ifdef __REACTOS__
static void DEVENUM_RegisterQuartz(void);
#endif
-/***********************************************************************
- * Global string constant definitions
- */
-const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I',
'D', 0 };
-
/***********************************************************************
* DllEntryPoint
*/
@@ -53,29 +41,101 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID
fImpLoad)
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
- DEVENUM_hInstance = hinstDLL;
+ devenum_instance = hinstDLL;
DisableThreadLibraryCalls(hinstDLL);
break;
}
return TRUE;
}
+struct class_factory
+{
+ IClassFactory IClassFactory_iface;
+ IUnknown *obj;
+};
+
+static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface )
+{
+ return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface );
+}
+
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void
**obj)
+{
+ TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
+
+ if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
+ {
+ IClassFactory_AddRef(iface);
+ *obj = iface;
+ return S_OK;
+ }
+
+ *obj = NULL;
+ WARN("no interface for %s\n", debugstr_guid(iid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+ DEVENUM_LockModule();
+ return 2;
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+ DEVENUM_UnlockModule();
+ return 1;
+}
+
+static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
+ IUnknown *outer, REFIID iid, void **obj)
+{
+ struct class_factory *This = impl_from_IClassFactory( iface );
+
+ TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
+
+ if (!obj) return E_POINTER;
+
+ if (outer) return CLASS_E_NOAGGREGATION;
+
+ return IUnknown_QueryInterface(This->obj, iid, obj);
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
+{
+ if (lock)
+ DEVENUM_LockModule();
+ else
+ DEVENUM_UnlockModule();
+ return S_OK;
+}
+
+static const IClassFactoryVtbl ClassFactory_vtbl = {
+ ClassFactory_QueryInterface,
+ ClassFactory_AddRef,
+ ClassFactory_Release,
+ ClassFactory_CreateInstance,
+ ClassFactory_LockServer
+};
+
+static struct class_factory create_devenum_cf = { { &ClassFactory_vtbl }, (IUnknown
*)&DEVENUM_CreateDevEnum };
+static struct class_factory device_moniker_cf = { { &ClassFactory_vtbl }, (IUnknown
*)&DEVENUM_ParseDisplayName };
+
/***********************************************************************
* DllGetClassObject (DEVENUM.@)
*/
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj)
{
- TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+ TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
- *ppv = NULL;
+ *obj = NULL;
- /* FIXME: we should really have two class factories.
- * Oh well - works just fine as it is */
- if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
- IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
- return
IClassFactory_QueryInterface(&DEVENUM_ClassFactory.IClassFactory_iface, iid, ppv);
+ if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum))
+ return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface,
iid, obj);
+ else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker))
+ return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface,
iid, obj);
- FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
+ FIXME("class %s not available\n", debugstr_guid(clsid));
return CLASS_E_CLASSNOTAVAILABLE;
}
@@ -98,7 +158,7 @@ HRESULT WINAPI DllRegisterServer(void)
TRACE("\n");
- res = __wine_register_resources( DEVENUM_hInstance );
+ res = __wine_register_resources( devenum_instance );
if (FAILED(res))
return res;
@@ -151,7 +211,7 @@ HRESULT WINAPI DllRegisterServer(void)
HRESULT WINAPI DllUnregisterServer(void)
{
FIXME("stub!\n");
- return __wine_unregister_resources( DEVENUM_hInstance );
+ return __wine_unregister_resources( devenum_instance );
}
#ifdef __REACTOS__
diff --git a/dll/directx/wine/devenum/devenum_private.h
b/dll/directx/wine/devenum/devenum_private.h
index 005f0b56e66..61287ef0e3e 100644
--- a/dll/directx/wine/devenum/devenum_private.h
+++ b/dll/directx/wine/devenum/devenum_private.h
@@ -42,10 +42,6 @@
#include "olectl.h"
#include "uuids.h"
-#ifndef RC_INVOKED
-#include "wine/unicode.h"
-#endif
-
/**********************************************************************
* Dll lifetime tracking declaration for devenum.dll
*/
@@ -53,19 +49,11 @@ extern LONG dll_refs DECLSPEC_HIDDEN;
static inline void DEVENUM_LockModule(void) { InterlockedIncrement(&dll_refs); }
static inline void DEVENUM_UnlockModule(void) { InterlockedDecrement(&dll_refs); }
-
-/**********************************************************************
- * ClassFactory declaration for devenum.dll
- */
-typedef struct
-{
- IClassFactory IClassFactory_iface;
-} ClassFactoryImpl;
-
enum device_type
{
DEVICE_FILTER,
DEVICE_CODEC,
+ DEVICE_DMO,
};
typedef struct
@@ -75,13 +63,16 @@ typedef struct
CLSID class;
BOOL has_class;
enum device_type type;
- WCHAR *name;
+ union
+ {
+ WCHAR *name; /* for filters and codecs */
+ CLSID clsid; /* for DMOs */
+ };
} MediaCatMoniker;
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **enum_mon) DECLSPEC_HIDDEN;
-extern ClassFactoryImpl DEVENUM_ClassFactory DECLSPEC_HIDDEN;
extern ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN;
extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
@@ -90,12 +81,13 @@ extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
*/
static const WCHAR backslashW[] = {'\\',0};
-static const WCHAR clsidW[] =
{'C','L','S','I','D','\\',0};
+static const WCHAR clsidW[] =
{'C','L','S','I','D',0};
static const WCHAR instanceW[] =
{'\\','I','n','s','t','a','n','c','e',0};
static const WCHAR wszActiveMovieKey[] =
{'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'A','c','t','i','v','e','M','o','v','i','e','\\',
'd','e','v','e','n','u','m','\\',0};
static const WCHAR deviceW[] =
{'@','d','e','v','i','c','e',':',0};
-
-extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN;
+static const WCHAR dmoW[] = {'d','m','o',':',0};
+static const WCHAR swW[] = {'s','w',':',0};
+static const WCHAR cmW[] = {'c','m',':',0};
diff --git a/dll/directx/wine/devenum/factory.c b/dll/directx/wine/devenum/factory.c
deleted file mode 100644
index c808fa532df..00000000000
--- a/dll/directx/wine/devenum/factory.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * ClassFactory implementation for DEVENUM.dll
- *
- * Copyright (C) 2002 John K. Hohm
- * Copyright (C) 2002 Robert Shearman
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "devenum_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(devenum);
-
-/**********************************************************************
- * DEVENUM_IClassFactory_QueryInterface (also IUnknown)
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_QueryInterface(IClassFactory *iface, REFIID
riid,
- void **ppvObj)
-{
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj);
-
- if (ppvObj == NULL) return E_POINTER;
-
- if (IsEqualGUID(riid, &IID_IUnknown) ||
- IsEqualGUID(riid, &IID_IClassFactory))
- {
- *ppvObj = iface;
- IClassFactory_AddRef(iface);
- return S_OK;
- }
- else if (IsEqualGUID(riid, &IID_IParseDisplayName))
- {
- return IClassFactory_CreateInstance(iface, NULL, riid, ppvObj);
- }
-
- FIXME("- no interface IID: %s\n", debugstr_guid(riid));
- return E_NOINTERFACE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_AddRef (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_AddRef(IClassFactory *iface)
-{
- TRACE("\n");
-
- DEVENUM_LockModule();
-
- return 2; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_Release (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_Release(IClassFactory *iface)
-{
- TRACE("\n");
-
- DEVENUM_UnlockModule();
-
- return 1; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_CreateInstance
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_CreateInstance(IClassFactory *iface,
- IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
-{
- TRACE("(%p)->(%p, %s, %p)\n", iface, pUnkOuter, debugstr_guid(riid),
ppvObj);
-
- if (ppvObj == NULL) return E_POINTER;
-
- /* Don't support aggregation (Windows doesn't) */
- if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
-
- if (IsEqualGUID(&IID_ICreateDevEnum, riid))
- {
- *ppvObj = &DEVENUM_CreateDevEnum;
- return S_OK;
- }
- if (IsEqualGUID(&IID_IParseDisplayName, riid))
- {
- *ppvObj = &DEVENUM_ParseDisplayName;
- return S_OK;
- }
-
- return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_LockServer
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
-{
- TRACE("\n");
-
- if (fLock)
- DEVENUM_LockModule();
- else
- DEVENUM_UnlockModule();
- return S_OK;
-}
-
-/**********************************************************************
- * IClassFactory_Vtbl
- */
-static const IClassFactoryVtbl IClassFactory_Vtbl =
-{
- DEVENUM_IClassFactory_QueryInterface,
- DEVENUM_IClassFactory_AddRef,
- DEVENUM_IClassFactory_Release,
- DEVENUM_IClassFactory_CreateInstance,
- DEVENUM_IClassFactory_LockServer
-};
-
-/**********************************************************************
- * static ClassFactory instance
- */
-ClassFactoryImpl DEVENUM_ClassFactory = { { &IClassFactory_Vtbl } };
diff --git a/dll/directx/wine/devenum/mediacatenum.c
b/dll/directx/wine/devenum/mediacatenum.c
index a76c7bebfb2..e728be342b1 100644
--- a/dll/directx/wine/devenum/mediacatenum.c
+++ b/dll/directx/wine/devenum/mediacatenum.c
@@ -25,6 +25,7 @@
#include "devenum_private.h"
#include "oleauto.h"
#include "ocidl.h"
+#include "dmoreg.h"
#include "wine/debug.h"
@@ -35,6 +36,7 @@ typedef struct
IEnumMoniker IEnumMoniker_iface;
CLSID class;
LONG ref;
+ IEnumDMO *dmo_enum;
HKEY sw_key;
DWORD sw_index;
HKEY cm_key;
@@ -46,7 +48,11 @@ typedef struct
IPropertyBag IPropertyBag_iface;
LONG ref;
enum device_type type;
- WCHAR path[MAX_PATH];
+ union
+ {
+ WCHAR path[MAX_PATH]; /* for filters and codecs */
+ CLSID clsid; /* for DMOs */
+ };
} RegPropBagImpl;
@@ -114,12 +120,14 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
VARIANT* pVar,
IErrorLog* pErrorLog)
{
+ static const WCHAR FriendlyNameW[] =
{'F','r','i','e','n','d','l','y','N','a','m','e',0};
LPVOID pData = NULL;
DWORD received;
DWORD type = 0;
RegPropBagImpl *This = impl_from_IPropertyBag(iface);
HRESULT res = S_OK;
LONG reswin32 = ERROR_SUCCESS;
+ WCHAR name[80];
HKEY hkey;
TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar,
pErrorLog);
@@ -127,6 +135,21 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
if (!pszPropName || !pVar)
return E_POINTER;
+ if (This->type == DEVICE_DMO)
+ {
+ if (!lstrcmpW(pszPropName, FriendlyNameW))
+ {
+ res = DMOGetName(&This->clsid, name);
+ if (SUCCEEDED(res))
+ {
+ V_VT(pVar) = VT_BSTR;
+ V_BSTR(pVar) = SysAllocString(name);
+ }
+ return res;
+ }
+ return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+ }
+
if (This->type == DEVICE_FILTER)
reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
else if (This->type == DEVICE_CODEC)
@@ -246,6 +269,9 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);
+ if (This->type == DEVICE_DMO)
+ return E_ACCESSDENIED;
+
switch (V_VT(pVar))
{
case VT_BSTR:
@@ -316,18 +342,30 @@ static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag
**ppBag)
rpb->ref = 1;
rpb->type = mon->type;
- if (rpb->type == DEVICE_FILTER)
- strcpyW(rpb->path, clsidW);
+ if (rpb->type == DEVICE_DMO)
+ rpb->clsid = mon->clsid;
+ else if (rpb->type == DEVICE_FILTER)
+ {
+ lstrcpyW(rpb->path, clsidW);
+ lstrcatW(rpb->path, backslashW);
+ if (mon->has_class)
+ {
+ StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path),
CHARS_IN_GUID);
+ lstrcatW(rpb->path, instanceW);
+ lstrcatW(rpb->path, backslashW);
+ }
+ lstrcatW(rpb->path, mon->name);
+ }
else if (rpb->type == DEVICE_CODEC)
- strcpyW(rpb->path, wszActiveMovieKey);
- if (mon->has_class)
{
- StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path),
CHARS_IN_GUID);
- if (rpb->type == DEVICE_FILTER)
- strcatW(rpb->path, instanceW);
- strcatW(rpb->path, backslashW);
+ lstrcpyW(rpb->path, wszActiveMovieKey);
+ if (mon->has_class)
+ {
+ StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path),
CHARS_IN_GUID);
+ lstrcatW(rpb->path, backslashW);
+ }
+ lstrcatW(rpb->path, mon->name);
}
- strcatW(rpb->path, mon->name);
*ppBag = &rpb->IPropertyBag_iface;
DEVENUM_LockModule();
@@ -459,7 +497,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker
*iface, IBi
if (SUCCEEDED(res))
{
V_VT(&var) = VT_LPWSTR;
- res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL);
+ res = IPropertyBag_Read(pProp, clsidW, &var, NULL);
}
if (SUCCEEDED(res))
{
@@ -658,8 +696,6 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker
*iface, I
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, IBindCtx
*pbc,
IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
{
- static const WCHAR swW[] = {'s','w',':',0};
- static const WCHAR cmW[] = {'c','m',':',0};
MediaCatMoniker *This = impl_from_IMoniker(iface);
WCHAR *buffer;
@@ -667,23 +703,36 @@ static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, I
*ppszDisplayName = NULL;
- buffer = CoTaskMemAlloc((strlenW(deviceW) + 4 + (This->has_class ? CHARS_IN_GUID :
0)
- + strlenW(This->name) + 1) * sizeof(WCHAR));
- if (!buffer)
- return E_OUTOFMEMORY;
+ if (This->type == DEVICE_DMO)
+ {
+ buffer = CoTaskMemAlloc((lstrlenW(deviceW) + lstrlenW(dmoW)
+ + 2 * CHARS_IN_GUID + 1) * sizeof(WCHAR));
+ if (!buffer) return E_OUTOFMEMORY;
+
+ lstrcpyW(buffer, deviceW);
+ lstrcatW(buffer, dmoW);
+ StringFromGUID2(&This->clsid, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+ StringFromGUID2(&This->class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+ }
+ else
+ {
+ buffer = CoTaskMemAlloc((lstrlenW(deviceW) + 3 + (This->has_class ?
CHARS_IN_GUID : 0)
+ + lstrlenW(This->name) + 1) * sizeof(WCHAR));
+ if (!buffer) return E_OUTOFMEMORY;
- strcpyW(buffer, deviceW);
- if (This->type == DEVICE_FILTER)
- strcatW(buffer, swW);
- else if (This->type == DEVICE_CODEC)
- strcatW(buffer, cmW);
+ lstrcpyW(buffer, deviceW);
+ if (This->type == DEVICE_FILTER)
+ lstrcatW(buffer, swW);
+ else if (This->type == DEVICE_CODEC)
+ lstrcatW(buffer, cmW);
- if (This->has_class)
- {
- StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID);
- strcatW(buffer, backslashW);
+ if (This->has_class)
+ {
+ StringFromGUID2(&This->class, buffer + lstrlenW(buffer),
CHARS_IN_GUID);
+ lstrcatW(buffer, backslashW);
+ }
+ lstrcatW(buffer, This->name);
}
- strcatW(buffer, This->name);
*ppszDisplayName = buffer;
return S_OK;
@@ -798,6 +847,7 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
if (!ref)
{
+ IEnumDMO_Release(This->dmo_enum);
RegCloseKey(This->sw_key);
RegCloseKey(This->cm_key);
CoTaskMemFree(This);
@@ -815,16 +865,30 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface,
ULONG celt,
LONG res;
ULONG fetched = 0;
MediaCatMoniker * pMoniker;
+ CLSID clsid;
+ HRESULT hr;
HKEY hkey;
TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
while (fetched < celt)
{
- /* FIXME: try PNP devices and DMOs first */
+ /* FIXME: try PNP devices first */
+
+ /* try DMOs */
+ if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, NULL, NULL)) == S_OK)
+ {
+ if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
+ return E_OUTOFMEMORY;
+
+ pMoniker->type = DEVICE_DMO;
+ pMoniker->clsid = clsid;
+ StringFromGUID2(&clsid, buffer, CHARS_IN_GUID);
+ StringFromGUID2(&This->class, buffer + CHARS_IN_GUID - 1,
CHARS_IN_GUID);
+ }
/* try DirectShow filters */
- if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer,
sizeof(buffer)/sizeof(WCHAR))))
+ else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer,
ARRAY_SIZE(buffer))))
{
This->sw_index++;
if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE,
&hkey)))
@@ -834,9 +898,16 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface,
ULONG celt,
return E_OUTOFMEMORY;
pMoniker->type = DEVICE_FILTER;
+
+ if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) *
sizeof(WCHAR))))
+ {
+ IMoniker_Release(&pMoniker->IMoniker_iface);
+ return E_OUTOFMEMORY;
+ }
+ lstrcpyW(pMoniker->name, buffer);
}
/* then try codecs */
- else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer,
sizeof(buffer)/sizeof(WCHAR))))
+ else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer,
ARRAY_SIZE(buffer))))
{
This->cm_index++;
@@ -847,16 +918,17 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface,
ULONG celt,
return E_OUTOFMEMORY;
pMoniker->type = DEVICE_CODEC;
+
+ if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) *
sizeof(WCHAR))))
+ {
+ IMoniker_Release(&pMoniker->IMoniker_iface);
+ return E_OUTOFMEMORY;
+ }
+ lstrcpyW(pMoniker->name, buffer);
}
else
break;
- if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) *
sizeof(WCHAR))))
- {
- IMoniker_Release(&pMoniker->IMoniker_iface);
- return E_OUTOFMEMORY;
- }
- strcpyW(pMoniker->name, buffer);
pMoniker->has_class = TRUE;
pMoniker->class = This->class;
@@ -883,10 +955,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface,
ULONG celt)
while (celt--)
{
- /* FIXME: try PNP devices and DMOs first */
+ /* FIXME: try PNP devices first */
+ /* try DMOs */
+ if (IEnumDMO_Skip(This->dmo_enum, 1) == S_OK)
+ ;
/* try DirectShow filters */
- if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) !=
ERROR_NO_MORE_ITEMS)
+ else if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) !=
ERROR_NO_MORE_ITEMS)
{
This->sw_index++;
}
@@ -908,6 +983,7 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface)
TRACE("(%p)->()\n", iface);
+ IEnumDMO_Reset(This->dmo_enum);
This->sw_index = 0;
This->cm_index = 0;
@@ -939,6 +1015,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker
**ppEnumMoniker)
{
EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
WCHAR buffer[78];
+ HRESULT hr;
if (!pEnumMoniker)
return E_OUTOFMEMORY;
@@ -949,17 +1026,25 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker
**ppEnumMoniker)
pEnumMoniker->cm_index = 0;
pEnumMoniker->class = *class;
- strcpyW(buffer, clsidW);
- StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
- strcatW(buffer, instanceW);
+ lstrcpyW(buffer, clsidW);
+ lstrcatW(buffer, backslashW);
+ StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+ lstrcatW(buffer, instanceW);
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_ENUMERATE_SUB_KEYS,
&pEnumMoniker->sw_key))
pEnumMoniker->sw_key = NULL;
- strcpyW(buffer, wszActiveMovieKey);
- StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
+ lstrcpyW(buffer, wszActiveMovieKey);
+ StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS,
&pEnumMoniker->cm_key))
pEnumMoniker->cm_key = NULL;
+ hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &pEnumMoniker->dmo_enum);
+ if (FAILED(hr))
+ {
+ IEnumMoniker_Release(&pEnumMoniker->IEnumMoniker_iface);
+ return hr;
+ }
+
*ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface;
DEVENUM_LockModule();
diff --git a/dll/directx/wine/devenum/parsedisplayname.c
b/dll/directx/wine/devenum/parsedisplayname.c
index 0f3ef3be5a0..62523c08d8a 100644
--- a/dll/directx/wine/devenum/parsedisplayname.c
+++ b/dll/directx/wine/devenum/parsedisplayname.c
@@ -87,20 +87,25 @@ static HRESULT WINAPI
DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
*ret = NULL;
if (eaten)
- *eaten = strlenW(name);
+ *eaten = lstrlenW(name);
- name = strchrW(name, ':') + 1;
+ name = wcschr(name, ':') + 1;
- if (name[0] == 's' && name[1] == 'w' && name[2] ==
':')
+ if (!wcsncmp(name, swW, 3))
{
type = DEVICE_FILTER;
name += 3;
}
- else if (name[0] == 'c' && name[1] == 'm' && name[2]
== ':')
+ else if (!wcsncmp(name, cmW, 3))
{
type = DEVICE_CODEC;
name += 3;
}
+ else if (!wcsncmp(name, dmoW, 4))
+ {
+ type = DEVICE_DMO;
+ name += 4;
+ }
else
{
FIXME("unhandled device type %s\n", debugstr_w(name));
@@ -110,22 +115,41 @@ static HRESULT WINAPI
DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
if (!(mon = DEVENUM_IMediaCatMoniker_Construct()))
return E_OUTOFMEMORY;
- lstrcpynW(buffer, name, CHARS_IN_GUID);
- if (CLSIDFromString(buffer, &class) == S_OK)
+ if (type == DEVICE_DMO)
{
- mon->has_class = TRUE;
- mon->class = class;
- name += CHARS_IN_GUID;
+ lstrcpynW(buffer, name, CHARS_IN_GUID);
+ if (FAILED(CLSIDFromString(buffer, &mon->clsid)))
+ {
+ IMoniker_Release(&mon->IMoniker_iface);
+ return MK_E_SYNTAX;
+ }
+
+ lstrcpynW(buffer, name + CHARS_IN_GUID - 1, CHARS_IN_GUID);
+ if (FAILED(CLSIDFromString(buffer, &mon->class)))
+ {
+ IMoniker_Release(&mon->IMoniker_iface);
+ return MK_E_SYNTAX;
+ }
}
-
- mon->type = type;
-
- if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR))))
+ else
{
- IMoniker_Release(&mon->IMoniker_iface);
- return E_OUTOFMEMORY;
+ lstrcpynW(buffer, name, CHARS_IN_GUID);
+ if (CLSIDFromString(buffer, &class) == S_OK)
+ {
+ mon->has_class = TRUE;
+ mon->class = class;
+ name += CHARS_IN_GUID;
+ }
+
+ if (!(mon->name = CoTaskMemAlloc((lstrlenW(name) + 1) * sizeof(WCHAR))))
+ {
+ IMoniker_Release(&mon->IMoniker_iface);
+ return E_OUTOFMEMORY;
+ }
+ lstrcpyW(mon->name, name);
}
- strcpyW(mon->name, name);
+
+ mon->type = type;
*ret = &mon->IMoniker_iface;
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index c6f0d42d836..a94f3ca32fa 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -29,7 +29,7 @@ dll/directx/wine/d3drm # Synced to WineStaging-4.0
dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-4.0
dll/directx/wine/d3dxof # Synced to WineStaging-3.17
dll/directx/wine/ddraw # Synced to WineStaging-3.3
-dll/directx/wine/devenum # Synced to WineStaging-3.9
+dll/directx/wine/devenum # Synced to WineStaging-4.18
dll/directx/wine/dinput # Synced to WineStaging-4.0
dll/directx/wine/dinput8 # Synced to WineStaging-3.3
dll/directx/wine/dmusic # Synced to WineStaging-4.0
diff --git a/sdk/include/reactos/wine/CMakeLists.txt
b/sdk/include/reactos/wine/CMakeLists.txt
index 5a5b7095e3f..709ed1b8c23 100644
--- a/sdk/include/reactos/wine/CMakeLists.txt
+++ b/sdk/include/reactos/wine/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_idl_headers(wineheaders itss.idl)
+add_idl_headers(wineheaders fil_data.idl itss.idl)
diff --git a/dll/directx/wine/devenum/fil_data.idl
b/sdk/include/reactos/wine/fil_data.idl
similarity index 69%
rename from dll/directx/wine/devenum/fil_data.idl
rename to sdk/include/reactos/wine/fil_data.idl
index 7e37a755d91..2475163f2e1 100644
--- a/dll/directx/wine/devenum/fil_data.idl
+++ b/sdk/include/reactos/wine/fil_data.idl
@@ -18,14 +18,9 @@
#pragma makedep header
-import "objidl.idl";
-import "strmif.idl";
import "unknwn.idl";
+import "strmif.idl";
-
-/*****************************************************************************
- * IAMFilterData interface
- */
[
object,
uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
@@ -33,15 +28,7 @@ import "unknwn.idl";
]
interface IAMFilterData : IUnknown
{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
+ HRESULT ParseFilterData( [in] BYTE *data, [in] ULONG size, [out] BYTE **regfilter );
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
+ HRESULT CreateFilterData( [in] REGFILTER2 *regfilter, [out] BYTE **data, [out] ULONG
*size );
}