4 * Copyright 2006 Christian Gmeiner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/test.h"
34 /* function pointers */
35 static HMODULE hSetupAPI;
36 static HDEVINFO (WINAPI *pSetupDiCreateDeviceInfoList)(GUID*,HWND);
37 static HDEVINFO (WINAPI *pSetupDiCreateDeviceInfoListExW)(GUID*,HWND,PCWSTR,PVOID);
38 static BOOL (WINAPI *pSetupDiCreateDeviceInterfaceA)(HDEVINFO, PSP_DEVINFO_DATA, const GUID *, PCSTR, DWORD, PSP_DEVICE_INTERFACE_DATA);
39 static BOOL (WINAPI *pSetupDiCallClassInstaller)(DI_FUNCTION, HDEVINFO, PSP_DEVINFO_DATA);
40 static BOOL (WINAPI *pSetupDiDestroyDeviceInfoList)(HDEVINFO);
41 static BOOL (WINAPI *pSetupDiEnumDeviceInfo)(HDEVINFO, DWORD, PSP_DEVINFO_DATA);
42 static BOOL (WINAPI *pSetupDiEnumDeviceInterfaces)(HDEVINFO, PSP_DEVINFO_DATA, const GUID *, DWORD, PSP_DEVICE_INTERFACE_DATA);
43 static BOOL (WINAPI *pSetupDiInstallClassA)(HWND, PCSTR, DWORD, HSPFILEQ);
44 static HKEY (WINAPI *pSetupDiOpenClassRegKeyExA)(GUID*,REGSAM,DWORD,PCSTR,PVOID);
45 static HKEY (WINAPI *pSetupDiOpenDevRegKey)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM);
46 static HKEY (WINAPI *pSetupDiCreateDevRegKeyW)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, HINF, PCWSTR);
47 static BOOL (WINAPI *pSetupDiCreateDeviceInfoA)(HDEVINFO, PCSTR, GUID *, PCSTR, HWND, DWORD, PSP_DEVINFO_DATA);
48 static BOOL (WINAPI *pSetupDiCreateDeviceInfoW)(HDEVINFO, PCWSTR, GUID *, PCWSTR, HWND, DWORD, PSP_DEVINFO_DATA);
49 static BOOL (WINAPI *pSetupDiGetDeviceInstanceIdA)(HDEVINFO, PSP_DEVINFO_DATA, PSTR, DWORD, PDWORD);
50 static BOOL (WINAPI *pSetupDiGetDeviceInterfaceDetailA)(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA);
51 static BOOL (WINAPI *pSetupDiGetDeviceInterfaceDetailW)(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_W, DWORD, PDWORD, PSP_DEVINFO_DATA);
52 static BOOL (WINAPI *pSetupDiRegisterDeviceInfo)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PSP_DETSIG_CMPPROC, PVOID, PSP_DEVINFO_DATA);
53 static HDEVINFO (WINAPI *pSetupDiGetClassDevsA)(CONST GUID *, LPCSTR, HWND, DWORD);
54 static HDEVINFO (WINAPI *pSetupDiGetClassDevsW)(CONST GUID *, LPCWSTR, HWND, DWORD);
55 static BOOL (WINAPI *pSetupDiSetDeviceRegistryPropertyA)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const BYTE *, DWORD);
56 static BOOL (WINAPI *pSetupDiSetDeviceRegistryPropertyW)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const BYTE *, DWORD);
57 static BOOL (WINAPI *pSetupDiGetDeviceRegistryPropertyA)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);
58 static BOOL (WINAPI *pSetupDiGetDeviceRegistryPropertyW)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);
60 /* This is a unique guid for testing purposes */
61 static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
63 static void init_function_pointers(void)
65 hSetupAPI = GetModuleHandleA("setupapi.dll");
67 pSetupDiCreateDeviceInfoA = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoA");
68 pSetupDiCreateDeviceInfoW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoW");
69 pSetupDiCreateDeviceInfoList = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoList");
70 pSetupDiCreateDeviceInfoListExW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoListExW");
71 pSetupDiCreateDeviceInterfaceA = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInterfaceA");
72 pSetupDiDestroyDeviceInfoList = (void *)GetProcAddress(hSetupAPI, "SetupDiDestroyDeviceInfoList");
73 pSetupDiCallClassInstaller = (void *)GetProcAddress(hSetupAPI, "SetupDiCallClassInstaller");
74 pSetupDiEnumDeviceInfo = (void *)GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInfo");
75 pSetupDiEnumDeviceInterfaces = (void *)GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInterfaces");
76 pSetupDiGetDeviceInstanceIdA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceInstanceIdA");
77 pSetupDiGetDeviceInterfaceDetailA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceInterfaceDetailA");
78 pSetupDiGetDeviceInterfaceDetailW = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceInterfaceDetailW");
79 pSetupDiInstallClassA = (void *)GetProcAddress(hSetupAPI, "SetupDiInstallClassA");
80 pSetupDiOpenClassRegKeyExA = (void *)GetProcAddress(hSetupAPI, "SetupDiOpenClassRegKeyExA");
81 pSetupDiOpenDevRegKey = (void *)GetProcAddress(hSetupAPI, "SetupDiOpenDevRegKey");
82 pSetupDiCreateDevRegKeyW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDevRegKeyW");
83 pSetupDiRegisterDeviceInfo = (void *)GetProcAddress(hSetupAPI, "SetupDiRegisterDeviceInfo");
84 pSetupDiGetClassDevsA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetClassDevsA");
85 pSetupDiGetClassDevsW = (void *)GetProcAddress(hSetupAPI, "SetupDiGetClassDevsW");
86 pSetupDiSetDeviceRegistryPropertyA = (void *)GetProcAddress(hSetupAPI, "SetupDiSetDeviceRegistryPropertyA");
87 pSetupDiSetDeviceRegistryPropertyW = (void *)GetProcAddress(hSetupAPI, "SetupDiSetDeviceRegistryPropertyW");
88 pSetupDiGetDeviceRegistryPropertyA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyA");
89 pSetupDiGetDeviceRegistryPropertyW = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyW");
92 static BOOL remove_device(void)
95 SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
98 SetLastError(0xdeadbeef);
99 set = pSetupDiGetClassDevsA(&guid, NULL, 0, 0);
100 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n",
103 SetLastError(0xdeadbeef);
104 ok(pSetupDiEnumDeviceInfo(set, 0, &devInfo),
105 "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError());
107 SetLastError(0xdeadbeef);
108 ret = pSetupDiCallClassInstaller(DIF_REMOVE, set, &devInfo);
110 ok(ret, "SetupDiCallClassInstaller(DIF_REMOVE...) failed: %08x\n", GetLastError());
112 SetLastError(0xdeadbeef);
113 ok(pSetupDiDestroyDeviceInfoList(set),
114 "SetupDiDestroyDeviceInfoList failed: %08x\n", GetLastError());
119 /* RegDeleteTreeW from dlls/advapi32/registry.c */
120 LSTATUS WINAPI devinst_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
123 DWORD dwMaxSubkeyLen, dwMaxValueLen;
124 DWORD dwMaxLen, dwSize;
125 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
130 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
134 /* Get highest length for keys, values */
135 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
136 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
137 if (ret) goto cleanup;
141 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
142 if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
144 /* Name too big: alloc a buffer for it */
145 if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
147 ret = ERROR_NOT_ENOUGH_MEMORY;
153 /* Recursively delete all the subkeys */
157 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
158 NULL, NULL, NULL)) break;
160 ret = devinst_RegDeleteTreeW(hSubKey, lpszName);
161 if (ret) goto cleanup;
165 ret = RegDeleteKeyW(hKey, lpszSubKey);
170 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
171 NULL, NULL, NULL, NULL)) break;
173 ret = RegDeleteValueW(hKey, lpszName);
174 if (ret) goto cleanup;
178 /* Free buffer if allocated */
179 if (lpszName != szNameBuf)
180 HeapFree( GetProcessHeap(), 0, lpszName);
182 RegCloseKey(hSubKey);
186 static void clean_devclass_key(void)
188 static const WCHAR devclass[] = {'S','y','s','t','e','m','\\',
189 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
190 'C','o','n','t','r','o','l','\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\',
191 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
192 '1','1','d','b','-','b','7','0','4','-',
193 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
197 /* Check if we have subkeys as Windows 2000 doesn't delete
198 * the keys under the DeviceClasses key after a SetupDiDestroyDeviceInfoList.
200 RegOpenKeyW(HKEY_LOCAL_MACHINE, devclass, &key);
201 RegQueryInfoKey(key, NULL, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
204 trace("We are most likely on Windows 2000\n");
205 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass);
209 ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, devclass),
210 "Couldn't delete deviceclass key\n");
214 static void test_SetupDiCreateDeviceInfoListEx(void)
219 static CHAR notnull[] = "NotNull";
220 static const WCHAR machine[] = { 'd','u','m','m','y',0 };
222 SetLastError(0xdeadbeef);
223 /* create empty DeviceInfoList, but set Reserved to a value, which is not NULL */
224 devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, notnull);
226 error = GetLastError();
227 if (error == ERROR_CALL_NOT_IMPLEMENTED)
229 skip("SetupDiCreateDeviceInfoListExW is not implemented\n");
232 ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE);
233 ok(error == ERROR_INVALID_PARAMETER, "GetLastError returned wrong value : %d, (expected %d)\n", error, ERROR_INVALID_PARAMETER);
235 SetLastError(0xdeadbeef);
236 /* create empty DeviceInfoList, but set MachineName to something */
237 devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, machine, NULL);
239 error = GetLastError();
240 ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE);
241 ok(error == ERROR_INVALID_MACHINENAME, "GetLastError returned wrong value : %d, (expected %d)\n", error, ERROR_INVALID_MACHINENAME);
243 /* create empty DeviceInfoList */
244 devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
245 ok(devlist && devlist != INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected != %p)\n", devlist, error, INVALID_HANDLE_VALUE);
247 /* destroy DeviceInfoList */
248 ret = pSetupDiDestroyDeviceInfoList(devlist);
249 ok(ret, "SetupDiDestroyDeviceInfoList failed : %d\n", error);
252 static void test_SetupDiOpenClassRegKeyExA(void)
254 static const CHAR guidString[] = "{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
257 /* Check return value for nonexistent key */
258 hkey = pSetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS,
259 DIOCR_INSTALLER, NULL, NULL);
260 ok(hkey == INVALID_HANDLE_VALUE,
261 "returned %p (expected INVALID_HANDLE_VALUE)\n", hkey);
263 /* Test it for a key that exists */
264 hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS);
265 if (hkey != INVALID_HANDLE_VALUE)
268 if (RegCreateKeyA(hkey, guidString, &classKey) == ERROR_SUCCESS)
270 RegCloseKey(classKey);
271 SetLastError(0xdeadbeef);
272 classKey = pSetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS,
273 DIOCR_INSTALLER, NULL, NULL);
274 ok(classKey != INVALID_HANDLE_VALUE,
275 "opening class registry key failed with error %d\n",
277 if (classKey != INVALID_HANDLE_VALUE)
278 RegCloseKey(classKey);
279 RegDeleteKeyA(hkey, guidString);
282 trace("failed to create registry key for test\n");
287 trace("failed to open classes key\n");
290 static void append_str(char **str, const char *data)
293 *str += strlen(*str);
296 static void create_inf_file(LPCSTR filename)
300 DWORD dwNumberOfBytesWritten;
301 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
302 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
304 append_str(&ptr, "[Version]\n");
305 append_str(&ptr, "Signature=\"$Chicago$\"\n");
306 append_str(&ptr, "Class=Bogus\n");
307 append_str(&ptr, "ClassGUID={6a55b5a4-3f65-11db-b704-0011955c2bdb}\n");
308 append_str(&ptr, "[ClassInstall32]\n");
309 append_str(&ptr, "AddReg=BogusClass.NT.AddReg\n");
310 append_str(&ptr, "[BogusClass.NT.AddReg]\n");
311 append_str(&ptr, "HKR,,,,\"Wine test devices\"\n");
313 WriteFile(hf, data, ptr - data, &dwNumberOfBytesWritten, NULL);
317 static void get_temp_filename(LPSTR path)
319 static char curr[MAX_PATH] = { 0 };
324 GetCurrentDirectoryA(MAX_PATH, curr);
325 GetTempFileNameA(curr, "set", 0, temp);
326 ptr = strrchr(temp, '\\');
328 lstrcpyA(path, ptr + 1);
331 static void testInstallClass(void)
333 static const WCHAR classKey[] = {'S','y','s','t','e','m','\\',
334 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
335 'C','o','n','t','r','o','l','\\','C','l','a','s','s','\\',
336 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
337 '1','1','d','b','-','b','7','0','4','-',
338 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
339 static const CHAR classKey_win9x[] =
340 "System\\CurrentControlSet\\Services\\Class\\"
341 "{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
342 static const CHAR bogus_win9x[] =
343 "System\\CurrentControlSet\\Services\\Class\\Bogus";
344 char tmpfile[MAX_PATH];
348 if (!pSetupDiInstallClassA)
350 skip("No SetupDiInstallClassA\n");
355 get_temp_filename(tmpfile + 2);
356 create_inf_file(tmpfile + 2);
358 ret = pSetupDiInstallClassA(NULL, NULL, 0, NULL);
359 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
360 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
361 ret = pSetupDiInstallClassA(NULL, NULL, DI_NOVCP, NULL);
362 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
363 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
364 ret = pSetupDiInstallClassA(NULL, tmpfile + 2, DI_NOVCP, NULL);
365 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
366 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
367 ret = pSetupDiInstallClassA(NULL, tmpfile + 2, 0, NULL);
368 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
369 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
370 /* The next call will succeed. Information is put into the registry but the
371 * location(s) is/are depending on the Windows version.
373 ret = pSetupDiInstallClassA(NULL, tmpfile, 0, NULL);
374 ok(ret, "SetupDiInstallClassA failed: %08x\n", GetLastError());
375 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, classKey_win9x, &hkey))
377 /* We are on win9x */
379 ok(!RegDeleteKeyA(HKEY_LOCAL_MACHINE, classKey_win9x),
380 "Couldn't delete win9x classkey\n");
381 ok(!RegDeleteKeyA(HKEY_LOCAL_MACHINE, bogus_win9x),
382 "Couldn't delete win9x bogus services class\n");
387 ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, classKey),
388 "Couldn't delete NT classkey\n");
393 static void testCreateDeviceInfo(void)
399 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
400 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
401 'E','n','u','m','\\','R','o','o','t','\\',
402 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
404 if (!pSetupDiCreateDeviceInfoList || !pSetupDiEnumDeviceInfo ||
405 !pSetupDiDestroyDeviceInfoList || !pSetupDiCreateDeviceInfoA)
407 skip("No SetupDiCreateDeviceInfoA\n");
410 SetLastError(0xdeadbeef);
411 ret = pSetupDiCreateDeviceInfoA(NULL, NULL, NULL, NULL, NULL, 0, NULL);
412 ok(!ret, "Expected failure\n");
413 ok(GetLastError() == ERROR_INVALID_DEVINST_NAME ||
414 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */ ||
415 GetLastError() == ERROR_INVALID_HANDLE /* Win9x */,
416 "Unexpected last error, got %08x\n", GetLastError());
418 /* If we are running on win9x we should skip these tests. Win95
419 * fails most tests anyway and win98 pops up the "Add New Hardware
422 if (GetLastError() == ERROR_INVALID_HANDLE)
424 skip("We are on win9x where the tests introduce issues\n");
428 SetLastError(0xdeadbeef);
429 ret = pSetupDiCreateDeviceInfoA(NULL, "Root\\LEGACY_BOGUS\\0000", NULL,
430 NULL, NULL, 0, NULL);
431 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
432 "Expected ERROR_INVALID_HANDLEHANDLE, got %08x\n", GetLastError());
433 set = pSetupDiCreateDeviceInfoList(&guid, NULL);
434 ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %08x\n",
438 SP_DEVINFO_DATA devInfo = { 0 };
440 static GUID deadbeef =
441 {0xdeadbeef, 0xdead, 0xbeef, {0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
444 SetLastError(0xdeadbeef);
445 ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", NULL,
446 NULL, NULL, 0, NULL);
447 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
448 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
449 /* We can't add device information to the set with a different GUID */
450 SetLastError(0xdeadbeef);
451 ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000",
452 &deadbeef, NULL, NULL, 0, NULL);
453 ok(!ret && GetLastError() == ERROR_CLASS_MISMATCH,
454 "Expected ERROR_CLASS_MISMATCH, got %08x\n", GetLastError());
455 /* Finally, with all three required parameters, this succeeds: */
456 ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid,
457 NULL, NULL, 0, NULL);
458 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
459 /* This fails because the device ID already exists.. */
460 SetLastError(0xdeadbeef);
461 ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid,
462 NULL, NULL, 0, &devInfo);
463 ok(!ret && GetLastError() == ERROR_DEVINST_ALREADY_EXISTS,
464 "Expected ERROR_DEVINST_ALREADY_EXISTS, got %08x\n", GetLastError());
465 /* whereas this "fails" because cbSize is wrong.. */
466 SetLastError(0xdeadbeef);
467 ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL,
468 DICD_GENERATE_ID, &devInfo);
469 ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
470 "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
471 /* and this finally succeeds. */
472 devInfo.cbSize = sizeof(devInfo);
473 ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL,
474 DICD_GENERATE_ID, &devInfo);
475 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
476 /* There were three devices added, however - the second failure just
477 * resulted in the SP_DEVINFO_DATA not getting copied.
479 SetLastError(0xdeadbeef);
481 while (pSetupDiEnumDeviceInfo(set, i, &devInfo))
483 ok(i == 3, "Expected 3 devices, got %d\n", i);
484 ok(GetLastError() == ERROR_NO_MORE_ITEMS,
485 "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError());
486 pSetupDiDestroyDeviceInfoList(set);
489 /* The bogus registry key shouldn't be there after this test. The only
490 * reasons this key would still be present:
492 * - We are running on Wine which has to be fixed
493 * - We have leftovers from old tests
495 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key);
497 ok(res == ERROR_FILE_NOT_FOUND, "Expected key to not exist\n");
498 if (res == ERROR_SUCCESS)
502 /* Check if we have subkeys */
503 RegQueryInfoKey(key, NULL, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
508 /* Leftovers from old tests */
509 trace("Going to remove %d devices\n", subkeys);
510 for (i = 0; i < subkeys; i++)
514 ret = remove_device();
515 ok(ret, "Expected a device to be removed\n");
520 /* Wine doesn't delete the bogus key itself currently */
521 trace("We are most likely on Wine\n");
522 RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus);
527 static void testGetDeviceInstanceId(void)
531 SP_DEVINFO_DATA devInfo = { 0 };
533 if (!pSetupDiCreateDeviceInfoList || !pSetupDiDestroyDeviceInfoList ||
534 !pSetupDiCreateDeviceInfoA || !pSetupDiGetDeviceInstanceIdA)
536 skip("No SetupDiGetDeviceInstanceIdA\n");
539 SetLastError(0xdeadbeef);
540 ret = pSetupDiGetDeviceInstanceIdA(NULL, NULL, NULL, 0, NULL);
541 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
542 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
543 SetLastError(0xdeadbeef);
544 ret = pSetupDiGetDeviceInstanceIdA(NULL, &devInfo, NULL, 0, NULL);
545 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
546 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
547 set = pSetupDiCreateDeviceInfoList(&guid, NULL);
548 ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %08x\n",
552 char instanceID[MAX_PATH];
555 SetLastError(0xdeadbeef);
556 ret = pSetupDiGetDeviceInstanceIdA(set, NULL, NULL, 0, NULL);
557 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
558 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
559 SetLastError(0xdeadbeef);
560 ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, NULL);
561 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
562 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
563 SetLastError(0xdeadbeef);
564 ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size);
565 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
566 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
567 devInfo.cbSize = sizeof(devInfo);
568 SetLastError(0xdeadbeef);
569 ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size);
570 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
571 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
572 ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid,
573 NULL, NULL, 0, &devInfo);
574 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
575 SetLastError(0xdeadbeef);
576 ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size);
577 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
578 "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError());
579 ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, instanceID,
580 sizeof(instanceID), NULL);
581 ok(ret, "SetupDiGetDeviceInstanceIdA failed: %08x\n", GetLastError());
582 ok(!lstrcmpA(instanceID, "ROOT\\LEGACY_BOGUS\\0000"),
583 "Unexpected instance ID %s\n", instanceID);
584 ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid,
585 NULL, NULL, DICD_GENERATE_ID, &devInfo);
586 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
587 ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, instanceID,
588 sizeof(instanceID), NULL);
589 ok(ret, "SetupDiGetDeviceInstanceIdA failed: %08x\n", GetLastError());
590 ok(!lstrcmpA(instanceID, "ROOT\\LEGACY_BOGUS\\0001"),
591 "Unexpected instance ID %s\n", instanceID);
592 pSetupDiDestroyDeviceInfoList(set);
596 static void testRegisterDeviceInfo(void)
601 SetLastError(0xdeadbeef);
602 ret = pSetupDiRegisterDeviceInfo(NULL, NULL, 0, NULL, NULL, NULL);
603 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
604 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
605 set = pSetupDiCreateDeviceInfoList(&guid, NULL);
606 ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError());
609 SP_DEVINFO_DATA devInfo = { 0 };
611 SetLastError(0xdeadbeef);
612 ret = pSetupDiRegisterDeviceInfo(set, NULL, 0, NULL, NULL, NULL);
613 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
614 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
615 SetLastError(0xdeadbeef);
616 ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL);
617 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
618 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
619 devInfo.cbSize = sizeof(devInfo);
620 SetLastError(0xdeadbeef);
621 ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL);
622 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
623 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
624 ret = pSetupDiCreateDeviceInfoA(set, "USB\\BOGUS\\0000", &guid,
625 NULL, NULL, 0, &devInfo);
626 ok(ret || GetLastError() == ERROR_DEVINST_ALREADY_EXISTS,
627 "SetupDiCreateDeviceInfoA failed: %d\n", GetLastError());
630 /* If it already existed, registering it again will fail */
631 ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL,
633 ok(ret, "SetupDiCreateDeviceInfoA failed: %d\n", GetLastError());
635 /* FIXME: On Win2K+ systems, this is now persisted to registry in
636 * HKLM\System\CCS\Enum\USB\Bogus\0000. I don't check because the
637 * Win9x location is different.
638 * FIXME: the key also becomes undeletable. How to get rid of it?
640 pSetupDiDestroyDeviceInfoList(set);
644 static void testCreateDeviceInterface(void)
649 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
650 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
651 'E','n','u','m','\\','R','o','o','t','\\',
652 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
653 static const WCHAR devclass[] = {'S','y','s','t','e','m','\\',
654 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
655 'C','o','n','t','r','o','l','\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\',
656 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
657 '1','1','d','b','-','b','7','0','4','-',
658 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
660 if (!pSetupDiCreateDeviceInfoList || !pSetupDiDestroyDeviceInfoList ||
661 !pSetupDiCreateDeviceInfoA || !pSetupDiCreateDeviceInterfaceA ||
662 !pSetupDiEnumDeviceInterfaces)
664 skip("No SetupDiCreateDeviceInterfaceA\n");
667 SetLastError(0xdeadbeef);
668 ret = pSetupDiCreateDeviceInterfaceA(NULL, NULL, NULL, NULL, 0, NULL);
669 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
670 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
671 SetLastError(0xdeadbeef);
672 ret = pSetupDiCreateDeviceInterfaceA(NULL, NULL, &guid, NULL, 0, NULL);
673 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
674 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
675 set = pSetupDiCreateDeviceInfoList(&guid, NULL);
676 ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError());
679 SP_DEVINFO_DATA devInfo = { 0 };
680 SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData),
684 SetLastError(0xdeadbeef);
685 ret = pSetupDiCreateDeviceInterfaceA(set, NULL, NULL, NULL, 0, NULL);
686 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
687 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
688 SetLastError(0xdeadbeef);
689 ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, NULL, NULL, 0,
691 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
692 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
693 devInfo.cbSize = sizeof(devInfo);
694 ret = pSetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid,
695 NULL, NULL, 0, &devInfo);
696 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
697 SetLastError(0xdeadbeef);
698 ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, NULL, NULL, 0,
700 ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
701 "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
702 ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0,
704 ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError());
705 /* Creating the same interface a second time succeeds */
706 ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0,
708 ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError());
709 ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, "Oogah", 0,
711 ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError());
712 ret = pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, 0,
714 ok(ret, "SetupDiEnumDeviceInterfaces failed: %d\n", GetLastError());
716 while (pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, i,
719 ok(i == 2, "expected 2 interfaces, got %d\n", i);
720 ok(GetLastError() == ERROR_NO_MORE_ITEMS,
721 "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError());
722 ret = pSetupDiDestroyDeviceInfoList(set);
723 ok(ret, "SetupDiDestroyDeviceInfoList failed: %08x\n", GetLastError());
726 /* FIXME: On Wine we still have the bogus entry in Enum\Root and
727 * subkeys, as well as the deviceclass key with subkeys.
728 * Only clean the deviceclass key once Wine if fixed.
730 if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key))
732 /* Wine doesn't delete the information currently */
733 trace("We are most likely on Wine\n");
734 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus);
735 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass);
739 clean_devclass_key();
744 static void testGetDeviceInterfaceDetail(void)
748 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
749 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
750 'E','n','u','m','\\','R','o','o','t','\\',
751 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
752 static const WCHAR devclass[] = {'S','y','s','t','e','m','\\',
753 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
754 'C','o','n','t','r','o','l','\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\',
755 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
756 '1','1','d','b','-','b','7','0','4','-',
757 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
759 if (!pSetupDiCreateDeviceInfoList || !pSetupDiDestroyDeviceInfoList ||
760 !pSetupDiCreateDeviceInfoA || !pSetupDiCreateDeviceInterfaceA ||
761 !pSetupDiGetDeviceInterfaceDetailA)
763 skip("No SetupDiGetDeviceInterfaceDetailA\n");
766 SetLastError(0xdeadbeef);
767 ret = pSetupDiGetDeviceInterfaceDetailA(NULL, NULL, NULL, 0, NULL, NULL);
768 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
769 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
770 set = pSetupDiCreateDeviceInfoList(&guid, NULL);
771 ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError());
774 SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
775 SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData),
780 SetLastError(0xdeadbeef);
781 ret = pSetupDiGetDeviceInterfaceDetailA(set, NULL, NULL, 0, NULL,
783 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
784 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
785 ret = pSetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid,
786 NULL, NULL, 0, &devInfo);
787 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
788 SetLastError(0xdeadbeef);
789 ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0,
791 ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError());
792 SetLastError(0xdeadbeef);
793 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL,
795 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
796 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
797 SetLastError(0xdeadbeef);
798 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL,
800 ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
801 "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
802 SetLastError(0xdeadbeef);
803 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL,
805 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
806 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
807 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
809 static const char path[] =
810 "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
811 static const char path_w2k[] =
812 "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\";
813 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
814 SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail =
815 (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)buf;
816 DWORD expectedsize = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) + sizeof(WCHAR)*(1 + strlen(path));
819 SetLastError(0xdeadbeef);
820 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail,
822 ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
823 "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
824 detail->cbSize = size;
825 SetLastError(0xdeadbeef);
826 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail,
828 ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
829 "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
830 detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
831 SetLastError(0xdeadbeef);
832 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail,
834 ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
835 "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
836 /* Windows 2000 and up check for the exact size. Win9x returns ERROR_INVALID_PARAMETER
837 * on every call (so doesn't get here) and NT4 doesn't have this function.
839 detail->cbSize = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath[1]);
840 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail,
842 ok(ret, "SetupDiGetDeviceInterfaceDetailA failed: %d\n",
844 ok(!lstrcmpiA(path, detail->DevicePath) ||
845 !lstrcmpiA(path_w2k, detail->DevicePath), "Unexpected path %s\n",
847 /* Check SetupDiGetDeviceInterfaceDetailW */
848 if (pSetupDiGetDeviceInterfaceDetailW)
850 ret = pSetupDiGetDeviceInterfaceDetailW(set, &interfaceData, NULL, 0, &size, NULL);
851 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
852 "Expected ERROR_INSUFFICIENT_BUFFER, got error code: %d\n", GetLastError());
853 ok(expectedsize == size ||
854 (expectedsize + sizeof(WCHAR)) == size /* W2K adds a backslash */,
855 "SetupDiGetDeviceInterfaceDetailW returned wrong reqsize, got %d\n",
859 skip("SetupDiGetDeviceInterfaceDetailW is not available\n");
861 HeapFree(GetProcessHeap(), 0, buf);
863 pSetupDiDestroyDeviceInfoList(set);
866 /* FIXME: On Wine we still have the bogus entry in Enum\Root and
867 * subkeys, as well as the deviceclass key with subkeys.
868 * Only do the RegDeleteKey, once Wine is fixed.
870 if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key))
872 /* Wine doesn't delete the information currently */
873 trace("We are most likely on Wine\n");
874 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus);
875 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass);
879 clean_devclass_key();
884 static void testDevRegKey(void)
886 static const WCHAR classKey[] = {'S','y','s','t','e','m','\\',
887 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
888 'C','o','n','t','r','o','l','\\','C','l','a','s','s','\\',
889 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
890 '1','1','d','b','-','b','7','0','4','-',
891 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
892 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
893 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
894 'E','n','u','m','\\','R','o','o','t','\\',
895 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
900 SetLastError(0xdeadbeef);
901 key = pSetupDiCreateDevRegKeyW(NULL, NULL, 0, 0, 0, NULL, NULL);
902 ok(key == INVALID_HANDLE_VALUE,
903 "Expected INVALID_HANDLE_VALUE, got %p\n", key);
904 ok(GetLastError() == ERROR_INVALID_HANDLE,
905 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
907 set = pSetupDiCreateDeviceInfoList(&guid, NULL);
908 ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError());
911 SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
914 /* The device info key shouldn't be there */
915 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key);
916 ok(res != ERROR_SUCCESS, "Expected key to not exist\n");
918 /* Create the device information */
919 ret = pSetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid,
920 NULL, NULL, 0, &devInfo);
921 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
922 /* The device info key should have been created */
923 ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key),
924 "Expected registry key to exist\n");
926 SetLastError(0xdeadbeef);
927 key = pSetupDiOpenDevRegKey(NULL, NULL, 0, 0, 0, 0);
928 ok(!key || key == INVALID_HANDLE_VALUE,
929 "Expected INVALID_HANDLE_VALUE or a NULL key (NT4)\n");
930 ok(GetLastError() == ERROR_INVALID_HANDLE,
931 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
932 SetLastError(0xdeadbeef);
933 key = pSetupDiOpenDevRegKey(set, NULL, 0, 0, 0, 0);
934 ok(key == INVALID_HANDLE_VALUE &&
935 GetLastError() == ERROR_INVALID_PARAMETER,
936 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
937 SetLastError(0xdeadbeef);
938 key = pSetupDiOpenDevRegKey(set, &devInfo, 0, 0, 0, 0);
939 ok(key == INVALID_HANDLE_VALUE &&
940 GetLastError() == ERROR_INVALID_FLAGS,
941 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
942 SetLastError(0xdeadbeef);
943 key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, 0, 0);
944 ok(key == INVALID_HANDLE_VALUE &&
945 GetLastError() == ERROR_INVALID_FLAGS,
946 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
947 SetLastError(0xdeadbeef);
948 key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0,
950 ok(key == INVALID_HANDLE_VALUE &&
951 GetLastError() == ERROR_INVALID_FLAGS,
952 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
953 SetLastError(0xdeadbeef);
954 key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0,
956 ok(key == INVALID_HANDLE_VALUE &&
957 GetLastError() == ERROR_DEVINFO_NOT_REGISTERED,
958 "Expected ERROR_DEVINFO_NOT_REGISTERED, got %08x\n", GetLastError());
959 SetLastError(0xdeadbeef);
960 ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL);
961 ok(ret, "SetupDiRegisterDeviceInfo failed: %08x\n", GetLastError());
962 SetLastError(0xdeadbeef);
963 key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0,
965 /* The software key isn't created by default */
967 ok(key == INVALID_HANDLE_VALUE &&
968 GetLastError() == ERROR_KEY_DOES_NOT_EXIST,
969 "Expected ERROR_KEY_DOES_NOT_EXIST, got %08x\n", GetLastError());
970 SetLastError(0xdeadbeef);
971 key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0,
974 ok(key == INVALID_HANDLE_VALUE &&
975 GetLastError() == ERROR_KEY_DOES_NOT_EXIST,
976 "Expected ERROR_KEY_DOES_NOT_EXIST, got %08x\n", GetLastError());
977 SetLastError(0xdeadbeef);
978 /* The class key shouldn't be there */
979 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key);
981 ok(res != ERROR_SUCCESS, "Expected key to not exist\n");
983 /* Create the device reg key */
984 key = pSetupDiCreateDevRegKeyW(set, &devInfo, DICS_FLAG_GLOBAL, 0,
985 DIREG_DRV, NULL, NULL);
986 ok(key != INVALID_HANDLE_VALUE, "SetupDiCreateDevRegKey failed: %08x\n",
989 /* The class key should have been created */
990 ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key),
991 "Expected registry key to exist\n");
993 SetLastError(0xdeadbeef);
994 key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0,
997 ok(key == INVALID_HANDLE_VALUE &&
998 (GetLastError() == ERROR_INVALID_DATA ||
999 GetLastError() == ERROR_ACCESS_DENIED), /* win2k3 */
1000 "Expected ERROR_INVALID_DATA or ERROR_ACCESS_DENIED, got %08x\n", GetLastError());
1001 key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0,
1002 DIREG_DRV, KEY_READ);
1003 ok(key != INVALID_HANDLE_VALUE, "SetupDiOpenDevRegKey failed: %08x\n",
1005 pSetupDiDestroyDeviceInfoList(set);
1008 ret = remove_device();
1010 ok(ret, "Expected the device to be removed: %08x\n", GetLastError());
1012 /* FIXME: Only do the RegDeleteKey, once Wine is fixed */
1015 /* Wine doesn't delete the information currently */
1016 trace("We are most likely on Wine\n");
1017 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus);
1018 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, classKey);
1022 /* There should only be a class key entry, so a simple
1023 * RegDeleteKey should work
1025 * This could fail if it's the first time for this new test
1026 * after running the old tests.
1028 ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, classKey),
1029 "Couldn't delete classkey\n");
1034 static void testRegisterAndGetDetail(void)
1038 SP_DEVINFO_DATA devInfo = { sizeof(SP_DEVINFO_DATA), { 0 } };
1039 SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData), { 0 } };
1041 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
1042 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
1043 'E','n','u','m','\\','R','o','o','t','\\',
1044 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
1045 static const WCHAR devclass[] = {'S','y','s','t','e','m','\\',
1046 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
1047 'C','o','n','t','r','o','l','\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\',
1048 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
1049 '1','1','d','b','-','b','7','0','4','-',
1050 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
1052 SetLastError(0xdeadbeef);
1053 set = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_ALLCLASSES);
1054 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n",
1057 SetLastError(0xdeadbeef);
1058 ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, 0,
1059 DICD_GENERATE_ID, &devInfo);
1060 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
1061 SetLastError(0xdeadbeef);
1062 ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0, &interfaceData);
1063 ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError());
1064 SetLastError(0xdeadbeef);
1065 ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL);
1066 ok(ret, "SetupDiRegisterDeviceInfo failed: %08x\n", GetLastError());
1068 pSetupDiDestroyDeviceInfoList(set);
1070 SetLastError(0xdeadbeef);
1071 set = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE);
1072 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n",
1075 SetLastError(0xdeadbeef);
1076 ret = pSetupDiEnumDeviceInterfaces(set, NULL, &guid, 0, &interfaceData);
1077 ok(ret, "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError());
1078 SetLastError(0xdeadbeef);
1079 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL, 0, &dwSize, NULL);
1080 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1081 "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError());
1082 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1084 static const char path[] =
1085 "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
1086 static const char path_w2k[] =
1087 "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\";
1088 PSP_DEVICE_INTERFACE_DETAIL_DATA_A detail = NULL;
1090 detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)HeapAlloc(GetProcessHeap(), 0, dwSize);
1093 detail->cbSize = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(char);
1094 SetLastError(0xdeadbeef);
1095 ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData,
1096 detail, dwSize, &dwSize, NULL);
1097 ok(ret, "SetupDiGetDeviceInterfaceDetailA failed: %08x\n", GetLastError());
1098 /* FIXME: This one only worked because old data wasn't removed properly. As soon
1099 * as all the tests are cleaned up correctly this has to be (or should be) fixed
1102 ok(!lstrcmpiA(path, detail->DevicePath) ||
1103 !lstrcmpiA(path_w2k, detail->DevicePath), "Unexpected path %s\n",
1104 detail->DevicePath);
1105 HeapFree(GetProcessHeap(), 0, detail);
1109 pSetupDiDestroyDeviceInfoList(set);
1112 ret = remove_device();
1114 ok(ret, "Expected the device to be removed: %08x\n", GetLastError());
1116 /* FIXME: Only do the RegDeleteKey, once Wine is fixed */
1119 /* Wine doesn't delete the information currently */
1120 trace("We are most likely on Wine\n");
1121 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus);
1122 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass);
1126 clean_devclass_key();
1130 static void testDeviceRegistryPropertyA()
1133 SP_DEVINFO_DATA devInfo = { sizeof(SP_DEVINFO_DATA), { 0 } };
1134 CHAR devName[] = "LEGACY_BOGUS";
1135 CHAR friendlyName[] = "Bogus";
1143 static const CHAR bogus[] =
1144 "System\\CurrentControlSet\\Enum\\Root\\LEGACY_BOGUS";
1146 SetLastError(0xdeadbeef);
1147 set = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE);
1148 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n",
1150 SetLastError(0xdeadbeef);
1151 ret = pSetupDiCreateDeviceInfoA(set, devName, &guid, NULL, NULL,
1152 DICD_GENERATE_ID, &devInfo);
1153 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
1154 SetLastError(0xdeadbeef);
1155 ret = pSetupDiSetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, 0);
1156 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
1157 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
1158 SetLastError(0xdeadbeef);
1159 ret = pSetupDiSetDeviceRegistryPropertyA(set, NULL, -1, NULL, 0);
1160 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1161 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1162 SetLastError(0xdeadbeef);
1163 ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, -1, NULL, 0);
1165 ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY,
1166 "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError());
1167 /* GetLastError() returns nonsense in win2k3 */
1168 ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1171 ok(!ret, "Expected failure, got %d\n", ret);
1172 SetLastError(0xdeadbeef);
1173 ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1174 (PBYTE)friendlyName, buflen);
1175 ok(ret, "SetupDiSetDeviceRegistryPropertyA failed: %08x\n", GetLastError());
1176 SetLastError(0xdeadbeef);
1177 ret = pSetupDiGetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, NULL, 0, NULL);
1178 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
1179 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
1180 SetLastError(0xdeadbeef);
1181 ret = pSetupDiGetDeviceRegistryPropertyA(set, NULL, -1, NULL, NULL, 0, NULL);
1182 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1183 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1184 SetLastError(0xdeadbeef);
1185 ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, -1, NULL, NULL, 0, NULL);
1187 ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY,
1188 "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError());
1189 /* GetLastError() returns nonsense in win2k3 */
1190 ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1191 NULL, NULL, buflen, NULL);
1192 ok(!ret, "Expected failure, got %d\n", ret);
1193 SetLastError(0xdeadbeef);
1194 ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1195 NULL, NULL, 0, &size);
1196 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1197 "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError());
1198 ok(buflen == size, "Unexpected size: %d\n", size);
1199 SetLastError(0xdeadbeef);
1200 ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1201 NULL, (PBYTE)buf, buflen, NULL);
1202 ok(ret, "SetupDiGetDeviceRegistryPropertyA failed: %08x\n", GetLastError());
1203 ok(!lstrcmpiA(friendlyName, buf), "Unexpected property\n");
1204 SetLastError(0xdeadbeef);
1205 ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1206 ®Type, (PBYTE)buf, buflen, NULL);
1207 ok(ret, "SetupDiGetDeviceRegistryPropertyA failed: %08x\n", GetLastError());
1208 ok(!lstrcmpiA(friendlyName, buf), "Unexpected value of property\n");
1209 ok(regType == REG_SZ, "Unexpected type of property: %d\n", regType);
1210 SetLastError(0xdeadbeef);
1211 ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1213 ok(ret, "SetupDiSetDeviceRegistryPropertyA failed: %08x\n", GetLastError());
1214 SetLastError(0xdeadbeef);
1215 ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME,
1216 NULL, (PBYTE)buf, buflen, &size);
1218 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
1219 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
1220 pSetupDiDestroyDeviceInfoList(set);
1222 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, bogus, &key);
1224 ok(res == ERROR_FILE_NOT_FOUND, "Expected key to not exist\n");
1225 /* FIXME: Remove when Wine is fixed */
1226 if (res == ERROR_SUCCESS)
1228 /* Wine doesn't delete the information currently */
1229 trace("We are most likely on Wine\n");
1230 RegDeleteKeyA(HKEY_LOCAL_MACHINE, bogus);
1234 static void testDeviceRegistryPropertyW()
1237 SP_DEVINFO_DATA devInfo = { sizeof(SP_DEVINFO_DATA), { 0 } };
1238 WCHAR devName[] = {'L','E','G','A','C','Y','_','B','O','G','U','S',0};
1239 WCHAR friendlyName[] = {'B','o','g','u','s',0};
1241 DWORD buflen = 6 * sizeof(WCHAR);
1247 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
1248 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
1249 'E','n','u','m','\\','R','o','o','t','\\',
1250 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
1252 SetLastError(0xdeadbeef);
1253 set = pSetupDiGetClassDevsW(&guid, NULL, 0, DIGCF_DEVICEINTERFACE);
1254 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsW failed: %08x\n",
1256 SetLastError(0xdeadbeef);
1257 ret = pSetupDiCreateDeviceInfoW(set, devName, &guid, NULL, NULL,
1258 DICD_GENERATE_ID, &devInfo);
1259 ok(ret, "SetupDiCreateDeviceInfoW failed: %08x\n", GetLastError());
1260 SetLastError(0xdeadbeef);
1261 ret = pSetupDiSetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, 0);
1262 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
1263 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
1264 SetLastError(0xdeadbeef);
1265 ret = pSetupDiSetDeviceRegistryPropertyW(set, NULL, -1, NULL, 0);
1266 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1267 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1268 SetLastError(0xdeadbeef);
1269 ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, -1, NULL, 0);
1271 ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY,
1272 "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError());
1273 /* GetLastError() returns nonsense in win2k3 */
1274 ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1277 ok(!ret, "Expected failure, got %d\n", ret);
1278 SetLastError(0xdeadbeef);
1279 ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1280 (PBYTE)friendlyName, buflen);
1281 ok(ret, "SetupDiSetDeviceRegistryPropertyW failed: %08x\n", GetLastError());
1282 SetLastError(0xdeadbeef);
1283 ret = pSetupDiGetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, NULL, 0, NULL);
1284 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
1285 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
1286 SetLastError(0xdeadbeef);
1287 ret = pSetupDiGetDeviceRegistryPropertyW(set, NULL, -1, NULL, NULL, 0, NULL);
1288 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1289 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1290 SetLastError(0xdeadbeef);
1291 ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, -1, NULL, NULL, 0, NULL);
1293 ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY,
1294 "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError());
1295 /* GetLastError() returns nonsense in win2k3 */
1296 ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1297 NULL, NULL, buflen, NULL);
1298 ok(!ret, "Expected failure, got %d\n", ret);
1299 SetLastError(0xdeadbeef);
1300 ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1301 NULL, NULL, 0, &size);
1302 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1303 "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError());
1304 ok(buflen == size, "Unexpected size: %d\n", size);
1305 SetLastError(0xdeadbeef);
1306 ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1307 NULL, (PBYTE)buf, buflen, NULL);
1308 ok(ret, "SetupDiGetDeviceRegistryPropertyW failed: %08x\n", GetLastError());
1309 ok(!lstrcmpiW(friendlyName, buf), "Unexpected property\n");
1310 SetLastError(0xdeadbeef);
1311 ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1312 ®Type, (PBYTE)buf, buflen, NULL);
1313 ok(ret, "SetupDiGetDeviceRegistryPropertyW failed: %08x\n", GetLastError());
1314 ok(!lstrcmpiW(friendlyName, buf), "Unexpected value of property\n");
1315 ok(regType == REG_SZ, "Unexpected type of property: %d\n", regType);
1316 SetLastError(0xdeadbeef);
1317 ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1319 ok(ret, "SetupDiSetDeviceRegistryPropertyW failed: %08x\n", GetLastError());
1320 SetLastError(0xdeadbeef);
1321 ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME,
1322 NULL, (PBYTE)buf, buflen, &size);
1324 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
1325 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
1326 pSetupDiDestroyDeviceInfoList(set);
1328 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key);
1330 ok(res == ERROR_FILE_NOT_FOUND, "Expected key to not exist\n");
1331 /* FIXME: Remove when Wine is fixed */
1332 if (res == ERROR_SUCCESS)
1334 /* Wine doesn't delete the information currently */
1335 trace("We are most likely on Wine\n");
1336 RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus);
1344 init_function_pointers();
1346 /* Win9x/WinMe does things totally different so we skip all the tests
1348 * We don't want to exclude NT4 so hence this check.
1350 SetLastError(0xdeadbeef);
1351 set = pSetupDiGetClassDevsW(NULL, NULL, 0, 0);
1352 if (set == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1354 skip("Win9x/WinMe has totally different behavior\n");
1358 if (pSetupDiCreateDeviceInfoListExW && pSetupDiDestroyDeviceInfoList)
1359 test_SetupDiCreateDeviceInfoListEx();
1361 skip("SetupDiCreateDeviceInfoListExW and/or SetupDiDestroyDeviceInfoList not available\n");
1363 if (pSetupDiOpenClassRegKeyExA)
1364 test_SetupDiOpenClassRegKeyExA();
1366 skip("SetupDiOpenClassRegKeyExA is not available\n");
1369 testCreateDeviceInfo();
1370 testGetDeviceInstanceId();
1371 testRegisterDeviceInfo();
1372 testCreateDeviceInterface();
1373 testGetDeviceInterfaceDetail();
1375 testRegisterAndGetDetail();
1376 testDeviceRegistryPropertyA();
1377 testDeviceRegistryPropertyW();