Module: wine Branch: master Commit: 92be7be48dbff2a28f196bceb087b76dee8b2680 URL: http://source.winehq.org/git/wine.git/?a=commit;h=92be7be48dbff2a28f196bceb0...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Jan 8 14:12:11 2014 +0100
devenum: Enumerate both regular key and special key for special categories.
---
dlls/devenum/createdevenum.c | 66 ++++++++++++++++++++++++++++++++-------- dlls/devenum/devenum_private.h | 2 +- dlls/devenum/mediacatenum.c | 32 +++++++++++++------ 3 files changed, 78 insertions(+), 22 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c index 58fe7a4..baeb91e 100644 --- a/dlls/devenum/createdevenum.c +++ b/dlls/devenum/createdevenum.c @@ -37,7 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum);
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','\', @@ -134,13 +134,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; @@ -466,9 +510,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); @@ -483,29 +525,29 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( DEVENUM_RegisterLegacyAmFilters(); }
- hr = DEVENUM_GetCategoryKey(clsidDeviceClass, &hbasekey, wszRegKey, MAX_PATH); - if (FAILED(hr)) - return hr; - 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); }
/********************************************************************** diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h index 17e89a5..4f14423 100644 --- a/dlls/devenum/devenum_private.h +++ b/dlls/devenum/devenum_private.h @@ -68,7 +68,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/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index 60ba110..ce66711 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -35,7 +35,9 @@ typedef struct IEnumMoniker IEnumMoniker_iface; LONG ref; DWORD index; + DWORD subkey_cnt; HKEY hkey; + HKEY special_hkey; } EnumMonikerImpl;
typedef struct @@ -717,6 +719,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(); @@ -738,7 +742,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; @@ -747,7 +756,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; @@ -772,17 +782,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; } @@ -824,7 +833,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) @@ -834,9 +843,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;