Hi
My work on the still image system for wine has highlighted a bug in setupapi's SetupDiOpenClassRegKeyExW(). In short, the registry keys for device classes have the form
HKEY_LOCAL_MACHINE\System\CurrentControlSet\ Class{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
while wine incorrectly tries to open HKEY_LOCAL_MACHINE\System\CurrentControlSet\ Class\xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ie. no curly braced around the guid. And in addition it incorrectly returns FALSE for a return type of HKEY (instead of INVALID_HANDLE_VALUE).
I've submitted a test and patch to wine-patches 7 times now, and received very little feedback, which I've always followed.
If this is how difficult it is to submit a patch, no wonder I hear people complaining about how wine doesn't have enough developers. How are you ever going to accept my still image code, which is 4000+ lines long and growing, when you can't accept a simple 182 line long patch?
Normally I'm very patient - but this is ridiculous.
I'm attaching my latest patch and would appreciate any comments.
Thank you Damjan
__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
--- a/dlls/setupapi/tests/Makefile.in 2006-07-10 18:01:08.000000000 +0200 +++ b/dlls/setupapi/tests/Makefile.in 2006-08-31 21:29:12.000000000 +0200 @@ -3,7 +3,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ TESTDLL = setupapi.dll -IMPORTS = setupapi kernel32 +IMPORTS = setupapi kernel32 advapi32 rpcrt4
CTESTS = \ devinst.c \ --- a/dlls/setupapi/devinst.c 2006-08-28 20:35:44.000000000 +0200 +++ b/dlls/setupapi/devinst.c 2006-08-31 22:27:19.000000000 +0200 @@ -1413,6 +1413,7 @@ PVOID Reserved) { LPWSTR lpGuidString; + LPWSTR lpBracedGuidString; HKEY hClassesKey; HKEY hClassKey; LPCWSTR lpKeyName; @@ -1453,21 +1454,30 @@ if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK) { RegCloseKey(hClassesKey); - return FALSE; + return INVALID_HANDLE_VALUE; }
+ lpBracedGuidString = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, + (1 + strlenW(lpGuidString) + 1 + 1) * sizeof(WCHAR)); + lpBracedGuidString[0] = (WCHAR) '{'; + memcpy(&lpBracedGuidString[1], lpGuidString, + strlenW(lpGuidString) * sizeof(WCHAR)); + lpBracedGuidString[1 + strlenW(lpGuidString)] = (WCHAR) '}'; + lpBracedGuidString[1 + strlenW(lpGuidString) + 1] = (WCHAR) 0; + RpcStringFreeW(&lpGuidString); + if (RegOpenKeyExW(hClassesKey, - lpGuidString, + lpBracedGuidString, 0, KEY_ALL_ACCESS, &hClassKey)) { - RpcStringFreeW(&lpGuidString); + RpcStringFreeW(&lpBracedGuidString); RegCloseKey(hClassesKey); - return FALSE; + return INVALID_HANDLE_VALUE; }
- RpcStringFreeW(&lpGuidString); + RpcStringFreeW(&lpBracedGuidString); RegCloseKey(hClassesKey);
return hClassKey; --- a/dlls/setupapi/tests/devinst.c 2006-08-28 20:35:53.000000000 +0200 +++ b/dlls/setupapi/tests/devinst.c 2006-08-31 22:14:36.000000000 +0200 @@ -26,6 +26,7 @@ #include "wingdi.h" #include "winuser.h" #include "winreg.h" +#include "rpc.h" #include "setupapi.h"
#include "wine/test.h" @@ -34,6 +35,7 @@ static HMODULE hSetupAPI; static HDEVINFO (WINAPI *pSetupDiCreateDeviceInfoListExW)(GUID*,HWND,PCWSTR,PVOID); static BOOL (WINAPI *pSetupDiDestroyDeviceInfoList)(HDEVINFO); +static HKEY (WINAPI *pSetupDiOpenClassRegKeyExW)(GUID*,REGSAM,DWORD,PCWSTR,PVOID);
static void init_function_pointers(void) { @@ -43,6 +45,7 @@ { pSetupDiCreateDeviceInfoListExW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoListExW"); pSetupDiDestroyDeviceInfoList = (void *)GetProcAddress(hSetupAPI, "SetupDiDestroyDeviceInfoList"); + pSetupDiOpenClassRegKeyExW = (void *)GetProcAddress(hSetupAPI, "SetupDiOpenClassRegKeyExW"); } }
@@ -79,6 +82,86 @@ ok(ret, "SetupDiDestroyDeviceInfoList failed : %ld\n", error); }
+static void test_SetupDiOpenClassRegKeyExW() +{ + GUID guid; + RPC_STATUS rpcStatus; + HKEY hkey; + WCHAR *unbracedGuid; + WCHAR *bracedGuid; + + rpcStatus = UuidCreate(&guid); + if (rpcStatus != RPC_S_OK) + { + ok(FALSE, "failed to generate test guid, error %ld", rpcStatus); + return; + } + + /* Check return value for non-existant key */ + hkey = pSetupDiOpenClassRegKeyExW(&guid, KEY_ALL_ACCESS, + DIOCR_INSTALLER, NULL, NULL); + ok(hkey == INVALID_HANDLE_VALUE, + "invalid return value %p from SetupDiOpenClassRegKeyExW " + "for non-existant key, expected %p\n", hkey, INVALID_HANDLE_VALUE); + + rpcStatus = UuidToStringW(&guid, &unbracedGuid); + if (rpcStatus != RPC_S_OK) + { + ok(FALSE, "failed to get string form of guid, error %ld", rpcStatus); + return; + } + + bracedGuid = HeapAlloc(GetProcessHeap(), 0, + (lstrlenW(unbracedGuid) + 3) * sizeof(WCHAR)); + if (bracedGuid != NULL) + { + HKEY classesKey; + + bracedGuid[0] = (WCHAR) '{'; + memcpy(&bracedGuid[1], unbracedGuid, + lstrlenW(unbracedGuid) * sizeof(WCHAR)); + bracedGuid[1 + lstrlenW(unbracedGuid)] = (WCHAR) '}'; + bracedGuid[1 + lstrlenW(unbracedGuid) + 1] = (WCHAR) 0; + + SetLastError(0xdeadbeef); + classesKey = pSetupDiOpenClassRegKeyExW(NULL, KEY_ALL_ACCESS, + DIOCR_INSTALLER, NULL, NULL); + ok(classesKey != INVALID_HANDLE_VALUE, + "failed to open the device classes registry key: error %ld\n", + GetLastError()); + if (classesKey != INVALID_HANDLE_VALUE) + { + DWORD ret; + HKEY classKey; + ret = RegCreateKeyW(classesKey, bracedGuid, &classKey); + if (ret == ERROR_SUCCESS) + { + RegCloseKey(classKey); + SetLastError(0xdeadbeef); + classKey = pSetupDiOpenClassRegKeyExW(&guid, KEY_ALL_ACCESS, + DIOCR_INSTALLER, NULL, NULL); + ok(classKey != INVALID_HANDLE_VALUE, + "failed opening class key, error %ld\n", GetLastError()); + ret = RegCloseKey(classKey); + ok(ret == ERROR_SUCCESS, + "failed closing class key, error %ld\n", ret); + + RegDeleteKeyW(classesKey, bracedGuid); + } + else + ok(FALSE, "failed creating device key: error %ld\n", ret); + + RegCloseKey(classesKey); + } + + HeapFree(GetProcessHeap(), 0, bracedGuid); + } + else + ok(FALSE, "failed to allocate memory for braced guid\n"); + + RpcStringFreeW(&unbracedGuid); +} + START_TEST(devinst) { init_function_pointers(); @@ -88,5 +171,10 @@ if (pSetupDiCreateDeviceInfoListExW && pSetupDiDestroyDeviceInfoList) test_SetupDiCreateDeviceInfoListEx(); else - trace("Needed calls not all available, skipping tests.\n"); + trace("Needed calls for SetupDiCreateDeviceInfoListEx not all available, skipping test.\n"); + + if (pSetupDiOpenClassRegKeyExW) + test_SetupDiOpenClassRegKeyExW(); + else + trace("Needed call for SetupDiOpenClassRegKeyExW not available, skipping test.\n"); }