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
42 #include "ddk/hidclass.h"
43 #include "ddk/hidsdi.h"
44 #include "ddk/hidpi.h"
45 #include "wine/test.h"
46 #include "wine/heap.h"
47 #include "wine/mssign.h"
51 static const GUID GUID_NULL
;
55 static struct test_data
*test_data
;
57 static BOOL (WINAPI
*pRtlDosPathNameToNtPathName_U
)(const WCHAR
*, UNICODE_STRING
*, WCHAR
**, CURDIR
*);
58 static BOOL (WINAPI
*pRtlFreeUnicodeString
)(UNICODE_STRING
*);
59 static BOOL (WINAPI
*pCancelIoEx
)(HANDLE
, OVERLAPPED
*);
60 static BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, BOOL
*);
61 static BOOL (WINAPI
*pSetFileCompletionNotificationModes
)(HANDLE
, UCHAR
);
62 static HRESULT (WINAPI
*pSignerSign
)(SIGNER_SUBJECT_INFO
*subject
, SIGNER_CERT
*cert
,
63 SIGNER_SIGNATURE_INFO
*signature
, SIGNER_PROVIDER_INFO
*provider
,
64 const WCHAR
*timestamp
, CRYPT_ATTRIBUTES
*attr
, void *sip_data
);
66 static void load_resource(const WCHAR
*name
, WCHAR
*filename
)
68 static WCHAR path
[MAX_PATH
];
74 GetTempPathW(ARRAY_SIZE(path
), path
);
75 GetTempFileNameW(path
, name
, 0, filename
);
77 file
= CreateFileW(filename
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
78 ok(file
!= INVALID_HANDLE_VALUE
, "failed to create %s, error %u\n", debugstr_w(filename
), GetLastError());
80 res
= FindResourceW(NULL
, name
, L
"TESTDLL");
81 ok( res
!= 0, "couldn't find resource\n" );
82 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
83 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
84 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
88 struct testsign_context
91 const CERT_CONTEXT
*cert
, *root_cert
, *publisher_cert
;
92 HCERTSTORE root_store
, publisher_store
;
95 static BOOL
testsign_create_cert(struct testsign_context
*ctx
)
97 BYTE encoded_name
[100], encoded_key_id
[200], public_key_info_buffer
[1000];
98 WCHAR container_name
[26];
99 BYTE hash_buffer
[16], cert_buffer
[1000], provider_nameA
[100], serial
[16];
100 CERT_PUBLIC_KEY_INFO
*public_key_info
= (CERT_PUBLIC_KEY_INFO
*)public_key_info_buffer
;
101 CRYPT_KEY_PROV_INFO provider_info
= {0};
102 CRYPT_ALGORITHM_IDENTIFIER algid
= {0};
103 CERT_AUTHORITY_KEY_ID_INFO key_info
;
104 CERT_INFO cert_info
= {0};
105 WCHAR provider_nameW
[100];
106 CERT_EXTENSION extension
;
111 memset(ctx
, 0, sizeof(*ctx
));
114 swprintf(container_name
, ARRAY_SIZE(container_name
), L
"wine_testsign%u", rand());
116 ret
= CryptAcquireContextW(&ctx
->provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
117 ok(ret
, "Failed to create container, error %#x\n", GetLastError());
119 ret
= CryptGenKey(ctx
->provider
, AT_SIGNATURE
, CRYPT_EXPORTABLE
, &key
);
120 ok(ret
, "Failed to create key, error %#x\n", GetLastError());
121 ret
= CryptDestroyKey(key
);
122 ok(ret
, "Failed to destroy key, error %#x\n", GetLastError());
123 ret
= CryptGetUserKey(ctx
->provider
, AT_SIGNATURE
, &key
);
124 ok(ret
, "Failed to get user key, error %#x\n", GetLastError());
125 ret
= CryptDestroyKey(key
);
126 ok(ret
, "Failed to destroy key, error %#x\n", GetLastError());
128 size
= sizeof(encoded_name
);
129 ret
= CertStrToNameA(X509_ASN_ENCODING
, "CN=winetest_cert", CERT_X500_NAME_STR
, NULL
, encoded_name
, &size
, NULL
);
130 ok(ret
, "Failed to convert name, error %#x\n", GetLastError());
131 key_info
.CertIssuer
.cbData
= size
;
132 key_info
.CertIssuer
.pbData
= encoded_name
;
134 size
= sizeof(public_key_info_buffer
);
135 ret
= CryptExportPublicKeyInfo(ctx
->provider
, AT_SIGNATURE
, X509_ASN_ENCODING
, public_key_info
, &size
);
136 ok(ret
, "Failed to export public key, error %#x\n", GetLastError());
137 cert_info
.SubjectPublicKeyInfo
= *public_key_info
;
139 size
= sizeof(hash_buffer
);
140 ret
= CryptHashPublicKeyInfo(ctx
->provider
, CALG_MD5
, 0, X509_ASN_ENCODING
, public_key_info
, hash_buffer
, &size
);
141 ok(ret
, "Failed to hash public key, error %#x\n", GetLastError());
143 key_info
.KeyId
.cbData
= size
;
144 key_info
.KeyId
.pbData
= hash_buffer
;
146 RtlGenRandom(serial
, sizeof(serial
));
147 key_info
.CertSerialNumber
.cbData
= sizeof(serial
);
148 key_info
.CertSerialNumber
.pbData
= serial
;
150 size
= sizeof(encoded_key_id
);
151 ret
= CryptEncodeObject(X509_ASN_ENCODING
, X509_AUTHORITY_KEY_ID
, &key_info
, encoded_key_id
, &size
);
152 ok(ret
, "Failed to convert name, error %#x\n", GetLastError());
154 extension
.pszObjId
= (char *)szOID_AUTHORITY_KEY_IDENTIFIER
;
155 extension
.fCritical
= TRUE
;
156 extension
.Value
.cbData
= size
;
157 extension
.Value
.pbData
= encoded_key_id
;
159 cert_info
.dwVersion
= CERT_V3
;
160 cert_info
.SerialNumber
= key_info
.CertSerialNumber
;
161 cert_info
.SignatureAlgorithm
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
162 cert_info
.Issuer
= key_info
.CertIssuer
;
163 GetSystemTimeAsFileTime(&cert_info
.NotBefore
);
164 GetSystemTimeAsFileTime(&cert_info
.NotAfter
);
165 cert_info
.NotAfter
.dwHighDateTime
+= 1;
166 cert_info
.Subject
= key_info
.CertIssuer
;
167 cert_info
.cExtension
= 1;
168 cert_info
.rgExtension
= &extension
;
169 algid
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
170 size
= sizeof(cert_buffer
);
171 ret
= CryptSignAndEncodeCertificate(ctx
->provider
, AT_SIGNATURE
, X509_ASN_ENCODING
,
172 X509_CERT_TO_BE_SIGNED
, &cert_info
, &algid
, NULL
, cert_buffer
, &size
);
173 ok(ret
, "Failed to create certificate, error %#x\n", GetLastError());
175 ctx
->cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, cert_buffer
, size
);
176 ok(!!ctx
->cert
, "Failed to create context, error %#x\n", GetLastError());
178 size
= sizeof(provider_nameA
);
179 ret
= CryptGetProvParam(ctx
->provider
, PP_NAME
, provider_nameA
, &size
, 0);
180 ok(ret
, "Failed to get prov param, error %#x\n", GetLastError());
181 MultiByteToWideChar(CP_ACP
, 0, (char *)provider_nameA
, -1, provider_nameW
, ARRAY_SIZE(provider_nameW
));
183 provider_info
.pwszContainerName
= (WCHAR
*)container_name
;
184 provider_info
.pwszProvName
= provider_nameW
;
185 provider_info
.dwProvType
= PROV_RSA_FULL
;
186 provider_info
.dwKeySpec
= AT_SIGNATURE
;
187 ret
= CertSetCertificateContextProperty(ctx
->cert
, CERT_KEY_PROV_INFO_PROP_ID
, 0, &provider_info
);
188 ok(ret
, "Failed to set provider info, error %#x\n", GetLastError());
190 ctx
->root_store
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A
, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
, "root");
191 if (!ctx
->root_store
&& GetLastError() == ERROR_ACCESS_DENIED
)
193 skip("Failed to open root store.\n");
195 ret
= CertFreeCertificateContext(ctx
->cert
);
196 ok(ret
, "Failed to free certificate, error %u\n", GetLastError());
197 ret
= CryptReleaseContext(ctx
->provider
, 0);
198 ok(ret
, "failed to release context, error %u\n", GetLastError());
202 ok(!!ctx
->root_store
, "Failed to open store, error %u\n", GetLastError());
203 ret
= CertAddCertificateContextToStore(ctx
->root_store
, ctx
->cert
, CERT_STORE_ADD_ALWAYS
, &ctx
->root_cert
);
204 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
206 skip("Failed to add self-signed certificate to store.\n");
208 ret
= CertFreeCertificateContext(ctx
->cert
);
209 ok(ret
, "Failed to free certificate, error %u\n", GetLastError());
210 ret
= CertCloseStore(ctx
->root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
211 ok(ret
, "Failed to close store, error %u\n", GetLastError());
212 ret
= CryptReleaseContext(ctx
->provider
, 0);
213 ok(ret
, "failed to release context, error %u\n", GetLastError());
217 ok(ret
, "Failed to add certificate, error %u\n", GetLastError());
219 ctx
->publisher_store
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A
, 0, 0,
220 CERT_SYSTEM_STORE_LOCAL_MACHINE
, "trustedpublisher");
221 ok(!!ctx
->publisher_store
, "Failed to open store, error %u\n", GetLastError());
222 ret
= CertAddCertificateContextToStore(ctx
->publisher_store
, ctx
->cert
,
223 CERT_STORE_ADD_ALWAYS
, &ctx
->publisher_cert
);
224 ok(ret
, "Failed to add certificate, error %u\n", GetLastError());
229 static void testsign_cleanup(struct testsign_context
*ctx
)
233 ret
= CertFreeCertificateContext(ctx
->cert
);
234 ok(ret
, "Failed to free certificate, error %u\n", GetLastError());
236 ret
= CertDeleteCertificateFromStore(ctx
->root_cert
);
237 ok(ret
, "Failed to remove certificate, error %u\n", GetLastError());
238 ret
= CertCloseStore(ctx
->root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
239 ok(ret
, "Failed to close store, error %u\n", GetLastError());
241 ret
= CertDeleteCertificateFromStore(ctx
->publisher_cert
);
242 ok(ret
, "Failed to remove certificate, error %u\n", GetLastError());
243 ret
= CertCloseStore(ctx
->publisher_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
244 ok(ret
, "Failed to close store, error %u\n", GetLastError());
246 ret
= CryptReleaseContext(ctx
->provider
, 0);
247 ok(ret
, "failed to release context, error %u\n", GetLastError());
250 static void testsign_sign(struct testsign_context
*ctx
, const WCHAR
*filename
)
252 SIGNER_ATTR_AUTHCODE authcode
= {sizeof(authcode
)};
253 SIGNER_SIGNATURE_INFO signature
= {sizeof(signature
)};
254 SIGNER_SUBJECT_INFO subject
= {sizeof(subject
)};
255 SIGNER_CERT_STORE_INFO store
= {sizeof(store
)};
256 SIGNER_CERT cert_info
= {sizeof(cert_info
)};
257 SIGNER_FILE_INFO file
= {sizeof(file
)};
261 subject
.dwSubjectChoice
= 1;
262 subject
.pdwIndex
= &index
;
263 subject
.pSignerFileInfo
= &file
;
264 file
.pwszFileName
= (WCHAR
*)filename
;
265 cert_info
.dwCertChoice
= 2;
266 cert_info
.pCertStoreInfo
= &store
;
267 store
.pSigningCert
= ctx
->cert
;
268 store
.dwCertPolicy
= 0;
269 signature
.algidHash
= CALG_SHA_256
;
270 signature
.dwAttrChoice
= SIGNER_AUTHCODE_ATTR
;
271 signature
.pAttrAuthcode
= &authcode
;
272 authcode
.pwszName
= L
"";
273 authcode
.pwszInfo
= L
"";
274 hr
= pSignerSign(&subject
, &cert_info
, &signature
, NULL
, NULL
, NULL
, NULL
);
275 todo_wine
ok(hr
== S_OK
|| broken(hr
== NTE_BAD_ALGID
) /* < 7 */, "Failed to sign, hr %#x\n", hr
);
278 static void unload_driver(SC_HANDLE service
)
280 SERVICE_STATUS status
;
282 ControlService(service
, SERVICE_CONTROL_STOP
, &status
);
283 while (status
.dwCurrentState
== SERVICE_STOP_PENDING
)
287 ret
= QueryServiceStatus(service
, &status
);
288 ok(ret
, "QueryServiceStatus failed: %u\n", GetLastError());
290 ok(status
.dwCurrentState
== SERVICE_STOPPED
,
291 "expected SERVICE_STOPPED, got %d\n", status
.dwCurrentState
);
293 DeleteService(service
);
294 CloseServiceHandle(service
);
297 static SC_HANDLE
load_driver(struct testsign_context
*ctx
, WCHAR
*filename
,
298 const WCHAR
*resname
, const WCHAR
*driver_name
)
300 SC_HANDLE manager
, service
;
302 manager
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_ALL_ACCESS
);
303 if (!manager
&& GetLastError() == ERROR_ACCESS_DENIED
)
305 skip("Failed to open SC manager, not enough permissions\n");
308 ok(!!manager
, "OpenSCManager failed\n");
310 /* stop any old drivers running under this name */
311 service
= OpenServiceW(manager
, driver_name
, SERVICE_ALL_ACCESS
);
312 if (service
) unload_driver(service
);
314 load_resource(resname
, filename
);
315 testsign_sign(ctx
, filename
);
316 trace("Trying to load driver %s\n", debugstr_w(filename
));
318 service
= CreateServiceW(manager
, driver_name
, driver_name
,
319 SERVICE_ALL_ACCESS
, SERVICE_KERNEL_DRIVER
,
320 SERVICE_DEMAND_START
, SERVICE_ERROR_NORMAL
,
321 filename
, NULL
, NULL
, NULL
, NULL
, NULL
);
322 ok(!!service
, "CreateService failed: %u\n", GetLastError());
324 CloseServiceHandle(manager
);
328 static BOOL
start_driver(HANDLE service
, BOOL vista_plus
)
330 SERVICE_STATUS status
;
333 SetLastError(0xdeadbeef);
334 ret
= StartServiceA(service
, 0, NULL
);
335 if (!ret
&& (GetLastError() == ERROR_DRIVER_BLOCKED
|| GetLastError() == ERROR_INVALID_IMAGE_HASH
336 || (vista_plus
&& GetLastError() == ERROR_FILE_NOT_FOUND
)))
338 if (vista_plus
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
340 skip("Windows Vista or newer is required to run this service.\n");
344 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
345 skip("Failed to start service; probably your machine doesn't accept unsigned drivers.\n");
347 DeleteService(service
);
348 CloseServiceHandle(service
);
351 ok(ret
, "StartService failed: %u\n", GetLastError());
353 /* wait for the service to start up properly */
354 ret
= QueryServiceStatus(service
, &status
);
355 ok(ret
, "QueryServiceStatus failed: %u\n", GetLastError());
356 while (status
.dwCurrentState
== SERVICE_START_PENDING
)
359 ret
= QueryServiceStatus(service
, &status
);
360 ok(ret
, "QueryServiceStatus failed: %u\n", GetLastError());
362 ok(status
.dwCurrentState
== SERVICE_RUNNING
,
363 "expected SERVICE_RUNNING, got %d\n", status
.dwCurrentState
);
364 ok(status
.dwServiceType
== SERVICE_KERNEL_DRIVER
,
365 "expected SERVICE_KERNEL_DRIVER, got %#x\n", status
.dwServiceType
);
370 static HANDLE okfile
;
372 static void cat_okfile(void)
377 SetFilePointer(okfile
, 0, NULL
, FILE_BEGIN
);
381 ReadFile(okfile
, buffer
, sizeof(buffer
), &size
, NULL
);
382 printf("%.*s", size
, buffer
);
383 } while (size
== sizeof(buffer
));
385 SetFilePointer(okfile
, 0, NULL
, FILE_BEGIN
);
386 SetEndOfFile(okfile
);
388 winetest_add_failures(InterlockedExchange(&test_data
->failures
, 0));
389 winetest_add_failures(InterlockedExchange(&test_data
->todo_failures
, 0));
392 static ULONG64 modified_value
;
394 static void main_test(void)
396 struct main_test_input
*test_input
;
400 test_input
= heap_alloc( sizeof(*test_input
) );
401 test_input
->process_id
= GetCurrentProcessId();
402 test_input
->teststr_offset
= (SIZE_T
)((BYTE
*)&teststr
- (BYTE
*)NtCurrentTeb()->Peb
->ImageBaseAddress
);
403 test_input
->modified_value
= &modified_value
;
406 res
= DeviceIoControl(device
, IOCTL_WINETEST_MAIN_TEST
, test_input
, sizeof(*test_input
), NULL
, 0, &size
, NULL
);
407 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
408 ok(!size
, "got size %u\n", size
);
410 heap_free(test_input
);
413 static void test_basic_ioctl(void)
415 char inbuf
[64], buf
[32];
419 res
= DeviceIoControl(device
, IOCTL_WINETEST_BASIC_IOCTL
, NULL
, 0, buf
,
420 sizeof(buf
), &written
, NULL
);
421 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
422 ok(written
== sizeof(teststr
), "got size %d\n", written
);
423 ok(!strcmp(buf
, teststr
), "got '%s'\n", buf
);
425 memset(buf
, 0, sizeof(buf
));
426 res
= DeviceIoControl(device
, IOCTL_WINETEST_BASIC_IOCTL
, inbuf
,
427 sizeof(inbuf
), buf
, 10, &written
, NULL
);
428 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
429 ok(written
== 10, "got size %d\n", written
);
430 ok(!strcmp(buf
, "Wine is no"), "got '%s'\n", buf
);
433 static void test_mismatched_status_ioctl(void)
439 res
= DeviceIoControl(device
, IOCTL_WINETEST_MISMATCHED_STATUS
, NULL
, 0, buf
,
440 sizeof(buf
), &written
, NULL
);
441 todo_wine
ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
442 todo_wine
ok(!strcmp(buf
, teststr
), "got '%s'\n", buf
);
445 static void test_overlapped(void)
447 OVERLAPPED overlapped
, overlapped2
, *o
;
448 DWORD cancel_cnt
, size
;
453 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
454 overlapped2
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
456 file
= CreateFileA("\\\\.\\WineTestDriver", FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
457 0, NULL
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
458 ok(file
!= INVALID_HANDLE_VALUE
, "failed to open device: %u\n", GetLastError());
460 /* test cancelling all device requests */
461 res
= DeviceIoControl(file
, IOCTL_WINETEST_RESET_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped
);
462 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
464 res
= DeviceIoControl(file
, IOCTL_WINETEST_TEST_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped
);
465 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "DeviceIoControl failed: %u\n", GetLastError());
467 res
= DeviceIoControl(file
, IOCTL_WINETEST_TEST_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped2
);
468 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "DeviceIoControl failed: %u\n", GetLastError());
470 cancel_cnt
= 0xdeadbeef;
471 res
= DeviceIoControl(file
, IOCTL_WINETEST_GET_CANCEL_COUNT
, NULL
, 0, &cancel_cnt
, sizeof(cancel_cnt
), NULL
, &overlapped
);
472 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
473 ok(cancel_cnt
== 0, "cancel_cnt = %u\n", cancel_cnt
);
477 cancel_cnt
= 0xdeadbeef;
478 res
= DeviceIoControl(file
, IOCTL_WINETEST_GET_CANCEL_COUNT
, NULL
, 0, &cancel_cnt
, sizeof(cancel_cnt
), NULL
, &overlapped
);
479 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
480 ok(cancel_cnt
== 2, "cancel_cnt = %u\n", cancel_cnt
);
482 /* test cancelling selected overlapped event */
485 res
= DeviceIoControl(file
, IOCTL_WINETEST_RESET_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped
);
486 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
488 res
= DeviceIoControl(file
, IOCTL_WINETEST_TEST_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped
);
489 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "DeviceIoControl failed: %u\n", GetLastError());
491 res
= DeviceIoControl(file
, IOCTL_WINETEST_TEST_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped2
);
492 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "DeviceIoControl failed: %u\n", GetLastError());
494 pCancelIoEx(file
, &overlapped
);
496 cancel_cnt
= 0xdeadbeef;
497 res
= DeviceIoControl(file
, IOCTL_WINETEST_GET_CANCEL_COUNT
, NULL
, 0, &cancel_cnt
, sizeof(cancel_cnt
), NULL
, &overlapped
);
498 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
499 ok(cancel_cnt
== 1, "cancel_cnt = %u\n", cancel_cnt
);
501 pCancelIoEx(file
, &overlapped2
);
503 cancel_cnt
= 0xdeadbeef;
504 res
= DeviceIoControl(file
, IOCTL_WINETEST_GET_CANCEL_COUNT
, NULL
, 0, &cancel_cnt
, sizeof(cancel_cnt
), NULL
, &overlapped
);
505 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
506 ok(cancel_cnt
== 2, "cancel_cnt = %u\n", cancel_cnt
);
509 port
= CreateIoCompletionPort(file
, NULL
, 0xdeadbeef, 0);
510 ok(port
!= NULL
, "CreateIoCompletionPort failed, error %u\n", GetLastError());
511 res
= GetQueuedCompletionStatus(port
, &size
, &key
, &o
, 0);
512 ok(!res
&& GetLastError() == WAIT_TIMEOUT
, "GetQueuedCompletionStatus returned %x(%u)\n", res
, GetLastError());
514 res
= DeviceIoControl(file
, IOCTL_WINETEST_RESET_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped
);
515 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
516 res
= GetQueuedCompletionStatus(port
, &size
, &key
, &o
, 0);
517 ok(res
, "GetQueuedCompletionStatus failed: %u\n", GetLastError());
518 ok(o
== &overlapped
, "o != overlapped\n");
520 if (pSetFileCompletionNotificationModes
)
522 res
= pSetFileCompletionNotificationModes(file
, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
);
523 ok(res
, "SetFileCompletionNotificationModes failed: %u\n", GetLastError());
525 res
= DeviceIoControl(file
, IOCTL_WINETEST_RESET_CANCEL
, NULL
, 0, NULL
, 0, NULL
, &overlapped
);
526 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
527 res
= GetQueuedCompletionStatus(port
, &size
, &key
, &o
, 0);
528 ok(!res
&& GetLastError() == WAIT_TIMEOUT
, "GetQueuedCompletionStatus returned %x(%u)\n", res
, GetLastError());
532 CloseHandle(overlapped
.hEvent
);
533 CloseHandle(overlapped2
.hEvent
);
537 static void test_load_driver(SC_HANDLE service
)
539 SERVICE_STATUS status
;
543 res
= QueryServiceStatus(service
, &status
);
544 ok(res
, "QueryServiceStatusEx failed: %u\n", GetLastError());
545 ok(status
.dwCurrentState
== SERVICE_STOPPED
, "got state %#x\n", status
.dwCurrentState
);
548 res
= DeviceIoControl(device
, IOCTL_WINETEST_LOAD_DRIVER
, &load
, sizeof(load
), NULL
, 0, &sz
, NULL
);
549 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
551 res
= QueryServiceStatus(service
, &status
);
552 ok(res
, "QueryServiceStatusEx failed: %u\n", GetLastError());
553 ok(status
.dwCurrentState
== SERVICE_RUNNING
, "got state %#x\n", status
.dwCurrentState
);
556 res
= DeviceIoControl(device
, IOCTL_WINETEST_LOAD_DRIVER
, &load
, sizeof(load
), NULL
, 0, &sz
, NULL
);
557 ok(res
, "DeviceIoControl failed: %u\n", GetLastError());
559 res
= QueryServiceStatus(service
, &status
);
560 ok(res
, "QueryServiceStatusEx failed: %u\n", GetLastError());
561 ok(status
.dwCurrentState
== SERVICE_STOPPED
, "got state %#x\n", status
.dwCurrentState
);
564 static void test_file_handles(void)
566 DWORD count
, ret_size
;
567 HANDLE file
, dup
, file2
;
570 ret
= DeviceIoControl(device
, IOCTL_WINETEST_GET_CREATE_COUNT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
571 ok(ret
, "ioctl failed: %u\n", GetLastError());
572 ok(count
== 2, "got %u\n", count
);
574 ret
= DeviceIoControl(device
, IOCTL_WINETEST_GET_CLOSE_COUNT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
575 ok(ret
, "ioctl failed: %u\n", GetLastError());
576 ok(count
== 1, "got %u\n", count
);
578 file
= CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
579 ok(file
!= INVALID_HANDLE_VALUE
, "failed to open device: %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
== 3, "got %u\n", count
);
585 file2
= CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
586 ok(file2
!= INVALID_HANDLE_VALUE
, "failed to open device: %u\n", GetLastError());
588 ret
= DeviceIoControl(device
, IOCTL_WINETEST_GET_CREATE_COUNT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
589 ok(ret
, "ioctl failed: %u\n", GetLastError());
590 ok(count
== 4, "got %u\n", count
);
592 ret
= DuplicateHandle(GetCurrentProcess(), file
, GetCurrentProcess(), &dup
, 0, FALSE
, DUPLICATE_SAME_ACCESS
);
593 ok(ret
, "failed to duplicate handle: %u\n", GetLastError());
595 ret
= DeviceIoControl(device
, IOCTL_WINETEST_GET_CREATE_COUNT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
596 ok(ret
, "ioctl failed: %u\n", GetLastError());
597 ok(count
== 4, "got %u\n", count
);
599 ret
= DeviceIoControl(device
, IOCTL_WINETEST_GET_FSCONTEXT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
600 ok(ret
, "ioctl failed: %u\n", GetLastError());
601 ok(count
== 1, "got %u\n", count
);
603 ret
= DeviceIoControl(file
, IOCTL_WINETEST_GET_FSCONTEXT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
604 ok(ret
, "ioctl failed: %u\n", GetLastError());
605 ok(count
== 3, "got %u\n", count
);
607 ret
= DeviceIoControl(file2
, IOCTL_WINETEST_GET_FSCONTEXT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
608 ok(ret
, "ioctl failed: %u\n", GetLastError());
609 ok(count
== 4, "got %u\n", count
);
611 ret
= DeviceIoControl(dup
, IOCTL_WINETEST_GET_FSCONTEXT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
612 ok(ret
, "ioctl failed: %u\n", GetLastError());
613 ok(count
== 3, "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
== 1, "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
== 2, "got %u\n", count
);
629 ret
= DeviceIoControl(device
, IOCTL_WINETEST_GET_CLOSE_COUNT
, NULL
, 0, &count
, sizeof(count
), &ret_size
, NULL
);
630 ok(ret
, "ioctl failed: %u\n", GetLastError());
631 ok(count
== 3, "got %u\n", count
);
634 static void test_return_status(void)
641 strcpy(buffer
, "abcdef");
642 status
= STATUS_SUCCESS
;
643 SetLastError(0xdeadbeef);
644 ret
= DeviceIoControl(device
, IOCTL_WINETEST_RETURN_STATUS
, &status
,
645 sizeof(status
), buffer
, sizeof(buffer
), &ret_size
, NULL
);
646 ok(ret
, "ioctl failed\n");
647 ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
648 ok(!strcmp(buffer
, "ghidef"), "got buffer %s\n", buffer
);
649 ok(ret_size
== 3, "got size %u\n", ret_size
);
651 strcpy(buffer
, "abcdef");
652 status
= STATUS_TIMEOUT
;
653 SetLastError(0xdeadbeef);
654 ret
= DeviceIoControl(device
, IOCTL_WINETEST_RETURN_STATUS
, &status
,
655 sizeof(status
), buffer
, sizeof(buffer
), &ret_size
, NULL
);
656 todo_wine
ok(ret
, "ioctl failed\n");
657 todo_wine
ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
658 ok(!strcmp(buffer
, "ghidef"), "got buffer %s\n", buffer
);
659 ok(ret_size
== 3, "got size %u\n", ret_size
);
661 strcpy(buffer
, "abcdef");
663 SetLastError(0xdeadbeef);
664 ret
= DeviceIoControl(device
, IOCTL_WINETEST_RETURN_STATUS
, &status
,
665 sizeof(status
), buffer
, sizeof(buffer
), &ret_size
, NULL
);
666 todo_wine
ok(ret
, "ioctl failed\n");
667 todo_wine
ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
668 ok(!strcmp(buffer
, "ghidef"), "got buffer %s\n", buffer
);
669 ok(ret_size
== 3, "got size %u\n", ret_size
);
671 strcpy(buffer
, "abcdef");
673 SetLastError(0xdeadbeef);
674 ret
= DeviceIoControl(device
, IOCTL_WINETEST_RETURN_STATUS
, &status
,
675 sizeof(status
), buffer
, sizeof(buffer
), &ret_size
, NULL
);
676 todo_wine
ok(ret
, "ioctl failed\n");
677 todo_wine
ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError());
678 ok(!strcmp(buffer
, "ghidef"), "got buffer %s\n", buffer
);
679 ok(ret_size
== 3, "got size %u\n", ret_size
);
681 strcpy(buffer
, "abcdef");
683 SetLastError(0xdeadbeef);
684 ret
= DeviceIoControl(device
, IOCTL_WINETEST_RETURN_STATUS
, &status
,
685 sizeof(status
), buffer
, sizeof(buffer
), &ret_size
, NULL
);
686 ok(!ret
, "ioctl succeeded\n");
687 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND
, "got error %u\n", GetLastError());
688 ok(!strcmp(buffer
, "ghidef"), "got buffer %s\n", buffer
);
689 ok(ret_size
== 3, "got size %u\n", ret_size
);
691 strcpy(buffer
, "abcdef");
693 SetLastError(0xdeadbeef);
694 ret
= DeviceIoControl(device
, IOCTL_WINETEST_RETURN_STATUS
, &status
,
695 sizeof(status
), buffer
, sizeof(buffer
), &ret_size
, NULL
);
696 ok(!ret
, "ioctl succeeded\n");
697 ok(GetLastError() == ERROR_MR_MID_NOT_FOUND
, "got error %u\n", GetLastError());
698 ok(!strcmp(buffer
, "abcdef"), "got buffer %s\n", buffer
);
699 ok(ret_size
== 3, "got size %u\n", ret_size
);
702 static BOOL
compare_unicode_string(const WCHAR
*buffer
, ULONG len
, const WCHAR
*expect
)
704 return len
== wcslen(expect
) * sizeof(WCHAR
) && !memcmp(buffer
, expect
, len
);
707 static void test_object_info(void)
710 OBJECT_NAME_INFORMATION
*name_info
= (OBJECT_NAME_INFORMATION
*)buffer
;
711 OBJECT_TYPE_INFORMATION
*type_info
= (OBJECT_TYPE_INFORMATION
*)buffer
;
712 FILE_FS_VOLUME_INFORMATION
*volume_info
= (FILE_FS_VOLUME_INFORMATION
*)buffer
;
713 FILE_NAME_INFORMATION
*file_info
= (FILE_NAME_INFORMATION
*)buffer
;
719 status
= NtQueryObject(device
, ObjectNameInformation
, buffer
, sizeof(buffer
), NULL
);
720 ok(!status
, "got %#x\n", status
);
721 ok(compare_unicode_string(name_info
->Name
.Buffer
, name_info
->Name
.Length
, L
"\\Device\\WineTestDriver"),
722 "wrong name %s\n", debugstr_w(name_info
->Name
.Buffer
));
724 status
= NtQueryObject(device
, ObjectTypeInformation
, buffer
, sizeof(buffer
), NULL
);
725 ok(!status
, "got %#x\n", status
);
726 ok(compare_unicode_string(type_info
->TypeName
.Buffer
, type_info
->TypeName
.Length
, L
"File"),
727 "wrong name %s\n", debugstr_wn(type_info
->TypeName
.Buffer
, type_info
->TypeName
.Length
/ sizeof(WCHAR
)));
729 status
= NtQueryInformationFile(device
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
730 todo_wine
ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "got %#x\n", status
);
732 status
= NtQueryVolumeInformationFile(device
, &io
, buffer
, sizeof(buffer
), FileFsVolumeInformation
);
733 todo_wine
ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "got %#x\n", status
);
735 file
= CreateFileA("\\\\.\\WineTestDriver\\subfile", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
736 todo_wine
ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
737 if (file
== INVALID_HANDLE_VALUE
) return;
739 memset(buffer
, 0xcc, sizeof(buffer
));
740 status
= NtQueryObject(file
, ObjectNameInformation
, buffer
, sizeof(buffer
), &size
);
741 ok(!status
, "got %#x\n", status
);
742 ok(size
== sizeof(*name_info
) + sizeof(L
"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size
);
743 ok(compare_unicode_string(name_info
->Name
.Buffer
, name_info
->Name
.Length
, L
"\\Device\\WineTestDriver\\subfile"),
744 "wrong name %s\n", debugstr_w(name_info
->Name
.Buffer
));
746 memset(buffer
, 0xcc, sizeof(buffer
));
747 status
= NtQueryObject(file
, ObjectNameInformation
, buffer
, size
- 2, &size
);
748 ok(status
== STATUS_BUFFER_OVERFLOW
, "got %#x\n", status
);
749 ok(size
== sizeof(*name_info
) + sizeof(L
"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size
);
750 ok(compare_unicode_string(name_info
->Name
.Buffer
, name_info
->Name
.Length
, L
"\\Device\\WineTestDriver\\subfil"),
751 "wrong name %s\n", debugstr_w(name_info
->Name
.Buffer
));
753 memset(buffer
, 0xcc, sizeof(buffer
));
754 status
= NtQueryObject(file
, ObjectNameInformation
, buffer
, sizeof(*name_info
), &size
);
755 ok(status
== STATUS_BUFFER_OVERFLOW
, "got %#x\n", status
);
756 ok(size
== sizeof(*name_info
) + sizeof(L
"\\Device\\WineTestDriver\\subfile"), "wrong size %u\n", size
);
758 status
= NtQueryObject(file
, ObjectTypeInformation
, buffer
, sizeof(buffer
), NULL
);
759 ok(!status
, "got %#x\n", status
);
760 ok(compare_unicode_string(type_info
->TypeName
.Buffer
, type_info
->TypeName
.Length
, L
"File"),
761 "wrong name %s\n", debugstr_wn(type_info
->TypeName
.Buffer
, type_info
->TypeName
.Length
/ sizeof(WCHAR
)));
763 status
= NtQueryInformationFile(file
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
764 ok(!status
, "got %#x\n", status
);
765 ok(compare_unicode_string(file_info
->FileName
, file_info
->FileNameLength
, L
"\\subfile"),
766 "wrong name %s\n", debugstr_wn(file_info
->FileName
, file_info
->FileNameLength
/ sizeof(WCHAR
)));
768 status
= NtQueryVolumeInformationFile(file
, &io
, buffer
, sizeof(buffer
), FileFsVolumeInformation
);
769 ok(!status
, "got %#x\n", status
);
770 ok(volume_info
->VolumeSerialNumber
== 0xdeadbeef,
771 "wrong serial number 0x%08x\n", volume_info
->VolumeSerialNumber
);
772 ok(compare_unicode_string(volume_info
->VolumeLabel
, volume_info
->VolumeLabelLength
, L
"WineTestDriver"),
773 "wrong name %s\n", debugstr_wn(volume_info
->VolumeLabel
, volume_info
->VolumeLabelLength
/ sizeof(WCHAR
)));
777 file
= CreateFileA("\\\\.\\WineTestDriver\\notimpl", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
778 ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
780 status
= NtQueryObject(file
, ObjectNameInformation
, buffer
, sizeof(buffer
), NULL
);
781 ok(!status
, "got %#x\n", status
);
782 ok(compare_unicode_string(name_info
->Name
.Buffer
, name_info
->Name
.Length
, L
"\\Device\\WineTestDriver"),
783 "wrong name %s\n", debugstr_w(name_info
->Name
.Buffer
));
785 status
= NtQueryInformationFile(file
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
786 ok(status
== STATUS_NOT_IMPLEMENTED
, "got %#x\n", status
);
790 file
= CreateFileA("\\\\.\\WineTestDriver\\badparam", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
791 ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
793 status
= NtQueryObject(file
, ObjectNameInformation
, buffer
, sizeof(buffer
), NULL
);
794 ok(!status
, "got %#x\n", status
);
795 ok(compare_unicode_string(name_info
->Name
.Buffer
, name_info
->Name
.Length
, L
"\\Device\\WineTestDriver"),
796 "wrong name %s\n", debugstr_w(name_info
->Name
.Buffer
));
798 status
= NtQueryInformationFile(file
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
799 ok(status
== STATUS_INVALID_PARAMETER
, "got %#x\n", status
);
803 file
= CreateFileA("\\\\.\\WineTestDriver\\genfail", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
804 ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
806 status
= NtQueryObject(file
, ObjectNameInformation
, buffer
, sizeof(buffer
), NULL
);
807 ok(status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
809 status
= NtQueryInformationFile(file
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
810 ok(status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
814 file
= CreateFileA("\\\\.\\WineTestDriver\\badtype", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
815 ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
817 status
= NtQueryObject(file
, ObjectNameInformation
, buffer
, sizeof(buffer
), NULL
);
818 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
, "got %#x\n", status
);
820 status
= NtQueryInformationFile(file
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
821 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
, "got %#x\n", status
);
826 static void test_driver3(struct testsign_context
*ctx
)
828 WCHAR filename
[MAX_PATH
];
832 service
= load_driver(ctx
, filename
, L
"driver3.dll", L
"WineTestDriver3");
833 ok(service
!= NULL
, "driver3 failed to load\n");
835 ret
= StartServiceA(service
, 0, NULL
);
836 ok(!ret
, "driver3 should fail to start\n");
837 ok(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
||
838 GetLastError() == ERROR_INVALID_FUNCTION
||
839 GetLastError() == ERROR_PROC_NOT_FOUND
/* XP */ ||
840 GetLastError() == ERROR_FILE_NOT_FOUND
/* Win7 */, "got %u\n", GetLastError());
842 DeleteService(service
);
843 CloseServiceHandle(service
);
844 DeleteFileW(filename
);
847 static DWORD WINAPI
wsk_test_thread(void *parameter
)
849 static const char test_send_string
[] = "Client test string 1.";
850 static const WORD version
= MAKEWORD(2, 2);
851 SOCKET s_listen
, s_accept
, s_connect
;
852 struct sockaddr_in addr
;
858 ret
= WSAStartup(version
, &data
);
859 ok(!ret
, "WSAStartup() failed, ret %u.\n", ret
);
861 s_connect
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
862 ok(s_connect
!= INVALID_SOCKET
, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
864 s_listen
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
865 ok(s_listen
!= INVALID_SOCKET
, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
868 setsockopt(s_listen
, SOL_SOCKET
, SO_REUSEADDR
, (const char *)&opt_val
, sizeof(opt_val
));
870 memset(&addr
, 0, sizeof(addr
));
871 addr
.sin_family
= AF_INET
;
872 addr
.sin_port
= htons(CLIENT_LISTEN_PORT
);
873 addr
.sin_addr
.s_addr
= htonl(0x7f000001);
874 ret
= bind(s_listen
, (struct sockaddr
*)&addr
, sizeof(addr
));
875 ok(!ret
, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret
, WSAGetLastError());
877 ret
= listen(s_listen
, SOMAXCONN
);
878 ok(!ret
, "Got unexpected ret %d, WSAGetLastError() %u.\n", ret
, WSAGetLastError());
880 addr
.sin_port
= htons(SERVER_LISTEN_PORT
);
882 ret
= connect(s_connect
, (struct sockaddr
*)&addr
, sizeof(addr
));
883 while (ret
&& ((err
= WSAGetLastError()) == WSAECONNREFUSED
|| err
== WSAECONNABORTED
))
886 ret
= connect(s_connect
, (struct sockaddr
*)&addr
, sizeof(addr
));
888 ok(!ret
, "Error connecting, WSAGetLastError() %u.\n", WSAGetLastError());
890 ret
= send(s_connect
, test_send_string
, sizeof(test_send_string
), 0);
891 ok(ret
== sizeof(test_send_string
), "Got unexpected ret %d.\n", ret
);
893 ret
= recv(s_connect
, buffer
, sizeof(buffer
), 0);
894 ok(ret
== sizeof(buffer
), "Got unexpected ret %d.\n", ret
);
895 ok(!strcmp(buffer
, "Server test string 1."), "Received unexpected data.\n");
897 s_accept
= accept(s_listen
, NULL
, NULL
);
898 ok(s_accept
!= INVALID_SOCKET
, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
900 closesocket(s_accept
);
901 closesocket(s_connect
);
902 closesocket(s_listen
);
906 static void test_driver_netio(struct testsign_context
*ctx
)
908 WCHAR filename
[MAX_PATH
];
913 if (!(service
= load_driver(ctx
, filename
, L
"driver_netio.dll", L
"winetest_netio")))
916 if (!start_driver(service
, TRUE
))
918 DeleteFileW(filename
);
922 device
= CreateFileA("\\\\.\\winetest_netio", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
923 ok(device
!= INVALID_HANDLE_VALUE
, "failed to open device: %u\n", GetLastError());
925 hthread
= CreateThread(NULL
, 0, wsk_test_thread
, NULL
, 0, NULL
);
927 WaitForSingleObject(hthread
, INFINITE
);
931 unload_driver(service
);
932 ret
= DeleteFileW(filename
);
933 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
940 #elif defined(__x86_64__)
942 #elif defined(__arm__)
944 #elif defined(__aarch64__)
950 static const char inf_text
[] =
952 "Signature=$Chicago$\n"
953 "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n"
954 "CatalogFile=winetest.cat\n"
955 "DriverVer=09/21/2006,6.0.5736.1\n"
958 "Wine=mfg_section,NT" EXT
"\n"
960 "[mfg_section.NT" EXT
"]\n"
961 "Wine test root driver=device_section,test_hardware_id\n"
963 "[device_section.NT" EXT
"]\n"
964 "CopyFiles=file_section\n"
966 "[device_section.NT" EXT
".Services]\n"
967 "AddService=winetest,0x2,svc_section\n"
972 "[SourceDisksFiles]\n"
975 "[SourceDisksNames]\n"
978 "[DestinationDirs]\n"
979 "DefaultDestDir=12\n"
982 "ServiceBinary=%12%\\winetest.sys\n"
986 "LoadOrderGroup=Extended Base\n"
987 "DisplayName=\"winetest bus driver\"\n"
988 "; they don't sleep anymore, on the beach\n";
990 static void add_file_to_catalog(HANDLE catalog
, const WCHAR
*file
)
992 SIP_SUBJECTINFO subject_info
= {sizeof(SIP_SUBJECTINFO
)};
993 SIP_INDIRECT_DATA
*indirect_data
;
994 const WCHAR
*filepart
= file
;
995 CRYPTCATMEMBER
*member
;
996 WCHAR hash_buffer
[100];
1002 ret
= CryptSIPRetrieveSubjectGuidForCatalogFile(file
, NULL
, &subject_guid
);
1003 todo_wine
ok(ret
, "Failed to get subject guid, error %u\n", GetLastError());
1006 subject_info
.pgSubjectType
= &subject_guid
;
1007 subject_info
.pwsFileName
= file
;
1008 subject_info
.DigestAlgorithm
.pszObjId
= (char *)szOID_OIWSEC_sha1
;
1009 subject_info
.dwFlags
= SPC_INC_PE_RESOURCES_FLAG
| SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG
| SPC_EXC_PE_PAGE_HASHES_FLAG
| 0x10000;
1010 ret
= CryptSIPCreateIndirectData(&subject_info
, &size
, NULL
);
1011 todo_wine
ok(ret
, "Failed to get indirect data size, error %u\n", GetLastError());
1013 indirect_data
= malloc(size
);
1014 ret
= CryptSIPCreateIndirectData(&subject_info
, &size
, indirect_data
);
1015 todo_wine
ok(ret
, "Failed to get indirect data, error %u\n", GetLastError());
1018 memset(hash_buffer
, 0, sizeof(hash_buffer
));
1019 for (i
= 0; i
< indirect_data
->Digest
.cbData
; ++i
)
1020 swprintf(&hash_buffer
[i
* 2], 2, L
"%02X", indirect_data
->Digest
.pbData
[i
]);
1022 member
= CryptCATPutMemberInfo(catalog
, (WCHAR
*)file
,
1023 hash_buffer
, &subject_guid
, 0, size
, (BYTE
*)indirect_data
);
1024 ok(!!member
, "Failed to write member, error %u\n", GetLastError());
1026 if (wcsrchr(file
, '\\'))
1027 filepart
= wcsrchr(file
, '\\') + 1;
1029 ret
= !!CryptCATPutAttrInfo(catalog
, member
, (WCHAR
*)L
"File",
1030 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
1031 (wcslen(filepart
) + 1) * 2, (BYTE
*)filepart
);
1032 ok(ret
, "Failed to write attr, error %u\n", GetLastError());
1034 ret
= !!CryptCATPutAttrInfo(catalog
, member
, (WCHAR
*)L
"OSAttr",
1035 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
1036 sizeof(L
"2:6.0"), (BYTE
*)L
"2:6.0");
1037 ok(ret
, "Failed to write attr, error %u\n", GetLastError());
1041 static const GUID bus_class
= {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc1}};
1042 static const GUID child_class
= {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc2}};
1044 static unsigned int got_bus_arrival
, got_bus_removal
, got_child_arrival
, got_child_removal
;
1046 static LRESULT WINAPI
device_notify_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
1048 if (message
!= WM_DEVICECHANGE
)
1049 return DefWindowProcA(window
, message
, wparam
, lparam
);
1053 case DBT_DEVNODES_CHANGED
:
1054 if (winetest_debug
> 1) trace("device nodes changed\n");
1056 ok(InSendMessageEx(NULL
) == ISMEX_NOTIFY
, "got message flags %#x\n", InSendMessageEx(NULL
));
1057 ok(!lparam
, "got lparam %#Ix\n", lparam
);
1060 case DBT_DEVICEARRIVAL
:
1062 const DEV_BROADCAST_DEVICEINTERFACE_A
*iface
= (const DEV_BROADCAST_DEVICEINTERFACE_A
*)lparam
;
1063 DWORD expect_size
= offsetof(DEV_BROADCAST_DEVICEINTERFACE_A
, dbcc_name
[strlen(iface
->dbcc_name
)]);
1065 if (winetest_debug
> 1) trace("device arrival %s\n", iface
->dbcc_name
);
1067 ok(InSendMessageEx(NULL
) == ISMEX_SEND
, "got message flags %#x\n", InSendMessageEx(NULL
));
1069 ok(iface
->dbcc_devicetype
== DBT_DEVTYP_DEVICEINTERFACE
,
1070 "got unexpected notification type %#x\n", iface
->dbcc_devicetype
);
1071 ok(iface
->dbcc_size
>= expect_size
, "expected size at least %u, got %u\n", expect_size
, iface
->dbcc_size
);
1072 ok(!iface
->dbcc_reserved
, "got reserved %#x\n", iface
->dbcc_reserved
);
1073 if (IsEqualGUID(&iface
->dbcc_classguid
, &bus_class
))
1076 todo_wine
ok(!strcmp(iface
->dbcc_name
, "\\\\?\\ROOT#WINETEST#0#{deadbeef-29ef-4538-a5fd-b69573a362c1}"),
1077 "got name %s\n", debugstr_a(iface
->dbcc_name
));
1079 else if (IsEqualGUID(&iface
->dbcc_classguid
, &child_class
))
1081 ++got_child_arrival
;
1082 todo_wine
ok(!strcmp(iface
->dbcc_name
, "\\\\?\\wine#test#1#{deadbeef-29ef-4538-a5fd-b69573a362c2}"),
1083 "got name %s\n", debugstr_a(iface
->dbcc_name
));
1088 case DBT_DEVICEREMOVECOMPLETE
:
1090 const DEV_BROADCAST_DEVICEINTERFACE_A
*iface
= (const DEV_BROADCAST_DEVICEINTERFACE_A
*)lparam
;
1091 DWORD expect_size
= offsetof(DEV_BROADCAST_DEVICEINTERFACE_A
, dbcc_name
[strlen(iface
->dbcc_name
)]);
1093 if (winetest_debug
> 1) trace("device removal %s\n", iface
->dbcc_name
);
1095 ok(InSendMessageEx(NULL
) == ISMEX_SEND
, "got message flags %#x\n", InSendMessageEx(NULL
));
1097 ok(iface
->dbcc_devicetype
== DBT_DEVTYP_DEVICEINTERFACE
,
1098 "got unexpected notification type %#x\n", iface
->dbcc_devicetype
);
1099 ok(iface
->dbcc_size
>= expect_size
, "expected size at least %u, got %u\n", expect_size
, iface
->dbcc_size
);
1100 ok(!iface
->dbcc_reserved
, "got reserved %#x\n", iface
->dbcc_reserved
);
1101 if (IsEqualGUID(&iface
->dbcc_classguid
, &bus_class
))
1104 todo_wine
ok(!strcmp(iface
->dbcc_name
, "\\\\?\\ROOT#WINETEST#0#{deadbeef-29ef-4538-a5fd-b69573a362c1}"),
1105 "got name %s\n", debugstr_a(iface
->dbcc_name
));
1107 else if (IsEqualGUID(&iface
->dbcc_classguid
, &child_class
))
1109 ++got_child_removal
;
1110 todo_wine
ok(!strcmp(iface
->dbcc_name
, "\\\\?\\wine#test#1#{deadbeef-29ef-4538-a5fd-b69573a362c2}"),
1111 "got name %s\n", debugstr_a(iface
->dbcc_name
));
1116 return DefWindowProcA(window
, message
, wparam
, lparam
);
1119 static void pump_messages(void)
1123 if (!MsgWaitForMultipleObjects(0, NULL
, FALSE
, 200, QS_ALLINPUT
))
1125 while (PeekMessageA(&msg
, NULL
, 0, 0, PM_REMOVE
))
1127 TranslateMessage(&msg
);
1128 DispatchMessageA(&msg
);
1133 static void test_pnp_devices(void)
1135 static const char expect_hardware_id
[] = "winetest_hardware\0winetest_hardware_1\0";
1136 static const char expect_compat_id
[] = "winetest_compat\0winetest_compat_1\0";
1139 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*iface_detail
= (void *)buffer
;
1140 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(iface
)};
1141 SP_DEVINFO_DATA device
= {sizeof(device
)};
1142 DEV_BROADCAST_DEVICEINTERFACE_A filter
=
1144 .dbcc_size
= sizeof(filter
),
1145 .dbcc_devicetype
= DBT_DEVTYP_DEVICEINTERFACE
,
1147 static const WNDCLASSA
class =
1149 .lpszClassName
= "ntoskrnl_test_wc",
1150 .lpfnWndProc
= device_notify_proc
,
1152 HDEVNOTIFY notify_handle
;
1153 DWORD size
, type
, dword
;
1154 HANDLE bus
, child
, tmp
;
1155 OBJECT_ATTRIBUTES attr
;
1156 UNICODE_STRING string
;
1157 OVERLAPPED ovl
= {0};
1164 ret
= RegisterClassA(&class);
1165 ok(ret
, "failed to register class\n");
1166 window
= CreateWindowA("ntoskrnl_test_wc", NULL
, 0, 0, 0, 0, 0, HWND_MESSAGE
, NULL
, NULL
, NULL
);
1167 ok(!!window
, "failed to create window\n");
1168 notify_handle
= RegisterDeviceNotificationA(window
, &filter
, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
);
1169 ok(!!notify_handle
, "failed to register window, error %u\n", GetLastError());
1171 set
= SetupDiGetClassDevsA(&control_class
, NULL
, NULL
, DIGCF_PRESENT
| DIGCF_DEVICEINTERFACE
);
1172 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1174 ret
= SetupDiEnumDeviceInfo(set
, 0, &device
);
1175 ok(ret
, "failed to get device, error %#x\n", GetLastError());
1176 ok(IsEqualGUID(&device
.ClassGuid
, &GUID_DEVCLASS_SYSTEM
), "wrong class %s\n", debugstr_guid(&device
.ClassGuid
));
1178 ret
= SetupDiGetDeviceInstanceIdA(set
, &device
, buffer
, sizeof(buffer
), NULL
);
1179 ok(ret
, "failed to get device ID, error %#x\n", GetLastError());
1180 ok(!strcasecmp(buffer
, "root\\winetest\\0"), "got ID %s\n", debugstr_a(buffer
));
1182 ret
= SetupDiEnumDeviceInterfaces(set
, NULL
, &control_class
, 0, &iface
);
1183 ok(ret
, "failed to get interface, error %#x\n", GetLastError());
1184 ok(IsEqualGUID(&iface
.InterfaceClassGuid
, &control_class
),
1185 "wrong class %s\n", debugstr_guid(&iface
.InterfaceClassGuid
));
1186 ok(iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
1188 iface_detail
->cbSize
= sizeof(*iface_detail
);
1189 ret
= SetupDiGetDeviceInterfaceDetailA(set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
1190 ok(ret
, "failed to get interface path, error %#x\n", GetLastError());
1191 ok(!strcasecmp(iface_detail
->DevicePath
, "\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}"),
1192 "wrong path %s\n", debugstr_a(iface_detail
->DevicePath
));
1194 SetupDiDestroyDeviceInfoList(set
);
1196 bus
= CreateFileA(iface_detail
->DevicePath
, 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1197 ok(bus
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
1199 ret
= DeviceIoControl(bus
, IOCTL_WINETEST_BUS_MAIN
, NULL
, 0, NULL
, 0, &size
, NULL
);
1200 ok(ret
, "got error %u\n", GetLastError());
1202 /* Test IoRegisterDeviceInterface() and IoSetDeviceInterfaceState(). */
1204 set
= SetupDiGetClassDevsA(&bus_class
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
);
1205 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1206 ret
= SetupDiEnumDeviceInterfaces(set
, NULL
, &bus_class
, 0, &iface
);
1207 ok(!ret
, "expected failure\n");
1208 ok(GetLastError() == ERROR_NO_MORE_ITEMS
, "got error %#x\n", GetLastError());
1209 SetupDiDestroyDeviceInfoList(set
);
1211 ret
= DeviceIoControl(bus
, IOCTL_WINETEST_BUS_REGISTER_IFACE
, NULL
, 0, NULL
, 0, &size
, NULL
);
1212 ok(ret
, "got error %u\n", GetLastError());
1214 set
= SetupDiGetClassDevsA(&bus_class
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
);
1215 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1216 ret
= SetupDiEnumDeviceInterfaces(set
, NULL
, &bus_class
, 0, &iface
);
1217 ok(ret
, "failed to get interface, error %#x\n", GetLastError());
1218 ok(IsEqualGUID(&iface
.InterfaceClassGuid
, &bus_class
),
1219 "wrong class %s\n", debugstr_guid(&iface
.InterfaceClassGuid
));
1220 ok(!iface
.Flags
, "got flags %#x\n", iface
.Flags
);
1221 SetupDiDestroyDeviceInfoList(set
);
1223 set
= SetupDiGetClassDevsA(&bus_class
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
1224 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1225 ret
= SetupDiEnumDeviceInterfaces(set
, NULL
, &bus_class
, 0, &iface
);
1226 ok(!ret
, "expected failure\n");
1227 ok(GetLastError() == ERROR_NO_MORE_ITEMS
, "got error %#x\n", GetLastError());
1228 SetupDiDestroyDeviceInfoList(set
);
1230 ret
= DeviceIoControl(bus
, IOCTL_WINETEST_BUS_ENABLE_IFACE
, NULL
, 0, NULL
, 0, &size
, NULL
);
1231 ok(ret
, "got error %u\n", GetLastError());
1234 ok(got_bus_arrival
== 1, "got %u bus arrival messages\n", got_bus_arrival
);
1235 ok(!got_bus_removal
, "got %u bus removal messages\n", got_bus_removal
);
1237 set
= SetupDiGetClassDevsA(&bus_class
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
1238 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1239 ret
= SetupDiEnumDeviceInterfaces(set
, NULL
, &bus_class
, 0, &iface
);
1240 ok(ret
, "failed to get interface, error %#x\n", GetLastError());
1241 ok(IsEqualGUID(&iface
.InterfaceClassGuid
, &bus_class
),
1242 "wrong class %s\n", debugstr_guid(&iface
.InterfaceClassGuid
));
1243 ok(iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
1244 SetupDiDestroyDeviceInfoList(set
);
1246 ret
= DeviceIoControl(bus
, IOCTL_WINETEST_BUS_DISABLE_IFACE
, NULL
, 0, NULL
, 0, &size
, NULL
);
1247 ok(ret
, "got error %u\n", GetLastError());
1250 ok(got_bus_arrival
== 1, "got %u bus arrival messages\n", got_bus_arrival
);
1251 ok(got_bus_removal
== 1, "got %u bus removal messages\n", got_bus_removal
);
1253 set
= SetupDiGetClassDevsA(&bus_class
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
);
1254 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1255 ret
= SetupDiEnumDeviceInterfaces(set
, NULL
, &bus_class
, 0, &iface
);
1256 ok(ret
, "failed to get interface, error %#x\n", GetLastError());
1257 ok(IsEqualGUID(&iface
.InterfaceClassGuid
, &bus_class
),
1258 "wrong class %s\n", debugstr_guid(&iface
.InterfaceClassGuid
));
1259 ok(!iface
.Flags
, "got flags %#x\n", iface
.Flags
);
1260 SetupDiDestroyDeviceInfoList(set
);
1262 set
= SetupDiGetClassDevsA(&bus_class
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
1263 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1264 ret
= SetupDiEnumDeviceInterfaces(set
, NULL
, &bus_class
, 0, &iface
);
1265 ok(!ret
, "expected failure\n");
1266 ok(GetLastError() == ERROR_NO_MORE_ITEMS
, "got error %#x\n", GetLastError());
1267 SetupDiDestroyDeviceInfoList(set
);
1269 /* Test exposing a child device. */
1272 ret
= DeviceIoControl(bus
, IOCTL_WINETEST_BUS_ADD_CHILD
, &id
, sizeof(id
), NULL
, 0, &size
, NULL
);
1273 ok(ret
, "got error %u\n", GetLastError());
1276 ok(got_child_arrival
== 1, "got %u child arrival messages\n", got_child_arrival
);
1277 ok(!got_child_removal
, "got %u child removal messages\n", got_child_removal
);
1279 set
= SetupDiGetClassDevsA(&child_class
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
1280 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1282 ret
= SetupDiEnumDeviceInfo(set
, 0, &device
);
1283 ok(ret
, "failed to get device, error %#x\n", GetLastError());
1284 ok(IsEqualGUID(&device
.ClassGuid
, &GUID_NULL
), "wrong class %s\n", debugstr_guid(&device
.ClassGuid
));
1286 ret
= SetupDiGetDeviceInstanceIdA(set
, &device
, buffer
, sizeof(buffer
), NULL
);
1287 ok(ret
, "failed to get device ID, error %#x\n", GetLastError());
1288 ok(!strcasecmp(buffer
, "wine\\test\\1"), "got ID %s\n", debugstr_a(buffer
));
1290 ret
= SetupDiGetDeviceRegistryPropertyA(set
, &device
, SPDRP_CAPABILITIES
,
1291 &type
, (BYTE
*)&dword
, sizeof(dword
), NULL
);
1292 todo_wine
ok(ret
, "got error %#x\n", GetLastError());
1295 ok(dword
== (CM_DEVCAP_EJECTSUPPORTED
| CM_DEVCAP_UNIQUEID
1296 | CM_DEVCAP_RAWDEVICEOK
| CM_DEVCAP_SURPRISEREMOVALOK
), "got flags %#x\n", dword
);
1297 ok(type
== REG_DWORD
, "got type %u\n", type
);
1300 ret
= SetupDiGetDeviceRegistryPropertyA(set
, &device
, SPDRP_CLASSGUID
,
1301 &type
, (BYTE
*)buffer
, sizeof(buffer
), NULL
);
1302 todo_wine
ok(!ret
, "expected failure\n");
1304 ok(GetLastError() == ERROR_INVALID_DATA
, "got error %#x\n", GetLastError());
1306 ret
= SetupDiGetDeviceRegistryPropertyA(set
, &device
, SPDRP_DEVTYPE
,
1307 &type
, (BYTE
*)&dword
, sizeof(dword
), NULL
);
1308 ok(!ret
, "expected failure\n");
1309 ok(GetLastError() == ERROR_INVALID_DATA
, "got error %#x\n", GetLastError());
1311 ret
= SetupDiGetDeviceRegistryPropertyA(set
, &device
, SPDRP_DRIVER
,
1312 &type
, (BYTE
*)buffer
, sizeof(buffer
), NULL
);
1313 ok(!ret
, "expected failure\n");
1314 ok(GetLastError() == ERROR_INVALID_DATA
, "got error %#x\n", GetLastError());
1316 ret
= SetupDiGetDeviceRegistryPropertyA(set
, &device
, SPDRP_HARDWAREID
,
1317 &type
, (BYTE
*)buffer
, sizeof(buffer
), &size
);
1318 ok(ret
, "got error %#x\n", GetLastError());
1319 ok(type
== REG_MULTI_SZ
, "got type %u\n", type
);
1320 ok(size
== sizeof(expect_hardware_id
), "got size %u\n", size
);
1321 ok(!memcmp(buffer
, expect_hardware_id
, size
), "got hardware IDs %s\n", debugstr_an(buffer
, size
));
1323 ret
= SetupDiGetDeviceRegistryPropertyA(set
, &device
, SPDRP_COMPATIBLEIDS
,
1324 &type
, (BYTE
*)buffer
, sizeof(buffer
), &size
);
1325 ok(ret
, "got error %#x\n", GetLastError());
1326 ok(type
== REG_MULTI_SZ
, "got type %u\n", type
);
1327 ok(size
== sizeof(expect_compat_id
), "got size %u\n", size
);
1328 ok(!memcmp(buffer
, expect_compat_id
, size
), "got compatible IDs %s\n", debugstr_an(buffer
, size
));
1330 ret
= SetupDiGetDeviceRegistryPropertyA(set
, &device
, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME
,
1331 &type
, (BYTE
*)buffer
, sizeof(buffer
), NULL
);
1332 todo_wine
ok(ret
, "got error %#x\n", GetLastError());
1335 ok(type
== REG_SZ
, "got type %u\n", type
);
1336 ok(!strcmp(buffer
, "\\Device\\winetest_pnp_1"), "got PDO name %s\n", debugstr_a(buffer
));
1339 SetupDiDestroyDeviceInfoList(set
);
1341 RtlInitUnicodeString(&string
, L
"\\Device\\winetest_pnp_1");
1342 InitializeObjectAttributes(&attr
, &string
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1343 ret
= NtOpenFile(&child
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
1344 ok(!ret
, "failed to open child: %#x\n", ret
);
1347 ret
= DeviceIoControl(child
, IOCTL_WINETEST_CHILD_GET_ID
, NULL
, 0, &id
, sizeof(id
), &size
, NULL
);
1348 ok(ret
, "got error %u\n", GetLastError());
1349 ok(id
== 1, "got id %d\n", id
);
1350 ok(size
== sizeof(id
), "got size %u\n", size
);
1354 ret
= NtOpenFile(&child
, SYNCHRONIZE
, &attr
, &io
, 0, 0);
1355 ok(!ret
, "failed to open child: %#x\n", ret
);
1357 ret
= DeviceIoControl(child
, IOCTL_WINETEST_MARK_PENDING
, NULL
, 0, NULL
, 0, &size
, &ovl
);
1358 ok(!ret
, "DeviceIoControl succeded\n");
1359 ok(GetLastError() == ERROR_IO_PENDING
, "got error %u\n", GetLastError());
1360 ok(size
== 0, "got size %u\n", size
);
1363 ret
= DeviceIoControl(bus
, IOCTL_WINETEST_BUS_REMOVE_CHILD
, &id
, sizeof(id
), NULL
, 0, &size
, NULL
);
1364 ok(ret
, "got error %u\n", GetLastError());
1367 ok(got_child_arrival
== 1, "got %u child arrival messages\n", got_child_arrival
);
1368 ok(got_child_removal
== 1, "got %u child removal messages\n", got_child_removal
);
1370 ret
= DeviceIoControl(child
, IOCTL_WINETEST_CHECK_REMOVED
, NULL
, 0, NULL
, 0, &size
, NULL
);
1371 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1373 ret
= NtOpenFile(&tmp
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
1374 todo_wine
ok(ret
== STATUS_NO_SUCH_DEVICE
, "got %#x\n", ret
);
1376 ret
= GetOverlappedResult(child
, &ovl
, &size
, TRUE
);
1377 ok(!ret
, "unexpected success.\n");
1378 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got error %u\n", GetLastError());
1379 ok(size
== 0, "got size %u\n", size
);
1384 ok(got_child_arrival
== 1, "got %u child arrival messages\n", got_child_arrival
);
1385 ok(got_child_removal
== 1, "got %u child removal messages\n", got_child_removal
);
1387 ret
= NtOpenFile(&tmp
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
1388 ok(ret
== STATUS_OBJECT_NAME_NOT_FOUND
, "got %#x\n", ret
);
1392 UnregisterDeviceNotification(notify_handle
);
1393 DestroyWindow(window
);
1394 UnregisterClassA("ntoskrnl_test_wc", GetModuleHandleA(NULL
));
1397 static void test_pnp_driver(struct testsign_context
*ctx
)
1399 static const char hardware_id
[] = "test_hardware_id\0";
1400 char path
[MAX_PATH
], dest
[MAX_PATH
], *filepart
;
1401 SP_DEVINFO_DATA device
= {sizeof(device
)};
1402 char cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
1403 WCHAR driver_filename
[MAX_PATH
];
1404 SC_HANDLE manager
, service
;
1405 BOOL ret
, need_reboot
;
1406 HANDLE catalog
, file
;
1411 GetCurrentDirectoryA(ARRAY_SIZE(cwd
), cwd
);
1412 GetTempPathA(ARRAY_SIZE(tempdir
), tempdir
);
1413 SetCurrentDirectoryA(tempdir
);
1415 load_resource(L
"driver_pnp.dll", driver_filename
);
1416 ret
= MoveFileExW(driver_filename
, L
"winetest.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
1417 ok(ret
, "failed to move file, error %u\n", GetLastError());
1419 f
= fopen("winetest.inf", "w");
1420 ok(!!f
, "failed to open winetest.inf: %s\n", strerror(errno
));
1424 /* Create the catalog file. */
1426 catalog
= CryptCATOpen((WCHAR
*)L
"winetest.cat", CRYPTCAT_OPEN_CREATENEW
, 0, CRYPTCAT_VERSION_1
, 0);
1427 ok(catalog
!= INVALID_HANDLE_VALUE
, "Failed to create catalog, error %#x\n", GetLastError());
1429 ret
= !!CryptCATPutCatAttrInfo(catalog
, (WCHAR
*)L
"HWID1",
1430 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
1431 sizeof(L
"test_hardware_id"), (BYTE
*)L
"test_hardware_id");
1432 todo_wine
ok(ret
, "failed to add attribute, error %#x\n", GetLastError());
1434 ret
= !!CryptCATPutCatAttrInfo(catalog
, (WCHAR
*)L
"OS",
1435 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
1436 sizeof(L
"VistaX64"), (BYTE
*)L
"VistaX64");
1437 todo_wine
ok(ret
, "failed to add attribute, error %#x\n", GetLastError());
1439 add_file_to_catalog(catalog
, L
"winetest.sys");
1440 add_file_to_catalog(catalog
, L
"winetest.inf");
1442 ret
= CryptCATPersistStore(catalog
);
1443 todo_wine
ok(ret
, "Failed to write catalog, error %u\n", GetLastError());
1445 ret
= CryptCATClose(catalog
);
1446 ok(ret
, "Failed to close catalog, error %u\n", GetLastError());
1448 testsign_sign(ctx
, L
"winetest.cat");
1450 /* Install the driver. */
1452 set
= SetupDiCreateDeviceInfoList(NULL
, NULL
);
1453 ok(set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %#x\n", GetLastError());
1455 ret
= SetupDiCreateDeviceInfoA(set
, "root\\winetest\\0", &GUID_NULL
, NULL
, NULL
, 0, &device
);
1456 ok(ret
, "failed to create device, error %#x\n", GetLastError());
1458 ret
= SetupDiSetDeviceRegistryPropertyA( set
, &device
, SPDRP_HARDWAREID
,
1459 (const BYTE
*)hardware_id
, sizeof(hardware_id
) );
1460 ok(ret
, "failed to create set hardware ID, error %#x\n", GetLastError());
1462 ret
= SetupDiCallClassInstaller(DIF_REGISTERDEVICE
, set
, &device
);
1463 ok(ret
, "failed to register device, error %#x\n", GetLastError());
1465 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
1466 ret
= UpdateDriverForPlugAndPlayDevicesA(NULL
, hardware_id
, path
, INSTALLFLAG_FORCE
, &need_reboot
);
1467 ok(ret
, "failed to install device, error %#x\n", GetLastError());
1468 ok(!need_reboot
, "expected no reboot necessary\n");
1476 ret
= SetupDiCallClassInstaller(DIF_REMOVE
, set
, &device
);
1477 ok(ret
, "failed to remove device, error %#x\n", GetLastError());
1479 file
= CreateFileA("\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1480 ok(file
== INVALID_HANDLE_VALUE
, "expected failure\n");
1481 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %u\n", GetLastError());
1483 ret
= SetupDiDestroyDeviceInfoList(set
);
1484 ok(ret
, "failed to destroy set, error %#x\n", GetLastError());
1486 set
= SetupDiGetClassDevsA(NULL
, "wine", NULL
, DIGCF_ALLCLASSES
);
1487 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
1489 for (i
= 0; SetupDiEnumDeviceInfo(set
, i
, &device
); ++i
)
1491 ret
= SetupDiCallClassInstaller(DIF_REMOVE
, set
, &device
);
1492 ok(ret
, "failed to remove device, error %#x\n", GetLastError());
1495 /* Windows stops the service but does not delete it. */
1496 manager
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
1497 ok(!!manager
, "failed to open service manager, error %u\n", GetLastError());
1498 service
= OpenServiceA(manager
, "winetest", SERVICE_STOP
| DELETE
);
1499 ok(!!service
, "failed to open service, error %u\n", GetLastError());
1500 unload_driver(service
);
1501 CloseServiceHandle(manager
);
1505 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
1506 ret
= SetupCopyOEMInfA(path
, NULL
, 0, 0, dest
, sizeof(dest
), NULL
, &filepart
);
1507 ok(ret
, "Failed to copy INF, error %#x\n", GetLastError());
1508 ret
= SetupUninstallOEMInfA(filepart
, 0, NULL
);
1509 ok(ret
, "Failed to uninstall INF, error %u\n", GetLastError());
1511 ret
= DeleteFileA("winetest.cat");
1512 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
1513 ret
= DeleteFileA("winetest.inf");
1514 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
1515 ret
= DeleteFileA("winetest.sys");
1516 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
1517 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
1518 ret
= DeleteFileA("C:/windows/system32/drivers/winetest.sys");
1519 ok(ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %u\n", GetLastError());
1521 SetCurrentDirectoryA(cwd
);
1524 #define check_member_(file, line, val, exp, fmt, member) \
1525 ok_(file, line)((val).member == (exp).member, \
1526 "got " #member " " fmt ", expected " fmt "\n", \
1527 (val).member, (exp).member)
1528 #define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member)
1530 #define check_hidp_caps(a, b) check_hidp_caps_(__LINE__, a, b)
1531 static inline void check_hidp_caps_(int line
, HIDP_CAPS
*caps
, const HIDP_CAPS
*exp
)
1533 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", Usage
);
1534 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
1535 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", InputReportByteLength
);
1536 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", OutputReportByteLength
);
1537 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", FeatureReportByteLength
);
1538 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberLinkCollectionNodes
);
1539 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberInputButtonCaps
);
1540 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberInputValueCaps
);
1541 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberInputDataIndices
);
1542 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberOutputButtonCaps
);
1543 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberOutputValueCaps
);
1544 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberOutputDataIndices
);
1545 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureButtonCaps
);
1546 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureValueCaps
);
1547 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureDataIndices
);
1550 #define check_hidp_link_collection_node(a, b) check_hidp_link_collection_node_(__LINE__, a, b)
1551 static inline void check_hidp_link_collection_node_(int line
, HIDP_LINK_COLLECTION_NODE
*node
,
1552 const HIDP_LINK_COLLECTION_NODE
*exp
)
1554 check_member_(__FILE__
, line
, *node
, *exp
, "%04x", LinkUsage
);
1555 check_member_(__FILE__
, line
, *node
, *exp
, "%04x", LinkUsagePage
);
1556 check_member_(__FILE__
, line
, *node
, *exp
, "%d", Parent
);
1557 check_member_(__FILE__
, line
, *node
, *exp
, "%d", NumberOfChildren
);
1558 check_member_(__FILE__
, line
, *node
, *exp
, "%d", NextSibling
);
1559 check_member_(__FILE__
, line
, *node
, *exp
, "%d", FirstChild
);
1560 check_member_(__FILE__
, line
, *node
, *exp
, "%d", CollectionType
);
1561 check_member_(__FILE__
, line
, *node
, *exp
, "%d", IsAlias
);
1564 #define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b)
1565 static inline void check_hidp_button_caps_(int line
, HIDP_BUTTON_CAPS
*caps
, const HIDP_BUTTON_CAPS
*exp
)
1567 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
1568 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
1569 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
1570 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", BitField
);
1571 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
1572 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", LinkUsage
);
1573 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", LinkUsagePage
);
1574 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
1575 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
1576 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
1577 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
1579 if (!caps
->IsRange
&& !exp
->IsRange
)
1581 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
1582 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
1584 else if (caps
->IsRange
&& exp
->IsRange
)
1586 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
1587 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
1588 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
1589 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
1592 if (!caps
->IsRange
&& !exp
->IsRange
)
1593 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
1594 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
1596 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
1597 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
1600 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
1601 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
1602 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
1604 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
1605 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
1609 #define check_hidp_value_caps(a, b) check_hidp_value_caps_(__LINE__, a, b)
1610 static inline void check_hidp_value_caps_(int line
, HIDP_VALUE_CAPS
*caps
, const HIDP_VALUE_CAPS
*exp
)
1612 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
1613 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
1614 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
1615 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", BitField
);
1616 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
1617 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", LinkUsage
);
1618 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", LinkUsagePage
);
1619 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
1620 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
1621 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
1622 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
1624 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", HasNull
);
1625 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", BitSize
);
1626 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", ReportCount
);
1627 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", UnitsExp
);
1628 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Units
);
1629 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", LogicalMin
);
1630 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", LogicalMax
);
1631 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", PhysicalMin
);
1632 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", PhysicalMax
);
1634 if (!caps
->IsRange
&& !exp
->IsRange
)
1636 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
1637 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
1639 else if (caps
->IsRange
&& exp
->IsRange
)
1641 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
1642 check_member_(__FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
1643 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
1644 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
1647 if (!caps
->IsRange
&& !exp
->IsRange
)
1648 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
1649 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
1651 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
1652 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
1655 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
1656 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
1657 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
1659 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
1660 check_member_(__FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
1664 static BOOL
sync_ioctl(HANDLE file
, DWORD code
, void *in_buf
, DWORD in_len
, void *out_buf
, DWORD
*ret_len
)
1666 OVERLAPPED ovl
= {0};
1667 DWORD out_len
= ret_len
? *ret_len
: 0;
1670 ovl
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
1671 ret
= DeviceIoControl(file
, code
, in_buf
, in_len
, out_buf
, out_len
, &out_len
, &ovl
);
1672 if (!ret
&& GetLastError() == ERROR_IO_PENDING
) ret
= GetOverlappedResult(file
, &ovl
, &out_len
, TRUE
);
1673 CloseHandle(ovl
.hEvent
);
1675 if (ret_len
) *ret_len
= out_len
;
1679 static void test_hidp(HANDLE file
, int report_id
)
1681 const HIDP_CAPS expect_hidp_caps
[] =
1683 /* without report id */
1685 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
1686 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1687 .InputReportByteLength
= 24,
1688 .OutputReportByteLength
= 3,
1689 .FeatureReportByteLength
= 18,
1690 .NumberLinkCollectionNodes
= 10,
1691 .NumberInputButtonCaps
= 13,
1692 .NumberInputValueCaps
= 7,
1693 .NumberInputDataIndices
= 43,
1694 .NumberFeatureButtonCaps
= 1,
1695 .NumberFeatureValueCaps
= 5,
1696 .NumberFeatureDataIndices
= 7,
1698 /* with report id */
1700 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
1701 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1702 .InputReportByteLength
= 23,
1703 .OutputReportByteLength
= 2,
1704 .FeatureReportByteLength
= 17,
1705 .NumberLinkCollectionNodes
= 10,
1706 .NumberInputButtonCaps
= 13,
1707 .NumberInputValueCaps
= 7,
1708 .NumberInputDataIndices
= 43,
1709 .NumberFeatureButtonCaps
= 1,
1710 .NumberFeatureValueCaps
= 5,
1711 .NumberFeatureDataIndices
= 7,
1714 const HIDP_BUTTON_CAPS expect_button_caps
[] =
1717 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1718 .ReportID
= report_id
,
1720 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1721 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1722 .LinkCollection
= 1,
1725 .Range
.UsageMin
= 1,
1726 .Range
.UsageMax
= 8,
1727 .Range
.DataIndexMin
= 2,
1728 .Range
.DataIndexMax
= 9,
1731 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1732 .ReportID
= report_id
,
1734 .LinkCollection
= 1,
1735 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1736 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1739 .Range
.UsageMin
= 0x18,
1740 .Range
.UsageMax
= 0x1f,
1741 .Range
.DataIndexMin
= 10,
1742 .Range
.DataIndexMax
= 17,
1745 .UsagePage
= HID_USAGE_PAGE_KEYBOARD
,
1746 .ReportID
= report_id
,
1748 .LinkCollection
= 1,
1749 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1750 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1752 .IsAbsolute
= FALSE
,
1753 .Range
.UsageMin
= 0x8,
1754 .Range
.UsageMax
= 0xf,
1755 .Range
.DataIndexMin
= 18,
1756 .Range
.DataIndexMax
= 25,
1759 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1760 .ReportID
= report_id
,
1762 .LinkCollection
= 1,
1763 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1764 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1767 .NotRange
.Usage
= 0x20,
1768 .NotRange
.Reserved1
= 0x20,
1769 .NotRange
.DataIndex
= 26,
1770 .NotRange
.Reserved4
= 26,
1773 const HIDP_VALUE_CAPS expect_value_caps
[] =
1776 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1777 .ReportID
= report_id
,
1779 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1780 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1781 .LinkCollection
= 1,
1787 .NotRange
.Usage
= HID_USAGE_GENERIC_Y
,
1788 .NotRange
.Reserved1
= HID_USAGE_GENERIC_Y
,
1791 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1792 .ReportID
= report_id
,
1794 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1795 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1796 .LinkCollection
= 1,
1802 .NotRange
.Usage
= HID_USAGE_GENERIC_X
,
1803 .NotRange
.Reserved1
= HID_USAGE_GENERIC_X
,
1804 .NotRange
.DataIndex
= 1,
1805 .NotRange
.Reserved4
= 1,
1808 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1809 .ReportID
= report_id
,
1811 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1812 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1813 .LinkCollection
= 1,
1818 .Range
.UsageMin
= 0x21,
1819 .Range
.UsageMax
= 0x22,
1820 .Range
.DataIndexMin
= 27,
1821 .Range
.DataIndexMax
= 28,
1824 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1825 .ReportID
= report_id
,
1827 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1828 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1829 .LinkCollection
= 1,
1835 .NotRange
.Usage
= HID_USAGE_GENERIC_HATSWITCH
,
1836 .NotRange
.Reserved1
= HID_USAGE_GENERIC_HATSWITCH
,
1837 .NotRange
.DataIndex
= 29,
1838 .NotRange
.Reserved4
= 29,
1841 static const HIDP_LINK_COLLECTION_NODE expect_collections
[] =
1844 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1845 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1846 .CollectionType
= 1,
1847 .NumberOfChildren
= 7,
1851 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1852 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1853 .CollectionType
= 2,
1856 static const HIDP_DATA expect_data
[] =
1858 { .DataIndex
= 0, },
1859 { .DataIndex
= 1, },
1860 { .DataIndex
= 5, .RawValue
= 1, },
1861 { .DataIndex
= 7, .RawValue
= 1, },
1862 { .DataIndex
= 19, .RawValue
= 1, },
1863 { .DataIndex
= 21, .RawValue
= 1, },
1864 { .DataIndex
= 30, },
1865 { .DataIndex
= 31, },
1866 { .DataIndex
= 32, .RawValue
= 0xfeedcafe, },
1867 { .DataIndex
= 37, .RawValue
= 1, },
1868 { .DataIndex
= 39, .RawValue
= 1, },
1871 HIDP_LINK_COLLECTION_NODE collections
[16];
1872 PHIDP_PREPARSED_DATA preparsed_data
;
1873 USAGE_AND_PAGE usage_and_pages
[16];
1874 HIDP_BUTTON_CAPS button_caps
[16];
1875 HIDP_VALUE_CAPS value_caps
[16];
1876 char buffer
[200], report
[200];
1877 DWORD collection_count
;
1878 DWORD waveform_list
;
1888 ret
= HidD_GetPreparsedData(file
, &preparsed_data
);
1889 ok(ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError());
1891 memset(buffer
, 0, sizeof(buffer
));
1892 status
= HidP_GetCaps((PHIDP_PREPARSED_DATA
)buffer
, &caps
);
1893 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetCaps returned %#x\n", status
);
1894 status
= HidP_GetCaps(preparsed_data
, &caps
);
1895 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetCaps returned %#x\n", status
);
1896 check_hidp_caps(&caps
, &expect_hidp_caps
[report_id
]);
1898 collection_count
= 0;
1899 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, preparsed_data
);
1900 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1901 ok(collection_count
== caps
.NumberLinkCollectionNodes
, "got %d collection nodes, expected %d\n",
1902 collection_count
, caps
.NumberLinkCollectionNodes
);
1903 collection_count
= ARRAY_SIZE(collections
);
1904 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, (PHIDP_PREPARSED_DATA
)buffer
);
1905 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1906 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, preparsed_data
);
1907 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1908 ok(collection_count
== caps
.NumberLinkCollectionNodes
, "got %d collection nodes, expected %d\n",
1909 collection_count
, caps
.NumberLinkCollectionNodes
);
1911 for (i
= 0; i
< ARRAY_SIZE(expect_collections
); ++i
)
1913 winetest_push_context("collections[%d]", i
);
1914 check_hidp_link_collection_node(&collections
[i
], &expect_collections
[i
]);
1915 winetest_pop_context();
1918 count
= ARRAY_SIZE(button_caps
);
1919 status
= HidP_GetButtonCaps(HidP_Output
, button_caps
, &count
, preparsed_data
);
1920 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetButtonCaps returned %#x\n", status
);
1921 status
= HidP_GetButtonCaps(HidP_Feature
+ 1, button_caps
, &count
, preparsed_data
);
1922 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetButtonCaps returned %#x\n", status
);
1924 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, preparsed_data
);
1925 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetButtonCaps returned %#x\n", status
);
1926 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1927 count
, caps
.NumberInputButtonCaps
);
1928 count
= ARRAY_SIZE(button_caps
);
1929 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1930 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetButtonCaps returned %#x\n", status
);
1931 memset(button_caps
, 0, sizeof(button_caps
));
1932 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, preparsed_data
);
1933 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetButtonCaps returned %#x\n", status
);
1934 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1935 count
, caps
.NumberInputButtonCaps
);
1937 for (i
= 0; i
< ARRAY_SIZE(expect_button_caps
); ++i
)
1939 winetest_push_context("button_caps[%d]", i
);
1940 check_hidp_button_caps(&button_caps
[i
], &expect_button_caps
[i
]);
1941 winetest_pop_context();
1944 count
= ARRAY_SIZE(button_caps
) - 1;
1945 status
= HidP_GetSpecificButtonCaps(HidP_Output
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1946 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1947 status
= HidP_GetSpecificButtonCaps(HidP_Feature
+ 1, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1948 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1950 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1951 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1952 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1953 count
, caps
.NumberInputButtonCaps
);
1954 count
= ARRAY_SIZE(button_caps
) - 1;
1955 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1956 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1958 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
+ 1, &count
, preparsed_data
);
1959 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1960 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1961 count
, caps
.NumberInputButtonCaps
);
1962 check_hidp_button_caps(&button_caps
[1], &button_caps
[0]);
1964 status
= HidP_GetSpecificButtonCaps(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, 5, button_caps
+ 1,
1965 &count
, preparsed_data
);
1966 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1967 ok(count
== 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 1);
1968 check_hidp_button_caps(&button_caps
[1], &button_caps
[0]);
1971 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0xfffe, 0, 0, button_caps
, &count
, preparsed_data
);
1972 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1973 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1975 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0xfffe, 0, button_caps
, &count
, preparsed_data
);
1976 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1977 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1979 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0xfffe, button_caps
, &count
, preparsed_data
);
1980 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1981 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1983 count
= ARRAY_SIZE(value_caps
);
1984 status
= HidP_GetValueCaps(HidP_Output
, value_caps
, &count
, preparsed_data
);
1985 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetValueCaps returned %#x\n", status
);
1986 status
= HidP_GetValueCaps(HidP_Feature
+ 1, value_caps
, &count
, preparsed_data
);
1987 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetValueCaps returned %#x\n", status
);
1989 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, preparsed_data
);
1990 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetValueCaps returned %#x\n", status
);
1991 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1992 count
, caps
.NumberInputValueCaps
);
1993 count
= ARRAY_SIZE(value_caps
);
1994 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1995 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetValueCaps returned %#x\n", status
);
1996 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, preparsed_data
);
1997 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetValueCaps returned %#x\n", status
);
1998 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1999 count
, caps
.NumberInputValueCaps
);
2001 for (i
= 0; i
< ARRAY_SIZE(expect_value_caps
); ++i
)
2003 winetest_push_context("value_caps[%d]", i
);
2004 check_hidp_value_caps(&value_caps
[i
], &expect_value_caps
[i
]);
2005 winetest_pop_context();
2008 count
= ARRAY_SIZE(value_caps
) - 4;
2009 status
= HidP_GetSpecificValueCaps(HidP_Output
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
2010 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2011 status
= HidP_GetSpecificValueCaps(HidP_Feature
+ 1, 0, 0, 0, value_caps
, &count
, preparsed_data
);
2012 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2014 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
2015 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2016 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
2017 count
, caps
.NumberInputValueCaps
);
2018 count
= ARRAY_SIZE(value_caps
) - 4;
2019 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
2020 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2022 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, preparsed_data
);
2023 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2024 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
2025 count
, caps
.NumberInputValueCaps
);
2026 check_hidp_value_caps(&value_caps
[4], &value_caps
[0]);
2027 check_hidp_value_caps(&value_caps
[5], &value_caps
[1]);
2028 check_hidp_value_caps(&value_caps
[6], &value_caps
[2]);
2029 check_hidp_value_caps(&value_caps
[7], &value_caps
[3]);
2032 status
= HidP_GetSpecificValueCaps(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
2033 value_caps
+ 4, &count
, preparsed_data
);
2034 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2035 ok(count
== 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 1);
2036 check_hidp_value_caps(&value_caps
[4], &value_caps
[3]);
2039 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0xfffe, 0, 0, value_caps
, &count
, preparsed_data
);
2040 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2041 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2043 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0xfffe, 0, value_caps
, &count
, preparsed_data
);
2044 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2045 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2047 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0xfffe, value_caps
, &count
, preparsed_data
);
2048 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2049 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2051 status
= HidP_InitializeReportForID(HidP_Input
, 0, (PHIDP_PREPARSED_DATA
)buffer
, report
, sizeof(report
));
2052 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_InitializeReportForID returned %#x\n", status
);
2053 status
= HidP_InitializeReportForID(HidP_Feature
+ 1, 0, preparsed_data
, report
, sizeof(report
));
2054 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_InitializeReportForID returned %#x\n", status
);
2055 status
= HidP_InitializeReportForID(HidP_Input
, 0, preparsed_data
, report
, sizeof(report
));
2056 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
2057 status
= HidP_InitializeReportForID(HidP_Input
, 0, preparsed_data
, report
, caps
.InputReportByteLength
+ 1);
2058 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
2059 status
= HidP_InitializeReportForID(HidP_Input
, 1 - report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2060 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2062 memset(report
, 0xcd, sizeof(report
));
2063 status
= HidP_InitializeReportForID(HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2064 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2066 memset(buffer
, 0xcd, sizeof(buffer
));
2067 memset(buffer
, 0, caps
.InputReportByteLength
);
2068 buffer
[0] = report_id
;
2069 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2071 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
2072 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
2073 ok(status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValueArray returned %#x\n", status
);
2074 memset(buffer
, 0xcd, sizeof(buffer
));
2075 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2076 0, preparsed_data
, report
, caps
.InputReportByteLength
);
2077 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2078 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2079 8, preparsed_data
, report
, caps
.InputReportByteLength
);
2081 ok(status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_SetUsageValueArray returned %#x\n", status
);
2083 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
2084 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
2085 ok(status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_GetUsageValueArray returned %#x\n", status
);
2086 memset(buffer
, 0xcd, sizeof(buffer
));
2087 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2088 0, preparsed_data
, report
, caps
.InputReportByteLength
);
2089 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2090 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2091 8, preparsed_data
, report
, caps
.InputReportByteLength
);
2093 ok(status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_GetUsageValueArray returned %#x\n", status
);
2096 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2097 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2098 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2100 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2101 &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2102 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2103 ok(value
== 0x80, "got value %x, expected %#x\n", value
, 0x80);
2105 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2106 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2107 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2108 ok(value
== -128, "got value %x, expected %#x\n", value
, -128);
2111 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2112 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2113 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2115 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2116 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2117 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2118 ok(value
== 127, "got value %x, expected %#x\n", value
, 127);
2121 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2122 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2123 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2125 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2126 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2127 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2128 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2131 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2132 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2133 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2135 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2136 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2137 ok(status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2138 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2140 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2141 &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2142 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2143 ok(value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff);
2146 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2147 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2148 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2150 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2151 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2152 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2153 ok(value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff);
2156 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2157 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2158 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2160 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2161 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2162 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2163 ok(value
== 0x80000000, "got value %x, expected %#x\n", value
, 0x80000000);
2166 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
2167 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2168 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2170 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
2171 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2172 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2173 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2176 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
2177 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2178 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2180 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
2181 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2182 ok(status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2183 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2185 value
= HidP_MaxUsageListLength(HidP_Feature
+ 1, 0, preparsed_data
);
2186 ok(value
== 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value
, 0);
2187 value
= HidP_MaxUsageListLength(HidP_Input
, 0, preparsed_data
);
2188 ok(value
== 42, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value
, 42);
2189 value
= HidP_MaxUsageListLength(HidP_Input
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
2190 ok(value
== 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value
, 32);
2191 value
= HidP_MaxUsageListLength(HidP_Input
, HID_USAGE_PAGE_LED
, preparsed_data
);
2192 ok(value
== 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value
, 8);
2193 value
= HidP_MaxUsageListLength(HidP_Feature
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
2194 ok(value
== 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value
, 8);
2195 value
= HidP_MaxUsageListLength(HidP_Feature
, HID_USAGE_PAGE_LED
, preparsed_data
);
2196 ok(value
== 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value
, 0);
2200 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2201 preparsed_data
, report
, caps
.InputReportByteLength
);
2202 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
2206 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2207 preparsed_data
, report
, caps
.InputReportByteLength
);
2208 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
2212 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2213 preparsed_data
, report
, caps
.InputReportByteLength
);
2214 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
2218 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
2219 report
, caps
.InputReportByteLength
);
2220 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
2226 ok(report
[6] == 0, "got report[6] %x expected 0\n", report
[6]);
2227 ok(report
[7] == 0, "got report[7] %x expected 0\n", report
[7]);
2228 memcpy(buffer
, report
, caps
.InputReportByteLength
);
2229 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
2230 report
, caps
.InputReportByteLength
);
2231 todo_wine
ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsages returned %#x\n", status
);
2234 todo_wine
ok(!memcmp(buffer
, report
, caps
.InputReportByteLength
), "unexpected report data\n");
2236 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, 1,
2237 preparsed_data
, report
, caps
.InputReportByteLength
);
2238 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2241 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, &value
,
2242 preparsed_data
, report
, caps
.InputReportByteLength
);
2243 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2244 ok(value
== 0xdeadbeef, "got value %x, expected %#x\n", value
, 0xdeadbeef);
2247 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2248 preparsed_data
, report
, caps
.InputReportByteLength
);
2249 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsages returned %#x\n", status
);
2250 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2251 value
= ARRAY_SIZE(usages
);
2252 memset(usages
, 0xcd, sizeof(usages
));
2253 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2254 preparsed_data
, report
, caps
.InputReportByteLength
);
2255 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
2256 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2257 ok(usages
[0] == 4, "got usages[0] %x, expected %x\n", usages
[0], 4);
2258 ok(usages
[1] == 6, "got usages[1] %x, expected %x\n", usages
[1], 6);
2260 value
= ARRAY_SIZE(usages
);
2261 memset(usages
, 0xcd, sizeof(usages
));
2262 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
2263 report
, caps
.InputReportByteLength
);
2264 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
2265 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2266 ok(usages
[0] == 6, "got usages[0] %x, expected %x\n", usages
[0], 6);
2267 ok(usages
[1] == 4, "got usages[1] %x, expected %x\n", usages
[1], 4);
2269 value
= ARRAY_SIZE(usage_and_pages
);
2270 memset(usage_and_pages
, 0xcd, sizeof(usage_and_pages
));
2271 status
= HidP_GetUsagesEx(HidP_Input
, 0, usage_and_pages
, &value
, preparsed_data
, report
,
2272 caps
.InputReportByteLength
);
2273 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsagesEx returned %#x\n", status
);
2274 todo_wine
ok(value
== 6, "got usage count %d, expected %d\n", value
, 4);
2275 ok(usage_and_pages
[0].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[0] UsagePage %x, expected %x\n",
2276 usage_and_pages
[0].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2277 ok(usage_and_pages
[1].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[1] UsagePage %x, expected %x\n",
2278 usage_and_pages
[1].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2279 ok(usage_and_pages
[2].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[2] UsagePage %x, expected %x\n",
2280 usage_and_pages
[2].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
2281 ok(usage_and_pages
[3].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[3] UsagePage %x, expected %x\n",
2282 usage_and_pages
[3].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
2284 ok(usage_and_pages
[4].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[4] UsagePage %x, expected %x\n",
2285 usage_and_pages
[4].UsagePage
, HID_USAGE_PAGE_LED
);
2286 ok(usage_and_pages
[5].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[5] UsagePage %x, expected %x\n",
2287 usage_and_pages
[5].UsagePage
, HID_USAGE_PAGE_LED
);
2288 ok(usage_and_pages
[0].Usage
== 4, "got usage_and_pages[0] Usage %x, expected %x\n",
2289 usage_and_pages
[0].Usage
, 4);
2290 ok(usage_and_pages
[1].Usage
== 6, "got usage_and_pages[1] Usage %x, expected %x\n",
2291 usage_and_pages
[1].Usage
, 6);
2292 ok(usage_and_pages
[2].Usage
== 9, "got usage_and_pages[2] Usage %x, expected %x\n",
2293 usage_and_pages
[2].Usage
, 9);
2295 ok(usage_and_pages
[3].Usage
== 11, "got usage_and_pages[3] Usage %x, expected %x\n",
2296 usage_and_pages
[3].Usage
, 11);
2298 ok(usage_and_pages
[4].Usage
== 6, "got usage_and_pages[4] Usage %x, expected %x\n",
2299 usage_and_pages
[4].Usage
, 6);
2301 ok(usage_and_pages
[5].Usage
== 4, "got usage_and_pages[5] Usage %x, expected %x\n",
2302 usage_and_pages
[5].Usage
, 4);
2304 value
= HidP_MaxDataListLength(HidP_Feature
+ 1, preparsed_data
);
2305 ok(value
== 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value
, 0);
2306 value
= HidP_MaxDataListLength(HidP_Input
, preparsed_data
);
2307 ok(value
== 50, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value
, 50);
2308 value
= HidP_MaxDataListLength(HidP_Output
, preparsed_data
);
2309 ok(value
== 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value
, 0);
2310 value
= HidP_MaxDataListLength(HidP_Feature
, preparsed_data
);
2311 ok(value
== 13, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value
, 13);
2314 status
= HidP_GetData(HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2315 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetData returned %#x\n", status
);
2316 todo_wine
ok(value
== 11, "got data count %d, expected %d\n", value
, 11);
2317 memset(data
, 0, sizeof(data
));
2318 status
= HidP_GetData(HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2319 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetData returned %#x\n", status
);
2320 for (i
= 0; i
< ARRAY_SIZE(expect_data
); ++i
)
2322 winetest_push_context("data[%d]", i
);
2323 todo_wine_if(i
>= 4) check_member(data
[i
], expect_data
[i
], "%d", DataIndex
);
2324 todo_wine_if(i
>= 4) check_member(data
[i
], expect_data
[i
], "%d", RawValue
);
2325 winetest_pop_context();
2328 memset(report
, 0xcd, sizeof(report
));
2329 status
= HidP_InitializeReportForID(HidP_Feature
, 3, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2330 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2332 memset(report
, 0xcd, sizeof(report
));
2333 status
= HidP_InitializeReportForID(HidP_Feature
, report_id
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2334 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2336 memset(buffer
, 0xcd, sizeof(buffer
));
2337 memset(buffer
, 0, caps
.FeatureReportByteLength
);
2338 buffer
[0] = report_id
;
2339 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2341 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
2343 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_HAPTICS
) continue;
2344 if (collections
[i
].LinkUsage
== HID_USAGE_HAPTICS_WAVEFORM_LIST
) break;
2346 ok(i
< caps
.NumberLinkCollectionNodes
,
2347 "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n");
2350 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2351 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, (PHIDP_PREPARSED_DATA
)buffer
,
2352 report
, caps
.FeatureReportByteLength
);
2353 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_SetUsageValue returned %#x\n", status
);
2354 status
= HidP_SetUsageValue(HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2355 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2356 caps
.FeatureReportByteLength
);
2357 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_SetUsageValue returned %#x\n", status
);
2358 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2359 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2360 caps
.FeatureReportByteLength
+ 1);
2361 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_SetUsageValue returned %#x\n", status
);
2362 report
[0] = 1 - report_id
;
2363 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2364 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2365 caps
.FeatureReportByteLength
);
2366 ok(status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2367 "HidP_SetUsageValue returned %#x\n", status
);
2369 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2370 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2371 caps
.FeatureReportByteLength
);
2372 ok(status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_SetUsageValue returned %#x\n", status
);
2373 report
[0] = report_id
;
2374 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
,
2375 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2376 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2378 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2379 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2380 caps
.FeatureReportByteLength
);
2381 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2383 memset(buffer
, 0xcd, sizeof(buffer
));
2384 memset(buffer
, 0, caps
.FeatureReportByteLength
);
2385 buffer
[0] = report_id
;
2386 value
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
2387 memcpy(buffer
+ 1, &value
, 2);
2388 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2390 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2391 (PHIDP_PREPARSED_DATA
)buffer
, report
, caps
.FeatureReportByteLength
);
2392 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetUsageValue returned %#x\n", status
);
2393 status
= HidP_GetUsageValue(HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2394 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2395 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetUsageValue returned %#x\n", status
);
2396 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2397 preparsed_data
, report
, caps
.FeatureReportByteLength
+ 1);
2398 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_GetUsageValue returned %#x\n", status
);
2399 report
[0] = 1 - report_id
;
2400 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2401 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2402 ok(status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2403 "HidP_GetUsageValue returned %#x\n", status
);
2405 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2406 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2407 ok(status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_GetUsageValue returned %#x\n", status
);
2408 report
[0] = report_id
;
2409 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, &value
,
2410 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2411 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#x\n", status
);
2414 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2415 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2416 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2417 ok(value
== HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, "got value %x, expected %#x\n", value
,
2418 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
);
2420 memset(buffer
, 0xff, sizeof(buffer
));
2421 status
= HidP_SetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2422 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2423 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2424 status
= HidP_SetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2425 64, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2426 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#x\n", status
);
2427 ok(!memcmp(report
+ 9, buffer
, 8), "unexpected report data\n");
2429 memset(buffer
, 0, sizeof(buffer
));
2430 status
= HidP_GetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2431 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2432 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2433 status
= HidP_GetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2434 64, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2435 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#x\n", status
);
2436 memset(buffer
+ 16, 0xff, 8);
2437 ok(!memcmp(buffer
, buffer
+ 16, 16), "unexpected report value\n");
2440 memset(report
, 0xcd, sizeof(report
));
2441 status
= HidP_InitializeReportForID(HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2442 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2444 SetLastError(0xdeadbeef);
2445 ret
= HidD_GetInputReport(file
, report
, 0);
2446 ok(!ret
, "HidD_GetInputReport succeeded\n");
2447 todo_wine
ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetInputReport returned error %u\n", GetLastError());
2449 SetLastError(0xdeadbeef);
2450 ret
= HidD_GetInputReport(file
, report
, caps
.InputReportByteLength
- 1);
2452 ok(!ret
, "HidD_GetInputReport succeeded\n");
2454 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2455 "HidD_GetInputReport returned error %u\n", GetLastError());
2457 SetLastError(0xdeadbeef);
2458 memset(buffer
, 0x5a, sizeof(buffer
));
2459 ret
= HidD_GetInputReport(file
, buffer
, caps
.InputReportByteLength
);
2460 if (report_id
|| broken(!ret
) /* w7u */)
2463 ok(!ret
, "HidD_GetInputReport succeeded, last error %u\n", GetLastError());
2465 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2466 "HidD_GetInputReport returned error %u\n", GetLastError());
2470 ok(ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError());
2471 todo_wine
ok(buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0]);
2474 SetLastError(0xdeadbeef);
2475 ret
= HidD_GetInputReport(file
, report
, caps
.InputReportByteLength
);
2476 ok(ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError());
2477 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2479 SetLastError(0xdeadbeef);
2480 value
= caps
.InputReportByteLength
* 2;
2481 ret
= sync_ioctl(file
, IOCTL_HID_GET_INPUT_REPORT
, NULL
, 0, report
, &value
);
2482 ok(ret
, "IOCTL_HID_GET_INPUT_REPORT failed, last error %u\n", GetLastError());
2483 todo_wine
ok(value
== 3, "got length %u, expected 3\n", value
);
2484 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2487 memset(report
, 0xcd, sizeof(report
));
2488 status
= HidP_InitializeReportForID(HidP_Feature
, report_id
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2489 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2491 SetLastError(0xdeadbeef);
2492 ret
= HidD_GetFeature(file
, report
, 0);
2493 ok(!ret
, "HidD_GetFeature succeeded\n");
2494 todo_wine
ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetFeature returned error %u\n", GetLastError());
2496 SetLastError(0xdeadbeef);
2497 ret
= HidD_GetFeature(file
, report
, caps
.FeatureReportByteLength
- 1);
2499 ok(!ret
, "HidD_GetFeature succeeded\n");
2501 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2502 "HidD_GetFeature returned error %u\n", GetLastError());
2504 SetLastError(0xdeadbeef);
2505 memset(buffer
, 0x5a, sizeof(buffer
));
2506 ret
= HidD_GetFeature(file
, buffer
, caps
.FeatureReportByteLength
);
2507 if (report_id
|| broken(!ret
))
2510 ok(!ret
, "HidD_GetFeature succeeded, last error %u\n", GetLastError());
2512 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2513 "HidD_GetFeature returned error %u\n", GetLastError());
2517 ok(ret
, "HidD_GetFeature failed, last error %u\n", GetLastError());
2518 todo_wine
ok(buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0]);
2521 SetLastError(0xdeadbeef);
2522 ret
= HidD_GetFeature(file
, report
, caps
.FeatureReportByteLength
);
2523 ok(ret
, "HidD_GetFeature failed, last error %u\n", GetLastError());
2524 todo_wine_if(!report_id
)
2525 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2527 value
= caps
.FeatureReportByteLength
* 2;
2528 SetLastError(0xdeadbeef);
2529 ret
= sync_ioctl(file
, IOCTL_HID_GET_FEATURE
, NULL
, 0, report
, &value
);
2530 ok(ret
, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError());
2531 todo_wine
ok(value
== 3, "got length %u, expected 3\n", value
);
2532 todo_wine_if(!report_id
)
2533 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2536 memset(report
, 0xcd, sizeof(report
));
2537 status
= HidP_InitializeReportForID(HidP_Feature
, report_id
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2538 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2540 SetLastError(0xdeadbeef);
2541 ret
= HidD_SetFeature(file
, report
, 0);
2542 todo_wine
ok(!ret
, "HidD_SetFeature succeeded\n");
2543 todo_wine
ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetFeature returned error %u\n", GetLastError());
2545 SetLastError(0xdeadbeef);
2546 ret
= HidD_SetFeature(file
, report
, caps
.FeatureReportByteLength
- 1);
2548 ok(!ret
, "HidD_SetFeature succeeded\n");
2550 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2551 "HidD_SetFeature returned error %u\n", GetLastError());
2553 SetLastError(0xdeadbeef);
2554 memset(buffer
, 0x5a, sizeof(buffer
));
2555 ret
= HidD_SetFeature(file
, buffer
, caps
.FeatureReportByteLength
);
2556 if (report_id
|| broken(!ret
))
2559 ok(!ret
, "HidD_SetFeature succeeded, last error %u\n", GetLastError());
2561 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2562 "HidD_SetFeature returned error %u\n", GetLastError());
2566 ok(ret
, "HidD_SetFeature failed, last error %u\n", GetLastError());
2569 SetLastError(0xdeadbeef);
2570 ret
= HidD_SetFeature(file
, report
, caps
.FeatureReportByteLength
);
2571 ok(ret
, "HidD_SetFeature failed, last error %u\n", GetLastError());
2573 value
= caps
.FeatureReportByteLength
* 2;
2574 SetLastError(0xdeadbeef);
2575 ret
= sync_ioctl(file
, IOCTL_HID_SET_FEATURE
, NULL
, 0, report
, &value
);
2576 todo_wine
ok(!ret
, "IOCTL_HID_SET_FEATURE succeeded\n");
2577 todo_wine
ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_FEATURE returned error %u\n", GetLastError());
2579 SetLastError(0xdeadbeef);
2580 ret
= sync_ioctl(file
, IOCTL_HID_SET_FEATURE
, report
, caps
.FeatureReportByteLength
* 2, NULL
, &value
);
2581 ok(ret
, "IOCTL_HID_SET_FEATURE failed, last error %u\n", GetLastError());
2582 todo_wine
ok(value
== 3, "got length %u, expected 3\n", value
);
2585 memset(report
, 0xcd, sizeof(report
));
2586 status
= HidP_InitializeReportForID(HidP_Output
, report_id
, preparsed_data
, report
, caps
.OutputReportByteLength
);
2587 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2588 memset(report
, 0, caps
.OutputReportByteLength
);
2589 report
[0] = report_id
;
2591 SetLastError(0xdeadbeef);
2592 ret
= HidD_SetOutputReport(file
, report
, 0);
2593 todo_wine
ok(!ret
, "HidD_SetOutputReport succeeded\n");
2594 todo_wine
ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetOutputReport returned error %u\n", GetLastError());
2596 SetLastError(0xdeadbeef);
2597 ret
= HidD_SetOutputReport(file
, report
, caps
.OutputReportByteLength
- 1);
2599 ok(!ret
, "HidD_SetOutputReport succeeded\n");
2601 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2602 "HidD_SetOutputReport returned error %u\n", GetLastError());
2604 SetLastError(0xdeadbeef);
2605 memset(buffer
, 0x5a, sizeof(buffer
));
2606 ret
= HidD_SetOutputReport(file
, buffer
, caps
.OutputReportByteLength
);
2607 if (report_id
|| broken(!ret
))
2610 ok(!ret
, "HidD_SetOutputReport succeeded, last error %u\n", GetLastError());
2612 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2613 "HidD_SetOutputReport returned error %u\n", GetLastError());
2617 ok(ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError());
2620 SetLastError(0xdeadbeef);
2621 ret
= HidD_SetOutputReport(file
, report
, caps
.OutputReportByteLength
);
2622 ok(ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError());
2624 value
= caps
.OutputReportByteLength
* 2;
2625 SetLastError(0xdeadbeef);
2626 ret
= sync_ioctl(file
, IOCTL_HID_SET_OUTPUT_REPORT
, NULL
, 0, report
, &value
);
2627 todo_wine
ok(!ret
, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n");
2628 todo_wine
ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError());
2630 SetLastError(0xdeadbeef);
2631 ret
= sync_ioctl(file
, IOCTL_HID_SET_OUTPUT_REPORT
, report
, caps
.OutputReportByteLength
* 2, NULL
, &value
);
2632 ok(ret
, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError());
2633 todo_wine
ok(value
== 3, "got length %u, expected 3\n", value
);
2636 HidD_FreePreparsedData(preparsed_data
);
2640 static void test_hid_device(DWORD report_id
, DWORD polled
)
2643 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*iface_detail
= (void *)buffer
;
2644 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(iface
)};
2645 SP_DEVINFO_DATA device
= {sizeof(device
)};
2646 BOOL ret
, found
= FALSE
;
2647 OBJECT_ATTRIBUTES attr
;
2648 UNICODE_STRING string
;
2655 winetest_push_context("report %d, polled %d", report_id
, polled
);
2657 set
= SetupDiGetClassDevsA(&GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
2658 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
2660 for (i
= 0; SetupDiEnumDeviceInfo(set
, i
, &device
); ++i
)
2662 ret
= SetupDiEnumDeviceInterfaces(set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
2663 ok(ret
, "failed to get interface, error %#x\n", GetLastError());
2664 ok(IsEqualGUID(&iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
),
2665 "wrong class %s\n", debugstr_guid(&iface
.InterfaceClassGuid
));
2666 ok(iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
2668 iface_detail
->cbSize
= sizeof(*iface_detail
);
2669 ret
= SetupDiGetDeviceInterfaceDetailA(set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
2670 ok(ret
, "failed to get interface path, error %#x\n", GetLastError());
2672 if (strstr(iface_detail
->DevicePath
, "\\\\?\\hid#winetest#1"))
2679 SetupDiDestroyDeviceInfoList(set
);
2681 todo_wine
ok(found
, "didn't find device\n");
2683 file
= CreateFileA(iface_detail
->DevicePath
, FILE_READ_ACCESS
,
2684 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
2685 ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
2687 test_hidp(file
, report_id
);
2691 RtlInitUnicodeString(&string
, L
"\\??\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}");
2692 InitializeObjectAttributes(&attr
, &string
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
2693 status
= NtOpenFile(&file
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
2694 todo_wine
ok(status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
2696 winetest_pop_context();
2699 static void test_hid_driver(struct testsign_context
*ctx
, DWORD report_id
, DWORD polled
)
2701 static const char hardware_id
[] = "test_hardware_id\0";
2702 char path
[MAX_PATH
], dest
[MAX_PATH
], *filepart
;
2703 SP_DEVINFO_DATA device
= {sizeof(device
)};
2704 char cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
2705 WCHAR driver_filename
[MAX_PATH
];
2706 SC_HANDLE manager
, service
;
2707 BOOL ret
, need_reboot
;
2708 HANDLE catalog
, file
;
2714 GetCurrentDirectoryA(ARRAY_SIZE(cwd
), cwd
);
2715 GetTempPathA(ARRAY_SIZE(tempdir
), tempdir
);
2716 SetCurrentDirectoryA(tempdir
);
2718 status
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest", 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
2719 ok(!status
, "RegCreateKeyExW returned %#x\n", status
);
2721 status
= RegSetValueExW(hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
));
2722 ok(!status
, "RegSetValueExW returned %#x\n", status
);
2724 status
= RegSetValueExW(hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
));
2725 ok(!status
, "RegSetValueExW returned %#x\n", status
);
2727 load_resource(L
"driver_hid.dll", driver_filename
);
2728 ret
= MoveFileExW(driver_filename
, L
"winetest.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
2729 ok(ret
, "failed to move file, error %u\n", GetLastError());
2731 f
= fopen("winetest.inf", "w");
2732 ok(!!f
, "failed to open winetest.inf: %s\n", strerror(errno
));
2736 /* Create the catalog file. */
2738 catalog
= CryptCATOpen((WCHAR
*)L
"winetest.cat", CRYPTCAT_OPEN_CREATENEW
, 0, CRYPTCAT_VERSION_1
, 0);
2739 ok(catalog
!= INVALID_HANDLE_VALUE
, "Failed to create catalog, error %#x\n", GetLastError());
2741 add_file_to_catalog(catalog
, L
"winetest.sys");
2742 add_file_to_catalog(catalog
, L
"winetest.inf");
2744 ret
= CryptCATPersistStore(catalog
);
2745 todo_wine
ok(ret
, "Failed to write catalog, error %u\n", GetLastError());
2747 ret
= CryptCATClose(catalog
);
2748 ok(ret
, "Failed to close catalog, error %u\n", GetLastError());
2750 testsign_sign(ctx
, L
"winetest.cat");
2752 /* Install the driver. */
2754 set
= SetupDiCreateDeviceInfoList(NULL
, NULL
);
2755 ok(set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %#x\n", GetLastError());
2757 ret
= SetupDiCreateDeviceInfoA(set
, "root\\winetest\\0", &GUID_NULL
, NULL
, NULL
, 0, &device
);
2758 ok(ret
, "failed to create device, error %#x\n", GetLastError());
2760 ret
= SetupDiSetDeviceRegistryPropertyA( set
, &device
, SPDRP_HARDWAREID
,
2761 (const BYTE
*)hardware_id
, sizeof(hardware_id
) );
2762 ok(ret
, "failed to create set hardware ID, error %#x\n", GetLastError());
2764 ret
= SetupDiCallClassInstaller(DIF_REGISTERDEVICE
, set
, &device
);
2765 ok(ret
, "failed to register device, error %#x\n", GetLastError());
2767 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
2768 ret
= UpdateDriverForPlugAndPlayDevicesA(NULL
, hardware_id
, path
, INSTALLFLAG_FORCE
, &need_reboot
);
2769 ok(ret
, "failed to install device, error %#x\n", GetLastError());
2770 ok(!need_reboot
, "expected no reboot necessary\n");
2774 test_hid_device(report_id
, polled
);
2778 ret
= SetupDiCallClassInstaller(DIF_REMOVE
, set
, &device
);
2779 ok(ret
, "failed to remove device, error %#x\n", GetLastError());
2781 file
= CreateFileA("\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2782 ok(file
== INVALID_HANDLE_VALUE
, "expected failure\n");
2783 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %u\n", GetLastError());
2785 ret
= SetupDiDestroyDeviceInfoList(set
);
2786 ok(ret
, "failed to destroy set, error %#x\n", GetLastError());
2788 /* Windows stops the service but does not delete it. */
2789 manager
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
2790 ok(!!manager
, "failed to open service manager, error %u\n", GetLastError());
2791 service
= OpenServiceA(manager
, "winetest", SERVICE_STOP
| DELETE
);
2792 ok(!!service
, "failed to open service, error %u\n", GetLastError());
2793 unload_driver(service
);
2794 CloseServiceHandle(manager
);
2798 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
2799 ret
= SetupCopyOEMInfA(path
, NULL
, 0, 0, dest
, sizeof(dest
), NULL
, &filepart
);
2800 ok(ret
, "Failed to copy INF, error %#x\n", GetLastError());
2801 ret
= SetupUninstallOEMInfA(filepart
, 0, NULL
);
2802 ok(ret
, "Failed to uninstall INF, error %u\n", GetLastError());
2804 ret
= DeleteFileA("winetest.cat");
2805 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2806 ret
= DeleteFileA("winetest.inf");
2807 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2808 ret
= DeleteFileA("winetest.sys");
2809 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2810 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
2811 ret
= DeleteFileA("C:/windows/system32/drivers/winetest.sys");
2812 ok(ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %u\n", GetLastError());
2814 SetCurrentDirectoryA(cwd
);
2817 START_TEST(ntoskrnl
)
2819 WCHAR filename
[MAX_PATH
], filename2
[MAX_PATH
];
2820 struct testsign_context ctx
;
2821 SC_HANDLE service
, service2
;
2826 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U");
2827 pRtlFreeUnicodeString
= (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString");
2828 pCancelIoEx
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx");
2829 pIsWow64Process
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
2830 pSetFileCompletionNotificationModes
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"),
2831 "SetFileCompletionNotificationModes");
2832 pSignerSign
= (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
2834 if (IsWow64Process(GetCurrentProcess(), &is_wow64
) && is_wow64
)
2836 skip("Running in WoW64.\n");
2840 if (!testsign_create_cert(&ctx
))
2843 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
,
2844 0, sizeof(*test_data
), "Global\\winetest_ntoskrnl_section");
2845 ok(!!mapping
, "got error %u\n", GetLastError());
2846 test_data
= MapViewOfFile(mapping
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 1024);
2847 test_data
->running_under_wine
= !strcmp(winetest_platform
, "wine");
2848 test_data
->winetest_report_success
= winetest_report_success
;
2849 test_data
->winetest_debug
= winetest_debug
;
2851 okfile
= CreateFileA("C:\\windows\\winetest_ntoskrnl_okfile", GENERIC_READ
| GENERIC_WRITE
,
2852 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
2853 ok(okfile
!= INVALID_HANDLE_VALUE
, "failed to create file, error %u\n", GetLastError());
2856 if (!(service
= load_driver(&ctx
, filename
, L
"driver.dll", L
"WineTestDriver")))
2859 if (!start_driver(service
, FALSE
))
2861 DeleteFileW(filename
);
2864 service2
= load_driver(&ctx
, filename2
, L
"driver2.dll", L
"WineTestDriver2");
2866 device
= CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2867 ok(device
!= INVALID_HANDLE_VALUE
, "failed to open device: %u\n", GetLastError());
2870 test_mismatched_status_ioctl();
2873 todo_wine
ok(modified_value
== 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value
);
2876 test_load_driver(service2
);
2877 test_file_handles();
2878 test_return_status();
2881 /* We need a separate ioctl to call IoDetachDevice(); calling it in the
2882 * driver unload routine causes a live-lock. */
2883 ret
= DeviceIoControl(device
, IOCTL_WINETEST_DETACH
, NULL
, 0, NULL
, 0, &written
, NULL
);
2884 ok(ret
, "DeviceIoControl failed: %u\n", GetLastError());
2886 CloseHandle(device
);
2888 unload_driver(service2
);
2889 unload_driver(service
);
2890 ret
= DeleteFileW(filename
);
2891 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
2892 ret
= DeleteFileW(filename2
);
2893 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
2898 subtest("driver_netio");
2899 test_driver_netio(&ctx
);
2901 subtest("driver_pnp");
2902 test_pnp_driver(&ctx
);
2904 subtest("driver_hid");
2905 test_hid_driver(&ctx
, 0, FALSE
);
2906 test_hid_driver(&ctx
, 1, FALSE
);
2907 test_hid_driver(&ctx
, 0, TRUE
);
2908 test_hid_driver(&ctx
, 1, TRUE
);
2911 testsign_cleanup(&ctx
);
2912 UnmapViewOfFile(test_data
);
2913 CloseHandle(mapping
);
2914 CloseHandle(okfile
);
2915 DeleteFileA("C:\\windows\\winetest_ntoskrnl_okfile");