[SETUPAPI_WINETEST]
[reactos.git] / rostests / winetests / setupapi / misc.c
1 /*
2 * Miscellaneous tests
3 *
4 * Copyright 2007 James Hawkins
5 * Copyright 2007 Hans Leidekker
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winnls.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "setupapi.h"
32
33 #include "wine/test.h"
34
35 static CHAR CURR_DIR[MAX_PATH];
36
37 /* test:
38 * - fails if not administrator
39 * - what if it's not a .inf file?
40 * - copied to %windir%/Inf
41 * - SourceInfFileName should be a full path
42 * - SourceInfFileName should be <= MAX_PATH
43 * - copy styles
44 */
45
46 static BOOL (WINAPI *pSetupGetFileCompressionInfoExA)(PCSTR, PSTR, DWORD, PDWORD, PDWORD, PDWORD, PUINT);
47 static BOOL (WINAPI *pSetupCopyOEMInfA)(PCSTR, PCSTR, DWORD, DWORD, PSTR, DWORD, PDWORD, PSTR *);
48 static BOOL (WINAPI *pSetupQueryInfOriginalFileInformationA)(PSP_INF_INFORMATION, UINT, PSP_ALTPLATFORM_INFO, PSP_ORIGINAL_FILE_INFO_A);
49 static BOOL (WINAPI *pSetupUninstallOEMInfA)(PCSTR, DWORD, PVOID);
50
51 static void create_inf_file(LPCSTR filename)
52 {
53 DWORD dwNumberOfBytesWritten;
54 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
55 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
56
57 static const char data[] =
58 "[Version]\n"
59 "Signature=\"$Chicago$\"\n"
60 "AdvancedINF=2.5\n"
61 "[DefaultInstall]\n"
62 "RegisterOCXs=RegisterOCXsSection\n"
63 "[RegisterOCXsSection]\n"
64 "%%11%%\\ole32.dll\n";
65
66 WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL);
67 CloseHandle(hf);
68 }
69
70 static void get_temp_filename(LPSTR path)
71 {
72 CHAR temp[MAX_PATH];
73 LPSTR ptr;
74
75 GetTempFileName(CURR_DIR, "set", 0, temp);
76 ptr = strrchr(temp, '\\');
77
78 lstrcpy(path, ptr + 1);
79 }
80
81 static BOOL file_exists(LPSTR path)
82 {
83 return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES;
84 }
85
86 static BOOL check_format(LPSTR path, LPSTR inf)
87 {
88 CHAR check[MAX_PATH];
89 BOOL res;
90
91 static const CHAR format[] = "\\INF\\oem";
92
93 GetWindowsDirectory(check, MAX_PATH);
94 lstrcat(check, format);
95 res = CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, check, -1, path, lstrlen(check)) == CSTR_EQUAL &&
96 path[lstrlen(check)] != '\\';
97
98 return (!inf) ? res : res && (inf == path + lstrlen(check) - 3);
99 }
100
101 static void test_original_file_name(LPCSTR original, LPCSTR dest)
102 {
103 HINF hinf;
104 PSP_INF_INFORMATION pspii;
105 SP_ORIGINAL_FILE_INFO spofi;
106 BOOL res;
107 DWORD size;
108
109 if (!pSetupQueryInfOriginalFileInformationA)
110 {
111 win_skip("SetupQueryInfOriginalFileInformationA is not available\n");
112 return;
113 }
114
115 hinf = SetupOpenInfFileA(dest, NULL, INF_STYLE_WIN4, NULL);
116 ok(hinf != NULL, "SetupOpenInfFileA failed with error %d\n", GetLastError());
117
118 res = SetupGetInfInformation(hinf, INFINFO_INF_SPEC_IS_HINF, NULL, 0, &size);
119 ok(res, "SetupGetInfInformation failed with error %d\n", GetLastError());
120
121 pspii = HeapAlloc(GetProcessHeap(), 0, size);
122
123 res = SetupGetInfInformation(hinf, INFINFO_INF_SPEC_IS_HINF, pspii, size, NULL);
124 ok(res, "SetupGetInfInformation failed with error %d\n", GetLastError());
125
126 spofi.cbSize = 0;
127 res = pSetupQueryInfOriginalFileInformationA(pspii, 0, NULL, &spofi);
128 ok(!res && GetLastError() == ERROR_INVALID_USER_BUFFER,
129 "SetupQueryInfOriginalFileInformationA should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", GetLastError());
130
131 spofi.cbSize = sizeof(spofi);
132 res = pSetupQueryInfOriginalFileInformationA(pspii, 0, NULL, &spofi);
133 ok(res, "SetupQueryInfOriginalFileInformationA failed with error %d\n", GetLastError());
134 ok(!spofi.OriginalCatalogName[0], "spofi.OriginalCatalogName should have been \"\" instead of \"%s\"\n", spofi.OriginalCatalogName);
135 todo_wine
136 ok(!strcmp(original, spofi.OriginalInfName), "spofi.OriginalInfName of %s didn't match real original name %s\n", spofi.OriginalInfName, original);
137
138 HeapFree(GetProcessHeap(), 0, pspii);
139
140 SetupCloseInfFile(hinf);
141 }
142
143 static void test_SetupCopyOEMInf(void)
144 {
145 CHAR toolong[MAX_PATH * 2];
146 CHAR path[MAX_PATH], dest[MAX_PATH];
147 CHAR tmpfile[MAX_PATH], dest_save[MAX_PATH];
148 LPSTR inf = NULL;
149 DWORD size;
150 BOOL res;
151
152 /* try NULL SourceInfFileName */
153 SetLastError(0xdeadbeef);
154 res = pSetupCopyOEMInfA(NULL, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
155 ok(res == FALSE, "Expected FALSE, got %d\n", res);
156 ok(GetLastError() == ERROR_INVALID_PARAMETER,
157 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
158
159 /* try empty SourceInfFileName */
160 SetLastError(0xdeadbeef);
161 res = pSetupCopyOEMInfA("", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
162 ok(res == FALSE, "Expected FALSE, got %d\n", res);
163 ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
164 GetLastError() == ERROR_BAD_PATHNAME || /* Win98 */
165 GetLastError() == ERROR_INVALID_PARAMETER, /* Vista, W2K8 */
166 "Unexpected error : %d\n", GetLastError());
167
168 /* try a relative nonexistent SourceInfFileName */
169 SetLastError(0xdeadbeef);
170 res = pSetupCopyOEMInfA("nonexistent", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
171 ok(res == FALSE, "Expected FALSE, got %d\n", res);
172 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
173 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
174
175 /* try an absolute nonexistent SourceInfFileName */
176 lstrcpy(path, CURR_DIR);
177 lstrcat(path, "\\nonexistent");
178 SetLastError(0xdeadbeef);
179 res = pSetupCopyOEMInfA(path, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
180 ok(res == FALSE, "Expected FALSE, got %d\n", res);
181 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
182 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
183
184 /* try a long SourceInfFileName */
185 memset(toolong, 'a', MAX_PATH * 2);
186 toolong[MAX_PATH * 2 - 1] = '\0';
187 SetLastError(0xdeadbeef);
188 res = pSetupCopyOEMInfA(toolong, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
189 ok(res == FALSE, "Expected FALSE, got %d\n", res);
190 ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
191 GetLastError() == ERROR_FILENAME_EXCED_RANGE, /* Win98 */
192 "Expected ERROR_FILE_NOT_FOUND or ERROR_FILENAME_EXCED_RANGE, got %d\n", GetLastError());
193
194 get_temp_filename(tmpfile);
195 create_inf_file(tmpfile);
196
197 /* try a relative SourceInfFileName */
198 SetLastError(0xdeadbeef);
199 res = pSetupCopyOEMInfA(tmpfile, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
200 ok(res == FALSE ||
201 broken(res == TRUE), /* Win98 */
202 "Expected FALSE, got %d\n", res);
203 if (GetLastError() == ERROR_WRONG_INF_TYPE || GetLastError() == ERROR_UNSUPPORTED_TYPE /* Win7 */)
204 {
205 /* FIXME:
206 * Vista needs a [Manufacturer] entry in the inf file. Doing this will give some
207 * popups during the installation though as it also needs a catalog file (signed?).
208 */
209 win_skip("Needs a different inf file on Vista+\n");
210 DeleteFile(tmpfile);
211 return;
212 }
213
214 ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
215 broken(GetLastError() == ERROR_SUCCESS), /* Win98 */
216 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
217 ok(file_exists(tmpfile), "Expected tmpfile to exist\n");
218
219 /* try SP_COPY_REPLACEONLY, dest does not exist */
220 SetLastError(0xdeadbeef);
221 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL);
222 ok(res == FALSE, "Expected FALSE, got %d\n", res);
223 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
224 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 ok(file_exists(tmpfile), "Expected source inf to exist\n");
226
227 /* try an absolute SourceInfFileName, without DestinationInfFileName */
228 lstrcpy(path, CURR_DIR);
229 lstrcat(path, "\\");
230 lstrcat(path, tmpfile);
231 SetLastError(0xdeadbeef);
232 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, NULL, 0, NULL, NULL);
233 ok(res == TRUE, "Expected TRUE, got %d\n", res);
234 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
235 ok(file_exists(path), "Expected source inf to exist\n");
236
237 /* try SP_COPY_REPLACEONLY, dest exists */
238 SetLastError(0xdeadbeef);
239 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL);
240 ok(res == TRUE, "Expected TRUE, got %d\n", res);
241 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
242 ok(file_exists(path), "Expected source inf to exist\n");
243
244 /* try SP_COPY_NOOVERWRITE */
245 SetLastError(0xdeadbeef);
246 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
247 ok(res == FALSE, "Expected FALSE, got %d\n", res);
248 ok(GetLastError() == ERROR_FILE_EXISTS,
249 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
250
251 /* get the DestinationInfFileName */
252 SetLastError(0xdeadbeef);
253 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, NULL, NULL);
254 ok(res == TRUE, "Expected TRUE, got %d\n", res);
255 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
256 ok(lstrlen(dest) != 0, "Expected a non-zero length string\n");
257 ok(file_exists(dest), "Expected destination inf to exist\n");
258 ok(check_format(dest, NULL), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
259 ok(file_exists(path), "Expected source inf to exist\n");
260
261 lstrcpy(dest_save, dest);
262 DeleteFile(dest_save);
263
264 /* get the DestinationInfFileName, DestinationInfFileNameSize is too small
265 * - inf is still copied
266 */
267 lstrcpy(dest, "aaa");
268 size = 0;
269 SetLastError(0xdeadbeef);
270 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, 5, &size, NULL);
271 ok(res == FALSE, "Expected FALSE, got %d\n", res);
272 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
273 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
274 ok(file_exists(path), "Expected source inf to exist\n");
275 ok(file_exists(dest_save), "Expected dest inf to exist\n");
276 ok(!lstrcmp(dest, "aaa"), "Expected dest to be unchanged\n");
277 ok(size == lstrlen(dest_save) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
278
279 /* get the DestinationInfFileName and DestinationInfFileNameSize */
280 SetLastError(0xdeadbeef);
281 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, &size, NULL);
282 ok(res == TRUE, "Expected TRUE, got %d\n", res);
283 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
284 ok(lstrlen(dest) + 1 == size, "Expected sizes to match, got (%d, %d)\n", lstrlen(dest), size);
285 ok(file_exists(dest), "Expected destination inf to exist\n");
286 ok(check_format(dest, NULL), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
287 ok(file_exists(path), "Expected source inf to exist\n");
288 ok(size == lstrlen(dest_save) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
289
290 test_original_file_name(strrchr(path, '\\') + 1, dest);
291
292 /* get the DestinationInfFileName, DestinationInfFileNameSize, and DestinationInfFileNameComponent */
293 SetLastError(0xdeadbeef);
294 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, &size, &inf);
295 ok(res == TRUE, "Expected TRUE, got %d\n", res);
296 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
297 ok(lstrlen(dest) + 1 == size, "Expected sizes to match, got (%d, %d)\n", lstrlen(dest), size);
298 ok(file_exists(dest), "Expected destination inf to exist\n");
299 ok((inf && inf[0] != 0) ||
300 broken(!inf), /* Win98 */
301 "Expected inf to point to the filename\n");
302 ok(check_format(dest, inf), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
303 ok(file_exists(path), "Expected source inf to exist\n");
304 ok(size == lstrlen(dest_save) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
305
306 /* try SP_COPY_DELETESOURCE */
307 SetLastError(0xdeadbeef);
308 res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_DELETESOURCE, NULL, 0, NULL, NULL);
309 ok(res == TRUE, "Expected TRUE, got %d\n", res);
310 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
311 ok(!file_exists(path), "Expected source inf to not exist\n");
312
313 if (pSetupUninstallOEMInfA)
314 {
315 char pnf[MAX_PATH];
316 char *pnffile;
317 char *destfile = strrchr(dest, '\\') + 1;
318
319 strcpy(pnf, dest);
320 *(strrchr(pnf, '.') + 1) = 'p';
321 pnffile = strrchr(pnf, '\\') + 1;
322
323 SetLastError(0xdeadbeef);
324 res = pSetupUninstallOEMInfA(destfile, 0, NULL);
325 if(!res)
326 res = pSetupUninstallOEMInfA(pnffile, 0, NULL);
327 ok(res, "Failed to uninstall '%s'/'%s' : %d\n", destfile,
328 pnffile, GetLastError());
329 todo_wine ok(!file_exists(dest), "Expected inf '%s' to not exist\n", dest);
330 if(file_exists(dest))
331 {
332 SetLastError(0xdeadbeef);
333 res = DeleteFileA(dest);
334 ok(res, "Failed to delete file '%s' : %d\n", dest, GetLastError());
335 }
336 ok(!file_exists(pnf), "Expected pnf '%s' to not exist\n", pnf);
337 if(file_exists(pnf))
338 {
339 SetLastError(0xdeadbeef);
340 res = DeleteFileA(pnf);
341 ok(res, "Failed to delete file '%s' : %d\n", pnf, GetLastError());
342 }
343 }
344 else
345 {
346 /* Win9x/WinMe */
347 SetLastError(0xdeadbeef);
348 res = DeleteFileA(dest);
349 ok(res, "Failed to delete file '%s' : %d\n", dest, GetLastError());
350
351 /* On WinMe we also need to remove the .pnf file */
352 *(strrchr(dest, '.') + 1) = 'p';
353 DeleteFileA(dest);
354 }
355 }
356
357 static void create_source_file(LPSTR filename, const BYTE *data, DWORD size)
358 {
359 HANDLE handle;
360 DWORD written;
361
362 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
363 WriteFile(handle, data, size, &written, NULL);
364 CloseHandle(handle);
365 }
366
367 static BOOL compare_file_data(LPSTR file, const BYTE *data, DWORD size)
368 {
369 DWORD read;
370 HANDLE handle;
371 BOOL ret = FALSE;
372 LPBYTE buffer;
373
374 handle = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
375 buffer = HeapAlloc(GetProcessHeap(), 0, size);
376 if (buffer)
377 {
378 ReadFile(handle, buffer, size, &read, NULL);
379 if (read == size && !memcmp(data, buffer, size)) ret = TRUE;
380 HeapFree(GetProcessHeap(), 0, buffer);
381 }
382 CloseHandle(handle);
383 return ret;
384 }
385
386 static const BYTE uncompressed[] = {
387 'u','n','c','o','m','p','r','e','s','s','e','d','\r','\n'
388 };
389 static const BYTE laurence[] = {
390 'l','a','u','r','e','n','c','e','\r','\n'
391 };
392 static const BYTE comp_lzx[] = {
393 0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33, 0x41, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xff, 0x00,
394 0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x3f, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64
395 };
396 static const BYTE comp_zip[] = {
397 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11,
398 0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x15, 0x00, 0x77, 0x69,
399 0x6e, 0x65, 0x55, 0x54, 0x09, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46, 0xfd, 0x0d, 0x10, 0x46, 0x55,
400 0x78, 0x04, 0x00, 0xe8, 0x03, 0xe8, 0x03, 0x00, 0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72,
401 0x65, 0x73, 0x73, 0x65, 0x64, 0x50, 0x4b, 0x01, 0x02, 0x17, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11, 0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
403 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00,
404 0x00, 0x00, 0x00, 0x77, 0x69, 0x6e, 0x65, 0x55, 0x54, 0x05, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46,
405 0x55, 0x78, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
406 0x3f, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00
407 };
408 static const BYTE comp_cab_lzx[] = {
409 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x0f, 0x0e, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x36, 0x86, 0x72, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
413 0x00, 0x19, 0xd0, 0x1a, 0xe3, 0x22, 0x00, 0x0e, 0x00, 0x5b, 0x80, 0x80, 0x8d, 0x00, 0x30, 0xe0,
414 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x6e, 0x63,
415 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x0d, 0x0a
416 };
417 static const BYTE comp_cab_zip[] = {
418 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x36, 0x2f, 0xa5, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
422 0x00, 0x7c, 0x80, 0x26, 0x2b, 0x12, 0x00, 0x0e, 0x00, 0x43, 0x4b, 0x2b, 0xcd, 0x4b, 0xce, 0xcf,
423 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e, 0x4d, 0xe1, 0xe5, 0x02, 0x00
424 };
425 static const BYTE comp_cab_zip_multi[] = {
426 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x38, 0xf0, 0x48, 0x20, 0x00, 0x74, 0x72, 0x69, 0x73,
430 0x74, 0x72, 0x61, 0x6d, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1,
431 0x38, 0xf0, 0x48, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0xd1, 0x38, 0xf0, 0x48, 0x20, 0x00, 0x73, 0x68, 0x61, 0x6e, 0x64, 0x79,
433 0x00, 0x67, 0x2c, 0x03, 0x85, 0x23, 0x00, 0x20, 0x00, 0x43, 0x4b, 0xcb, 0x49, 0x2c, 0x2d, 0x4a,
434 0xcd, 0x4b, 0x4e, 0xe5, 0xe5, 0x2a, 0xcd, 0x4b, 0xce, 0xcf, 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e,
435 0x4d, 0xe1, 0xe5, 0x2a, 0x2e, 0x49, 0x2d, 0xca, 0x03, 0x8a, 0x02, 0x00
436 };
437
438 static void test_SetupGetFileCompressionInfo(void)
439 {
440 DWORD ret, source_size, target_size;
441 char source[MAX_PATH], temp[MAX_PATH], *name;
442 UINT type;
443
444 GetTempPathA(sizeof(temp), temp);
445 GetTempFileNameA(temp, "fci", 0, source);
446
447 create_source_file(source, uncompressed, sizeof(uncompressed));
448
449 ret = SetupGetFileCompressionInfoA(NULL, NULL, NULL, NULL, NULL);
450 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
451
452 ret = SetupGetFileCompressionInfoA(source, NULL, NULL, NULL, NULL);
453 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
454
455 ret = SetupGetFileCompressionInfoA(source, &name, NULL, NULL, NULL);
456 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
457
458 ret = SetupGetFileCompressionInfoA(source, &name, &source_size, NULL, NULL);
459 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
460
461 ret = SetupGetFileCompressionInfoA(source, &name, &source_size, &target_size, NULL);
462 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
463
464 name = NULL;
465 source_size = target_size = 0;
466 type = 5;
467
468 ret = SetupGetFileCompressionInfoA(source, &name, &source_size, &target_size, &type);
469 ok(!ret, "SetupGetFileCompressionInfo failed unexpectedly\n");
470 ok(name && !lstrcmpA(name, source), "got %s, expected %s\n", name, source);
471 ok(source_size == sizeof(uncompressed), "got %d\n", source_size);
472 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
473 ok(type == FILE_COMPRESSION_NONE, "got %d, expected FILE_COMPRESSION_NONE\n", type);
474
475 MyFree(name);
476 DeleteFileA(source);
477 }
478
479 static void test_SetupGetFileCompressionInfoEx(void)
480 {
481 BOOL ret;
482 DWORD required_len, source_size, target_size;
483 char source[MAX_PATH], temp[MAX_PATH], name[MAX_PATH];
484 UINT type;
485
486 GetTempPathA(sizeof(temp), temp);
487 GetTempFileNameA(temp, "doc", 0, source);
488
489 ret = pSetupGetFileCompressionInfoExA(NULL, NULL, 0, NULL, NULL, NULL, NULL);
490 ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
491
492 ret = pSetupGetFileCompressionInfoExA(source, NULL, 0, NULL, NULL, NULL, NULL);
493 ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
494
495 ret = pSetupGetFileCompressionInfoExA(source, NULL, 0, &required_len, NULL, NULL, NULL);
496 ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
497 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
498
499 create_source_file(source, comp_lzx, sizeof(comp_lzx));
500
501 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
502 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
503 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
504 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
505 ok(source_size == sizeof(comp_lzx), "got %d\n", source_size);
506 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
507 ok(type == FILE_COMPRESSION_WINLZA, "got %d, expected FILE_COMPRESSION_WINLZA\n", type);
508 DeleteFileA(source);
509
510 create_source_file(source, comp_zip, sizeof(comp_zip));
511
512 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
513 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
514 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
515 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
516 ok(source_size == sizeof(comp_zip), "got %d\n", source_size);
517 ok(target_size == sizeof(comp_zip), "got %d\n", target_size);
518 ok(type == FILE_COMPRESSION_NONE, "got %d, expected FILE_COMPRESSION_NONE\n", type);
519 DeleteFileA(source);
520
521 create_source_file(source, comp_cab_lzx, sizeof(comp_cab_lzx));
522
523 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
524 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
525 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
526 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
527 ok(source_size == sizeof(comp_cab_lzx), "got %d\n", source_size);
528 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
529 ok(type == FILE_COMPRESSION_MSZIP, "got %d, expected FILE_COMPRESSION_MSZIP\n", type);
530 DeleteFileA(source);
531
532 create_source_file(source, comp_cab_zip, sizeof(comp_cab_zip));
533
534 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
535 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
536 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
537 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
538 ok(source_size == sizeof(comp_cab_zip), "got %d\n", source_size);
539 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
540 ok(type == FILE_COMPRESSION_MSZIP, "got %d, expected FILE_COMPRESSION_MSZIP\n", type);
541 DeleteFileA(source);
542 }
543
544 static void test_SetupDecompressOrCopyFile(void)
545 {
546 DWORD ret;
547 char source[MAX_PATH], target[MAX_PATH], temp[MAX_PATH], *p;
548 UINT type;
549 int i;
550
551 const struct
552 {
553 PCSTR source;
554 PCSTR target;
555 PUINT type;
556 } invalid_parameters[] =
557 {
558 {NULL, NULL, NULL},
559 {NULL, NULL, &type},
560 {NULL, target, NULL},
561 {NULL, target, &type},
562 {source, NULL, NULL},
563 {source, NULL, &type},
564 };
565
566 const struct
567 {
568 const char *filename;
569 const BYTE *expected_buffer;
570 const size_t buffer_size;
571 } zip_multi_tests[] =
572 {
573 {"tristram", laurence, sizeof(laurence)},
574 {"tristram.txt", laurence, sizeof(laurence)},
575 {"wine", laurence, sizeof(laurence)},
576 {"wine.txt", laurence, sizeof(laurence)},
577 {"shandy", laurence, sizeof(laurence)},
578 {"shandy.txt", laurence, sizeof(laurence)},
579 {"deadbeef", laurence, sizeof(laurence)},
580 {"deadbeef.txt", laurence, sizeof(laurence)},
581 };
582
583 GetTempPathA(sizeof(temp), temp);
584 GetTempFileNameA(temp, "doc", 0, source);
585 GetTempFileNameA(temp, "doc", 0, target);
586
587 /* parameter tests */
588
589 create_source_file(source, uncompressed, sizeof(uncompressed));
590
591 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
592 {
593 type = FILE_COMPRESSION_NONE;
594 ret = SetupDecompressOrCopyFileA(invalid_parameters[i].source,
595 invalid_parameters[i].target,
596 invalid_parameters[i].type);
597 ok(ret == ERROR_INVALID_PARAMETER,
598 "[%d] Expected SetupDecompressOrCopyFileA to return ERROR_INVALID_PARAMETER, got %u\n",
599 i, ret);
600
601 /* try an invalid compression type */
602 type = 5;
603 ret = SetupDecompressOrCopyFileA(invalid_parameters[i].source,
604 invalid_parameters[i].target,
605 invalid_parameters[i].type);
606 ok(ret == ERROR_INVALID_PARAMETER,
607 "[%d] Expected SetupDecompressOrCopyFileA to return ERROR_INVALID_PARAMETER, got %u\n",
608 i, ret);
609 }
610
611 type = 5; /* try an invalid compression type */
612 ret = SetupDecompressOrCopyFileA(source, target, &type);
613 ok(ret == ERROR_INVALID_PARAMETER, "SetupDecompressOrCopyFile failed unexpectedly\n");
614
615 DeleteFileA(target);
616
617 /* no compression tests */
618
619 ret = SetupDecompressOrCopyFileA(source, target, NULL);
620 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
621 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
622
623 /* try overwriting existing file */
624 ret = SetupDecompressOrCopyFileA(source, target, NULL);
625 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
626 DeleteFileA(target);
627
628 type = FILE_COMPRESSION_NONE;
629 ret = SetupDecompressOrCopyFileA(source, target, &type);
630 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
631 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
632 DeleteFileA(target);
633
634 type = FILE_COMPRESSION_WINLZA;
635 ret = SetupDecompressOrCopyFileA(source, target, &type);
636 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
637 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
638 DeleteFileA(target);
639
640 /* lz compression tests */
641
642 create_source_file(source, comp_lzx, sizeof(comp_lzx));
643
644 ret = SetupDecompressOrCopyFileA(source, target, NULL);
645 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
646 DeleteFileA(target);
647
648 /* zip compression tests */
649
650 create_source_file(source, comp_zip, sizeof(comp_zip));
651
652 ret = SetupDecompressOrCopyFileA(source, target, NULL);
653 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
654 ok(compare_file_data(target, comp_zip, sizeof(comp_zip)), "incorrect target file\n");
655 DeleteFileA(target);
656
657 /* cabinet compression tests */
658
659 create_source_file(source, comp_cab_zip, sizeof(comp_cab_zip));
660
661 p = strrchr(target, '\\');
662 lstrcpyA(p + 1, "wine");
663
664 ret = SetupDecompressOrCopyFileA(source, target, NULL);
665 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
666 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
667
668 /* try overwriting existing file */
669 ret = SetupDecompressOrCopyFileA(source, target, NULL);
670 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
671
672 /* try zip compression */
673 type = FILE_COMPRESSION_MSZIP;
674 ret = SetupDecompressOrCopyFileA(source, target, &type);
675 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
676 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
677
678 /* try no compression */
679 type = FILE_COMPRESSION_NONE;
680 ret = SetupDecompressOrCopyFileA(source, target, &type);
681 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
682 ok(compare_file_data(target, comp_cab_zip, sizeof(comp_cab_zip)), "incorrect target file\n");
683
684 /* Show that SetupDecompressOrCopyFileA simply extracts the first file it
685 * finds within the compressed cabinet. Contents are:
686 * tristram -> "laurence\r\n"
687 * wine -> "uncompressed\r\n"
688 * shandy -> "sterne\r\n" */
689
690 create_source_file(source, comp_cab_zip_multi, sizeof(comp_cab_zip_multi));
691
692 p = strrchr(target, '\\');
693
694 for (i = 0; i < sizeof(zip_multi_tests)/sizeof(zip_multi_tests[0]); i++)
695 {
696 lstrcpyA(p + 1, zip_multi_tests[i].filename);
697
698 ret = SetupDecompressOrCopyFileA(source, target, NULL);
699 ok(!ret, "[%d] SetupDecompressOrCopyFile failed unexpectedly: %d\n", i, ret);
700 ok(compare_file_data(target, zip_multi_tests[i].expected_buffer, zip_multi_tests[i].buffer_size),
701 "[%d] incorrect target file\n", i);
702 DeleteFileA(target);
703 }
704
705 DeleteFileA(source);
706 }
707
708 static void test_SetupUninstallOEMInf(void)
709 {
710 BOOL ret;
711
712 SetLastError(0xdeadbeef);
713 ret = pSetupUninstallOEMInfA(NULL, 0, NULL);
714 ok(!ret, "Expected failure\n");
715 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
716
717 SetLastError(0xdeadbeef);
718 ret = pSetupUninstallOEMInfA("", 0, NULL);
719 todo_wine
720 {
721 ok(!ret, "Expected failure\n");
722 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
723 }
724
725 SetLastError(0xdeadbeef);
726 ret = pSetupUninstallOEMInfA("nonexistent.inf", 0, NULL);
727 todo_wine
728 {
729 ok(!ret, "Expected failure\n");
730 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
731 }
732 }
733
734 START_TEST(misc)
735 {
736 HMODULE hsetupapi = GetModuleHandle("setupapi.dll");
737
738 pSetupGetFileCompressionInfoExA = (void*)GetProcAddress(hsetupapi, "SetupGetFileCompressionInfoExA");
739 pSetupCopyOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupCopyOEMInfA");
740 pSetupQueryInfOriginalFileInformationA = (void*)GetProcAddress(hsetupapi, "SetupQueryInfOriginalFileInformationA");
741 pSetupUninstallOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupUninstallOEMInfA");
742
743 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
744
745 if (pSetupCopyOEMInfA)
746 test_SetupCopyOEMInf();
747 else
748 win_skip("SetupCopyOEMInfA is not available\n");
749
750 test_SetupGetFileCompressionInfo();
751
752 if (pSetupGetFileCompressionInfoExA)
753 test_SetupGetFileCompressionInfoEx();
754 else
755 win_skip("SetupGetFileCompressionInfoExA is not available\n");
756
757 test_SetupDecompressOrCopyFile();
758
759 if (pSetupUninstallOEMInfA)
760 test_SetupUninstallOEMInf();
761 else
762 win_skip("SetupUninstallOEMInfA is not available\n");
763 }