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
, HANDLE async_file
, int report_id
, BOOL polled
)
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 OVERLAPPED overlapped
= {0}, overlapped2
= {0};
1872 HIDP_LINK_COLLECTION_NODE collections
[16];
1873 PHIDP_PREPARSED_DATA preparsed_data
;
1874 USAGE_AND_PAGE usage_and_pages
[16];
1875 HIDP_BUTTON_CAPS button_caps
[16];
1876 HIDP_VALUE_CAPS value_caps
[16];
1877 char buffer
[200], report
[200];
1878 DWORD collection_count
;
1879 DWORD waveform_list
;
1889 ret
= HidD_GetPreparsedData(file
, &preparsed_data
);
1890 ok(ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError());
1892 memset(buffer
, 0, sizeof(buffer
));
1893 status
= HidP_GetCaps((PHIDP_PREPARSED_DATA
)buffer
, &caps
);
1894 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetCaps returned %#x\n", status
);
1895 status
= HidP_GetCaps(preparsed_data
, &caps
);
1896 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetCaps returned %#x\n", status
);
1897 check_hidp_caps(&caps
, &expect_hidp_caps
[report_id
]);
1899 collection_count
= 0;
1900 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, preparsed_data
);
1901 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1902 ok(collection_count
== caps
.NumberLinkCollectionNodes
, "got %d collection nodes, expected %d\n",
1903 collection_count
, caps
.NumberLinkCollectionNodes
);
1904 collection_count
= ARRAY_SIZE(collections
);
1905 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, (PHIDP_PREPARSED_DATA
)buffer
);
1906 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1907 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, preparsed_data
);
1908 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1909 ok(collection_count
== caps
.NumberLinkCollectionNodes
, "got %d collection nodes, expected %d\n",
1910 collection_count
, caps
.NumberLinkCollectionNodes
);
1912 for (i
= 0; i
< ARRAY_SIZE(expect_collections
); ++i
)
1914 winetest_push_context("collections[%d]", i
);
1915 check_hidp_link_collection_node(&collections
[i
], &expect_collections
[i
]);
1916 winetest_pop_context();
1919 count
= ARRAY_SIZE(button_caps
);
1920 status
= HidP_GetButtonCaps(HidP_Output
, button_caps
, &count
, preparsed_data
);
1921 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetButtonCaps returned %#x\n", status
);
1922 status
= HidP_GetButtonCaps(HidP_Feature
+ 1, button_caps
, &count
, preparsed_data
);
1923 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetButtonCaps returned %#x\n", status
);
1925 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, preparsed_data
);
1926 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetButtonCaps returned %#x\n", status
);
1927 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1928 count
, caps
.NumberInputButtonCaps
);
1929 count
= ARRAY_SIZE(button_caps
);
1930 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1931 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetButtonCaps returned %#x\n", status
);
1932 memset(button_caps
, 0, sizeof(button_caps
));
1933 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, preparsed_data
);
1934 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetButtonCaps returned %#x\n", status
);
1935 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1936 count
, caps
.NumberInputButtonCaps
);
1938 for (i
= 0; i
< ARRAY_SIZE(expect_button_caps
); ++i
)
1940 winetest_push_context("button_caps[%d]", i
);
1941 check_hidp_button_caps(&button_caps
[i
], &expect_button_caps
[i
]);
1942 winetest_pop_context();
1945 count
= ARRAY_SIZE(button_caps
) - 1;
1946 status
= HidP_GetSpecificButtonCaps(HidP_Output
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1947 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1948 status
= HidP_GetSpecificButtonCaps(HidP_Feature
+ 1, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1949 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1951 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1952 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1953 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1954 count
, caps
.NumberInputButtonCaps
);
1955 count
= ARRAY_SIZE(button_caps
) - 1;
1956 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1957 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1959 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
+ 1, &count
, preparsed_data
);
1960 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1961 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1962 count
, caps
.NumberInputButtonCaps
);
1963 check_hidp_button_caps(&button_caps
[1], &button_caps
[0]);
1965 status
= HidP_GetSpecificButtonCaps(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, 5, button_caps
+ 1,
1966 &count
, preparsed_data
);
1967 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1968 ok(count
== 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 1);
1969 check_hidp_button_caps(&button_caps
[1], &button_caps
[0]);
1972 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0xfffe, 0, 0, button_caps
, &count
, preparsed_data
);
1973 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1974 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1976 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0xfffe, 0, button_caps
, &count
, preparsed_data
);
1977 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1978 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1980 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0xfffe, button_caps
, &count
, preparsed_data
);
1981 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1982 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1984 count
= ARRAY_SIZE(value_caps
);
1985 status
= HidP_GetValueCaps(HidP_Output
, value_caps
, &count
, preparsed_data
);
1986 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetValueCaps returned %#x\n", status
);
1987 status
= HidP_GetValueCaps(HidP_Feature
+ 1, value_caps
, &count
, preparsed_data
);
1988 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetValueCaps returned %#x\n", status
);
1990 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, preparsed_data
);
1991 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetValueCaps returned %#x\n", status
);
1992 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1993 count
, caps
.NumberInputValueCaps
);
1994 count
= ARRAY_SIZE(value_caps
);
1995 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1996 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetValueCaps returned %#x\n", status
);
1997 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, preparsed_data
);
1998 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetValueCaps returned %#x\n", status
);
1999 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
2000 count
, caps
.NumberInputValueCaps
);
2002 for (i
= 0; i
< ARRAY_SIZE(expect_value_caps
); ++i
)
2004 winetest_push_context("value_caps[%d]", i
);
2005 check_hidp_value_caps(&value_caps
[i
], &expect_value_caps
[i
]);
2006 winetest_pop_context();
2009 count
= ARRAY_SIZE(value_caps
) - 4;
2010 status
= HidP_GetSpecificValueCaps(HidP_Output
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
2011 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2012 status
= HidP_GetSpecificValueCaps(HidP_Feature
+ 1, 0, 0, 0, value_caps
, &count
, preparsed_data
);
2013 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2015 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
2016 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2017 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
2018 count
, caps
.NumberInputValueCaps
);
2019 count
= ARRAY_SIZE(value_caps
) - 4;
2020 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
2021 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2023 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, preparsed_data
);
2024 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2025 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
2026 count
, caps
.NumberInputValueCaps
);
2027 check_hidp_value_caps(&value_caps
[4], &value_caps
[0]);
2028 check_hidp_value_caps(&value_caps
[5], &value_caps
[1]);
2029 check_hidp_value_caps(&value_caps
[6], &value_caps
[2]);
2030 check_hidp_value_caps(&value_caps
[7], &value_caps
[3]);
2033 status
= HidP_GetSpecificValueCaps(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
2034 value_caps
+ 4, &count
, preparsed_data
);
2035 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2036 ok(count
== 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 1);
2037 check_hidp_value_caps(&value_caps
[4], &value_caps
[3]);
2040 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0xfffe, 0, 0, value_caps
, &count
, preparsed_data
);
2041 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2042 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2044 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0xfffe, 0, value_caps
, &count
, preparsed_data
);
2045 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2046 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2048 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0xfffe, value_caps
, &count
, preparsed_data
);
2049 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2050 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2052 status
= HidP_InitializeReportForID(HidP_Input
, 0, (PHIDP_PREPARSED_DATA
)buffer
, report
, sizeof(report
));
2053 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_InitializeReportForID returned %#x\n", status
);
2054 status
= HidP_InitializeReportForID(HidP_Feature
+ 1, 0, preparsed_data
, report
, sizeof(report
));
2055 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_InitializeReportForID returned %#x\n", status
);
2056 status
= HidP_InitializeReportForID(HidP_Input
, 0, preparsed_data
, report
, sizeof(report
));
2057 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
2058 status
= HidP_InitializeReportForID(HidP_Input
, 0, preparsed_data
, report
, caps
.InputReportByteLength
+ 1);
2059 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
2060 status
= HidP_InitializeReportForID(HidP_Input
, 1 - report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2061 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2063 memset(report
, 0xcd, sizeof(report
));
2064 status
= HidP_InitializeReportForID(HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2065 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2067 memset(buffer
, 0xcd, sizeof(buffer
));
2068 memset(buffer
, 0, caps
.InputReportByteLength
);
2069 buffer
[0] = report_id
;
2070 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2072 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
2073 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
2074 ok(status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValueArray returned %#x\n", status
);
2075 memset(buffer
, 0xcd, sizeof(buffer
));
2076 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2077 0, preparsed_data
, report
, caps
.InputReportByteLength
);
2078 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2079 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2080 8, preparsed_data
, report
, caps
.InputReportByteLength
);
2082 ok(status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_SetUsageValueArray returned %#x\n", status
);
2084 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
2085 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
2086 ok(status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_GetUsageValueArray returned %#x\n", status
);
2087 memset(buffer
, 0xcd, sizeof(buffer
));
2088 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2089 0, preparsed_data
, report
, caps
.InputReportByteLength
);
2090 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2091 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2092 8, preparsed_data
, report
, caps
.InputReportByteLength
);
2094 ok(status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_GetUsageValueArray returned %#x\n", status
);
2097 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2098 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2099 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2101 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2102 &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2103 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2104 ok(value
== 0x80, "got value %x, expected %#x\n", value
, 0x80);
2106 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2107 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2108 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2109 ok(value
== -128, "got value %x, expected %#x\n", value
, -128);
2112 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2113 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2114 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2116 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2117 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2118 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2119 ok(value
== 127, "got value %x, expected %#x\n", value
, 127);
2122 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2123 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2124 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2126 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2127 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2128 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2129 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2132 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2133 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2134 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2136 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2137 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2138 ok(status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2139 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2141 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2142 &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2143 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2144 ok(value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff);
2147 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2148 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2149 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2151 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2152 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2153 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2154 ok(value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff);
2157 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2158 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2159 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2161 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2162 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2163 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2164 ok(value
== 0x80000000, "got value %x, expected %#x\n", value
, 0x80000000);
2167 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
2168 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2169 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2171 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
2172 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2173 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2174 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2177 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
2178 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2179 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2181 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
2182 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2183 ok(status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2184 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2186 value
= HidP_MaxUsageListLength(HidP_Feature
+ 1, 0, preparsed_data
);
2187 ok(value
== 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value
, 0);
2188 value
= HidP_MaxUsageListLength(HidP_Input
, 0, preparsed_data
);
2189 ok(value
== 42, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value
, 42);
2190 value
= HidP_MaxUsageListLength(HidP_Input
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
2191 ok(value
== 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value
, 32);
2192 value
= HidP_MaxUsageListLength(HidP_Input
, HID_USAGE_PAGE_LED
, preparsed_data
);
2193 ok(value
== 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value
, 8);
2194 value
= HidP_MaxUsageListLength(HidP_Feature
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
2195 ok(value
== 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value
, 8);
2196 value
= HidP_MaxUsageListLength(HidP_Feature
, HID_USAGE_PAGE_LED
, preparsed_data
);
2197 ok(value
== 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value
, 0);
2201 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2202 preparsed_data
, report
, caps
.InputReportByteLength
);
2203 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
2207 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2208 preparsed_data
, report
, caps
.InputReportByteLength
);
2209 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
2213 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2214 preparsed_data
, report
, caps
.InputReportByteLength
);
2215 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
2219 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
2220 report
, caps
.InputReportByteLength
);
2221 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
2227 ok(report
[6] == 0, "got report[6] %x expected 0\n", report
[6]);
2228 ok(report
[7] == 0, "got report[7] %x expected 0\n", report
[7]);
2229 memcpy(buffer
, report
, caps
.InputReportByteLength
);
2230 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
2231 report
, caps
.InputReportByteLength
);
2232 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsages returned %#x\n", status
);
2235 ok(!memcmp(buffer
, report
, caps
.InputReportByteLength
), "unexpected report data\n");
2237 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, 1,
2238 preparsed_data
, report
, caps
.InputReportByteLength
);
2239 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2242 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, &value
,
2243 preparsed_data
, report
, caps
.InputReportByteLength
);
2244 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2245 ok(value
== 0xdeadbeef, "got value %x, expected %#x\n", value
, 0xdeadbeef);
2248 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2249 preparsed_data
, report
, caps
.InputReportByteLength
);
2250 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsages returned %#x\n", status
);
2251 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2252 value
= ARRAY_SIZE(usages
);
2253 memset(usages
, 0xcd, sizeof(usages
));
2254 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2255 preparsed_data
, report
, caps
.InputReportByteLength
);
2256 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
2257 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2258 ok(usages
[0] == 4, "got usages[0] %x, expected %x\n", usages
[0], 4);
2259 ok(usages
[1] == 6, "got usages[1] %x, expected %x\n", usages
[1], 6);
2261 value
= ARRAY_SIZE(usages
);
2262 memset(usages
, 0xcd, sizeof(usages
));
2263 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
2264 report
, caps
.InputReportByteLength
);
2265 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
2266 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2267 ok(usages
[0] == 6, "got usages[0] %x, expected %x\n", usages
[0], 6);
2268 ok(usages
[1] == 4, "got usages[1] %x, expected %x\n", usages
[1], 4);
2270 value
= ARRAY_SIZE(usage_and_pages
);
2271 memset(usage_and_pages
, 0xcd, sizeof(usage_and_pages
));
2272 status
= HidP_GetUsagesEx(HidP_Input
, 0, usage_and_pages
, &value
, preparsed_data
, report
,
2273 caps
.InputReportByteLength
);
2274 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsagesEx returned %#x\n", status
);
2275 ok(value
== 6, "got usage count %d, expected %d\n", value
, 4);
2276 ok(usage_and_pages
[0].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[0] UsagePage %x, expected %x\n",
2277 usage_and_pages
[0].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2278 ok(usage_and_pages
[1].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[1] UsagePage %x, expected %x\n",
2279 usage_and_pages
[1].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2280 ok(usage_and_pages
[2].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[2] UsagePage %x, expected %x\n",
2281 usage_and_pages
[2].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
2282 ok(usage_and_pages
[3].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[3] UsagePage %x, expected %x\n",
2283 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);
2294 ok(usage_and_pages
[3].Usage
== 11, "got usage_and_pages[3] Usage %x, expected %x\n",
2295 usage_and_pages
[3].Usage
, 11);
2296 ok(usage_and_pages
[4].Usage
== 6, "got usage_and_pages[4] Usage %x, expected %x\n",
2297 usage_and_pages
[4].Usage
, 6);
2298 ok(usage_and_pages
[5].Usage
== 4, "got usage_and_pages[5] Usage %x, expected %x\n",
2299 usage_and_pages
[5].Usage
, 4);
2301 value
= HidP_MaxDataListLength(HidP_Feature
+ 1, preparsed_data
);
2302 ok(value
== 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value
, 0);
2303 value
= HidP_MaxDataListLength(HidP_Input
, preparsed_data
);
2304 ok(value
== 50, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value
, 50);
2305 value
= HidP_MaxDataListLength(HidP_Output
, preparsed_data
);
2306 ok(value
== 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value
, 0);
2307 value
= HidP_MaxDataListLength(HidP_Feature
, preparsed_data
);
2308 ok(value
== 13, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value
, 13);
2311 status
= HidP_GetData(HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2312 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetData returned %#x\n", status
);
2313 ok(value
== 11, "got data count %d, expected %d\n", value
, 11);
2314 memset(data
, 0, sizeof(data
));
2315 status
= HidP_GetData(HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2316 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetData returned %#x\n", status
);
2317 for (i
= 0; i
< ARRAY_SIZE(expect_data
); ++i
)
2319 winetest_push_context("data[%d]", i
);
2320 check_member(data
[i
], expect_data
[i
], "%d", DataIndex
);
2321 check_member(data
[i
], expect_data
[i
], "%d", RawValue
);
2322 winetest_pop_context();
2325 memset(report
, 0xcd, sizeof(report
));
2326 status
= HidP_InitializeReportForID(HidP_Feature
, 3, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2327 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2329 memset(report
, 0xcd, sizeof(report
));
2330 status
= HidP_InitializeReportForID(HidP_Feature
, report_id
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2331 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2333 memset(buffer
, 0xcd, sizeof(buffer
));
2334 memset(buffer
, 0, caps
.FeatureReportByteLength
);
2335 buffer
[0] = report_id
;
2336 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2338 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
2340 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_HAPTICS
) continue;
2341 if (collections
[i
].LinkUsage
== HID_USAGE_HAPTICS_WAVEFORM_LIST
) break;
2343 ok(i
< caps
.NumberLinkCollectionNodes
,
2344 "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n");
2347 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2348 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, (PHIDP_PREPARSED_DATA
)buffer
,
2349 report
, caps
.FeatureReportByteLength
);
2350 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_SetUsageValue returned %#x\n", status
);
2351 status
= HidP_SetUsageValue(HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2352 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2353 caps
.FeatureReportByteLength
);
2354 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_SetUsageValue returned %#x\n", status
);
2355 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2356 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2357 caps
.FeatureReportByteLength
+ 1);
2358 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_SetUsageValue returned %#x\n", status
);
2359 report
[0] = 1 - report_id
;
2360 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2361 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2362 caps
.FeatureReportByteLength
);
2363 ok(status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2364 "HidP_SetUsageValue returned %#x\n", status
);
2366 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2367 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2368 caps
.FeatureReportByteLength
);
2369 ok(status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_SetUsageValue returned %#x\n", status
);
2370 report
[0] = report_id
;
2371 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
,
2372 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2373 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2375 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2376 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2377 caps
.FeatureReportByteLength
);
2378 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2380 memset(buffer
, 0xcd, sizeof(buffer
));
2381 memset(buffer
, 0, caps
.FeatureReportByteLength
);
2382 buffer
[0] = report_id
;
2383 value
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
2384 memcpy(buffer
+ 1, &value
, 2);
2385 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2387 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2388 (PHIDP_PREPARSED_DATA
)buffer
, report
, caps
.FeatureReportByteLength
);
2389 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetUsageValue returned %#x\n", status
);
2390 status
= HidP_GetUsageValue(HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2391 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2392 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetUsageValue returned %#x\n", status
);
2393 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2394 preparsed_data
, report
, caps
.FeatureReportByteLength
+ 1);
2395 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_GetUsageValue returned %#x\n", status
);
2396 report
[0] = 1 - report_id
;
2397 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2398 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2399 ok(status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2400 "HidP_GetUsageValue returned %#x\n", status
);
2402 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2403 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2404 ok(status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_GetUsageValue returned %#x\n", status
);
2405 report
[0] = report_id
;
2406 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, &value
,
2407 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2408 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#x\n", status
);
2411 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2412 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2413 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2414 ok(value
== HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, "got value %x, expected %#x\n", value
,
2415 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
);
2417 memset(buffer
, 0xff, sizeof(buffer
));
2418 status
= HidP_SetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2419 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2420 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2421 status
= HidP_SetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2422 64, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2423 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#x\n", status
);
2424 ok(!memcmp(report
+ 9, buffer
, 8), "unexpected report data\n");
2426 memset(buffer
, 0, sizeof(buffer
));
2427 status
= HidP_GetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2428 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2429 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2430 status
= HidP_GetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2431 64, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2432 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#x\n", status
);
2433 memset(buffer
+ 16, 0xff, 8);
2434 ok(!memcmp(buffer
, buffer
+ 16, 16), "unexpected report value\n");
2437 memset(report
, 0xcd, sizeof(report
));
2438 status
= HidP_InitializeReportForID(HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2439 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2441 SetLastError(0xdeadbeef);
2442 ret
= HidD_GetInputReport(file
, report
, 0);
2443 ok(!ret
, "HidD_GetInputReport succeeded\n");
2444 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetInputReport returned error %u\n", GetLastError());
2446 SetLastError(0xdeadbeef);
2447 ret
= HidD_GetInputReport(file
, report
, caps
.InputReportByteLength
- 1);
2448 ok(!ret
, "HidD_GetInputReport succeeded\n");
2449 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2450 "HidD_GetInputReport returned error %u\n", GetLastError());
2452 SetLastError(0xdeadbeef);
2453 memset(buffer
, 0x5a, sizeof(buffer
));
2454 ret
= HidD_GetInputReport(file
, buffer
, caps
.InputReportByteLength
);
2455 if (report_id
|| broken(!ret
) /* w7u */)
2457 ok(!ret
, "HidD_GetInputReport succeeded, last error %u\n", GetLastError());
2458 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2459 "HidD_GetInputReport returned error %u\n", GetLastError());
2463 ok(ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError());
2464 ok(buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0]);
2467 SetLastError(0xdeadbeef);
2468 ret
= HidD_GetInputReport(file
, report
, caps
.InputReportByteLength
);
2469 ok(ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError());
2470 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2472 SetLastError(0xdeadbeef);
2473 value
= caps
.InputReportByteLength
* 2;
2474 ret
= sync_ioctl(file
, IOCTL_HID_GET_INPUT_REPORT
, NULL
, 0, report
, &value
);
2475 ok(ret
, "IOCTL_HID_GET_INPUT_REPORT failed, last error %u\n", GetLastError());
2476 ok(value
== 3, "got length %u, expected 3\n", value
);
2477 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2480 memset(report
, 0xcd, sizeof(report
));
2481 status
= HidP_InitializeReportForID(HidP_Feature
, report_id
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2482 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2484 SetLastError(0xdeadbeef);
2485 ret
= HidD_GetFeature(file
, report
, 0);
2486 ok(!ret
, "HidD_GetFeature succeeded\n");
2487 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetFeature returned error %u\n", GetLastError());
2489 SetLastError(0xdeadbeef);
2490 ret
= HidD_GetFeature(file
, report
, caps
.FeatureReportByteLength
- 1);
2491 ok(!ret
, "HidD_GetFeature succeeded\n");
2492 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2493 "HidD_GetFeature returned error %u\n", GetLastError());
2495 SetLastError(0xdeadbeef);
2496 memset(buffer
, 0x5a, sizeof(buffer
));
2497 ret
= HidD_GetFeature(file
, buffer
, caps
.FeatureReportByteLength
);
2498 if (report_id
|| broken(!ret
))
2500 ok(!ret
, "HidD_GetFeature succeeded, last error %u\n", GetLastError());
2501 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2502 "HidD_GetFeature returned error %u\n", GetLastError());
2506 ok(ret
, "HidD_GetFeature failed, last error %u\n", GetLastError());
2507 ok(buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0]);
2510 SetLastError(0xdeadbeef);
2511 ret
= HidD_GetFeature(file
, report
, caps
.FeatureReportByteLength
);
2512 ok(ret
, "HidD_GetFeature failed, last error %u\n", GetLastError());
2513 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2515 value
= caps
.FeatureReportByteLength
* 2;
2516 SetLastError(0xdeadbeef);
2517 ret
= sync_ioctl(file
, IOCTL_HID_GET_FEATURE
, NULL
, 0, report
, &value
);
2518 ok(ret
, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError());
2519 ok(value
== 3, "got length %u, expected 3\n", value
);
2520 ok(report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
2523 memset(report
, 0xcd, sizeof(report
));
2524 status
= HidP_InitializeReportForID(HidP_Feature
, report_id
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2525 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2527 SetLastError(0xdeadbeef);
2528 ret
= HidD_SetFeature(file
, report
, 0);
2529 ok(!ret
, "HidD_SetFeature succeeded\n");
2530 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetFeature returned error %u\n", GetLastError());
2532 SetLastError(0xdeadbeef);
2533 ret
= HidD_SetFeature(file
, report
, caps
.FeatureReportByteLength
- 1);
2534 ok(!ret
, "HidD_SetFeature succeeded\n");
2535 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2536 "HidD_SetFeature returned error %u\n", GetLastError());
2538 SetLastError(0xdeadbeef);
2539 memset(buffer
, 0x5a, sizeof(buffer
));
2540 ret
= HidD_SetFeature(file
, buffer
, caps
.FeatureReportByteLength
);
2541 if (report_id
|| broken(!ret
))
2543 ok(!ret
, "HidD_SetFeature succeeded, last error %u\n", GetLastError());
2544 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2545 "HidD_SetFeature returned error %u\n", GetLastError());
2549 ok(ret
, "HidD_SetFeature failed, last error %u\n", GetLastError());
2552 SetLastError(0xdeadbeef);
2553 ret
= HidD_SetFeature(file
, report
, caps
.FeatureReportByteLength
);
2554 ok(ret
, "HidD_SetFeature failed, last error %u\n", GetLastError());
2556 value
= caps
.FeatureReportByteLength
* 2;
2557 SetLastError(0xdeadbeef);
2558 ret
= sync_ioctl(file
, IOCTL_HID_SET_FEATURE
, NULL
, 0, report
, &value
);
2559 ok(!ret
, "IOCTL_HID_SET_FEATURE succeeded\n");
2560 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_FEATURE returned error %u\n", GetLastError());
2562 SetLastError(0xdeadbeef);
2563 ret
= sync_ioctl(file
, IOCTL_HID_SET_FEATURE
, report
, caps
.FeatureReportByteLength
* 2, NULL
, &value
);
2564 ok(ret
, "IOCTL_HID_SET_FEATURE failed, last error %u\n", GetLastError());
2565 ok(value
== 3, "got length %u, expected 3\n", value
);
2568 memset(report
, 0xcd, sizeof(report
));
2569 status
= HidP_InitializeReportForID(HidP_Output
, report_id
, preparsed_data
, report
, caps
.OutputReportByteLength
);
2570 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2571 memset(report
, 0, caps
.OutputReportByteLength
);
2572 report
[0] = report_id
;
2574 SetLastError(0xdeadbeef);
2575 ret
= HidD_SetOutputReport(file
, report
, 0);
2576 ok(!ret
, "HidD_SetOutputReport succeeded\n");
2577 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetOutputReport returned error %u\n", GetLastError());
2579 SetLastError(0xdeadbeef);
2580 ret
= HidD_SetOutputReport(file
, report
, caps
.OutputReportByteLength
- 1);
2581 ok(!ret
, "HidD_SetOutputReport succeeded\n");
2582 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2583 "HidD_SetOutputReport returned error %u\n", GetLastError());
2585 SetLastError(0xdeadbeef);
2586 memset(buffer
, 0x5a, sizeof(buffer
));
2587 ret
= HidD_SetOutputReport(file
, buffer
, caps
.OutputReportByteLength
);
2588 if (report_id
|| broken(!ret
))
2590 ok(!ret
, "HidD_SetOutputReport succeeded, last error %u\n", GetLastError());
2591 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == ERROR_CRC
),
2592 "HidD_SetOutputReport returned error %u\n", GetLastError());
2596 ok(ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError());
2599 SetLastError(0xdeadbeef);
2600 ret
= HidD_SetOutputReport(file
, report
, caps
.OutputReportByteLength
);
2601 ok(ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError());
2603 value
= caps
.OutputReportByteLength
* 2;
2604 SetLastError(0xdeadbeef);
2605 ret
= sync_ioctl(file
, IOCTL_HID_SET_OUTPUT_REPORT
, NULL
, 0, report
, &value
);
2606 ok(!ret
, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n");
2607 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError());
2609 SetLastError(0xdeadbeef);
2610 ret
= sync_ioctl(file
, IOCTL_HID_SET_OUTPUT_REPORT
, report
, caps
.OutputReportByteLength
* 2, NULL
, &value
);
2611 ok(ret
, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError());
2612 ok(value
== 3, "got length %u, expected 3\n", value
);
2615 SetLastError(0xdeadbeef);
2616 ret
= WriteFile(file
, report
, 0, &value
, NULL
);
2617 ok(!ret
, "WriteFile succeeded\n");
2618 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "WriteFile returned error %u\n", GetLastError());
2619 ok(value
== 0, "WriteFile returned %x\n", value
);
2620 SetLastError(0xdeadbeef);
2621 ret
= WriteFile(file
, report
, caps
.OutputReportByteLength
- 1, &value
, NULL
);
2622 ok(!ret
, "WriteFile succeeded\n");
2623 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_USER_BUFFER
,
2624 "WriteFile returned error %u\n", GetLastError());
2625 ok(value
== 0, "WriteFile returned %x\n", value
);
2627 memset(report
, 0xcd, sizeof(report
));
2629 SetLastError(0xdeadbeef);
2630 ret
= WriteFile(file
, report
, caps
.OutputReportByteLength
* 2, &value
, NULL
);
2631 if (report_id
|| broken(!ret
) /* w7u */)
2634 ok(!ret
, "WriteFile succeeded\n");
2636 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "WriteFile returned error %u\n", GetLastError());
2638 ok(value
== 0, "WriteFile wrote %u\n", value
);
2639 SetLastError(0xdeadbeef);
2640 report
[0] = report_id
;
2641 ret
= WriteFile(file
, report
, caps
.OutputReportByteLength
, &value
, NULL
);
2646 ok(ret
, "WriteFile failed, last error %u\n", GetLastError());
2647 ok(value
== 2, "WriteFile wrote %u\n", value
);
2651 ok(ret
, "WriteFile failed, last error %u\n", GetLastError());
2652 todo_wine
ok(value
== 3, "WriteFile wrote %u\n", value
);
2656 memset(report
, 0xcd, sizeof(report
));
2657 SetLastError(0xdeadbeef);
2658 ret
= ReadFile(file
, report
, 0, &value
, NULL
);
2659 ok(!ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n", GetLastError());
2660 ok(value
== 0, "ReadFile returned %x\n", value
);
2661 SetLastError(0xdeadbeef);
2662 ret
= ReadFile(file
, report
, caps
.InputReportByteLength
- 1, &value
, NULL
);
2663 ok(!ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n", GetLastError());
2664 ok(value
== 0, "ReadFile returned %x\n", value
);
2668 memset(report
, 0xcd, sizeof(report
));
2669 SetLastError(0xdeadbeef);
2670 ret
= ReadFile(file
, report
, caps
.InputReportByteLength
, &value
, NULL
);
2671 ok(ret
, "ReadFile failed, last error %u\n", GetLastError());
2672 ok(value
== (report_id
? 3 : 4), "ReadFile returned %x\n", value
);
2673 ok(report
[0] == report_id
, "unexpected report data\n");
2675 overlapped
.hEvent
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
2676 overlapped2
.hEvent
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
2678 /* drain available input reports */
2679 SetLastError(0xdeadbeef);
2680 while (ReadFile(async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
))
2681 ResetEvent(overlapped
.hEvent
);
2682 ok(GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError());
2683 ret
= GetOverlappedResult(async_file
, &overlapped
, &value
, TRUE
);
2684 ok(ret
, "GetOverlappedResult failed, last error %u\n", GetLastError());
2685 ok(value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value
);
2686 ResetEvent(overlapped
.hEvent
);
2688 memcpy(buffer
, report
, caps
.InputReportByteLength
);
2689 memcpy(buffer
+ caps
.InputReportByteLength
, report
, caps
.InputReportByteLength
);
2691 SetLastError(0xdeadbeef);
2692 ret
= ReadFile(async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2693 ok(!ret
, "ReadFile succeded\n");
2694 ok(GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError());
2696 SetLastError(0xdeadbeef);
2697 ret
= ReadFile(async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2698 ok(!ret
, "ReadFile succeded\n");
2699 ok(GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError());
2701 /* wait for second report to be ready */
2702 ret
= GetOverlappedResult(async_file
, &overlapped2
, &value
, TRUE
);
2703 ok(ret
, "GetOverlappedResult failed, last error %u\n", GetLastError());
2704 ok(value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value
);
2705 /* first report should be ready and the same */
2706 ret
= GetOverlappedResult(async_file
, &overlapped
, &value
, FALSE
);
2707 ok(ret
, "GetOverlappedResult failed, last error %u\n", GetLastError());
2708 ok(value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value
);
2709 ok(memcmp(report
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
),
2710 "expected different report\n");
2711 ok(!memcmp(report
, buffer
, caps
.InputReportByteLength
), "expected identical reports\n");
2713 CloseHandle(overlapped
.hEvent
);
2714 CloseHandle(overlapped2
.hEvent
);
2718 HidD_FreePreparsedData(preparsed_data
);
2721 static void test_hid_device(DWORD report_id
, DWORD polled
)
2724 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*iface_detail
= (void *)buffer
;
2725 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(iface
)};
2726 SP_DEVINFO_DATA device
= {sizeof(device
)};
2727 ULONG count
, poll_freq
, out_len
;
2728 HANDLE file
, async_file
;
2729 BOOL ret
, found
= FALSE
;
2730 OBJECT_ATTRIBUTES attr
;
2731 UNICODE_STRING string
;
2737 winetest_push_context("id %d%s", report_id
, polled
? " poll" : "");
2739 set
= SetupDiGetClassDevsA(&GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
2740 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
2742 for (i
= 0; SetupDiEnumDeviceInfo(set
, i
, &device
); ++i
)
2744 ret
= SetupDiEnumDeviceInterfaces(set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
2745 ok(ret
, "failed to get interface, error %#x\n", GetLastError());
2746 ok(IsEqualGUID(&iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
),
2747 "wrong class %s\n", debugstr_guid(&iface
.InterfaceClassGuid
));
2748 ok(iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
2750 iface_detail
->cbSize
= sizeof(*iface_detail
);
2751 ret
= SetupDiGetDeviceInterfaceDetailA(set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
2752 ok(ret
, "failed to get interface path, error %#x\n", GetLastError());
2754 if (strstr(iface_detail
->DevicePath
, "\\\\?\\hid#winetest#1"))
2761 SetupDiDestroyDeviceInfoList(set
);
2763 todo_wine
ok(found
, "didn't find device\n");
2765 file
= CreateFileA(iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2766 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
2767 ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
2770 SetLastError(0xdeadbeef);
2771 ret
= HidD_GetNumInputBuffers(file
, &count
);
2772 ok(ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError());
2773 ok(count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2775 SetLastError(0xdeadbeef);
2776 ret
= HidD_SetNumInputBuffers(file
, 1);
2777 ok(!ret
, "HidD_SetNumInputBuffers succeeded\n");
2778 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n", GetLastError());
2779 SetLastError(0xdeadbeef);
2780 ret
= HidD_SetNumInputBuffers(file
, 513);
2781 ok(!ret
, "HidD_SetNumInputBuffers succeeded\n");
2782 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n", GetLastError());
2784 SetLastError(0xdeadbeef);
2785 ret
= HidD_SetNumInputBuffers(file
, 16);
2786 ok(ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError());
2789 SetLastError(0xdeadbeef);
2790 ret
= HidD_GetNumInputBuffers(file
, &count
);
2791 ok(ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError());
2792 ok(count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2794 async_file
= CreateFileA(iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2795 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
2796 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
2797 ok(async_file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
2800 SetLastError(0xdeadbeef);
2801 ret
= HidD_GetNumInputBuffers(async_file
, &count
);
2802 ok(ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError());
2803 todo_wine
ok(count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2805 SetLastError(0xdeadbeef);
2806 ret
= HidD_SetNumInputBuffers(async_file
, 2);
2807 ok(ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError());
2810 SetLastError(0xdeadbeef);
2811 ret
= HidD_GetNumInputBuffers(async_file
, &count
);
2812 ok(ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError());
2813 ok(count
== 2, "HidD_GetNumInputBuffers returned %u\n", count
);
2815 SetLastError(0xdeadbeef);
2816 ret
= HidD_GetNumInputBuffers(file
, &count
);
2817 ok(ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError());
2818 todo_wine
ok(count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2822 out_len
= sizeof(ULONG
);
2823 SetLastError(0xdeadbeef);
2824 ret
= sync_ioctl(file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
);
2825 ok(ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError());
2826 ok(out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2827 todo_wine
ok(poll_freq
== 5, "got poll_freq %u, expected 5\n", poll_freq
);
2831 SetLastError(0xdeadbeef);
2832 ret
= sync_ioctl(file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
);
2833 ok(ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError());
2834 ok(out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2836 out_len
= sizeof(ULONG
);
2837 SetLastError(0xdeadbeef);
2838 ret
= sync_ioctl(file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
);
2839 ok(ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError());
2840 ok(out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2841 ok(poll_freq
== 500, "got poll_freq %u, expected 100\n", poll_freq
);
2843 out_len
= sizeof(ULONG
);
2844 SetLastError(0xdeadbeef);
2845 ret
= sync_ioctl(async_file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
);
2846 ok(ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError());
2847 ok(out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2848 ok(poll_freq
== 500, "got poll_freq %u, expected 100\n", poll_freq
);
2851 test_hidp(file
, async_file
, report_id
, polled
);
2853 CloseHandle(async_file
);
2856 RtlInitUnicodeString(&string
, L
"\\??\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}");
2857 InitializeObjectAttributes(&attr
, &string
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
2858 status
= NtOpenFile(&file
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
2859 todo_wine
ok(status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
2861 winetest_pop_context();
2864 static void test_hid_driver(struct testsign_context
*ctx
, DWORD report_id
, DWORD polled
)
2866 static const char hardware_id
[] = "test_hardware_id\0";
2867 char path
[MAX_PATH
], dest
[MAX_PATH
], *filepart
;
2868 SP_DEVINFO_DATA device
= {sizeof(device
)};
2869 char cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
2870 WCHAR driver_filename
[MAX_PATH
];
2871 SC_HANDLE manager
, service
;
2872 BOOL ret
, need_reboot
;
2873 HANDLE catalog
, file
;
2879 GetCurrentDirectoryA(ARRAY_SIZE(cwd
), cwd
);
2880 GetTempPathA(ARRAY_SIZE(tempdir
), tempdir
);
2881 SetCurrentDirectoryA(tempdir
);
2883 status
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest", 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
2884 ok(!status
, "RegCreateKeyExW returned %#x\n", status
);
2886 status
= RegSetValueExW(hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
));
2887 ok(!status
, "RegSetValueExW returned %#x\n", status
);
2889 status
= RegSetValueExW(hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
));
2890 ok(!status
, "RegSetValueExW returned %#x\n", status
);
2892 load_resource(L
"driver_hid.dll", driver_filename
);
2893 ret
= MoveFileExW(driver_filename
, L
"winetest.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
2894 ok(ret
, "failed to move file, error %u\n", GetLastError());
2896 f
= fopen("winetest.inf", "w");
2897 ok(!!f
, "failed to open winetest.inf: %s\n", strerror(errno
));
2901 /* Create the catalog file. */
2903 catalog
= CryptCATOpen((WCHAR
*)L
"winetest.cat", CRYPTCAT_OPEN_CREATENEW
, 0, CRYPTCAT_VERSION_1
, 0);
2904 ok(catalog
!= INVALID_HANDLE_VALUE
, "Failed to create catalog, error %#x\n", GetLastError());
2906 add_file_to_catalog(catalog
, L
"winetest.sys");
2907 add_file_to_catalog(catalog
, L
"winetest.inf");
2909 ret
= CryptCATPersistStore(catalog
);
2910 todo_wine
ok(ret
, "Failed to write catalog, error %u\n", GetLastError());
2912 ret
= CryptCATClose(catalog
);
2913 ok(ret
, "Failed to close catalog, error %u\n", GetLastError());
2915 testsign_sign(ctx
, L
"winetest.cat");
2917 /* Install the driver. */
2919 set
= SetupDiCreateDeviceInfoList(NULL
, NULL
);
2920 ok(set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %#x\n", GetLastError());
2922 ret
= SetupDiCreateDeviceInfoA(set
, "root\\winetest\\0", &GUID_NULL
, NULL
, NULL
, 0, &device
);
2923 ok(ret
, "failed to create device, error %#x\n", GetLastError());
2925 ret
= SetupDiSetDeviceRegistryPropertyA( set
, &device
, SPDRP_HARDWAREID
,
2926 (const BYTE
*)hardware_id
, sizeof(hardware_id
) );
2927 ok(ret
, "failed to create set hardware ID, error %#x\n", GetLastError());
2929 ret
= SetupDiCallClassInstaller(DIF_REGISTERDEVICE
, set
, &device
);
2930 ok(ret
, "failed to register device, error %#x\n", GetLastError());
2932 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
2933 ret
= UpdateDriverForPlugAndPlayDevicesA(NULL
, hardware_id
, path
, INSTALLFLAG_FORCE
, &need_reboot
);
2934 ok(ret
, "failed to install device, error %#x\n", GetLastError());
2935 ok(!need_reboot
, "expected no reboot necessary\n");
2939 test_hid_device(report_id
, polled
);
2943 ret
= SetupDiCallClassInstaller(DIF_REMOVE
, set
, &device
);
2944 ok(ret
, "failed to remove device, error %#x\n", GetLastError());
2946 file
= CreateFileA("\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2947 ok(file
== INVALID_HANDLE_VALUE
, "expected failure\n");
2948 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %u\n", GetLastError());
2950 ret
= SetupDiDestroyDeviceInfoList(set
);
2951 ok(ret
, "failed to destroy set, error %#x\n", GetLastError());
2953 /* Windows stops the service but does not delete it. */
2954 manager
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
2955 ok(!!manager
, "failed to open service manager, error %u\n", GetLastError());
2956 service
= OpenServiceA(manager
, "winetest", SERVICE_STOP
| DELETE
);
2957 ok(!!service
, "failed to open service, error %u\n", GetLastError());
2958 unload_driver(service
);
2959 CloseServiceHandle(manager
);
2963 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
2964 ret
= SetupCopyOEMInfA(path
, NULL
, 0, 0, dest
, sizeof(dest
), NULL
, &filepart
);
2965 ok(ret
, "Failed to copy INF, error %#x\n", GetLastError());
2966 ret
= SetupUninstallOEMInfA(filepart
, 0, NULL
);
2967 ok(ret
, "Failed to uninstall INF, error %u\n", GetLastError());
2969 ret
= DeleteFileA("winetest.cat");
2970 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2971 ret
= DeleteFileA("winetest.inf");
2972 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2973 ret
= DeleteFileA("winetest.sys");
2974 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2975 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
2976 ret
= DeleteFileA("C:/windows/system32/drivers/winetest.sys");
2977 ok(ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %u\n", GetLastError());
2979 SetCurrentDirectoryA(cwd
);
2982 START_TEST(ntoskrnl
)
2984 WCHAR filename
[MAX_PATH
], filename2
[MAX_PATH
];
2985 struct testsign_context ctx
;
2986 SC_HANDLE service
, service2
;
2991 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U");
2992 pRtlFreeUnicodeString
= (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString");
2993 pCancelIoEx
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx");
2994 pIsWow64Process
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
2995 pSetFileCompletionNotificationModes
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"),
2996 "SetFileCompletionNotificationModes");
2997 pSignerSign
= (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
2999 if (IsWow64Process(GetCurrentProcess(), &is_wow64
) && is_wow64
)
3001 skip("Running in WoW64.\n");
3005 if (!testsign_create_cert(&ctx
))
3008 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
,
3009 0, sizeof(*test_data
), "Global\\winetest_ntoskrnl_section");
3010 ok(!!mapping
, "got error %u\n", GetLastError());
3011 test_data
= MapViewOfFile(mapping
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 1024);
3012 test_data
->running_under_wine
= !strcmp(winetest_platform
, "wine");
3013 test_data
->winetest_report_success
= winetest_report_success
;
3014 test_data
->winetest_debug
= winetest_debug
;
3016 okfile
= CreateFileA("C:\\windows\\winetest_ntoskrnl_okfile", GENERIC_READ
| GENERIC_WRITE
,
3017 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
3018 ok(okfile
!= INVALID_HANDLE_VALUE
, "failed to create file, error %u\n", GetLastError());
3021 if (!(service
= load_driver(&ctx
, filename
, L
"driver.dll", L
"WineTestDriver")))
3024 if (!start_driver(service
, FALSE
))
3026 DeleteFileW(filename
);
3029 service2
= load_driver(&ctx
, filename2
, L
"driver2.dll", L
"WineTestDriver2");
3031 device
= CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
3032 ok(device
!= INVALID_HANDLE_VALUE
, "failed to open device: %u\n", GetLastError());
3035 test_mismatched_status_ioctl();
3038 todo_wine
ok(modified_value
== 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value
);
3041 test_load_driver(service2
);
3042 test_file_handles();
3043 test_return_status();
3046 /* We need a separate ioctl to call IoDetachDevice(); calling it in the
3047 * driver unload routine causes a live-lock. */
3048 ret
= DeviceIoControl(device
, IOCTL_WINETEST_DETACH
, NULL
, 0, NULL
, 0, &written
, NULL
);
3049 ok(ret
, "DeviceIoControl failed: %u\n", GetLastError());
3051 CloseHandle(device
);
3053 unload_driver(service2
);
3054 unload_driver(service
);
3055 ret
= DeleteFileW(filename
);
3056 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
3057 ret
= DeleteFileW(filename2
);
3058 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
3063 subtest("driver_netio");
3064 test_driver_netio(&ctx
);
3066 subtest("driver_pnp");
3067 test_pnp_driver(&ctx
);
3069 subtest("driver_hid");
3070 test_hid_driver(&ctx
, 0, FALSE
);
3071 test_hid_driver(&ctx
, 1, FALSE
);
3072 test_hid_driver(&ctx
, 0, TRUE
);
3073 test_hid_driver(&ctx
, 1, TRUE
);
3076 testsign_cleanup(&ctx
);
3077 UnmapViewOfFile(test_data
);
3078 CloseHandle(mapping
);
3079 CloseHandle(okfile
);
3080 DeleteFileA("C:\\windows\\winetest_ntoskrnl_okfile");