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 void test_hidp(HANDLE file
, int report_id
)
1666 const HIDP_CAPS expect_hidp_caps
[] =
1668 /* without report id */
1670 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
1671 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1672 .InputReportByteLength
= 24,
1673 .FeatureReportByteLength
= 18,
1674 .NumberLinkCollectionNodes
= 8,
1675 .NumberInputButtonCaps
= 13,
1676 .NumberInputValueCaps
= 7,
1677 .NumberInputDataIndices
= 43,
1678 .NumberFeatureButtonCaps
= 1,
1679 .NumberFeatureValueCaps
= 5,
1680 .NumberFeatureDataIndices
= 7,
1682 /* with report id */
1684 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
1685 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1686 .InputReportByteLength
= 23,
1687 .FeatureReportByteLength
= 17,
1688 .NumberLinkCollectionNodes
= 8,
1689 .NumberInputButtonCaps
= 13,
1690 .NumberInputValueCaps
= 7,
1691 .NumberInputDataIndices
= 43,
1692 .NumberFeatureButtonCaps
= 1,
1693 .NumberFeatureValueCaps
= 5,
1694 .NumberFeatureDataIndices
= 7,
1697 const HIDP_BUTTON_CAPS expect_button_caps
[] =
1700 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1701 .ReportID
= report_id
,
1703 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1704 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1705 .LinkCollection
= 1,
1708 .Range
.UsageMin
= 1,
1709 .Range
.UsageMax
= 8,
1710 .Range
.DataIndexMin
= 2,
1711 .Range
.DataIndexMax
= 9,
1714 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1715 .ReportID
= report_id
,
1717 .LinkCollection
= 1,
1718 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1719 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1722 .Range
.UsageMin
= 0x18,
1723 .Range
.UsageMax
= 0x1f,
1724 .Range
.DataIndexMin
= 10,
1725 .Range
.DataIndexMax
= 17,
1728 .UsagePage
= HID_USAGE_PAGE_KEYBOARD
,
1729 .ReportID
= report_id
,
1731 .LinkCollection
= 1,
1732 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1733 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1735 .IsAbsolute
= FALSE
,
1736 .Range
.UsageMin
= 0x8,
1737 .Range
.UsageMax
= 0xf,
1738 .Range
.DataIndexMin
= 18,
1739 .Range
.DataIndexMax
= 25,
1742 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1743 .ReportID
= report_id
,
1745 .LinkCollection
= 1,
1746 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1747 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1750 .NotRange
.Usage
= 0x20,
1751 .NotRange
.Reserved1
= 0x20,
1752 .NotRange
.DataIndex
= 26,
1753 .NotRange
.Reserved4
= 26,
1756 const HIDP_VALUE_CAPS expect_value_caps
[] =
1759 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1760 .ReportID
= report_id
,
1762 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1763 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1764 .LinkCollection
= 1,
1770 .NotRange
.Usage
= HID_USAGE_GENERIC_Y
,
1771 .NotRange
.Reserved1
= HID_USAGE_GENERIC_Y
,
1774 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1775 .ReportID
= report_id
,
1777 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1778 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1779 .LinkCollection
= 1,
1785 .NotRange
.Usage
= HID_USAGE_GENERIC_X
,
1786 .NotRange
.Reserved1
= HID_USAGE_GENERIC_X
,
1787 .NotRange
.DataIndex
= 1,
1788 .NotRange
.Reserved4
= 1,
1791 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1792 .ReportID
= report_id
,
1794 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1795 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1796 .LinkCollection
= 1,
1801 .Range
.UsageMin
= 0x21,
1802 .Range
.UsageMax
= 0x22,
1803 .Range
.DataIndexMin
= 27,
1804 .Range
.DataIndexMax
= 28,
1807 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1808 .ReportID
= report_id
,
1810 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1811 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1812 .LinkCollection
= 1,
1818 .NotRange
.Usage
= HID_USAGE_GENERIC_HATSWITCH
,
1819 .NotRange
.Reserved1
= HID_USAGE_GENERIC_HATSWITCH
,
1820 .NotRange
.DataIndex
= 29,
1821 .NotRange
.Reserved4
= 29,
1824 static const HIDP_LINK_COLLECTION_NODE expect_collections
[] =
1827 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1828 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1829 .CollectionType
= 1,
1830 .NumberOfChildren
= 5,
1834 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1835 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1836 .CollectionType
= 2,
1839 static const HIDP_DATA expect_data
[] =
1841 { .DataIndex
= 0, },
1842 { .DataIndex
= 1, },
1843 { .DataIndex
= 5, .RawValue
= 1, },
1844 { .DataIndex
= 7, .RawValue
= 1, },
1845 { .DataIndex
= 19, .RawValue
= 1, },
1846 { .DataIndex
= 21, .RawValue
= 1, },
1847 { .DataIndex
= 30, },
1848 { .DataIndex
= 31, },
1849 { .DataIndex
= 32, .RawValue
= 0xfeedcafe, },
1850 { .DataIndex
= 37, .RawValue
= 1, },
1851 { .DataIndex
= 39, .RawValue
= 1, },
1854 HIDP_LINK_COLLECTION_NODE collections
[16];
1855 PHIDP_PREPARSED_DATA preparsed_data
;
1856 USAGE_AND_PAGE usage_and_pages
[16];
1857 HIDP_BUTTON_CAPS button_caps
[16];
1858 HIDP_VALUE_CAPS value_caps
[16];
1859 char buffer
[200], report
[200];
1860 DWORD collection_count
;
1861 DWORD waveform_list
;
1871 ret
= HidD_GetPreparsedData(file
, &preparsed_data
);
1872 ok(ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError());
1874 memset(buffer
, 0, sizeof(buffer
));
1875 status
= HidP_GetCaps((PHIDP_PREPARSED_DATA
)buffer
, &caps
);
1876 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetCaps returned %#x\n", status
);
1877 status
= HidP_GetCaps(preparsed_data
, &caps
);
1878 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetCaps returned %#x\n", status
);
1879 check_hidp_caps(&caps
, &expect_hidp_caps
[report_id
]);
1881 collection_count
= 0;
1882 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, preparsed_data
);
1883 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1884 ok(collection_count
== caps
.NumberLinkCollectionNodes
, "got %d collection nodes, expected %d\n",
1885 collection_count
, caps
.NumberLinkCollectionNodes
);
1886 collection_count
= ARRAY_SIZE(collections
);
1887 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, (PHIDP_PREPARSED_DATA
)buffer
);
1888 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1889 status
= HidP_GetLinkCollectionNodes(collections
, &collection_count
, preparsed_data
);
1890 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1891 ok(collection_count
== caps
.NumberLinkCollectionNodes
, "got %d collection nodes, expected %d\n",
1892 collection_count
, caps
.NumberLinkCollectionNodes
);
1894 for (i
= 0; i
< ARRAY_SIZE(expect_collections
); ++i
)
1896 winetest_push_context("collections[%d]", i
);
1897 check_hidp_link_collection_node(&collections
[i
], &expect_collections
[i
]);
1898 winetest_pop_context();
1901 count
= ARRAY_SIZE(button_caps
);
1902 status
= HidP_GetButtonCaps(HidP_Output
, button_caps
, &count
, preparsed_data
);
1903 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetButtonCaps returned %#x\n", status
);
1904 status
= HidP_GetButtonCaps(HidP_Feature
+ 1, button_caps
, &count
, preparsed_data
);
1905 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetButtonCaps returned %#x\n", status
);
1907 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, preparsed_data
);
1908 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetButtonCaps returned %#x\n", status
);
1909 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1910 count
, caps
.NumberInputButtonCaps
);
1911 count
= ARRAY_SIZE(button_caps
);
1912 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1913 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetButtonCaps returned %#x\n", status
);
1914 memset(button_caps
, 0, sizeof(button_caps
));
1915 status
= HidP_GetButtonCaps(HidP_Input
, button_caps
, &count
, preparsed_data
);
1916 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetButtonCaps returned %#x\n", status
);
1917 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1918 count
, caps
.NumberInputButtonCaps
);
1920 for (i
= 0; i
< ARRAY_SIZE(expect_button_caps
); ++i
)
1922 winetest_push_context("button_caps[%d]", i
);
1923 check_hidp_button_caps(&button_caps
[i
], &expect_button_caps
[i
]);
1924 winetest_pop_context();
1927 count
= ARRAY_SIZE(button_caps
) - 1;
1928 status
= HidP_GetSpecificButtonCaps(HidP_Output
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1929 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1930 status
= HidP_GetSpecificButtonCaps(HidP_Feature
+ 1, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1931 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1933 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1934 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1935 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1936 count
, caps
.NumberInputButtonCaps
);
1937 count
= ARRAY_SIZE(button_caps
) - 1;
1938 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1939 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1941 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0, button_caps
+ 1, &count
, preparsed_data
);
1942 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1943 ok(count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1944 count
, caps
.NumberInputButtonCaps
);
1945 check_hidp_button_caps(&button_caps
[1], &button_caps
[0]);
1947 status
= HidP_GetSpecificButtonCaps(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, 5, button_caps
+ 1,
1948 &count
, preparsed_data
);
1949 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1950 ok(count
== 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 1);
1951 check_hidp_button_caps(&button_caps
[1], &button_caps
[0]);
1954 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0xfffe, 0, 0, button_caps
, &count
, preparsed_data
);
1955 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1956 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1958 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0xfffe, 0, button_caps
, &count
, preparsed_data
);
1959 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1960 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1962 status
= HidP_GetSpecificButtonCaps(HidP_Input
, 0, 0, 0xfffe, button_caps
, &count
, preparsed_data
);
1963 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1964 ok(count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0);
1966 count
= ARRAY_SIZE(value_caps
);
1967 status
= HidP_GetValueCaps(HidP_Output
, value_caps
, &count
, preparsed_data
);
1968 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetValueCaps returned %#x\n", status
);
1969 status
= HidP_GetValueCaps(HidP_Feature
+ 1, value_caps
, &count
, preparsed_data
);
1970 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetValueCaps returned %#x\n", status
);
1972 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, preparsed_data
);
1973 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetValueCaps returned %#x\n", status
);
1974 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1975 count
, caps
.NumberInputValueCaps
);
1976 count
= ARRAY_SIZE(value_caps
);
1977 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1978 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetValueCaps returned %#x\n", status
);
1979 status
= HidP_GetValueCaps(HidP_Input
, value_caps
, &count
, preparsed_data
);
1980 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetValueCaps returned %#x\n", status
);
1981 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1982 count
, caps
.NumberInputValueCaps
);
1984 for (i
= 0; i
< ARRAY_SIZE(expect_value_caps
); ++i
)
1986 winetest_push_context("value_caps[%d]", i
);
1987 check_hidp_value_caps(&value_caps
[i
], &expect_value_caps
[i
]);
1988 winetest_pop_context();
1991 count
= ARRAY_SIZE(value_caps
) - 4;
1992 status
= HidP_GetSpecificValueCaps(HidP_Output
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1993 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1994 status
= HidP_GetSpecificValueCaps(HidP_Feature
+ 1, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1995 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1997 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1998 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1999 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
2000 count
, caps
.NumberInputValueCaps
);
2001 count
= ARRAY_SIZE(value_caps
) - 4;
2002 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
2003 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2005 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, preparsed_data
);
2006 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2007 ok(count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
2008 count
, caps
.NumberInputValueCaps
);
2009 check_hidp_value_caps(&value_caps
[4], &value_caps
[0]);
2010 check_hidp_value_caps(&value_caps
[5], &value_caps
[1]);
2011 check_hidp_value_caps(&value_caps
[6], &value_caps
[2]);
2012 check_hidp_value_caps(&value_caps
[7], &value_caps
[3]);
2015 status
= HidP_GetSpecificValueCaps(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
2016 value_caps
+ 4, &count
, preparsed_data
);
2017 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2018 ok(count
== 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 1);
2019 check_hidp_value_caps(&value_caps
[4], &value_caps
[3]);
2022 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0xfffe, 0, 0, value_caps
, &count
, preparsed_data
);
2023 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2024 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2026 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0xfffe, 0, value_caps
, &count
, preparsed_data
);
2027 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2028 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2030 status
= HidP_GetSpecificValueCaps(HidP_Input
, 0, 0, 0xfffe, value_caps
, &count
, preparsed_data
);
2031 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
2032 ok(count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0);
2034 status
= HidP_InitializeReportForID(HidP_Input
, 0, (PHIDP_PREPARSED_DATA
)buffer
, report
, sizeof(report
));
2035 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_InitializeReportForID returned %#x\n", status
);
2036 status
= HidP_InitializeReportForID(HidP_Feature
+ 1, 0, preparsed_data
, report
, sizeof(report
));
2037 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_InitializeReportForID returned %#x\n", status
);
2038 status
= HidP_InitializeReportForID(HidP_Input
, 0, preparsed_data
, report
, sizeof(report
));
2039 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
2040 status
= HidP_InitializeReportForID(HidP_Input
, 0, preparsed_data
, report
, caps
.InputReportByteLength
+ 1);
2041 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
2042 status
= HidP_InitializeReportForID(HidP_Input
, 1 - report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2043 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2045 memset(report
, 0xcd, sizeof(report
));
2046 status
= HidP_InitializeReportForID(HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2047 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2049 memset(buffer
, 0xcd, sizeof(buffer
));
2050 memset(buffer
, 0, caps
.InputReportByteLength
);
2051 buffer
[0] = report_id
;
2052 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2054 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
2055 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
2056 ok(status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValueArray returned %#x\n", status
);
2057 memset(buffer
, 0xcd, sizeof(buffer
));
2058 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2059 0, preparsed_data
, report
, caps
.InputReportByteLength
);
2060 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2061 status
= HidP_SetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2062 8, preparsed_data
, report
, caps
.InputReportByteLength
);
2064 ok(status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_SetUsageValueArray returned %#x\n", status
);
2066 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
2067 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
2068 ok(status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_GetUsageValueArray returned %#x\n", status
);
2069 memset(buffer
, 0xcd, sizeof(buffer
));
2070 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2071 0, preparsed_data
, report
, caps
.InputReportByteLength
);
2072 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2073 status
= HidP_GetUsageValueArray(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
, buffer
,
2074 8, preparsed_data
, report
, caps
.InputReportByteLength
);
2076 ok(status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_GetUsageValueArray returned %#x\n", status
);
2079 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2080 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2081 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2083 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2084 &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2085 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2086 ok(value
== 0x80, "got value %x, expected %#x\n", value
, 0x80);
2088 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2089 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2090 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2091 ok(value
== -128, "got value %x, expected %#x\n", value
, -128);
2094 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2095 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2096 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2098 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2099 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2100 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2101 ok(value
== 127, "got value %x, expected %#x\n", value
, 127);
2104 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2105 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2106 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2108 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
2109 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2110 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2111 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2114 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2115 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2116 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2118 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2119 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2120 ok(status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2121 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2123 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2124 &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2125 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2126 ok(value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff);
2129 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2130 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2131 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2133 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2134 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2135 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2136 ok(value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff);
2139 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2140 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2141 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2143 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2144 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2145 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2146 ok(value
== 0x80000000, "got value %x, expected %#x\n", value
, 0x80000000);
2149 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
2150 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2151 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2153 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
2154 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2155 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2156 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2159 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
2160 value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2161 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2163 status
= HidP_GetScaledUsageValue(HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
2164 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2165 ok(status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2166 ok(value
== 0, "got value %x, expected %#x\n", value
, 0);
2168 value
= HidP_MaxUsageListLength(HidP_Feature
+ 1, 0, preparsed_data
);
2169 ok(value
== 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value
, 0);
2170 value
= HidP_MaxUsageListLength(HidP_Input
, 0, preparsed_data
);
2171 ok(value
== 42, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value
, 42);
2172 value
= HidP_MaxUsageListLength(HidP_Input
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
2173 ok(value
== 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value
, 32);
2174 value
= HidP_MaxUsageListLength(HidP_Input
, HID_USAGE_PAGE_LED
, preparsed_data
);
2175 ok(value
== 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value
, 8);
2176 value
= HidP_MaxUsageListLength(HidP_Feature
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
2177 ok(value
== 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value
, 8);
2178 value
= HidP_MaxUsageListLength(HidP_Feature
, HID_USAGE_PAGE_LED
, preparsed_data
);
2179 ok(value
== 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value
, 0);
2183 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2184 preparsed_data
, report
, caps
.InputReportByteLength
);
2185 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
2189 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2190 preparsed_data
, report
, caps
.InputReportByteLength
);
2191 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
2195 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2196 preparsed_data
, report
, caps
.InputReportByteLength
);
2197 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
2201 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
2202 report
, caps
.InputReportByteLength
);
2203 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
2209 ok(report
[6] == 0, "got report[6] %x expected 0\n", report
[6]);
2210 ok(report
[7] == 0, "got report[7] %x expected 0\n", report
[7]);
2211 memcpy(buffer
, report
, caps
.InputReportByteLength
);
2212 status
= HidP_SetUsages(HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
2213 report
, caps
.InputReportByteLength
);
2214 todo_wine
ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsages returned %#x\n", status
);
2217 todo_wine
ok(!memcmp(buffer
, report
, caps
.InputReportByteLength
), "unexpected report data\n");
2219 status
= HidP_SetUsageValue(HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, 1,
2220 preparsed_data
, report
, caps
.InputReportByteLength
);
2221 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2224 status
= HidP_GetUsageValue(HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, &value
,
2225 preparsed_data
, report
, caps
.InputReportByteLength
);
2226 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2227 ok(value
== 0xdeadbeef, "got value %x, expected %#x\n", value
, 0xdeadbeef);
2230 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2231 preparsed_data
, report
, caps
.InputReportByteLength
);
2232 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsages returned %#x\n", status
);
2233 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2234 value
= ARRAY_SIZE(usages
);
2235 memset(usages
, 0xcd, sizeof(usages
));
2236 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
,
2237 preparsed_data
, report
, caps
.InputReportByteLength
);
2238 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
2239 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2240 ok(usages
[0] == 4, "got usages[0] %x, expected %x\n", usages
[0], 4);
2241 ok(usages
[1] == 6, "got usages[1] %x, expected %x\n", usages
[1], 6);
2243 value
= ARRAY_SIZE(usages
);
2244 memset(usages
, 0xcd, sizeof(usages
));
2245 status
= HidP_GetUsages(HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
2246 report
, caps
.InputReportByteLength
);
2247 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
2248 ok(value
== 2, "got usage count %d, expected %d\n", value
, 2);
2249 ok(usages
[0] == 6, "got usages[0] %x, expected %x\n", usages
[0], 6);
2250 ok(usages
[1] == 4, "got usages[1] %x, expected %x\n", usages
[1], 4);
2252 value
= ARRAY_SIZE(usage_and_pages
);
2253 memset(usage_and_pages
, 0xcd, sizeof(usage_and_pages
));
2254 status
= HidP_GetUsagesEx(HidP_Input
, 0, usage_and_pages
, &value
, preparsed_data
, report
,
2255 caps
.InputReportByteLength
);
2256 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsagesEx returned %#x\n", status
);
2257 todo_wine
ok(value
== 6, "got usage count %d, expected %d\n", value
, 4);
2258 ok(usage_and_pages
[0].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[0] UsagePage %x, expected %x\n",
2259 usage_and_pages
[0].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2260 ok(usage_and_pages
[1].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[1] UsagePage %x, expected %x\n",
2261 usage_and_pages
[1].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2262 ok(usage_and_pages
[2].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[2] UsagePage %x, expected %x\n",
2263 usage_and_pages
[2].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
2264 ok(usage_and_pages
[3].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[3] UsagePage %x, expected %x\n",
2265 usage_and_pages
[3].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
2267 ok(usage_and_pages
[4].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[4] UsagePage %x, expected %x\n",
2268 usage_and_pages
[4].UsagePage
, HID_USAGE_PAGE_LED
);
2269 ok(usage_and_pages
[5].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[5] UsagePage %x, expected %x\n",
2270 usage_and_pages
[5].UsagePage
, HID_USAGE_PAGE_LED
);
2271 ok(usage_and_pages
[0].Usage
== 4, "got usage_and_pages[0] Usage %x, expected %x\n",
2272 usage_and_pages
[0].Usage
, 4);
2273 ok(usage_and_pages
[1].Usage
== 6, "got usage_and_pages[1] Usage %x, expected %x\n",
2274 usage_and_pages
[1].Usage
, 6);
2275 ok(usage_and_pages
[2].Usage
== 9, "got usage_and_pages[2] Usage %x, expected %x\n",
2276 usage_and_pages
[2].Usage
, 9);
2278 ok(usage_and_pages
[3].Usage
== 11, "got usage_and_pages[3] Usage %x, expected %x\n",
2279 usage_and_pages
[3].Usage
, 11);
2281 ok(usage_and_pages
[4].Usage
== 6, "got usage_and_pages[4] Usage %x, expected %x\n",
2282 usage_and_pages
[4].Usage
, 6);
2284 ok(usage_and_pages
[5].Usage
== 4, "got usage_and_pages[5] Usage %x, expected %x\n",
2285 usage_and_pages
[5].Usage
, 4);
2287 value
= HidP_MaxDataListLength(HidP_Feature
+ 1, preparsed_data
);
2288 ok(value
== 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value
, 0);
2289 value
= HidP_MaxDataListLength(HidP_Input
, preparsed_data
);
2290 ok(value
== 50, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value
, 50);
2291 value
= HidP_MaxDataListLength(HidP_Output
, preparsed_data
);
2292 ok(value
== 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value
, 0);
2293 value
= HidP_MaxDataListLength(HidP_Feature
, preparsed_data
);
2294 ok(value
== 13, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value
, 13);
2297 status
= HidP_GetData(HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2298 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetData returned %#x\n", status
);
2299 todo_wine
ok(value
== 11, "got data count %d, expected %d\n", value
, 11);
2300 memset(data
, 0, sizeof(data
));
2301 status
= HidP_GetData(HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2302 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetData returned %#x\n", status
);
2303 for (i
= 0; i
< ARRAY_SIZE(expect_data
); ++i
)
2305 winetest_push_context("data[%d]", i
);
2306 todo_wine_if(i
>= 4) check_member(data
[i
], expect_data
[i
], "%d", DataIndex
);
2307 todo_wine_if(i
>= 4) check_member(data
[i
], expect_data
[i
], "%d", RawValue
);
2308 winetest_pop_context();
2311 memset(report
, 0xcd, sizeof(report
));
2312 status
= HidP_InitializeReportForID(HidP_Feature
, 3, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2313 ok(status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
2315 memset(report
, 0xcd, sizeof(report
));
2316 status
= HidP_InitializeReportForID(HidP_Feature
, report_id
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2317 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
2319 memset(buffer
, 0xcd, sizeof(buffer
));
2320 memset(buffer
, 0, caps
.FeatureReportByteLength
);
2321 buffer
[0] = report_id
;
2322 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2324 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
2326 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_HAPTICS
) continue;
2327 if (collections
[i
].LinkUsage
== HID_USAGE_HAPTICS_WAVEFORM_LIST
) break;
2329 ok(i
< caps
.NumberLinkCollectionNodes
,
2330 "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n");
2333 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2334 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, (PHIDP_PREPARSED_DATA
)buffer
,
2335 report
, caps
.FeatureReportByteLength
);
2336 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_SetUsageValue returned %#x\n", status
);
2337 status
= HidP_SetUsageValue(HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2338 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2339 caps
.FeatureReportByteLength
);
2340 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_SetUsageValue returned %#x\n", status
);
2341 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2342 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2343 caps
.FeatureReportByteLength
+ 1);
2344 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_SetUsageValue returned %#x\n", status
);
2345 report
[0] = 1 - report_id
;
2346 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2347 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2348 caps
.FeatureReportByteLength
);
2349 ok(status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2350 "HidP_SetUsageValue returned %#x\n", status
);
2352 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2353 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2354 caps
.FeatureReportByteLength
);
2355 ok(status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_SetUsageValue returned %#x\n", status
);
2356 report
[0] = report_id
;
2357 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
,
2358 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2359 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
2361 status
= HidP_SetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2362 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2363 caps
.FeatureReportByteLength
);
2364 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2366 memset(buffer
, 0xcd, sizeof(buffer
));
2367 memset(buffer
, 0, caps
.FeatureReportByteLength
);
2368 buffer
[0] = report_id
;
2369 value
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
2370 memcpy(buffer
+ 1, &value
, 2);
2371 ok(!memcmp(buffer
, report
, sizeof(buffer
)), "unexpected report data\n");
2373 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2374 (PHIDP_PREPARSED_DATA
)buffer
, report
, caps
.FeatureReportByteLength
);
2375 ok(status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetUsageValue returned %#x\n", status
);
2376 status
= HidP_GetUsageValue(HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2377 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2378 ok(status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetUsageValue returned %#x\n", status
);
2379 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2380 preparsed_data
, report
, caps
.FeatureReportByteLength
+ 1);
2381 ok(status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_GetUsageValue returned %#x\n", status
);
2382 report
[0] = 1 - report_id
;
2383 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2384 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2385 ok(status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2386 "HidP_GetUsageValue returned %#x\n", status
);
2388 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2389 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2390 ok(status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_GetUsageValue returned %#x\n", status
);
2391 report
[0] = report_id
;
2392 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, &value
,
2393 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2394 ok(status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#x\n", status
);
2397 status
= HidP_GetUsageValue(HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2398 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2399 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2400 ok(value
== HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, "got value %x, expected %#x\n", value
,
2401 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
);
2403 memset(buffer
, 0xff, sizeof(buffer
));
2404 status
= HidP_SetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2405 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2406 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2407 status
= HidP_SetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2408 64, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2409 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#x\n", status
);
2410 ok(!memcmp(report
+ 9, buffer
, 8), "unexpected report data\n");
2412 memset(buffer
, 0, sizeof(buffer
));
2413 status
= HidP_GetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2414 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2415 ok(status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2416 status
= HidP_GetUsageValueArray(HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
,
2417 64, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2418 ok(status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#x\n", status
);
2419 memset(buffer
+ 16, 0xff, 8);
2420 ok(!memcmp(buffer
, buffer
+ 16, 16), "unexpected report value\n");
2422 HidD_FreePreparsedData(preparsed_data
);
2426 static void test_hid_device(DWORD report_id
)
2429 SP_DEVICE_INTERFACE_DETAIL_DATA_A
*iface_detail
= (void *)buffer
;
2430 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(iface
)};
2431 SP_DEVINFO_DATA device
= {sizeof(device
)};
2432 BOOL ret
, found
= FALSE
;
2433 OBJECT_ATTRIBUTES attr
;
2434 UNICODE_STRING string
;
2441 winetest_push_context("report %d", report_id
);
2443 set
= SetupDiGetClassDevsA(&GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
2444 ok(set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError());
2446 for (i
= 0; SetupDiEnumDeviceInfo(set
, i
, &device
); ++i
)
2448 ret
= SetupDiEnumDeviceInterfaces(set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
2449 ok(ret
, "failed to get interface, error %#x\n", GetLastError());
2450 ok(IsEqualGUID(&iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
),
2451 "wrong class %s\n", debugstr_guid(&iface
.InterfaceClassGuid
));
2452 ok(iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
2454 iface_detail
->cbSize
= sizeof(*iface_detail
);
2455 ret
= SetupDiGetDeviceInterfaceDetailA(set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
2456 ok(ret
, "failed to get interface path, error %#x\n", GetLastError());
2458 if (strstr(iface_detail
->DevicePath
, "\\\\?\\hid#winetest#1"))
2465 SetupDiDestroyDeviceInfoList(set
);
2467 todo_wine
ok(found
, "didn't find device\n");
2469 file
= CreateFileA(iface_detail
->DevicePath
, FILE_READ_ACCESS
,
2470 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
2471 ok(file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError());
2473 test_hidp(file
, report_id
);
2477 RtlInitUnicodeString(&string
, L
"\\??\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}");
2478 InitializeObjectAttributes(&attr
, &string
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
2479 status
= NtOpenFile(&file
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
2480 todo_wine
ok(status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
2482 winetest_pop_context();
2485 static void test_hid_driver(struct testsign_context
*ctx
, DWORD report_id
)
2487 static const char hardware_id
[] = "test_hardware_id\0";
2488 char path
[MAX_PATH
], dest
[MAX_PATH
], *filepart
;
2489 SP_DEVINFO_DATA device
= {sizeof(device
)};
2490 char cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
2491 WCHAR driver_filename
[MAX_PATH
];
2492 SC_HANDLE manager
, service
;
2493 BOOL ret
, need_reboot
;
2494 HANDLE catalog
, file
;
2500 GetCurrentDirectoryA(ARRAY_SIZE(cwd
), cwd
);
2501 GetTempPathA(ARRAY_SIZE(tempdir
), tempdir
);
2502 SetCurrentDirectoryA(tempdir
);
2504 status
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest", 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
2505 ok(!status
, "RegCreateKeyExW returned %#x\n", status
);
2507 status
= RegSetValueExW(hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
));
2508 ok(!status
, "RegSetValueExW returned %#x\n", status
);
2510 load_resource(L
"driver_hid.dll", driver_filename
);
2511 ret
= MoveFileExW(driver_filename
, L
"winetest.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
2512 ok(ret
, "failed to move file, error %u\n", GetLastError());
2514 f
= fopen("winetest.inf", "w");
2515 ok(!!f
, "failed to open winetest.inf: %s\n", strerror(errno
));
2519 /* Create the catalog file. */
2521 catalog
= CryptCATOpen((WCHAR
*)L
"winetest.cat", CRYPTCAT_OPEN_CREATENEW
, 0, CRYPTCAT_VERSION_1
, 0);
2522 ok(catalog
!= INVALID_HANDLE_VALUE
, "Failed to create catalog, error %#x\n", GetLastError());
2524 add_file_to_catalog(catalog
, L
"winetest.sys");
2525 add_file_to_catalog(catalog
, L
"winetest.inf");
2527 ret
= CryptCATPersistStore(catalog
);
2528 todo_wine
ok(ret
, "Failed to write catalog, error %u\n", GetLastError());
2530 ret
= CryptCATClose(catalog
);
2531 ok(ret
, "Failed to close catalog, error %u\n", GetLastError());
2533 testsign_sign(ctx
, L
"winetest.cat");
2535 /* Install the driver. */
2537 set
= SetupDiCreateDeviceInfoList(NULL
, NULL
);
2538 ok(set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %#x\n", GetLastError());
2540 ret
= SetupDiCreateDeviceInfoA(set
, "root\\winetest\\0", &GUID_NULL
, NULL
, NULL
, 0, &device
);
2541 ok(ret
, "failed to create device, error %#x\n", GetLastError());
2543 ret
= SetupDiSetDeviceRegistryPropertyA( set
, &device
, SPDRP_HARDWAREID
,
2544 (const BYTE
*)hardware_id
, sizeof(hardware_id
) );
2545 ok(ret
, "failed to create set hardware ID, error %#x\n", GetLastError());
2547 ret
= SetupDiCallClassInstaller(DIF_REGISTERDEVICE
, set
, &device
);
2548 ok(ret
, "failed to register device, error %#x\n", GetLastError());
2550 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
2551 ret
= UpdateDriverForPlugAndPlayDevicesA(NULL
, hardware_id
, path
, INSTALLFLAG_FORCE
, &need_reboot
);
2552 ok(ret
, "failed to install device, error %#x\n", GetLastError());
2553 ok(!need_reboot
, "expected no reboot necessary\n");
2557 test_hid_device(report_id
);
2561 ret
= SetupDiCallClassInstaller(DIF_REMOVE
, set
, &device
);
2562 ok(ret
, "failed to remove device, error %#x\n", GetLastError());
2564 file
= CreateFileA("\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2565 ok(file
== INVALID_HANDLE_VALUE
, "expected failure\n");
2566 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %u\n", GetLastError());
2568 ret
= SetupDiDestroyDeviceInfoList(set
);
2569 ok(ret
, "failed to destroy set, error %#x\n", GetLastError());
2571 /* Windows stops the service but does not delete it. */
2572 manager
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
2573 ok(!!manager
, "failed to open service manager, error %u\n", GetLastError());
2574 service
= OpenServiceA(manager
, "winetest", SERVICE_STOP
| DELETE
);
2575 ok(!!service
, "failed to open service, error %u\n", GetLastError());
2576 unload_driver(service
);
2577 CloseServiceHandle(manager
);
2581 GetFullPathNameA("winetest.inf", sizeof(path
), path
, NULL
);
2582 ret
= SetupCopyOEMInfA(path
, NULL
, 0, 0, dest
, sizeof(dest
), NULL
, &filepart
);
2583 ok(ret
, "Failed to copy INF, error %#x\n", GetLastError());
2584 ret
= SetupUninstallOEMInfA(filepart
, 0, NULL
);
2585 ok(ret
, "Failed to uninstall INF, error %u\n", GetLastError());
2587 ret
= DeleteFileA("winetest.cat");
2588 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2589 ret
= DeleteFileA("winetest.inf");
2590 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2591 ret
= DeleteFileA("winetest.sys");
2592 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
2593 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
2594 ret
= DeleteFileA("C:/windows/system32/drivers/winetest.sys");
2595 ok(ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %u\n", GetLastError());
2597 SetCurrentDirectoryA(cwd
);
2600 START_TEST(ntoskrnl
)
2602 WCHAR filename
[MAX_PATH
], filename2
[MAX_PATH
];
2603 struct testsign_context ctx
;
2604 SC_HANDLE service
, service2
;
2609 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U");
2610 pRtlFreeUnicodeString
= (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString");
2611 pCancelIoEx
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx");
2612 pIsWow64Process
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
2613 pSetFileCompletionNotificationModes
= (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"),
2614 "SetFileCompletionNotificationModes");
2615 pSignerSign
= (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
2617 if (IsWow64Process(GetCurrentProcess(), &is_wow64
) && is_wow64
)
2619 skip("Running in WoW64.\n");
2623 if (!testsign_create_cert(&ctx
))
2626 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
,
2627 0, sizeof(*test_data
), "Global\\winetest_ntoskrnl_section");
2628 ok(!!mapping
, "got error %u\n", GetLastError());
2629 test_data
= MapViewOfFile(mapping
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 1024);
2630 test_data
->running_under_wine
= !strcmp(winetest_platform
, "wine");
2631 test_data
->winetest_report_success
= winetest_report_success
;
2632 test_data
->winetest_debug
= winetest_debug
;
2634 okfile
= CreateFileA("C:\\windows\\winetest_ntoskrnl_okfile", GENERIC_READ
| GENERIC_WRITE
,
2635 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
2636 ok(okfile
!= INVALID_HANDLE_VALUE
, "failed to create file, error %u\n", GetLastError());
2639 if (!(service
= load_driver(&ctx
, filename
, L
"driver.dll", L
"WineTestDriver")))
2642 if (!start_driver(service
, FALSE
))
2644 DeleteFileW(filename
);
2647 service2
= load_driver(&ctx
, filename2
, L
"driver2.dll", L
"WineTestDriver2");
2649 device
= CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2650 ok(device
!= INVALID_HANDLE_VALUE
, "failed to open device: %u\n", GetLastError());
2653 test_mismatched_status_ioctl();
2656 todo_wine
ok(modified_value
== 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value
);
2659 test_load_driver(service2
);
2660 test_file_handles();
2661 test_return_status();
2664 /* We need a separate ioctl to call IoDetachDevice(); calling it in the
2665 * driver unload routine causes a live-lock. */
2666 ret
= DeviceIoControl(device
, IOCTL_WINETEST_DETACH
, NULL
, 0, NULL
, 0, &written
, NULL
);
2667 ok(ret
, "DeviceIoControl failed: %u\n", GetLastError());
2669 CloseHandle(device
);
2671 unload_driver(service2
);
2672 unload_driver(service
);
2673 ret
= DeleteFileW(filename
);
2674 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
2675 ret
= DeleteFileW(filename2
);
2676 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
2681 subtest("driver_netio");
2682 test_driver_netio(&ctx
);
2684 subtest("driver_pnp");
2685 test_pnp_driver(&ctx
);
2687 subtest("driver_hid");
2688 test_hid_driver(&ctx
, 0);
2689 test_hid_driver(&ctx
, 1);
2692 testsign_cleanup(&ctx
);
2693 UnmapViewOfFile(test_data
);
2694 CloseHandle(mapping
);
2695 CloseHandle(okfile
);
2696 DeleteFileA("C:\\windows\\winetest_ntoskrnl_okfile");