Jacek Caban : devenum: Enumerate both regular key and special key for special categories.
Alexandre Julliard
julliard at winehq.org
Wed Jan 8 13:41:34 CST 2014
Module: wine
Branch: master
Commit: 92be7be48dbff2a28f196bceb087b76dee8b2680
URL: http://source.winehq.org/git/wine.git/?a=commit;h=92be7be48dbff2a28f196bceb087b76dee8b2680
Author: Jacek Caban <jacek at 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;
More information about the wine-cvs
mailing list