urlmon: Don't create stgmed_obj for binding to object.
[wine] / dlls / setupapi / tests / query.c
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 /* function pointers */
27 static HMODULE hSetupAPI;
28 static void (WINAPI *pSetupCloseInfFile)(HINF);
29 static BOOL (WINAPI *pSetupGetInfInformationA)(LPCVOID,DWORD,PSP_INF_INFORMATION,DWORD,PDWORD);
30 static HINF (WINAPI *pSetupOpenInfFileA)(PCSTR,PCSTR,DWORD,PUINT);
31 static BOOL (WINAPI *pSetupQueryInfFileInformationA)(PSP_INF_INFORMATION,UINT,PSTR,DWORD,PDWORD);
32 static BOOL (WINAPI *pSetupGetSourceFileLocationA)(HINF,PINFCONTEXT,PCSTR,PUINT,PSTR,DWORD,PDWORD);
33 static BOOL (WINAPI *pSetupGetSourceInfoA)(HINF,UINT,UINT,PSTR,DWORD,PDWORD);
34 static BOOL (WINAPI *pSetupGetTargetPathA)(HINF,PINFCONTEXT,PCSTR,PSTR,DWORD,PDWORD);
35
36 CHAR CURR_DIR[MAX_PATH];
37 CHAR WIN_DIR[MAX_PATH];
38
39 static void init_function_pointers(void)
40 {
41     hSetupAPI = GetModuleHandleA("setupapi.dll");
42
43     pSetupCloseInfFile = (void *)GetProcAddress(hSetupAPI, "SetupCloseInfFile");
44     pSetupGetInfInformationA = (void *)GetProcAddress(hSetupAPI, "SetupGetInfInformationA");
45     pSetupOpenInfFileA = (void *)GetProcAddress(hSetupAPI, "SetupOpenInfFileA");
46     pSetupQueryInfFileInformationA = (void *)GetProcAddress(hSetupAPI, "SetupQueryInfFileInformationA");
47     pSetupGetSourceFileLocationA = (void *)GetProcAddress(hSetupAPI, "SetupGetSourceFileLocationA");
48     pSetupGetSourceInfoA = (void *)GetProcAddress(hSetupAPI, "SetupGetSourceInfoA");
49     pSetupGetTargetPathA = (void *)GetProcAddress(hSetupAPI, "SetupGetTargetPathA");
50 }
51
52 static void get_directories(void)
53 {
54     int len;
55
56     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
57     len = lstrlenA(CURR_DIR);
58
59     if(len && (CURR_DIR[len-1] == '\\'))
60         CURR_DIR[len-1] = 0;
61
62     GetWindowsDirectoryA(WIN_DIR, MAX_PATH);
63     len = lstrlenA(WIN_DIR);
64
65     if (len && (WIN_DIR[len-1] == '\\'))
66         WIN_DIR[len-1] = 0;
67 }
68
69 static void append_str(char **str, const char *data)
70 {
71     sprintf(*str, data);
72     *str += strlen(*str);
73 }
74
75 static void create_inf_file(LPSTR filename)
76 {
77     char data[1024];
78     char *ptr = data;
79     DWORD dwNumberOfBytesWritten;
80     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
81                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
82
83     append_str(&ptr, "[Version]\n");
84     append_str(&ptr, "Signature=\"$Chicago$\"\n");
85     append_str(&ptr, "AdvancedINF=2.5\n");
86     append_str(&ptr, "[SourceDisksNames]\n");
87     append_str(&ptr, "2 = %%SrcDiskName%%, LANCOM\\LANtools\\lanconf.cab\n");
88     append_str(&ptr, "[SourceDisksFiles]\n");
89     append_str(&ptr, "lanconf.exe = 2\n");
90     append_str(&ptr, "[DestinationDirs]\n");
91     append_str(&ptr, "DefaultDestDir = 24, %%DefaultDest%%\n");
92     append_str(&ptr, "[Strings]\n");
93     append_str(&ptr, "LangDir = english\n");
94     append_str(&ptr, "DefaultDest = LANCOM\n");
95     append_str(&ptr, "SrcDiskName = \"LANCOM Software CD\"\n");
96
97     WriteFile(hf, data, ptr - data, &dwNumberOfBytesWritten, NULL);
98     CloseHandle(hf);
99 }
100
101 static void create_inf_file2(LPSTR filename)
102 {
103     char data[1024];
104     char *ptr = data;
105     DWORD dwNumberOfBytesWritten;
106     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
107                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
108
109     append_str(&ptr, "[SourceFileInfo]\n");
110     append_str(&ptr, "sp1qfe\\bitsinst.exe=250B3702C7CCD7C2F9E4DAA1555C933E,000600060A28062C,27136,SP1QFE\n");
111     append_str(&ptr, "sp1qfe\\bitsprx2.dll=4EBEA67F4BB4EB402E725CA7CA2857AE,000600060A280621,7680,SP1QFE\n");
112     append_str(&ptr, "sp1qfe\\bitsprx3.dll=C788A1D9330DA011EF25E95D3BC7BDE5,000600060A280621,7168,SP1QFE\n");
113     append_str(&ptr, "sp1qfe\\qmgr.dll=696AC82FB290A03F205901442E0E9589,000600060A280621,361984,SP1QFE\n");
114     append_str(&ptr, "sp1qfe\\qmgrprxy.dll=8B5848144829E1BC985EA4C3D8CA7E3F,000600060A280621,17408,SP1QFE\n");
115     append_str(&ptr, "sp1qfe\\winhttp.dll=3EC6F518114606CA59D4160322077437,000500010A280615,331776,SP1QFE\n");
116     append_str(&ptr, "sp1qfe\\xpob2res.dll=DB83156B9F496F20D1EA70E4ABEC0166,000500010A280622,158720,SP1QFE\n");
117
118     WriteFile(hf, data, ptr - data, &dwNumberOfBytesWritten, NULL);
119     CloseHandle(hf);
120 }
121
122 static BOOL check_info_filename(PSP_INF_INFORMATION info, LPSTR test)
123 {
124     LPSTR filename;
125     DWORD size;
126     BOOL ret = FALSE;
127
128     if (!pSetupQueryInfFileInformationA(info, 0, NULL, 0, &size))
129         return FALSE;
130
131     filename = HeapAlloc(GetProcessHeap(), 0, size);
132     if (!filename)
133         return FALSE;
134
135     pSetupQueryInfFileInformationA(info, 0, filename, size, &size);
136
137     if (!lstrcmpiA(test, filename))
138         ret = TRUE;
139
140     HeapFree(GetProcessHeap(), 0, filename);
141     return ret;
142 }
143
144 static PSP_INF_INFORMATION alloc_inf_info(LPCSTR filename, DWORD search, PDWORD size)
145 {
146     PSP_INF_INFORMATION info;
147     BOOL ret;
148
149     ret = pSetupGetInfInformationA(filename, search, NULL, 0, size);
150     if (!ret)
151         return NULL;
152
153     info = HeapAlloc(GetProcessHeap(), 0, *size);
154     return info;
155 }
156
157 static void test_SetupGetInfInformation(void)
158 {
159     PSP_INF_INFORMATION info;
160     CHAR inf_filename[MAX_PATH];
161     CHAR inf_one[MAX_PATH], inf_two[MAX_PATH];
162     DWORD size;
163     HINF hinf;
164     BOOL ret;
165
166     lstrcpyA(inf_filename, CURR_DIR);
167     lstrcatA(inf_filename, "\\");
168     lstrcatA(inf_filename, "test.inf");
169
170     /* try an invalid inf handle */
171     size = 0xdeadbeef;
172     SetLastError(0xbeefcafe);
173     ret = pSetupGetInfInformationA(NULL, INFINFO_INF_SPEC_IS_HINF, NULL, 0, &size);
174     ok(ret == FALSE, "Expected SetupGetInfInformation to fail\n");
175     ok(GetLastError() == ERROR_INVALID_HANDLE,
176        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
177     ok(size == 0xdeadbeef, "Expected size to remain unchanged\n");
178
179     /* try an invalid inf filename */
180     size = 0xdeadbeef;
181     SetLastError(0xbeefcafe);
182     ret = pSetupGetInfInformationA(NULL, INFINFO_INF_NAME_IS_ABSOLUTE, NULL, 0, &size);
183     ok(ret == FALSE, "Expected SetupGetInfInformation to fail\n");
184     ok(GetLastError() == ERROR_INVALID_PARAMETER,
185        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
186     ok(size == 0xdeadbeef, "Expected size to remain unchanged\n");
187
188     create_inf_file(inf_filename);
189
190     /* try an invalid search flag */
191     size = 0xdeadbeef;
192     SetLastError(0xbeefcafe);
193     ret = pSetupGetInfInformationA(inf_filename, -1, NULL, 0, &size);
194     ok(ret == FALSE, "Expected SetupGetInfInformation to fail\n");
195     ok(GetLastError() == ERROR_INVALID_PARAMETER,
196        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
197     ok(size == 0xdeadbeef, "Expected size to remain unchanged\n");
198
199     /* try a nonexistent inf file */
200     size = 0xdeadbeef;
201     SetLastError(0xbeefcafe);
202     ret = pSetupGetInfInformationA("idontexist", INFINFO_INF_NAME_IS_ABSOLUTE, NULL, 0, &size);
203     ok(ret == FALSE, "Expected SetupGetInfInformation to fail\n");
204     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
205        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
206     ok(size == 0xdeadbeef, "Expected size to remain unchanged\n");
207
208     /* successfully open the inf file */
209     size = 0xdeadbeef;
210     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, NULL, 0, &size);
211     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
212     ok(size != 0xdeadbeef, "Expected a valid size on return\n");
213
214     /* set ReturnBuffer to NULL and ReturnBufferSize to non-zero value 'size' */
215     SetLastError(0xbeefcafe);
216     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, NULL, size, &size);
217     ok(ret == FALSE, "Expected SetupGetInfInformation to fail\n");
218     ok(GetLastError() == ERROR_INVALID_PARAMETER,
219        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
220
221     /* set ReturnBuffer to NULL and ReturnBufferSize to non-zero value 'size-1' */
222     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, NULL, size-1, &size);
223     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
224
225     /* some tests for behaviour with a NULL RequiredSize pointer */
226     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, NULL, 0, NULL);
227     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
228     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, NULL, size - 1, NULL);
229     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
230     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, NULL, size, NULL);
231     ok(ret == FALSE, "Expected SetupGetInfInformation to fail\n");
232
233     info = HeapAlloc(GetProcessHeap(), 0, size);
234
235     /* try valid ReturnBuffer but too small size */
236     SetLastError(0xbeefcafe);
237     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, info, size - 1, &size);
238     ok(ret == FALSE, "Expected SetupGetInfInformation to fail\n");
239     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
240        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
241
242     /* successfully get the inf information */
243     ret = pSetupGetInfInformationA(inf_filename, INFINFO_INF_NAME_IS_ABSOLUTE, info, size, &size);
244     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
245     ok(check_info_filename(info, inf_filename), "Expected returned filename to be equal\n");
246
247     HeapFree(GetProcessHeap(), 0, info);
248
249     /* try the INFINFO_INF_SPEC_IS_HINF search flag */
250     hinf = pSetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
251     info = alloc_inf_info(hinf, INFINFO_INF_SPEC_IS_HINF, &size);
252     ret = pSetupGetInfInformationA(hinf, INFINFO_INF_SPEC_IS_HINF, info, size, &size);
253     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
254     ok(check_info_filename(info, inf_filename), "Expected returned filename to be equal\n");
255     pSetupCloseInfFile(hinf);
256
257     lstrcpyA(inf_one, WIN_DIR);
258     lstrcatA(inf_one, "\\inf\\");
259     lstrcatA(inf_one, "test.inf");
260     create_inf_file(inf_one);
261
262     lstrcpyA(inf_two, WIN_DIR);
263     lstrcatA(inf_two, "\\system32\\");
264     lstrcatA(inf_two, "test.inf");
265     create_inf_file(inf_two);
266
267     HeapFree(GetProcessHeap(), 0, info);
268     info = alloc_inf_info("test.inf", INFINFO_DEFAULT_SEARCH, &size);
269
270     /* test the INFINFO_DEFAULT_SEARCH search flag */
271     ret = pSetupGetInfInformationA("test.inf", INFINFO_DEFAULT_SEARCH, info, size, &size);
272     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
273     ok(check_info_filename(info, inf_one), "Expected returned filename to be equal\n");
274
275     HeapFree(GetProcessHeap(), 0, info);
276     info = alloc_inf_info("test.inf", INFINFO_REVERSE_DEFAULT_SEARCH, &size);
277
278     /* test the INFINFO_REVERSE_DEFAULT_SEARCH search flag */
279     ret = pSetupGetInfInformationA("test.inf", INFINFO_REVERSE_DEFAULT_SEARCH, info, size, &size);
280     ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n");
281     ok(check_info_filename(info, inf_two), "Expected returned filename to be equal\n");
282
283     DeleteFileA(inf_filename);
284     DeleteFileA(inf_one);
285     DeleteFileA(inf_two);
286 }
287
288 static void test_SetupGetSourceFileLocation(void)
289 {
290     char buffer[MAX_PATH] = "not empty", inf_filename[MAX_PATH];
291     UINT source_id;
292     DWORD required, error;
293     HINF hinf;
294     BOOL ret;
295
296     lstrcpyA(inf_filename, CURR_DIR);
297     lstrcatA(inf_filename, "\\");
298     lstrcatA(inf_filename, "test.inf");
299
300     create_inf_file(inf_filename);
301
302     hinf = pSetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
303     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
304
305     required = 0;
306     source_id = 0;
307
308     ret = pSetupGetSourceFileLocationA(hinf, NULL, "lanconf.exe", &source_id, buffer, sizeof(buffer), &required);
309     ok(ret, "SetupGetSourceFileLocation failed\n");
310
311     ok(required == 1, "unexpected required size: %d\n", required);
312     ok(source_id == 2, "unexpected source id: %d\n", source_id);
313     ok(!lstrcmpA("", buffer), "unexpected result string: %s\n", buffer);
314
315     pSetupCloseInfFile(hinf);
316     DeleteFileA(inf_filename);
317
318     create_inf_file2(inf_filename);
319
320     SetLastError(0xdeadbeef);
321     hinf = pSetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
322     error = GetLastError();
323     ok(hinf == INVALID_HANDLE_VALUE, "could open inf file\n");
324     ok(error == ERROR_WRONG_INF_STYLE, "got wrong error: %d\n", error);
325
326     hinf = pSetupOpenInfFileA(inf_filename, NULL, INF_STYLE_OLDNT, NULL);
327     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
328
329     ret = pSetupGetSourceFileLocationA(hinf, NULL, "", &source_id, buffer, sizeof(buffer), &required);
330     ok(!ret, "SetupGetSourceFileLocation succeeded\n");
331
332     pSetupCloseInfFile(hinf);
333     DeleteFileA(inf_filename);
334 }
335
336 static void test_SetupGetSourceInfo(void)
337 {
338     char buffer[MAX_PATH], inf_filename[MAX_PATH];
339     DWORD required;
340     HINF hinf;
341     BOOL ret;
342
343     lstrcpyA(inf_filename, CURR_DIR);
344     lstrcatA(inf_filename, "\\");
345     lstrcatA(inf_filename, "test.inf");
346
347     create_inf_file(inf_filename);
348
349     hinf = pSetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
350     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
351
352     required = 0;
353
354     ret = pSetupGetSourceInfoA(hinf, 2, SRCINFO_PATH, buffer, sizeof(buffer), &required);
355     ok(ret, "SetupGetSourceInfoA failed\n");
356
357     ok(required == 1, "unexpected required size: %d\n", required);
358     ok(!lstrcmpA("", buffer), "unexpected result string: %s\n", buffer);
359
360     required = 0;
361     buffer[0] = 0;
362
363     ret = pSetupGetSourceInfoA(hinf, 2, SRCINFO_TAGFILE, buffer, sizeof(buffer), &required);
364     ok(ret, "SetupGetSourceInfoA failed\n");
365
366     ok(required == 28, "unexpected required size: %d\n", required);
367     ok(!lstrcmpA("LANCOM\\LANtools\\lanconf.cab", buffer), "unexpected result string: %s\n", buffer);
368
369     required = 0;
370     buffer[0] = 0;
371
372     ret = pSetupGetSourceInfoA(hinf, 2, SRCINFO_DESCRIPTION, buffer, sizeof(buffer), &required);
373     ok(ret, "SetupGetSourceInfoA failed\n");
374
375     ok(required == 19, "unexpected required size: %d\n", required);
376     ok(!lstrcmpA("LANCOM Software CD", buffer), "unexpected result string: %s\n", buffer);
377
378     pSetupCloseInfFile(hinf);
379     DeleteFileA(inf_filename);
380 }
381
382 static void test_SetupGetTargetPath(void)
383 {
384     char buffer[MAX_PATH], inf_filename[MAX_PATH];
385     DWORD required;
386     HINF hinf;
387     INFCONTEXT ctx;
388     BOOL ret;
389
390     lstrcpyA(inf_filename, CURR_DIR);
391     lstrcatA(inf_filename, "\\");
392     lstrcatA(inf_filename, "test.inf");
393
394     create_inf_file(inf_filename);
395
396     hinf = pSetupOpenInfFileA(inf_filename, NULL, INF_STYLE_WIN4, NULL);
397     ok(hinf != INVALID_HANDLE_VALUE, "could not open inf file\n");
398
399     ctx.Inf = hinf;
400     ctx.CurrentInf = hinf;
401     ctx.Section = 7;
402     ctx.Line = 0;
403
404     required = 0;
405
406     ret = pSetupGetTargetPathA(hinf, &ctx, NULL, buffer, sizeof(buffer), &required);
407     ok(ret, "SetupGetTargetPathA failed\n");
408
409     ok(required == 10, "unexpected required size: %d\n", required);
410     ok(!lstrcmpiA("C:\\LANCOM", buffer), "unexpected result string: %s\n", buffer);
411
412     pSetupCloseInfFile(hinf);
413     DeleteFileA(inf_filename);
414 }
415
416 START_TEST(query)
417 {
418     init_function_pointers();
419     get_directories();
420
421     test_SetupGetInfInformation();
422     test_SetupGetSourceFileLocation();
423     test_SetupGetSourceInfo();
424     test_SetupGetTargetPath();
425 }