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
26 #define WIN32_NO_STATUS
40 #include "wine/test.h"
41 #include "wine/heap.h"
42 #include "wine/mssign.h"
46 static const GUID GUID_NULL
;
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
];
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" );
81 struct testsign_context
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
;
104 memset(ctx
, 0, sizeof(*ctx
));
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());
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());
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());
222 static void testsign_cleanup(struct testsign_context
*ctx
)
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
)};
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
)
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");
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
);
325 static BOOL
start_driver(HANDLE service
, BOOL vista_plus
)
327 SERVICE_STATUS status
;
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");
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
);
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
)
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
);
367 static ULONG64 modified_value
;
369 static void main_test(void)
371 struct main_test_input
*test_input
;
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
;
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. */
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
);
404 DeleteFileA("C:\\windows\\winetest_ntoskrnl_okfile");
407 static void test_basic_ioctl(void)
409 char inbuf
[64], buf
[32];
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)
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
;
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
);
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 */
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());
526 CloseHandle(overlapped
.hEvent
);
527 CloseHandle(overlapped2
.hEvent
);
531 static void test_load_driver(SC_HANDLE service
)
533 SERVICE_STATUS status
;
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
);
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
);
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
;
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
);
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
);
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
);
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)
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");
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");
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");
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");
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)
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
;
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
)));
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
);
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
);
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
);
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
);
820 static void test_driver3(struct testsign_context
*ctx
)
822 WCHAR filename
[MAX_PATH
];
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
;
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());
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
))
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
);
900 static void test_driver_netio(struct testsign_context
*ctx
)
902 WCHAR filename
[MAX_PATH
];
907 if (!(service
= load_driver(ctx
, filename
, L
"driver_netio.dll", L
"winetest_netio")))
910 if (!start_driver(service
, TRUE
))
912 DeleteFileW(filename
);
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
);
921 WaitForSingleObject(hthread
, INFINITE
);
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];
942 ret
= CryptSIPRetrieveSubjectGuidForCatalogFile(file
, NULL
, &subject_guid
);
943 todo_wine
ok(ret
, "Failed to get subject guid, error %u\n", GetLastError());
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());
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}};
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
)};
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());
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
;
1039 #elif defined(__x86_64__)
1041 #elif defined(__arm__)
1043 #elif defined(__aarch64__)
1049 static const char inf_text
[] =
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"
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"
1071 "[SourceDisksFiles]\n"
1074 "[SourceDisksNames]\n"
1077 "[DestinationDirs]\n"
1078 "DefaultDestDir=12\n"
1081 "ServiceBinary=%12%\\winetest.sys\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
));
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");
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
;
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");
1215 if (!testsign_create_cert(&ctx
))
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
;
1227 if (!(service
= load_driver(&ctx
, filename
, L
"driver.dll", L
"WineTestDriver")))
1230 if (!start_driver(service
, FALSE
))
1232 DeleteFileW(filename
);
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());
1241 test_mismatched_status_ioctl();
1244 todo_wine
ok(modified_value
== 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value
);
1247 test_load_driver(service2
);
1248 test_file_handles();
1249 test_return_status();
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());
1267 subtest("driver_netio");
1268 test_driver_netio(&ctx
);
1270 test_pnp_driver(&ctx
);
1273 testsign_cleanup(&ctx
);
1274 UnmapViewOfFile(data
);
1275 CloseHandle(mapping
);