mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 17:31:31 +00:00
[DEVENUM] Sync with Wine Staging 4.18. CORE-16441
This commit is contained in:
parent
a186e66945
commit
c1585bb868
|
@ -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)
|
||||
|
|
|
@ -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,24 +119,50 @@ 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);
|
||||
|
||||
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)
|
||||
{
|
||||
HKEY hkeyTypes = NULL;
|
||||
|
@ -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);
|
||||
hr = CLSIDFromString(wszFilterSubkeyName, &clsid);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
lstrcpyW(wszRegKey, clsidW);
|
||||
lstrcatW(wszRegKey, backslashW);
|
||||
lstrcatW(wszRegKey, wszFilterSubkeyName);
|
||||
|
||||
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, &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 */
|
||||
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;
|
||||
if ((V_BSTR(&var) = SysAllocString(clsid)))
|
||||
hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
|
||||
if (FAILED(hr)) goto cleanup;
|
||||
|
||||
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;
|
||||
name = (i == -1) ? defaultW : caps.szPname;
|
||||
|
||||
if (i == -1) /* WAVE_MAPPER */
|
||||
V_BSTR(&var) = SysAllocString(defaultW);
|
||||
else
|
||||
V_BSTR(&var) = SysAllocString(caps.szPname);
|
||||
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_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;
|
||||
name = (i == -1) ? defaultW : caps.szPname;
|
||||
|
||||
if (i == -1) /* MIDI_MAPPER */
|
||||
V_BSTR(&var) = SysAllocString(defaultW);
|
||||
else
|
||||
V_BSTR(&var) = SysAllocString(caps.szPname);
|
||||
if (!(V_BSTR(&var)))
|
||||
goto cleanup;
|
||||
|
||||
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();
|
||||
if (!RegOpenKeyW(HKEY_CURRENT_USER, wszActiveMovieKey, &key))
|
||||
{
|
||||
StringFromGUID2(class, guidstr, ARRAY_SIZE(guidstr));
|
||||
RegDeleteTreeW(key, guidstr);
|
||||
}
|
||||
|
||||
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_wavein_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();
|
||||
|
||||
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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 } };
|
|
@ -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);
|
||||
else if (rpb->type == DEVICE_CODEC)
|
||||
strcpyW(rpb->path, wszActiveMovieKey);
|
||||
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 + strlenW(rpb->path), CHARS_IN_GUID);
|
||||
if (rpb->type == DEVICE_FILTER)
|
||||
strcatW(rpb->path, instanceW);
|
||||
strcatW(rpb->path, backslashW);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
strcpyW(buffer, deviceW);
|
||||
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;
|
||||
|
||||
lstrcpyW(buffer, deviceW);
|
||||
if (This->type == DEVICE_FILTER)
|
||||
strcatW(buffer, swW);
|
||||
lstrcatW(buffer, swW);
|
||||
else if (This->type == DEVICE_CODEC)
|
||||
strcatW(buffer, cmW);
|
||||
lstrcatW(buffer, cmW);
|
||||
|
||||
if (This->has_class)
|
||||
{
|
||||
StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID);
|
||||
strcatW(buffer, backslashW);
|
||||
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;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
|
||||
if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) * sizeof(WCHAR))))
|
||||
{
|
||||
IMoniker_Release(&pMoniker->IMoniker_iface);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
strcpyW(pMoniker->name, buffer);
|
||||
lstrcpyW(pMoniker->name, buffer);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
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();
|
||||
|
|
|
@ -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,6 +115,24 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
|
|||
if (!(mon = DEVENUM_IMediaCatMoniker_Construct()))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (type == DEVICE_DMO)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lstrcpynW(buffer, name, CHARS_IN_GUID);
|
||||
if (CLSIDFromString(buffer, &class) == S_OK)
|
||||
{
|
||||
|
@ -118,14 +141,15 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
|
|||
name += CHARS_IN_GUID;
|
||||
}
|
||||
|
||||
mon->type = type;
|
||||
|
||||
if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR))))
|
||||
if (!(mon->name = CoTaskMemAlloc((lstrlenW(name) + 1) * sizeof(WCHAR))))
|
||||
{
|
||||
IMoniker_Release(&mon->IMoniker_iface);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
strcpyW(mon->name, name);
|
||||
lstrcpyW(mon->name, name);
|
||||
}
|
||||
|
||||
mon->type = type;
|
||||
|
||||
*ret = &mon->IMoniker_iface;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
|
||||
add_idl_headers(wineheaders itss.idl)
|
||||
add_idl_headers(wineheaders fil_data.idl itss.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 *data, [in] ULONG size, [out] BYTE **regfilter );
|
||||
|
||||
HRESULT ParseFilterData(
|
||||
[in] BYTE * rgbFilterData,
|
||||
[in] ULONG cb,
|
||||
[out] BYTE ** prgbRegFilter2);
|
||||
|
||||
HRESULT CreateFilterData(
|
||||
[in] REGFILTER2 * prf2,
|
||||
[out] BYTE ** prgbFilterData,
|
||||
[out] ULONG * pcb);
|
||||
HRESULT CreateFilterData( [in] REGFILTER2 *regfilter, [out] BYTE **data, [out] ULONG *size );
|
||||
}
|
Loading…
Reference in a new issue