2 * Unit tests for setupapi.dll query functions
4 * Copyright (C) 2006 James Hawkins
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
24 #include "wine/test.h"
26 static CHAR CURR_DIR
[MAX_PATH
];
27 static CHAR WIN_DIR
[MAX_PATH
];
29 static void get_directories(void)
33 GetCurrentDirectoryA(MAX_PATH
, CURR_DIR
);
34 len
= lstrlenA(CURR_DIR
);
36 if(len
&& (CURR_DIR
[len
-1] == '\\'))
39 GetWindowsDirectoryA(WIN_DIR
, MAX_PATH
);
40 len
= lstrlenA(WIN_DIR
);
42 if (len
&& (WIN_DIR
[len
-1] == '\\'))
46 static const char inf_data1
[] =
48 "Signature=\"$Chicago$\"\n"
50 "[SourceDisksNames]\n"
51 "2 = %SrcDiskName%, LANCOM\\LANtools\\lanconf.cab\n"
52 "[SourceDisksFiles]\n"
55 "DefaultDestDir = 24, %DefaultDest%\n"
58 "DefaultDest = LANCOM\n"
59 "SrcDiskName = \"LANCOM Software CD\"\n";
61 static const char inf_data2
[] =
63 "sp1qfe\\bitsinst.exe=250B3702C7CCD7C2F9E4DAA1555C933E,000600060A28062C,27136,SP1QFE\n"
64 "sp1qfe\\bitsprx2.dll=4EBEA67F4BB4EB402E725CA7CA2857AE,000600060A280621,7680,SP1QFE\n"
65 "sp1qfe\\bitsprx3.dll=C788A1D9330DA011EF25E95D3BC7BDE5,000600060A280621,7168,SP1QFE\n"
66 "sp1qfe\\qmgr.dll=696AC82FB290A03F205901442E0E9589,000600060A280621,361984,SP1QFE\n"
67 "sp1qfe\\qmgrprxy.dll=8B5848144829E1BC985EA4C3D8CA7E3F,000600060A280621,17408,SP1QFE\n"
68 "sp1qfe\\winhttp.dll=3EC6F518114606CA59D4160322077437,000500010A280615,331776,SP1QFE\n"
69 "sp1qfe\\xpob2res.dll=DB83156B9F496F20D1EA70E4ABEC0166,000500010A280622,158720,SP1QFE\n";
71 static const char inf_data3
[] =
73 "Signature = \"$Windows NT$\"\n"
75 "CopyAlways.Windir.files = 10\n"
76 "[CopyAlways.Windir.Files]\n"
77 "WindowsCodecs.dll\n";
79 static const char inf_data4
[] =
81 "Signature = \"$Windows NT$\"\n"
82 "[CopyAlways.System32.Files]\n"
83 "WindowsCodecs.dll\n";
85 static const char inf_data5
[] =
87 "Signature = \"$Windows NT$\"\n"
89 "DefaultDestDir = 11\n"
90 "CopyAlways.Windir.files = 10\n"
91 "[CopyAlways.Windir.Files]\n"
92 "WindowsCodecs.dll\n";
94 static const char inf_data6
[] =
96 "Signature = \"$Windows NT$\"\n"
98 "DefaultDestDir = 10\n"
99 "[CopyAlways.Windir.Files]\n"
100 "WindowsCodecs.dll\n";
102 static BOOL
create_inf_file(LPSTR filename
, const char *data
, DWORD size
)
105 DWORD dwNumberOfBytesWritten
;
106 HANDLE hf
= CreateFileA(filename
, GENERIC_WRITE
, 0, NULL
,
107 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
108 if (hf
== INVALID_HANDLE_VALUE
) return FALSE
;
109 ret
= WriteFile(hf
, data
, size
, &dwNumberOfBytesWritten
, NULL
);
114 static BOOL
check_info_filename(PSP_INF_INFORMATION info
, LPSTR test
)
120 if (!SetupQueryInfFileInformationA(info
, 0, NULL
, 0, &size
))
123 filename
= HeapAlloc(GetProcessHeap(), 0, size
);
127 SetupQueryInfFileInformationA(info
, 0, filename
, size
, &size
);
129 if (!lstrcmpiA(test
, filename
))
132 HeapFree(GetProcessHeap(), 0, filename
);
136 static PSP_INF_INFORMATION
alloc_inf_info(LPCSTR filename
, DWORD search
, PDWORD size
)
138 PSP_INF_INFORMATION info
;
141 ret
= SetupGetInfInformationA(filename
, search
, NULL
, 0, size
);
145 info
= HeapAlloc(GetProcessHeap(), 0, *size
);
149 static void test_SetupGetInfInformation(void)
151 PSP_INF_INFORMATION info
;
152 CHAR inf_filename
[MAX_PATH
];
153 CHAR inf_one
[MAX_PATH
], inf_two
[MAX_PATH
];
159 lstrcpyA(inf_filename
, CURR_DIR
);
160 lstrcatA(inf_filename
, "\\");
161 lstrcatA(inf_filename
, "test.inf");
163 /* try an invalid inf handle */
165 SetLastError(0xbeefcafe);
166 ret
= SetupGetInfInformationA(NULL
, INFINFO_INF_SPEC_IS_HINF
, NULL
, 0, &size
);
167 ok(ret
== FALSE
, "Expected SetupGetInfInformation to fail\n");
168 ok(GetLastError() == ERROR_INVALID_HANDLE
||
169 broken(GetLastError() == ERROR_BAD_PATHNAME
) || /* win95 */
170 broken(GetLastError() == ERROR_FILE_NOT_FOUND
) || /* win98 */
171 broken(GetLastError() == ERROR_PATH_NOT_FOUND
) || /* NT4 */
172 broken(GetLastError() == ERROR_INVALID_NAME
) || /* win2k */
173 broken(GetLastError() == ERROR_GENERAL_SYNTAX
), /* another win2k / winMe */
174 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
175 ok(size
== 0xdeadbeef, "Expected size to remain unchanged\n");
177 /* try an invalid inf filename */
178 /* do not use NULL as absolute inf filename on win9x/winMe (crash) */
179 if ((GetLastError() != ERROR_BAD_PATHNAME
) && /* win95 */
180 (GetLastError() != ERROR_FILE_NOT_FOUND
) && /* win98 */
181 (GetLastError() != ERROR_GENERAL_SYNTAX
)) /* winMe */
184 SetLastError(0xbeefcafe);
185 ret
= SetupGetInfInformationA(NULL
, INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, 0, &size
);
186 ok(ret
== FALSE
, "Expected SetupGetInfInformation to fail\n");
187 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
188 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
189 ok(size
== 0xdeadbeef, "Expected size to remain unchanged\n");
192 create_inf_file(inf_filename
, inf_data1
, sizeof(inf_data1
) - 1);
194 /* try an invalid search flag */
196 SetLastError(0xbeefcafe);
197 ret
= SetupGetInfInformationA(inf_filename
, -1, NULL
, 0, &size
);
198 ok(ret
== FALSE
, "Expected SetupGetInfInformation to fail\n");
199 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
200 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
201 ok(size
== 0xdeadbeef, "Expected size to remain unchanged\n");
203 /* try a nonexistent inf file */
205 SetLastError(0xbeefcafe);
206 ret
= SetupGetInfInformationA("idontexist", INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, 0, &size
);
207 ok(ret
== FALSE
, "Expected SetupGetInfInformation to fail\n");
208 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
209 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
210 ok(size
== 0xdeadbeef, "Expected size to remain unchanged\n");
212 /* successfully open the inf file */
214 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, 0, &size
);
215 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed\n");
216 ok(size
!= 0xdeadbeef, "Expected a valid size on return\n");
218 /* set ReturnBuffer to NULL and ReturnBufferSize to non-zero value 'size' */
219 SetLastError(0xbeefcafe);
220 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, size
, &size
);
221 ok(ret
== FALSE
, "Expected SetupGetInfInformation to fail\n");
222 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
223 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
225 /* set ReturnBuffer to NULL and ReturnBufferSize to non-zero value 'size-1' */
226 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, size
-1, &size
);
227 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed\n");
229 /* some tests for behaviour with a NULL RequiredSize pointer */
230 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, 0, NULL
);
231 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed\n");
232 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, size
- 1, NULL
);
233 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed\n");
234 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, NULL
, size
, NULL
);
235 ok(ret
== FALSE
, "Expected SetupGetInfInformation to fail\n");
237 info
= HeapAlloc(GetProcessHeap(), 0, size
);
239 /* try valid ReturnBuffer but too small size */
240 SetLastError(0xbeefcafe);
241 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, info
, size
- 1, &size
);
242 ok(ret
== FALSE
, "Expected SetupGetInfInformation to fail\n");
243 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
244 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
246 /* successfully get the inf information */
247 ret
= SetupGetInfInformationA(inf_filename
, INFINFO_INF_NAME_IS_ABSOLUTE
, info
, size
, &size
);
248 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed\n");
249 ok(check_info_filename(info
, inf_filename
), "Expected returned filename to be equal\n");
251 HeapFree(GetProcessHeap(), 0, info
);
253 /* try the INFINFO_INF_SPEC_IS_HINF search flag */
254 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
255 info
= alloc_inf_info(hinf
, INFINFO_INF_SPEC_IS_HINF
, &size
);
256 ret
= SetupGetInfInformationA(hinf
, INFINFO_INF_SPEC_IS_HINF
, info
, size
, &size
);
257 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed\n");
258 ok(check_info_filename(info
, inf_filename
), "Expected returned filename to be equal\n");
259 SetupCloseInfFile(hinf
);
261 lstrcpyA(inf_two
, WIN_DIR
);
262 lstrcatA(inf_two
, "\\system32\\");
263 lstrcatA(inf_two
, "test.inf");
264 ret
= create_inf_file(inf_two
, inf_data1
, sizeof(inf_data1
) - 1);
265 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
267 skip("need admin rights\n");
270 ok(ret
, "can't create inf file %u\n", GetLastError());
272 HeapFree(GetProcessHeap(), 0, info
);
273 info
= alloc_inf_info("test.inf", INFINFO_DEFAULT_SEARCH
, &size
);
275 /* check if system32 is searched for inf */
276 ret
= SetupGetInfInformationA("test.inf", INFINFO_DEFAULT_SEARCH
, info
, size
, &size
);
277 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
278 revfile
= inf_one
; /* Vista */
282 lstrcpyA(inf_one
, WIN_DIR
);
283 lstrcatA(inf_one
, "\\inf\\");
284 lstrcatA(inf_one
, "test.inf");
285 create_inf_file(inf_one
, inf_data1
, sizeof(inf_data1
) - 1);
287 HeapFree(GetProcessHeap(), 0, info
);
288 info
= alloc_inf_info("test.inf", INFINFO_DEFAULT_SEARCH
, &size
);
290 /* test the INFINFO_DEFAULT_SEARCH search flag */
291 ret
= SetupGetInfInformationA("test.inf", INFINFO_DEFAULT_SEARCH
, info
, size
, &size
);
292 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed: %d\n", GetLastError());
293 ok(check_info_filename(info
, inf_one
), "Expected returned filename to be equal\n");
295 HeapFree(GetProcessHeap(), 0, info
);
296 info
= alloc_inf_info("test.inf", INFINFO_REVERSE_DEFAULT_SEARCH
, &size
);
298 /* test the INFINFO_REVERSE_DEFAULT_SEARCH search flag */
299 ret
= SetupGetInfInformationA("test.inf", INFINFO_REVERSE_DEFAULT_SEARCH
, info
, size
, &size
);
300 ok(ret
== TRUE
, "Expected SetupGetInfInformation to succeed\n");
301 ok(check_info_filename(info
, revfile
), "Expected returned filename to be equal\n");
304 HeapFree(GetProcessHeap(), 0, info
);
305 DeleteFileA(inf_filename
);
306 DeleteFileA(inf_one
);
307 DeleteFileA(inf_two
);
310 static void test_SetupGetSourceFileLocation(void)
312 char buffer
[MAX_PATH
] = "not empty", inf_filename
[MAX_PATH
];
314 DWORD required
, error
;
318 lstrcpyA(inf_filename
, CURR_DIR
);
319 lstrcatA(inf_filename
, "\\");
320 lstrcatA(inf_filename
, "test.inf");
322 create_inf_file(inf_filename
, inf_data1
, sizeof(inf_data1
) - 1);
324 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
325 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
330 ret
= SetupGetSourceFileLocationA(hinf
, NULL
, "lanconf.exe", &source_id
, buffer
, sizeof(buffer
), &required
);
331 ok(ret
, "SetupGetSourceFileLocation failed\n");
333 ok(required
== 1, "unexpected required size: %d\n", required
);
334 ok(source_id
== 2, "unexpected source id: %d\n", source_id
);
335 ok(!lstrcmpA("", buffer
), "unexpected result string: %s\n", buffer
);
337 SetupCloseInfFile(hinf
);
338 DeleteFileA(inf_filename
);
340 create_inf_file(inf_filename
, inf_data2
, sizeof(inf_data2
) - 1);
342 SetLastError(0xdeadbeef);
343 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
344 error
= GetLastError();
345 ok(hinf
== INVALID_HANDLE_VALUE
, "could open inf file\n");
346 ok(error
== ERROR_WRONG_INF_STYLE
, "got wrong error: %d\n", error
);
348 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_OLDNT
, NULL
);
349 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
351 ret
= SetupGetSourceFileLocationA(hinf
, NULL
, "", &source_id
, buffer
, sizeof(buffer
), &required
);
352 ok(!ret
, "SetupGetSourceFileLocation succeeded\n");
354 SetupCloseInfFile(hinf
);
355 DeleteFileA(inf_filename
);
358 static void test_SetupGetSourceInfo(void)
360 char buffer
[MAX_PATH
], inf_filename
[MAX_PATH
];
365 lstrcpyA(inf_filename
, CURR_DIR
);
366 lstrcatA(inf_filename
, "\\");
367 lstrcatA(inf_filename
, "test.inf");
369 create_inf_file(inf_filename
, inf_data1
, sizeof(inf_data1
) - 1);
371 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
372 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
376 ret
= SetupGetSourceInfoA(hinf
, 2, SRCINFO_PATH
, buffer
, sizeof(buffer
), &required
);
377 ok(ret
, "SetupGetSourceInfoA failed\n");
379 ok(required
== 1, "unexpected required size: %d\n", required
);
380 ok(!lstrcmpA("", buffer
), "unexpected result string: %s\n", buffer
);
385 ret
= SetupGetSourceInfoA(hinf
, 2, SRCINFO_TAGFILE
, buffer
, sizeof(buffer
), &required
);
386 ok(ret
, "SetupGetSourceInfoA failed\n");
388 ok(required
== 28, "unexpected required size: %d\n", required
);
389 ok(!lstrcmpA("LANCOM\\LANtools\\lanconf.cab", buffer
), "unexpected result string: %s\n", buffer
);
394 ret
= SetupGetSourceInfoA(hinf
, 2, SRCINFO_DESCRIPTION
, buffer
, sizeof(buffer
), &required
);
395 ok(ret
, "SetupGetSourceInfoA failed\n");
397 ok(required
== 19, "unexpected required size: %d\n", required
);
398 ok(!lstrcmpA("LANCOM Software CD", buffer
), "unexpected result string: %s\n", buffer
);
400 SetupCloseInfFile(hinf
);
401 DeleteFileA(inf_filename
);
404 static void test_SetupGetTargetPath(void)
406 char buffer
[MAX_PATH
], inf_filename
[MAX_PATH
];
407 char destfile
[MAX_PATH
];
413 lstrcpyA(inf_filename
, CURR_DIR
);
414 lstrcatA(inf_filename
, "\\");
415 lstrcatA(inf_filename
, "test.inf");
417 create_inf_file(inf_filename
, inf_data1
, sizeof(inf_data1
) - 1);
419 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
420 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
423 ctx
.CurrentInf
= hinf
;
429 ret
= SetupGetTargetPathA(hinf
, &ctx
, NULL
, buffer
, sizeof(buffer
), &required
);
430 ok(ret
, "SetupGetTargetPathA failed\n");
431 ok(required
== 10, "unexpected required size: %d\n", required
);
432 /* Retrieve the system drive from the windows directory.
433 * (%SystemDrive% is not available on Win9x)
435 lstrcpyA(destfile
, WIN_DIR
);
437 lstrcatA(destfile
, "LANCOM");
438 ok(!lstrcmpiA(destfile
, buffer
), "unexpected result string: %s\n", buffer
);
440 SetupCloseInfFile(hinf
);
441 DeleteFileA(inf_filename
);
443 create_inf_file(inf_filename
, inf_data3
, sizeof(inf_data3
) - 1);
445 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
446 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
450 ret
= SetupGetTargetPathA(hinf
, NULL
, "CopyAlways.Windir.Files", buffer
, sizeof(buffer
), &required
);
451 ok(ret
, "SetupGetTargetPathA failed\n");
453 lstrcpyA(destfile
, WIN_DIR
);
455 ok(required
== lstrlenA(destfile
) + 1, "unexpected required size: %d\n", required
);
456 ok(!lstrcmpiA(buffer
, destfile
), "unexpected path: %s\n", buffer
);
458 SetupCloseInfFile(hinf
);
459 DeleteFileA(inf_filename
);
461 create_inf_file(inf_filename
, inf_data4
, sizeof(inf_data4
) - 1);
463 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
464 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
468 ret
= SetupGetTargetPathA(hinf
, NULL
, "CopyAlways.System32.Files", buffer
, sizeof(buffer
), &required
);
469 ok(ret
, "SetupGetTargetPathA failed\n");
471 GetSystemDirectoryA(destfile
, MAX_PATH
);
473 ok(required
== lstrlenA(destfile
) + 1, "unexpected required size: %d\n", required
);
474 ok(!lstrcmpiA(buffer
, destfile
), "unexpected path: %s\n", buffer
);
476 SetupCloseInfFile(hinf
);
477 DeleteFileA(inf_filename
);
479 create_inf_file(inf_filename
, inf_data5
, sizeof(inf_data5
) - 1);
481 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
482 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
486 ret
= SetupGetTargetPathA(hinf
, NULL
, "CopyAlways.Windir.Files", buffer
, sizeof(buffer
), &required
);
487 ok(ret
, "SetupGetTargetPathA failed\n");
489 lstrcpyA(destfile
, WIN_DIR
);
491 ok(required
== lstrlenA(destfile
) + 1, "unexpected required size: %d\n", required
);
492 ok(!lstrcmpiA(buffer
, destfile
), "unexpected path: %s\n", buffer
);
494 SetupCloseInfFile(hinf
);
495 DeleteFileA(inf_filename
);
497 create_inf_file(inf_filename
, inf_data6
, sizeof(inf_data6
) - 1);
499 hinf
= SetupOpenInfFileA(inf_filename
, NULL
, INF_STYLE_WIN4
, NULL
);
500 ok(hinf
!= INVALID_HANDLE_VALUE
, "could not open inf file\n");
504 ret
= SetupGetTargetPathA(hinf
, NULL
, "CopyAlways.Windir.Files", buffer
, sizeof(buffer
), &required
);
505 ok(ret
, "SetupGetTargetPathA failed\n");
507 lstrcpyA(destfile
, WIN_DIR
);
509 ok(required
== lstrlenA(destfile
) + 1, "unexpected required size: %d\n", required
);
510 ok(!lstrcmpiA(buffer
, destfile
), "unexpected path: %s\n", buffer
);
512 SetupCloseInfFile(hinf
);
513 DeleteFileA(inf_filename
);
520 test_SetupGetInfInformation();
521 test_SetupGetSourceFileLocation();
522 test_SetupGetSourceInfo();
523 test_SetupGetTargetPath();