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