ntoskrnl.exe/tests: Add basic tests for ZwLoadDriver()/ZwUnloadDriver().
[wine.git] / dlls / ntoskrnl.exe / tests / ntoskrnl.c
blob73f0e85a51828d96271cf40c450568bf203eccc1
1 /*
2 * ntoskrnl.exe testing framework
4 * Copyright 2015 Sebastian Lackner
5 * Copyright 2015 Michael Müller
6 * Copyright 2015 Christian Costa
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdio.h>
24 #include "windows.h"
25 #include "winsvc.h"
26 #include "winioctl.h"
27 #include "winternl.h"
28 #include "wine/test.h"
29 #include "wine/heap.h"
31 #include "driver.h"
33 static HANDLE device;
35 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* );
37 static void load_resource(const char *name, char *filename)
39 static char path[MAX_PATH];
40 DWORD written;
41 HANDLE file;
42 HRSRC res;
43 void *ptr;
45 GetTempPathA(sizeof(path), path);
46 GetTempFileNameA(path, name, 0, filename);
48 file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
49 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", filename, GetLastError());
51 res = FindResourceA(NULL, name, "TESTDLL");
52 ok( res != 0, "couldn't find resource\n" );
53 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
54 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
55 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
56 CloseHandle( file );
59 static void unload_driver(SC_HANDLE service)
61 SERVICE_STATUS status;
63 CloseHandle(device);
65 ControlService(service, SERVICE_CONTROL_STOP, &status);
66 while (status.dwCurrentState == SERVICE_STOP_PENDING)
68 BOOL ret;
69 Sleep(100);
70 ret = QueryServiceStatus(service, &status);
71 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
73 ok(status.dwCurrentState == SERVICE_STOPPED,
74 "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState);
76 DeleteService(service);
77 CloseServiceHandle(service);
80 static SC_HANDLE load_driver(char *filename, const char *resname, const char *driver_name)
82 SC_HANDLE manager, service;
84 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
85 if (!manager && GetLastError() == ERROR_ACCESS_DENIED)
87 skip("Failed to open SC manager, not enough permissions\n");
88 return FALSE;
90 ok(!!manager, "OpenSCManager failed\n");
92 /* stop any old drivers running under this name */
93 service = OpenServiceA(manager, driver_name, SERVICE_ALL_ACCESS);
94 if (service) unload_driver(service);
96 load_resource(resname, filename);
97 trace("Trying to load driver %s\n", filename);
99 service = CreateServiceA(manager, driver_name, driver_name,
100 SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
101 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
102 filename, NULL, NULL, NULL, NULL, NULL);
103 ok(!!service, "CreateService failed: %u\n", GetLastError());
105 CloseServiceHandle(manager);
106 return service;
109 static BOOL start_driver(HANDLE service)
111 SERVICE_STATUS status;
112 BOOL ret;
114 SetLastError(0xdeadbeef);
115 ret = StartServiceA(service, 0, NULL);
116 if (!ret && (GetLastError() == ERROR_DRIVER_BLOCKED || GetLastError() == ERROR_INVALID_IMAGE_HASH))
118 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
119 skip("Failed to start service; probably your machine doesn't accept unsigned drivers.\n");
120 DeleteService(service);
121 CloseServiceHandle(service);
122 return FALSE;
124 ok(ret, "StartService failed: %u\n", GetLastError());
126 /* wait for the service to start up properly */
127 ret = QueryServiceStatus(service, &status);
128 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
129 while (status.dwCurrentState == SERVICE_START_PENDING)
131 Sleep(100);
132 ret = QueryServiceStatus(service, &status);
133 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
135 ok(status.dwCurrentState == SERVICE_RUNNING,
136 "expected SERVICE_RUNNING, got %d\n", status.dwCurrentState);
138 return TRUE;
141 static void main_test(void)
143 static const WCHAR dokW[] = {'d','o','k',0};
144 WCHAR temppathW[MAX_PATH], pathW[MAX_PATH];
145 struct test_input *test_input;
146 UNICODE_STRING pathU;
147 DWORD written, read;
148 LONG new_failures;
149 char buffer[512];
150 HANDLE okfile;
151 BOOL res;
153 /* Create a temporary file that the driver will write ok/trace output to. */
154 GetTempPathW(MAX_PATH, temppathW);
155 GetTempFileNameW(temppathW, dokW, 0, pathW);
156 pRtlDosPathNameToNtPathName_U( pathW, &pathU, NULL, NULL );
158 test_input = heap_alloc(sizeof(*test_input) + pathU.Length);
159 test_input->running_under_wine = !strcmp(winetest_platform, "wine");
160 test_input->winetest_report_success = winetest_report_success;
161 test_input->winetest_debug = winetest_debug;
162 lstrcpynW(test_input->path, pathU.Buffer, pathU.Length);
163 res = DeviceIoControl(device, IOCTL_WINETEST_MAIN_TEST, test_input, sizeof(*test_input) + pathU.Length,
164 &new_failures, sizeof(new_failures), &written, NULL);
165 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
166 ok(written == sizeof(new_failures), "got size %x\n", written);
168 okfile = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
169 ok(okfile != INVALID_HANDLE_VALUE, "failed to create %s: %u\n", wine_dbgstr_w(pathW), GetLastError());
171 /* Print the ok/trace output and then add to our failure count. */
172 do {
173 ReadFile(okfile, buffer, sizeof(buffer), &read, NULL);
174 printf("%.*s", read, buffer);
175 } while (read == sizeof(buffer));
176 winetest_add_failures(new_failures);
178 CloseHandle(okfile);
179 DeleteFileW(pathW);
182 static void test_basic_ioctl(void)
184 DWORD written;
185 char buf[32];
186 BOOL res;
188 res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, NULL, 0, buf,
189 sizeof(buf), &written, NULL);
190 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
191 ok(written == sizeof(teststr), "got size %d\n", written);
192 ok(!strcmp(buf, teststr), "got '%s'\n", buf);
195 static void test_load_driver(SC_HANDLE service)
197 SERVICE_STATUS status;
198 BOOL load, res;
199 DWORD sz;
201 res = QueryServiceStatus(service, &status);
202 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
203 ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
205 load = TRUE;
206 res = DeviceIoControl(device, IOCTL_WINETEST_LOAD_DRIVER, &load, sizeof(load), NULL, 0, &sz, NULL);
207 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
209 res = QueryServiceStatus(service, &status);
210 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
211 ok(status.dwCurrentState == SERVICE_RUNNING, "got state %#x\n", status.dwCurrentState);
213 load = FALSE;
214 res = DeviceIoControl(device, IOCTL_WINETEST_LOAD_DRIVER, &load, sizeof(load), NULL, 0, &sz, NULL);
215 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
217 res = QueryServiceStatus(service, &status);
218 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
219 ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
222 START_TEST(ntoskrnl)
224 char filename[MAX_PATH], filename2[MAX_PATH];
225 SC_HANDLE service, service2;
227 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
228 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
230 if (!(service = load_driver(filename, "driver.dll", "WineTestDriver")))
231 return;
232 if (!start_driver(service))
234 DeleteFileA(filename);
235 return;
237 service2 = load_driver(filename2, "driver2.dll", "WineTestDriver2");
239 device = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
240 ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
242 test_basic_ioctl();
243 main_test();
244 test_load_driver(service2);
246 unload_driver(service2);
247 unload_driver(service);
248 ok(DeleteFileA(filename), "DeleteFile failed: %u\n", GetLastError());
249 ok(DeleteFileA(filename2), "DeleteFile failed: %u\n", GetLastError());