ntoskrnl/tests: Add a basic PnP test driver.
[wine.git] / dlls / ntoskrnl.exe / tests / ntoskrnl.c
blobc9f680f01e8216c4b9f53dd866634b6a711920fc
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 "setupapi.h"
36 #include "newdev.h"
37 #include "wine/test.h"
38 #include "wine/heap.h"
39 #include "wine/mssign.h"
41 #include "driver.h"
43 static const GUID GUID_NULL;
45 static HANDLE device;
47 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR *, UNICODE_STRING *, WCHAR **, CURDIR *);
48 static BOOL (WINAPI *pRtlFreeUnicodeString)(UNICODE_STRING *);
49 static BOOL (WINAPI *pCancelIoEx)(HANDLE, OVERLAPPED *);
50 static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *);
51 static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR);
52 static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert,
53 SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider,
54 const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data);
56 static void load_resource(const WCHAR *name, WCHAR *filename)
58 static WCHAR path[MAX_PATH];
59 DWORD written;
60 HANDLE file;
61 HRSRC res;
62 void *ptr;
64 GetTempPathW(ARRAY_SIZE(path), path);
65 GetTempFileNameW(path, name, 0, filename);
67 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
68 ok(file != INVALID_HANDLE_VALUE, "failed to create %s, error %u\n", debugstr_w(filename), GetLastError());
70 res = FindResourceW(NULL, name, L"TESTDLL");
71 ok( res != 0, "couldn't find resource\n" );
72 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
73 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
74 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
75 CloseHandle( file );
78 struct testsign_context
80 HCRYPTPROV provider;
81 const CERT_CONTEXT *cert, *root_cert, *publisher_cert;
82 HCERTSTORE root_store, publisher_store;
85 static BOOL testsign_create_cert(struct testsign_context *ctx)
87 BYTE encoded_name[100], encoded_key_id[200], public_key_info_buffer[1000];
88 WCHAR container_name[26];
89 BYTE hash_buffer[16], cert_buffer[1000], provider_nameA[100], serial[16];
90 CERT_PUBLIC_KEY_INFO *public_key_info = (CERT_PUBLIC_KEY_INFO *)public_key_info_buffer;
91 CRYPT_KEY_PROV_INFO provider_info = {0};
92 CRYPT_ALGORITHM_IDENTIFIER algid = {0};
93 CERT_AUTHORITY_KEY_ID_INFO key_info;
94 CERT_INFO cert_info = {0};
95 WCHAR provider_nameW[100];
96 CERT_EXTENSION extension;
97 HCRYPTKEY key;
98 DWORD size;
99 BOOL ret;
101 memset(ctx, 0, sizeof(*ctx));
103 srand(time(NULL));
104 swprintf(container_name, ARRAY_SIZE(container_name), L"wine_testsign%u", rand());
106 ret = CryptAcquireContextW(&ctx->provider, container_name, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
107 ok(ret, "Failed to create container, error %#x\n", GetLastError());
109 ret = CryptGenKey(ctx->provider, AT_SIGNATURE, CRYPT_EXPORTABLE, &key);
110 ok(ret, "Failed to create key, error %#x\n", GetLastError());
111 ret = CryptDestroyKey(key);
112 ok(ret, "Failed to destroy key, error %#x\n", GetLastError());
113 ret = CryptGetUserKey(ctx->provider, AT_SIGNATURE, &key);
114 ok(ret, "Failed to get user key, error %#x\n", GetLastError());
115 ret = CryptDestroyKey(key);
116 ok(ret, "Failed to destroy key, error %#x\n", GetLastError());
118 size = sizeof(encoded_name);
119 ret = CertStrToNameA(X509_ASN_ENCODING, "CN=winetest_cert", CERT_X500_NAME_STR, NULL, encoded_name, &size, NULL);
120 ok(ret, "Failed to convert name, error %#x\n", GetLastError());
121 key_info.CertIssuer.cbData = size;
122 key_info.CertIssuer.pbData = encoded_name;
124 size = sizeof(public_key_info_buffer);
125 ret = CryptExportPublicKeyInfo(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, public_key_info, &size);
126 ok(ret, "Failed to export public key, error %#x\n", GetLastError());
127 cert_info.SubjectPublicKeyInfo = *public_key_info;
129 size = sizeof(hash_buffer);
130 ret = CryptHashPublicKeyInfo(ctx->provider, CALG_MD5, 0, X509_ASN_ENCODING, public_key_info, hash_buffer, &size);
131 ok(ret, "Failed to hash public key, error %#x\n", GetLastError());
133 key_info.KeyId.cbData = size;
134 key_info.KeyId.pbData = hash_buffer;
136 RtlGenRandom(serial, sizeof(serial));
137 key_info.CertSerialNumber.cbData = sizeof(serial);
138 key_info.CertSerialNumber.pbData = serial;
140 size = sizeof(encoded_key_id);
141 ret = CryptEncodeObject(X509_ASN_ENCODING, X509_AUTHORITY_KEY_ID, &key_info, encoded_key_id, &size);
142 ok(ret, "Failed to convert name, error %#x\n", GetLastError());
144 extension.pszObjId = (char *)szOID_AUTHORITY_KEY_IDENTIFIER;
145 extension.fCritical = TRUE;
146 extension.Value.cbData = size;
147 extension.Value.pbData = encoded_key_id;
149 cert_info.dwVersion = CERT_V3;
150 cert_info.SerialNumber = key_info.CertSerialNumber;
151 cert_info.SignatureAlgorithm.pszObjId = (char *)szOID_RSA_SHA1RSA;
152 cert_info.Issuer = key_info.CertIssuer;
153 GetSystemTimeAsFileTime(&cert_info.NotBefore);
154 GetSystemTimeAsFileTime(&cert_info.NotAfter);
155 cert_info.NotAfter.dwHighDateTime += 1;
156 cert_info.Subject = key_info.CertIssuer;
157 cert_info.cExtension = 1;
158 cert_info.rgExtension = &extension;
159 algid.pszObjId = (char *)szOID_RSA_SHA1RSA;
160 size = sizeof(cert_buffer);
161 ret = CryptSignAndEncodeCertificate(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING,
162 X509_CERT_TO_BE_SIGNED, &cert_info, &algid, NULL, cert_buffer, &size);
163 ok(ret, "Failed to create certificate, error %#x\n", GetLastError());
165 ctx->cert = CertCreateCertificateContext(X509_ASN_ENCODING, cert_buffer, size);
166 ok(!!ctx->cert, "Failed to create context, error %#x\n", GetLastError());
168 size = sizeof(provider_nameA);
169 ret = CryptGetProvParam(ctx->provider, PP_NAME, provider_nameA, &size, 0);
170 ok(ret, "Failed to get prov param, error %#x\n", GetLastError());
171 MultiByteToWideChar(CP_ACP, 0, (char *)provider_nameA, -1, provider_nameW, ARRAY_SIZE(provider_nameW));
173 provider_info.pwszContainerName = (WCHAR *)container_name;
174 provider_info.pwszProvName = provider_nameW;
175 provider_info.dwProvType = PROV_RSA_FULL;
176 provider_info.dwKeySpec = AT_SIGNATURE;
177 ret = CertSetCertificateContextProperty(ctx->cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &provider_info);
178 ok(ret, "Failed to set provider info, error %#x\n", GetLastError());
180 ctx->root_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "root");
181 if (!ctx->root_store && GetLastError() == ERROR_ACCESS_DENIED)
183 skip("Failed to open root store.\n");
185 ret = CertFreeCertificateContext(ctx->cert);
186 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
187 ret = CryptReleaseContext(ctx->provider, 0);
188 ok(ret, "failed to release context, error %u\n", GetLastError());
190 return FALSE;
192 ok(!!ctx->root_store, "Failed to open store, error %u\n", GetLastError());
193 ret = CertAddCertificateContextToStore(ctx->root_store, ctx->cert, CERT_STORE_ADD_ALWAYS, &ctx->root_cert);
194 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
196 skip("Failed to add self-signed certificate to store.\n");
198 ret = CertFreeCertificateContext(ctx->cert);
199 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
200 ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG);
201 ok(ret, "Failed to close store, error %u\n", GetLastError());
202 ret = CryptReleaseContext(ctx->provider, 0);
203 ok(ret, "failed to release context, error %u\n", GetLastError());
205 return FALSE;
207 ok(ret, "Failed to add certificate, error %u\n", GetLastError());
209 ctx->publisher_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0,
210 CERT_SYSTEM_STORE_LOCAL_MACHINE, "trustedpublisher");
211 ok(!!ctx->publisher_store, "Failed to open store, error %u\n", GetLastError());
212 ret = CertAddCertificateContextToStore(ctx->publisher_store, ctx->cert,
213 CERT_STORE_ADD_ALWAYS, &ctx->publisher_cert);
214 ok(ret, "Failed to add certificate, error %u\n", GetLastError());
216 return TRUE;
219 static void testsign_cleanup(struct testsign_context *ctx)
221 BOOL ret;
223 ret = CertFreeCertificateContext(ctx->cert);
224 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
226 ret = CertDeleteCertificateFromStore(ctx->root_cert);
227 ok(ret, "Failed to remove certificate, error %u\n", GetLastError());
228 ret = CertFreeCertificateContext(ctx->root_cert);
229 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
230 ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG);
231 ok(ret, "Failed to close store, error %u\n", GetLastError());
233 ret = CertDeleteCertificateFromStore(ctx->publisher_cert);
234 ok(ret, "Failed to remove certificate, error %u\n", GetLastError());
235 ret = CertFreeCertificateContext(ctx->publisher_cert);
236 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
237 ret = CertCloseStore(ctx->publisher_store, CERT_CLOSE_STORE_CHECK_FLAG);
238 ok(ret, "Failed to close store, error %u\n", GetLastError());
240 ret = CryptReleaseContext(ctx->provider, 0);
241 ok(ret, "failed to release context, error %u\n", GetLastError());
244 static void testsign_sign(struct testsign_context *ctx, const WCHAR *filename)
246 SIGNER_ATTR_AUTHCODE authcode = {sizeof(authcode)};
247 SIGNER_SIGNATURE_INFO signature = {sizeof(signature)};
248 SIGNER_SUBJECT_INFO subject = {sizeof(subject)};
249 SIGNER_CERT_STORE_INFO store = {sizeof(store)};
250 SIGNER_CERT cert_info = {sizeof(cert_info)};
251 SIGNER_FILE_INFO file = {sizeof(file)};
252 DWORD index = 0;
253 HRESULT hr;
255 subject.dwSubjectChoice = 1;
256 subject.pdwIndex = &index;
257 subject.pSignerFileInfo = &file;
258 file.pwszFileName = (WCHAR *)filename;
259 cert_info.dwCertChoice = 2;
260 cert_info.pCertStoreInfo = &store;
261 store.pSigningCert = ctx->cert;
262 store.dwCertPolicy = 0;
263 signature.algidHash = CALG_SHA_256;
264 signature.dwAttrChoice = SIGNER_AUTHCODE_ATTR;
265 signature.pAttrAuthcode = &authcode;
266 authcode.pwszName = L"";
267 authcode.pwszInfo = L"";
268 hr = pSignerSign(&subject, &cert_info, &signature, NULL, NULL, NULL, NULL);
269 todo_wine ok(hr == S_OK || broken(hr == NTE_BAD_ALGID) /* < 7 */, "Failed to sign, hr %#x\n", hr);
272 static void unload_driver(SC_HANDLE service)
274 SERVICE_STATUS status;
276 ControlService(service, SERVICE_CONTROL_STOP, &status);
277 while (status.dwCurrentState == SERVICE_STOP_PENDING)
279 BOOL ret;
280 Sleep(100);
281 ret = QueryServiceStatus(service, &status);
282 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
284 ok(status.dwCurrentState == SERVICE_STOPPED,
285 "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState);
287 DeleteService(service);
288 CloseServiceHandle(service);
291 static SC_HANDLE load_driver(struct testsign_context *ctx, WCHAR *filename,
292 const WCHAR *resname, const WCHAR *driver_name)
294 SC_HANDLE manager, service;
296 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
297 if (!manager && GetLastError() == ERROR_ACCESS_DENIED)
299 skip("Failed to open SC manager, not enough permissions\n");
300 return FALSE;
302 ok(!!manager, "OpenSCManager failed\n");
304 /* stop any old drivers running under this name */
305 service = OpenServiceW(manager, driver_name, SERVICE_ALL_ACCESS);
306 if (service) unload_driver(service);
308 load_resource(resname, filename);
309 testsign_sign(ctx, filename);
310 trace("Trying to load driver %s\n", debugstr_w(filename));
312 service = CreateServiceW(manager, driver_name, driver_name,
313 SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
314 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
315 filename, NULL, NULL, NULL, NULL, NULL);
316 ok(!!service, "CreateService failed: %u\n", GetLastError());
318 CloseServiceHandle(manager);
319 return service;
322 static BOOL start_driver(HANDLE service, BOOL vista_plus)
324 SERVICE_STATUS status;
325 BOOL ret;
327 SetLastError(0xdeadbeef);
328 ret = StartServiceA(service, 0, NULL);
329 if (!ret && (GetLastError() == ERROR_DRIVER_BLOCKED || GetLastError() == ERROR_INVALID_IMAGE_HASH
330 || (vista_plus && GetLastError() == ERROR_FILE_NOT_FOUND)))
332 if (vista_plus && GetLastError() == ERROR_FILE_NOT_FOUND)
334 skip("Windows Vista or newer is required to run this service.\n");
336 else
338 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
339 skip("Failed to start service; probably your machine doesn't accept unsigned drivers.\n");
341 DeleteService(service);
342 CloseServiceHandle(service);
343 return FALSE;
345 ok(ret, "StartService failed: %u\n", GetLastError());
347 /* wait for the service to start up properly */
348 ret = QueryServiceStatus(service, &status);
349 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
350 while (status.dwCurrentState == SERVICE_START_PENDING)
352 Sleep(100);
353 ret = QueryServiceStatus(service, &status);
354 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
356 ok(status.dwCurrentState == SERVICE_RUNNING,
357 "expected SERVICE_RUNNING, got %d\n", status.dwCurrentState);
358 ok(status.dwServiceType == SERVICE_KERNEL_DRIVER,
359 "expected SERVICE_KERNEL_DRIVER, got %#x\n", status.dwServiceType);
361 return TRUE;
364 static ULONG64 modified_value;
366 static void main_test(void)
368 WCHAR temppathW[MAX_PATH], pathW[MAX_PATH];
369 struct test_input *test_input;
370 DWORD len, written, read;
371 UNICODE_STRING pathU;
372 LONG new_failures;
373 char buffer[512];
374 HANDLE okfile;
375 BOOL res;
377 /* Create a temporary file that the driver will write ok/trace output to. */
378 GetTempPathW(MAX_PATH, temppathW);
379 GetTempFileNameW(temppathW, L"dok", 0, pathW);
380 pRtlDosPathNameToNtPathName_U( pathW, &pathU, NULL, NULL );
382 len = pathU.Length + sizeof(WCHAR);
383 test_input = heap_alloc( offsetof( struct test_input, path[len / sizeof(WCHAR)]) );
384 test_input->running_under_wine = !strcmp(winetest_platform, "wine");
385 test_input->winetest_report_success = winetest_report_success;
386 test_input->winetest_debug = winetest_debug;
387 test_input->process_id = GetCurrentProcessId();
388 test_input->teststr_offset = (SIZE_T)((BYTE *)&teststr - (BYTE *)NtCurrentTeb()->Peb->ImageBaseAddress);
389 test_input->modified_value = &modified_value;
390 modified_value = 0;
392 memcpy(test_input->path, pathU.Buffer, len);
393 res = DeviceIoControl(device, IOCTL_WINETEST_MAIN_TEST, test_input,
394 offsetof( struct test_input, path[len / sizeof(WCHAR)]),
395 &new_failures, sizeof(new_failures), &written, NULL);
396 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
397 ok(written == sizeof(new_failures), "got size %x\n", written);
399 okfile = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
400 ok(okfile != INVALID_HANDLE_VALUE, "failed to create %s: %u\n", wine_dbgstr_w(pathW), GetLastError());
402 /* Print the ok/trace output and then add to our failure count. */
403 do {
404 ReadFile(okfile, buffer, sizeof(buffer), &read, NULL);
405 printf("%.*s", read, buffer);
406 } while (read == sizeof(buffer));
407 winetest_add_failures(new_failures);
409 pRtlFreeUnicodeString(&pathU);
410 heap_free(test_input);
411 CloseHandle(okfile);
412 DeleteFileW(pathW);
415 static void test_basic_ioctl(void)
417 char inbuf[64], buf[32];
418 DWORD written;
419 BOOL res;
421 res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, NULL, 0, buf,
422 sizeof(buf), &written, NULL);
423 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
424 ok(written == sizeof(teststr), "got size %d\n", written);
425 ok(!strcmp(buf, teststr), "got '%s'\n", buf);
427 memset(buf, 0, sizeof(buf));
428 res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, inbuf,
429 sizeof(inbuf), buf, 10, &written, NULL);
430 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
431 ok(written == 10, "got size %d\n", written);
432 ok(!strcmp(buf, "Wine is no"), "got '%s'\n", buf);
435 static void test_mismatched_status_ioctl(void)
437 DWORD written;
438 char buf[32];
439 BOOL res;
441 res = DeviceIoControl(device, IOCTL_WINETEST_MISMATCHED_STATUS, NULL, 0, buf,
442 sizeof(buf), &written, NULL);
443 todo_wine ok(res, "DeviceIoControl failed: %u\n", GetLastError());
444 todo_wine ok(!strcmp(buf, teststr), "got '%s'\n", buf);
447 static void test_overlapped(void)
449 OVERLAPPED overlapped, overlapped2, *o;
450 DWORD cancel_cnt, size;
451 HANDLE file, port;
452 ULONG_PTR key;
453 BOOL res;
455 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
456 overlapped2.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
458 file = CreateFileA("\\\\.\\WineTestDriver", FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
459 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
460 ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
462 /* test cancelling all device requests */
463 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
464 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
466 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
467 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
469 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
470 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
472 cancel_cnt = 0xdeadbeef;
473 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
474 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
475 ok(cancel_cnt == 0, "cancel_cnt = %u\n", cancel_cnt);
477 CancelIo(file);
479 cancel_cnt = 0xdeadbeef;
480 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
481 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
482 ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
484 /* test cancelling selected overlapped event */
485 if (pCancelIoEx)
487 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
488 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
490 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
491 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
493 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
494 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
496 pCancelIoEx(file, &overlapped);
498 cancel_cnt = 0xdeadbeef;
499 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
500 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
501 ok(cancel_cnt == 1, "cancel_cnt = %u\n", cancel_cnt);
503 pCancelIoEx(file, &overlapped2);
505 cancel_cnt = 0xdeadbeef;
506 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
507 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
508 ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
511 port = CreateIoCompletionPort(file, NULL, 0xdeadbeef, 0);
512 ok(port != NULL, "CreateIoCompletionPort failed, error %u\n", GetLastError());
513 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
514 ok(!res && GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus returned %x(%u)\n", res, GetLastError());
516 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
517 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
518 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
519 ok(res, "GetQueuedCompletionStatus failed: %u\n", GetLastError());
520 ok(o == &overlapped, "o != overlapped\n");
522 if (pSetFileCompletionNotificationModes)
524 res = pSetFileCompletionNotificationModes(file, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
525 ok(res, "SetFileCompletionNotificationModes failed: %u\n", GetLastError());
527 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
528 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
529 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
530 ok(!res && GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus returned %x(%u)\n", res, GetLastError());
533 CloseHandle(port);
534 CloseHandle(overlapped.hEvent);
535 CloseHandle(overlapped2.hEvent);
536 CloseHandle(file);
539 static void test_load_driver(SC_HANDLE service)
541 SERVICE_STATUS status;
542 BOOL load, res;
543 DWORD sz;
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);
549 load = TRUE;
550 res = DeviceIoControl(device, IOCTL_WINETEST_LOAD_DRIVER, &load, sizeof(load), NULL, 0, &sz, NULL);
551 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
553 res = QueryServiceStatus(service, &status);
554 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
555 ok(status.dwCurrentState == SERVICE_RUNNING, "got state %#x\n", status.dwCurrentState);
557 load = FALSE;
558 res = DeviceIoControl(device, IOCTL_WINETEST_LOAD_DRIVER, &load, sizeof(load), NULL, 0, &sz, NULL);
559 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
561 res = QueryServiceStatus(service, &status);
562 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
563 ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
566 static void test_file_handles(void)
568 DWORD count, ret_size;
569 HANDLE file, dup, file2;
570 BOOL ret;
572 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
573 ok(ret, "ioctl failed: %u\n", GetLastError());
574 ok(count == 2, "got %u\n", count);
576 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
577 ok(ret, "ioctl failed: %u\n", GetLastError());
578 ok(count == 1, "got %u\n", count);
580 file = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
581 ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
583 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
584 ok(ret, "ioctl failed: %u\n", GetLastError());
585 ok(count == 3, "got %u\n", count);
587 file2 = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
588 ok(file2 != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
590 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
591 ok(ret, "ioctl failed: %u\n", GetLastError());
592 ok(count == 4, "got %u\n", count);
594 ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
595 ok(ret, "failed to duplicate handle: %u\n", GetLastError());
597 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
598 ok(ret, "ioctl failed: %u\n", GetLastError());
599 ok(count == 4, "got %u\n", count);
601 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
602 ok(ret, "ioctl failed: %u\n", GetLastError());
603 ok(count == 1, "got %u\n", count);
605 ret = DeviceIoControl(file, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
606 ok(ret, "ioctl failed: %u\n", GetLastError());
607 ok(count == 3, "got %u\n", count);
609 ret = DeviceIoControl(file2, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
610 ok(ret, "ioctl failed: %u\n", GetLastError());
611 ok(count == 4, "got %u\n", count);
613 ret = DeviceIoControl(dup, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
614 ok(ret, "ioctl failed: %u\n", GetLastError());
615 ok(count == 3, "got %u\n", count);
617 CloseHandle(dup);
619 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
620 ok(ret, "ioctl failed: %u\n", GetLastError());
621 ok(count == 1, "got %u\n", count);
623 CloseHandle(file2);
625 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
626 ok(ret, "ioctl failed: %u\n", GetLastError());
627 ok(count == 2, "got %u\n", count);
629 CloseHandle(file);
631 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
632 ok(ret, "ioctl failed: %u\n", GetLastError());
633 ok(count == 3, "got %u\n", count);
636 static void test_return_status(void)
638 NTSTATUS status;
639 char buffer[7];
640 DWORD ret_size;
641 BOOL ret;
643 strcpy(buffer, "abcdef");
644 status = STATUS_SUCCESS;
645 SetLastError(0xdeadbeef);
646 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
647 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
648 ok(ret, "ioctl failed\n");
649 ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
650 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
651 ok(ret_size == 3, "got size %u\n", ret_size);
653 strcpy(buffer, "abcdef");
654 status = STATUS_TIMEOUT;
655 SetLastError(0xdeadbeef);
656 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
657 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
658 todo_wine ok(ret, "ioctl failed\n");
659 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
660 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
661 ok(ret_size == 3, "got size %u\n", ret_size);
663 strcpy(buffer, "abcdef");
664 status = 0x0eadbeef;
665 SetLastError(0xdeadbeef);
666 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
667 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
668 todo_wine ok(ret, "ioctl failed\n");
669 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
670 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
671 ok(ret_size == 3, "got size %u\n", ret_size);
673 strcpy(buffer, "abcdef");
674 status = 0x4eadbeef;
675 SetLastError(0xdeadbeef);
676 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
677 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
678 todo_wine ok(ret, "ioctl failed\n");
679 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
680 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
681 ok(ret_size == 3, "got size %u\n", ret_size);
683 strcpy(buffer, "abcdef");
684 status = 0x8eadbeef;
685 SetLastError(0xdeadbeef);
686 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
687 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
688 ok(!ret, "ioctl succeeded\n");
689 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError());
690 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
691 ok(ret_size == 3, "got size %u\n", ret_size);
693 strcpy(buffer, "abcdef");
694 status = 0xceadbeef;
695 SetLastError(0xdeadbeef);
696 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
697 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
698 ok(!ret, "ioctl succeeded\n");
699 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError());
700 ok(!strcmp(buffer, "abcdef"), "got buffer %s\n", buffer);
701 ok(ret_size == 3, "got size %u\n", ret_size);
704 static BOOL compare_unicode_string(const WCHAR *buffer, ULONG len, const WCHAR *expect)
706 return len == wcslen(expect) * sizeof(WCHAR) && !memcmp(buffer, expect, len);
709 static void test_object_info(void)
711 char buffer[200];
712 OBJECT_NAME_INFORMATION *name_info = (OBJECT_NAME_INFORMATION *)buffer;
713 OBJECT_TYPE_INFORMATION *type_info = (OBJECT_TYPE_INFORMATION *)buffer;
714 FILE_FS_VOLUME_INFORMATION *volume_info = (FILE_FS_VOLUME_INFORMATION *)buffer;
715 FILE_NAME_INFORMATION *file_info = (FILE_NAME_INFORMATION *)buffer;
716 HANDLE file;
717 NTSTATUS status;
718 IO_STATUS_BLOCK io;
719 ULONG size;
721 status = NtQueryObject(device, ObjectNameInformation, buffer, sizeof(buffer), NULL);
722 ok(!status, "got %#x\n", status);
723 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
724 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
726 status = NtQueryObject(device, ObjectTypeInformation, buffer, sizeof(buffer), NULL);
727 ok(!status, "got %#x\n", status);
728 ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"),
729 "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR)));
731 status = NtQueryInformationFile(device, &io, buffer, sizeof(buffer), FileNameInformation);
732 todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#x\n", status);
734 status = NtQueryVolumeInformationFile(device, &io, buffer, sizeof(buffer), FileFsVolumeInformation);
735 todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#x\n", status);
737 file = CreateFileA("\\\\.\\WineTestDriver\\subfile", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
738 todo_wine ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
739 if (file == INVALID_HANDLE_VALUE) return;
741 memset(buffer, 0xcc, sizeof(buffer));
742 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), &size);
743 ok(!status, "got %#x\n", status);
744 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
745 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver\\subfile"),
746 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
748 memset(buffer, 0xcc, sizeof(buffer));
749 status = NtQueryObject(file, ObjectNameInformation, buffer, size - 2, &size);
750 ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status);
751 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
752 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver\\subfil"),
753 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
755 memset(buffer, 0xcc, sizeof(buffer));
756 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(*name_info), &size);
757 ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status);
758 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
760 status = NtQueryObject(file, ObjectTypeInformation, buffer, sizeof(buffer), NULL);
761 ok(!status, "got %#x\n", status);
762 ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"),
763 "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR)));
765 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
766 ok(!status, "got %#x\n", status);
767 ok(compare_unicode_string(file_info->FileName, file_info->FileNameLength, L"\\subfile"),
768 "wrong name %s\n", debugstr_wn(file_info->FileName, file_info->FileNameLength / sizeof(WCHAR)));
770 status = NtQueryVolumeInformationFile(file, &io, buffer, sizeof(buffer), FileFsVolumeInformation);
771 ok(!status, "got %#x\n", status);
772 ok(volume_info->VolumeSerialNumber == 0xdeadbeef,
773 "wrong serial number 0x%08x\n", volume_info->VolumeSerialNumber);
774 ok(compare_unicode_string(volume_info->VolumeLabel, volume_info->VolumeLabelLength, L"WineTestDriver"),
775 "wrong name %s\n", debugstr_wn(volume_info->VolumeLabel, volume_info->VolumeLabelLength / sizeof(WCHAR)));
777 CloseHandle(file);
779 file = CreateFileA("\\\\.\\WineTestDriver\\notimpl", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
780 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
782 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
783 ok(!status, "got %#x\n", status);
784 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
785 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
787 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
788 ok(status == STATUS_NOT_IMPLEMENTED, "got %#x\n", status);
790 CloseHandle(file);
792 file = CreateFileA("\\\\.\\WineTestDriver\\badparam", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
793 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
795 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
796 ok(!status, "got %#x\n", status);
797 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
798 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
800 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
801 ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status);
803 CloseHandle(file);
805 file = CreateFileA("\\\\.\\WineTestDriver\\genfail", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
806 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
808 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
809 ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status);
811 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
812 ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status);
814 CloseHandle(file);
816 file = CreateFileA("\\\\.\\WineTestDriver\\badtype", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
817 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
819 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
820 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status);
822 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
823 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status);
825 CloseHandle(file);
828 static void test_driver3(struct testsign_context *ctx)
830 WCHAR filename[MAX_PATH];
831 SC_HANDLE service;
832 BOOL ret;
834 service = load_driver(ctx, filename, L"driver3.dll", L"WineTestDriver3");
835 ok(service != NULL, "driver3 failed to load\n");
837 ret = StartServiceA(service, 0, NULL);
838 ok(!ret, "driver3 should fail to start\n");
839 ok(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED ||
840 GetLastError() == ERROR_INVALID_FUNCTION ||
841 GetLastError() == ERROR_PROC_NOT_FOUND /* XP */ ||
842 GetLastError() == ERROR_FILE_NOT_FOUND /* Win7 */, "got %u\n", GetLastError());
844 DeleteService(service);
845 CloseServiceHandle(service);
846 DeleteFileW(filename);
849 static DWORD WINAPI wsk_test_thread(void *parameter)
851 static const char test_send_string[] = "Client test string 1.";
852 static const WORD version = MAKEWORD(2, 2);
853 SOCKET s_listen, s_accept, s_connect;
854 struct sockaddr_in addr;
855 char buffer[256];
856 int ret, err;
857 WSADATA data;
858 int opt_val;
860 ret = WSAStartup(version, &data);
861 ok(!ret, "WSAStartup() failed, ret %u.\n", ret);
863 s_connect = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
864 ok(s_connect != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
866 s_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
867 ok(s_listen != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
869 opt_val = 1;
870 setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt_val, sizeof(opt_val));
872 memset(&addr, 0, sizeof(addr));
873 addr.sin_family = AF_INET;
874 addr.sin_port = htons(CLIENT_LISTEN_PORT);
875 addr.sin_addr.s_addr = htonl(0x7f000001);
876 ret = bind(s_listen, (struct sockaddr *)&addr, sizeof(addr));
877 ok(!ret, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret, WSAGetLastError());
879 ret = listen(s_listen, SOMAXCONN);
880 ok(!ret, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret, WSAGetLastError());
882 addr.sin_port = htons(SERVER_LISTEN_PORT);
884 ret = connect(s_connect, (struct sockaddr *)&addr, sizeof(addr));
885 while (ret && ((err = WSAGetLastError()) == WSAECONNREFUSED || err == WSAECONNABORTED))
887 SwitchToThread();
888 ret = connect(s_connect, (struct sockaddr *)&addr, sizeof(addr));
890 ok(!ret, "Error connecting, WSAGetLastError() %u.\n", WSAGetLastError());
892 ret = send(s_connect, test_send_string, sizeof(test_send_string), 0);
893 ok(ret == sizeof(test_send_string), "Got unexpected ret %d.\n", ret);
895 ret = recv(s_connect, buffer, sizeof(buffer), 0);
896 ok(ret == sizeof(buffer), "Got unexpected ret %d.\n", ret);
897 ok(!strcmp(buffer, "Server test string 1."), "Received unexpected data.\n");
899 s_accept = accept(s_listen, NULL, NULL);
900 ok(s_accept != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
902 closesocket(s_accept);
903 closesocket(s_connect);
904 closesocket(s_listen);
905 return TRUE;
908 static void test_driver4(struct testsign_context *ctx)
910 WCHAR filename[MAX_PATH];
911 SC_HANDLE service;
912 HANDLE hthread;
913 DWORD written;
914 BOOL ret;
916 if (!(service = load_driver(ctx, filename, L"driver4.dll", L"WineTestDriver4")))
917 return;
919 if (!start_driver(service, TRUE))
921 DeleteFileW(filename);
922 return;
925 device = CreateFileA("\\\\.\\WineTestDriver4", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
926 ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
928 hthread = CreateThread(NULL, 0, wsk_test_thread, NULL, 0, NULL);
929 main_test();
930 WaitForSingleObject(hthread, INFINITE);
932 ret = DeviceIoControl(device, IOCTL_WINETEST_DETACH, NULL, 0, NULL, 0, &written, NULL);
933 ok(ret, "DeviceIoControl failed: %u\n", GetLastError());
935 CloseHandle(device);
937 unload_driver(service);
938 ret = DeleteFileW(filename);
939 ok(ret, "DeleteFile failed: %u\n", GetLastError());
942 static void add_file_to_catalog(HANDLE catalog, const WCHAR *file)
944 SIP_SUBJECTINFO subject_info = {sizeof(SIP_SUBJECTINFO)};
945 SIP_INDIRECT_DATA *indirect_data;
946 const WCHAR *filepart = file;
947 CRYPTCATMEMBER *member;
948 WCHAR hash_buffer[100];
949 GUID subject_guid;
950 unsigned int i;
951 DWORD size;
952 BOOL ret;
954 ret = CryptSIPRetrieveSubjectGuidForCatalogFile(file, NULL, &subject_guid);
955 todo_wine ok(ret, "Failed to get subject guid, error %u\n", GetLastError());
957 size = 0;
958 subject_info.pgSubjectType = &subject_guid;
959 subject_info.pwsFileName = file;
960 subject_info.DigestAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1;
961 subject_info.dwFlags = SPC_INC_PE_RESOURCES_FLAG | SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG | SPC_EXC_PE_PAGE_HASHES_FLAG | 0x10000;
962 ret = CryptSIPCreateIndirectData(&subject_info, &size, NULL);
963 todo_wine ok(ret, "Failed to get indirect data size, error %u\n", GetLastError());
965 indirect_data = malloc(size);
966 ret = CryptSIPCreateIndirectData(&subject_info, &size, indirect_data);
967 todo_wine ok(ret, "Failed to get indirect data, error %u\n", GetLastError());
968 if (ret)
970 memset(hash_buffer, 0, sizeof(hash_buffer));
971 for (i = 0; i < indirect_data->Digest.cbData; ++i)
972 swprintf(&hash_buffer[i * 2], 2, L"%02X", indirect_data->Digest.pbData[i]);
974 member = CryptCATPutMemberInfo(catalog, (WCHAR *)file,
975 hash_buffer, &subject_guid, 0, size, (BYTE *)indirect_data);
976 ok(!!member, "Failed to write member, error %u\n", GetLastError());
978 if (wcsrchr(file, '\\'))
979 filepart = wcsrchr(file, '\\') + 1;
981 ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"File",
982 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
983 (wcslen(filepart) + 1) * 2, (BYTE *)filepart);
984 ok(ret, "Failed to write attr, error %u\n", GetLastError());
986 ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"OSAttr",
987 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
988 sizeof(L"2:6.0"), (BYTE *)L"2:6.0");
989 ok(ret, "Failed to write attr, error %u\n", GetLastError());
993 static void test_pnp_driver(struct testsign_context *ctx)
995 static const char hardware_id[] = "test_hardware_id\0";
996 char path[MAX_PATH], dest[MAX_PATH], *filepart;
997 SP_DEVINFO_DATA device = {sizeof(device)};
998 char cwd[MAX_PATH], tempdir[MAX_PATH];
999 WCHAR driver_filename[MAX_PATH];
1000 SC_HANDLE manager, service;
1001 BOOL ret, need_reboot;
1002 HANDLE catalog, file;
1003 HDEVINFO set;
1004 FILE *f;
1006 #ifdef __i386__
1007 #define EXT "x86"
1008 #elif defined(__x86_64__)
1009 #define EXT "amd64"
1010 #elif defined(__arm__)
1011 #define EXT "arm"
1012 #elif defined(__aarch64__)
1013 #define EXT "arm64"
1014 #else
1015 #define EXT
1016 #endif
1018 static const char inf_text[] =
1019 "[Version]\n"
1020 "Signature=$Chicago$\n"
1021 "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n"
1022 "CatalogFile=winetest.cat\n"
1023 "DriverVer=09/21/2006,6.0.5736.1\n"
1025 "[Manufacturer]\n"
1026 "Wine=mfg_section,NT" EXT "\n"
1028 "[mfg_section.NT" EXT "]\n"
1029 "Wine test root driver=device_section,test_hardware_id\n"
1031 "[device_section.NT" EXT "]\n"
1032 "CopyFiles=file_section\n"
1034 "[device_section.NT" EXT ".Services]\n"
1035 "AddService=winetest,0x2,svc_section\n"
1037 "[file_section]\n"
1038 "winetest.sys\n"
1040 "[SourceDisksFiles]\n"
1041 "winetest.sys=1\n"
1043 "[SourceDisksNames]\n"
1044 "1=,winetest.sys\n"
1046 "[DestinationDirs]\n"
1047 "DefaultDestDir=12\n"
1049 "[svc_section]\n"
1050 "ServiceBinary=%12%\\winetest.sys\n"
1051 "ServiceType=1\n"
1052 "StartType=3\n"
1053 "ErrorControl=1\n"
1054 "LoadOrderGroup=Extended Base\n"
1055 "DisplayName=\"winetest bus driver\"\n"
1056 "; they don't sleep anymore, on the beach\n";
1058 GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd);
1059 GetTempPathA(ARRAY_SIZE(tempdir), tempdir);
1060 SetCurrentDirectoryA(tempdir);
1062 load_resource(L"driver_pnp.dll", driver_filename);
1063 ret = MoveFileExW(driver_filename, L"winetest.sys", MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
1064 ok(ret, "failed to move file, error %u\n", GetLastError());
1066 f = fopen("winetest.inf", "w");
1067 ok(!!f, "failed to open winetest.inf: %s\n", strerror(errno));
1068 fputs(inf_text, f);
1069 fclose(f);
1071 /* Create the catalog file. */
1073 catalog = CryptCATOpen((WCHAR *)L"winetest.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0);
1074 ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#x\n", GetLastError());
1076 ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"HWID1",
1077 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
1078 sizeof(L"test_hardware_id"), (BYTE *)L"test_hardware_id");
1079 todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError());
1081 ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"OS",
1082 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
1083 sizeof(L"VistaX64"), (BYTE *)L"VistaX64");
1084 todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError());
1086 add_file_to_catalog(catalog, L"winetest.sys");
1087 add_file_to_catalog(catalog, L"winetest.inf");
1089 ret = CryptCATPersistStore(catalog);
1090 todo_wine ok(ret, "Failed to write catalog, error %u\n", GetLastError());
1092 ret = CryptCATClose(catalog);
1093 ok(ret, "Failed to close catalog, error %u\n", GetLastError());
1095 testsign_sign(ctx, L"winetest.cat");
1097 /* Install the driver. */
1099 set = SetupDiCreateDeviceInfoList(NULL, NULL);
1100 ok(set != INVALID_HANDLE_VALUE, "failed to create device list, error %#x\n", GetLastError());
1102 ret = SetupDiCreateDeviceInfoA(set, "root\\winetest\\0", &GUID_NULL, NULL, NULL, 0, &device);
1103 ok(ret, "failed to create device, error %#x\n", GetLastError());
1105 ret = SetupDiSetDeviceRegistryPropertyA( set, &device, SPDRP_HARDWAREID,
1106 (const BYTE *)hardware_id, sizeof(hardware_id) );
1107 ok(ret, "failed to create set hardware ID, error %#x\n", GetLastError());
1109 ret = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device);
1110 ok(ret, "failed to register device, error %#x\n", GetLastError());
1112 GetFullPathNameA("winetest.inf", sizeof(path), path, NULL);
1113 ret = UpdateDriverForPlugAndPlayDevicesA(NULL, hardware_id, path, INSTALLFLAG_FORCE, &need_reboot);
1114 ok(ret, "failed to install device, error %#x\n", GetLastError());
1115 ok(!need_reboot, "expected no reboot necessary\n");
1117 /* Tests. */
1119 file = CreateFileA("\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1120 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
1121 CloseHandle(file);
1123 /* Clean up. */
1125 ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device);
1126 ok(ret, "failed to remove device, error %#x\n", GetLastError());
1128 file = CreateFileA("\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1129 ok(file == INVALID_HANDLE_VALUE, "expected failure\n");
1130 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %u\n", GetLastError());
1132 ret = SetupDiDestroyDeviceInfoList(set);
1133 ok(ret, "failed to destroy set, error %#x\n", GetLastError());
1135 /* Windows stops the service but does not delete it. */
1136 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1137 ok(!!manager, "failed to open service manager, error %u\n", GetLastError());
1138 service = OpenServiceA(manager, "winetest", SERVICE_STOP | DELETE);
1139 ok(!!service, "failed to open service, error %u\n", GetLastError());
1140 unload_driver(service);
1141 CloseServiceHandle(manager);
1143 GetFullPathNameA("winetest.inf", sizeof(path), path, NULL);
1144 ret = SetupCopyOEMInfA(path, NULL, 0, 0, dest, sizeof(dest), NULL, &filepart);
1145 ok(ret, "Failed to copy INF, error %#x\n", GetLastError());
1146 ret = SetupUninstallOEMInfA(filepart, 0, NULL);
1147 ok(ret, "Failed to uninstall INF, error %u\n", GetLastError());
1149 ret = DeleteFileA("winetest.cat");
1150 ok(ret, "Failed to delete file, error %u\n", GetLastError());
1151 ret = DeleteFileA("winetest.inf");
1152 ok(ret, "Failed to delete file, error %u\n", GetLastError());
1153 ret = DeleteFileA("winetest.sys");
1154 ok(ret, "Failed to delete file, error %u\n", GetLastError());
1155 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
1156 ret = DeleteFileA("C:/windows/system32/drivers/winetest.sys");
1157 ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND, "Failed to delete file, error %u\n", GetLastError());
1159 SetCurrentDirectoryA(cwd);
1162 START_TEST(ntoskrnl)
1164 WCHAR filename[MAX_PATH], filename2[MAX_PATH];
1165 struct testsign_context ctx;
1166 SC_HANDLE service, service2;
1167 BOOL ret, is_wow64;
1168 DWORD written;
1170 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U");
1171 pRtlFreeUnicodeString = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString");
1172 pCancelIoEx = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx");
1173 pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
1174 pSetFileCompletionNotificationModes = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"),
1175 "SetFileCompletionNotificationModes");
1176 pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
1178 if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)
1180 skip("Running in WoW64.\n");
1181 return;
1184 if (!testsign_create_cert(&ctx))
1185 return;
1187 subtest("driver");
1188 if (!(service = load_driver(&ctx, filename, L"driver.dll", L"WineTestDriver")))
1190 testsign_cleanup(&ctx);
1191 return;
1194 if (!start_driver(service, FALSE))
1196 DeleteFileW(filename);
1197 testsign_cleanup(&ctx);
1198 return;
1200 service2 = load_driver(&ctx, filename2, L"driver2.dll", L"WineTestDriver2");
1202 device = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1203 ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
1205 test_basic_ioctl();
1206 test_mismatched_status_ioctl();
1208 main_test();
1209 todo_wine ok(modified_value == 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value);
1211 test_overlapped();
1212 test_load_driver(service2);
1213 test_file_handles();
1214 test_return_status();
1215 test_object_info();
1217 /* We need a separate ioctl to call IoDetachDevice(); calling it in the
1218 * driver unload routine causes a live-lock. */
1219 ret = DeviceIoControl(device, IOCTL_WINETEST_DETACH, NULL, 0, NULL, 0, &written, NULL);
1220 ok(ret, "DeviceIoControl failed: %u\n", GetLastError());
1222 CloseHandle(device);
1224 unload_driver(service2);
1225 unload_driver(service);
1226 ret = DeleteFileW(filename);
1227 ok(ret, "DeleteFile failed: %u\n", GetLastError());
1228 ret = DeleteFileW(filename2);
1229 ok(ret, "DeleteFile failed: %u\n", GetLastError());
1231 test_driver3(&ctx);
1232 subtest("driver4");
1233 test_driver4(&ctx);
1235 test_pnp_driver(&ctx);
1237 testsign_cleanup(&ctx);