ntoskrnl/tests: Retrieve test global variables from a memory section.
[wine.git] / dlls / ntoskrnl.exe / tests / ntoskrnl.c
blob92cbfa6a329d14f41f403380f34df8f7ee8dad37
1 /*
2 * ntoskrnl.exe testing framework
4 * Copyright 2015 Sebastian Lackner
5 * Copyright 2015 Michael Müller
6 * Copyright 2015 Christian Costa
7 * Copyright 2020-2021 Zebediah Figura for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <stdio.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windows.h"
28 #include "winsvc.h"
29 #include "winioctl.h"
30 #include "winternl.h"
31 #include "winsock2.h"
32 #include "wincrypt.h"
33 #include "ntsecapi.h"
34 #include "mscat.h"
35 #include "mssip.h"
36 #include "setupapi.h"
37 #include "newdev.h"
38 #include "initguid.h"
39 #include "devguid.h"
40 #include "wine/test.h"
41 #include "wine/heap.h"
42 #include "wine/mssign.h"
44 #include "driver.h"
46 static const GUID GUID_NULL;
48 static HANDLE device;
50 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR *, UNICODE_STRING *, WCHAR **, CURDIR *);
51 static BOOL (WINAPI *pRtlFreeUnicodeString)(UNICODE_STRING *);
52 static BOOL (WINAPI *pCancelIoEx)(HANDLE, OVERLAPPED *);
53 static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *);
54 static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR);
55 static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert,
56 SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider,
57 const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data);
59 static void load_resource(const WCHAR *name, WCHAR *filename)
61 static WCHAR path[MAX_PATH];
62 DWORD written;
63 HANDLE file;
64 HRSRC res;
65 void *ptr;
67 GetTempPathW(ARRAY_SIZE(path), path);
68 GetTempFileNameW(path, name, 0, filename);
70 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
71 ok(file != INVALID_HANDLE_VALUE, "failed to create %s, error %u\n", debugstr_w(filename), GetLastError());
73 res = FindResourceW(NULL, name, L"TESTDLL");
74 ok( res != 0, "couldn't find resource\n" );
75 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
76 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
77 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
78 CloseHandle( file );
81 struct testsign_context
83 HCRYPTPROV provider;
84 const CERT_CONTEXT *cert, *root_cert, *publisher_cert;
85 HCERTSTORE root_store, publisher_store;
88 static BOOL testsign_create_cert(struct testsign_context *ctx)
90 BYTE encoded_name[100], encoded_key_id[200], public_key_info_buffer[1000];
91 WCHAR container_name[26];
92 BYTE hash_buffer[16], cert_buffer[1000], provider_nameA[100], serial[16];
93 CERT_PUBLIC_KEY_INFO *public_key_info = (CERT_PUBLIC_KEY_INFO *)public_key_info_buffer;
94 CRYPT_KEY_PROV_INFO provider_info = {0};
95 CRYPT_ALGORITHM_IDENTIFIER algid = {0};
96 CERT_AUTHORITY_KEY_ID_INFO key_info;
97 CERT_INFO cert_info = {0};
98 WCHAR provider_nameW[100];
99 CERT_EXTENSION extension;
100 HCRYPTKEY key;
101 DWORD size;
102 BOOL ret;
104 memset(ctx, 0, sizeof(*ctx));
106 srand(time(NULL));
107 swprintf(container_name, ARRAY_SIZE(container_name), L"wine_testsign%u", rand());
109 ret = CryptAcquireContextW(&ctx->provider, container_name, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
110 ok(ret, "Failed to create container, error %#x\n", GetLastError());
112 ret = CryptGenKey(ctx->provider, AT_SIGNATURE, CRYPT_EXPORTABLE, &key);
113 ok(ret, "Failed to create key, error %#x\n", GetLastError());
114 ret = CryptDestroyKey(key);
115 ok(ret, "Failed to destroy key, error %#x\n", GetLastError());
116 ret = CryptGetUserKey(ctx->provider, AT_SIGNATURE, &key);
117 ok(ret, "Failed to get user key, error %#x\n", GetLastError());
118 ret = CryptDestroyKey(key);
119 ok(ret, "Failed to destroy key, error %#x\n", GetLastError());
121 size = sizeof(encoded_name);
122 ret = CertStrToNameA(X509_ASN_ENCODING, "CN=winetest_cert", CERT_X500_NAME_STR, NULL, encoded_name, &size, NULL);
123 ok(ret, "Failed to convert name, error %#x\n", GetLastError());
124 key_info.CertIssuer.cbData = size;
125 key_info.CertIssuer.pbData = encoded_name;
127 size = sizeof(public_key_info_buffer);
128 ret = CryptExportPublicKeyInfo(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, public_key_info, &size);
129 ok(ret, "Failed to export public key, error %#x\n", GetLastError());
130 cert_info.SubjectPublicKeyInfo = *public_key_info;
132 size = sizeof(hash_buffer);
133 ret = CryptHashPublicKeyInfo(ctx->provider, CALG_MD5, 0, X509_ASN_ENCODING, public_key_info, hash_buffer, &size);
134 ok(ret, "Failed to hash public key, error %#x\n", GetLastError());
136 key_info.KeyId.cbData = size;
137 key_info.KeyId.pbData = hash_buffer;
139 RtlGenRandom(serial, sizeof(serial));
140 key_info.CertSerialNumber.cbData = sizeof(serial);
141 key_info.CertSerialNumber.pbData = serial;
143 size = sizeof(encoded_key_id);
144 ret = CryptEncodeObject(X509_ASN_ENCODING, X509_AUTHORITY_KEY_ID, &key_info, encoded_key_id, &size);
145 ok(ret, "Failed to convert name, error %#x\n", GetLastError());
147 extension.pszObjId = (char *)szOID_AUTHORITY_KEY_IDENTIFIER;
148 extension.fCritical = TRUE;
149 extension.Value.cbData = size;
150 extension.Value.pbData = encoded_key_id;
152 cert_info.dwVersion = CERT_V3;
153 cert_info.SerialNumber = key_info.CertSerialNumber;
154 cert_info.SignatureAlgorithm.pszObjId = (char *)szOID_RSA_SHA1RSA;
155 cert_info.Issuer = key_info.CertIssuer;
156 GetSystemTimeAsFileTime(&cert_info.NotBefore);
157 GetSystemTimeAsFileTime(&cert_info.NotAfter);
158 cert_info.NotAfter.dwHighDateTime += 1;
159 cert_info.Subject = key_info.CertIssuer;
160 cert_info.cExtension = 1;
161 cert_info.rgExtension = &extension;
162 algid.pszObjId = (char *)szOID_RSA_SHA1RSA;
163 size = sizeof(cert_buffer);
164 ret = CryptSignAndEncodeCertificate(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING,
165 X509_CERT_TO_BE_SIGNED, &cert_info, &algid, NULL, cert_buffer, &size);
166 ok(ret, "Failed to create certificate, error %#x\n", GetLastError());
168 ctx->cert = CertCreateCertificateContext(X509_ASN_ENCODING, cert_buffer, size);
169 ok(!!ctx->cert, "Failed to create context, error %#x\n", GetLastError());
171 size = sizeof(provider_nameA);
172 ret = CryptGetProvParam(ctx->provider, PP_NAME, provider_nameA, &size, 0);
173 ok(ret, "Failed to get prov param, error %#x\n", GetLastError());
174 MultiByteToWideChar(CP_ACP, 0, (char *)provider_nameA, -1, provider_nameW, ARRAY_SIZE(provider_nameW));
176 provider_info.pwszContainerName = (WCHAR *)container_name;
177 provider_info.pwszProvName = provider_nameW;
178 provider_info.dwProvType = PROV_RSA_FULL;
179 provider_info.dwKeySpec = AT_SIGNATURE;
180 ret = CertSetCertificateContextProperty(ctx->cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &provider_info);
181 ok(ret, "Failed to set provider info, error %#x\n", GetLastError());
183 ctx->root_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "root");
184 if (!ctx->root_store && GetLastError() == ERROR_ACCESS_DENIED)
186 skip("Failed to open root store.\n");
188 ret = CertFreeCertificateContext(ctx->cert);
189 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
190 ret = CryptReleaseContext(ctx->provider, 0);
191 ok(ret, "failed to release context, error %u\n", GetLastError());
193 return FALSE;
195 ok(!!ctx->root_store, "Failed to open store, error %u\n", GetLastError());
196 ret = CertAddCertificateContextToStore(ctx->root_store, ctx->cert, CERT_STORE_ADD_ALWAYS, &ctx->root_cert);
197 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
199 skip("Failed to add self-signed certificate to store.\n");
201 ret = CertFreeCertificateContext(ctx->cert);
202 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
203 ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG);
204 ok(ret, "Failed to close store, error %u\n", GetLastError());
205 ret = CryptReleaseContext(ctx->provider, 0);
206 ok(ret, "failed to release context, error %u\n", GetLastError());
208 return FALSE;
210 ok(ret, "Failed to add certificate, error %u\n", GetLastError());
212 ctx->publisher_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0,
213 CERT_SYSTEM_STORE_LOCAL_MACHINE, "trustedpublisher");
214 ok(!!ctx->publisher_store, "Failed to open store, error %u\n", GetLastError());
215 ret = CertAddCertificateContextToStore(ctx->publisher_store, ctx->cert,
216 CERT_STORE_ADD_ALWAYS, &ctx->publisher_cert);
217 ok(ret, "Failed to add certificate, error %u\n", GetLastError());
219 return TRUE;
222 static void testsign_cleanup(struct testsign_context *ctx)
224 BOOL ret;
226 ret = CertFreeCertificateContext(ctx->cert);
227 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
229 ret = CertDeleteCertificateFromStore(ctx->root_cert);
230 ok(ret, "Failed to remove certificate, error %u\n", GetLastError());
231 ret = CertFreeCertificateContext(ctx->root_cert);
232 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
233 ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG);
234 ok(ret, "Failed to close store, error %u\n", GetLastError());
236 ret = CertDeleteCertificateFromStore(ctx->publisher_cert);
237 ok(ret, "Failed to remove certificate, error %u\n", GetLastError());
238 ret = CertFreeCertificateContext(ctx->publisher_cert);
239 ok(ret, "Failed to free certificate, error %u\n", GetLastError());
240 ret = CertCloseStore(ctx->publisher_store, CERT_CLOSE_STORE_CHECK_FLAG);
241 ok(ret, "Failed to close store, error %u\n", GetLastError());
243 ret = CryptReleaseContext(ctx->provider, 0);
244 ok(ret, "failed to release context, error %u\n", GetLastError());
247 static void testsign_sign(struct testsign_context *ctx, const WCHAR *filename)
249 SIGNER_ATTR_AUTHCODE authcode = {sizeof(authcode)};
250 SIGNER_SIGNATURE_INFO signature = {sizeof(signature)};
251 SIGNER_SUBJECT_INFO subject = {sizeof(subject)};
252 SIGNER_CERT_STORE_INFO store = {sizeof(store)};
253 SIGNER_CERT cert_info = {sizeof(cert_info)};
254 SIGNER_FILE_INFO file = {sizeof(file)};
255 DWORD index = 0;
256 HRESULT hr;
258 subject.dwSubjectChoice = 1;
259 subject.pdwIndex = &index;
260 subject.pSignerFileInfo = &file;
261 file.pwszFileName = (WCHAR *)filename;
262 cert_info.dwCertChoice = 2;
263 cert_info.pCertStoreInfo = &store;
264 store.pSigningCert = ctx->cert;
265 store.dwCertPolicy = 0;
266 signature.algidHash = CALG_SHA_256;
267 signature.dwAttrChoice = SIGNER_AUTHCODE_ATTR;
268 signature.pAttrAuthcode = &authcode;
269 authcode.pwszName = L"";
270 authcode.pwszInfo = L"";
271 hr = pSignerSign(&subject, &cert_info, &signature, NULL, NULL, NULL, NULL);
272 todo_wine ok(hr == S_OK || broken(hr == NTE_BAD_ALGID) /* < 7 */, "Failed to sign, hr %#x\n", hr);
275 static void unload_driver(SC_HANDLE service)
277 SERVICE_STATUS status;
279 ControlService(service, SERVICE_CONTROL_STOP, &status);
280 while (status.dwCurrentState == SERVICE_STOP_PENDING)
282 BOOL ret;
283 Sleep(100);
284 ret = QueryServiceStatus(service, &status);
285 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
287 ok(status.dwCurrentState == SERVICE_STOPPED,
288 "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState);
290 DeleteService(service);
291 CloseServiceHandle(service);
294 static SC_HANDLE load_driver(struct testsign_context *ctx, WCHAR *filename,
295 const WCHAR *resname, const WCHAR *driver_name)
297 SC_HANDLE manager, service;
299 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
300 if (!manager && GetLastError() == ERROR_ACCESS_DENIED)
302 skip("Failed to open SC manager, not enough permissions\n");
303 return FALSE;
305 ok(!!manager, "OpenSCManager failed\n");
307 /* stop any old drivers running under this name */
308 service = OpenServiceW(manager, driver_name, SERVICE_ALL_ACCESS);
309 if (service) unload_driver(service);
311 load_resource(resname, filename);
312 testsign_sign(ctx, filename);
313 trace("Trying to load driver %s\n", debugstr_w(filename));
315 service = CreateServiceW(manager, driver_name, driver_name,
316 SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
317 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
318 filename, NULL, NULL, NULL, NULL, NULL);
319 ok(!!service, "CreateService failed: %u\n", GetLastError());
321 CloseServiceHandle(manager);
322 return service;
325 static BOOL start_driver(HANDLE service, BOOL vista_plus)
327 SERVICE_STATUS status;
328 BOOL ret;
330 SetLastError(0xdeadbeef);
331 ret = StartServiceA(service, 0, NULL);
332 if (!ret && (GetLastError() == ERROR_DRIVER_BLOCKED || GetLastError() == ERROR_INVALID_IMAGE_HASH
333 || (vista_plus && GetLastError() == ERROR_FILE_NOT_FOUND)))
335 if (vista_plus && GetLastError() == ERROR_FILE_NOT_FOUND)
337 skip("Windows Vista or newer is required to run this service.\n");
339 else
341 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
342 skip("Failed to start service; probably your machine doesn't accept unsigned drivers.\n");
344 DeleteService(service);
345 CloseServiceHandle(service);
346 return FALSE;
348 ok(ret, "StartService failed: %u\n", GetLastError());
350 /* wait for the service to start up properly */
351 ret = QueryServiceStatus(service, &status);
352 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
353 while (status.dwCurrentState == SERVICE_START_PENDING)
355 Sleep(100);
356 ret = QueryServiceStatus(service, &status);
357 ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
359 ok(status.dwCurrentState == SERVICE_RUNNING,
360 "expected SERVICE_RUNNING, got %d\n", status.dwCurrentState);
361 ok(status.dwServiceType == SERVICE_KERNEL_DRIVER,
362 "expected SERVICE_KERNEL_DRIVER, got %#x\n", status.dwServiceType);
364 return TRUE;
367 static ULONG64 modified_value;
369 static void main_test(void)
371 struct main_test_input *test_input;
372 DWORD written, read;
373 LONG new_failures;
374 char buffer[512];
375 HANDLE okfile;
376 BOOL res;
378 /* Create a temporary file that the driver will write ok/trace output to. */
380 okfile = CreateFileA("C:\\windows\\winetest_ntoskrnl_okfile", GENERIC_READ,
381 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
382 ok(okfile != INVALID_HANDLE_VALUE, "failed to create file, error %u\n", GetLastError());
384 test_input = heap_alloc( sizeof(*test_input) );
385 test_input->process_id = GetCurrentProcessId();
386 test_input->teststr_offset = (SIZE_T)((BYTE *)&teststr - (BYTE *)NtCurrentTeb()->Peb->ImageBaseAddress);
387 test_input->modified_value = &modified_value;
388 modified_value = 0;
390 res = DeviceIoControl(device, IOCTL_WINETEST_MAIN_TEST, test_input, sizeof(*test_input),
391 &new_failures, sizeof(new_failures), &written, NULL);
392 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
393 ok(written == sizeof(new_failures), "got size %x\n", written);
395 /* Print the ok/trace output and then add to our failure count. */
396 do {
397 ReadFile(okfile, buffer, sizeof(buffer), &read, NULL);
398 printf("%.*s", read, buffer);
399 } while (read == sizeof(buffer));
400 winetest_add_failures(new_failures);
402 heap_free(test_input);
403 CloseHandle(okfile);
404 DeleteFileA("C:\\windows\\winetest_ntoskrnl_okfile");
407 static void test_basic_ioctl(void)
409 char inbuf[64], buf[32];
410 DWORD written;
411 BOOL res;
413 res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, NULL, 0, buf,
414 sizeof(buf), &written, NULL);
415 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
416 ok(written == sizeof(teststr), "got size %d\n", written);
417 ok(!strcmp(buf, teststr), "got '%s'\n", buf);
419 memset(buf, 0, sizeof(buf));
420 res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, inbuf,
421 sizeof(inbuf), buf, 10, &written, NULL);
422 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
423 ok(written == 10, "got size %d\n", written);
424 ok(!strcmp(buf, "Wine is no"), "got '%s'\n", buf);
427 static void test_mismatched_status_ioctl(void)
429 DWORD written;
430 char buf[32];
431 BOOL res;
433 res = DeviceIoControl(device, IOCTL_WINETEST_MISMATCHED_STATUS, NULL, 0, buf,
434 sizeof(buf), &written, NULL);
435 todo_wine ok(res, "DeviceIoControl failed: %u\n", GetLastError());
436 todo_wine ok(!strcmp(buf, teststr), "got '%s'\n", buf);
439 static void test_overlapped(void)
441 OVERLAPPED overlapped, overlapped2, *o;
442 DWORD cancel_cnt, size;
443 HANDLE file, port;
444 ULONG_PTR key;
445 BOOL res;
447 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
448 overlapped2.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
450 file = CreateFileA("\\\\.\\WineTestDriver", FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
451 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
452 ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
454 /* test cancelling all device requests */
455 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
456 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
458 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
459 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
461 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
462 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
464 cancel_cnt = 0xdeadbeef;
465 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
466 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
467 ok(cancel_cnt == 0, "cancel_cnt = %u\n", cancel_cnt);
469 CancelIo(file);
471 cancel_cnt = 0xdeadbeef;
472 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
473 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
474 ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
476 /* test cancelling selected overlapped event */
477 if (pCancelIoEx)
479 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
480 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
482 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
483 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
485 res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
486 ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
488 pCancelIoEx(file, &overlapped);
490 cancel_cnt = 0xdeadbeef;
491 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
492 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
493 ok(cancel_cnt == 1, "cancel_cnt = %u\n", cancel_cnt);
495 pCancelIoEx(file, &overlapped2);
497 cancel_cnt = 0xdeadbeef;
498 res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
499 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
500 ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
503 port = CreateIoCompletionPort(file, NULL, 0xdeadbeef, 0);
504 ok(port != NULL, "CreateIoCompletionPort failed, error %u\n", GetLastError());
505 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
506 ok(!res && GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus returned %x(%u)\n", res, GetLastError());
508 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
509 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
510 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
511 ok(res, "GetQueuedCompletionStatus failed: %u\n", GetLastError());
512 ok(o == &overlapped, "o != overlapped\n");
514 if (pSetFileCompletionNotificationModes)
516 res = pSetFileCompletionNotificationModes(file, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
517 ok(res, "SetFileCompletionNotificationModes failed: %u\n", GetLastError());
519 res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
520 ok(res, "DeviceIoControl failed: %u\n", GetLastError());
521 res = GetQueuedCompletionStatus(port, &size, &key, &o, 0);
522 ok(!res && GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus returned %x(%u)\n", res, GetLastError());
525 CloseHandle(port);
526 CloseHandle(overlapped.hEvent);
527 CloseHandle(overlapped2.hEvent);
528 CloseHandle(file);
531 static void test_load_driver(SC_HANDLE service)
533 SERVICE_STATUS status;
534 BOOL load, res;
535 DWORD sz;
537 res = QueryServiceStatus(service, &status);
538 ok(res, "QueryServiceStatusEx failed: %u\n", GetLastError());
539 ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
541 load = TRUE;
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_RUNNING, "got state %#x\n", status.dwCurrentState);
549 load = FALSE;
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_STOPPED, "got state %#x\n", status.dwCurrentState);
558 static void test_file_handles(void)
560 DWORD count, ret_size;
561 HANDLE file, dup, file2;
562 BOOL ret;
564 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
565 ok(ret, "ioctl failed: %u\n", GetLastError());
566 ok(count == 2, "got %u\n", count);
568 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
569 ok(ret, "ioctl failed: %u\n", GetLastError());
570 ok(count == 1, "got %u\n", count);
572 file = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
573 ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
575 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
576 ok(ret, "ioctl failed: %u\n", GetLastError());
577 ok(count == 3, "got %u\n", count);
579 file2 = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
580 ok(file2 != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
582 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
583 ok(ret, "ioctl failed: %u\n", GetLastError());
584 ok(count == 4, "got %u\n", count);
586 ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
587 ok(ret, "failed to duplicate handle: %u\n", GetLastError());
589 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
590 ok(ret, "ioctl failed: %u\n", GetLastError());
591 ok(count == 4, "got %u\n", count);
593 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
594 ok(ret, "ioctl failed: %u\n", GetLastError());
595 ok(count == 1, "got %u\n", count);
597 ret = DeviceIoControl(file, 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 ret = DeviceIoControl(file2, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
602 ok(ret, "ioctl failed: %u\n", GetLastError());
603 ok(count == 4, "got %u\n", count);
605 ret = DeviceIoControl(dup, 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 CloseHandle(dup);
611 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
612 ok(ret, "ioctl failed: %u\n", GetLastError());
613 ok(count == 1, "got %u\n", count);
615 CloseHandle(file2);
617 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
618 ok(ret, "ioctl failed: %u\n", GetLastError());
619 ok(count == 2, "got %u\n", count);
621 CloseHandle(file);
623 ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
624 ok(ret, "ioctl failed: %u\n", GetLastError());
625 ok(count == 3, "got %u\n", count);
628 static void test_return_status(void)
630 NTSTATUS status;
631 char buffer[7];
632 DWORD ret_size;
633 BOOL ret;
635 strcpy(buffer, "abcdef");
636 status = STATUS_SUCCESS;
637 SetLastError(0xdeadbeef);
638 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
639 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
640 ok(ret, "ioctl failed\n");
641 ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
642 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
643 ok(ret_size == 3, "got size %u\n", ret_size);
645 strcpy(buffer, "abcdef");
646 status = STATUS_TIMEOUT;
647 SetLastError(0xdeadbeef);
648 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
649 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
650 todo_wine ok(ret, "ioctl failed\n");
651 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
652 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
653 ok(ret_size == 3, "got size %u\n", ret_size);
655 strcpy(buffer, "abcdef");
656 status = 0x0eadbeef;
657 SetLastError(0xdeadbeef);
658 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
659 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
660 todo_wine ok(ret, "ioctl failed\n");
661 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
662 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
663 ok(ret_size == 3, "got size %u\n", ret_size);
665 strcpy(buffer, "abcdef");
666 status = 0x4eadbeef;
667 SetLastError(0xdeadbeef);
668 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
669 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
670 todo_wine ok(ret, "ioctl failed\n");
671 todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
672 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
673 ok(ret_size == 3, "got size %u\n", ret_size);
675 strcpy(buffer, "abcdef");
676 status = 0x8eadbeef;
677 SetLastError(0xdeadbeef);
678 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
679 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
680 ok(!ret, "ioctl succeeded\n");
681 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError());
682 ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer);
683 ok(ret_size == 3, "got size %u\n", ret_size);
685 strcpy(buffer, "abcdef");
686 status = 0xceadbeef;
687 SetLastError(0xdeadbeef);
688 ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status,
689 sizeof(status), buffer, sizeof(buffer), &ret_size, NULL);
690 ok(!ret, "ioctl succeeded\n");
691 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError());
692 ok(!strcmp(buffer, "abcdef"), "got buffer %s\n", buffer);
693 ok(ret_size == 3, "got size %u\n", ret_size);
696 static BOOL compare_unicode_string(const WCHAR *buffer, ULONG len, const WCHAR *expect)
698 return len == wcslen(expect) * sizeof(WCHAR) && !memcmp(buffer, expect, len);
701 static void test_object_info(void)
703 char buffer[200];
704 OBJECT_NAME_INFORMATION *name_info = (OBJECT_NAME_INFORMATION *)buffer;
705 OBJECT_TYPE_INFORMATION *type_info = (OBJECT_TYPE_INFORMATION *)buffer;
706 FILE_FS_VOLUME_INFORMATION *volume_info = (FILE_FS_VOLUME_INFORMATION *)buffer;
707 FILE_NAME_INFORMATION *file_info = (FILE_NAME_INFORMATION *)buffer;
708 HANDLE file;
709 NTSTATUS status;
710 IO_STATUS_BLOCK io;
711 ULONG size;
713 status = NtQueryObject(device, ObjectNameInformation, buffer, sizeof(buffer), NULL);
714 ok(!status, "got %#x\n", status);
715 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
716 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
718 status = NtQueryObject(device, ObjectTypeInformation, buffer, sizeof(buffer), NULL);
719 ok(!status, "got %#x\n", status);
720 ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"),
721 "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR)));
723 status = NtQueryInformationFile(device, &io, buffer, sizeof(buffer), FileNameInformation);
724 todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#x\n", status);
726 status = NtQueryVolumeInformationFile(device, &io, buffer, sizeof(buffer), FileFsVolumeInformation);
727 todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#x\n", status);
729 file = CreateFileA("\\\\.\\WineTestDriver\\subfile", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
730 todo_wine ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
731 if (file == INVALID_HANDLE_VALUE) return;
733 memset(buffer, 0xcc, sizeof(buffer));
734 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), &size);
735 ok(!status, "got %#x\n", status);
736 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
737 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver\\subfile"),
738 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
740 memset(buffer, 0xcc, sizeof(buffer));
741 status = NtQueryObject(file, ObjectNameInformation, buffer, size - 2, &size);
742 ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status);
743 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
744 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver\\subfil"),
745 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
747 memset(buffer, 0xcc, sizeof(buffer));
748 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(*name_info), &size);
749 ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status);
750 ok(size == sizeof(*name_info) + sizeof(L"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size);
752 status = NtQueryObject(file, ObjectTypeInformation, buffer, sizeof(buffer), NULL);
753 ok(!status, "got %#x\n", status);
754 ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"),
755 "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR)));
757 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
758 ok(!status, "got %#x\n", status);
759 ok(compare_unicode_string(file_info->FileName, file_info->FileNameLength, L"\\subfile"),
760 "wrong name %s\n", debugstr_wn(file_info->FileName, file_info->FileNameLength / sizeof(WCHAR)));
762 status = NtQueryVolumeInformationFile(file, &io, buffer, sizeof(buffer), FileFsVolumeInformation);
763 ok(!status, "got %#x\n", status);
764 ok(volume_info->VolumeSerialNumber == 0xdeadbeef,
765 "wrong serial number 0x%08x\n", volume_info->VolumeSerialNumber);
766 ok(compare_unicode_string(volume_info->VolumeLabel, volume_info->VolumeLabelLength, L"WineTestDriver"),
767 "wrong name %s\n", debugstr_wn(volume_info->VolumeLabel, volume_info->VolumeLabelLength / sizeof(WCHAR)));
769 CloseHandle(file);
771 file = CreateFileA("\\\\.\\WineTestDriver\\notimpl", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
772 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
774 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
775 ok(!status, "got %#x\n", status);
776 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
777 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
779 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
780 ok(status == STATUS_NOT_IMPLEMENTED, "got %#x\n", status);
782 CloseHandle(file);
784 file = CreateFileA("\\\\.\\WineTestDriver\\badparam", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
785 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
787 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
788 ok(!status, "got %#x\n", status);
789 ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\\Device\\WineTestDriver"),
790 "wrong name %s\n", debugstr_w(name_info->Name.Buffer));
792 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
793 ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status);
795 CloseHandle(file);
797 file = CreateFileA("\\\\.\\WineTestDriver\\genfail", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
798 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
800 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
801 ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status);
803 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
804 ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status);
806 CloseHandle(file);
808 file = CreateFileA("\\\\.\\WineTestDriver\\badtype", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
809 ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
811 status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL);
812 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status);
814 status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation);
815 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status);
817 CloseHandle(file);
820 static void test_driver3(struct testsign_context *ctx)
822 WCHAR filename[MAX_PATH];
823 SC_HANDLE service;
824 BOOL ret;
826 service = load_driver(ctx, filename, L"driver3.dll", L"WineTestDriver3");
827 ok(service != NULL, "driver3 failed to load\n");
829 ret = StartServiceA(service, 0, NULL);
830 ok(!ret, "driver3 should fail to start\n");
831 ok(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED ||
832 GetLastError() == ERROR_INVALID_FUNCTION ||
833 GetLastError() == ERROR_PROC_NOT_FOUND /* XP */ ||
834 GetLastError() == ERROR_FILE_NOT_FOUND /* Win7 */, "got %u\n", GetLastError());
836 DeleteService(service);
837 CloseServiceHandle(service);
838 DeleteFileW(filename);
841 static DWORD WINAPI wsk_test_thread(void *parameter)
843 static const char test_send_string[] = "Client test string 1.";
844 static const WORD version = MAKEWORD(2, 2);
845 SOCKET s_listen, s_accept, s_connect;
846 struct sockaddr_in addr;
847 char buffer[256];
848 int ret, err;
849 WSADATA data;
850 int opt_val;
852 ret = WSAStartup(version, &data);
853 ok(!ret, "WSAStartup() failed, ret %u.\n", ret);
855 s_connect = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
856 ok(s_connect != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
858 s_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
859 ok(s_listen != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
861 opt_val = 1;
862 setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt_val, sizeof(opt_val));
864 memset(&addr, 0, sizeof(addr));
865 addr.sin_family = AF_INET;
866 addr.sin_port = htons(CLIENT_LISTEN_PORT);
867 addr.sin_addr.s_addr = htonl(0x7f000001);
868 ret = bind(s_listen, (struct sockaddr *)&addr, sizeof(addr));
869 ok(!ret, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret, WSAGetLastError());
871 ret = listen(s_listen, SOMAXCONN);
872 ok(!ret, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret, WSAGetLastError());
874 addr.sin_port = htons(SERVER_LISTEN_PORT);
876 ret = connect(s_connect, (struct sockaddr *)&addr, sizeof(addr));
877 while (ret && ((err = WSAGetLastError()) == WSAECONNREFUSED || err == WSAECONNABORTED))
879 SwitchToThread();
880 ret = connect(s_connect, (struct sockaddr *)&addr, sizeof(addr));
882 ok(!ret, "Error connecting, WSAGetLastError() %u.\n", WSAGetLastError());
884 ret = send(s_connect, test_send_string, sizeof(test_send_string), 0);
885 ok(ret == sizeof(test_send_string), "Got unexpected ret %d.\n", ret);
887 ret = recv(s_connect, buffer, sizeof(buffer), 0);
888 ok(ret == sizeof(buffer), "Got unexpected ret %d.\n", ret);
889 ok(!strcmp(buffer, "Server test string 1."), "Received unexpected data.\n");
891 s_accept = accept(s_listen, NULL, NULL);
892 ok(s_accept != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
894 closesocket(s_accept);
895 closesocket(s_connect);
896 closesocket(s_listen);
897 return TRUE;
900 static void test_driver_netio(struct testsign_context *ctx)
902 WCHAR filename[MAX_PATH];
903 SC_HANDLE service;
904 HANDLE hthread;
905 BOOL ret;
907 if (!(service = load_driver(ctx, filename, L"driver_netio.dll", L"winetest_netio")))
908 return;
910 if (!start_driver(service, TRUE))
912 DeleteFileW(filename);
913 return;
916 device = CreateFileA("\\\\.\\winetest_netio", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
917 ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
919 hthread = CreateThread(NULL, 0, wsk_test_thread, NULL, 0, NULL);
920 main_test();
921 WaitForSingleObject(hthread, INFINITE);
923 CloseHandle(device);
925 unload_driver(service);
926 ret = DeleteFileW(filename);
927 ok(ret, "DeleteFile failed: %u\n", GetLastError());
930 static void add_file_to_catalog(HANDLE catalog, const WCHAR *file)
932 SIP_SUBJECTINFO subject_info = {sizeof(SIP_SUBJECTINFO)};
933 SIP_INDIRECT_DATA *indirect_data;
934 const WCHAR *filepart = file;
935 CRYPTCATMEMBER *member;
936 WCHAR hash_buffer[100];
937 GUID subject_guid;
938 unsigned int i;
939 DWORD size;
940 BOOL ret;
942 ret = CryptSIPRetrieveSubjectGuidForCatalogFile(file, NULL, &subject_guid);
943 todo_wine ok(ret, "Failed to get subject guid, error %u\n", GetLastError());
945 size = 0;
946 subject_info.pgSubjectType = &subject_guid;
947 subject_info.pwsFileName = file;
948 subject_info.DigestAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1;
949 subject_info.dwFlags = SPC_INC_PE_RESOURCES_FLAG | SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG | SPC_EXC_PE_PAGE_HASHES_FLAG | 0x10000;
950 ret = CryptSIPCreateIndirectData(&subject_info, &size, NULL);
951 todo_wine ok(ret, "Failed to get indirect data size, error %u\n", GetLastError());
953 indirect_data = malloc(size);
954 ret = CryptSIPCreateIndirectData(&subject_info, &size, indirect_data);
955 todo_wine ok(ret, "Failed to get indirect data, error %u\n", GetLastError());
956 if (ret)
958 memset(hash_buffer, 0, sizeof(hash_buffer));
959 for (i = 0; i < indirect_data->Digest.cbData; ++i)
960 swprintf(&hash_buffer[i * 2], 2, L"%02X", indirect_data->Digest.pbData[i]);
962 member = CryptCATPutMemberInfo(catalog, (WCHAR *)file,
963 hash_buffer, &subject_guid, 0, size, (BYTE *)indirect_data);
964 ok(!!member, "Failed to write member, error %u\n", GetLastError());
966 if (wcsrchr(file, '\\'))
967 filepart = wcsrchr(file, '\\') + 1;
969 ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"File",
970 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
971 (wcslen(filepart) + 1) * 2, (BYTE *)filepart);
972 ok(ret, "Failed to write attr, error %u\n", GetLastError());
974 ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"OSAttr",
975 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
976 sizeof(L"2:6.0"), (BYTE *)L"2:6.0");
977 ok(ret, "Failed to write attr, error %u\n", GetLastError());
981 static void test_pnp_devices(void)
983 static const GUID control_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc0}};
985 char buffer[200];
986 SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer;
987 SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
988 SP_DEVINFO_DATA device = {sizeof(device)};
989 HDEVINFO set;
990 HANDLE bus;
991 BOOL ret;
993 set = SetupDiGetClassDevsA(&control_class, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
994 ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError());
996 ret = SetupDiEnumDeviceInfo(set, 0, &device);
997 ok(ret, "failed to get device, error %#x\n", GetLastError());
998 ok(IsEqualGUID(&device.ClassGuid, &GUID_DEVCLASS_SYSTEM), "wrong class %s\n", debugstr_guid(&device.ClassGuid));
1000 ret = SetupDiGetDeviceInstanceIdA(set, &device, buffer, sizeof(buffer), NULL);
1001 ok(ret, "failed to get device ID, error %#x\n", GetLastError());
1002 ok(!strcasecmp(buffer, "root\\winetest\\0"), "got ID %s\n", debugstr_a(buffer));
1004 ret = SetupDiEnumDeviceInterfaces(set, NULL, &control_class, 0, &iface);
1005 ok(ret, "failed to get interface, error %#x\n", GetLastError());
1006 ok(IsEqualGUID(&iface.InterfaceClassGuid, &control_class),
1007 "wrong class %s\n", debugstr_guid(&iface.InterfaceClassGuid));
1008 ok(iface.Flags == SPINT_ACTIVE, "got flags %#x\n", iface.Flags);
1010 iface_detail->cbSize = sizeof(*iface_detail);
1011 ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, iface_detail, sizeof(buffer), NULL, NULL);
1012 ok(ret, "failed to get interface path, error %#x\n", GetLastError());
1013 ok(!strcasecmp(iface_detail->DevicePath, "\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}"),
1014 "wrong path %s\n", debugstr_a(iface_detail->DevicePath));
1016 SetupDiDestroyDeviceInfoList(set);
1018 bus = CreateFileA(iface_detail->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1019 ok(bus != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
1021 CloseHandle(bus);
1024 static void test_pnp_driver(struct testsign_context *ctx)
1026 static const char hardware_id[] = "test_hardware_id\0";
1027 char path[MAX_PATH], dest[MAX_PATH], *filepart;
1028 SP_DEVINFO_DATA device = {sizeof(device)};
1029 char cwd[MAX_PATH], tempdir[MAX_PATH];
1030 WCHAR driver_filename[MAX_PATH];
1031 SC_HANDLE manager, service;
1032 BOOL ret, need_reboot;
1033 HANDLE catalog, file;
1034 HDEVINFO set;
1035 FILE *f;
1037 #ifdef __i386__
1038 #define EXT "x86"
1039 #elif defined(__x86_64__)
1040 #define EXT "amd64"
1041 #elif defined(__arm__)
1042 #define EXT "arm"
1043 #elif defined(__aarch64__)
1044 #define EXT "arm64"
1045 #else
1046 #define EXT
1047 #endif
1049 static const char inf_text[] =
1050 "[Version]\n"
1051 "Signature=$Chicago$\n"
1052 "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n"
1053 "CatalogFile=winetest.cat\n"
1054 "DriverVer=09/21/2006,6.0.5736.1\n"
1056 "[Manufacturer]\n"
1057 "Wine=mfg_section,NT" EXT "\n"
1059 "[mfg_section.NT" EXT "]\n"
1060 "Wine test root driver=device_section,test_hardware_id\n"
1062 "[device_section.NT" EXT "]\n"
1063 "CopyFiles=file_section\n"
1065 "[device_section.NT" EXT ".Services]\n"
1066 "AddService=winetest,0x2,svc_section\n"
1068 "[file_section]\n"
1069 "winetest.sys\n"
1071 "[SourceDisksFiles]\n"
1072 "winetest.sys=1\n"
1074 "[SourceDisksNames]\n"
1075 "1=,winetest.sys\n"
1077 "[DestinationDirs]\n"
1078 "DefaultDestDir=12\n"
1080 "[svc_section]\n"
1081 "ServiceBinary=%12%\\winetest.sys\n"
1082 "ServiceType=1\n"
1083 "StartType=3\n"
1084 "ErrorControl=1\n"
1085 "LoadOrderGroup=Extended Base\n"
1086 "DisplayName=\"winetest bus driver\"\n"
1087 "; they don't sleep anymore, on the beach\n";
1089 GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd);
1090 GetTempPathA(ARRAY_SIZE(tempdir), tempdir);
1091 SetCurrentDirectoryA(tempdir);
1093 load_resource(L"driver_pnp.dll", driver_filename);
1094 ret = MoveFileExW(driver_filename, L"winetest.sys", MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
1095 ok(ret, "failed to move file, error %u\n", GetLastError());
1097 f = fopen("winetest.inf", "w");
1098 ok(!!f, "failed to open winetest.inf: %s\n", strerror(errno));
1099 fputs(inf_text, f);
1100 fclose(f);
1102 /* Create the catalog file. */
1104 catalog = CryptCATOpen((WCHAR *)L"winetest.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0);
1105 ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#x\n", GetLastError());
1107 ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"HWID1",
1108 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
1109 sizeof(L"test_hardware_id"), (BYTE *)L"test_hardware_id");
1110 todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError());
1112 ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"OS",
1113 CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED,
1114 sizeof(L"VistaX64"), (BYTE *)L"VistaX64");
1115 todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError());
1117 add_file_to_catalog(catalog, L"winetest.sys");
1118 add_file_to_catalog(catalog, L"winetest.inf");
1120 ret = CryptCATPersistStore(catalog);
1121 todo_wine ok(ret, "Failed to write catalog, error %u\n", GetLastError());
1123 ret = CryptCATClose(catalog);
1124 ok(ret, "Failed to close catalog, error %u\n", GetLastError());
1126 testsign_sign(ctx, L"winetest.cat");
1128 /* Install the driver. */
1130 set = SetupDiCreateDeviceInfoList(NULL, NULL);
1131 ok(set != INVALID_HANDLE_VALUE, "failed to create device list, error %#x\n", GetLastError());
1133 ret = SetupDiCreateDeviceInfoA(set, "root\\winetest\\0", &GUID_NULL, NULL, NULL, 0, &device);
1134 ok(ret, "failed to create device, error %#x\n", GetLastError());
1136 ret = SetupDiSetDeviceRegistryPropertyA( set, &device, SPDRP_HARDWAREID,
1137 (const BYTE *)hardware_id, sizeof(hardware_id) );
1138 ok(ret, "failed to create set hardware ID, error %#x\n", GetLastError());
1140 ret = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device);
1141 ok(ret, "failed to register device, error %#x\n", GetLastError());
1143 GetFullPathNameA("winetest.inf", sizeof(path), path, NULL);
1144 ret = UpdateDriverForPlugAndPlayDevicesA(NULL, hardware_id, path, INSTALLFLAG_FORCE, &need_reboot);
1145 ok(ret, "failed to install device, error %#x\n", GetLastError());
1146 ok(!need_reboot, "expected no reboot necessary\n");
1148 /* Tests. */
1150 test_pnp_devices();
1152 /* Clean up. */
1154 ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device);
1155 ok(ret, "failed to remove device, error %#x\n", GetLastError());
1157 file = CreateFileA("\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1158 ok(file == INVALID_HANDLE_VALUE, "expected failure\n");
1159 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %u\n", GetLastError());
1161 ret = SetupDiDestroyDeviceInfoList(set);
1162 ok(ret, "failed to destroy set, error %#x\n", GetLastError());
1164 /* Windows stops the service but does not delete it. */
1165 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1166 ok(!!manager, "failed to open service manager, error %u\n", GetLastError());
1167 service = OpenServiceA(manager, "winetest", SERVICE_STOP | DELETE);
1168 ok(!!service, "failed to open service, error %u\n", GetLastError());
1169 unload_driver(service);
1170 CloseServiceHandle(manager);
1172 GetFullPathNameA("winetest.inf", sizeof(path), path, NULL);
1173 ret = SetupCopyOEMInfA(path, NULL, 0, 0, dest, sizeof(dest), NULL, &filepart);
1174 ok(ret, "Failed to copy INF, error %#x\n", GetLastError());
1175 ret = SetupUninstallOEMInfA(filepart, 0, NULL);
1176 ok(ret, "Failed to uninstall INF, error %u\n", GetLastError());
1178 ret = DeleteFileA("winetest.cat");
1179 ok(ret, "Failed to delete file, error %u\n", GetLastError());
1180 ret = DeleteFileA("winetest.inf");
1181 ok(ret, "Failed to delete file, error %u\n", GetLastError());
1182 ret = DeleteFileA("winetest.sys");
1183 ok(ret, "Failed to delete file, error %u\n", GetLastError());
1184 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
1185 ret = DeleteFileA("C:/windows/system32/drivers/winetest.sys");
1186 ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND, "Failed to delete file, error %u\n", GetLastError());
1188 SetCurrentDirectoryA(cwd);
1191 START_TEST(ntoskrnl)
1193 WCHAR filename[MAX_PATH], filename2[MAX_PATH];
1194 struct testsign_context ctx;
1195 SC_HANDLE service, service2;
1196 struct test_data *data;
1197 BOOL ret, is_wow64;
1198 HANDLE mapping;
1199 DWORD written;
1201 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U");
1202 pRtlFreeUnicodeString = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString");
1203 pCancelIoEx = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx");
1204 pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
1205 pSetFileCompletionNotificationModes = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"),
1206 "SetFileCompletionNotificationModes");
1207 pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
1209 if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)
1211 skip("Running in WoW64.\n");
1212 return;
1215 if (!testsign_create_cert(&ctx))
1216 return;
1218 mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
1219 0, sizeof(*data), "Global\\winetest_ntoskrnl_section");
1220 ok(!!mapping, "got error %u\n", GetLastError());
1221 data = MapViewOfFile(mapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024);
1222 data->running_under_wine = !strcmp(winetest_platform, "wine");
1223 data->winetest_report_success = winetest_report_success;
1224 data->winetest_debug = winetest_debug;
1226 subtest("driver");
1227 if (!(service = load_driver(&ctx, filename, L"driver.dll", L"WineTestDriver")))
1228 goto out;
1230 if (!start_driver(service, FALSE))
1232 DeleteFileW(filename);
1233 goto out;
1235 service2 = load_driver(&ctx, filename2, L"driver2.dll", L"WineTestDriver2");
1237 device = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1238 ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
1240 test_basic_ioctl();
1241 test_mismatched_status_ioctl();
1243 main_test();
1244 todo_wine ok(modified_value == 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value);
1246 test_overlapped();
1247 test_load_driver(service2);
1248 test_file_handles();
1249 test_return_status();
1250 test_object_info();
1252 /* We need a separate ioctl to call IoDetachDevice(); calling it in the
1253 * driver unload routine causes a live-lock. */
1254 ret = DeviceIoControl(device, IOCTL_WINETEST_DETACH, NULL, 0, NULL, 0, &written, NULL);
1255 ok(ret, "DeviceIoControl failed: %u\n", GetLastError());
1257 CloseHandle(device);
1259 unload_driver(service2);
1260 unload_driver(service);
1261 ret = DeleteFileW(filename);
1262 ok(ret, "DeleteFile failed: %u\n", GetLastError());
1263 ret = DeleteFileW(filename2);
1264 ok(ret, "DeleteFile failed: %u\n", GetLastError());
1266 test_driver3(&ctx);
1267 subtest("driver_netio");
1268 test_driver_netio(&ctx);
1270 test_pnp_driver(&ctx);
1272 out:
1273 testsign_cleanup(&ctx);
1274 UnmapViewOfFile(data);
1275 CloseHandle(mapping);