[APITESTS] Use StringCbPrintfA instead of sprintf
[reactos.git] / modules / rostests / apitests / setupapi / SetupDiInstallClassExA.c
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
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, strlen(data), &res, NULL);
43 assert(ret != 0);
44 CloseHandle(handle);
45 }
46
47 static void test_SetupDiInstallClassExA(void)
48 {
49 char inf[2048];
50 char path[MAX_PATH];
51 BOOL ret;
52 ULONG del;
53 HKEY RegHandle;
54 HINF infhandle;
55 SC_HANDLE scm_handle, svc_handle;
56
57 /* [Version]:Signature */
58 strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n");
59 create_inf_file(inffile, inf);
60 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
61
62 SetLastError(0xdeadbeef);
63 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
64 ok(!ret, "Expected failure\n");
65 ok(GetLastError() == ERROR_INVALID_CLASS,
66 "Expected ERROR_INVALID_CLASS, got %08x\n", (int)GetLastError());
67 DeleteFileA(inffile);
68
69 /* [Version]:Signature+Class */
70 strcat(inf, "Class=MySampleClass\n");
71 create_inf_file(inffile, inf);
72 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
73
74 SetLastError(0xdeadbeef);
75 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
76 ok(!ret, "Expected failure\n");
77 ok(GetLastError() == ERROR_INVALID_CLASS,
78 "Expected ERROR_INVALID_CLASS, got %08x\n", (int)GetLastError());
79 DeleteFileA(inffile);
80
81 /* [Version]:Signature+Class+ClassGUID */
82 strcat(inf, "ClassGuid={3b409830-5f9d-432a-abf5-7d2e4e102467}\n");
83 create_inf_file(inffile, inf);
84 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
85
86 SetLastError(0xdeadbeef);
87 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
88 ok(!ret, "Expected failure\n");
89 ok(GetLastError() == ERROR_SECTION_NOT_FOUND,
90 "Expected ERROR_SECTION_NOT_FOUND, got %08x\n", (int)GetLastError());
91 DeleteFileA(inffile);
92
93 /* [Version]Signature+Class+ClassGUID;[ClassInstall32.NT]Empty */
94 strcat(inf, "[ClassInstall32.NT]\n");
95 create_inf_file(inffile, inf);
96 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
97
98 SetLastError(0xdeadbeef);
99 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
100 ok(ret, "Expected success\n");
101 ok(!GetLastError(),
102 "Expected no error, got %08x\n", (int)GetLastError());
103 DeleteFileA(inffile);
104 if (ret == TRUE)
105 {
106 RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_ALL_ACCESS, &RegHandle);
107 del = RegDeleteKeyW(RegHandle, L"CurrentControlSet\\Control\\Class\\{3B409830-5F9D-432A-ABF5-7D2E4E102467}");
108 ok(del == ERROR_SUCCESS, "Expected success \n");
109 }
110
111 /* [Version]Signature+Class+ClassGUID;[ClassInstall32.NT]AddReg */
112 strcat(inf, "AddReg=SampleClassAddReg\n");
113 create_inf_file(inffile, inf);
114 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
115
116 SetLastError(0xdeadbeef);
117 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
118 ok(ret, "Expected success\n");
119 ok(!GetLastError(),
120 "Expected no error, got %08x\n", (int)GetLastError());
121 DeleteFileA(inffile);
122 if (ret == TRUE)
123 {
124 RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_ALL_ACCESS, &RegHandle);
125 del = RegDeleteKeyW(RegHandle, L"CurrentControlSet\\Control\\Class\\{3B409830-5F9D-432A-ABF5-7D2E4E102467}");
126 ok(del == ERROR_SUCCESS, "Expected success \n");
127 }
128
129 /* [Version]Signature+Class+ClassGUID;[ClassInstall32.NT]AddReg; [SampleClassAddReg];*/
130 strcat(inf, "[SampleClassAddReg]\n");
131 create_inf_file(inffile, inf);
132 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
133
134 SetLastError(0xdeadbeef);
135 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
136 ok(ret, "Expected success\n");
137 ok(!GetLastError(),
138 "Expected no error, got %08x\n", (int)GetLastError());
139 DeleteFileA(inffile);
140 if (ret == TRUE)
141 {
142 RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_ALL_ACCESS, &RegHandle);
143 del = RegDeleteKeyW(RegHandle, L"CurrentControlSet\\Control\\Class\\{3B409830-5F9D-432A-ABF5-7D2E4E102467}");
144 ok(del == ERROR_SUCCESS, "Expected success \n");
145 }
146
147 /* [Version]Signature+Class+ClassGUID;[ClassInstall32.NT]AddReg; [SampleClassAddReg]HKR;*/
148 strcat(inf, "HKR,,,,\"ReactOS Test SetupDiInstallClassExA\"\n");
149 create_inf_file(inffile, inf);
150 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
151
152 SetLastError(0xdeadbeef);
153 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
154 ok(ret, "Expected success\n");
155 ok(!GetLastError(),
156 "Expected no error, got %08x\n", (int)GetLastError());
157 DeleteFileA(inffile);
158 if (ret == TRUE)
159 {
160 RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_ALL_ACCESS, &RegHandle);
161 del = RegDeleteKeyW(RegHandle, L"CurrentControlSet\\Control\\Class\\{3B409830-5F9D-432A-ABF5-7D2E4E102467}");
162 ok(del == ERROR_SUCCESS, "Expected success \n");
163 }
164
165 /*[Version]Signature+Class+ClassGUID;[ClassInstall32.NT]AddReg;[SampleClassAddReg]HKR;[ClassInstall32.NT.Services]*/
166 strcat(inf, "[ClassInstall32.NT.Services]\n");
167 create_inf_file(inffile, inf);
168 StringCbPrintfA(path, sizeof(path), "%s\\%s", CURR_DIR, inffile);
169
170 SetLastError(0xdeadbeef);
171 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
172 ok(ret, "Expected success\n");
173 ok(!GetLastError(),
174 "Expected no error, got %08x\n", (int)GetLastError());
175 DeleteFileA(inffile);
176 if (ret == TRUE)
177 {
178 RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_ALL_ACCESS, &RegHandle);
179 del = RegDeleteKeyW(RegHandle, L"CurrentControlSet\\Control\\Class\\{3B409830-5F9D-432A-ABF5-7D2E4E102467}");
180 ok(del == ERROR_SUCCESS, "Expected success\n");
181 }
182
183 /* Add a reference */
184 strcat(inf, "AddService=Reactostest,,Reactostest.Service\n");
185 create_inf_file(inffile, inf);
186 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
187 SetLastError(0xdeadbeef);
188 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
189 ok(!ret, "Expected failure\n");
190 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
191 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", (int)GetLastError());
192 SetupCloseInfFile(infhandle);
193 DeleteFileA(inffile);
194
195 /* Add the section */
196 strcat(inf, "[Reactostest.Service]\n");
197 create_inf_file(inffile, inf);
198 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
199 SetLastError(0xdeadbeef);
200 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
201 ok(!ret, "Expected failure\n");
202 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
203 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", (int)GetLastError());
204 SetupCloseInfFile(infhandle);
205 DeleteFileA(inffile);
206
207 /* Just the ServiceBinary */
208 strcat(inf, "ServiceBinary=%12%\\reactostest.sys\n");
209 create_inf_file(inffile, inf);
210 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
211 SetLastError(0xdeadbeef);
212 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
213 ok(!ret, "Expected failure\n");
214 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
215 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", (int)GetLastError());
216 SetupCloseInfFile(infhandle);
217 DeleteFileA(inffile);
218
219 /* Add the ServiceType */
220 strcat(inf, "ServiceType=1\n");
221 create_inf_file(inffile, inf);
222 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
223 SetLastError(0xdeadbeef);
224 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
225 ok(!ret, "Expected failure\n");
226 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
227 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", (int)GetLastError());
228 SetupCloseInfFile(infhandle);
229 DeleteFileA(inffile);
230
231 /* Add the StartType */
232 strcat(inf, "StartType=4\n");
233 create_inf_file(inffile, inf);
234 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
235 SetLastError(0xdeadbeef);
236 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
237 ok(!ret, "Expected failure\n");
238 ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT,
239 "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", (int)GetLastError());
240 SetupCloseInfFile(infhandle);
241 DeleteFileA(inffile);
242
243 /* This should be it, the minimal entries to install a service */
244 strcat(inf, "ErrorControl=1");
245 create_inf_file(inffile, inf);
246 infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
247 SetLastError(0xdeadbeef);
248 ret = SetupDiInstallClassExA(NULL, path, DI_QUIETINSTALL, NULL, NULL, NULL,NULL);
249 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
250 {
251 skip("Not enough rights to install the service\n");
252 SetupCloseInfFile(infhandle);
253 DeleteFileA(inffile);
254 return;
255 }
256 ok(ret, "Expected success\n");
257 ok(GetLastError() == ERROR_SUCCESS,
258 "Expected ERROR_SUCCESS, got %08x\n", (int)GetLastError());
259 SetupCloseInfFile(infhandle);
260 DeleteFileA(inffile);
261
262 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
263
264 /* Open the service to see if it's really there */
265 svc_handle = OpenServiceA(scm_handle, "Reactostest", DELETE);
266 ok(svc_handle != NULL, "Service was not created\n");
267
268 SetLastError(0xdeadbeef);
269 ret = DeleteService(svc_handle);
270 ok(ret, "Service could not be deleted : %d\n", (int)GetLastError());
271
272 CloseServiceHandle(svc_handle);
273 CloseServiceHandle(scm_handle);
274 }
275
276
277 START_TEST(SetupDiInstallClassExA)
278 {
279 char temp_path[MAX_PATH], prev_path[MAX_PATH];
280 DWORD len;
281
282 GetCurrentDirectoryA(MAX_PATH, prev_path);
283 GetTempPathA(MAX_PATH, temp_path);
284 SetCurrentDirectoryA(temp_path);
285
286 strcpy(CURR_DIR, temp_path);
287 len = strlen(CURR_DIR);
288 if (len && (CURR_DIR[len - 1] == '\\'))
289 CURR_DIR[len - 1] = 0;
290
291 test_SetupDiInstallClassExA();
292 SetCurrentDirectoryA(prev_path);
293
294 }