1 /*
2  * Unit tests for setupapi.dll query functions
3  *
4  * Copyright (C) 2006 James Hawkins
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 <stdio.h>
22 #include <windows.h>
23 #include <setupapi.h>
24 #include "wine/test.h"
25 
26 static CHAR CURR_DIR[MAX_PATH];
27 static CHAR WIN_DIR[MAX_PATH];
28 
29 static void get_directories(void)
30 {
31     int len;
32 
33     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
34     len = lstrlenA(CURR_DIR);
35 
36     if(len && (CURR_DIR[len-1] == '\\'))
37         CURR_DIR[len-1] = 0;
38 
39     GetWindowsDirectoryA(WIN_DIR, MAX_PATH);
40     len = lstrlenA(WIN_DIR);
41 
42     if (len && (WIN_DIR[len-1] == '\\'))
43         WIN_DIR[len-1] = 0;
44 }
45 
46 static const char inf_data1[] =
47     "[Version]\n"
48     "Signature=\"$Chicago$\"\n"
49     "AdvancedINF=2.5\n"
50     "[SourceDisksNames]\n"
51     "2 = %SrcDiskName%, LANCOM\\LANtools\\lanconf.cab\n"
52     "[SourceDisksFiles]\n"
53     "lanconf.exe = 2\n"
54     "[DestinationDirs]\n"
55     "DefaultDestDir = 24, %DefaultDest%\n"
56     "[Strings]\n"
57     "LangDir = english\n"
58     "DefaultDest = LANCOM\n"
59     "SrcDiskName = \"LANCOM Software CD\"\n";
60 
61 static const char inf_data2[] =
62     "[SourceFileInfo]\n"
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";
70 
71 static const char inf_data3[] =
72     "[Version]\n"
73     "Signature = \"$Windows NT$\"\n"
74     "[DestinationDirs]\n"
75     "CopyAlways.Windir.files = 10\n"
76     "[CopyAlways.Windir.Files]\n"
77     "WindowsCodecs.dll\n";
78 
79 static const char inf_data4[] =
80     "[Version]\n"
81     "Signature = \"$Windows NT$\"\n"
82     "[CopyAlways.System32.Files]\n"
83     "WindowsCodecs.dll\n";
84 
85 static const char inf_data5[] =
86     "[Version]\n"
87     "Signature = \"$Windows NT$\"\n"
88     "[DestinationDirs]\n"
89     "DefaultDestDir = 11\n"
90     "CopyAlways.Windir.files = 10\n"
91     "[CopyAlways.Windir.Files]\n"
92     "WindowsCodecs.dll\n";
93 
94 static const char inf_data6[] =
95     "[Version]\n"
96     "Signature = \"$Windows NT$\"\n"
97     "[DestinationDirs]\n"
98     "DefaultDestDir = 10\n"
99     "[CopyAlways.Windir.Files]\n"
100     "WindowsCodecs.dll\n";
101 
102 static BOOL create_inf_file(LPSTR filename, const char *data, DWORD size)
103 {
104     BOOL ret;
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);
110     CloseHandle(hf);
111     return ret;
112 }
113 
114 static BOOL check_info_filename(PSP_INF_INFORMATION info, LPSTR test)
115 {
116     LPSTR filename;
117     DWORD size;
118     BOOL ret = FALSE;
119 
120     if (!SetupQueryInfFileInformationA(info, 0, NULL, 0, &size))
121         return FALSE;
122 
123     filename = HeapAlloc(GetProcessHeap(), 0, size);
124     if (!filename)
125         return FALSE;
126 
127     SetupQueryInfFileInformationA(info, 0, filename, size, &size);
128 
129     if (!lstrcmpiA(test, filename))
130         ret = TRUE;
131 
132     HeapFree(GetProcessHeap(), 0, filename);
133     return ret;
134 }
135 
136 static PSP_INF_INFORMATION alloc_inf_info(LPCSTR filename, DWORD search, PDWORD size)
137 {
138     PSP_INF_INFORMATION info;
139     BOOL ret;
140 
141     ret = SetupGetInfInformationA(filename, search, NULL, 0, size);
142     if (!ret)
143         return NULL;
144 
145     info = HeapAlloc(GetProcessHeap(), 0, *size);
146     return info;
147 }
148 
149 static void test_SetupGetInfInformation(void)
150 {
151     PSP_INF_INFORMATION info;
152     CHAR inf_filename[MAX_PATH];
153     CHAR inf_one[MAX_PATH], inf_two[MAX_PATH];
154     LPSTR revfile;
155     DWORD size;
156     HINF hinf;
157     BOOL ret;
158 
159     lstrcpyA(inf_filename, CURR_DIR);
160     lstrcatA(inf_filename, "\\");
161     lstrcatA(inf_filename, "test.inf");
162 
163     /* try an invalid inf handle */
164     size = 0xdeadbeef;
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");
176 
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 */
182     {
183         size = 0xdeadbeef;
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");
190     }
191 
192     create_inf_file(inf_filename, inf_data1, sizeof(inf_data1) - 1);
193 
194     /* try an invalid search flag */
195     size = 0xdeadbeef;
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");
202 
203     /* try a nonexistent inf file */
204     size = 0xdeadbeef;
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");
211 
212     /* successfully open the inf file */
213     size = 0xdeadbeef;
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");
217 
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());
224 
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");
228 
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");
236 
237     info = HeapAlloc(GetProcessHeap(), 0, size);
238 
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());
245 
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");
250 
251     HeapFree(GetProcessHeap(), 0, info);
252 
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);
260 
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)
266     {
267         skip("need admin rights\n");
268         goto done;
269     }
270     ok(ret, "can't create inf file %u\n", GetLastError());
271 
272     HeapFree(GetProcessHeap(), 0, info);
273     info = alloc_inf_info("test.inf", INFINFO_DEFAULT_SEARCH, &size);
274 
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 */
279     else
280         revfile = inf_two;
281 
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);
286 
287     HeapFree(GetProcessHeap(), 0, info);
288     info = alloc_inf_info("test.inf", INFINFO_DEFAULT_SEARCH, &size);
289 
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");
294 
295     HeapFree(GetProcessHeap(), 0, info);
296     info = alloc_inf_info("test.inf", INFINFO_REVERSE_DEFAULT_SEARCH, &size);
297 
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");
302 
303 done:
304     HeapFree(GetProcessHeap(), 0, info);
305     DeleteFileA(inf_filename);
306     DeleteFileA(inf_one);
307     DeleteFileA(inf_two);
308 }
309 
310 static void test_SetupGetSourceFileLocation(void)
311 {
312     char buffer[MAX_PATH] = "not empty", inf_filename[MAX_PATH];
313     UINT source_id;
314     DWORD required, error;
315     HINF hinf;
316     BOOL ret;
317 
318     lstrcpyA(inf_filename, CURR_DIR);
319     lstrcatA(inf_filename, "\\");
320     lstrcatA(inf_filename, "test.inf");
321 
322     create_inf_file(inf_filename, inf_data1, sizeof(inf_data1) - 1);
323 
324     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
325     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
326 
327     required = 0;
328     source_id = 0;
329 
330     ret = SetupGetSourceFileLocationA(hinf, NULL, "lanconf.exe", &source_id, buffer, sizeof(buffer), &required);
331     ok(ret, "SetupGetSourceFileLocation failed\n");
332 
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);
336 
337     SetupCloseInfFile(hinf);
338     DeleteFileA(inf_filename);
339 
340     create_inf_file(inf_filename, inf_data2, sizeof(inf_data2) - 1);
341 
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);
347 
348     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_OLDNT, NULL);
349     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
350 
351     ret = SetupGetSourceFileLocationA(hinf, NULL, "", &source_id, buffer, sizeof(buffer), &required);
352     ok(!ret, "SetupGetSourceFileLocation succeeded\n");
353 
354     SetupCloseInfFile(hinf);
355     DeleteFileA(inf_filename);
356 }
357 
358 static void test_SetupGetSourceInfo(void)
359 {
360     char buffer[MAX_PATH], inf_filename[MAX_PATH];
361     DWORD required;
362     HINF hinf;
363     BOOL ret;
364 
365     lstrcpyA(inf_filename, CURR_DIR);
366     lstrcatA(inf_filename, "\\");
367     lstrcatA(inf_filename, "test.inf");
368 
369     create_inf_file(inf_filename, inf_data1, sizeof(inf_data1) - 1);
370 
371     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
372     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
373 
374     required = 0;
375 
376     ret = SetupGetSourceInfoA(hinf, 2, SRCINFO_PATH, buffer, sizeof(buffer), &required);
377     ok(ret, "SetupGetSourceInfoA failed\n");
378 
379     ok(required == 1, "unexpected required size: %d\n", required);
380     ok(!lstrcmpA("", buffer), "unexpected result string: %s\n", buffer);
381 
382     required = 0;
383     buffer[0] = 0;
384 
385     ret = SetupGetSourceInfoA(hinf, 2, SRCINFO_TAGFILE, buffer, sizeof(buffer), &required);
386     ok(ret, "SetupGetSourceInfoA failed\n");
387 
388     ok(required == 28, "unexpected required size: %d\n", required);
389     ok(!lstrcmpA("LANCOM\\LANtools\\lanconf.cab", buffer), "unexpected result string: %s\n", buffer);
390 
391     required = 0;
392     buffer[0] = 0;
393 
394     ret = SetupGetSourceInfoA(hinf, 2, SRCINFO_DESCRIPTION, buffer, sizeof(buffer), &required);
395     ok(ret, "SetupGetSourceInfoA failed\n");
396 
397     ok(required == 19, "unexpected required size: %d\n", required);
398     ok(!lstrcmpA("LANCOM Software CD", buffer), "unexpected result string: %s\n", buffer);
399 
400     SetupCloseInfFile(hinf);
401     DeleteFileA(inf_filename);
402 }
403 
404 static void test_SetupGetTargetPath(void)
405 {
406     char buffer[MAX_PATH], inf_filename[MAX_PATH];
407     char destfile[MAX_PATH];
408     DWORD required;
409     HINF hinf;
410     INFCONTEXT ctx;
411     BOOL ret;
412 
413     lstrcpyA(inf_filename, CURR_DIR);
414     lstrcatA(inf_filename, "\\");
415     lstrcatA(inf_filename, "test.inf");
416 
417     create_inf_file(inf_filename, inf_data1, sizeof(inf_data1) - 1);
418 
419     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
420     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
421 
422     ctx.Inf = hinf;
423     ctx.CurrentInf = hinf;
424     ctx.Section = 7;
425     ctx.Line = 0;
426 
427     required = 0;
428 
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)
434      */
435     lstrcpyA(destfile, WIN_DIR);
436     destfile[3] = '\0';
437     lstrcatA(destfile, "LANCOM");
438     ok(!lstrcmpiA(destfile, buffer), "unexpected result string: %s\n", buffer);
439 
440     SetupCloseInfFile(hinf);
441     DeleteFileA(inf_filename);
442 
443     create_inf_file(inf_filename, inf_data3, sizeof(inf_data3) - 1);
444 
445     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
446     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
447 
448     required = 0;
449 
450     ret = SetupGetTargetPathA(hinf, NULL, "CopyAlways.Windir.Files", buffer, sizeof(buffer), &required);
451     ok(ret, "SetupGetTargetPathA failed\n");
452 
453     lstrcpyA(destfile, WIN_DIR);
454 
455     ok(required == lstrlenA(destfile) + 1, "unexpected required size: %d\n", required);
456     ok(!lstrcmpiA(buffer, destfile), "unexpected path: %s\n", buffer);
457 
458     SetupCloseInfFile(hinf);
459     DeleteFileA(inf_filename);
460 
461     create_inf_file(inf_filename, inf_data4, sizeof(inf_data4) - 1);
462 
463     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
464     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
465 
466     required = 0;
467 
468     ret = SetupGetTargetPathA(hinf, NULL, "CopyAlways.System32.Files", buffer, sizeof(buffer), &required);
469     ok(ret, "SetupGetTargetPathA failed\n");
470 
471     GetSystemDirectoryA(destfile, MAX_PATH);
472 
473     ok(required == lstrlenA(destfile) + 1, "unexpected required size: %d\n", required);
474     ok(!lstrcmpiA(buffer, destfile), "unexpected path: %s\n", buffer);
475 
476     SetupCloseInfFile(hinf);
477     DeleteFileA(inf_filename);
478 
479     create_inf_file(inf_filename, inf_data5, sizeof(inf_data5) - 1);
480 
481     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
482     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
483 
484     required = 0;
485 
486     ret = SetupGetTargetPathA(hinf, NULL, "CopyAlways.Windir.Files", buffer, sizeof(buffer), &required);
487     ok(ret, "SetupGetTargetPathA failed\n");
488 
489     lstrcpyA(destfile, WIN_DIR);
490 
491     ok(required == lstrlenA(destfile) + 1, "unexpected required size: %d\n", required);
492     ok(!lstrcmpiA(buffer, destfile), "unexpected path: %s\n", buffer);
493 
494     SetupCloseInfFile(hinf);
495     DeleteFileA(inf_filename);
496 
497     create_inf_file(inf_filename, inf_data6, sizeof(inf_data6) - 1);
498 
499     hinf = SetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
500     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
501 
502     required = 0;
503 
504     ret = SetupGetTargetPathA(hinf, NULL, "CopyAlways.Windir.Files", buffer, sizeof(buffer), &required);
505     ok(ret, "SetupGetTargetPathA failed\n");
506 
507     lstrcpyA(destfile, WIN_DIR);
508 
509     ok(required == lstrlenA(destfile) + 1, "unexpected required size: %d\n", required);
510     ok(!lstrcmpiA(buffer, destfile), "unexpected path: %s\n", buffer);
511 
512     SetupCloseInfFile(hinf);
513     DeleteFileA(inf_filename);
514 }
515 
516 START_TEST(query)
517 {
518     get_directories();
519 
520     test_SetupGetInfInformation();
521     test_SetupGetSourceFileLocation();
522     test_SetupGetSourceInfo();
523     test_SetupGetTargetPath();
524 }
525