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