1 /*
2 * Devinst tests
3 *
4 * Copyright 2006 Christian Gmeiner
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winreg.h"
29 #include "guiddef.h"
30 #include "setupapi.h"
31 #include "cfgmgr32.h"
32
33 #include "wine/heap.h"
34 #include "wine/test.h"
35
36 #ifdef __REACTOS__
37 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
38 #endif
39
40 /* This is a unique guid for testing purposes */
41 static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
42 static GUID guid2 = {0x6a55b5a5, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
43
devinst_RegDeleteTreeW(HKEY hKey,LPCWSTR lpszSubKey)44 static LSTATUS devinst_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
45 {
46 LONG ret;
47 DWORD dwMaxSubkeyLen, dwMaxValueLen;
48 DWORD dwMaxLen, dwSize;
49 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
50 HKEY hSubKey = hKey;
51
52 if(lpszSubKey)
53 {
54 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
55 if (ret) return ret;
56 }
57
58 /* Get highest length for keys, values */
59 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
60 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
61 if (ret) goto cleanup;
62
63 dwMaxSubkeyLen++;
64 dwMaxValueLen++;
65 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
66 if (dwMaxLen > ARRAY_SIZE(szNameBuf))
67 {
68 /* Name too big: alloc a buffer for it */
69 if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
70 {
71 ret = ERROR_NOT_ENOUGH_MEMORY;
72 goto cleanup;
73 }
74 }
75
76
77 /* Recursively delete all the subkeys */
78 while (TRUE)
79 {
80 dwSize = dwMaxLen;
81 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
82 NULL, NULL, NULL)) break;
83
84 ret = devinst_RegDeleteTreeW(hSubKey, lpszName);
85 if (ret) goto cleanup;
86 }
87
88 if (lpszSubKey)
89 ret = RegDeleteKeyW(hKey, lpszSubKey);
90 else
91 while (TRUE)
92 {
93 dwSize = dwMaxLen;
94 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
95 NULL, NULL, NULL, NULL)) break;
96
97 ret = RegDeleteValueW(hKey, lpszName);
98 if (ret) goto cleanup;
99 }
100
101 cleanup:
102 /* Free buffer if allocated */
103 if (lpszName != szNameBuf)
104 HeapFree( GetProcessHeap(), 0, lpszName);
105 if(lpszSubKey)
106 RegCloseKey(hSubKey);
107 return ret;
108 }
109
test_create_device_list_ex(void)110 static void test_create_device_list_ex(void)
111 {
112 static const WCHAR machine[] = { 'd','u','m','m','y',0 };
113 static const WCHAR empty[] = { 0 };
114 static char notnull[] = "NotNull";
115 HDEVINFO set;
116 BOOL ret;
117
118 SetLastError(0xdeadbeef);
119 set = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, notnull);
120 ok(set == INVALID_HANDLE_VALUE, "Expected failure.\n");
121 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
122
123 SetLastError(0xdeadbeef);
124 set = SetupDiCreateDeviceInfoListExW(NULL, NULL, machine, NULL);
125 ok(set == INVALID_HANDLE_VALUE, "Expected failure.\n");
126 ok(GetLastError() == ERROR_INVALID_MACHINENAME
127 || GetLastError() == ERROR_MACHINE_UNAVAILABLE
128 || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
129 "Got unexpected error %#x.\n", GetLastError());
130
131 set = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
132 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.", GetLastError());
133
134 ret = SetupDiDestroyDeviceInfoList(set);
135 ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError());
136
137 set = SetupDiCreateDeviceInfoListExW(NULL, NULL, empty, NULL);
138 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.", GetLastError());
139
140 ret = SetupDiDestroyDeviceInfoList(set);
141 ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError());
142 }
143
test_open_class_key(void)144 static void test_open_class_key(void)
145 {
146 static const char guidstr[] = "{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
147 HKEY root_key, class_key;
148 LONG res;
149
150 SetLastError(0xdeadbeef);
151 class_key = SetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS, DIOCR_INSTALLER, NULL, NULL);
152 ok(class_key == INVALID_HANDLE_VALUE, "Expected failure.\n");
153 todo_wine
154 ok(GetLastError() == ERROR_INVALID_CLASS, "Got unexpected error %#x.\n", GetLastError());
155
156 root_key = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS);
157 ok(root_key != INVALID_HANDLE_VALUE, "Failed to open root key, error %#x.\n", GetLastError());
158
159 res = RegCreateKeyA(root_key, guidstr, &class_key);
160 ok(!res, "Failed to create class key, error %#x.\n", GetLastError());
161 RegCloseKey(class_key);
162
163 SetLastError(0xdeadbeef);
164 class_key = SetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS, DIOCR_INSTALLER, NULL, NULL);
165 ok(class_key != INVALID_HANDLE_VALUE, "Failed to open class key, error %#x.\n", GetLastError());
166 RegCloseKey(class_key);
167
168 RegDeleteKeyA(root_key, guidstr);
169 RegCloseKey(root_key);
170 }
171
create_inf_file(LPCSTR filename)172 static void create_inf_file(LPCSTR filename)
173 {
174 DWORD dwNumberOfBytesWritten;
175 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
176 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
177
178 static const char data[] =
179 "[Version]\n"
180 "Signature=\"$Chicago$\"\n"
181 "Class=Bogus\n"
182 "ClassGUID={6a55b5a4-3f65-11db-b704-0011955c2bdb}\n"
183 "[ClassInstall32]\n"
184 "AddReg=BogusClass.NT.AddReg\n"
185 "[BogusClass.NT.AddReg]\n"
186 "HKR,,,,\"Wine test devices\"\n";
187
188 WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL);
189 CloseHandle(hf);
190 }
191
get_temp_filename(LPSTR path)192 static void get_temp_filename(LPSTR path)
193 {
194 static char curr[MAX_PATH] = { 0 };
195 char temp[MAX_PATH];
196 LPSTR ptr;
197
198 if (!*curr)
199 GetCurrentDirectoryA(MAX_PATH, curr);
200 GetTempFileNameA(curr, "set", 0, temp);
201 ptr = strrchr(temp, '\\');
202
203 lstrcpyA(path, ptr + 1);
204 }
205
test_install_class(void)206 static void test_install_class(void)
207 {
208 static const WCHAR classKey[] = {'S','y','s','t','e','m','\\',
209 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
210 'C','o','n','t','r','o','l','\\','C','l','a','s','s','\\',
211 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
212 '1','1','d','b','-','b','7','0','4','-',
213 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
214 char tmpfile[MAX_PATH];
215 BOOL ret;
216
217 tmpfile[0] = '.';
218 tmpfile[1] = '\\';
219 get_temp_filename(tmpfile + 2);
220 create_inf_file(tmpfile + 2);
221
222 ret = SetupDiInstallClassA(NULL, NULL, 0, NULL);
223 ok(!ret, "Expected failure.\n");
224 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
225
226 ret = SetupDiInstallClassA(NULL, NULL, DI_NOVCP, NULL);
227 ok(!ret, "Expected failure.\n");
228 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
229
230 ret = SetupDiInstallClassA(NULL, tmpfile + 2, DI_NOVCP, NULL);
231 ok(!ret, "Expected failure.\n");
232 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
233
234 ret = SetupDiInstallClassA(NULL, tmpfile + 2, 0, NULL);
235 ok(!ret, "Expected failure.\n");
236 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got unexpected error %#x.\n", GetLastError());
237
238 /* The next call will succeed. Information is put into the registry but the
239 * location(s) is/are depending on the Windows version.
240 */
241 ret = SetupDiInstallClassA(NULL, tmpfile, 0, NULL);
242 ok(ret, "Failed to install class, error %#x.\n", GetLastError());
243
244 ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, classKey), "Failed to delete class key, error %u.\n", GetLastError());
245 DeleteFileA(tmpfile);
246 }
247
check_device_info_(int line,HDEVINFO set,int index,const GUID * class,const char * expect_id)248 static void check_device_info_(int line, HDEVINFO set, int index, const GUID *class, const char *expect_id)
249 {
250 SP_DEVINFO_DATA device = {sizeof(device)};
251 char id[50];
252 BOOL ret;
253
254 SetLastError(0xdeadbeef);
255 ret = SetupDiEnumDeviceInfo(set, index, &device);
256 if (expect_id)
257 {
258 ok_(__FILE__, line)(ret, "Got unexpected error %#x.\n", GetLastError());
259 ok_(__FILE__, line)(IsEqualGUID(&device.ClassGuid, class),
260 "Got unexpected class %s.\n", wine_dbgstr_guid(&device.ClassGuid));
261 ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL);
262 ok_(__FILE__, line)(ret, "Got unexpected error %#x.\n", GetLastError());
263 ok_(__FILE__, line)(!strcasecmp(id, expect_id), "Got unexpected id %s.\n", id);
264 }
265 else
266 {
267 ok_(__FILE__, line)(!ret, "Expected failure.\n");
268 ok_(__FILE__, line)(GetLastError() == ERROR_NO_MORE_ITEMS,
269 "Got unexpected error %#x.\n", GetLastError());
270 }
271 }
272 #define check_device_info(a,b,c,d) check_device_info_(__LINE__,a,b,c,d)
273
test_device_info(void)274 static void test_device_info(void)
275 {
276 static const GUID deadbeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
277 SP_DEVINFO_DATA device = {0}, ret_device = {sizeof(ret_device)};
278 char id[MAX_DEVICE_ID_LEN + 2];
279 HDEVINFO set;
280 BOOL ret;
281
282 SetLastError(0xdeadbeef);
283 ret = SetupDiCreateDeviceInfoA(NULL, NULL, NULL, NULL, NULL, 0, NULL);
284 ok(!ret, "Expected failure.\n");
285 ok(GetLastError() == ERROR_INVALID_DEVINST_NAME, "Got unexpected error %#x.\n", GetLastError());
286
287 SetLastError(0xdeadbeef);
288 ret = SetupDiCreateDeviceInfoA(NULL, "Root\\LEGACY_BOGUS\\0000", NULL, NULL, NULL, 0, NULL);
289 ok(!ret, "Expected failure.\n");
290 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
291
292 set = SetupDiCreateDeviceInfoList(&guid, NULL);
293 ok(set != INVALID_HANDLE_VALUE, "Failed to create device info, error %#x.\n", GetLastError());
294
295 SetLastError(0xdeadbeef);
296 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", NULL, NULL, NULL, 0, NULL);
297 ok(!ret, "Expected failure.\n");
298 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
299
300 SetLastError(0xdeadbeef);
301 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &deadbeef, NULL, NULL, 0, NULL);
302 ok(!ret, "Expected failure.\n");
303 ok(GetLastError() == ERROR_CLASS_MISMATCH, "Got unexpected error %#x.\n", GetLastError());
304
305 SetLastError(0xdeadbeef);
306 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &GUID_NULL, NULL, NULL, 0, NULL);
307 ok(!ret, "Expected failure.\n");
308 ok(GetLastError() == ERROR_CLASS_MISMATCH, "Got unexpected error %#x.\n", GetLastError());
309
310 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, NULL);
311 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
312
313 check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0000");
314 check_device_info(set, 1, &guid, NULL);
315
316 SetLastError(0xdeadbeef);
317 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
318 ok(!ret, "Expected failure.\n");
319 ok(GetLastError() == ERROR_DEVINST_ALREADY_EXISTS, "Got unexpected error %#x.\n", GetLastError());
320
321 SetLastError(0xdeadbeef);
322 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &device);
323 ok(!ret, "Expected failure.\n");
324 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError());
325
326 check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0000");
327 check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\0001");
328 check_device_info(set, 2, &guid, NULL);
329
330 device.cbSize = sizeof(device);
331 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0002", &guid, NULL, NULL, 0, &device);
332 ok(ret, "Got unexpected error %#x.\n", GetLastError());
333 ok(IsEqualGUID(&device.ClassGuid, &guid), "Got unexpected class %s.\n",
334 wine_dbgstr_guid(&device.ClassGuid));
335 ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL);
336 ok(ret, "Got unexpected error %#x.\n", GetLastError());
337 ok(!strcmp(id, "ROOT\\LEGACY_BOGUS\\0002"), "Got unexpected id %s.\n", id);
338
339 check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0000");
340 check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\0001");
341 check_device_info(set, 2, &guid, "ROOT\\LEGACY_BOGUS\\0002");
342 check_device_info(set, 3, &guid, NULL);
343
344 ret = SetupDiEnumDeviceInfo(set, 0, &ret_device);
345 ok(ret, "Failed to enumerate devices, error %#x.\n", GetLastError());
346 ret = SetupDiDeleteDeviceInfo(set, &ret_device);
347 ok(ret, "Failed to delete device, error %#x.\n", GetLastError());
348
349 check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0001");
350 check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\0002");
351 check_device_info(set, 2, &guid, NULL);
352
353 ret = SetupDiRemoveDevice(set, &device);
354 ok(ret, "Got unexpected error %#x.\n", GetLastError());
355
356 check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0001");
357
358 ret = SetupDiEnumDeviceInfo(set, 1, &ret_device);
359 ok(ret, "Got unexpected error %#x.\n", GetLastError());
360 ok(IsEqualGUID(&ret_device.ClassGuid, &guid), "Got unexpected class %s.\n",
361 wine_dbgstr_guid(&ret_device.ClassGuid));
362 ret = SetupDiGetDeviceInstanceIdA(set, &ret_device, id, sizeof(id), NULL);
363 ok(!ret, "Expected failure.\n");
364 ok(GetLastError() == ERROR_NO_SUCH_DEVINST, "Got unexpected error %#x.\n", GetLastError());
365 ok(ret_device.DevInst == device.DevInst, "Expected device node %#x, got %#x.\n",
366 device.DevInst, ret_device.DevInst);
367
368 check_device_info(set, 2, &guid, NULL);
369
370 SetupDiDestroyDeviceInfoList(set);
371
372 set = SetupDiCreateDeviceInfoList(NULL, NULL);
373 ok(set != INVALID_HANDLE_VALUE, "Failed to create device info, error %#x.\n", GetLastError());
374
375 SetLastError(0xdeadbeef);
376 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", NULL, NULL, NULL, 0, NULL);
377 ok(!ret, "Expected failure.\n");
378 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
379
380 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\deadbeef", &deadbeef, NULL, NULL, 0, NULL);
381 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
382
383 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\null", &GUID_NULL, NULL, NULL, 0, NULL);
384 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
385
386 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\testguid", &guid, NULL, NULL, 0, NULL);
387 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
388
389 check_device_info(set, 0, &deadbeef, "ROOT\\LEGACY_BOGUS\\deadbeef");
390 check_device_info(set, 1, &GUID_NULL, "ROOT\\LEGACY_BOGUS\\null");
391 check_device_info(set, 2, &guid, "ROOT\\LEGACY_BOGUS\\testguid");
392 check_device_info(set, 3, NULL, NULL);
393
394 memset(id, 'x', sizeof(id));
395 memcpy(id, "Root\\LEGACY_BOGUS\\", strlen("Root\\LEGACY_BOGUS\\"));
396 id[MAX_DEVICE_ID_LEN + 1] = 0;
397 SetLastError(0xdeadbeef);
398 ret = SetupDiCreateDeviceInfoA(set, id, &guid, NULL, NULL, 0, NULL);
399 ok(!ret, "Expected failure.\n");
400 ok(GetLastError() == ERROR_INVALID_DEVINST_NAME, "Got unexpected error %#x.\n", GetLastError());
401
402 id[MAX_DEVICE_ID_LEN] = 0;
403 SetLastError(0xdeadbeef);
404 ret = SetupDiCreateDeviceInfoA(set, id, &guid, NULL, NULL, 0, NULL);
405 ok(!ret, "Expected failure.\n");
406 ok(GetLastError() == ERROR_INVALID_DEVINST_NAME, "Got unexpected error %#x.\n", GetLastError());
407
408 id[MAX_DEVICE_ID_LEN - 1] = 0;
409 ret = SetupDiCreateDeviceInfoA(set, id, &guid, NULL, NULL, 0, NULL);
410 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
411
412 SetupDiDestroyDeviceInfoList(set);
413 }
414
test_get_device_instance_id(void)415 static void test_get_device_instance_id(void)
416 {
417 BOOL ret;
418 HDEVINFO set;
419 SP_DEVINFO_DATA device = {0};
420 char id[200];
421 DWORD size;
422
423 SetLastError(0xdeadbeef);
424 ret = SetupDiGetDeviceInstanceIdA(NULL, NULL, NULL, 0, NULL);
425 ok(!ret, "Expected failure.\n");
426 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
427
428 SetLastError(0xdeadbeef);
429 ret = SetupDiGetDeviceInstanceIdA(NULL, &device, NULL, 0, NULL);
430 ok(!ret, "Expected failure.\n");
431 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
432
433 set = SetupDiCreateDeviceInfoList(&guid, NULL);
434 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
435
436 SetLastError(0xdeadbeef);
437 ret = SetupDiGetDeviceInstanceIdA(set, NULL, NULL, 0, NULL);
438 ok(!ret, "Expected failure.\n");
439 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
440
441 SetLastError(0xdeadbeef);
442 ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, NULL);
443 ok(!ret, "Expected failure.\n");
444 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
445
446 SetLastError(0xdeadbeef);
447 ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, &size);
448 ok(!ret, "Expected failure.\n");
449 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
450
451 device.cbSize = sizeof(device);
452 SetLastError(0xdeadbeef);
453 ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, &size);
454 ok(!ret, "Expected failure.\n");
455 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
456
457 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
458 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
459
460 SetLastError(0xdeadbeef);
461 ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, &size);
462 ok(!ret, "Expected failure.\n");
463 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError());
464
465 ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL);
466 ok(ret, "Failed to get device id, error %#x.\n", GetLastError());
467 ok(!strcmp(id, "ROOT\\LEGACY_BOGUS\\0000"), "Got unexpected id %s.\n", id);
468
469 ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device);
470 ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
471
472 ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL);
473 ok(ret, "Failed to get device id, error %#x.\n", GetLastError());
474 ok(!strcmp(id, "ROOT\\LEGACY_BOGUS\\0001"), "Got unexpected id %s.\n", id);
475
476 SetupDiDestroyDeviceInfoList(set);
477 }
478
test_register_device_info(void)479 static void test_register_device_info(void)
480 {
481 SP_DEVINFO_DATA device = {0};
482 BOOL ret;
483 HDEVINFO set;
484 int i = 0;
485
486 SetLastError(0xdeadbeef);
487 ret = SetupDiRegisterDeviceInfo(NULL, NULL, 0, NULL, NULL, NULL);
488 ok(!ret, "Expected failure.\n");
489 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
490
491 set = SetupDiCreateDeviceInfoList(&guid, NULL);
492 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
493
494 SetLastError(0xdeadbeef);
495 ret = SetupDiRegisterDeviceInfo(set, NULL, 0, NULL, NULL, NULL);
496 ok(!ret, "Expected failure.\n");
497 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
498
499 SetLastError(0xdeadbeef);
500 ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL);
501 ok(!ret, "Expected failure.\n");
502 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
503
504 device.cbSize = sizeof(device);
505 SetLastError(0xdeadbeef);
506 ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL);
507 ok(!ret, "Expected failure.\n");
508 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
509
510 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
511 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
512 ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL);
513 ok(ret, "Failed to register device, error %#x.\n", GetLastError());
514
515 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &device);
516 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
517 ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL);
518 ok(ret, "Failed to register device, error %#x.\n", GetLastError());
519 ret = SetupDiRemoveDevice(set, &device);
520 ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
521
522 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0002", &guid, NULL, NULL, 0, &device);
523 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
524 ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL);
525 ok(ret, "Failed to register device, error %#x.\n", GetLastError());
526 ret = SetupDiDeleteDeviceInfo(set, &device);
527 ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
528
529 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0003", &guid, NULL, NULL, 0, &device);
530 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
531
532 SetupDiDestroyDeviceInfoList(set);
533
534 set = SetupDiGetClassDevsA(&guid, NULL, NULL, 0);
535 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
536
537 check_device_info(set, 0, &guid, "Root\\LEGACY_BOGUS\\0000");
538 check_device_info(set, 1, &guid, "Root\\LEGACY_BOGUS\\0002");
539 check_device_info(set, 2, &guid, NULL);
540
541 while (SetupDiEnumDeviceInfo(set, i++, &device))
542 {
543 ret = SetupDiRemoveDevice(set, &device);
544 ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
545 }
546
547 SetupDiDestroyDeviceInfoList(set);
548 }
549
check_device_iface_(int line,HDEVINFO set,SP_DEVINFO_DATA * device,const GUID * class,int index,DWORD flags,const char * path)550 static void check_device_iface_(int line, HDEVINFO set, SP_DEVINFO_DATA *device,
551 const GUID *class, int index, DWORD flags, const char *path)
552 {
553 char buffer[200];
554 SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)buffer;
555 SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
556 BOOL ret;
557
558 detail->cbSize = sizeof(*detail);
559
560 SetLastError(0xdeadbeef);
561 ret = SetupDiEnumDeviceInterfaces(set, device, class, index, &iface);
562 if (path)
563 {
564 ok_(__FILE__, line)(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError());
565 ok_(__FILE__, line)(IsEqualGUID(&iface.InterfaceClassGuid, class),
566 "Got unexpected class %s.\n", wine_dbgstr_guid(&iface.InterfaceClassGuid));
567 ok_(__FILE__, line)(iface.Flags == flags, "Got unexpected flags %#x.\n", iface.Flags);
568 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, sizeof(buffer), NULL, NULL);
569 ok_(__FILE__, line)(ret, "Failed to get interface detail, error %#x.\n", GetLastError());
570 ok_(__FILE__, line)(!strcasecmp(detail->DevicePath, path), "Got unexpected path %s.\n", detail->DevicePath);
571 }
572 else
573 {
574 ok_(__FILE__, line)(!ret, "Expected failure.\n");
575 ok_(__FILE__, line)(GetLastError() == ERROR_NO_MORE_ITEMS,
576 "Got unexpected error %#x.\n", GetLastError());
577 }
578 }
579 #define check_device_iface(a,b,c,d,e,f) check_device_iface_(__LINE__,a,b,c,d,e,f)
580
test_device_iface(void)581 static void test_device_iface(void)
582 {
583 char buffer[200];
584 SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)buffer;
585 SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
586 SP_DEVINFO_DATA device = {0};
587 BOOL ret;
588 HDEVINFO set;
589
590 detail->cbSize = sizeof(*detail);
591
592 SetLastError(0xdeadbeef);
593 ret = SetupDiCreateDeviceInterfaceA(NULL, NULL, NULL, NULL, 0, NULL);
594 ok(!ret, "Expected failure.\n");
595 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
596
597 SetLastError(0xdeadbeef);
598 ret = SetupDiCreateDeviceInterfaceA(NULL, NULL, &guid, NULL, 0, NULL);
599 ok(!ret, "Expected failure.\n");
600 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
601
602 set = SetupDiCreateDeviceInfoList(&guid, NULL);
603 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
604
605 SetLastError(0xdeadbeef);
606 ret = SetupDiCreateDeviceInterfaceA(set, NULL, NULL, NULL, 0, NULL);
607 ok(!ret, "Expected failure.\n");
608 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
609
610 SetLastError(0xdeadbeef);
611 ret = SetupDiCreateDeviceInterfaceA(set, &device, NULL, NULL, 0, NULL);
612 ok(!ret, "Expected failure.\n");
613 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
614
615 device.cbSize = sizeof(device);
616 ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
617 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
618
619 check_device_iface(set, &device, &guid, 0, 0, NULL);
620
621 SetLastError(0xdeadbeef);
622 ret = SetupDiCreateDeviceInterfaceA(set, &device, NULL, NULL, 0, NULL);
623 ok(!ret, "Expected failure.\n");
624 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError());
625
626 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, NULL);
627 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
628
629 check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}");
630 check_device_iface(set, &device, &guid, 1, 0, NULL);
631
632 /* Creating the same interface a second time succeeds */
633 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, NULL);
634 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
635
636 check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}");
637 check_device_iface(set, &device, &guid, 1, 0, NULL);
638
639 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "Oogah", 0, NULL);
640 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
641
642 check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}");
643 check_device_iface(set, &device, &guid, 1, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\Oogah");
644 check_device_iface(set, &device, &guid, 2, 0, NULL);
645
646 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "test", 0, &iface);
647 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
648 ok(IsEqualGUID(&iface.InterfaceClassGuid, &guid), "Got unexpected class %s.\n",
649 wine_dbgstr_guid(&iface.InterfaceClassGuid));
650 ok(iface.Flags == 0, "Got unexpected flags %#x.\n", iface.Flags);
651 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, sizeof(buffer), NULL, NULL);
652 ok(ret, "Failed to get interface detail, error %#x.\n", GetLastError());
653 ok(!strcasecmp(detail->DevicePath, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\test"),
654 "Got unexpected path %s.\n", detail->DevicePath);
655
656 check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}");
657 check_device_iface(set, &device, &guid, 1, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\Oogah");
658 check_device_iface(set, &device, &guid, 2, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\test");
659 check_device_iface(set, &device, &guid, 3, 0, NULL);
660
661 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid2, NULL, 0, NULL);
662 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
663
664 check_device_iface(set, &device, &guid2, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A5-3F65-11DB-B704-0011955C2BDB}");
665 check_device_iface(set, &device, &guid2, 1, 0, NULL);
666
667 ret = SetupDiEnumDeviceInterfaces(set, &device, &guid2, 0, &iface);
668 ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError());
669 ret = SetupDiRemoveDeviceInterface(set, &iface);
670 ok(ret, "Failed to remove interface, error %#x.\n", GetLastError());
671
672 check_device_iface(set, &device, &guid2, 0, SPINT_REMOVED, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A5-3F65-11DB-B704-0011955C2BDB}");
673 check_device_iface(set, &device, &guid2, 1, 0, NULL);
674
675 ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 0, &iface);
676 ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError());
677 ret = SetupDiDeleteDeviceInterfaceData(set, &iface);
678 ok(ret, "Failed to delete interface, error %#x.\n", GetLastError());
679
680 check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\Oogah");
681 check_device_iface(set, &device, &guid, 1, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\test");
682 check_device_iface(set, &device, &guid, 2, 0, NULL);
683
684 ret = SetupDiDestroyDeviceInfoList(set);
685 ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError());
686 }
687
test_device_iface_detail(void)688 static void test_device_iface_detail(void)
689 {
690 static const char path[] = "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
691 SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail;
692 SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
693 SP_DEVINFO_DATA device = {sizeof(device)};
694 DWORD size = 0, expectedsize;
695 HDEVINFO set;
696 BOOL ret;
697
698 SetLastError(0xdeadbeef);
699 ret = SetupDiGetDeviceInterfaceDetailA(NULL, NULL, NULL, 0, NULL, NULL);
700 ok(!ret, "Expected failure.\n");
701 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
702
703 set = SetupDiCreateDeviceInfoList(&guid, NULL);
704 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
705
706 SetLastError(0xdeadbeef);
707 ret = SetupDiGetDeviceInterfaceDetailA(set, NULL, NULL, 0, NULL, NULL);
708 ok(!ret, "Expected failure.\n");
709 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
710
711 ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
712 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
713
714 SetLastError(0xdeadbeef);
715 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, &iface);
716 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
717
718 SetLastError(0xdeadbeef);
719 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, NULL, 0, NULL, NULL);
720 ok(!ret, "Expected failure.\n");
721 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError());
722
723 SetLastError(0xdeadbeef);
724 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, NULL, 100, NULL, NULL);
725 ok(!ret, "Expected failure.\n");
726 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError());
727
728 SetLastError(0xdeadbeef);
729 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, NULL, 0, &size, NULL);
730 ok(!ret, "Expected failure.\n");
731 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError());
732
733 detail = heap_alloc(size);
734 expectedsize = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath[strlen(path) + 1]);
735
736 detail->cbSize = 0;
737 SetLastError(0xdeadbeef);
738 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, size, &size, NULL);
739 ok(!ret, "Expected failure.\n");
740 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError());
741
742 detail->cbSize = size;
743 SetLastError(0xdeadbeef);
744 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, size, &size, NULL);
745 ok(!ret, "Expected failure.\n");
746 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError());
747
748 detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
749 SetLastError(0xdeadbeef);
750 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, size, &size, NULL);
751 ok(ret, "Failed to get interface detail, error %#x.\n", GetLastError());
752 ok(!strcasecmp(path, detail->DevicePath), "Got unexpected path %s.\n", detail->DevicePath);
753
754 ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, NULL, 0, &size, NULL);
755 ok(!ret, "Expected failure.\n");
756 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError());
757 ok(size == expectedsize, "Got unexpected size %d.\n", size);
758
759 memset(&device, 0, sizeof(device));
760 device.cbSize = sizeof(device);
761 ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, NULL, 0, &size, &device);
762 ok(!ret, "Expected failure.\n");
763 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError());
764 ok(IsEqualGUID(&device.ClassGuid, &guid), "Got unexpected class %s.\n", wine_dbgstr_guid(&device.ClassGuid));
765
766 heap_free(detail);
767 SetupDiDestroyDeviceInfoList(set);
768 }
769
test_device_key(void)770 static void test_device_key(void)
771 {
772 static const WCHAR classKey[] = {'S','y','s','t','e','m','\\',
773 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
774 'C','o','n','t','r','o','l','\\','C','l','a','s','s','\\',
775 '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-',
776 '1','1','d','b','-','b','7','0','4','-',
777 '0','0','1','1','9','5','5','c','2','b','d','b','}',0};
778 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
779 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
780 'E','n','u','m','\\','R','o','o','t','\\',
781 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
782 SP_DEVINFO_DATA device = {sizeof(device)};
783 BOOL ret;
784 HDEVINFO set;
785 HKEY key = NULL;
786 LONG res;
787
788 SetLastError(0xdeadbeef);
789 key = SetupDiCreateDevRegKeyW(NULL, NULL, 0, 0, 0, NULL, NULL);
790 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
791 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
792
793 set = SetupDiCreateDeviceInfoList(&guid, NULL);
794 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
795
796 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key);
797 ok(res != ERROR_SUCCESS, "Key should not exist.\n");
798 RegCloseKey(key);
799
800 ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
801 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
802 ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key), "Key should exist.\n");
803 RegCloseKey(key);
804
805 SetLastError(0xdeadbeef);
806 key = SetupDiOpenDevRegKey(NULL, NULL, 0, 0, 0, 0);
807 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
808 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
809
810 SetLastError(0xdeadbeef);
811 key = SetupDiOpenDevRegKey(set, NULL, 0, 0, 0, 0);
812 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
813 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
814
815 SetLastError(0xdeadbeef);
816 key = SetupDiOpenDevRegKey(set, &device, 0, 0, 0, 0);
817 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
818 ok(GetLastError() == ERROR_INVALID_FLAGS, "Got unexpected error %#x.\n", GetLastError());
819
820 SetLastError(0xdeadbeef);
821 key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, 0, 0);
822 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
823 ok(GetLastError() == ERROR_INVALID_FLAGS, "Got unexpected error %#x.\n", GetLastError());
824
825 SetLastError(0xdeadbeef);
826 key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_BOTH, 0);
827 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
828 ok(GetLastError() == ERROR_INVALID_FLAGS, "Got unexpected error %#x.\n", GetLastError());
829
830 SetLastError(0xdeadbeef);
831 key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0);
832 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
833 ok(GetLastError() == ERROR_DEVINFO_NOT_REGISTERED, "Got unexpected error %#x.\n", GetLastError());
834
835 ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL);
836 ok(ret, "Failed to register device, error %#x.\n", GetLastError());
837
838 SetLastError(0xdeadbeef);
839 key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0);
840 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
841 ok(GetLastError() == ERROR_KEY_DOES_NOT_EXIST, "Got unexpected error %#x.\n", GetLastError());
842
843 SetLastError(0xdeadbeef);
844 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key);
845 todo_wine
846 ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n");
847 RegCloseKey(key);
848
849 key = SetupDiCreateDevRegKeyW(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
850 ok(key != INVALID_HANDLE_VALUE || GetLastError() == ERROR_KEY_DOES_NOT_EXIST, /* Vista+ */
851 "Failed to create device key, error %#x.\n", GetLastError());
852 if (key != INVALID_HANDLE_VALUE)
853 {
854 RegCloseKey(key);
855
856 ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key), "Key should exist.\n");
857 RegCloseKey(key);
858
859 SetLastError(0xdeadbeef);
860 key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0);
861 todo_wine {
862 ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
863 ok(GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_ACCESS_DENIED, /* win2k3 */
864 "Got unexpected error %#x.\n", GetLastError());
865 }
866
867 key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
868 ok(key != INVALID_HANDLE_VALUE, "Failed to open device key, error %#x.\n", GetLastError());
869 RegCloseKey(key);
870 }
871
872 ret = SetupDiRemoveDevice(set, &device);
873 ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
874 SetupDiDestroyDeviceInfoList(set);
875
876 /* remove once Wine is fixed */
877 devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, classKey);
878 }
879
test_register_device_iface(void)880 static void test_register_device_iface(void)
881 {
882 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
883 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
884 'E','n','u','m','\\','R','o','o','t','\\',
885 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
886 SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}, ret_iface = {sizeof(ret_iface)};
887 SP_DEVINFO_DATA device = {sizeof(device)};
888 HDEVINFO set, set2;
889 BOOL ret;
890 HKEY key;
891 LONG res;
892
893 set = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_ALLCLASSES);
894 ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
895
896 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key);
897 ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n");
898
899 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
900 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
901 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, &iface);
902 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
903 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "removed", 0, &iface);
904 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
905 ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "deleted", 0, &iface);
906 ok(ret, "Failed to create interface, error %#x.\n", GetLastError());
907 ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL);
908 ok(ret, "Failed to register device, error %#x.\n", GetLastError());
909
910 ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 1, &iface);
911 ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError());
912 ret = SetupDiRemoveDeviceInterface(set, &iface);
913 ok(ret, "Failed to delete interface, error %#x.\n", GetLastError());
914 ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 2, &iface);
915 ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError());
916 ret = SetupDiDeleteDeviceInterfaceData(set, &iface);
917 ok(ret, "Failed to delete interface, error %#x.\n", GetLastError());
918
919 set2 = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE);
920 ok(set2 != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
921
922 check_device_iface(set2, NULL, &guid, 0, 0, "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}");
923 check_device_iface(set2, NULL, &guid, 1, 0, "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\deleted");
924 check_device_iface(set2, NULL, &guid, 2, 0, NULL);
925
926 ret = SetupDiRemoveDevice(set, &device);
927 ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
928
929 SetupDiDestroyDeviceInfoList(set);
930 SetupDiDestroyDeviceInfoList(set2);
931 }
932
test_registry_property_a(void)933 static void test_registry_property_a(void)
934 {
935 static const CHAR bogus[] = "System\\CurrentControlSet\\Enum\\Root\\LEGACY_BOGUS";
936 SP_DEVINFO_DATA device = {sizeof(device)};
937 CHAR buf[6] = "";
938 DWORD size, type;
939 HDEVINFO set;
940 BOOL ret;
941 LONG res;
942 HKEY key;
943
944 set = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE);
945 ok(set != INVALID_HANDLE_VALUE, "Failed to get device list, error %#x.\n", GetLastError());
946
947 ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device);
948 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
949
950 SetLastError(0xdeadbeef);
951 ret = SetupDiSetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, 0);
952 ok(!ret, "Expected failure.\n");
953 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
954
955 SetLastError(0xdeadbeef);
956 ret = SetupDiSetDeviceRegistryPropertyA(set, NULL, -1, NULL, 0);
957 ok(!ret, "Expected failure.\n");
958 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
959
960 SetLastError(0xdeadbeef);
961 ret = SetupDiSetDeviceRegistryPropertyA(set, &device, -1, NULL, 0);
962 ok(!ret, "Expected failure.\n");
963 todo_wine
964 ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
965
966 ret = SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, 0);
967 todo_wine
968 ok(!ret, "Expected failure.\n");
969 /* GetLastError() returns nonsense in win2k3 */
970
971 SetLastError(0xdeadbeef);
972 ret = SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, (BYTE *)"Bogus", sizeof("Bogus"));
973 ok(ret, "Failed to set property, error %#x.\n", GetLastError());
974
975 SetLastError(0xdeadbeef);
976 ret = SetupDiGetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, NULL, 0, NULL);
977 ok(!ret, "Expected failure.\n");
978 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
979
980 SetLastError(0xdeadbeef);
981 ret = SetupDiGetDeviceRegistryPropertyA(set, NULL, -1, NULL, NULL, 0, NULL);
982 ok(!ret, "Expected failure.\n");
983 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
984
985 SetLastError(0xdeadbeef);
986 ret = SetupDiGetDeviceRegistryPropertyA(set, &device, -1, NULL, NULL, 0, NULL);
987 ok(!ret, "Expected failure.\n");
988 todo_wine
989 ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
990
991 ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, sizeof("Bogus"), NULL);
992 ok(!ret, "Expected failure, got %d\n", ret);
993 /* GetLastError() returns nonsense in win2k3 */
994
995 SetLastError(0xdeadbeef);
996 ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, 0, &size);
997 ok(!ret, "Expected failure.\n");
998 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError());
999 ok(size == sizeof("Bogus"), "Got unexpected size %d.\n", size);
1000
1001 SetLastError(0xdeadbeef);
1002 ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), NULL);
1003 ok(ret, "Failed to get property, error %#x.\n", GetLastError());
1004 ok(!strcmp(buf, "Bogus"), "Got unexpected property %s.\n", buf);
1005
1006 SetLastError(0xdeadbeef);
1007 ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, &type, (BYTE *)buf, sizeof(buf), NULL);
1008 ok(ret, "Failed to get property, error %#x.\n", GetLastError());
1009 ok(!strcmp(buf, "Bogus"), "Got unexpected property %s.\n", buf);
1010 ok(type == REG_SZ, "Got unexpected type %d.\n", type);
1011
1012 SetLastError(0xdeadbeef);
1013 ret = SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, 0);
1014 ok(ret, "Failed to set property, error %#x.\n", GetLastError());
1015
1016 SetLastError(0xdeadbeef);
1017 ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), &size);
1018 todo_wine {
1019 ok(!ret, "Expected failure.\n");
1020 ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
1021 }
1022
1023 ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_HARDWAREID, NULL, NULL, 0, &size);
1024 ok(!ret, "Expected failure.\n");
1025 ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
1026
1027 SetupDiDestroyDeviceInfoList(set);
1028
1029 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, bogus, &key);
1030 ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n");
1031 }
1032
test_registry_property_w(void)1033 static void test_registry_property_w(void)
1034 {
1035 WCHAR friendly_name[] = {'B','o','g','u','s',0};
1036 SP_DEVINFO_DATA device = {sizeof(device)};
1037 WCHAR buf[6] = {0};
1038 DWORD size, type;
1039 HDEVINFO set;
1040 BOOL ret;
1041 LONG res;
1042 HKEY key;
1043 static const WCHAR bogus[] = {'S','y','s','t','e','m','\\',
1044 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
1045 'E','n','u','m','\\','R','o','o','t','\\',
1046 'L','E','G','A','C','Y','_','B','O','G','U','S',0};
1047
1048 set = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE);
1049 ok(set != INVALID_HANDLE_VALUE, "Failed to get device list, error %#x.\n", GetLastError());
1050
1051 ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device);
1052 ok(ret, "Failed to create device, error %#x.\n", GetLastError());
1053
1054 SetLastError(0xdeadbeef);
1055 ret = SetupDiSetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, 0);
1056 ok(!ret, "Expected failure.\n");
1057 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
1058
1059 SetLastError(0xdeadbeef);
1060 ret = SetupDiSetDeviceRegistryPropertyW(set, NULL, -1, NULL, 0);
1061 ok(!ret, "Expected failure.\n");
1062 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
1063
1064 SetLastError(0xdeadbeef);
1065 ret = SetupDiSetDeviceRegistryPropertyW(set, &device, -1, NULL, 0);
1066 ok(!ret, "Expected failure.\n");
1067 todo_wine
1068 ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
1069
1070 ret = SetupDiSetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, 0);
1071 todo_wine
1072 ok(!ret, "Expected failure.\n");
1073 /* GetLastError() returns nonsense in win2k3 */
1074
1075 SetLastError(0xdeadbeef);
1076 ret = SetupDiSetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, (BYTE *)friendly_name, sizeof(friendly_name));
1077 ok(ret, "Failed to set property, error %#x.\n", GetLastError());
1078
1079 SetLastError(0xdeadbeef);
1080 ret = SetupDiGetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, NULL, 0, NULL);
1081 ok(!ret, "Expected failure.\n");
1082 ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError());
1083
1084 SetLastError(0xdeadbeef);
1085 ret = SetupDiGetDeviceRegistryPropertyW(set, NULL, -1, NULL, NULL, 0, NULL);
1086 ok(!ret, "Expected failure.\n");
1087 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError());
1088
1089 SetLastError(0xdeadbeef);
1090 ret = SetupDiGetDeviceRegistryPropertyW(set, &device, -1, NULL, NULL, 0, NULL);
1091 ok(!ret, "Expected failure.\n");
1092 todo_wine
1093 ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
1094
1095 ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, sizeof(buf), NULL);
1096 ok(!ret, "Expected failure.\n");
1097 /* GetLastError() returns nonsense in win2k3 */
1098
1099 SetLastError(0xdeadbeef);
1100 ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, 0, &size);
1101 ok(!ret, "Expected failure.\n");
1102 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError());
1103 ok(size == sizeof(friendly_name), "Got unexpected size %d.\n", size);
1104
1105 SetLastError(0xdeadbeef);
1106 ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), NULL);
1107 ok(ret, "Failed to get property, error %#x.\n", GetLastError());
1108 ok(!lstrcmpW(buf, friendly_name), "Got unexpected property %s.\n", wine_dbgstr_w(buf));
1109
1110 SetLastError(0xdeadbeef);
1111 ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, &type, (BYTE *)buf, sizeof(buf), NULL);
1112 ok(ret, "Failed to get property, error %#x.\n", GetLastError());
1113 ok(!lstrcmpW(buf, friendly_name), "Got unexpected property %s.\n", wine_dbgstr_w(buf));
1114 ok(type == REG_SZ, "Got unexpected type %d.\n", type);
1115
1116 SetLastError(0xdeadbeef);
1117 ret = SetupDiSetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, 0);
1118 ok(ret, "Failed to set property, error %#x.\n", GetLastError());
1119
1120 SetLastError(0xdeadbeef);
1121 ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), &size);
1122 todo_wine {
1123 ok(!ret, "Expected failure.\n");
1124 ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
1125 }
1126
1127 ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_HARDWAREID, NULL, NULL, 0, &size);
1128 ok(!ret, "Expected failure.\n");
1129 ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
1130
1131 SetupDiDestroyDeviceInfoList(set);
1132
1133 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key);
1134 ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n");
1135 }
1136
test_get_inf_class(void)1137 static void test_get_inf_class(void)
1138 {
1139 static const char inffile[] = "winetest.inf";
1140 static const char content[] = "[Version]\r\n\r\n";
1141 static const char* signatures[] = {"\"$CHICAGO$\"", "\"$Windows NT$\""};
1142
1143 char cn[MAX_PATH];
1144 char filename[MAX_PATH];
1145 DWORD count;
1146 BOOL retval;
1147 GUID guid;
1148 HANDLE h;
1149 int i;
1150
1151 GetTempPathA(MAX_PATH, filename);
1152 strcat(filename, inffile);
1153 DeleteFileA(filename);
1154
1155 /* not existing file */
1156 SetLastError(0xdeadbeef);
1157 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
1158 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1159 ok(ERROR_FILE_NOT_FOUND == GetLastError(),
1160 "expected error ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1161
1162 /* missing file wins against other invalid parameter */
1163 SetLastError(0xdeadbeef);
1164 retval = SetupDiGetINFClassA(filename, NULL, cn, MAX_PATH, &count);
1165 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1166 ok(ERROR_FILE_NOT_FOUND == GetLastError(),
1167 "expected error ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1168
1169 SetLastError(0xdeadbeef);
1170 retval = SetupDiGetINFClassA(filename, &guid, NULL, MAX_PATH, &count);
1171 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1172 ok(ERROR_FILE_NOT_FOUND == GetLastError(),
1173 "expected error ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1174
1175 SetLastError(0xdeadbeef);
1176 retval = SetupDiGetINFClassA(filename, &guid, cn, 0, &count);
1177 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1178 ok(ERROR_FILE_NOT_FOUND == GetLastError(),
1179 "expected error ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1180
1181 SetLastError(0xdeadbeef);
1182 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, NULL);
1183 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1184 ok(ERROR_FILE_NOT_FOUND == GetLastError(),
1185 "expected error ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1186
1187 /* test file content */
1188 h = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1189 FILE_ATTRIBUTE_NORMAL, NULL);
1190 ok(h != INVALID_HANDLE_VALUE, "Failed to create file, error %#x.\n", GetLastError());
1191 CloseHandle(h);
1192
1193 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
1194 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1195
1196 for(i=0; i < ARRAY_SIZE(signatures); i++)
1197 {
1198 trace("testing signature %s\n", signatures[i]);
1199 h = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1200 FILE_ATTRIBUTE_NORMAL, NULL);
1201 ok(h != INVALID_HANDLE_VALUE, "Failed to create file, error %#x.\n", GetLastError());
1202 WriteFile(h, content, sizeof(content), &count, NULL);
1203 CloseHandle(h);
1204
1205 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
1206 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1207
1208 WritePrivateProfileStringA("Version", "Signature", signatures[i], filename);
1209
1210 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
1211 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1212
1213 WritePrivateProfileStringA("Version", "Class", "WINE", filename);
1214
1215 count = 0xdeadbeef;
1216 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
1217 ok(retval, "expected SetupDiGetINFClassA to succeed! error %u\n", GetLastError());
1218 ok(count == 5, "expected count==5, got %u\n", count);
1219
1220 count = 0xdeadbeef;
1221 retval = SetupDiGetINFClassA(filename, &guid, cn, 5, &count);
1222 ok(retval, "expected SetupDiGetINFClassA to succeed! error %u\n", GetLastError());
1223 ok(count == 5, "expected count==5, got %u\n", count);
1224
1225 count = 0xdeadbeef;
1226 SetLastError(0xdeadbeef);
1227 retval = SetupDiGetINFClassA(filename, &guid, cn, 4, &count);
1228 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1229 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1230 "expected error ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
1231 ok(count == 5, "expected count==5, got %u\n", count);
1232
1233 /* invalid parameter */
1234 SetLastError(0xdeadbeef);
1235 retval = SetupDiGetINFClassA(NULL, &guid, cn, MAX_PATH, &count);
1236 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1237 ok(ERROR_INVALID_PARAMETER == GetLastError(),
1238 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1239
1240 SetLastError(0xdeadbeef);
1241 retval = SetupDiGetINFClassA(filename, NULL, cn, MAX_PATH, &count);
1242 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1243 ok(ERROR_INVALID_PARAMETER == GetLastError(),
1244 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1245
1246 SetLastError(0xdeadbeef);
1247 retval = SetupDiGetINFClassA(filename, &guid, NULL, MAX_PATH, &count);
1248 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1249 ok(ERROR_INVALID_PARAMETER == GetLastError(),
1250 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1251
1252 SetLastError(0xdeadbeef);
1253 retval = SetupDiGetINFClassA(filename, &guid, cn, 0, &count);
1254 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1255 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_INVALID_PARAMETER /* 2k3+ */,
1256 "Got unexpected error %#x.\n", GetLastError());
1257
1258 DeleteFileA(filename);
1259
1260 WritePrivateProfileStringA("Version", "Signature", signatures[i], filename);
1261 WritePrivateProfileStringA("Version", "ClassGUID", "WINE", filename);
1262
1263 SetLastError(0xdeadbeef);
1264 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
1265 ok(!retval, "expected SetupDiGetINFClassA to fail!\n");
1266 ok(GetLastError() == RPC_S_INVALID_STRING_UUID || GetLastError() == ERROR_INVALID_PARAMETER /* 7+ */,
1267 "Got unexpected error %#x.\n", GetLastError());
1268
1269 /* network adapter guid */
1270 WritePrivateProfileStringA("Version", "ClassGUID",
1271 "{4d36e972-e325-11ce-bfc1-08002be10318}", filename);
1272
1273 /* this test succeeds only if the guid is known to the system */
1274 count = 0xdeadbeef;
1275 retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
1276 ok(retval, "expected SetupDiGetINFClassA to succeed! error %u\n", GetLastError());
1277 todo_wine
1278 ok(count == 4, "expected count==4, got %u(%s)\n", count, cn);
1279
1280 DeleteFileA(filename);
1281 }
1282 }
1283
test_devnode(void)1284 static void test_devnode(void)
1285 {
1286 HDEVINFO set;
1287 SP_DEVINFO_DATA device = { sizeof(SP_DEVINFO_DATA) };
1288 char buffer[50];
1289 DWORD ret;
1290
1291 set = SetupDiGetClassDevsA(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE);
1292 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError());
1293 ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL,
1294 NULL, 0, &device);
1295 ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError());
1296
1297 ret = CM_Get_Device_IDA(device.DevInst, buffer, sizeof(buffer), 0);
1298 ok(!ret, "got %#x\n", ret);
1299 ok(!strcmp(buffer, "ROOT\\LEGACY_BOGUS\\0000"), "got %s\n", buffer);
1300
1301 SetupDiDestroyDeviceInfoList(set);
1302 }
1303
test_device_interface_key(void)1304 static void test_device_interface_key(void)
1305 {
1306 const char keypath[] = "System\\CurrentControlSet\\Control\\DeviceClasses\\"
1307 "{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\"
1308 "##?#ROOT#LEGACY_BOGUS#0001#{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
1309 SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
1310 SP_DEVINFO_DATA devinfo = { sizeof(devinfo) };
1311 HKEY parent, key, dikey;
1312 char buffer[5];
1313 HDEVINFO set;
1314 LONG sz, ret;
1315
1316 set = SetupDiGetClassDevsA(NULL, NULL, 0, DIGCF_ALLCLASSES);
1317 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError());
1318
1319 ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &devinfo);
1320 ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError());
1321
1322 ret = SetupDiCreateDeviceInterfaceA(set, &devinfo, &guid, NULL, 0, &iface);
1323 ok(ret, "SetupDiCreateDeviceInterface failed: %#x\n", GetLastError());
1324
1325 ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &parent);
1326 ok(!ret, "failed to open device parent key: %u\n", ret);
1327
1328 ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
1329 ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
1330
1331 dikey = SetupDiCreateDeviceInterfaceRegKeyA(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL);
1332 ok(dikey != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
1333
1334 ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
1335 ok(!ret, "key should exist: %u\n", ret);
1336
1337 ret = RegSetValueA(key, NULL, REG_SZ, "test", 5);
1338 sz = sizeof(buffer);
1339 ret = RegQueryValueA(dikey, NULL, buffer, &sz);
1340 ok(!ret, "RegQueryValue failed: %u\n", ret);
1341 ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer);
1342
1343 RegCloseKey(dikey);
1344 RegCloseKey(key);
1345
1346 ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0);
1347 ok(ret, "got error %u\n", GetLastError());
1348
1349 ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
1350 ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
1351
1352 RegCloseKey(parent);
1353 SetupDiRemoveDeviceInterface(set, &iface);
1354 SetupDiRemoveDevice(set, &devinfo);
1355 SetupDiDestroyDeviceInfoList(set);
1356 }
1357
testSetupDiGetClassDevsA(void)1358 static void testSetupDiGetClassDevsA(void)
1359 {
1360 static GUID displayguid = {0x4d36e968, 0xe325, 0x11ce, {0xbf,0xc1,0x08,0x00,0x2b,0xe1,0x03,0x18}};
1361 SP_DEVINFO_DATA devinfo;
1362 DISPLAY_DEVICEA disp;
1363 HDEVINFO set;
1364 BOOL ret;
1365
1366 disp.cb = sizeof(disp);
1367 ok(EnumDisplayDevicesA(NULL, 0, &disp, 0), "EnumDisplayDevices failed: %08x\n", GetLastError());
1368
1369 SetLastError(0xdeadbeef);
1370 set = SetupDiGetClassDevsA(&displayguid, disp.DeviceID, 0, 0);
1371 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", GetLastError());
1372
1373 devinfo.cbSize = sizeof(devinfo);
1374 ret = SetupDiEnumDeviceInfo(set, 0, &devinfo);
1375 ok(ret, "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError());
1376
1377 SetupDiDestroyDeviceInfoList(set);
1378 }
1379
START_TEST(devinst)1380 START_TEST(devinst)
1381 {
1382 HKEY hkey;
1383
1384 if ((hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS)) == INVALID_HANDLE_VALUE)
1385 {
1386 skip("needs admin rights\n");
1387 return;
1388 }
1389 RegCloseKey(hkey);
1390
1391 test_create_device_list_ex();
1392 test_open_class_key();
1393 test_install_class();
1394 test_device_info();
1395 test_get_device_instance_id();
1396 test_register_device_info();
1397 test_device_iface();
1398 test_device_iface_detail();
1399 test_device_key();
1400 test_register_device_iface();
1401 test_registry_property_a();
1402 test_registry_property_w();
1403 test_get_inf_class();
1404 testSetupDiGetClassDevsA();
1405 test_devnode();
1406 test_device_interface_key();
1407 }
1408