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
34 #include "wine/test.h"
36 static CHAR CURR_DIR
[MAX_PATH
];
39 * - fails if not administrator
40 * - what if it's not a .inf file?
41 * - copied to %windir%/Inf
42 * - SourceInfFileName should be a full path
43 * - SourceInfFileName should be <= MAX_PATH
47 static BOOL (WINAPI
*pSetupGetFileCompressionInfoExA
)(PCSTR
, PSTR
, DWORD
, PDWORD
, PDWORD
, PDWORD
, PUINT
);
48 static BOOL (WINAPI
*pSetupCopyOEMInfA
)(PCSTR
, PCSTR
, DWORD
, DWORD
, PSTR
, DWORD
, PDWORD
, PSTR
*);
49 static BOOL (WINAPI
*pSetupQueryInfOriginalFileInformationA
)(PSP_INF_INFORMATION
, UINT
, PSP_ALTPLATFORM_INFO
, PSP_ORIGINAL_FILE_INFO_A
);
50 static BOOL (WINAPI
*pSetupUninstallOEMInfA
)(PCSTR
, DWORD
, PVOID
);
52 static void create_inf_file(LPCSTR filename
)
54 DWORD dwNumberOfBytesWritten
;
55 HANDLE hf
= CreateFileA(filename
, GENERIC_WRITE
, 0, NULL
,
56 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
58 static const char data
[] =
60 "Signature=\"$Chicago$\"\n"
63 "RegisterOCXs=RegisterOCXsSection\n"
64 "[RegisterOCXsSection]\n"
65 "%%11%%\\ole32.dll\n";
67 WriteFile(hf
, data
, sizeof(data
) - 1, &dwNumberOfBytesWritten
, NULL
);
71 static void get_temp_filename(LPSTR path
)
76 GetTempFileNameA(CURR_DIR
, "set", 0, temp
);
77 ptr
= strrchr(temp
, '\\');
79 strcpy(path
, ptr
+ 1);
82 static BOOL
file_exists(LPSTR path
)
84 return GetFileAttributesA(path
) != INVALID_FILE_ATTRIBUTES
;
87 static BOOL
check_format(LPSTR path
, LPSTR inf
)
92 static const CHAR format
[] = "\\INF\\oem";
94 GetWindowsDirectoryA(check
, MAX_PATH
);
95 strcat(check
, format
);
96 res
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, NORM_IGNORECASE
, check
, -1, path
, strlen(check
)) == CSTR_EQUAL
&&
97 path
[strlen(check
)] != '\\';
99 return (!inf
) ? res
: res
&& (inf
== path
+ strlen(check
) - 3);
102 static void test_original_file_name(LPCSTR original
, LPCSTR dest
)
105 PSP_INF_INFORMATION pspii
;
106 SP_ORIGINAL_FILE_INFO_A spofi
;
110 if (!pSetupQueryInfOriginalFileInformationA
)
112 win_skip("SetupQueryInfOriginalFileInformationA is not available\n");
116 hinf
= SetupOpenInfFileA(dest
, NULL
, INF_STYLE_WIN4
, NULL
);
117 ok(hinf
!= NULL
, "SetupOpenInfFileA failed with error %d\n", GetLastError());
119 res
= SetupGetInfInformationA(hinf
, INFINFO_INF_SPEC_IS_HINF
, NULL
, 0, &size
);
120 ok(res
, "SetupGetInfInformation failed with error %d\n", GetLastError());
122 pspii
= HeapAlloc(GetProcessHeap(), 0, size
);
124 res
= SetupGetInfInformationA(hinf
, INFINFO_INF_SPEC_IS_HINF
, pspii
, size
, NULL
);
125 ok(res
, "SetupGetInfInformation failed with error %d\n", GetLastError());
128 res
= pSetupQueryInfOriginalFileInformationA(pspii
, 0, NULL
, &spofi
);
129 ok(!res
&& GetLastError() == ERROR_INVALID_USER_BUFFER
,
130 "SetupQueryInfOriginalFileInformationA should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", GetLastError());
132 spofi
.cbSize
= sizeof(spofi
);
133 res
= pSetupQueryInfOriginalFileInformationA(pspii
, 0, NULL
, &spofi
);
134 ok(res
, "SetupQueryInfOriginalFileInformationA failed with error %d\n", GetLastError());
135 ok(!spofi
.OriginalCatalogName
[0], "spofi.OriginalCatalogName should have been \"\" instead of \"%s\"\n", spofi
.OriginalCatalogName
);
137 ok(!strcmp(original
, spofi
.OriginalInfName
), "spofi.OriginalInfName of %s didn't match real original name %s\n", spofi
.OriginalInfName
, original
);
139 HeapFree(GetProcessHeap(), 0, pspii
);
141 SetupCloseInfFile(hinf
);
144 static void test_SetupCopyOEMInf(void)
146 CHAR toolong
[MAX_PATH
* 2];
147 CHAR path
[MAX_PATH
], dest
[MAX_PATH
];
148 CHAR tmpfile
[MAX_PATH
], dest_save
[MAX_PATH
];
153 /* try NULL SourceInfFileName */
154 SetLastError(0xdeadbeef);
155 res
= pSetupCopyOEMInfA(NULL
, NULL
, 0, SP_COPY_NOOVERWRITE
, NULL
, 0, NULL
, NULL
);
156 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
157 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
158 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
160 /* try empty SourceInfFileName */
161 SetLastError(0xdeadbeef);
162 res
= pSetupCopyOEMInfA("", NULL
, 0, SP_COPY_NOOVERWRITE
, NULL
, 0, NULL
, NULL
);
163 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
164 ok(GetLastError() == ERROR_FILE_NOT_FOUND
||
165 GetLastError() == ERROR_BAD_PATHNAME
|| /* Win98 */
166 GetLastError() == ERROR_INVALID_PARAMETER
, /* Vista, W2K8 */
167 "Unexpected error : %d\n", GetLastError());
169 /* try a relative nonexistent SourceInfFileName */
170 SetLastError(0xdeadbeef);
171 res
= pSetupCopyOEMInfA("nonexistent", NULL
, 0, SP_COPY_NOOVERWRITE
, NULL
, 0, NULL
, NULL
);
172 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
173 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
174 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
176 /* try an absolute nonexistent SourceInfFileName */
177 strcpy(path
, CURR_DIR
);
178 strcat(path
, "\\nonexistent");
179 SetLastError(0xdeadbeef);
180 res
= pSetupCopyOEMInfA(path
, NULL
, 0, SP_COPY_NOOVERWRITE
, NULL
, 0, NULL
, NULL
);
181 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
182 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
183 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
185 /* try a long SourceInfFileName */
186 memset(toolong
, 'a', MAX_PATH
* 2);
187 toolong
[MAX_PATH
* 2 - 1] = '\0';
188 SetLastError(0xdeadbeef);
189 res
= pSetupCopyOEMInfA(toolong
, NULL
, 0, SP_COPY_NOOVERWRITE
, NULL
, 0, NULL
, NULL
);
190 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
191 ok(GetLastError() == ERROR_FILE_NOT_FOUND
||
192 GetLastError() == ERROR_FILENAME_EXCED_RANGE
, /* Win98 */
193 "Expected ERROR_FILE_NOT_FOUND or ERROR_FILENAME_EXCED_RANGE, got %d\n", GetLastError());
195 get_temp_filename(tmpfile
);
196 create_inf_file(tmpfile
);
198 /* try a relative SourceInfFileName */
199 SetLastError(0xdeadbeef);
200 res
= pSetupCopyOEMInfA(tmpfile
, NULL
, 0, SP_COPY_NOOVERWRITE
, NULL
, 0, NULL
, NULL
);
202 broken(res
== TRUE
), /* Win98 */
203 "Expected FALSE, got %d\n", res
);
204 if (GetLastError() == ERROR_WRONG_INF_TYPE
|| GetLastError() == ERROR_UNSUPPORTED_TYPE
/* Win7 */)
207 * Vista needs a [Manufacturer] entry in the inf file. Doing this will give some
208 * popups during the installation though as it also needs a catalog file (signed?).
210 win_skip("Needs a different inf file on Vista+\n");
211 DeleteFileA(tmpfile
);
215 ok(GetLastError() == ERROR_FILE_NOT_FOUND
||
216 broken(GetLastError() == ERROR_SUCCESS
), /* Win98 */
217 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
218 ok(file_exists(tmpfile
), "Expected tmpfile to exist\n");
220 /* try SP_COPY_REPLACEONLY, dest does not exist */
221 SetLastError(0xdeadbeef);
222 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, SP_COPY_REPLACEONLY
, NULL
, 0, NULL
, NULL
);
223 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
224 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
225 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
226 ok(file_exists(tmpfile
), "Expected source inf to exist\n");
228 /* try an absolute SourceInfFileName, without DestinationInfFileName */
229 strcpy(path
, CURR_DIR
);
231 strcat(path
, tmpfile
);
232 SetLastError(0xdeadbeef);
233 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, 0, NULL
, 0, NULL
, NULL
);
234 ok(res
== TRUE
, "Expected TRUE, got %d\n", res
);
235 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
236 ok(file_exists(path
), "Expected source inf to exist\n");
238 /* try SP_COPY_REPLACEONLY, dest exists */
239 SetLastError(0xdeadbeef);
240 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, SP_COPY_REPLACEONLY
, NULL
, 0, NULL
, NULL
);
241 ok(res
== TRUE
, "Expected TRUE, got %d\n", res
);
242 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
243 ok(file_exists(path
), "Expected source inf to exist\n");
245 /* try SP_COPY_NOOVERWRITE */
246 SetLastError(0xdeadbeef);
247 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, SP_COPY_NOOVERWRITE
, NULL
, 0, NULL
, NULL
);
248 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
249 ok(GetLastError() == ERROR_FILE_EXISTS
,
250 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
252 /* get the DestinationInfFileName */
253 SetLastError(0xdeadbeef);
254 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, 0, dest
, MAX_PATH
, NULL
, NULL
);
255 ok(res
== TRUE
, "Expected TRUE, got %d\n", res
);
256 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
257 ok(strlen(dest
) != 0, "Expected a non-zero length string\n");
258 ok(file_exists(dest
), "Expected destination inf to exist\n");
259 ok(check_format(dest
, NULL
), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest
);
260 ok(file_exists(path
), "Expected source inf to exist\n");
262 strcpy(dest_save
, dest
);
263 DeleteFileA(dest_save
);
265 /* get the DestinationInfFileName, DestinationInfFileNameSize is too small
266 * - inf is still copied
270 SetLastError(0xdeadbeef);
271 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, 0, dest
, 5, &size
, NULL
);
272 ok(res
== FALSE
, "Expected FALSE, got %d\n", res
);
273 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
274 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
275 ok(file_exists(path
), "Expected source inf to exist\n");
276 ok(file_exists(dest_save
), "Expected dest inf to exist\n");
277 ok(!strcmp(dest
, "aaa"), "Expected dest to be unchanged\n");
278 ok(size
== strlen(dest_save
) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
280 /* get the DestinationInfFileName and DestinationInfFileNameSize */
281 SetLastError(0xdeadbeef);
282 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, 0, dest
, MAX_PATH
, &size
, NULL
);
283 ok(res
== TRUE
, "Expected TRUE, got %d\n", res
);
284 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
285 ok(lstrlenA(dest
) + 1 == size
, "Expected sizes to match, got (%d, %d)\n", lstrlenA(dest
), size
);
286 ok(file_exists(dest
), "Expected destination inf to exist\n");
287 ok(check_format(dest
, NULL
), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest
);
288 ok(file_exists(path
), "Expected source inf to exist\n");
289 ok(size
== lstrlenA(dest_save
) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
291 test_original_file_name(strrchr(path
, '\\') + 1, dest
);
293 /* get the DestinationInfFileName, DestinationInfFileNameSize, and DestinationInfFileNameComponent */
294 SetLastError(0xdeadbeef);
295 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, 0, dest
, MAX_PATH
, &size
, &inf
);
296 ok(res
== TRUE
, "Expected TRUE, got %d\n", res
);
297 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
298 ok(lstrlenA(dest
) + 1 == size
, "Expected sizes to match, got (%d, %d)\n", lstrlenA(dest
), size
);
299 ok(file_exists(dest
), "Expected destination inf to exist\n");
300 ok((inf
&& inf
[0] != 0) ||
301 broken(!inf
), /* Win98 */
302 "Expected inf to point to the filename\n");
303 ok(check_format(dest
, inf
), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest
);
304 ok(file_exists(path
), "Expected source inf to exist\n");
305 ok(size
== lstrlenA(dest_save
) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
307 /* try SP_COPY_DELETESOURCE */
308 SetLastError(0xdeadbeef);
309 res
= pSetupCopyOEMInfA(path
, NULL
, SPOST_NONE
, SP_COPY_DELETESOURCE
, NULL
, 0, NULL
, NULL
);
310 ok(res
== TRUE
, "Expected TRUE, got %d\n", res
);
311 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
312 ok(!file_exists(path
), "Expected source inf to not exist\n");
314 if (pSetupUninstallOEMInfA
)
318 char *destfile
= strrchr(dest
, '\\') + 1;
321 *(strrchr(pnf
, '.') + 1) = 'p';
322 pnffile
= strrchr(pnf
, '\\') + 1;
324 SetLastError(0xdeadbeef);
325 res
= pSetupUninstallOEMInfA(destfile
, 0, NULL
);
327 res
= pSetupUninstallOEMInfA(pnffile
, 0, NULL
);
328 ok(res
, "Failed to uninstall '%s'/'%s' : %d\n", destfile
,
329 pnffile
, GetLastError());
330 todo_wine
ok(!file_exists(dest
), "Expected inf '%s' to not exist\n", dest
);
331 if(file_exists(dest
))
333 SetLastError(0xdeadbeef);
334 res
= DeleteFileA(dest
);
335 ok(res
, "Failed to delete file '%s' : %d\n", dest
, GetLastError());
337 ok(!file_exists(pnf
), "Expected pnf '%s' to not exist\n", pnf
);
340 SetLastError(0xdeadbeef);
341 res
= DeleteFileA(pnf
);
342 ok(res
, "Failed to delete file '%s' : %d\n", pnf
, GetLastError());
348 SetLastError(0xdeadbeef);
349 res
= DeleteFileA(dest
);
350 ok(res
, "Failed to delete file '%s' : %d\n", dest
, GetLastError());
352 /* On WinMe we also need to remove the .pnf file */
353 *(strrchr(dest
, '.') + 1) = 'p';
358 static void create_source_file(LPSTR filename
, const BYTE
*data
, DWORD size
)
363 handle
= CreateFileA(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
364 WriteFile(handle
, data
, size
, &written
, NULL
);
368 static BOOL
compare_file_data(LPSTR file
, const BYTE
*data
, DWORD size
)
375 handle
= CreateFileA(file
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
376 buffer
= HeapAlloc(GetProcessHeap(), 0, size
);
379 ReadFile(handle
, buffer
, size
, &read
, NULL
);
380 if (read
== size
&& !memcmp(data
, buffer
, size
)) ret
= TRUE
;
381 HeapFree(GetProcessHeap(), 0, buffer
);
387 static const BYTE uncompressed
[] = {
388 'u','n','c','o','m','p','r','e','s','s','e','d','\r','\n'
390 static const BYTE laurence
[] = {
391 'l','a','u','r','e','n','c','e','\r','\n'
393 static const BYTE comp_lzx
[] = {
394 0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33, 0x41, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xff, 0x00,
395 0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x3f, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64
397 static const BYTE comp_zip
[] = {
398 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11,
399 0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x15, 0x00, 0x77, 0x69,
400 0x6e, 0x65, 0x55, 0x54, 0x09, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46, 0xfd, 0x0d, 0x10, 0x46, 0x55,
401 0x78, 0x04, 0x00, 0xe8, 0x03, 0xe8, 0x03, 0x00, 0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72,
402 0x65, 0x73, 0x73, 0x65, 0x64, 0x50, 0x4b, 0x01, 0x02, 0x17, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11, 0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
404 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00,
405 0x00, 0x00, 0x00, 0x77, 0x69, 0x6e, 0x65, 0x55, 0x54, 0x05, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46,
406 0x55, 0x78, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
407 0x3f, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00
409 static const BYTE comp_cab_lzx
[] = {
410 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x0f, 0x0e, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x36, 0x86, 0x72, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
414 0x00, 0x19, 0xd0, 0x1a, 0xe3, 0x22, 0x00, 0x0e, 0x00, 0x5b, 0x80, 0x80, 0x8d, 0x00, 0x30, 0xe0,
415 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x6e, 0x63,
416 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x0d, 0x0a
418 static const BYTE comp_cab_zip
[] = {
419 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x36, 0x2f, 0xa5, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
423 0x00, 0x7c, 0x80, 0x26, 0x2b, 0x12, 0x00, 0x0e, 0x00, 0x43, 0x4b, 0x2b, 0xcd, 0x4b, 0xce, 0xcf,
424 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e, 0x4d, 0xe1, 0xe5, 0x02, 0x00
426 static const BYTE comp_cab_zip_multi
[] = {
427 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x38, 0xf0, 0x48, 0x20, 0x00, 0x74, 0x72, 0x69, 0x73,
431 0x74, 0x72, 0x61, 0x6d, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1,
432 0x38, 0xf0, 0x48, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0xd1, 0x38, 0xf0, 0x48, 0x20, 0x00, 0x73, 0x68, 0x61, 0x6e, 0x64, 0x79,
434 0x00, 0x67, 0x2c, 0x03, 0x85, 0x23, 0x00, 0x20, 0x00, 0x43, 0x4b, 0xcb, 0x49, 0x2c, 0x2d, 0x4a,
435 0xcd, 0x4b, 0x4e, 0xe5, 0xe5, 0x2a, 0xcd, 0x4b, 0xce, 0xcf, 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e,
436 0x4d, 0xe1, 0xe5, 0x2a, 0x2e, 0x49, 0x2d, 0xca, 0x03, 0x8a, 0x02, 0x00
439 static void test_SetupGetFileCompressionInfo(void)
441 DWORD ret
, source_size
, target_size
;
442 char source
[MAX_PATH
], temp
[MAX_PATH
], *name
;
445 GetTempPathA(sizeof(temp
), temp
);
446 GetTempFileNameA(temp
, "fci", 0, source
);
448 create_source_file(source
, uncompressed
, sizeof(uncompressed
));
450 ret
= SetupGetFileCompressionInfoA(NULL
, NULL
, NULL
, NULL
, NULL
);
451 ok(ret
== ERROR_INVALID_PARAMETER
, "SetupGetFileCompressionInfo failed unexpectedly\n");
453 ret
= SetupGetFileCompressionInfoA(source
, NULL
, NULL
, NULL
, NULL
);
454 ok(ret
== ERROR_INVALID_PARAMETER
, "SetupGetFileCompressionInfo failed unexpectedly\n");
456 ret
= SetupGetFileCompressionInfoA(source
, &name
, NULL
, NULL
, NULL
);
457 ok(ret
== ERROR_INVALID_PARAMETER
, "SetupGetFileCompressionInfo failed unexpectedly\n");
459 ret
= SetupGetFileCompressionInfoA(source
, &name
, &source_size
, NULL
, NULL
);
460 ok(ret
== ERROR_INVALID_PARAMETER
, "SetupGetFileCompressionInfo failed unexpectedly\n");
462 ret
= SetupGetFileCompressionInfoA(source
, &name
, &source_size
, &target_size
, NULL
);
463 ok(ret
== ERROR_INVALID_PARAMETER
, "SetupGetFileCompressionInfo failed unexpectedly\n");
466 source_size
= target_size
= 0;
469 ret
= SetupGetFileCompressionInfoA(source
, &name
, &source_size
, &target_size
, &type
);
470 ok(!ret
, "SetupGetFileCompressionInfo failed unexpectedly\n");
471 ok(name
&& !lstrcmpA(name
, source
), "got %s, expected %s\n", name
, source
);
472 ok(source_size
== sizeof(uncompressed
), "got %d\n", source_size
);
473 ok(target_size
== sizeof(uncompressed
), "got %d\n", target_size
);
474 ok(type
== FILE_COMPRESSION_NONE
, "got %d, expected FILE_COMPRESSION_NONE\n", type
);
480 static void test_SetupGetFileCompressionInfoEx(void)
483 DWORD required_len
, source_size
, target_size
;
484 char source
[MAX_PATH
], temp
[MAX_PATH
], name
[MAX_PATH
];
487 GetTempPathA(sizeof(temp
), temp
);
488 GetTempFileNameA(temp
, "doc", 0, source
);
490 ret
= pSetupGetFileCompressionInfoExA(NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
491 ok(!ret
, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
493 ret
= pSetupGetFileCompressionInfoExA(source
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
494 ok(!ret
, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
496 ret
= pSetupGetFileCompressionInfoExA(source
, NULL
, 0, &required_len
, NULL
, NULL
, NULL
);
497 ok(!ret
, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
498 ok(required_len
== lstrlenA(source
) + 1, "got %d, expected %d\n", required_len
, lstrlenA(source
) + 1);
500 create_source_file(source
, comp_lzx
, sizeof(comp_lzx
));
502 ret
= pSetupGetFileCompressionInfoExA(source
, name
, sizeof(name
), &required_len
, &source_size
, &target_size
, &type
);
503 ok(ret
, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret
);
504 ok(!lstrcmpA(name
, source
), "got %s, expected %s\n", name
, source
);
505 ok(required_len
== lstrlenA(source
) + 1, "got %d, expected %d\n", required_len
, lstrlenA(source
) + 1);
506 ok(source_size
== sizeof(comp_lzx
), "got %d\n", source_size
);
507 ok(target_size
== sizeof(uncompressed
), "got %d\n", target_size
);
508 ok(type
== FILE_COMPRESSION_WINLZA
, "got %d, expected FILE_COMPRESSION_WINLZA\n", type
);
511 create_source_file(source
, comp_zip
, sizeof(comp_zip
));
513 ret
= pSetupGetFileCompressionInfoExA(source
, name
, sizeof(name
), &required_len
, &source_size
, &target_size
, &type
);
514 ok(ret
, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret
);
515 ok(!lstrcmpA(name
, source
), "got %s, expected %s\n", name
, source
);
516 ok(required_len
== lstrlenA(source
) + 1, "got %d, expected %d\n", required_len
, lstrlenA(source
) + 1);
517 ok(source_size
== sizeof(comp_zip
), "got %d\n", source_size
);
518 ok(target_size
== sizeof(comp_zip
), "got %d\n", target_size
);
519 ok(type
== FILE_COMPRESSION_NONE
, "got %d, expected FILE_COMPRESSION_NONE\n", type
);
522 create_source_file(source
, comp_cab_lzx
, sizeof(comp_cab_lzx
));
524 ret
= pSetupGetFileCompressionInfoExA(source
, name
, sizeof(name
), &required_len
, &source_size
, &target_size
, &type
);
525 ok(ret
, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret
);
526 ok(!lstrcmpA(name
, source
), "got %s, expected %s\n", name
, source
);
527 ok(required_len
== lstrlenA(source
) + 1, "got %d, expected %d\n", required_len
, lstrlenA(source
) + 1);
528 ok(source_size
== sizeof(comp_cab_lzx
), "got %d\n", source_size
);
529 ok(target_size
== sizeof(uncompressed
), "got %d\n", target_size
);
530 ok(type
== FILE_COMPRESSION_MSZIP
, "got %d, expected FILE_COMPRESSION_MSZIP\n", type
);
533 create_source_file(source
, comp_cab_zip
, sizeof(comp_cab_zip
));
535 ret
= pSetupGetFileCompressionInfoExA(source
, name
, sizeof(name
), &required_len
, &source_size
, &target_size
, &type
);
536 ok(ret
, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret
);
537 ok(!lstrcmpA(name
, source
), "got %s, expected %s\n", name
, source
);
538 ok(required_len
== lstrlenA(source
) + 1, "got %d, expected %d\n", required_len
, lstrlenA(source
) + 1);
539 ok(source_size
== sizeof(comp_cab_zip
), "got %d\n", source_size
);
540 ok(target_size
== sizeof(uncompressed
), "got %d\n", target_size
);
541 ok(type
== FILE_COMPRESSION_MSZIP
, "got %d, expected FILE_COMPRESSION_MSZIP\n", type
);
545 static void test_SetupDecompressOrCopyFile(void)
548 char source
[MAX_PATH
], target
[MAX_PATH
], temp
[MAX_PATH
], *p
;
557 } invalid_parameters
[] =
561 {NULL
, target
, NULL
},
562 {NULL
, target
, &type
},
563 {source
, NULL
, NULL
},
564 {source
, NULL
, &type
},
569 const char *filename
;
570 const BYTE
*expected_buffer
;
571 const size_t buffer_size
;
572 } zip_multi_tests
[] =
574 {"tristram", laurence
, sizeof(laurence
)},
575 {"tristram.txt", laurence
, sizeof(laurence
)},
576 {"wine", laurence
, sizeof(laurence
)},
577 {"wine.txt", laurence
, sizeof(laurence
)},
578 {"shandy", laurence
, sizeof(laurence
)},
579 {"shandy.txt", laurence
, sizeof(laurence
)},
580 {"deadbeef", laurence
, sizeof(laurence
)},
581 {"deadbeef.txt", laurence
, sizeof(laurence
)},
584 GetTempPathA(sizeof(temp
), temp
);
585 GetTempFileNameA(temp
, "doc", 0, source
);
586 GetTempFileNameA(temp
, "doc", 0, target
);
588 /* parameter tests */
590 create_source_file(source
, uncompressed
, sizeof(uncompressed
));
592 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
594 type
= FILE_COMPRESSION_NONE
;
595 ret
= SetupDecompressOrCopyFileA(invalid_parameters
[i
].source
,
596 invalid_parameters
[i
].target
,
597 invalid_parameters
[i
].type
);
598 ok(ret
== ERROR_INVALID_PARAMETER
,
599 "[%d] Expected SetupDecompressOrCopyFileA to return ERROR_INVALID_PARAMETER, got %u\n",
602 /* try an invalid compression type */
604 ret
= SetupDecompressOrCopyFileA(invalid_parameters
[i
].source
,
605 invalid_parameters
[i
].target
,
606 invalid_parameters
[i
].type
);
607 ok(ret
== ERROR_INVALID_PARAMETER
,
608 "[%d] Expected SetupDecompressOrCopyFileA to return ERROR_INVALID_PARAMETER, got %u\n",
612 type
= 5; /* try an invalid compression type */
613 ret
= SetupDecompressOrCopyFileA(source
, target
, &type
);
614 ok(ret
== ERROR_INVALID_PARAMETER
, "SetupDecompressOrCopyFile failed unexpectedly\n");
618 /* no compression tests */
620 ret
= SetupDecompressOrCopyFileA(source
, target
, NULL
);
621 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
622 ok(compare_file_data(target
, uncompressed
, sizeof(uncompressed
)), "incorrect target file\n");
624 /* try overwriting existing file */
625 ret
= SetupDecompressOrCopyFileA(source
, target
, NULL
);
626 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
629 type
= FILE_COMPRESSION_NONE
;
630 ret
= SetupDecompressOrCopyFileA(source
, target
, &type
);
631 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
632 ok(compare_file_data(target
, uncompressed
, sizeof(uncompressed
)), "incorrect target file\n");
635 type
= FILE_COMPRESSION_WINLZA
;
636 ret
= SetupDecompressOrCopyFileA(source
, target
, &type
);
637 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
638 ok(compare_file_data(target
, uncompressed
, sizeof(uncompressed
)), "incorrect target file\n");
641 /* lz compression tests */
643 create_source_file(source
, comp_lzx
, sizeof(comp_lzx
));
645 ret
= SetupDecompressOrCopyFileA(source
, target
, NULL
);
646 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
649 /* zip compression tests */
651 create_source_file(source
, comp_zip
, sizeof(comp_zip
));
653 ret
= SetupDecompressOrCopyFileA(source
, target
, NULL
);
654 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
655 ok(compare_file_data(target
, comp_zip
, sizeof(comp_zip
)), "incorrect target file\n");
658 /* cabinet compression tests */
660 create_source_file(source
, comp_cab_zip
, sizeof(comp_cab_zip
));
662 p
= strrchr(target
, '\\');
663 lstrcpyA(p
+ 1, "wine");
665 ret
= SetupDecompressOrCopyFileA(source
, target
, NULL
);
666 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
667 ok(compare_file_data(target
, uncompressed
, sizeof(uncompressed
)), "incorrect target file\n");
669 /* try overwriting existing file */
670 ret
= SetupDecompressOrCopyFileA(source
, target
, NULL
);
671 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
673 /* try zip compression */
674 type
= FILE_COMPRESSION_MSZIP
;
675 ret
= SetupDecompressOrCopyFileA(source
, target
, &type
);
676 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
677 ok(compare_file_data(target
, uncompressed
, sizeof(uncompressed
)), "incorrect target file\n");
679 /* try no compression */
680 type
= FILE_COMPRESSION_NONE
;
681 ret
= SetupDecompressOrCopyFileA(source
, target
, &type
);
682 ok(!ret
, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret
);
683 ok(compare_file_data(target
, comp_cab_zip
, sizeof(comp_cab_zip
)), "incorrect target file\n");
685 /* Show that SetupDecompressOrCopyFileA simply extracts the first file it
686 * finds within the compressed cabinet. Contents are:
687 * tristram -> "laurence\r\n"
688 * wine -> "uncompressed\r\n"
689 * shandy -> "sterne\r\n" */
691 create_source_file(source
, comp_cab_zip_multi
, sizeof(comp_cab_zip_multi
));
693 p
= strrchr(target
, '\\');
695 for (i
= 0; i
< sizeof(zip_multi_tests
)/sizeof(zip_multi_tests
[0]); i
++)
697 lstrcpyA(p
+ 1, zip_multi_tests
[i
].filename
);
699 ret
= SetupDecompressOrCopyFileA(source
, target
, NULL
);
700 ok(!ret
, "[%d] SetupDecompressOrCopyFile failed unexpectedly: %d\n", i
, ret
);
701 ok(compare_file_data(target
, zip_multi_tests
[i
].expected_buffer
, zip_multi_tests
[i
].buffer_size
),
702 "[%d] incorrect target file\n", i
);
709 static void test_SetupUninstallOEMInf(void)
713 SetLastError(0xdeadbeef);
714 ret
= pSetupUninstallOEMInfA(NULL
, 0, NULL
);
715 ok(!ret
, "Expected failure\n");
716 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
718 SetLastError(0xdeadbeef);
719 ret
= pSetupUninstallOEMInfA("", 0, NULL
);
722 ok(!ret
, "Expected failure\n");
723 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
726 SetLastError(0xdeadbeef);
727 ret
= pSetupUninstallOEMInfA("nonexistent.inf", 0, NULL
);
730 ok(!ret
, "Expected failure\n");
731 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
735 struct default_callback_context
746 static void test_defaultcallback(void)
748 struct default_callback_context
*ctxt
;
749 static const DWORD magic
= 0x43515053; /* "SPQC" */
750 HWND owner
, progress
;
753 progress
= (HWND
)0x456;
754 ctxt
= SetupInitDefaultQueueCallbackEx(owner
, progress
, WM_USER
, 0, NULL
);
755 ok(ctxt
!= NULL
, "got %p\n", ctxt
);
757 ok(ctxt
->magic
== magic
|| broken(ctxt
->magic
!= magic
) /* win2000 */, "got magic 0x%08x\n", ctxt
->magic
);
758 if (ctxt
->magic
== magic
)
760 ok(ctxt
->owner
== owner
, "got %p, expected %p\n", ctxt
->owner
, owner
);
761 ok(ctxt
->progress
== progress
, "got %p, expected %p\n", ctxt
->progress
, progress
);
762 ok(ctxt
->message
== WM_USER
, "got %d, expected %d\n", ctxt
->message
, WM_USER
);
763 SetupTermDefaultQueueCallback(ctxt
);
767 win_skip("Skipping tests on old systems.\n");
768 SetupTermDefaultQueueCallback(ctxt
);
772 ctxt
= SetupInitDefaultQueueCallback(owner
);
773 ok(ctxt
->magic
== magic
, "got magic 0x%08x\n", ctxt
->magic
);
774 ok(ctxt
->owner
== owner
, "got %p, expected %p\n", ctxt
->owner
, owner
);
775 ok(ctxt
->progress
== NULL
, "got %p, expected %p\n", ctxt
->progress
, progress
);
776 ok(ctxt
->message
== 0, "got %d\n", ctxt
->message
);
777 SetupTermDefaultQueueCallback(ctxt
);
780 static void test_SetupLogError(void)
785 SetLastError(0xdeadbeef);
786 ret
= SetupLogErrorA("Test without opening\r\n", LogSevInformation
);
787 error
= GetLastError();
788 ok(!ret
, "SetupLogError succeeded\n");
789 ok(error
== ERROR_FILE_INVALID
, "got wrong error: %d\n", error
);
791 SetLastError(0xdeadbeef);
792 ret
= SetupOpenLog(FALSE
);
793 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
795 win_skip("SetupOpenLog() failed on insufficient permissions\n");
798 ok(ret
, "SetupOpenLog failed, error %d\n", GetLastError());
800 SetLastError(0xdeadbeef);
801 ret
= SetupLogErrorA("Test with wrong log severity\r\n", LogSevMaximum
);
802 error
= GetLastError();
803 ok(!ret
, "SetupLogError succeeded\n");
804 ok(error
== 0xdeadbeef, "got wrong error: %d\n", error
);
805 ret
= SetupLogErrorA("Test without EOL", LogSevInformation
);
806 ok(ret
, "SetupLogError failed\n");
808 SetLastError(0xdeadbeef);
809 ret
= SetupLogErrorA(NULL
, LogSevInformation
);
810 ok(ret
|| broken(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
/* Win Vista+ */),
811 "SetupLogError failed: %08x\n", GetLastError());
813 SetLastError(0xdeadbeef);
814 ret
= SetupOpenLog(FALSE
);
815 ok(ret
, "SetupOpenLog failed, error %d\n", GetLastError());
820 static void test_CM_Get_Version(void)
824 ret
= CM_Get_Version();
825 ok(ret
== 0x0400, "got version %#x\n", ret
);
830 HMODULE hsetupapi
= GetModuleHandleA("setupapi.dll");
832 pSetupGetFileCompressionInfoExA
= (void*)GetProcAddress(hsetupapi
, "SetupGetFileCompressionInfoExA");
833 pSetupCopyOEMInfA
= (void*)GetProcAddress(hsetupapi
, "SetupCopyOEMInfA");
834 pSetupQueryInfOriginalFileInformationA
= (void*)GetProcAddress(hsetupapi
, "SetupQueryInfOriginalFileInformationA");
835 pSetupUninstallOEMInfA
= (void*)GetProcAddress(hsetupapi
, "SetupUninstallOEMInfA");
837 GetCurrentDirectoryA(MAX_PATH
, CURR_DIR
);
839 if (pSetupCopyOEMInfA
)
840 test_SetupCopyOEMInf();
842 win_skip("SetupCopyOEMInfA is not available\n");
844 test_SetupGetFileCompressionInfo();
846 if (pSetupGetFileCompressionInfoExA
)
847 test_SetupGetFileCompressionInfoEx();
849 win_skip("SetupGetFileCompressionInfoExA is not available\n");
851 test_SetupDecompressOrCopyFile();
853 if (pSetupUninstallOEMInfA
)
854 test_SetupUninstallOEMInf();
856 win_skip("SetupUninstallOEMInfA is not available\n");
858 test_defaultcallback();
860 test_SetupLogError();
861 test_CM_Get_Version();