ntoskrnl/tests: Test-sign driver files.
[wine.git] / dlls / ntoskrnl.exe / tests / ntoskrnl.c
blob50abb9f9d1f6a26e460bf2af2903d4c59417c8e2
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 "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windows.h"
27 #include "winsvc.h"
28 #include "winioctl.h"
29 #include "winternl.h"
30 #include "winsock2.h"
31 #include "wincrypt.h"
32 #include "ntsecapi.h"
33 #include "mscat.h"
34 #include "mssip.h"
35 #include "wine/test.h"
36 #include "wine/heap.h"
37 #include "wine/mssign.h"
39 #include "driver.h"
41 static HANDLE device;
43 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR *, UNICODE_STRING *, WCHAR **, CURDIR *);
44 static BOOL (WINAPI *pRtlFreeUnicodeString)(UNICODE_STRING *);
45 static BOOL (WINAPI *pCancelIoEx)(HANDLE, OVERLAPPED *);
46 static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR);
47 static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert,
48 SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider,
49 const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data);
51 static void load_resource(const WCHAR *name, WCHAR *filename)
53 static WCHAR path[MAX_PATH];
54 DWORD written;
55 HANDLE file;
56 HRSRC res;
57 void *ptr;
59 GetTempPathW(ARRAY_SIZE(path), path);
60 GetTempFileNameW(path, name, 0, filename);
62 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
63 ok(file != INVALID_HANDLE_VALUE, "failed to create %s, error %u\n", debugstr_w(filename), GetLastError());
65 res = FindResourceW(NULL, name, L"TESTDLL");
66 ok( res != 0, "couldn't find resource\n" );
67 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
68 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
69 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
70 CloseHandle( file );
73 struct testsign_context
75 HCRYPTPROV provider;
76 const CERT_CONTEXT *cert, *root_cert, *publisher_cert;
77 HCERTSTORE root_store, publisher_store;
80 static BOOL testsign_create_cert(struct testsign_context *ctx)
82 BYTE encoded_name[100], encoded_key_id[200], public_key_info_buffer[1000];
83 WCHAR container_name[26];
84 BYTE hash_buffer[16], cert_buffer[1000], provider_nameA[100], serial[16];
85 CERT_PUBLIC_KEY_INFO *public_key_info = (CERT_PUBLIC_KEY_INFO *)public_key_info_buffer;
86 CRYPT_KEY_PROV_INFO provider_info = {0};
87 CRYPT_ALGORITHM_IDENTIFIER algid = {0};
88 CERT_AUTHORITY_KEY_ID_INFO key_info;
89 CERT_INFO cert_info = {0};
90 WCHAR provider_nameW[100];
91 CERT_EXTENSION extension;
92 HCRYPTKEY key;
93 DWORD size;
94 BOOL ret;
96 memset(ctx, 0, sizeof(*ctx));
98 srand(time(NULL));
99 swprintf(container_name, ARRAY_SIZE(container_name), L"wine_testsign%u", rand());
101 ret = CryptAcquireContextW(&ctx->provider, container_name, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
102 ok(ret, "Failed to create container, error %#x\n", GetLastError());
104 ret = CryptGenKey(ctx->provider, AT_SIGNATURE, CRYPT_EXPORTABLE, &key);
105 ok(ret, "Failed to create key, error %#x\n", GetLastError());
106 ret = CryptDestroyKey(key);
107 ok(ret, "Failed to destroy key, error %#x\n", GetLastError());
108 ret = CryptGetUserKey(ctx->provider, AT_SIGNATURE, &key);
109 ok(ret, "Failed to get user key, error %#x\n", GetLastError());
110 ret = CryptDestroyKey(key);
111 ok(ret, "Failed to destroy key, error %#x\n", GetLastError());
113 size = sizeof(encoded_name);
114 ret = CertStrToNameA(X509_ASN_ENCODING, "CN=winetest_cert", CERT_X500_NAME_STR, NULL, encoded_name, &size, NULL);
115 ok(ret, "Failed to convert name, error %#x\n", GetLastError());
116 key_info.CertIssuer.cbData = size;
117 key_info.CertIssuer.pbData = encoded_name;
119 size = sizeof(public_key_info_buffer);
120 ret = CryptExportPublicKeyInfo(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, public_key_info, &size);
121 ok(ret, "Failed to export public key, error %#x\n", GetLastError());
122 cert_info.SubjectPublicKeyInfo = *public_key_info;
124 size = sizeof(hash_buffer);
125 ret = CryptHashPublicKeyInfo(ctx->provider, CALG_MD5, 0, X509_ASN_ENCODING, public_key_info, hash_buffer, &size);
126 ok(ret, "Failed to hash public key, error %#x\n", GetLastError());
128 key_info.KeyId.cbData = size;
129 key_info.KeyId.pbData = hash_buffer;
131 RtlGenRandom(serial, sizeof(serial));
132 key_info.CertSerialNumber.cbData = sizeof(serial);
133 key_info.CertSerialNumber.pbData = serial;
135 size = sizeof(encoded_key_id);
136 ret = CryptEncodeObject(X509_ASN_ENCODING, X509_AUTHORITY_KEY_ID, &key_info, encoded_key_id, &size);
137 ok(ret, "Failed to convert name, error %#x\n", GetLastError());
139 extension.pszObjId = (char *)szOID_AUTHORITY_KEY_IDENTIFIER;
140 extension.fCritical = TRUE;
141 extension.Value.cbData = size;
142 extension.Value.pbData = encoded_key_id;
144 cert_info.dwVersion = CERT_V3;
145 cert_info.SerialNumber = key_info.CertSerialNumber;
146 cert_info.SignatureAlgorithm.pszObjId = (char *)szOID_RSA_SHA1RSA;
147 cert_info.Issuer = key_info.CertIssuer;
148 GetSystemTimeAsFileTime(&cert_info.NotBefore);
149 GetSystemTimeAsFileTime(&cert_info.NotAfter);
150 cert_info.NotAfter.dwHighDateTime += 1;
151 cert_info.Subject = key_info.CertIssuer;
152 cert_info.cExtension = 1;
153 cert_info.rgExtension = &extension;
154 algid.pszObjId = (char *)szOID_RSA_SHA1RSA;
155 size = sizeof(cert_buffer);
156 ret = CryptSignAndEncodeCertificate(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING,
157 X509_CERT_TO_BE_SIGNED, &cert_info, &algid, NULL, cert_buffer, &size);
158 ok(ret, "Failed to create certificate, error %#x\n", GetLastError());
160 ctx->cert = CertCreateCertificateContext(X509_ASN_ENCODING, cert_buffer, size);
161 ok(!!ctx->cert, "Failed to create context, error %#x\n", GetLastError());
163 size = sizeof(provider_nameA);
164 ret = CryptGetProvParam(ctx->provider, PP_NAME, provider_nameA, &size, 0);
165 ok(ret, "Failed to get prov param, error %#x\n", GetLastError());
166 MultiByteToWideChar(CP_ACP, 0, (char *)provider_nameA, -1, provider_nameW, ARRAY_SIZE(provider_nameW));
168 provider_info.pwszContainerName = (WCHAR *)container_name;
169 provider_info.pwszProvName = provider_nameW;
170 provider_info.dwProvType = PROV_RSA_FULL;
171 provider_info.dwKeySpec = AT_SIGNATURE;
172 ret = CertSetCertificateContextProperty(ctx->cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &provider_info);
173 ok(ret, "Failed to set provider info, error %#x\n", GetLastError());
175 ctx->root_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "root");
176 ok(!!ctx->root_store, "Failed to open store, error %u\n", GetLastError());
177 ret = CertAddCertificateContextToStore(ctx->root_store, ctx->cert, CERT_STORE_ADD_ALWAYS, &ctx->root_cert);
178 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
180 skip("Failed to add self-signed certificate to store.\n");
182 ret = CertFreeCertificateContext(ctx->cert);
183 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
184 ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG);
185 ok(ret, "Failed to close store, error %u\n", GetLastError());
186 ret = CryptReleaseContext(ctx->provider, 0);
187 ok(ret, "failed to release context, error %u\n", GetLastError());
189 return FALSE;
191 ok(ret, "Failed to add certificate, error %u\n", GetLastError());
193 ctx->publisher_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0,
194 CERT_SYSTEM_STORE_LOCAL_MACHINE, "trustedpublisher");
195 ok(!!ctx->publisher_store, "Failed to open store, error %u\n", GetLastError());
196 ret = CertAddCertificateContextToStore(ctx->publisher_store, ctx->cert,
197 CERT_STORE_ADD_ALWAYS, &ctx->publisher_cert);
198 ok(ret, "Failed to add certificate, error %u\n", GetLastError());
200 return TRUE;
203 static void testsign_cleanup(struct testsign_context *ctx)
205 BOOL ret;
207 ret = CertFreeCertificateContext(ctx->cert);
208 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
210 ret = CertDeleteCertificateFromStore(ctx->root_cert);
211 ok(ret, "Failed to remove certificate, error %u\n", GetLastError());
212 ret = CertFreeCertificateContext(ctx->root_cert);
213 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
214 ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG);
215 ok(ret, "Failed to close store, error %u\n", GetLastError());
217 ret = CertDeleteCertificateFromStore(ctx->publisher_cert);
218 ok(ret, "Failed to remove certificate, error %u\n", GetLastError());
219 ret = CertFreeCertificateContext(ctx->publisher_cert);
220 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
221 ret = CertCloseStore(ctx->publisher_store, CERT_CLOSE_STORE_CHECK_FLAG);
222 ok(ret, "Failed to close store, error %u\n", GetLastError());
224 ret = CryptReleaseContext(ctx->provider, 0);
225 ok(ret, "failed to release context, error %u\n", GetLastError());
228 static void testsign_sign(struct testsign_context *ctx, const WCHAR *filename)
230 SIGNER_ATTR_AUTHCODE authcode = {sizeof(authcode)};
231 SIGNER_SIGNATURE_INFO signature = {sizeof(signature)};
232 SIGNER_SUBJECT_INFO subject = {sizeof(subject)};
233 SIGNER_CERT_STORE_INFO store = {sizeof(store)};
234 SIGNER_CERT cert_info = {sizeof(cert_info)};
235 SIGNER_FILE_INFO file = {sizeof(file)};
236 DWORD index = 0;
237 HRESULT hr;
239 subject.dwSubjectChoice = 1;
240 subject.pdwIndex = &index;
241 subject.pSignerFileInfo = &file;
242 file.pwszFileName = (WCHAR *)filename;
243 cert_info.dwCertChoice = 2;
244 cert_info.pCertStoreInfo = &store;
245 store.pSigningCert = ctx->cert;
246 store.dwCertPolicy = 0;
247 signature.algidHash = CALG_SHA_256;
248 signature.dwAttrChoice = SIGNER_AUTHCODE_ATTR;
249 signature.pAttrAuthcode = &authcode;
250 authcode.pwszName = L"";
251 authcode.pwszInfo = L"";
252 hr = pSignerSign(&subject, &cert_info, &signature, NULL, NULL, NULL, NULL);
253 todo_wine ok(hr == S_OK || broken(hr == NTE_BAD_ALGID) /* < 7 */, "Failed to sign, hr %#x\n", hr);
256 static void unload_driver(SC_HANDLE service)
258 SERVICE_STATUS status;
260 ControlService(service, SERVICE_CONTROL_STOP, &status);
261 while (status.dwCurrentState == SERVICE_STOP_PENDING)
263 BOOL ret;
264 Sleep(100);
265 ret = QueryServiceStatus(service, &status);
266 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
268 ok(status.dwCurrentState == SERVICE_STOPPED,
269 "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState);
271 DeleteService(service);
272 CloseServiceHandle(service);
275 static SC_HANDLE load_driver(struct testsign_context *ctx, WCHAR *filename,
276 const WCHAR *resname, const WCHAR *driver_name)
278 SC_HANDLE manager, service;
280 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
281 if (!manager && GetLastError() == ERROR_ACCESS_DENIED)
283 skip("Failed to open SC manager, not enough permissions\n");
284 return FALSE;
286 ok(!!manager, "OpenSCManager failed\n");
288 /* stop any old drivers running under this name */
289 service = OpenServiceW(manager, driver_name, SERVICE_ALL_ACCESS);
290 if (service) unload_driver(service);
292 load_resource(resname, filename);
293 testsign_sign(ctx, filename);
294 trace("Trying to load driver %s\n", debugstr_w(filename));
296 service = CreateServiceW(manager, driver_name, driver_name,
297 SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
298 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
299 filename, NULL, NULL, NULL, NULL, NULL);
300 ok(!!service, "CreateService failed: %u\n", GetLastError());
302 CloseServiceHandle(manager);
303 return service;
306 static BOOL start_driver(HANDLE service, BOOL vista_plus)
308 SERVICE_STATUS status;
309 BOOL ret;
311 SetLastError(0xdeadbeef);
312 ret = StartServiceA(service, 0, NULL);
313 if (!ret && (GetLastError() == ERROR_DRIVER_BLOCKED || GetLastError() == ERROR_INVALID_IMAGE_HASH
314 || (vista_plus && GetLastError() == ERROR_FILE_NOT_FOUND)))
316 if (vista_plus && GetLastError() == ERROR_FILE_NOT_FOUND)
318 skip("Windows Vista or newer is required to run this service.\n");
320 else
322 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
323 skip("Failed to start service; probably your machine doesn't accept unsigned drivers.\n");
325 DeleteService(service);
326 CloseServiceHandle(service);
327 return FALSE;
329 ok(ret, "StartService failed: %u\n", GetLastError());
331 /* wait for the service to start up properly */
332 ret = QueryServiceStatus(service, &status);
333 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
334 while (status.dwCurrentState == SERVICE_START_PENDING)
336 Sleep(100);
337 ret = QueryServiceStatus(service, &status);
338 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
340 ok(status.dwCurrentState == SERVICE_RUNNING,
341 "expected SERVICE_RUNNING, got %d\n", status.dwCurrentState);
342 ok(status.dwServiceType == SERVICE_KERNEL_DRIVER,
343 "expected SERVICE_KERNEL_DRIVER, got %#x\n", status.dwServiceType);
345 return TRUE;
348 static ULONG64 modified_value;
350 static void main_test(void)
352 WCHAR temppathW[MAX_PATH], pathW[MAX_PATH];
353 struct test_input *test_input;
354 DWORD len, written, read;
355 UNICODE_STRING pathU;
356 LONG new_failures;
357 char buffer[512];
358 HANDLE okfile;
359 BOOL res;
361 /* Create a temporary file that the driver will write ok/trace output to. */
362 GetTempPathW(MAX_PATH, temppathW);
363 GetTempFileNameW(temppathW, L"dok", 0, pathW);
364 pRtlDosPathNameToNtPathName_U( pathW, &pathU, NULL, NULL );
366 len = pathU.Length + sizeof(WCHAR);
367 test_input = heap_alloc( offsetof( struct test_input, path[len / sizeof(WCHAR)]) );
368 test_input->running_under_wine = !strcmp(winetest_platform, "wine");
369 test_input->winetest_report_success = winetest_report_success;
370 test_input->winetest_debug = winetest_debug;
371 test_input->process_id = GetCurrentProcessId();
372 test_input->teststr_offset = (SIZE_T)((BYTE *)&teststr - (BYTE *)NtCurrentTeb()->Peb->ImageBaseAddress);
373 test_input->modified_value = &modified_value;
374 modified_value = 0;
376 memcpy(test_input->path, pathU.Buffer, len);
377 res = DeviceIoControl(device, IOCTL_WINETEST_MAIN_TEST, test_input,
378 offsetof( struct test_input, path[len / sizeof(WCHAR)]),
379 &new_failures, sizeof(new_failures), &written, NULL);
380 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
381 ok(written == sizeof(new_failures), "got size %x\n", written);
383 okfile = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
384 ok(okfile != INVALID_HANDLE_VALUE, "failed to create %s: %u\n", wine_dbgstr_w(pathW), GetLastError());
386 /* Print the ok/trace output and then add to our failure count. */
387 do {
388 ReadFile(okfile, buffer, sizeof(buffer), &read, NULL);
389 printf("%.*s", read, buffer);
390 } while (read == sizeof(buffer));
391 winetest_add_failures(new_failures);
393 pRtlFreeUnicodeString(&pathU);
394 heap_free(test_input);
395 CloseHandle(okfile);
396 DeleteFileW(pathW);
399 static void test_basic_ioctl(void)
401 char inbuf[64], buf[32];
402 DWORD written;
403 BOOL res;
405 res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, NULL, 0, buf,
406 sizeof(buf), &written, NULL);
407 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
408 ok(written == sizeof(teststr), "got size %d\n", written);
409 ok(!strcmp(buf, teststr), "got '%s'\n", buf);
411 memset(buf, 0, sizeof(buf));
412 res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, inbuf,
413 sizeof(inbuf), buf, 10, &written, NULL);
414 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
415 ok(written == 10, "got size %d\n", written);
416 ok(!strcmp(buf, "Wine is no"), "got '%s'\n", buf);
419 static void test_mismatched_status_ioctl(void)
421 DWORD written;
422 char buf[32];
423 BOOL res;
425 res = DeviceIoControl(device, IOCTL_WINETEST_MISMATCHED_STATUS, NULL, 0, buf,
426 sizeof(buf), &written, NULL);
427 todo_wine ok(res, "DeviceIoControl failed: %u\n", GetLastError());
428 todo_wine ok(!strcmp(buf, teststr), "got '%s'\n", buf);
431 static void test_overlapped(void)
433 OVERLAPPED overlapped, overlapped2, *o;
434 DWORD cancel_cnt, size;
435 HANDLE file, port;
436 ULONG_PTR key;
437 BOOL res;
439 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
440 overlapped2.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
442 file = CreateFileA("\\\\.\\WineTestDriver", FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
443 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
444 ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
446 /* test cancelling all device requests */
447 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
448 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
450 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
451 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
453 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
454 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
456 cancel_cnt = 0xdeadbeef;
457 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
458 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
459 ok(cancel_cnt == 0, "cancel_cnt = %u\n", cancel_cnt);
461 CancelIo(file);
463 cancel_cnt = 0xdeadbeef;
464 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
465 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
466 ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
468 /* test cancelling selected overlapped event */
469 if (pCancelIoEx)
471 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
472 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
474 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
475 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
477 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
478 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
480 pCancelIoEx(file, &overlapped);
482 cancel_cnt = 0xdeadbeef;
483 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
484 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
485 ok(cancel_cnt == 1, "cancel_cnt = %u\n", cancel_cnt);
487 pCancelIoEx(file, &overlapped2);
489 cancel_cnt = 0xdeadbeef;
490 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
491 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
492 ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
495 port = CreateIoCompletionPort(file, NULL, 0xdeadbeef, 0);
496 ok(port != NULL, "CreateIoCompletionPort failed, error %u\n", GetLastError());
497 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
498 ok(!res && GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus returned %x(%u)\n", res, GetLastError());
500 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
501 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
502 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
503 ok(res, "GetQueuedCompletionStatus failed: %u\n", GetLastError());
504 ok(o == &overlapped, "o != overlapped\n");
506 if (pSetFileCompletionNotificationModes)
508 res = pSetFileCompletionNotificationModes(file, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
509 ok(res, "SetFileCompletionNotificationModes failed: %u\n", GetLastError());
511 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
512 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
513 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
514 ok(!res && GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus returned %x(%u)\n", res, GetLastError());
517 CloseHandle(port);
518 CloseHandle(overlapped.hEvent);
519 CloseHandle(overlapped2.hEvent);
520 CloseHandle(file);
523 static void test_load_driver(SC_HANDLE service)
525 SERVICE_STATUS status;
526 BOOL load, res;
527 DWORD sz;
529 res = QueryServiceStatus(service, &status);
530 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
531 ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
533 load = TRUE;
534 res = DeviceIoControl(device, IOCTL_WINETEST_LOAD_DRIVER, &load, sizeof(load), NULL, 0, &sz, NULL);
535 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
537 res = QueryServiceStatus(service, &status);
538 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
539 ok(status.dwCurrentState == SERVICE_RUNNING, "got state %#x\n", status.dwCurrentState);
541 load = FALSE;
542 res = DeviceIoControl(device, IOCTL_WINETEST_LOAD_DRIVER, &load, sizeof(load), NULL, 0, &sz, NULL);
543 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
545 res = QueryServiceStatus(service, &status);
546 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
547 ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
550 static void test_file_handles(void)
552 DWORD count, ret_size;
553 HANDLE file, dup, file2;
554 BOOL ret;
556 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
557 ok(ret, "ioctl failed: %u\n", GetLastError());
558 ok(count == 2, "got %u\n", count);
560 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
561 ok(ret, "ioctl failed: %u\n", GetLastError());
562 ok(count == 1, "got %u\n", count);
564 file = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
565 ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
567 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
568 ok(ret, "ioctl failed: %u\n", GetLastError());
569 ok(count == 3, "got %u\n", count);
571 file2 = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
572 ok(file2 != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
574 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
575 ok(ret, "ioctl failed: %u\n", GetLastError());
576 ok(count == 4, "got %u\n", count);
578 ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
579 ok(ret, "failed to duplicate handle: %u\n", GetLastError());
581 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
582 ok(ret, "ioctl failed: %u\n", GetLastError());
583 ok(count == 4, "got %u\n", count);
585 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
586 ok(ret, "ioctl failed: %u\n", GetLastError());
587 ok(count == 1, "got %u\n", count);
589 ret = DeviceIoControl(file, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
590 ok(ret, "ioctl failed: %u\n", GetLastError());
591 ok(count == 3, "got %u\n", count);
593 ret = DeviceIoControl(file2, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
594 ok(ret, "ioctl failed: %u\n", GetLastError());
595 ok(count == 4, "got %u\n", count);
597 ret = DeviceIoControl(dup, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
598 ok(ret, "ioctl failed: %u\n", GetLastError());
599 ok(count == 3, "got %u\n", count);
601 CloseHandle(dup);
603 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
604 ok(ret, "ioctl failed: %u\n", GetLastError());
605 ok(count == 1, "got %u\n", count);
607 CloseHandle(file2);
609 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
610 ok(ret, "ioctl failed: %u\n", GetLastError());
611 ok(count == 2, "got %u\n", count);
613 CloseHandle(file);
615 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
616 ok(ret, "ioctl failed: %u\n", GetLastError());
617 ok(count == 3, "got %u\n", count);
620 static void test_return_status(void)
622 NTSTATUS status;
623 char buffer[7];
624 DWORD ret_size;
625 BOOL ret;
627 strcpy(buffer, "abcdef");
628 status = STATUS_SUCCESS;
629 SetLastError(0xdeadbeef);
630 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
631 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
632 ok(ret, "ioctl failed\n");
633 ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
634 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
635 ok(ret_size == 3, "got size %u\n", ret_size);
637 strcpy(buffer, "abcdef");
638 status = STATUS_TIMEOUT;
639 SetLastError(0xdeadbeef);
640 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
641 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
642 todo_wine ok(ret, "ioctl failed\n");
643 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
644 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
645 ok(ret_size == 3, "got size %u\n", ret_size);
647 strcpy(buffer, "abcdef");
648 status = 0x0eadbeef;
649 SetLastError(0xdeadbeef);
650 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
651 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
652 todo_wine ok(ret, "ioctl failed\n");
653 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
654 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
655 ok(ret_size == 3, "got size %u\n", ret_size);
657 strcpy(buffer, "abcdef");
658 status = 0x4eadbeef;
659 SetLastError(0xdeadbeef);
660 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
661 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
662 todo_wine ok(ret, "ioctl failed\n");
663 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
664 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
665 ok(ret_size == 3, "got size %u\n", ret_size);
667 strcpy(buffer, "abcdef");
668 status = 0x8eadbeef;
669 SetLastError(0xdeadbeef);
670 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
671 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
672 ok(!ret, "ioctl succeeded\n");
673 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError());
674 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
675 ok(ret_size == 3, "got size %u\n", ret_size);
677 strcpy(buffer, "abcdef");
678 status = 0xceadbeef;
679 SetLastError(0xdeadbeef);
680 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
681 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
682 ok(!ret, "ioctl succeeded\n");
683 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError());
684 ok(!strcmp(buffer, "abcdef"), "got buffer %s\n", buffer);
685 ok(ret_size == 3, "got size %u\n", ret_size);
688 static BOOL compare_unicode_string(const WCHAR *buffer, ULONG len, const WCHAR *expect)
690 return len == wcslen(expect) * sizeof(WCHAR) && !memcmp(buffer, expect, len);
693 static void test_object_info(void)
695 char buffer[200];
696 OBJECT_NAME_INFORMATION *name_info = (OBJECT_NAME_INFORMATION *)buffer;
697 OBJECT_TYPE_INFORMATION *type_info = (OBJECT_TYPE_INFORMATION *)buffer;
698 FILE_FS_VOLUME_INFORMATION *volume_info = (FILE_FS_VOLUME_INFORMATION *)buffer;
699 FILE_NAME_INFORMATION *file_info = (FILE_NAME_INFORMATION *)buffer;
700 HANDLE file;
701 NTSTATUS status;
702 IO_STATUS_BLOCK io;
703 ULONG size;
705 status = NtQueryObject(device, ObjectNameInformation, buffer, sizeof(buffer), NULL);
706 ok(!status, "got %#x\n", status);
707 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
708 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
710 status = NtQueryObject(device, ObjectTypeInformation, buffer, sizeof(buffer), NULL);
711 ok(!status, "got %#x\n", status);
712 ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"),
713 "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR)));
715 status = NtQueryInformationFile(device, &io, buffer, sizeof(buffer), FileNameInformation);
716 todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#x\n", status);
718 status = NtQueryVolumeInformationFile(device, &io, buffer, sizeof(buffer), FileFsVolumeInformation);
719 todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#x\n", status);
721 file = CreateFileA("\\\\.\\WineTestDriver\\subfile", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
722 todo_wine ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
723 if (file == INVALID_HANDLE_VALUE) return;
725 memset(buffer, 0xcc, sizeof(buffer));
726 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), &size);
727 ok(!status, "got %#x\n", status);
728 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
729 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver\\subfile"),
730 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
732 memset(buffer, 0xcc, sizeof(buffer));
733 status = NtQueryObject(file, ObjectNameInformation, buffer, size - 2, &size);
734 ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status);
735 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
736 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver\\subfil"),
737 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
739 memset(buffer, 0xcc, sizeof(buffer));
740 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(*name_info), &size);
741 ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status);
742 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
744 status = NtQueryObject(file, ObjectTypeInformation, buffer, sizeof(buffer), NULL);
745 ok(!status, "got %#x\n", status);
746 ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"),
747 "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR)));
749 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
750 ok(!status, "got %#x\n", status);
751 ok(compare_unicode_string(file_info->FileName, file_info->FileNameLength, L"\\subfile"),
752 "wrong name %s\n", debugstr_wn(file_info->FileName, file_info->FileNameLength / sizeof(WCHAR)));
754 status = NtQueryVolumeInformationFile(file, &io, buffer, sizeof(buffer), FileFsVolumeInformation);
755 ok(!status, "got %#x\n", status);
756 ok(volume_info->VolumeSerialNumber == 0xdeadbeef,
757 "wrong serial number 0x%08x\n", volume_info->VolumeSerialNumber);
758 ok(compare_unicode_string(volume_info->VolumeLabel, volume_info->VolumeLabelLength, L"WineTestDriver"),
759 "wrong name %s\n", debugstr_wn(volume_info->VolumeLabel, volume_info->VolumeLabelLength / sizeof(WCHAR)));
761 CloseHandle(file);
763 file = CreateFileA("\\\\.\\WineTestDriver\\notimpl", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
764 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
766 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
767 ok(!status, "got %#x\n", status);
768 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
769 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
771 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
772 ok(status == STATUS_NOT_IMPLEMENTED, "got %#x\n", status);
774 CloseHandle(file);
776 file = CreateFileA("\\\\.\\WineTestDriver\\badparam", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
777 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
779 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
780 ok(!status, "got %#x\n", status);
781 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
782 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
784 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
785 ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status);
787 CloseHandle(file);
789 file = CreateFileA("\\\\.\\WineTestDriver\\genfail", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
790 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
792 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
793 ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status);
795 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
796 ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status);
798 CloseHandle(file);
800 file = CreateFileA("\\\\.\\WineTestDriver\\badtype", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
801 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
803 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
804 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status);
806 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
807 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status);
809 CloseHandle(file);
812 static void test_driver3(struct testsign_context *ctx)
814 WCHAR filename[MAX_PATH];
815 SC_HANDLE service;
816 BOOL ret;
818 service = load_driver(ctx, filename, L"driver3.dll", L"WineTestDriver3");
819 ok(service != NULL, "driver3 failed to load\n");
821 ret = StartServiceA(service, 0, NULL);
822 ok(!ret, "driver3 should fail to start\n");
823 ok(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED ||
824 GetLastError() == ERROR_INVALID_FUNCTION ||
825 GetLastError() == ERROR_PROC_NOT_FOUND /* XP */ ||
826 GetLastError() == ERROR_FILE_NOT_FOUND /* Win7 */, "got %u\n", GetLastError());
828 DeleteService(service);
829 CloseServiceHandle(service);
830 DeleteFileW(filename);
833 static DWORD WINAPI wsk_test_thread(void *parameter)
835 static const char test_send_string[] = "Client test string 1.";
836 static const WORD version = MAKEWORD(2, 2);
837 SOCKET s_listen, s_accept, s_connect;
838 struct sockaddr_in addr;
839 char buffer[256];
840 int ret, err;
841 WSADATA data;
842 int opt_val;
844 ret = WSAStartup(version, &data);
845 ok(!ret, "WSAStartup() failed, ret %u.\n", ret);
847 s_connect = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
848 ok(s_connect != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
850 s_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
851 ok(s_listen != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
853 opt_val = 1;
854 setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt_val, sizeof(opt_val));
856 memset(&addr, 0, sizeof(addr));
857 addr.sin_family = AF_INET;
858 addr.sin_port = htons(CLIENT_LISTEN_PORT);
859 addr.sin_addr.s_addr = htonl(0x7f000001);
860 ret = bind(s_listen, (struct sockaddr *)&addr, sizeof(addr));
861 ok(!ret, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret, WSAGetLastError());
863 ret = listen(s_listen, SOMAXCONN);
864 ok(!ret, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret, WSAGetLastError());
866 addr.sin_port = htons(SERVER_LISTEN_PORT);
868 ret = connect(s_connect, (struct sockaddr *)&addr, sizeof(addr));
869 while (ret && ((err = WSAGetLastError()) == WSAECONNREFUSED || err == WSAECONNABORTED))
871 SwitchToThread();
872 ret = connect(s_connect, (struct sockaddr *)&addr, sizeof(addr));
874 ok(!ret, "Error connecting, WSAGetLastError() %u.\n", WSAGetLastError());
876 ret = send(s_connect, test_send_string, sizeof(test_send_string), 0);
877 ok(ret == sizeof(test_send_string), "Got unexpected ret %d.\n", ret);
879 ret = recv(s_connect, buffer, sizeof(buffer), 0);
880 ok(ret == sizeof(buffer), "Got unexpected ret %d.\n", ret);
881 ok(!strcmp(buffer, "Server test string 1."), "Received unexpected data.\n");
883 s_accept = accept(s_listen, NULL, NULL);
884 ok(s_accept != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
886 closesocket(s_accept);
887 closesocket(s_connect);
888 closesocket(s_listen);
889 return TRUE;
892 static void test_driver4(struct testsign_context *ctx)
894 WCHAR filename[MAX_PATH];
895 SC_HANDLE service;
896 HANDLE hthread;
897 DWORD written;
898 BOOL ret;
900 if (!(service = load_driver(ctx, filename, L"driver4.dll", L"WineTestDriver4")))
901 return;
903 if (!start_driver(service, TRUE))
905 DeleteFileW(filename);
906 return;
909 device = CreateFileA("\\\\.\\WineTestDriver4", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
910 ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
912 hthread = CreateThread(NULL, 0, wsk_test_thread, NULL, 0, NULL);
913 main_test();
914 WaitForSingleObject(hthread, INFINITE);
916 ret = DeviceIoControl(device, IOCTL_WINETEST_DETACH, NULL, 0, NULL, 0, &written, NULL);
917 ok(ret, "DeviceIoControl failed: %u\n", GetLastError());
919 CloseHandle(device);
921 unload_driver(service);
922 ret = DeleteFileW(filename);
923 ok(ret, "DeleteFile failed: %u\n", GetLastError());
926 START_TEST(ntoskrnl)
928 WCHAR filename[MAX_PATH], filename2[MAX_PATH];
929 struct testsign_context ctx;
930 SC_HANDLE service, service2;
931 DWORD written;
932 BOOL ret;
934 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U");
935 pRtlFreeUnicodeString = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString");
936 pCancelIoEx = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx");
937 pSetFileCompletionNotificationModes = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"),
938 "SetFileCompletionNotificationModes");
939 pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
941 if (!testsign_create_cert(&ctx))
942 return;
944 subtest("driver");
945 if (!(service = load_driver(&ctx, filename, L"driver.dll", L"WineTestDriver")))
947 testsign_cleanup(&ctx);
948 return;
951 if (!start_driver(service, FALSE))
953 DeleteFileW(filename);
954 testsign_cleanup(&ctx);
955 return;
957 service2 = load_driver(&ctx, filename2, L"driver2.dll", L"WineTestDriver2");
959 device = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
960 ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
962 test_basic_ioctl();
963 test_mismatched_status_ioctl();
965 main_test();
966 todo_wine ok(modified_value == 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value);
968 test_overlapped();
969 test_load_driver(service2);
970 test_file_handles();
971 test_return_status();
972 test_object_info();
974 /* We need a separate ioctl to call IoDetachDevice(); calling it in the
975 * driver unload routine causes a live-lock. */
976 ret = DeviceIoControl(device, IOCTL_WINETEST_DETACH, NULL, 0, NULL, 0, &written, NULL);
977 ok(ret, "DeviceIoControl failed: %u\n", GetLastError());
979 CloseHandle(device);
981 unload_driver(service2);
982 unload_driver(service);
983 ret = DeleteFileW(filename);
984 ok(ret, "DeleteFile failed: %u\n", GetLastError());
985 ret = DeleteFileW(filename2);
986 ok(ret, "DeleteFile failed: %u\n", GetLastError());
988 test_driver3(&ctx);
989 subtest("driver4");
990 test_driver4(&ctx);
992 testsign_cleanup(&ctx);