mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 18:24:24 +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__)
|
add_definitions(-D__WINESRC__)
|
||||||
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
|
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
|
||||||
add_idl_headers(devenum_fil_data_header fil_data.idl)
|
|
||||||
spec2def(devenum.dll devenum.spec)
|
spec2def(devenum.dll devenum.spec)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
createdevenum.c
|
createdevenum.c
|
||||||
devenum_main.c
|
devenum_main.c
|
||||||
factory.c
|
|
||||||
mediacatenum.c
|
mediacatenum.c
|
||||||
parsedisplayname.c
|
parsedisplayname.c
|
||||||
precomp.h)
|
precomp.h)
|
||||||
|
@ -24,7 +22,7 @@ set_source_files_properties(devenum.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT
|
||||||
set_module_type(devenum win32dll UNICODE)
|
set_module_type(devenum win32dll UNICODE)
|
||||||
target_link_libraries(devenum strmiids uuid wine)
|
target_link_libraries(devenum strmiids uuid wine)
|
||||||
add_delay_importlibs(devenum msvfw32)
|
add_delay_importlibs(devenum msvfw32)
|
||||||
add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 dsound msvcrt kernel32 ntdll)
|
add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 dsound msdmo msvcrt kernel32 ntdll)
|
||||||
add_dependencies(devenum devenum_fil_data_header)
|
add_dependencies(devenum wineheaders)
|
||||||
add_pch(devenum precomp.h SOURCE)
|
add_pch(devenum precomp.h SOURCE)
|
||||||
add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all)
|
||||||
|
|
|
@ -32,17 +32,14 @@
|
||||||
#include "dsound.h"
|
#include "dsound.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/unicode.h"
|
|
||||||
#include "wine/heap.h"
|
#include "wine/heap.h"
|
||||||
#include "mmddk.h"
|
#include "mmddk.h"
|
||||||
|
|
||||||
#include "initguid.h"
|
#include "initguid.h"
|
||||||
#include "fil_data.h"
|
#include "wine/fil_data.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
|
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
|
||||||
|
|
||||||
extern HINSTANCE DEVENUM_hInstance;
|
|
||||||
|
|
||||||
static const WCHAR wszFilterKeyName[] = {'F','i','l','t','e','r',0};
|
static const WCHAR wszFilterKeyName[] = {'F','i','l','t','e','r',0};
|
||||||
static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
|
static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
|
||||||
static const WCHAR wszPins[] = {'P','i','n','s',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 const WCHAR wszFilterData[] = {'F','i','l','t','e','r','D','a','t','a',0};
|
||||||
|
|
||||||
static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface);
|
static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface);
|
||||||
static HRESULT register_codecs(void);
|
|
||||||
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
|
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 */
|
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};
|
static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':','c','m',':',0};
|
||||||
|
WCHAR guidstr[CHARS_IN_GUID];
|
||||||
IParseDisplayName *parser;
|
IParseDisplayName *parser;
|
||||||
|
IPropertyBag *propbag;
|
||||||
|
IMoniker *mon;
|
||||||
WCHAR *buffer;
|
WCHAR *buffer;
|
||||||
|
VARIANT var;
|
||||||
ULONG eaten;
|
ULONG eaten;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -118,24 +119,50 @@ static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return 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)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
IParseDisplayName_Release(parser);
|
IParseDisplayName_Release(parser);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpyW(buffer, deviceW);
|
lstrcpyW(buffer, deviceW);
|
||||||
StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
|
StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
|
||||||
strcatW(buffer, backslashW);
|
lstrcatW(buffer, backslashW);
|
||||||
strcatW(buffer, name);
|
lstrcatW(buffer, name);
|
||||||
|
|
||||||
hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, ret);
|
IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
|
||||||
IParseDisplayName_Release(parser);
|
IParseDisplayName_Release(parser);
|
||||||
heap_free(buffer);
|
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;
|
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)
|
static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
|
||||||
{
|
{
|
||||||
HKEY hkeyTypes = NULL;
|
HKEY hkeyTypes = NULL;
|
||||||
|
@ -157,7 +184,7 @@ static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
|
||||||
{
|
{
|
||||||
HKEY hkeyMajorType = NULL;
|
HKEY hkeyMajorType = NULL;
|
||||||
WCHAR wszMajorTypeName[64];
|
WCHAR wszMajorTypeName[64];
|
||||||
DWORD cName = sizeof(wszMajorTypeName) / sizeof(WCHAR);
|
DWORD cName = ARRAY_SIZE(wszMajorTypeName);
|
||||||
DWORD dwMinorTypes, i1;
|
DWORD dwMinorTypes, i1;
|
||||||
|
|
||||||
if (RegEnumKeyExW(hkeyTypes, i, wszMajorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
|
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;
|
CLSID *clsMajorType = NULL, *clsMinorType = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
cName = sizeof(wszMinorTypeName) / sizeof(WCHAR);
|
cName = ARRAY_SIZE(wszMinorTypeName);
|
||||||
if (RegEnumKeyExW(hkeyMajorType, i1, wszMinorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
|
if (RegEnumKeyExW(hkeyMajorType, i1, wszMinorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
|
||||||
|
|
||||||
clsMinorType = CoTaskMemAlloc(sizeof(CLSID));
|
clsMinorType = CoTaskMemAlloc(sizeof(CLSID));
|
||||||
|
@ -263,7 +290,7 @@ static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2)
|
||||||
{
|
{
|
||||||
HKEY hkeyPinKey = NULL;
|
HKEY hkeyPinKey = NULL;
|
||||||
WCHAR wszPinName[MAX_PATH];
|
WCHAR wszPinName[MAX_PATH];
|
||||||
DWORD cName = sizeof(wszPinName) / sizeof(WCHAR);
|
DWORD cName = ARRAY_SIZE(wszPinName);
|
||||||
REGFILTERPINS2 *rgPin = &rgPins[rgf2->u.s2.cPins2];
|
REGFILTERPINS2 *rgPin = &rgPins[rgf2->u.s2.cPins2];
|
||||||
DWORD value, size, Type;
|
DWORD value, size, Type;
|
||||||
LONG lRet;
|
LONG lRet;
|
||||||
|
@ -352,9 +379,9 @@ static void free_regfilter2(REGFILTER2 *rgf)
|
||||||
|
|
||||||
static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
|
static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
|
||||||
{
|
{
|
||||||
|
BYTE *data = NULL, *array;
|
||||||
IAMFilterData *fildata;
|
IAMFilterData *fildata;
|
||||||
SAFEARRAYBOUND sabound;
|
SAFEARRAYBOUND sabound;
|
||||||
BYTE *data, *array;
|
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -410,59 +437,53 @@ static void register_legacy_filters(void)
|
||||||
for (i = 0; i < dwFilterSubkeys; i++)
|
for (i = 0; i < dwFilterSubkeys; i++)
|
||||||
{
|
{
|
||||||
WCHAR wszFilterSubkeyName[64];
|
WCHAR wszFilterSubkeyName[64];
|
||||||
DWORD cName = sizeof(wszFilterSubkeyName) / sizeof(WCHAR);
|
DWORD cName = ARRAY_SIZE(wszFilterSubkeyName);
|
||||||
IPropertyBag *prop_bag = NULL;
|
IPropertyBag *prop_bag = NULL;
|
||||||
WCHAR wszRegKey[MAX_PATH];
|
WCHAR wszRegKey[MAX_PATH];
|
||||||
HKEY classkey = NULL;
|
HKEY classkey = NULL;
|
||||||
IMoniker *mon = NULL;
|
|
||||||
VARIANT var;
|
|
||||||
REGFILTER2 rgf2;
|
REGFILTER2 rgf2;
|
||||||
DWORD Type, len;
|
DWORD Type, len;
|
||||||
|
GUID clsid;
|
||||||
|
|
||||||
if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
|
if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
|
||||||
|
|
||||||
TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
|
TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
|
||||||
|
|
||||||
strcpyW(wszRegKey, clsidW);
|
hr = CLSIDFromString(wszFilterSubkeyName, &clsid);
|
||||||
strcatW(wszRegKey, wszFilterSubkeyName);
|
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)
|
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
|
||||||
continue;
|
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;
|
len = 0;
|
||||||
V_VT(&var) = VT_BSTR;
|
|
||||||
if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len))
|
if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len))
|
||||||
{
|
{
|
||||||
WCHAR *friendlyname = heap_alloc(len);
|
WCHAR *friendlyname = heap_alloc(len);
|
||||||
if (!friendlyname)
|
if (!friendlyname)
|
||||||
goto cleanup;
|
{
|
||||||
|
RegCloseKey(classkey);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname, &len);
|
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);
|
heap_free(friendlyname);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
V_BSTR(&var) = SysAllocString(wszFilterSubkeyName);
|
hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
|
||||||
|
&clsid, wszFilterSubkeyName, &prop_bag);
|
||||||
if (!V_BSTR(&var))
|
if (FAILED(hr))
|
||||||
goto cleanup;
|
{
|
||||||
hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
|
RegCloseKey(classkey);
|
||||||
if (FAILED(hr)) goto cleanup;
|
continue;
|
||||||
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);
|
|
||||||
|
|
||||||
/* write filter data */
|
/* write filter data */
|
||||||
rgf2.dwMerit = MERIT_NORMAL;
|
rgf2.dwMerit = MERIT_NORMAL;
|
||||||
|
@ -474,11 +495,8 @@ static void register_legacy_filters(void)
|
||||||
|
|
||||||
write_filter_data(prop_bag, &rgf2);
|
write_filter_data(prop_bag, &rgf2);
|
||||||
|
|
||||||
cleanup:
|
IPropertyBag_Release(prop_bag);
|
||||||
if (prop_bag) IPropertyBag_Release(prop_bag);
|
|
||||||
if (mon) IMoniker_Release(mon);
|
|
||||||
RegCloseKey(classkey);
|
RegCloseKey(classkey);
|
||||||
VariantClear(&var);
|
|
||||||
free_regfilter2(&rgf2);
|
free_regfilter2(&rgf2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,50 +514,30 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
|
||||||
REGPINTYPES rgtypes = {0};
|
REGPINTYPES rgtypes = {0};
|
||||||
REGFILTER2 rgf = {0};
|
REGFILTER2 rgf = {0};
|
||||||
WCHAR clsid[CHARS_IN_GUID];
|
WCHAR clsid[CHARS_IN_GUID];
|
||||||
IMoniker *mon = NULL;
|
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
|
hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
|
||||||
if (FAILED(hr)) goto cleanup;
|
if (FAILED(hr))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
V_VT(&var) = VT_BSTR;
|
|
||||||
if (guid)
|
if (guid)
|
||||||
{
|
{
|
||||||
WCHAR *name = heap_alloc(sizeof(defaultW) + strlenW(desc) * sizeof(WCHAR));
|
WCHAR *name = heap_alloc(sizeof(defaultW) + lstrlenW(desc) * sizeof(WCHAR));
|
||||||
if (!name)
|
if (!name)
|
||||||
goto cleanup;
|
return FALSE;
|
||||||
strcpyW(name, directsoundW);
|
lstrcpyW(name, directsoundW);
|
||||||
strcatW(name, desc);
|
lstrcatW(name, desc);
|
||||||
|
|
||||||
V_BSTR(&var) = SysAllocString(name);
|
hr = register_codec(&CLSID_AudioRendererCategory, name,
|
||||||
|
&CLSID_DSoundRender, name, &prop_bag);
|
||||||
heap_free(name);
|
heap_free(name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
V_BSTR(&var) = SysAllocString(defaultW);
|
hr = register_codec(&CLSID_AudioRendererCategory, defaultW,
|
||||||
|
&CLSID_DSoundRender, defaultW, &prop_bag);
|
||||||
if (!V_BSTR(&var))
|
if (FAILED(hr))
|
||||||
goto cleanup;
|
return FALSE;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* write filter data */
|
/* write filter data */
|
||||||
rgf.dwVersion = 2;
|
rgf.dwVersion = 2;
|
||||||
|
@ -558,16 +556,11 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
|
||||||
/* write DSound guid */
|
/* write DSound guid */
|
||||||
V_VT(&var) = VT_BSTR;
|
V_VT(&var) = VT_BSTR;
|
||||||
StringFromGUID2(guid ? guid : &GUID_NULL, clsid, CHARS_IN_GUID);
|
StringFromGUID2(guid ? guid : &GUID_NULL, clsid, CHARS_IN_GUID);
|
||||||
if (!(V_BSTR(&var) = SysAllocString(clsid)))
|
if ((V_BSTR(&var) = SysAllocString(clsid)))
|
||||||
goto cleanup;
|
|
||||||
hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
|
hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VariantClear(&var);
|
VariantClear(&var);
|
||||||
if (prop_bag) IPropertyBag_Release(prop_bag);
|
IPropertyBag_Release(prop_bag);
|
||||||
if (mon) IMoniker_Release(mon);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,9 +572,8 @@ static void register_waveout_devices(void)
|
||||||
REGFILTERPINS2 rgpins = {0};
|
REGFILTERPINS2 rgpins = {0};
|
||||||
REGPINTYPES rgtypes = {0};
|
REGPINTYPES rgtypes = {0};
|
||||||
REGFILTER2 rgf = {0};
|
REGFILTER2 rgf = {0};
|
||||||
WCHAR clsid[CHARS_IN_GUID];
|
|
||||||
IMoniker *mon = NULL;
|
|
||||||
WAVEOUTCAPSW caps;
|
WAVEOUTCAPSW caps;
|
||||||
|
const WCHAR *name;
|
||||||
int i, count;
|
int i, count;
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -595,34 +587,12 @@ static void register_waveout_devices(void)
|
||||||
{
|
{
|
||||||
waveOutGetDevCapsW(i, &caps, sizeof(caps));
|
waveOutGetDevCapsW(i, &caps, sizeof(caps));
|
||||||
|
|
||||||
V_VT(&var) = VT_BSTR;
|
name = (i == -1) ? defaultW : caps.szPname;
|
||||||
|
|
||||||
if (i == -1) /* WAVE_MAPPER */
|
hr = register_codec(&CLSID_AudioRendererCategory, name,
|
||||||
V_BSTR(&var) = SysAllocString(defaultW);
|
&CLSID_AudioRender, name, &prop_bag);
|
||||||
else
|
if (FAILED(hr))
|
||||||
V_BSTR(&var) = SysAllocString(caps.szPname);
|
continue;
|
||||||
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);
|
|
||||||
|
|
||||||
/* write filter data */
|
/* write filter data */
|
||||||
rgf.dwVersion = 2;
|
rgf.dwVersion = 2;
|
||||||
|
@ -640,13 +610,10 @@ static void register_waveout_devices(void)
|
||||||
/* write WaveOutId */
|
/* write WaveOutId */
|
||||||
V_VT(&var) = VT_I4;
|
V_VT(&var) = VT_I4;
|
||||||
V_I4(&var) = i;
|
V_I4(&var) = i;
|
||||||
hr = IPropertyBag_Write(prop_bag, waveoutidW, &var);
|
IPropertyBag_Write(prop_bag, waveoutidW, &var);
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VariantClear(&var);
|
VariantClear(&var);
|
||||||
if (prop_bag) IPropertyBag_Release(prop_bag);
|
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};
|
static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0};
|
||||||
IPropertyBag *prop_bag = NULL;
|
IPropertyBag *prop_bag = NULL;
|
||||||
REGFILTER2 rgf = {0};
|
REGFILTER2 rgf = {0};
|
||||||
WCHAR clsid[CHARS_IN_GUID];
|
|
||||||
IMoniker *mon = NULL;
|
|
||||||
WAVEINCAPSW caps;
|
WAVEINCAPSW caps;
|
||||||
int i, count;
|
int i, count;
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
|
@ -671,31 +636,10 @@ static void register_wavein_devices(void)
|
||||||
{
|
{
|
||||||
waveInGetDevCapsW(i, &caps, sizeof(caps));
|
waveInGetDevCapsW(i, &caps, sizeof(caps));
|
||||||
|
|
||||||
V_VT(&var) = VT_BSTR;
|
hr = register_codec(&CLSID_AudioInputDeviceCategory, caps.szPname,
|
||||||
|
&CLSID_AudioRecord, caps.szPname, &prop_bag);
|
||||||
V_BSTR(&var) = SysAllocString(caps.szPname);
|
if (FAILED(hr))
|
||||||
if (!(V_BSTR(&var)))
|
continue;
|
||||||
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);
|
|
||||||
|
|
||||||
/* write filter data */
|
/* write filter data */
|
||||||
rgf.dwVersion = 2;
|
rgf.dwVersion = 2;
|
||||||
|
@ -706,13 +650,10 @@ static void register_wavein_devices(void)
|
||||||
/* write WaveInId */
|
/* write WaveInId */
|
||||||
V_VT(&var) = VT_I4;
|
V_VT(&var) = VT_I4;
|
||||||
V_I4(&var) = i;
|
V_I4(&var) = i;
|
||||||
hr = IPropertyBag_Write(prop_bag, waveinidW, &var);
|
IPropertyBag_Write(prop_bag, waveinidW, &var);
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VariantClear(&var);
|
VariantClear(&var);
|
||||||
if (prop_bag) IPropertyBag_Release(prop_bag);
|
IPropertyBag_Release(prop_bag);
|
||||||
if (mon) IMoniker_Release(mon);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,9 +665,8 @@ static void register_midiout_devices(void)
|
||||||
REGFILTERPINS2 rgpins = {0};
|
REGFILTERPINS2 rgpins = {0};
|
||||||
REGPINTYPES rgtypes = {0};
|
REGPINTYPES rgtypes = {0};
|
||||||
REGFILTER2 rgf = {0};
|
REGFILTER2 rgf = {0};
|
||||||
WCHAR clsid[CHARS_IN_GUID];
|
|
||||||
IMoniker *mon = NULL;
|
|
||||||
MIDIOUTCAPSW caps;
|
MIDIOUTCAPSW caps;
|
||||||
|
const WCHAR *name;
|
||||||
int i, count;
|
int i, count;
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -740,34 +680,12 @@ static void register_midiout_devices(void)
|
||||||
{
|
{
|
||||||
midiOutGetDevCapsW(i, &caps, sizeof(caps));
|
midiOutGetDevCapsW(i, &caps, sizeof(caps));
|
||||||
|
|
||||||
V_VT(&var) = VT_BSTR;
|
name = (i == -1) ? defaultW : caps.szPname;
|
||||||
|
|
||||||
if (i == -1) /* MIDI_MAPPER */
|
hr = register_codec(&CLSID_MidiRendererCategory, name,
|
||||||
V_BSTR(&var) = SysAllocString(defaultW);
|
&CLSID_AVIMIDIRender, name, &prop_bag);
|
||||||
else
|
if (FAILED(hr))
|
||||||
V_BSTR(&var) = SysAllocString(caps.szPname);
|
continue;
|
||||||
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);
|
|
||||||
|
|
||||||
/* write filter data */
|
/* write filter data */
|
||||||
rgf.dwVersion = 2;
|
rgf.dwVersion = 2;
|
||||||
|
@ -785,13 +703,10 @@ static void register_midiout_devices(void)
|
||||||
/* write MidiOutId */
|
/* write MidiOutId */
|
||||||
V_VT(&var) = VT_I4;
|
V_VT(&var) = VT_I4;
|
||||||
V_I4(&var) = i;
|
V_I4(&var) = i;
|
||||||
hr = IPropertyBag_Write(prop_bag, midioutidW, &var);
|
IPropertyBag_Write(prop_bag, midioutidW, &var);
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VariantClear(&var);
|
VariantClear(&var);
|
||||||
if (prop_bag) IPropertyBag_Release(prop_bag);
|
IPropertyBag_Release(prop_bag);
|
||||||
if (mon) IMoniker_Release(mon);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,8 +717,6 @@ static void register_vfw_codecs(void)
|
||||||
IPropertyBag *prop_bag = NULL;
|
IPropertyBag *prop_bag = NULL;
|
||||||
REGPINTYPES rgtypes[2];
|
REGPINTYPES rgtypes[2];
|
||||||
REGFILTER2 rgf;
|
REGFILTER2 rgf;
|
||||||
WCHAR clsid[CHARS_IN_GUID];
|
|
||||||
IMoniker *mon = NULL;
|
|
||||||
GUID typeguid;
|
GUID typeguid;
|
||||||
ICINFO info;
|
ICINFO info;
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
|
@ -823,40 +736,10 @@ static void register_vfw_codecs(void)
|
||||||
ICGetInfo(hic, &info, sizeof(info));
|
ICGetInfo(hic, &info, sizeof(info));
|
||||||
ICClose(hic);
|
ICClose(hic);
|
||||||
|
|
||||||
V_VT(&var) = VT_BSTR;
|
hr = register_codec(&CLSID_VideoCompressorCategory, name,
|
||||||
|
&CLSID_AVICo, info.szDescription, &prop_bag);
|
||||||
V_BSTR(&var) = SysAllocString(name);
|
if (FAILED(hr))
|
||||||
if (!(V_BSTR(&var)))
|
continue;
|
||||||
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);
|
|
||||||
|
|
||||||
/* write filter data */
|
/* write filter data */
|
||||||
rgf.dwVersion = 2;
|
rgf.dwVersion = 2;
|
||||||
|
@ -878,10 +761,65 @@ static void register_vfw_codecs(void)
|
||||||
|
|
||||||
write_filter_data(prop_bag, &rgf);
|
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);
|
VariantClear(&var);
|
||||||
if (prop_bag) IPropertyBag_Release(prop_bag);
|
IPropertyBag_Release(prop_bag);
|
||||||
if (mon) IMoniker_Release(mon);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
* DEVENUM_ICreateDevEnum_CreateClassEnumerator
|
||||||
*/
|
*/
|
||||||
static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
|
static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
|
||||||
ICreateDevEnum * iface,
|
ICreateDevEnum *iface, REFCLSID class, IEnumMoniker **out, DWORD flags)
|
||||||
REFCLSID clsidDeviceClass,
|
|
||||||
IEnumMoniker **ppEnumMoniker,
|
|
||||||
DWORD dwFlags)
|
|
||||||
{
|
{
|
||||||
|
WCHAR guidstr[CHARS_IN_GUID];
|
||||||
HRESULT hr;
|
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;
|
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();
|
register_legacy_filters();
|
||||||
|
else if (IsEqualGUID(class, &CLSID_AudioRendererCategory))
|
||||||
|
{
|
||||||
hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL);
|
hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL);
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
register_waveout_devices();
|
register_waveout_devices();
|
||||||
register_wavein_devices();
|
|
||||||
register_midiout_devices();
|
register_midiout_devices();
|
||||||
|
}
|
||||||
|
else if (IsEqualGUID(class, &CLSID_AudioInputDeviceCategory))
|
||||||
|
register_wavein_devices();
|
||||||
|
else if (IsEqualGUID(class, &CLSID_VideoCompressorCategory))
|
||||||
register_vfw_codecs();
|
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;
|
HRESULT res = S_OK;
|
||||||
HKEY hkeyDummy = NULL;
|
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;
|
res = E_INVALIDARG;
|
||||||
|
|
||||||
if (SUCCEEDED(res))
|
if (SUCCEEDED(res))
|
||||||
|
@ -962,111 +928,3 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
|
||||||
|
|
||||||
return res;
|
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 John K. Hohm
|
||||||
* Copyright (C) 2002 Robert Shearman
|
* Copyright (C) 2002 Robert Shearman
|
||||||
|
@ -26,24 +26,12 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
|
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
|
||||||
|
|
||||||
DECLSPEC_HIDDEN LONG dll_refs;
|
DECLSPEC_HIDDEN LONG dll_refs;
|
||||||
DECLSPEC_HIDDEN HINSTANCE DEVENUM_hInstance;
|
static HINSTANCE devenum_instance;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
REFCLSID clsid;
|
|
||||||
LPCWSTR friendly_name;
|
|
||||||
BOOL instance;
|
|
||||||
} register_info;
|
|
||||||
|
|
||||||
#ifdef __REACTOS__
|
#ifdef __REACTOS__
|
||||||
static void DEVENUM_RegisterQuartz(void);
|
static void DEVENUM_RegisterQuartz(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Global string constant definitions
|
|
||||||
*/
|
|
||||||
const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 };
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DllEntryPoint
|
* DllEntryPoint
|
||||||
*/
|
*/
|
||||||
|
@ -53,29 +41,101 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||||
|
|
||||||
switch(fdwReason) {
|
switch(fdwReason) {
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DEVENUM_hInstance = hinstDLL;
|
devenum_instance = hinstDLL;
|
||||||
DisableThreadLibraryCalls(hinstDLL);
|
DisableThreadLibraryCalls(hinstDLL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
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.@)
|
* 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.
|
if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum))
|
||||||
* Oh well - works just fine as it is */
|
return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface, iid, obj);
|
||||||
if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
|
else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker))
|
||||||
IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
|
return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface, iid, obj);
|
||||||
return IClassFactory_QueryInterface(&DEVENUM_ClassFactory.IClassFactory_iface, iid, ppv);
|
|
||||||
|
|
||||||
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;
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +158,7 @@ HRESULT WINAPI DllRegisterServer(void)
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
res = __wine_register_resources( DEVENUM_hInstance );
|
res = __wine_register_resources( devenum_instance );
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -151,7 +211,7 @@ HRESULT WINAPI DllRegisterServer(void)
|
||||||
HRESULT WINAPI DllUnregisterServer(void)
|
HRESULT WINAPI DllUnregisterServer(void)
|
||||||
{
|
{
|
||||||
FIXME("stub!\n");
|
FIXME("stub!\n");
|
||||||
return __wine_unregister_resources( DEVENUM_hInstance );
|
return __wine_unregister_resources( devenum_instance );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __REACTOS__
|
#ifdef __REACTOS__
|
||||||
|
|
|
@ -42,10 +42,6 @@
|
||||||
#include "olectl.h"
|
#include "olectl.h"
|
||||||
#include "uuids.h"
|
#include "uuids.h"
|
||||||
|
|
||||||
#ifndef RC_INVOKED
|
|
||||||
#include "wine/unicode.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Dll lifetime tracking declaration for devenum.dll
|
* 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_LockModule(void) { InterlockedIncrement(&dll_refs); }
|
||||||
static inline void DEVENUM_UnlockModule(void) { InterlockedDecrement(&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
|
enum device_type
|
||||||
{
|
{
|
||||||
DEVICE_FILTER,
|
DEVICE_FILTER,
|
||||||
DEVICE_CODEC,
|
DEVICE_CODEC,
|
||||||
|
DEVICE_DMO,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -75,13 +63,16 @@ typedef struct
|
||||||
CLSID class;
|
CLSID class;
|
||||||
BOOL has_class;
|
BOOL has_class;
|
||||||
enum device_type type;
|
enum device_type type;
|
||||||
WCHAR *name;
|
union
|
||||||
|
{
|
||||||
|
WCHAR *name; /* for filters and codecs */
|
||||||
|
CLSID clsid; /* for DMOs */
|
||||||
|
};
|
||||||
} MediaCatMoniker;
|
} MediaCatMoniker;
|
||||||
|
|
||||||
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
|
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
|
||||||
HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **enum_mon) 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 ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN;
|
||||||
extern IParseDisplayName DEVENUM_ParseDisplayName 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 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 instanceW[] = {'\\','I','n','s','t','a','n','c','e',0};
|
||||||
static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
|
static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
'A','c','t','i','v','e','M','o','v','i','e','\\',
|
'A','c','t','i','v','e','M','o','v','i','e','\\',
|
||||||
'd','e','v','e','n','u','m','\\',0};
|
'd','e','v','e','n','u','m','\\',0};
|
||||||
static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
|
static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
|
||||||
|
static const WCHAR dmoW[] = {'d','m','o',':',0};
|
||||||
extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN;
|
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 "devenum_private.h"
|
||||||
#include "oleauto.h"
|
#include "oleauto.h"
|
||||||
#include "ocidl.h"
|
#include "ocidl.h"
|
||||||
|
#include "dmoreg.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ typedef struct
|
||||||
IEnumMoniker IEnumMoniker_iface;
|
IEnumMoniker IEnumMoniker_iface;
|
||||||
CLSID class;
|
CLSID class;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
IEnumDMO *dmo_enum;
|
||||||
HKEY sw_key;
|
HKEY sw_key;
|
||||||
DWORD sw_index;
|
DWORD sw_index;
|
||||||
HKEY cm_key;
|
HKEY cm_key;
|
||||||
|
@ -46,7 +48,11 @@ typedef struct
|
||||||
IPropertyBag IPropertyBag_iface;
|
IPropertyBag IPropertyBag_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
enum device_type type;
|
enum device_type type;
|
||||||
WCHAR path[MAX_PATH];
|
union
|
||||||
|
{
|
||||||
|
WCHAR path[MAX_PATH]; /* for filters and codecs */
|
||||||
|
CLSID clsid; /* for DMOs */
|
||||||
|
};
|
||||||
} RegPropBagImpl;
|
} RegPropBagImpl;
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,12 +120,14 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
|
||||||
VARIANT* pVar,
|
VARIANT* pVar,
|
||||||
IErrorLog* pErrorLog)
|
IErrorLog* pErrorLog)
|
||||||
{
|
{
|
||||||
|
static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
|
||||||
LPVOID pData = NULL;
|
LPVOID pData = NULL;
|
||||||
DWORD received;
|
DWORD received;
|
||||||
DWORD type = 0;
|
DWORD type = 0;
|
||||||
RegPropBagImpl *This = impl_from_IPropertyBag(iface);
|
RegPropBagImpl *This = impl_from_IPropertyBag(iface);
|
||||||
HRESULT res = S_OK;
|
HRESULT res = S_OK;
|
||||||
LONG reswin32 = ERROR_SUCCESS;
|
LONG reswin32 = ERROR_SUCCESS;
|
||||||
|
WCHAR name[80];
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
|
|
||||||
TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
|
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)
|
if (!pszPropName || !pVar)
|
||||||
return E_POINTER;
|
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)
|
if (This->type == DEVICE_FILTER)
|
||||||
reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
|
reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
|
||||||
else if (This->type == DEVICE_CODEC)
|
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);
|
TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);
|
||||||
|
|
||||||
|
if (This->type == DEVICE_DMO)
|
||||||
|
return E_ACCESSDENIED;
|
||||||
|
|
||||||
switch (V_VT(pVar))
|
switch (V_VT(pVar))
|
||||||
{
|
{
|
||||||
case VT_BSTR:
|
case VT_BSTR:
|
||||||
|
@ -316,18 +342,30 @@ static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag)
|
||||||
rpb->ref = 1;
|
rpb->ref = 1;
|
||||||
rpb->type = mon->type;
|
rpb->type = mon->type;
|
||||||
|
|
||||||
if (rpb->type == DEVICE_FILTER)
|
if (rpb->type == DEVICE_DMO)
|
||||||
strcpyW(rpb->path, clsidW);
|
rpb->clsid = mon->clsid;
|
||||||
else if (rpb->type == DEVICE_CODEC)
|
else if (rpb->type == DEVICE_FILTER)
|
||||||
strcpyW(rpb->path, wszActiveMovieKey);
|
{
|
||||||
|
lstrcpyW(rpb->path, clsidW);
|
||||||
|
lstrcatW(rpb->path, backslashW);
|
||||||
if (mon->has_class)
|
if (mon->has_class)
|
||||||
{
|
{
|
||||||
StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID);
|
StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path), CHARS_IN_GUID);
|
||||||
if (rpb->type == DEVICE_FILTER)
|
lstrcatW(rpb->path, instanceW);
|
||||||
strcatW(rpb->path, instanceW);
|
lstrcatW(rpb->path, backslashW);
|
||||||
strcatW(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;
|
*ppBag = &rpb->IPropertyBag_iface;
|
||||||
DEVENUM_LockModule();
|
DEVENUM_LockModule();
|
||||||
|
@ -459,7 +497,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBi
|
||||||
if (SUCCEEDED(res))
|
if (SUCCEEDED(res))
|
||||||
{
|
{
|
||||||
V_VT(&var) = VT_LPWSTR;
|
V_VT(&var) = VT_LPWSTR;
|
||||||
res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL);
|
res = IPropertyBag_Read(pProp, clsidW, &var, NULL);
|
||||||
}
|
}
|
||||||
if (SUCCEEDED(res))
|
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,
|
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
|
||||||
IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
|
IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
|
||||||
{
|
{
|
||||||
static const WCHAR swW[] = {'s','w',':',0};
|
|
||||||
static const WCHAR cmW[] = {'c','m',':',0};
|
|
||||||
MediaCatMoniker *This = impl_from_IMoniker(iface);
|
MediaCatMoniker *This = impl_from_IMoniker(iface);
|
||||||
WCHAR *buffer;
|
WCHAR *buffer;
|
||||||
|
|
||||||
|
@ -667,23 +703,36 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, I
|
||||||
|
|
||||||
*ppszDisplayName = NULL;
|
*ppszDisplayName = NULL;
|
||||||
|
|
||||||
buffer = CoTaskMemAlloc((strlenW(deviceW) + 4 + (This->has_class ? CHARS_IN_GUID : 0)
|
if (This->type == DEVICE_DMO)
|
||||||
+ strlenW(This->name) + 1) * sizeof(WCHAR));
|
{
|
||||||
if (!buffer)
|
buffer = CoTaskMemAlloc((lstrlenW(deviceW) + lstrlenW(dmoW)
|
||||||
return E_OUTOFMEMORY;
|
+ 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)
|
if (This->type == DEVICE_FILTER)
|
||||||
strcatW(buffer, swW);
|
lstrcatW(buffer, swW);
|
||||||
else if (This->type == DEVICE_CODEC)
|
else if (This->type == DEVICE_CODEC)
|
||||||
strcatW(buffer, cmW);
|
lstrcatW(buffer, cmW);
|
||||||
|
|
||||||
if (This->has_class)
|
if (This->has_class)
|
||||||
{
|
{
|
||||||
StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID);
|
StringFromGUID2(&This->class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
|
||||||
strcatW(buffer, backslashW);
|
lstrcatW(buffer, backslashW);
|
||||||
|
}
|
||||||
|
lstrcatW(buffer, This->name);
|
||||||
}
|
}
|
||||||
strcatW(buffer, This->name);
|
|
||||||
|
|
||||||
*ppszDisplayName = buffer;
|
*ppszDisplayName = buffer;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -798,6 +847,7 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
{
|
{
|
||||||
|
IEnumDMO_Release(This->dmo_enum);
|
||||||
RegCloseKey(This->sw_key);
|
RegCloseKey(This->sw_key);
|
||||||
RegCloseKey(This->cm_key);
|
RegCloseKey(This->cm_key);
|
||||||
CoTaskMemFree(This);
|
CoTaskMemFree(This);
|
||||||
|
@ -815,16 +865,30 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
|
||||||
LONG res;
|
LONG res;
|
||||||
ULONG fetched = 0;
|
ULONG fetched = 0;
|
||||||
MediaCatMoniker * pMoniker;
|
MediaCatMoniker * pMoniker;
|
||||||
|
CLSID clsid;
|
||||||
|
HRESULT hr;
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
|
|
||||||
TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
|
TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
|
||||||
|
|
||||||
while (fetched < celt)
|
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 */
|
/* 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++;
|
This->sw_index++;
|
||||||
if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
|
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;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
pMoniker->type = DEVICE_FILTER;
|
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 */
|
/* 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++;
|
This->cm_index++;
|
||||||
|
|
||||||
|
@ -847,16 +918,17 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
pMoniker->type = DEVICE_CODEC;
|
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);
|
IMoniker_Release(&pMoniker->IMoniker_iface);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
strcpyW(pMoniker->name, buffer);
|
lstrcpyW(pMoniker->name, buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
pMoniker->has_class = TRUE;
|
pMoniker->has_class = TRUE;
|
||||||
pMoniker->class = This->class;
|
pMoniker->class = This->class;
|
||||||
|
|
||||||
|
@ -883,10 +955,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt)
|
||||||
|
|
||||||
while (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 */
|
/* 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++;
|
This->sw_index++;
|
||||||
}
|
}
|
||||||
|
@ -908,6 +983,7 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface)
|
||||||
|
|
||||||
TRACE("(%p)->()\n", iface);
|
TRACE("(%p)->()\n", iface);
|
||||||
|
|
||||||
|
IEnumDMO_Reset(This->dmo_enum);
|
||||||
This->sw_index = 0;
|
This->sw_index = 0;
|
||||||
This->cm_index = 0;
|
This->cm_index = 0;
|
||||||
|
|
||||||
|
@ -939,6 +1015,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
|
||||||
{
|
{
|
||||||
EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
|
EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
|
||||||
WCHAR buffer[78];
|
WCHAR buffer[78];
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
if (!pEnumMoniker)
|
if (!pEnumMoniker)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
@ -949,17 +1026,25 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
|
||||||
pEnumMoniker->cm_index = 0;
|
pEnumMoniker->cm_index = 0;
|
||||||
pEnumMoniker->class = *class;
|
pEnumMoniker->class = *class;
|
||||||
|
|
||||||
strcpyW(buffer, clsidW);
|
lstrcpyW(buffer, clsidW);
|
||||||
StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
|
lstrcatW(buffer, backslashW);
|
||||||
strcatW(buffer, instanceW);
|
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))
|
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->sw_key))
|
||||||
pEnumMoniker->sw_key = NULL;
|
pEnumMoniker->sw_key = NULL;
|
||||||
|
|
||||||
strcpyW(buffer, wszActiveMovieKey);
|
lstrcpyW(buffer, wszActiveMovieKey);
|
||||||
StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
|
StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID);
|
||||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key))
|
if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key))
|
||||||
pEnumMoniker->cm_key = NULL;
|
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;
|
*ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface;
|
||||||
|
|
||||||
DEVENUM_LockModule();
|
DEVENUM_LockModule();
|
||||||
|
|
|
@ -87,20 +87,25 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
|
||||||
|
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
if (eaten)
|
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;
|
type = DEVICE_FILTER;
|
||||||
name += 3;
|
name += 3;
|
||||||
}
|
}
|
||||||
else if (name[0] == 'c' && name[1] == 'm' && name[2] == ':')
|
else if (!wcsncmp(name, cmW, 3))
|
||||||
{
|
{
|
||||||
type = DEVICE_CODEC;
|
type = DEVICE_CODEC;
|
||||||
name += 3;
|
name += 3;
|
||||||
}
|
}
|
||||||
|
else if (!wcsncmp(name, dmoW, 4))
|
||||||
|
{
|
||||||
|
type = DEVICE_DMO;
|
||||||
|
name += 4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FIXME("unhandled device type %s\n", debugstr_w(name));
|
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()))
|
if (!(mon = DEVENUM_IMediaCatMoniker_Construct()))
|
||||||
return E_OUTOFMEMORY;
|
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);
|
lstrcpynW(buffer, name, CHARS_IN_GUID);
|
||||||
if (CLSIDFromString(buffer, &class) == S_OK)
|
if (CLSIDFromString(buffer, &class) == S_OK)
|
||||||
{
|
{
|
||||||
|
@ -118,14 +141,15 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
|
||||||
name += CHARS_IN_GUID;
|
name += CHARS_IN_GUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
mon->type = type;
|
if (!(mon->name = CoTaskMemAlloc((lstrlenW(name) + 1) * sizeof(WCHAR))))
|
||||||
|
|
||||||
if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR))))
|
|
||||||
{
|
{
|
||||||
IMoniker_Release(&mon->IMoniker_iface);
|
IMoniker_Release(&mon->IMoniker_iface);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
strcpyW(mon->name, name);
|
lstrcpyW(mon->name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
mon->type = type;
|
||||||
|
|
||||||
*ret = &mon->IMoniker_iface;
|
*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/d3dx9_24 => 43 # Synced to WineStaging-4.0
|
||||||
dll/directx/wine/d3dxof # Synced to WineStaging-3.17
|
dll/directx/wine/d3dxof # Synced to WineStaging-3.17
|
||||||
dll/directx/wine/ddraw # Synced to WineStaging-3.3
|
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/dinput # Synced to WineStaging-4.0
|
||||||
dll/directx/wine/dinput8 # Synced to WineStaging-3.3
|
dll/directx/wine/dinput8 # Synced to WineStaging-3.3
|
||||||
dll/directx/wine/dmusic # Synced to WineStaging-4.0
|
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
|
#pragma makedep header
|
||||||
|
|
||||||
import "objidl.idl";
|
|
||||||
import "strmif.idl";
|
|
||||||
import "unknwn.idl";
|
import "unknwn.idl";
|
||||||
|
import "strmif.idl";
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* IAMFilterData interface
|
|
||||||
*/
|
|
||||||
[
|
[
|
||||||
object,
|
object,
|
||||||
uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
|
uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
|
||||||
|
@ -33,15 +28,7 @@ import "unknwn.idl";
|
||||||
]
|
]
|
||||||
interface IAMFilterData : IUnknown
|
interface IAMFilterData : IUnknown
|
||||||
{
|
{
|
||||||
typedef [unique] IAMFilterData *LPIAMFILTERDATA;
|
HRESULT ParseFilterData( [in] BYTE *data, [in] ULONG size, [out] BYTE **regfilter );
|
||||||
|
|
||||||
HRESULT ParseFilterData(
|
HRESULT CreateFilterData( [in] REGFILTER2 *regfilter, [out] BYTE **data, [out] ULONG *size );
|
||||||
[in] BYTE * rgbFilterData,
|
|
||||||
[in] ULONG cb,
|
|
||||||
[out] BYTE ** prgbRegFilter2);
|
|
||||||
|
|
||||||
HRESULT CreateFilterData(
|
|
||||||
[in] REGFILTER2 * prf2,
|
|
||||||
[out] BYTE ** prgbFilterData,
|
|
||||||
[out] ULONG * pcb);
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue