1 /*
2 * SetupAPI device class-related functions tests
3 *
4 * Copyright 2015 V�ctor Mart�nez (victor.martinez@reactos.org)
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence as
8 * published by the Free Software Foundation; either version 2 of
9 * 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 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this library; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <apitest.h>
22 #include <stdio.h>
23 #include <assert.h>
24 #include <winuser.h>
25 #include <winreg.h>
26 #include <winsvc.h>
27 #include <setupapi.h>
28 #include <strsafe.h>
29
30 static const char inffile[] = "test.inf";
31 static char CURR_DIR[MAX_PATH];
32
33 /* Helpers */
34
create_inf_file(LPCSTR filename,const char * data)35 static void create_inf_file(LPCSTR filename, const char *data)
36 {
37 DWORD res;
38 BOOL ret;
39 HANDLE handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
40 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
41 assert(handle != INVALID_HANDLE_VALUE);
42 ret = WriteFile(handle, data, lstrlenA(data), &res, NULL);
43 assert(ret != 0);
44 CloseHandle(handle);
45 }
46
47 /* CBT hook to ensure a window (e.g., MessageBox) cannot be created */
48 static HHOOK hhook;
cbt_hook_proc(int nCode,WPARAM wParam,LPARAM lParam)49 static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
50 {
51 return nCode == HCBT_CREATEWND ? 1: CallNextHookEx(hhook, nCode, wParam, lParam);
52 }
53
test_SetupInstallServicesFromInfSectionExA(void)54 static void test_SetupInstallServicesFromInfSectionExA(void)
55 {
56 char inf[2048];
57 char path[MAX_PATH];
58 HINF infhandle;
59 BOOL ret;
60 SC_HANDLE scm_handle, svc_handle;
61
62 /* Bail out if we are on win98 */
63 SetLastError(0xdeadbeef);
64 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
65
66 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
67 {
68 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
69 return;
70 }
71 CloseServiceHandle(scm_handle);
72
73 /* Basic inf file to satisfy SetupOpenInfFileA */
74 strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n");
75 create_inf_file(inffile, inf);
76 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
77 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
78
79 /* Nothing but the Version section */
80 SetLastError(0xdeadbeef);
81 ret = SetupInstallServicesFromInfSectionExA(infhandle, "trolololo", 0, NULL, NULL, NULL,NULL);
82 ok(!ret, "Expected failure\n");
83 ok(GetLastError() == ERROR_SECTION_NOT_FOUND,
84 "Expected ERROR_SECTION_NOT_FOUND, got %08d\n", (int)GetLastError());
85 SetupCloseInfFile(infhandle);
86 DeleteFileA(inffile);
87
88
89 /* Add the section */
90 strcat(inf, "[Winetest.Services]\n");
91 create_inf_file(inffile, inf);
92 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
93 SetLastError(0xdeadbeef);
94 ret = SetupInstallServicesFromInfSectionExA(infhandle, "Winetest.Services", 0, NULL, NULL, NULL, NULL);
95 ok(!ret, "Expected failure\n");
96 ok(GetLastError() == ERROR_SECTION_NOT_FOUND,
97 "Expected ERROR_SECTION_NOT_FOUND, got %08d\n", (int)GetLastError());
98 SetupCloseInfFile(infhandle);
99 DeleteFileA(inffile);
100
101 /* Add a reference */
102 strcat(inf, "AddService=Winetest,,Winetest.Service\n");
103 create_inf_file(inffile, inf);
104 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
105 SetLastError(0xdeadbeef);
106 ret = SetupInstallServicesFromInfSectionExA(infhandle, "Winetest.Services", 0, NULL, NULL, NULL, NULL);
107 ok(!ret, "Expected failure\n");
108 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
109 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
110 SetupCloseInfFile(infhandle);
111 DeleteFileA(inffile);
112
113 /* Add the section */
114 strcat(inf, "[Winetest.Service]\n");
115 create_inf_file(inffile, inf);
116 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
117 SetLastError(0xdeadbeef);
118 ret = SetupInstallServicesFromInfSectionExA(infhandle, "Winetest.Services", 0, NULL, NULL, NULL, NULL);
119 ok(!ret, "Expected failure\n");
120 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
121 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
122 SetupCloseInfFile(infhandle);
123 DeleteFileA(inffile);
124
125 /* Just the ServiceBinary */
126 strcat(inf, "ServiceBinary=%12%\\winetest.sys\n");
127 create_inf_file(inffile, inf);
128 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
129 SetLastError(0xdeadbeef);
130 ret = SetupInstallServicesFromInfSectionExA(infhandle, "Winetest.Services", 0, NULL, NULL, NULL, NULL);
131 ok(!ret, "Expected failure\n");
132 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
133 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
134 SetupCloseInfFile(infhandle);
135 DeleteFileA(inffile);
136
137 /* Add the ServiceType */
138 strcat(inf, "ServiceType=1\n");
139 create_inf_file(inffile, inf);
140 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
141 SetLastError(0xdeadbeef);
142 ret = SetupInstallServicesFromInfSectionExA(infhandle, "Winetest.Services", 0, NULL, NULL, NULL, NULL);
143 ok(!ret, "Expected failure\n");
144 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
145 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
146 SetupCloseInfFile(infhandle);
147 DeleteFileA(inffile);
148
149 /* Add the StartType */
150 strcat(inf, "StartType=4\n");
151 create_inf_file(inffile, inf);
152 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
153 SetLastError(0xdeadbeef);
154 ret = SetupInstallServicesFromInfSectionExA(infhandle, "Winetest.Services", 0, NULL, NULL, NULL, NULL);
155 ok(!ret, "Expected failure\n");
156 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
157 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
158 SetupCloseInfFile(infhandle);
159 DeleteFileA(inffile);
160
161 /* This should be it, the minimal entries to install a service */
162 strcat(inf, "ErrorControl=1");
163 create_inf_file(inffile, inf);
164 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
165 SetLastError(0xdeadbeef);
166 ret = SetupInstallServicesFromInfSectionExA(infhandle, "Winetest.Services", 0, NULL, NULL, NULL, NULL);
167 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
168 {
169 skip("Not enough rights to install the service\n");
170 SetupCloseInfFile(infhandle);
171 DeleteFileA(inffile);
172 return;
173 }
174 ok(ret, "Expected success\n");
175 ok(GetLastError() == ERROR_SUCCESS,
176 "Expected ERROR_SUCCESS, got %08d\n", (int)GetLastError());
177 SetupCloseInfFile(infhandle);
178 DeleteFileA(inffile);
179
180 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
181
182 /* Open the service to see if it's really there */
183 svc_handle = OpenServiceA(scm_handle, "Winetest", DELETE);
184 ok(svc_handle != NULL, "Service was not created\n");
185
186 SetLastError(0xdeadbeef);
187 ret = DeleteService(svc_handle);
188 ok(ret, "Service could not be deleted : %d\n", (int)GetLastError());
189
190 CloseServiceHandle(svc_handle);
191 CloseServiceHandle(scm_handle);
192
193 strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n");
194 strcat(inf, "[XSP.InstallPerVer]\n");
195 strcat(inf, "AddReg=AspEventlogMsg.Reg,Perf.Reg,AspVersions.Reg,FreeADO.Reg,IndexServer.Reg\n");
196 create_inf_file(inffile, inf);
197 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
198 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
199
200 SetLastError(0xdeadbeef);
201 ret = SetupInstallServicesFromInfSectionExA(infhandle, "XSP.InstallPerVer", 0, NULL, NULL, NULL,NULL);
202 ok(ret, "Expected success\n");
203 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08d\n", (int)GetLastError());
204 SetupCloseInfFile(infhandle);
205 DeleteFileA(inffile);
206
207 /* TODO: Test the Flags */
208 }
test_SetupInstallServicesFromInfSectionExW(void)209 static void test_SetupInstallServicesFromInfSectionExW(void)
210 {
211 char inf[2048];
212 char path[MAX_PATH];
213 HINF infhandle;
214 BOOL ret;
215 SC_HANDLE scm_handle, svc_handle;
216
217 /* Bail out if we are on win98 */
218 SetLastError(0xdeadbeef);
219 scm_handle = OpenSCManagerW(NULL, NULL, GENERIC_ALL);
220
221 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
222 {
223 win_skip("OpenSCManagerW is not implemented, we are most likely on win9x\n");
224 return;
225 }
226 CloseServiceHandle(scm_handle);
227
228 /* Basic inf file to satisfy SetupOpenInfFileA */
229 strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n");
230 create_inf_file(inffile, inf);
231 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
232 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
233
234 /* Nothing but the Version section */
235 SetLastError(0xdeadbeef);
236 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"trolololo", 0, NULL, NULL, NULL,NULL);
237 ok(!ret, "Expected failure\n");
238 ok(GetLastError() == ERROR_SECTION_NOT_FOUND,
239 "Expected ERROR_SECTION_NOT_FOUND, got %08d\n", (int)GetLastError());
240 SetupCloseInfFile(infhandle);
241 DeleteFileA(inffile);
242
243
244 /* Add the section */
245 strcat(inf, "[Winetest.Services]\n");
246 create_inf_file(inffile, inf);
247 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
248 SetLastError(0xdeadbeef);
249 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"Winetest.Services", 0, NULL, NULL, NULL, NULL);
250 ok(!ret, "Expected failure\n");
251 ok(GetLastError() == ERROR_SECTION_NOT_FOUND,
252 "Expected ERROR_SECTION_NOT_FOUND, got %08d\n", (int)GetLastError());
253 SetupCloseInfFile(infhandle);
254 DeleteFileA(inffile);
255
256 /* Add a reference */
257 strcat(inf, "AddService=Winetest,,Winetest.Service\n");
258 create_inf_file(inffile, inf);
259 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
260 SetLastError(0xdeadbeef);
261 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"Winetest.Services", 0, NULL, NULL, NULL, NULL);
262 ok(!ret, "Expected failure\n");
263 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
264 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
265 SetupCloseInfFile(infhandle);
266 DeleteFileA(inffile);
267
268 /* Add the section */
269 strcat(inf, "[Winetest.Service]\n");
270 create_inf_file(inffile, inf);
271 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
272 SetLastError(0xdeadbeef);
273 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"Winetest.Services", 0, NULL, NULL, NULL, NULL);
274 ok(!ret, "Expected failure\n");
275 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
276 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
277 SetupCloseInfFile(infhandle);
278 DeleteFileA(inffile);
279
280 /* Just the ServiceBinary */
281 strcat(inf, "ServiceBinary=%12%\\winetest.sys\n");
282 create_inf_file(inffile, inf);
283 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
284 SetLastError(0xdeadbeef);
285 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"Winetest.Services", 0, NULL, NULL, NULL, NULL);
286 ok(!ret, "Expected failure\n");
287 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
288 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
289 SetupCloseInfFile(infhandle);
290 DeleteFileA(inffile);
291
292 /* Add the ServiceType */
293 strcat(inf, "ServiceType=1\n");
294 create_inf_file(inffile, inf);
295 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
296 SetLastError(0xdeadbeef);
297 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"Winetest.Services", 0, NULL, NULL, NULL, NULL);
298 ok(!ret, "Expected failure\n");
299 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
300 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
301 SetupCloseInfFile(infhandle);
302 DeleteFileA(inffile);
303
304 /* Add the StartType */
305 strcat(inf, "StartType=4\n");
306 create_inf_file(inffile, inf);
307 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
308 SetLastError(0xdeadbeef);
309 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"Winetest.Services", 0, NULL, NULL, NULL, NULL);
310 ok(!ret, "Expected failure\n");
311 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
312 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08d\n", (int)GetLastError());
313 SetupCloseInfFile(infhandle);
314 DeleteFileA(inffile);
315
316 /* This should be it, the minimal entries to install a service */
317 strcat(inf, "ErrorControl=1");
318 create_inf_file(inffile, inf);
319 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
320 SetLastError(0xdeadbeef);
321 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"Winetest.Services", 0, NULL, NULL, NULL, NULL);
322 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
323 {
324 skip("Not enough rights to install the service\n");
325 SetupCloseInfFile(infhandle);
326 DeleteFileA(inffile);
327 return;
328 }
329 ok(ret, "Expected success\n");
330 ok(GetLastError() == ERROR_SUCCESS,
331 "Expected ERROR_SUCCESS, got %08d\n", (int)GetLastError());
332 SetupCloseInfFile(infhandle);
333 DeleteFileA(inffile);
334
335 scm_handle = OpenSCManagerW(NULL, NULL, GENERIC_ALL);
336
337 /* Open the service to see if it's really there */
338 svc_handle = OpenServiceW(scm_handle, L"Winetest", DELETE);
339 ok(svc_handle != NULL, "Service was not created\n");
340
341 SetLastError(0xdeadbeef);
342 ret = DeleteService(svc_handle);
343 ok(ret, "Service could not be deleted : %d\n", (int)GetLastError());
344
345 CloseServiceHandle(svc_handle);
346 CloseServiceHandle(scm_handle);
347
348 strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n");
349 strcat(inf, "[XSP.InstallPerVer]\n");
350 strcat(inf, "AddReg=AspEventlogMsg.Reg,Perf.Reg,AspVersions.Reg,FreeADO.Reg,IndexServer.Reg\n");
351 create_inf_file(inffile, inf);
352 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
353 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
354
355 SetLastError(0xdeadbeef);
356 ret = SetupInstallServicesFromInfSectionExW(infhandle, L"XSP.InstallPerVer", 0, NULL, NULL, NULL, NULL);
357 ok(ret, "Expected success\n");
358 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08d\n", (int)GetLastError());
359 SetupCloseInfFile(infhandle);
360 DeleteFileA(inffile);
361
362 /* TODO: Test the Flags */
363 }
364
365
START_TEST(SetupInstallServicesFromInfSectionEx)366 START_TEST(SetupInstallServicesFromInfSectionEx)
367 {
368 char temp_path[MAX_PATH], prev_path[MAX_PATH];
369
370 GetCurrentDirectoryA(MAX_PATH, prev_path);
371 GetTempPathA(MAX_PATH, temp_path);
372 SetCurrentDirectoryA(temp_path);
373
374 strcpy(CURR_DIR, temp_path);
375
376 /* Set CBT hook to disallow MessageBox creation in current thread */
377 hhook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());
378 assert(hhook != 0);
379
380 test_SetupInstallServicesFromInfSectionExA();
381 test_SetupInstallServicesFromInfSectionExW();
382
383 UnhookWindowsHookEx(hhook);
384 SetCurrentDirectoryA(prev_path);
385 }
386