diff --git a/reactos/dll/directx/wine/devenum/CMakeLists.txt b/reactos/dll/directx/wine/devenum/CMakeLists.txt index 47ad36eb20e..3992202e2ed 100644 --- a/reactos/dll/directx/wine/devenum/CMakeLists.txt +++ b/reactos/dll/directx/wine/devenum/CMakeLists.txt @@ -23,6 +23,6 @@ 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 msvcrt kernel32 ntdll) +add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 msvcrt kernel32 ntdll) add_pch(devenum devenum_private.h SOURCE) add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/directx/wine/devenum/createdevenum.c b/reactos/dll/directx/wine/devenum/createdevenum.c index a4d0df5a34b..3cb58cadb3f 100644 --- a/reactos/dll/directx/wine/devenum/createdevenum.c +++ b/reactos/dll/directx/wine/devenum/createdevenum.c @@ -109,6 +109,7 @@ static BOOL IsSpecialCategory(const CLSID *clsid) IsEqualGUID(clsid, &CLSID_AudioInputDeviceCategory) || IsEqualGUID(clsid, &CLSID_VideoInputDeviceCategory) || IsEqualGUID(clsid, &CLSID_VideoCompressorCategory) || + IsEqualGUID(clsid, &CLSID_AudioCompressorCategory) || IsEqualGUID(clsid, &CLSID_MidiRendererCategory); } @@ -633,6 +634,72 @@ static void register_vfw_codecs(void) RegCloseKey(basekey); } +static BOOL WINAPI acm_driver_callback(HACMDRIVERID hadid, DWORD_PTR user, DWORD support) +{ + static const WCHAR CLSIDW[] = {'C','L','S','I','D',0}; + static const WCHAR AcmIdW[] = {'A','c','m','I','d',0}; + static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; + static const WCHAR fmtW[] = {'%','u','%','s',0}; + + WCHAR acmwrapper_clsid_str[CHARS_IN_GUID], buffer[MAX_PATH]; + HKEY key, basekey = (HKEY) user; + ACMFORMATTAGDETAILSW format; + ACMDRIVERDETAILSW driver; + HACMDRIVER had; + DWORD i, res; + + StringFromGUID2(&CLSID_ACMWrapper, acmwrapper_clsid_str, sizeof(acmwrapper_clsid_str)/sizeof(WCHAR)); + + driver.cbStruct = sizeof(driver); + if (acmDriverDetailsW(hadid, &driver, 0) != MMSYSERR_NOERROR) + return TRUE; + + if (acmDriverOpen(&had, hadid, 0) != MMSYSERR_NOERROR) + return TRUE; + + for (i = 0; i < driver.cFormatTags; i++) + { + memset(&format, 0, sizeof(format)); + format.cbStruct = sizeof(format); + format.dwFormatTagIndex = i; + + if (acmFormatTagDetailsW(had, &format, ACM_FORMATTAGDETAILSF_INDEX) != MMSYSERR_NOERROR) + continue; + + snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), fmtW, format.dwFormatTag, format.szFormatTag); + + res = RegCreateKeyW(basekey, buffer, &key); + if (res != ERROR_SUCCESS) continue; + + RegSetValueExW(key, CLSIDW, 0, REG_SZ, (BYTE*)acmwrapper_clsid_str, sizeof(acmwrapper_clsid_str)); + RegSetValueExW(key, AcmIdW, 0, REG_DWORD, (BYTE*)&format.dwFormatTag, sizeof(DWORD)); + RegSetValueExW(key, FriendlyNameW, 0, REG_SZ, (BYTE*)format.szFormatTag, (strlenW(format.szFormatTag)+1)*sizeof(WCHAR)); + /* FIXME: Set FilterData values */ + + RegCloseKey(key); + } + + acmDriverClose(had, 0); + + return TRUE; +} + +static void register_acm_codecs(void) +{ + HKEY basekey; + + basekey = open_special_category_key(&CLSID_AudioCompressorCategory, TRUE); + if (!basekey) + { + ERR("Could not create key\n"); + return; + } + + acmDriverEnum(acm_driver_callback, (DWORD_PTR)basekey, 0); + + RegCloseKey(basekey); +} + static HANDLE DEVENUM_populate_handle; static const WCHAR DEVENUM_populate_handle_nameW[] = {'_','_','W','I','N','E','_', @@ -685,6 +752,8 @@ static HRESULT DEVENUM_CreateSpecialCategories(void) RegDeleteTreeW(basekey, path); if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_VideoCompressorCategory, &basekey, path, MAX_PATH))) RegDeleteTreeW(basekey, path); + if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_AudioCompressorCategory, &basekey, path, MAX_PATH))) + RegDeleteTreeW(basekey, path); rf2.dwVersion = 2; rf2.dwMerit = MERIT_PREFERRED; @@ -966,6 +1035,7 @@ static HRESULT DEVENUM_CreateSpecialCategories(void) IFilterMapper2_Release(pMapper); register_vfw_codecs(); + register_acm_codecs(); SetEvent(DEVENUM_populate_handle); return res; diff --git a/reactos/dll/directx/wine/devenum/mediacatenum.c b/reactos/dll/directx/wine/devenum/mediacatenum.c index 4e30d66a2c3..fb4e561dc7d 100644 --- a/reactos/dll/directx/wine/devenum/mediacatenum.c +++ b/reactos/dll/directx/wine/devenum/mediacatenum.c @@ -352,12 +352,14 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetClassID(IMoniker *iface, CLSID { MediaCatMoniker *This = impl_from_IMoniker(iface); - FIXME("(%p)->(%p): stub\n", This, pClassID); + TRACE("(%p)->(%p)\n", This, pClassID); if (pClassID == NULL) - return E_POINTER; + return E_INVALIDARG; - return E_NOTIMPL; + *pClassID = CLSID_CDeviceMoniker; + + return S_OK; } static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsDirty(IMoniker *iface) @@ -523,9 +525,36 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Enum(IMoniker *iface, BOOL fForwa static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker) { - FIXME("(%p)->(%p): stub\n", iface, pmkOtherMoniker); + CLSID clsid; + LPOLESTR this_name, other_name; + IBindCtx *bind; + HRESULT res; - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", iface, pmkOtherMoniker); + + if (!pmkOtherMoniker) + return E_INVALIDARG; + + IMoniker_GetClassID(pmkOtherMoniker, &clsid); + if (!IsEqualCLSID(&clsid, &CLSID_CDeviceMoniker)) + return S_FALSE; + + res = CreateBindCtx(0, &bind); + if (FAILED(res)) + return res; + + res = S_FALSE; + if (SUCCEEDED(IMoniker_GetDisplayName(iface, bind, NULL, &this_name)) && + SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker, bind, NULL, &other_name))) + { + int result = lstrcmpiW(this_name, other_name); + CoTaskMemFree(this_name); + CoTaskMemFree(other_name); + if (!result) + res = S_OK; + } + IBindCtx_Release(bind); + return res; } static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Hash(IMoniker *iface, DWORD *pdwHash) @@ -591,14 +620,14 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, I MediaCatMoniker *This = impl_from_IMoniker(iface); WCHAR wszBuffer[MAX_PATH]; static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; - LONG received = sizeof(wszFriendlyName); + DWORD received = sizeof(wszBuffer); TRACE("(%p)->(%p, %p, %p)\n", iface, pbc, pmkToLeft, ppszDisplayName); *ppszDisplayName = NULL; /* FIXME: should this be the weird stuff we have to parse in IParseDisplayName? */ - if (RegQueryValueW(This->hkey, wszFriendlyName, wszBuffer, &received) == ERROR_SUCCESS) + if (RegQueryValueExW(This->hkey, wszFriendlyName, NULL, NULL, (LPBYTE)wszBuffer, &received) == ERROR_SUCCESS) { *ppszDisplayName = CoTaskMemAlloc(received); strcpyW(*ppszDisplayName, wszBuffer); diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 98b444c385f..415119b76c1 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -29,7 +29,7 @@ reactos/dll/directx/wine/d3drm # Synced to WineStaging-1.9.23 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-1.9.4 reactos/dll/directx/wine/d3dxof # Synced to WineStaging-1.9.23 reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.9.4 -reactos/dll/directx/wine/devenum # Synced to WineStaging-1.9.23 +reactos/dll/directx/wine/devenum # Synced to WineStaging-2.9 reactos/dll/directx/wine/dinput # Synced to WineStaging-2.2 reactos/dll/directx/wine/dinput8 # Synced to WineStaging-1.9.23 reactos/dll/directx/wine/dmusic # Synced to WineStaging-1.9.23