From c5a095eadbd307bed43f2a9cd5abd729a48594e1 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 19 Apr 2014 19:30:15 +0000 Subject: [PATCH] [DEVENUM] * Sync with Wine 1.7.17. CORE-8080 svn path=/trunk/; revision=62821 --- .../dll/directx/wine/devenum/CMakeLists.txt | 1 + .../dll/directx/wine/devenum/createdevenum.c | 129 +++++++++++++++--- .../directx/wine/devenum/devenum_classes.idl | 2 + .../directx/wine/devenum/devenum_private.h | 2 +- .../dll/directx/wine/devenum/mediacatenum.c | 32 +++-- reactos/media/doc/README.WINE | 2 +- 6 files changed, 137 insertions(+), 31 deletions(-) diff --git a/reactos/dll/directx/wine/devenum/CMakeLists.txt b/reactos/dll/directx/wine/devenum/CMakeLists.txt index 52d6f4a01a7..5768de217ba 100644 --- a/reactos/dll/directx/wine/devenum/CMakeLists.txt +++ b/reactos/dll/directx/wine/devenum/CMakeLists.txt @@ -23,5 +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_importlibs(devenum advapi32 ole32 oleaut32 winmm user32 avicap32 msvcrt kernel32 ntdll) +add_delay_importlibs(devenum msvfw32) 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 c69849b69b3..29ba0e8ca33 100644 --- a/reactos/dll/directx/wine/devenum/createdevenum.c +++ b/reactos/dll/directx/wine/devenum/createdevenum.c @@ -26,12 +26,13 @@ #include "devenum_private.h" #include +#include #include "resource.h" extern HINSTANCE DEVENUM_hInstance; -const WCHAR wszInstanceKeyName[] ={'I','n','s','t','a','n','c','e',0}; +const WCHAR wszInstanceKeyName[] ={'\\','I','n','s','t','a','n','c','e',0}; static const WCHAR wszRegSeparator[] = {'\\', 0 }; static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\', @@ -101,12 +102,18 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum * iface) return 1; /* non-heap based object */ } +static BOOL IsSpecialCategory(const CLSID *clsid) +{ + return IsEqualGUID(clsid, &CLSID_AudioRendererCategory) || + IsEqualGUID(clsid, &CLSID_AudioInputDeviceCategory) || + IsEqualGUID(clsid, &CLSID_VideoInputDeviceCategory) || + IsEqualGUID(clsid, &CLSID_VideoCompressorCategory) || + IsEqualGUID(clsid, &CLSID_MidiRendererCategory); +} + HRESULT DEVENUM_GetCategoryKey(REFCLSID clsidDeviceClass, HKEY *pBaseKey, WCHAR *wszRegKeyName, UINT maxLen) { - if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) || - IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) || - IsEqualGUID(clsidDeviceClass, &CLSID_VideoInputDeviceCategory) || - IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory)) + if (IsSpecialCategory(clsidDeviceClass)) { *pBaseKey = HKEY_CURRENT_USER; strcpyW(wszRegKeyName, wszActiveMovieKey); @@ -123,13 +130,57 @@ HRESULT DEVENUM_GetCategoryKey(REFCLSID clsidDeviceClass, HKEY *pBaseKey, WCHAR if (!StringFromGUID2(clsidDeviceClass, wszRegKeyName + CLSID_STR_LEN, maxLen - CLSID_STR_LEN)) return E_OUTOFMEMORY; - strcatW(wszRegKeyName, wszRegSeparator); strcatW(wszRegKeyName, wszInstanceKeyName); } return S_OK; } +static HKEY open_category_key(const CLSID *clsid) +{ + WCHAR key_name[sizeof(wszInstanceKeyName)/sizeof(WCHAR) + CHARS_IN_GUID-1 + 6 /* strlen("CLSID\") */], *ptr; + HKEY ret; + + strcpyW(key_name, clsid_keyname); + ptr = key_name + strlenW(key_name); + *ptr++ = '\\'; + + if (!StringFromGUID2(clsid, ptr, CHARS_IN_GUID)) + return NULL; + + ptr += strlenW(ptr); + strcpyW(ptr, wszInstanceKeyName); + + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ, &ret) != ERROR_SUCCESS) { + WARN("Could not open %s\n", debugstr_w(key_name)); + return NULL; + } + + return ret; +} + +static HKEY open_special_category_key(const CLSID *clsid, BOOL create) +{ + WCHAR key_name[sizeof(wszActiveMovieKey)/sizeof(WCHAR) + CHARS_IN_GUID-1]; + HKEY ret; + LONG res; + + strcpyW(key_name, wszActiveMovieKey); + if (!StringFromGUID2(clsid, key_name + sizeof(wszActiveMovieKey)/sizeof(WCHAR)-1, CHARS_IN_GUID)) + return NULL; + + if(create) + res = RegCreateKeyW(HKEY_CURRENT_USER, key_name, &ret); + else + res = RegOpenKeyExW(HKEY_CURRENT_USER, key_name, 0, KEY_READ, &ret); + if (res != ERROR_SUCCESS) { + WARN("Could not open %s\n", debugstr_w(key_name)); + return NULL; + } + + return ret; +} + static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS *rgPin) { HKEY hkeyTypes = NULL; @@ -455,9 +506,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( IEnumMoniker **ppEnumMoniker, DWORD dwFlags) { - WCHAR wszRegKey[MAX_PATH]; - HKEY hkey; - HKEY hbasekey; + HKEY hkey, special_hkey = NULL; HRESULT hr; TRACE("(%p)->(%s, %p, %x)\n", iface, debugstr_guid(clsidDeviceClass), ppEnumMoniker, dwFlags); @@ -472,32 +521,29 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( DEVENUM_RegisterLegacyAmFilters(); } - hr = DEVENUM_GetCategoryKey(clsidDeviceClass, &hbasekey, wszRegKey, MAX_PATH); - if (FAILED(hr)) - return hr; - - if (IsEqualGUID(clsidDeviceClass, &CLSID_AudioRendererCategory) || - IsEqualGUID(clsidDeviceClass, &CLSID_AudioInputDeviceCategory) || - IsEqualGUID(clsidDeviceClass, &CLSID_VideoInputDeviceCategory) || - IsEqualGUID(clsidDeviceClass, &CLSID_MidiRendererCategory)) + if (IsSpecialCategory(clsidDeviceClass)) { hr = DEVENUM_CreateSpecialCategories(); if (FAILED(hr)) return hr; - if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS) + + special_hkey = open_special_category_key(clsidDeviceClass, FALSE); + if (!special_hkey) { ERR("Couldn't open registry key for special device: %s\n", debugstr_guid(clsidDeviceClass)); return S_FALSE; } } - else if (RegOpenKeyW(hbasekey, wszRegKey, &hkey) != ERROR_SUCCESS) + + hkey = open_category_key(clsidDeviceClass); + if (!hkey && !special_hkey) { FIXME("Category %s not found\n", debugstr_guid(clsidDeviceClass)); return S_FALSE; } - return DEVENUM_IEnumMoniker_Construct(hkey, ppEnumMoniker); + return DEVENUM_IEnumMoniker_Construct(hkey, special_hkey, ppEnumMoniker); } /********************************************************************** @@ -548,6 +594,44 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory) return res; } +static void register_vfw_codecs(void) +{ + WCHAR avico_clsid_str[CHARS_IN_GUID]; + HKEY basekey, key; + ICINFO icinfo; + DWORD i, res; + + static const WCHAR CLSIDW[] = {'C','L','S','I','D',0}; + static const WCHAR FccHandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; + static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; + + StringFromGUID2(&CLSID_AVICo, avico_clsid_str, sizeof(avico_clsid_str)/sizeof(WCHAR)); + + basekey = open_special_category_key(&CLSID_VideoCompressorCategory, TRUE); + if(!basekey) { + ERR("Could not create key\n"); + return; + } + + for(i=0; ICInfo(FCC('v','i','d','c'), i, &icinfo); i++) { + WCHAR fcc_str[5] = {LOBYTE(LOWORD(icinfo.fccHandler)), HIBYTE(LOWORD(icinfo.fccHandler)), + LOBYTE(HIWORD(icinfo.fccHandler)), HIBYTE(HIWORD(icinfo.fccHandler))}; + + res = RegCreateKeyW(basekey, fcc_str, &key); + if(res != ERROR_SUCCESS) + continue; + + RegSetValueExW(key, CLSIDW, 0, REG_SZ, (const BYTE*)avico_clsid_str, sizeof(avico_clsid_str)); + RegSetValueExW(key, FccHandlerW, 0, REG_SZ, (const BYTE*)fcc_str, sizeof(fcc_str)); + RegSetValueExW(key, FriendlyNameW, 0, REG_SZ, (const BYTE*)icinfo.szName, (strlenW(icinfo.szName)+1)*sizeof(WCHAR)); + /* FIXME: Set ClassManagerFlags and FilterData values */ + + RegCloseKey(key); + } + + RegCloseKey(basekey); +} + static HANDLE DEVENUM_populate_handle; static const WCHAR DEVENUM_populate_handle_nameW[] = {'_','_','W','I','N','E','_', @@ -598,6 +682,8 @@ static HRESULT DEVENUM_CreateSpecialCategories(void) RegDeleteTreeW(basekey, path); if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_MidiRendererCategory, &basekey, path, MAX_PATH))) RegDeleteTreeW(basekey, path); + if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_VideoCompressorCategory, &basekey, path, MAX_PATH))) + RegDeleteTreeW(basekey, path); rf2.dwVersion = 2; rf2.dwMerit = MERIT_PREFERRED; @@ -877,6 +963,9 @@ static HRESULT DEVENUM_CreateSpecialCategories(void) if (pMapper) IFilterMapper2_Release(pMapper); + + register_vfw_codecs(); + SetEvent(DEVENUM_populate_handle); return res; } diff --git a/reactos/dll/directx/wine/devenum/devenum_classes.idl b/reactos/dll/directx/wine/devenum/devenum_classes.idl index 872291026e8..81052e15825 100644 --- a/reactos/dll/directx/wine/devenum/devenum_classes.idl +++ b/reactos/dll/directx/wine/devenum/devenum_classes.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("System Device Enum"), threading(both), diff --git a/reactos/dll/directx/wine/devenum/devenum_private.h b/reactos/dll/directx/wine/devenum/devenum_private.h index 35d4d46ba90..32e71da6839 100644 --- a/reactos/dll/directx/wine/devenum/devenum_private.h +++ b/reactos/dll/directx/wine/devenum/devenum_private.h @@ -77,7 +77,7 @@ typedef struct } MediaCatMoniker; MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN; -HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker) DECLSPEC_HIDDEN; +HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, HKEY special_hkey, IEnumMoniker ** ppEnumMoniker) DECLSPEC_HIDDEN; extern ClassFactoryImpl DEVENUM_ClassFactory DECLSPEC_HIDDEN; extern ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN; diff --git a/reactos/dll/directx/wine/devenum/mediacatenum.c b/reactos/dll/directx/wine/devenum/mediacatenum.c index 58022096831..3f28d2675cd 100644 --- a/reactos/dll/directx/wine/devenum/mediacatenum.c +++ b/reactos/dll/directx/wine/devenum/mediacatenum.c @@ -32,7 +32,9 @@ typedef struct IEnumMoniker IEnumMoniker_iface; LONG ref; DWORD index; + DWORD subkey_cnt; HKEY hkey; + HKEY special_hkey; } EnumMonikerImpl; typedef struct @@ -714,6 +716,8 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface) if (!ref) { + if(This->special_hkey) + RegCloseKey(This->special_hkey); RegCloseKey(This->hkey); CoTaskMemFree(This); DEVENUM_UnlockModule(); @@ -735,7 +739,12 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, while (fetched < celt) { - res = RegEnumKeyW(This->hkey, This->index, buffer, sizeof(buffer) / sizeof(WCHAR)); + if(This->index+fetched < This->subkey_cnt) + res = RegEnumKeyW(This->hkey, This->index+fetched, buffer, sizeof(buffer) / sizeof(WCHAR)); + else if(This->special_hkey) + res = RegEnumKeyW(This->special_hkey, This->index+fetched-This->subkey_cnt, buffer, sizeof(buffer) / sizeof(WCHAR)); + else + break; if (res != ERROR_SUCCESS) { break; @@ -744,7 +753,8 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, if (!pMoniker) return E_OUTOFMEMORY; - if (RegOpenKeyW(This->hkey, buffer, &pMoniker->hkey) != ERROR_SUCCESS) + if (RegOpenKeyW(This->index+fetched < This->subkey_cnt ? This->hkey : This->special_hkey, + buffer, &pMoniker->hkey) != ERROR_SUCCESS) { IMoniker_Release(&pMoniker->IMoniker_iface); break; @@ -769,17 +779,16 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt) { EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - DWORD subKeys; + DWORD special_subkeys = 0; TRACE("(%p)->(%d)\n", iface, celt); /* Before incrementing, check if there are any more values to run through. Some programs use the Skip() function to get the number of devices */ - if(RegQueryInfoKeyW(This->hkey, NULL, NULL, NULL, &subKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) - { - return S_FALSE; - } - if((This->index + celt) >= subKeys) + if(This->special_hkey) + RegQueryInfoKeyW(This->special_hkey, NULL, NULL, NULL, &special_subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + if((This->index + celt) >= This->subkey_cnt + special_subkeys) { return S_FALSE; } @@ -821,7 +830,7 @@ static const IEnumMonikerVtbl IEnumMoniker_Vtbl = DEVENUM_IEnumMoniker_Clone }; -HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker) +HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, HKEY special_hkey, IEnumMoniker ** ppEnumMoniker) { EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl)); if (!pEnumMoniker) @@ -831,9 +840,14 @@ HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker) pEnumMoniker->ref = 1; pEnumMoniker->index = 0; pEnumMoniker->hkey = hkey; + pEnumMoniker->special_hkey = special_hkey; *ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface; + if(RegQueryInfoKeyW(pEnumMoniker->hkey, NULL, NULL, NULL, &pEnumMoniker->subkey_cnt, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + pEnumMoniker->subkey_cnt = 0; + + DEVENUM_LockModule(); return S_OK; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 6b716b81850..3184ddebe2b 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -34,7 +34,7 @@ reactos/dll/directx/wine/d3dcompiler_43 # Synced to Wine-1.7.17 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-1.7.17 reactos/dll/directx/wine/d3dxof # Synced to Wine-1.7.17 reactos/dll/directx/wine/ddraw # Synced to Wine-1.7.17 -reactos/dll/directx/wine/devenum # Synced to Wine-1.7.1 +reactos/dll/directx/wine/devenum # Synced to Wine-1.7.17 reactos/dll/directx/wine/dinput # Synced to Wine-1.7.1 reactos/dll/directx/wine/dinput8 # Synced to Wine-1.7.1 reactos/dll/directx/wine/dmusic # Synced to Wine-1.7.1