kernel32: Reimplement GetPrivateProfileString16 on top of 32-bit functions and move...
[wine] / dlls / setupapi / tests / 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, "Expected FALSE, got %d\n", res);
201     if (GetLastError() == ERROR_WRONG_INF_TYPE || GetLastError() == ERROR_UNSUPPORTED_TYPE /* Win7 */)
202     {
203        /* FIXME:
204         * Vista needs a [Manufacturer] entry in the inf file. Doing this will give some
205         * popups during the installation though as it also needs a catalog file (signed?).
206         */
207        win_skip("Needs a different inf file on Vista+\n");
208        DeleteFile(tmpfile);
209        return;
210     }
211
212     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
213        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
214     ok(file_exists(tmpfile), "Expected tmpfile to exist\n");
215
216     /* try SP_COPY_REPLACEONLY, dest does not exist */
217     SetLastError(0xdeadbeef);
218     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL);
219     ok(res == FALSE, "Expected FALSE, got %d\n", res);
220     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
221        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
222     ok(file_exists(tmpfile), "Expected source inf to exist\n");
223
224     /* try an absolute SourceInfFileName, without DestinationInfFileName */
225     lstrcpy(path, CURR_DIR);
226     lstrcat(path, "\\");
227     lstrcat(path, tmpfile);
228     SetLastError(0xdeadbeef);
229     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, NULL, 0, NULL, NULL);
230     ok(res == TRUE, "Expected TRUE, got %d\n", res);
231     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
232     ok(file_exists(path), "Expected source inf to exist\n");
233
234     /* try SP_COPY_REPLACEONLY, dest exists */
235     SetLastError(0xdeadbeef);
236     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL);
237     ok(res == TRUE, "Expected TRUE, got %d\n", res);
238     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
239     ok(file_exists(path), "Expected source inf to exist\n");
240
241     /* try SP_COPY_NOOVERWRITE */
242     SetLastError(0xdeadbeef);
243     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
244     ok(res == FALSE, "Expected FALSE, got %d\n", res);
245     ok(GetLastError() == ERROR_FILE_EXISTS,
246        "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
247
248     /* get the DestinationInfFileName */
249     SetLastError(0xdeadbeef);
250     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, NULL, NULL);
251     ok(res == TRUE, "Expected TRUE, got %d\n", res);
252     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
253     ok(lstrlen(dest) != 0, "Expected a non-zero length string\n");
254     ok(file_exists(dest), "Expected destination inf to exist\n");
255     ok(check_format(dest, NULL), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
256     ok(file_exists(path), "Expected source inf to exist\n");
257
258     lstrcpy(dest_save, dest);
259     DeleteFile(dest_save);
260
261     /* get the DestinationInfFileName, DestinationInfFileNameSize is too small
262      *   - inf is still copied
263      */
264     lstrcpy(dest, "aaa");
265     size = 0;
266     SetLastError(0xdeadbeef);
267     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, 5, &size, NULL);
268     ok(res == FALSE, "Expected FALSE, got %d\n", res);
269     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
270        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
271     ok(file_exists(path), "Expected source inf to exist\n");
272     ok(file_exists(dest_save), "Expected dest inf to exist\n");
273     ok(!lstrcmp(dest, "aaa"), "Expected dest to be unchanged\n");
274     ok(size == lstrlen(dest_save) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
275
276     /* get the DestinationInfFileName and DestinationInfFileNameSize */
277     SetLastError(0xdeadbeef);
278     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, &size, NULL);
279     ok(res == TRUE, "Expected TRUE, got %d\n", res);
280     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
281     ok(lstrlen(dest) + 1 == size, "Expected sizes to match, got (%d, %d)\n", lstrlen(dest), size);
282     ok(file_exists(dest), "Expected destination inf to exist\n");
283     ok(check_format(dest, NULL), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
284     ok(file_exists(path), "Expected source inf to exist\n");
285     ok(size == lstrlen(dest_save) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
286
287     test_original_file_name(strrchr(path, '\\') + 1, dest);
288
289     /* get the DestinationInfFileName, DestinationInfFileNameSize, and DestinationInfFileNameComponent */
290     SetLastError(0xdeadbeef);
291     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, &size, &inf);
292     ok(res == TRUE, "Expected TRUE, got %d\n", res);
293     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
294     ok(lstrlen(dest) + 1 == size, "Expected sizes to match, got (%d, %d)\n", lstrlen(dest), size);
295     ok(file_exists(dest), "Expected destination inf to exist\n");
296     ok((inf && inf[0] != 0) ||
297        broken(!inf), /* Win98 */
298        "Expected inf to point to the filename\n");
299     ok(check_format(dest, inf), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
300     ok(file_exists(path), "Expected source inf to exist\n");
301     ok(size == lstrlen(dest_save) + 1, "Expected size to be lstrlen(dest_save) + 1\n");
302
303     /* try SP_COPY_DELETESOURCE */
304     SetLastError(0xdeadbeef);
305     res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_DELETESOURCE, NULL, 0, NULL, NULL);
306     ok(res == TRUE, "Expected TRUE, got %d\n", res);
307     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
308     ok(!file_exists(path), "Expected source inf to not exist\n");
309
310     if (pSetupUninstallOEMInfA)
311     {
312         char *destfile = strrchr(dest, '\\') + 1;
313
314         SetLastError(0xdeadbeef);
315         ok(pSetupUninstallOEMInfA(destfile, 0, NULL), "Failed to uninstall '%s' : %d\n", destfile, GetLastError());
316     }
317     else
318     {
319         /* Win9x/WinMe */
320         SetLastError(0xdeadbeef);
321         ok(DeleteFileA(dest), "Failed to delete file '%s' : %d\n", dest, GetLastError());
322
323         /* On WinMe we also need to remove the .pnf file */
324         *(strrchr(dest, '.') + 1) = 'p';
325         DeleteFileA(dest);
326     }
327 }
328
329 static void create_source_file(LPSTR filename, const BYTE *data, DWORD size)
330 {
331     HANDLE handle;
332     DWORD written;
333
334     handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
335     WriteFile(handle, data, size, &written, NULL);
336     CloseHandle(handle);
337 }
338
339 static BOOL compare_file_data(LPSTR file, const BYTE *data, DWORD size)
340 {
341     DWORD read;
342     HANDLE handle;
343     BOOL ret = FALSE;
344     LPBYTE buffer;
345
346     handle = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
347     buffer = HeapAlloc(GetProcessHeap(), 0, size);
348     if (buffer)
349     {
350         ReadFile(handle, buffer, size, &read, NULL);
351         if (read == size && !memcmp(data, buffer, size)) ret = TRUE;
352         HeapFree(GetProcessHeap(), 0, buffer);
353     }
354     CloseHandle(handle);
355     return ret;
356 }
357
358 static const BYTE uncompressed[] = {
359     'u','n','c','o','m','p','r','e','s','s','e','d','\r','\n'
360 };
361 static const BYTE comp_lzx[] = {
362     0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33, 0x41, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xff, 0x00,
363     0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x3f, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64
364 };
365 static const BYTE comp_zip[] = {
366     0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11,
367     0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x15, 0x00, 0x77, 0x69,
368     0x6e, 0x65, 0x55, 0x54, 0x09, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46, 0xfd, 0x0d, 0x10, 0x46, 0x55,
369     0x78, 0x04, 0x00, 0xe8, 0x03, 0xe8, 0x03, 0x00, 0x00, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72,
370     0x65, 0x73, 0x73, 0x65, 0x64, 0x50, 0x4b, 0x01, 0x02, 0x17, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00,
371     0x00, 0xbd, 0xae, 0x81, 0x36, 0x75, 0x11, 0x2c, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
372     0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00,
373     0x00, 0x00, 0x00, 0x77, 0x69, 0x6e, 0x65, 0x55, 0x54, 0x05, 0x00, 0x03, 0xd6, 0x0d, 0x10, 0x46,
374     0x55, 0x78, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
375     0x3f, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00
376 };
377 static const BYTE comp_cab_lzx[] = {
378     0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379     0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
380     0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x0f, 0x0e, 0x00, 0x00, 0x00,
381     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x36, 0x86, 0x72, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
382     0x00, 0x19, 0xd0, 0x1a, 0xe3, 0x22, 0x00, 0x0e, 0x00, 0x5b, 0x80, 0x80, 0x8d, 0x00, 0x30, 0xe0,
383     0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x6e, 0x63,
384     0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x0d, 0x0a
385 };
386 static const BYTE comp_cab_zip[] =  {
387     0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388     0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
389     0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00,
390     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x36, 0x2f, 0xa5, 0x20, 0x00, 0x77, 0x69, 0x6e, 0x65,
391     0x00, 0x7c, 0x80, 0x26, 0x2b, 0x12, 0x00, 0x0e, 0x00, 0x43, 0x4b, 0x2b, 0xcd, 0x4b, 0xce, 0xcf,
392     0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e, 0x4d, 0xe1, 0xe5, 0x02, 0x00
393 };
394
395 static void test_SetupGetFileCompressionInfo(void)
396 {
397     DWORD ret, source_size, target_size;
398     char source[MAX_PATH], temp[MAX_PATH], *name;
399     UINT type;
400
401     GetTempPathA(sizeof(temp), temp);
402     GetTempFileNameA(temp, "fci", 0, source);
403
404     create_source_file(source, uncompressed, sizeof(uncompressed));
405
406     ret = SetupGetFileCompressionInfoA(NULL, NULL, NULL, NULL, NULL);
407     ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
408
409     ret = SetupGetFileCompressionInfoA(source, NULL, NULL, NULL, NULL);
410     ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
411
412     ret = SetupGetFileCompressionInfoA(source, &name, NULL, NULL, NULL);
413     ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
414
415     ret = SetupGetFileCompressionInfoA(source, &name, &source_size, NULL, NULL);
416     ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
417
418     ret = SetupGetFileCompressionInfoA(source, &name, &source_size, &target_size, NULL);
419     ok(ret == ERROR_INVALID_PARAMETER, "SetupGetFileCompressionInfo failed unexpectedly\n");
420
421     name = NULL;
422     source_size = target_size = 0;
423     type = 5;
424
425     ret = SetupGetFileCompressionInfoA(source, &name, &source_size, &target_size, &type);
426     ok(!ret, "SetupGetFileCompressionInfo failed unexpectedly\n");
427     ok(name && !lstrcmpA(name, source), "got %s, expected %s\n", name, source);
428     ok(source_size == sizeof(uncompressed), "got %d\n", source_size);
429     ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
430     ok(type == FILE_COMPRESSION_NONE, "got %d, expected FILE_COMPRESSION_NONE\n", type);
431
432     MyFree(name);
433     DeleteFileA(source);
434 }
435
436 static void test_SetupGetFileCompressionInfoEx(void)
437 {
438     BOOL ret;
439     DWORD required_len, source_size, target_size;
440     char source[MAX_PATH], temp[MAX_PATH], name[MAX_PATH];
441     UINT type;
442
443     GetTempPathA(sizeof(temp), temp);
444     GetTempFileNameA(temp, "doc", 0, source);
445
446     ret = pSetupGetFileCompressionInfoExA(NULL, NULL, 0, NULL, NULL, NULL, NULL);
447     ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
448
449     ret = pSetupGetFileCompressionInfoExA(source, NULL, 0, NULL, NULL, NULL, NULL);
450     ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
451
452     ret = pSetupGetFileCompressionInfoExA(source, NULL, 0, &required_len, NULL, NULL, NULL);
453     ok(!ret, "SetupGetFileCompressionInfoEx succeeded unexpectedly\n");
454     ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
455
456     create_source_file(source, comp_lzx, sizeof(comp_lzx));
457
458     ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
459     ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
460     ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
461     ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
462     ok(source_size == sizeof(comp_lzx), "got %d\n", source_size);
463     ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
464     ok(type == FILE_COMPRESSION_WINLZA, "got %d, expected FILE_COMPRESSION_WINLZA\n", type);
465     DeleteFileA(source);
466
467     create_source_file(source, comp_zip, sizeof(comp_zip));
468
469     ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
470     ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
471     ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
472     ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
473     ok(source_size == sizeof(comp_zip), "got %d\n", source_size);
474     ok(target_size == sizeof(comp_zip), "got %d\n", target_size);
475     ok(type == FILE_COMPRESSION_NONE, "got %d, expected FILE_COMPRESSION_NONE\n", type);
476     DeleteFileA(source);
477
478     create_source_file(source, comp_cab_lzx, sizeof(comp_cab_lzx));
479
480     ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
481     ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
482     ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
483     ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
484     ok(source_size == sizeof(comp_cab_lzx), "got %d\n", source_size);
485     ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
486     ok(type == FILE_COMPRESSION_MSZIP, "got %d, expected FILE_COMPRESSION_MSZIP\n", type);
487     DeleteFileA(source);
488
489     create_source_file(source, comp_cab_zip, sizeof(comp_cab_zip));
490
491     ret = pSetupGetFileCompressionInfoExA(source, name, sizeof(name), &required_len, &source_size, &target_size, &type);
492     ok(ret, "SetupGetFileCompressionInfoEx failed unexpectedly: %d\n", ret);
493     ok(!lstrcmpA(name, source), "got %s, expected %s\n", name, source);
494     ok(required_len == lstrlenA(source) + 1, "got %d, expected %d\n", required_len, lstrlenA(source) + 1);
495     ok(source_size == sizeof(comp_cab_zip), "got %d\n", source_size);
496     ok(target_size == sizeof(uncompressed), "got %d\n", target_size);
497     ok(type == FILE_COMPRESSION_MSZIP, "got %d, expected FILE_COMPRESSION_MSZIP\n", type);
498     DeleteFileA(source);
499 }
500
501 static void test_SetupDecompressOrCopyFile(void)
502 {
503     DWORD ret;
504     char source[MAX_PATH], target[MAX_PATH], temp[MAX_PATH], *p;
505     UINT type;
506
507     GetTempPathA(sizeof(temp), temp);
508     GetTempFileNameA(temp, "doc", 0, source);
509     GetTempFileNameA(temp, "doc", 0, target);
510
511     /* parameter tests */
512
513     create_source_file(source, uncompressed, sizeof(uncompressed));
514
515     ret = SetupDecompressOrCopyFileA(NULL, NULL, NULL);
516     ok(ret == ERROR_INVALID_PARAMETER, "SetupDecompressOrCopyFile failed unexpectedly\n");
517
518     type = FILE_COMPRESSION_NONE;
519     ret = SetupDecompressOrCopyFileA(NULL, target, &type);
520     ok(ret == ERROR_INVALID_PARAMETER, "SetupDecompressOrCopyFile failed unexpectedly\n");
521
522     ret = SetupDecompressOrCopyFileA(source, NULL, &type);
523     ok(ret == ERROR_INVALID_PARAMETER, "SetupDecompressOrCopyFile failed unexpectedly\n");
524
525     type = 5; /* try an invalid compression type */
526     ret = SetupDecompressOrCopyFileA(source, target, &type);
527     ok(ret == ERROR_INVALID_PARAMETER, "SetupDecompressOrCopyFile failed unexpectedly\n");
528
529     DeleteFileA(target);
530
531     /* no compression tests */
532
533     ret = SetupDecompressOrCopyFileA(source, target, NULL);
534     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
535     ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
536
537     /* try overwriting existing file */
538     ret = SetupDecompressOrCopyFileA(source, target, NULL);
539     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
540     DeleteFileA(target);
541
542     type = FILE_COMPRESSION_NONE;
543     ret = SetupDecompressOrCopyFileA(source, target, &type);
544     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
545     ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
546     DeleteFileA(target);
547
548     type = FILE_COMPRESSION_WINLZA;
549     ret = SetupDecompressOrCopyFileA(source, target, &type);
550     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
551     ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
552     DeleteFileA(target);
553
554     /* lz compression tests */
555
556     create_source_file(source, comp_lzx, sizeof(comp_lzx));
557
558     ret = SetupDecompressOrCopyFileA(source, target, NULL);
559     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
560     DeleteFileA(target);
561
562     /* zip compression tests */
563
564     create_source_file(source, comp_zip, sizeof(comp_zip));
565
566     ret = SetupDecompressOrCopyFileA(source, target, NULL);
567     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
568     ok(compare_file_data(target, comp_zip, sizeof(comp_zip)), "incorrect target file\n");
569     DeleteFileA(target);
570
571     /* cabinet compression tests */
572
573     create_source_file(source, comp_cab_zip, sizeof(comp_cab_zip));
574
575     p = strrchr(target, '\\');
576     lstrcpyA(p + 1, "wine");
577
578     ret = SetupDecompressOrCopyFileA(source, target, NULL);
579     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
580     ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
581
582     /* try overwriting existing file */
583     ret = SetupDecompressOrCopyFileA(source, target, NULL);
584     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
585
586     /* try zip compression */
587     type = FILE_COMPRESSION_MSZIP;
588     ret = SetupDecompressOrCopyFileA(source, target, &type);
589     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
590     ok(compare_file_data(target, uncompressed, sizeof(uncompressed)), "incorrect target file\n");
591
592     /* try no compression */
593     type = FILE_COMPRESSION_NONE;
594     ret = SetupDecompressOrCopyFileA(source, target, &type);
595     ok(!ret, "SetupDecompressOrCopyFile failed unexpectedly: %d\n", ret);
596     ok(compare_file_data(target, comp_cab_zip, sizeof(comp_cab_zip)), "incorrect target file\n");
597
598     DeleteFileA(target);
599     DeleteFileA(source);
600 }
601
602 static void test_SetupUninstallOEMInf(void)
603 {
604     BOOL ret;
605
606     SetLastError(0xdeadbeef);
607     ret = pSetupUninstallOEMInfA(NULL, 0, NULL);
608     ok(!ret, "Expected failure\n");
609     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
610
611     SetLastError(0xdeadbeef);
612     ret = pSetupUninstallOEMInfA("", 0, NULL);
613     todo_wine
614     {
615     ok(!ret, "Expected failure\n");
616     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
617     }
618
619     SetLastError(0xdeadbeef);
620     ret = pSetupUninstallOEMInfA("nonexistent.inf", 0, NULL);
621     todo_wine
622     {
623     ok(!ret, "Expected failure\n");
624     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
625     }
626 }
627
628 START_TEST(misc)
629 {
630     HMODULE hsetupapi = GetModuleHandle("setupapi.dll");
631
632     pSetupGetFileCompressionInfoExA = (void*)GetProcAddress(hsetupapi, "SetupGetFileCompressionInfoExA");
633     pSetupCopyOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupCopyOEMInfA");
634     pSetupQueryInfOriginalFileInformationA = (void*)GetProcAddress(hsetupapi, "SetupQueryInfOriginalFileInformationA");
635     pSetupUninstallOEMInfA = (void*)GetProcAddress(hsetupapi, "SetupUninstallOEMInfA");
636
637     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
638
639     if (pSetupCopyOEMInfA)
640         test_SetupCopyOEMInf();
641     else
642         win_skip("SetupCopyOEMInfA is not available\n");
643
644     test_SetupGetFileCompressionInfo();
645
646     if (pSetupGetFileCompressionInfoExA)
647         test_SetupGetFileCompressionInfoEx();
648     else
649         win_skip("SetupGetFileCompressionInfoExA is not available\n");
650
651     test_SetupDecompressOrCopyFile();
652
653     if (pSetupUninstallOEMInfA)
654         test_SetupUninstallOEMInf();
655     else
656         win_skip("SetupUninstallOEMInfA is not available\n");
657 }