setupapi: Don't allow relative paths in SetupCopyOEMInf.
[wine] / dlls / setupapi / tests / misc.c
1 /*
2  * Miscellaneous tests
3  *
4  * Copyright 2007 James Hawkins
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "winreg.h"
29 #include "setupapi.h"
30
31 #include "wine/test.h"
32
33 static CHAR CURR_DIR[MAX_PATH];
34
35 /* test:
36  *  - fails if not administrator
37  *  - what if it's not a .inf file?
38  *  - copied to %windir%/Inf
39  *  - SourceInfFileName should be a full path
40  *  - SourceInfFileName should be <= MAX_PATH
41  *  - copy styles
42  */
43
44 static void append_str(char **str, const char *data)
45 {
46     sprintf(*str, data);
47     *str += strlen(*str);
48 }
49
50 static void create_inf_file(LPCSTR filename)
51 {
52     char data[1024];
53     char *ptr = data;
54     DWORD dwNumberOfBytesWritten;
55     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
56                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
57
58     append_str(&ptr, "[Version]\n");
59     append_str(&ptr, "Signature=\"$Chicago$\"\n");
60     append_str(&ptr, "AdvancedINF=2.5\n");
61     append_str(&ptr, "[DefaultInstall]\n");
62     append_str(&ptr, "RegisterOCXs=RegisterOCXsSection\n");
63     append_str(&ptr, "[RegisterOCXsSection]\n");
64     append_str(&ptr, "%%11%%\\ole32.dll\n");
65
66     WriteFile(hf, data, ptr - data, &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 = !strncmp(check, path, lstrlen(check)) &&
96           path[lstrlen(check)] != '\\';
97
98     return (!inf) ? res : res && (inf == path + lstrlen(check) - 3);
99 }
100
101 static void test_SetupCopyOEMInf(void)
102 {
103     CHAR toolong[MAX_PATH * 2];
104     CHAR path[MAX_PATH], dest[MAX_PATH];
105     CHAR tmpfile[MAX_PATH];
106     LPSTR inf;
107     DWORD size;
108     BOOL res;
109
110     /* try NULL SourceInfFileName */
111     SetLastError(0xdeadbeef);
112     res = SetupCopyOEMInf(NULL, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
113     ok(res == FALSE, "Expected FALSE, got %d\n", res);
114     ok(GetLastError() == ERROR_INVALID_PARAMETER,
115        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
116
117     /* try empty SourceInfFileName */
118     SetLastError(0xdeadbeef);
119     res = SetupCopyOEMInf("", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
120     ok(res == FALSE, "Expected FALSE, got %d\n", res);
121     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
122        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
123
124     /* try a relative nonexistent SourceInfFileName */
125     SetLastError(0xdeadbeef);
126     res = SetupCopyOEMInf("nonexistent", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
127     ok(res == FALSE, "Expected FALSE, got %d\n", res);
128     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
129        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
130
131     /* try an absolute nonexistent SourceInfFileName */
132     lstrcpy(path, CURR_DIR);
133     lstrcat(path, "\\nonexistent");
134     SetLastError(0xdeadbeef);
135     res = SetupCopyOEMInf(path, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
136     ok(res == FALSE, "Expected FALSE, got %d\n", res);
137     todo_wine
138     {
139         ok(GetLastError() == ERROR_FILE_NOT_FOUND,
140            "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
141     }
142
143     /* try a long SourceInfFileName */
144     memset(toolong, 'a', MAX_PATH * 2);
145     toolong[MAX_PATH * 2 - 1] = '\0';
146     SetLastError(0xdeadbeef);
147     res = SetupCopyOEMInf(toolong, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
148     ok(res == FALSE, "Expected FALSE, got %d\n", res);
149     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
150        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
151
152     get_temp_filename(tmpfile);
153     create_inf_file(tmpfile);
154
155     /* try a relative SourceInfFileName */
156     SetLastError(0xdeadbeef);
157     res = SetupCopyOEMInf(tmpfile, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
158     ok(res == FALSE, "Expected FALSE, got %d\n", res);
159     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
160        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
161     ok(file_exists(tmpfile), "Expected tmpfile to exist\n");
162
163     /* try SP_COPY_REPLACEONLY, dest does not exist */
164     SetLastError(0xdeadbeef);
165     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL);
166     ok(res == FALSE, "Expected FALSE, got %d\n", res);
167     todo_wine
168     {
169         ok(GetLastError() == ERROR_FILE_NOT_FOUND,
170            "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
171     }
172     ok(file_exists(tmpfile), "Expected source inf to exist\n");
173
174     /* try an absolute SourceInfFileName, without DestinationInfFileName */
175     lstrcpy(path, CURR_DIR);
176     lstrcat(path, "\\");
177     lstrcat(path, tmpfile);
178     SetLastError(0xdeadbeef);
179     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, 0, NULL, 0, NULL, NULL);
180     todo_wine
181     {
182         ok(res == TRUE, "Expected TRUE, got %d\n", res);
183         ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
184     }
185     ok(file_exists(path), "Expected source inf to exist\n");
186
187     /* try SP_COPY_REPLACEONLY, dest exists */
188     SetLastError(0xdeadbeef);
189     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL);
190     todo_wine
191     {
192         ok(res == TRUE, "Expected TRUE, got %d\n", res);
193         ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
194     }
195     ok(file_exists(path), "Expected source inf to exist\n");
196
197     /* try SP_COPY_NOOVERWRITE */
198     SetLastError(0xdeadbeef);
199     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL);
200     ok(res == FALSE, "Expected FALSE, got %d\n", res);
201     todo_wine
202     {
203         ok(GetLastError() == ERROR_FILE_EXISTS,
204            "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
205     }
206
207     /* get the DestinationInfFileName */
208     SetLastError(0xdeadbeef);
209     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, NULL, NULL);
210     ok(res == TRUE, "Expected TRUE, got %d\n", res);
211     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
212     ok(lstrlen(dest) != 0, "Expected a non-zero length string\n");
213     ok(file_exists(dest), "Expected destination inf to exist\n");
214     todo_wine
215     {
216         ok(check_format(dest, NULL), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
217     }
218     ok(file_exists(path), "Expected source inf to exist\n");
219
220     /* get the DestinationInfFileName and DestinationInfFileNameSize */
221     SetLastError(0xdeadbeef);
222     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, &size, NULL);
223     ok(res == TRUE, "Expected TRUE, got %d\n", res);
224     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
225     ok(lstrlen(dest) + 1 == size, "Expected sizes to match, got (%d, %d)\n", lstrlen(dest), size);
226     ok(file_exists(dest), "Expected destination inf to exist\n");
227     todo_wine
228     {
229         ok(check_format(dest, NULL), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
230     }
231     ok(file_exists(path), "Expected source inf to exist\n");
232
233     /* get the DestinationInfFileName, DestinationInfFileNameSize, and DestinationInfFileNameComponent */
234     SetLastError(0xdeadbeef);
235     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, 0, dest, MAX_PATH, &size, &inf);
236     ok(res == TRUE, "Expected TRUE, got %d\n", res);
237     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
238     ok(lstrlen(dest) + 1 == size, "Expected sizes to match, got (%d, %d)\n", lstrlen(dest), size);
239     ok(file_exists(dest), "Expected destination inf to exist\n");
240     todo_wine
241     {
242         ok(check_format(dest, inf), "Expected %%windir%%\\inf\\OEMx.inf, got %s\n", dest);
243     }
244     ok(file_exists(path), "Expected source inf to exist\n");
245
246     /* try SP_COPY_DELETESOURCE */
247     SetLastError(0xdeadbeef);
248     res = SetupCopyOEMInf(path, NULL, SPOST_NONE, SP_COPY_DELETESOURCE, NULL, 0, NULL, NULL);
249     todo_wine
250     {
251         ok(res == TRUE, "Expected TRUE, got %d\n", res);
252         ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
253         ok(!file_exists(path), "Expected source inf to not exist\n");
254     }
255 }
256
257 START_TEST(misc)
258 {
259     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
260
261     test_SetupCopyOEMInf();
262 }