advapi32: Make rpcrt4 a delayed import to work around circular dependencies with...
[wine/testsucceed.git] / dlls / setupapi / tests / misc.c
blobf2d885d9904cfc0805574794d3af9f82f43554ee
1 /*
2 * Miscellaneous tests
4 * Copyright 2007 James Hawkins
5 * Copyright 2007 Hans Leidekker
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.
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.
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
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winnls.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "setupapi.h"
33 #include "wine/test.h"
35 static CHAR CURR_DIR[MAX_PATH];
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
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);
51 static void create_inf_file(LPCSTR filename)
53 DWORD dwNumberOfBytesWritten;
54 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
55 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
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";
66 WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL);
67 CloseHandle(hf);
70 static void get_temp_filename(LPSTR path)
72 CHAR temp[MAX_PATH];
73 LPSTR ptr;
75 GetTempFileName(CURR_DIR, "set", 0, temp);
76 ptr = strrchr(temp, '\\');
78 lstrcpy(path, ptr + 1);
81 static BOOL file_exists(LPSTR path)
83 return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES;
86 static BOOL check_format(LPSTR path, LPSTR inf)
88 CHAR check[MAX_PATH];
89 BOOL res;
91 static const CHAR format[] = "\\INF\\oem";
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)] != '\\';
98 return (!inf) ? res : res && (inf == path + lstrlen(check) - 3);
101 static void test_original_file_name(LPCSTR original, LPCSTR dest)
103 HINF hinf;
104 PSP_INF_INFORMATION pspii;
105 SP_ORIGINAL_FILE_INFO spofi;
106 BOOL res;
107 DWORD size;
109 if (!pSetupQueryInfOriginalFileInformationA)
111 win_skip("SetupQueryInfOriginalFileInformationA is not available\n");
112 return;
115 hinf = SetupOpenInfFileA(dest, NULL, INF_STYLE_WIN4, NULL);
116 ok(hinf != NULL, "SetupOpenInfFileA failed with error %d\n", GetLastError());
118 res = SetupGetInfInformation(hinf, INFINFO_INF_SPEC_IS_HINF, NULL, 0, &size);
119 ok(res, "SetupGetInfInformation failed with error %d\n", GetLastError());
121 pspii = HeapAlloc(GetProcessHeap(), 0, size);
123 res = SetupGetInfInformation(hinf, INFINFO_INF_SPEC_IS_HINF, pspii, size, NULL);
124 ok(res, "SetupGetInfInformation failed with error %d\n", GetLastError());
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());
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);
138 HeapFree(GetProcessHeap(), 0, pspii);
140 SetupCloseInfFile(hinf);
143 static void test_SetupCopyOEMInf(void)
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;
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());
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());
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());
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());
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());
194 get_temp_filename(tmpfile);
195 create_inf_file(tmpfile);
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 */)
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?).
209 win_skip("Needs a different inf file on Vista+\n");
210 DeleteFile(tmpfile);
211 return;
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");
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");
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");
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");
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());
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");
261 lstrcpy(dest_save, dest);
262 DeleteFile(dest_save);
264 /* get the DestinationInfFileName, DestinationInfFileNameSize is too small
265 * - inf is still copied
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");
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");
290 test_original_file_name(strrchr(path, '\\') + 1, dest);
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");
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");
313 if (pSetupUninstallOEMInfA)
315 char *destfile = strrchr(dest, '\\') + 1;
317 SetLastError(0xdeadbeef);
318 ok(pSetupUninstallOEMInfA(destfile, 0, NULL), "Failed to uninstall '%s' : %d\n", destfile, GetLastError());
320 else
322 /* Win9x/WinMe */
323 SetLastError(0xdeadbeef);
324 ok(DeleteFileA(dest), "Failed to delete file '%s' : %d\n", dest, GetLastError());
326 /* On WinMe we also need to remove the .pnf file */
327 *(strrchr(dest, '.') + 1) = 'p';
328 DeleteFileA(dest);
332 static void create_source_file(LPSTR filename, const BYTE *data, DWORD size)
334 HANDLE handle;
335 DWORD written;
337 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
338 WriteFile(handle, data, size, &written, NULL);
339 CloseHandle(handle);
342 static BOOL compare_file_data(LPSTR file, const BYTE *data, DWORD size)
344 DWORD read;
345 HANDLE handle;
346 BOOL ret = FALSE;
347 LPBYTE buffer;
349 handle = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
350 buffer = HeapAlloc(GetProcessHeap(), 0, size);
351 if (buffer)
353 ReadFile(handle, buffer, size, &read, NULL);
354 if (read == size && !memcmp(data, buffer, size)) ret = TRUE;
355 HeapFree(GetProcessHeap(), 0, buffer);
357 CloseHandle(handle);
358 return ret;
361 static const BYTE uncompressed[] = {
362 'u','n','c','o','m','p','r','e','s','s','e','d','\r','\n'
364 static const BYTE laurence[] = {
365 'l','a','u','r','e','n','c','e','\r','\n'
367 static const BYTE comp_lzx[] = {
368 0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33, 0x41, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xff, 0x00,
369 0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x3f, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64
371 static const BYTE comp_zip[] = {
372 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11,
373 0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x15, 0x00, 0x77, 0x69,
374 0x6e, 0x65, 0x55, 0x54, 0x09, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46, 0xfd, 0x0d, 0x10, 0x46, 0x55,
375 0x78, 0x04, 0x00, 0xe8, 0x03, 0xe8, 0x03, 0x00, 0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72,
376 0x65, 0x73, 0x73, 0x65, 0x64, 0x50, 0x4b, 0x01, 0x02, 0x17, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11, 0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
378 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00,
379 0x00, 0x00, 0x00, 0x77, 0x69, 0x6e, 0x65, 0x55, 0x54, 0x05, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46,
380 0x55, 0x78, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
381 0x3f, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00
383 static const BYTE comp_cab_lzx[] = {
384 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x0f, 0x0e, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x36, 0x86, 0x72, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
388 0x00, 0x19, 0xd0, 0x1a, 0xe3, 0x22, 0x00, 0x0e, 0x00, 0x5b, 0x80, 0x80, 0x8d, 0x00, 0x30, 0xe0,
389 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x6e, 0x63,
390 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x0d, 0x0a
392 static const BYTE comp_cab_zip[] = {
393 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x36, 0x2f, 0xa5, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
397 0x00, 0x7c, 0x80, 0x26, 0x2b, 0x12, 0x00, 0x0e, 0x00, 0x43, 0x4b, 0x2b, 0xcd, 0x4b, 0xce, 0xcf,
398 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e, 0x4d, 0xe1, 0xe5, 0x02, 0x00
400 static const BYTE comp_cab_zip_multi[] = {
401 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x38, 0xf0, 0x48, 0x20, 0x00, 0x74, 0x72, 0x69, 0x73,
405 0x74, 0x72, 0x61, 0x6d, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1,
406 0x38, 0xf0, 0x48, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0xd1, 0x38, 0xf0, 0x48, 0x20, 0x00, 0x73, 0x68, 0x61, 0x6e, 0x64, 0x79,
408 0x00, 0x67, 0x2c, 0x03, 0x85, 0x23, 0x00, 0x20, 0x00, 0x43, 0x4b, 0xcb, 0x49, 0x2c, 0x2d, 0x4a,
409 0xcd, 0x4b, 0x4e, 0xe5, 0xe5, 0x2a, 0xcd, 0x4b, 0xce, 0xcf, 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e,
410 0x4d, 0xe1, 0xe5, 0x2a, 0x2e, 0x49, 0x2d, 0xca, 0x03, 0x8a, 0x02, 0x00
413 static void test_SetupGetFileCompressionInfo(void)
415 DWORD ret, source_size, target_size;
416 char source[MAX_PATH], temp[MAX_PATH], *name;
417 UINT type;
419 GetTempPathA(sizeof(temp), temp);
420 GetTempFileNameA(temp, "fci", 0, source);
422 create_source_file(source, uncompressed, sizeof(uncompressed));
424 ret = SetupGetFileCompressionInfoA(NULL, NULL, NULL, NULL, NULL);
425 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
427 ret = SetupGetFileCompressionInfoA(source, NULL, NULL, NULL, NULL);
428 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
430 ret = SetupGetFileCompressionInfoA(source, &name, NULL, NULL, NULL);
431 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
433 ret = SetupGetFileCompressionInfoA(source, &name, &source_size, NULL, NULL);
434 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
436 ret = SetupGetFileCompressionInfoA(source, &name, &source_size, &target_size, NULL);
437 ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
439 name = NULL;
440 source_size = target_size = 0;
441 type = 5;
443 ret = SetupGetFileCompressionInfoA(source, &name, &source_size, &target_size, &type);
444 ok(!ret, "SetupGetFileCompressionInfo failed unexpectedly\n");
445 ok(name && !lstrcmpA(name, source), "got %s, expected %s\n", name, source);
446 ok(source_size == sizeof(uncompressed), "got %d\n", source_size);
447 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
448 ok(type == FILE_COMPRESSION_NONE, "got %d, expected FILE_COMPRESSION_NONE\n", type);
450 MyFree(name);
451 DeleteFileA(source);
454 static void test_SetupGetFileCompressionInfoEx(void)
456 BOOL ret;
457 DWORD required_len, source_size, target_size;
458 char source[MAX_PATH], temp[MAX_PATH], name[MAX_PATH];
459 UINT type;
461 GetTempPathA(sizeof(temp), temp);
462 GetTempFileNameA(temp, "doc", 0, source);
464 ret = pSetupGetFileCompressionInfoExA(NULL, NULL, 0, NULL, NULL, NULL, NULL);
465 ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
467 ret = pSetupGetFileCompressionInfoExA(source, NULL, 0, NULL, NULL, NULL, NULL);
468 ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
470 ret = pSetupGetFileCompressionInfoExA(source, NULL, 0, &required_len, NULL, NULL, NULL);
471 ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
472 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
474 create_source_file(source, comp_lzx, sizeof(comp_lzx));
476 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
477 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
478 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
479 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
480 ok(source_size == sizeof(comp_lzx), "got %d\n", source_size);
481 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
482 ok(type == FILE_COMPRESSION_WINLZA, "got %d, expected FILE_COMPRESSION_WINLZA\n", type);
483 DeleteFileA(source);
485 create_source_file(source, comp_zip, sizeof(comp_zip));
487 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
488 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
489 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
490 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
491 ok(source_size == sizeof(comp_zip), "got %d\n", source_size);
492 ok(target_size == sizeof(comp_zip), "got %d\n", target_size);
493 ok(type == FILE_COMPRESSION_NONE, "got %d, expected FILE_COMPRESSION_NONE\n", type);
494 DeleteFileA(source);
496 create_source_file(source, comp_cab_lzx, sizeof(comp_cab_lzx));
498 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
499 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
500 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
501 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
502 ok(source_size == sizeof(comp_cab_lzx), "got %d\n", source_size);
503 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
504 ok(type == FILE_COMPRESSION_MSZIP, "got %d, expected FILE_COMPRESSION_MSZIP\n", type);
505 DeleteFileA(source);
507 create_source_file(source, comp_cab_zip, sizeof(comp_cab_zip));
509 ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
510 ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
511 ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
512 ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
513 ok(source_size == sizeof(comp_cab_zip), "got %d\n", source_size);
514 ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
515 ok(type == FILE_COMPRESSION_MSZIP, "got %d, expected FILE_COMPRESSION_MSZIP\n", type);
516 DeleteFileA(source);
519 static void test_SetupDecompressOrCopyFile(void)
521 DWORD ret;
522 char source[MAX_PATH], target[MAX_PATH], temp[MAX_PATH], *p;
523 UINT type;
524 int i;
526 const struct
528 PCSTR source;
529 PCSTR target;
530 PUINT type;
531 } invalid_parameters[] =
533 {NULL, NULL, NULL},
534 {NULL, NULL, &type},
535 {NULL, target, NULL},
536 {NULL, target, &type},
537 {source, NULL, NULL},
538 {source, NULL, &type},
541 const struct
543 const char *filename;
544 const BYTE *expected_buffer;
545 const size_t buffer_size;
546 } zip_multi_tests[] =
548 {"tristram", laurence, sizeof(laurence)},
549 {"tristram.txt", laurence, sizeof(laurence)},
550 {"wine", laurence, sizeof(laurence)},
551 {"wine.txt", laurence, sizeof(laurence)},
552 {"shandy", laurence, sizeof(laurence)},
553 {"shandy.txt", laurence, sizeof(laurence)},
554 {"deadbeef", laurence, sizeof(laurence)},
555 {"deadbeef.txt", laurence, sizeof(laurence)},
558 GetTempPathA(sizeof(temp), temp);
559 GetTempFileNameA(temp, "doc", 0, source);
560 GetTempFileNameA(temp, "doc", 0, target);
562 /* parameter tests */
564 create_source_file(source, uncompressed, sizeof(uncompressed));
566 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
568 type = FILE_COMPRESSION_NONE;
569 ret = SetupDecompressOrCopyFileA(invalid_parameters[i].source,
570 invalid_parameters[i].target,
571 invalid_parameters[i].type);
572 ok(ret == ERROR_INVALID_PARAMETER,
573 "[%d] Expected SetupDecompressOrCopyFileA to return ERROR_INVALID_PARAMETER, got %u\n",
574 i, ret);
576 /* try an invalid compression type */
577 type = 5;
578 ret = SetupDecompressOrCopyFileA(invalid_parameters[i].source,
579 invalid_parameters[i].target,
580 invalid_parameters[i].type);
581 ok(ret == ERROR_INVALID_PARAMETER,
582 "[%d] Expected SetupDecompressOrCopyFileA to return ERROR_INVALID_PARAMETER, got %u\n",
583 i, ret);
586 type = 5; /* try an invalid compression type */
587 ret = SetupDecompressOrCopyFileA(source, target, &type);
588 ok(ret == ERROR_INVALID_PARAMETER, "SetupDecompressOrCopyFile failed unexpectedly\n");
590 DeleteFileA(target);
592 /* no compression tests */
594 ret = SetupDecompressOrCopyFileA(source, target, NULL);
595 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
596 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
598 /* try overwriting existing file */
599 ret = SetupDecompressOrCopyFileA(source, target, NULL);
600 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
601 DeleteFileA(target);
603 type = FILE_COMPRESSION_NONE;
604 ret = SetupDecompressOrCopyFileA(source, target, &type);
605 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
606 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
607 DeleteFileA(target);
609 type = FILE_COMPRESSION_WINLZA;
610 ret = SetupDecompressOrCopyFileA(source, target, &type);
611 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
612 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
613 DeleteFileA(target);
615 /* lz compression tests */
617 create_source_file(source, comp_lzx, sizeof(comp_lzx));
619 ret = SetupDecompressOrCopyFileA(source, target, NULL);
620 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
621 DeleteFileA(target);
623 /* zip compression tests */
625 create_source_file(source, comp_zip, sizeof(comp_zip));
627 ret = SetupDecompressOrCopyFileA(source, target, NULL);
628 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
629 ok(compare_file_data(target, comp_zip, sizeof(comp_zip)), "incorrect target file\n");
630 DeleteFileA(target);
632 /* cabinet compression tests */
634 create_source_file(source, comp_cab_zip, sizeof(comp_cab_zip));
636 p = strrchr(target, '\\');
637 lstrcpyA(p + 1, "wine");
639 ret = SetupDecompressOrCopyFileA(source, target, NULL);
640 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
641 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
643 /* try overwriting existing file */
644 ret = SetupDecompressOrCopyFileA(source, target, NULL);
645 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
647 /* try zip compression */
648 type = FILE_COMPRESSION_MSZIP;
649 ret = SetupDecompressOrCopyFileA(source, target, &type);
650 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
651 ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
653 /* try no compression */
654 type = FILE_COMPRESSION_NONE;
655 ret = SetupDecompressOrCopyFileA(source, target, &type);
656 ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
657 ok(compare_file_data(target, comp_cab_zip, sizeof(comp_cab_zip)), "incorrect target file\n");
659 /* Show that SetupDecompressOrCopyFileA simply extracts the first file it
660 * finds within the compressed cabinet. Contents are:
661 * tristram -> "laurence\r\n"
662 * wine -> "uncompressed\r\n"
663 * shandy -> "sterne\r\n" */
665 create_source_file(source, comp_cab_zip_multi, sizeof(comp_cab_zip_multi));
667 p = strrchr(target, '\\');
669 for (i = 0; i < sizeof(zip_multi_tests)/sizeof(zip_multi_tests[0]); i++)
671 lstrcpyA(p + 1, zip_multi_tests[i].filename);
673 ret = SetupDecompressOrCopyFileA(source, target, NULL);
674 ok(!ret, "[%d] SetupDecompressOrCopyFile failed unexpectedly: %d\n", i, ret);
675 ok(compare_file_data(target, zip_multi_tests[i].expected_buffer, zip_multi_tests[i].buffer_size),
676 "[%d] incorrect target file\n", i);
677 DeleteFileA(target);
680 DeleteFileA(source);
683 static void test_SetupUninstallOEMInf(void)
685 BOOL ret;
687 SetLastError(0xdeadbeef);
688 ret = pSetupUninstallOEMInfA(NULL, 0, NULL);
689 ok(!ret, "Expected failure\n");
690 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
692 SetLastError(0xdeadbeef);
693 ret = pSetupUninstallOEMInfA("", 0, NULL);
694 todo_wine
696 ok(!ret, "Expected failure\n");
697 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
700 SetLastError(0xdeadbeef);
701 ret = pSetupUninstallOEMInfA("nonexistent.inf", 0, NULL);
702 todo_wine
704 ok(!ret, "Expected failure\n");
705 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
709 START_TEST(misc)
711 HMODULE hsetupapi = GetModuleHandle("setupapi.dll");
713 pSetupGetFileCompressionInfoExA = (void*)GetProcAddress(hsetupapi, "SetupGetFileCompressionInfoExA");
714 pSetupCopyOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupCopyOEMInfA");
715 pSetupQueryInfOriginalFileInformationA = (void*)GetProcAddress(hsetupapi, "SetupQueryInfOriginalFileInformationA");
716 pSetupUninstallOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupUninstallOEMInfA");
718 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
720 if (pSetupCopyOEMInfA)
721 test_SetupCopyOEMInf();
722 else
723 win_skip("SetupCopyOEMInfA is not available\n");
725 test_SetupGetFileCompressionInfo();
727 if (pSetupGetFileCompressionInfoExA)
728 test_SetupGetFileCompressionInfoEx();
729 else
730 win_skip("SetupGetFileCompressionInfoExA is not available\n");
732 test_SetupDecompressOrCopyFile();
734 if (pSetupUninstallOEMInfA)
735 test_SetupUninstallOEMInf();
736 else
737 win_skip("SetupUninstallOEMInfA is not available\n");