Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/advpack/tests/install.c
8709 views
1
/*
2
* Unit tests for advpack.dll install functions
3
*
4
* Copyright (C) 2006 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 <stdio.h>
22
#include <windows.h>
23
#include <advpub.h>
24
#include "wine/test.h"
25
26
static HMODULE hAdvPack;
27
/* function pointers */
28
static HRESULT (WINAPI *pRunSetupCommand)(HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, HANDLE*, DWORD, LPVOID);
29
static INT (WINAPI *pLaunchINFSection)(HWND, HINSTANCE, LPSTR, INT);
30
static HRESULT (WINAPI *pLaunchINFSectionEx)(HWND, HINSTANCE, LPSTR, INT);
31
32
static char CURR_DIR[MAX_PATH];
33
34
static BOOL init_function_pointers(void)
35
{
36
hAdvPack = LoadLibraryA("advpack.dll");
37
if (!hAdvPack)
38
return FALSE;
39
40
pRunSetupCommand = (void *)GetProcAddress(hAdvPack, "RunSetupCommand");
41
pLaunchINFSection = (void *)GetProcAddress(hAdvPack, "LaunchINFSection");
42
pLaunchINFSectionEx = (void *)GetProcAddress(hAdvPack, "LaunchINFSectionEx");
43
44
if (!pRunSetupCommand || !pLaunchINFSection || !pLaunchINFSectionEx)
45
return FALSE;
46
47
return TRUE;
48
}
49
50
static BOOL is_spapi_err(DWORD err)
51
{
52
const DWORD SPAPI_PREFIX = 0x800F0000L;
53
const DWORD SPAPI_MASK = 0xFFFF0000L;
54
55
return (((err & SPAPI_MASK) ^ SPAPI_PREFIX) == 0);
56
}
57
58
static void load_resource(const char *name, const char *filename)
59
{
60
DWORD written;
61
HANDLE file;
62
HRSRC res;
63
void *ptr;
64
65
file = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
66
ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n", filename, GetLastError());
67
68
res = FindResourceA(NULL, name, "TESTDLL");
69
ok(res != 0, "couldn't find resource\n");
70
ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
71
WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res), &written, NULL);
72
ok(written == SizeofResource(GetModuleHandleA(NULL), res), "couldn't write resource\n");
73
CloseHandle(file);
74
}
75
76
static void create_inf_file(LPCSTR filename)
77
{
78
DWORD dwNumberOfBytesWritten;
79
HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
80
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
81
82
static const char data[] =
83
"[Version]\n"
84
"Signature=\"$Chicago$\"\n"
85
"AdvancedINF=2.5\n"
86
"[DefaultInstall]\n"
87
"CheckAdminRights=1\n"
88
89
"[OcxInstallGood]\n"
90
"RegisterOCXs=GoodOCX\n"
91
"[OcxUninstallGood]\n"
92
"UnregisterOCXs=GoodOCX\n"
93
"[GoodOCX]\n"
94
"winetest_selfreg.ocx\n"
95
96
"[OcxInstallAtGood]\n"
97
"RegisterOCXs=AtGoodOCX\n"
98
"[AtGoodOCX]\n"
99
"@winetest_selfreg.ocx\n"
100
101
"[OcxInstallBad]\n"
102
"RegisterOCXs=BadOCXsToRegister\n"
103
"[BadOCXsToRegister]\n"
104
"nonexistent.ocx\n"
105
106
"[OcxInstallAtBad]\n"
107
"RegisterOCXs=AtBadOCX\n"
108
"[AtBadOCX]\n"
109
"@nonexistent.ocx\n";
110
111
WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL);
112
CloseHandle(hf);
113
}
114
115
static void test_RunSetupCommand(void)
116
{
117
HRESULT hr;
118
HANDLE hexe;
119
char path[MAX_PATH];
120
char dir[MAX_PATH];
121
char systemdir[MAX_PATH];
122
123
GetSystemDirectoryA(systemdir, sizeof(systemdir));
124
125
/* try an invalid cmd name */
126
hr = pRunSetupCommand(NULL, NULL, "Install", "Dir", "Title", NULL, 0, NULL);
127
ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %ld\n", hr);
128
129
/* try an invalid directory */
130
hr = pRunSetupCommand(NULL, "winver.exe", "Install", NULL, "Title", NULL, 0, NULL);
131
ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %ld\n", hr);
132
133
/* try to run a nonexistent exe */
134
hexe = (HANDLE)0xdeadbeef;
135
hr = pRunSetupCommand(NULL, "idontexist.exe", "Install", systemdir, "Title", &hexe, 0, NULL);
136
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
137
"Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %ld\n", hr);
138
ok(hexe == NULL, "Expected hexe to be NULL\n");
139
ok(!TerminateProcess(hexe, 0), "Expected TerminateProcess to fail\n");
140
141
/* try a bad directory */
142
hexe = (HANDLE)0xdeadbeef;
143
hr = pRunSetupCommand(NULL, "winver.exe", "Install", "non\\existent\\directory", "Title", &hexe, 0, NULL);
144
ok(hr == HRESULT_FROM_WIN32(ERROR_DIRECTORY),
145
"Expected HRESULT_FROM_WIN32(ERROR_DIRECTORY), got %ld\n", hr);
146
ok(hexe == NULL, "Expected hexe to be NULL\n");
147
ok(!TerminateProcess(hexe, 0), "Expected TerminateProcess to fail\n");
148
149
/* try to run an exe with the RSC_FLAG_INF flag */
150
hexe = (HANDLE)0xdeadbeef;
151
hr = pRunSetupCommand(NULL, "winver.exe", "Install", systemdir, "Title", &hexe, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
152
ok(is_spapi_err(hr), "Expected a setupapi error, got %ld\n", hr);
153
ok(hexe == (HANDLE)0xdeadbeef, "Expected hexe to be 0xdeadbeef\n");
154
ok(!TerminateProcess(hexe, 0), "Expected TerminateProcess to fail\n");
155
156
/* run winver.exe */
157
hexe = (HANDLE)0xdeadbeef;
158
hr = pRunSetupCommand(NULL, "winver.exe", "Install", systemdir, "Title", &hexe, 0, NULL);
159
ok(hr == S_ASYNCHRONOUS, "Expected S_ASYNCHRONOUS, got %ld\n", hr);
160
ok(hexe != NULL, "Expected hexe to be non-NULL\n");
161
ok(TerminateProcess(hexe, 0), "Expected TerminateProcess to succeed\n");
162
163
CreateDirectoryA("one", NULL);
164
create_inf_file("one\\test.inf");
165
166
/* try a full path to the INF, with working dir provided */
167
lstrcpyA(path, CURR_DIR);
168
lstrcatA(path, "\\one\\test.inf");
169
lstrcpyA(dir, CURR_DIR);
170
lstrcatA(dir, "\\one");
171
hr = pRunSetupCommand(NULL, path, "DefaultInstall", dir, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
172
ok(hr == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", hr);
173
174
/* try a full path to the INF, NULL working dir */
175
hr = pRunSetupCommand(NULL, path, "DefaultInstall", NULL, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
176
ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
177
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %ld\n", hr);
178
179
/* try a full path to the INF, empty working dir */
180
hr = pRunSetupCommand(NULL, path, "DefaultInstall", "", "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
181
ok(hr == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", hr);
182
183
/* try a relative path to the INF, with working dir provided */
184
hr = pRunSetupCommand(NULL, "one\\test.inf", "DefaultInstall", dir, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
185
ok(hr == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", hr);
186
187
/* try a relative path to the INF, NULL working dir */
188
hr = pRunSetupCommand(NULL, "one\\test.inf", "DefaultInstall", NULL, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
189
ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
190
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %ld\n", hr);
191
192
/* try a relative path to the INF, empty working dir */
193
hr = pRunSetupCommand(NULL, "one\\test.inf", "DefaultInstall", "", "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
194
ok(hr == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", hr);
195
196
/* try only the INF filename, with working dir provided */
197
hr = pRunSetupCommand(NULL, "test.inf", "DefaultInstall", dir, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
198
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %ld\n", hr);
199
200
/* try only the INF filename, NULL working dir */
201
hr = pRunSetupCommand(NULL, "test.inf", "DefaultInstall", NULL, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
202
ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
203
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %ld\n", hr);
204
205
/* try only the INF filename, empty working dir */
206
hr = pRunSetupCommand(NULL, "test.inf", "DefaultInstall", "", "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
207
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %ld\n", hr);
208
209
DeleteFileA("one\\test.inf");
210
RemoveDirectoryA("one");
211
212
create_inf_file("test.inf");
213
214
/* try INF file in the current directory, working directory provided */
215
hr = pRunSetupCommand(NULL, "test.inf", "DefaultInstall", CURR_DIR, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
216
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %ld\n", hr);
217
218
/* try INF file in the current directory, NULL working directory */
219
hr = pRunSetupCommand(NULL, "test.inf", "DefaultInstall", NULL, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
220
ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
221
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %ld\n", hr);
222
223
/* try INF file in the current directory, empty working directory */
224
hr = pRunSetupCommand(NULL, "test.inf", "DefaultInstall", CURR_DIR, "Title", NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, NULL);
225
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %ld\n", hr);
226
}
227
228
static void test_LaunchINFSection(void)
229
{
230
HRESULT hr;
231
char cmdline[MAX_PATH];
232
static char file[] = "test.inf,DefaultInstall,4,0";
233
static char file2[] = "test.inf,,1,0";
234
235
/* The 'No UI' flag seems to have no effect whatsoever on Windows.
236
* So only do this test in interactive mode.
237
*/
238
if (winetest_interactive)
239
{
240
/* try an invalid cmdline */
241
hr = pLaunchINFSection(NULL, NULL, NULL, 0);
242
ok(hr == 1, "Expected 1, got %ld\n", hr);
243
}
244
245
CreateDirectoryA("one", NULL);
246
create_inf_file("one\\test.inf");
247
248
/* try a full path to the INF */
249
lstrcpyA(cmdline, CURR_DIR);
250
lstrcatA(cmdline, "\\");
251
lstrcatA(cmdline, "one\\test.inf,DefaultInstall,,4");
252
hr = pLaunchINFSection(NULL, NULL, cmdline, 0);
253
ok(hr == 0, "Expected 0, got %ld\n", hr);
254
255
DeleteFileA("one\\test.inf");
256
RemoveDirectoryA("one");
257
258
create_inf_file("test.inf");
259
260
/* try just the INF filename */
261
hr = pLaunchINFSection(NULL, NULL, file, 0);
262
ok(hr == 0, "Expected 0, got %ld\n", hr);
263
264
hr = pLaunchINFSection(NULL, NULL, file2, 0);
265
ok(hr == 0, "Expected 0, got %ld\n", hr);
266
267
DeleteFileA("test.inf");
268
}
269
270
static void test_LaunchINFSectionEx(void)
271
{
272
HRESULT hr;
273
char cmdline[MAX_PATH];
274
275
create_inf_file("test.inf");
276
277
/* try an invalid CAB filename with an absolute INF name */
278
lstrcpyA(cmdline, CURR_DIR);
279
lstrcatA(cmdline, "\\");
280
lstrcatA(cmdline, "test.inf,DefaultInstall,c:imacab.cab,4");
281
hr = pLaunchINFSectionEx(NULL, NULL, cmdline, 0);
282
ok(hr == 0, "Expected 0, got %ld\n", hr);
283
284
/* try quoting the parameters */
285
lstrcpyA(cmdline, "\"");
286
lstrcatA(cmdline, CURR_DIR);
287
lstrcatA(cmdline, "\\test.inf\",\"DefaultInstall\",\"c:,imacab.cab\",\"4\"");
288
hr = pLaunchINFSectionEx(NULL, NULL, cmdline, 0);
289
ok(hr == 0, "Expected 0, got %ld\n", hr);
290
291
/* The 'No UI' flag seems to have no effect whatsoever on Windows.
292
* So only do this test in interactive mode.
293
*/
294
if (winetest_interactive)
295
{
296
/* try an invalid CAB filename with a relative INF name */
297
lstrcpyA(cmdline, "test.inf,DefaultInstall,c:imacab.cab,4");
298
hr = pLaunchINFSectionEx(NULL, NULL, cmdline, 0);
299
ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %ld\n", hr);
300
}
301
302
DeleteFileA("test.inf");
303
}
304
305
static LRESULT CALLBACK hide_window_hook(int code, WPARAM wparam, LPARAM lparam)
306
{
307
if (code == HCBT_CREATEWND)
308
{
309
/* Suppress the "Error registering the OCX" dialog */
310
return 1;
311
}
312
313
return CallNextHookEx(NULL, code, wparam, lparam);
314
}
315
316
static void test_RegisterOCXs(void)
317
{
318
static char install_good_section[] = "test.inf,OcxInstallGood,4,0";
319
static char uninstall_good_section[] = "test.inf,OcxUninstallGood,4,0";
320
static char install_at_good_section[] = "test.inf,OcxInstallAtGood,4,0";
321
static char install_bad_section[] = "test.inf,OcxInstallBad,4,0";
322
static char install_at_bad_section[] = "test.inf,OcxInstallAtBad,4,0";
323
HHOOK hook;
324
HKEY key;
325
INT res;
326
327
load_resource("selfreg.dll", "winetest_selfreg.ocx");
328
create_inf_file("test.inf");
329
330
RegDeleteKeyA(HKEY_CLASSES_ROOT, "selfreg_test");
331
res = pLaunchINFSection(NULL, NULL, install_good_section, 0);
332
ok(res == 0, "Expected 0, got %d\n", res);
333
res = RegOpenKeyA(HKEY_CLASSES_ROOT, "selfreg_test", &key);
334
ok(res == 0, "Expected 0, got %d\n", res);
335
RegCloseKey(key);
336
337
res = pLaunchINFSection(NULL, NULL, uninstall_good_section, 0);
338
ok(res == 0, "Expected 0, got %d\n", res);
339
res = RegOpenKeyA(HKEY_CLASSES_ROOT, "selfreg_test", &key);
340
todo_wine ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
341
RegDeleteKeyA(HKEY_CLASSES_ROOT, "selfreg_test");
342
343
res = pLaunchINFSection(NULL, NULL, install_at_good_section, 0);
344
ok(res == 0, "Expected 0, got %d\n", res);
345
res = RegOpenKeyA(HKEY_CLASSES_ROOT, "selfreg_test", &key);
346
ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
347
348
hook = SetWindowsHookExW(WH_CBT, hide_window_hook, NULL, GetCurrentThreadId());
349
res = pLaunchINFSection(NULL, NULL, install_bad_section, 0);
350
ok(res == 1, "Expected 1, got %d\n", res);
351
UnhookWindowsHookEx(hook);
352
353
res = pLaunchINFSection(NULL, NULL, install_at_bad_section, 0);
354
ok(res == 0, "Expected 0, got %d\n", res);
355
356
DeleteFileA("winetest_selfreg.ocx");
357
DeleteFileA("test.inf");
358
}
359
360
START_TEST(install)
361
{
362
DWORD len;
363
char temp_path[MAX_PATH], prev_path[MAX_PATH];
364
365
if (!init_function_pointers())
366
return;
367
368
if (!IsNTAdmin(0, NULL))
369
{
370
skip("Most tests need admin rights\n");
371
return;
372
}
373
374
GetCurrentDirectoryA(MAX_PATH, prev_path);
375
GetTempPathA(MAX_PATH, temp_path);
376
SetCurrentDirectoryA(temp_path);
377
378
lstrcpyA(CURR_DIR, temp_path);
379
len = lstrlenA(CURR_DIR);
380
381
if(len && (CURR_DIR[len - 1] == '\\'))
382
CURR_DIR[len - 1] = 0;
383
384
test_RunSetupCommand();
385
test_LaunchINFSection();
386
test_LaunchINFSectionEx();
387
test_RegisterOCXs();
388
389
FreeLibrary(hAdvPack);
390
SetCurrentDirectoryA(prev_path);
391
}
392
393