2 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define DIRECTINPUT_VERSION 0x0800
25 #define WIN32_NO_STATUS
51 #include "ddk/hidclass.h"
52 #include "ddk/hidsdi.h"
53 #include "ddk/hidpi.h"
54 #include "ddk/hidport.h"
59 #include "wine/mssign.h"
61 #include "dinput_test.h"
64 BOOL localized
; /* object names get translated */
66 const HID_DEVICE_ATTRIBUTES default_attributes
=
68 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
69 .VendorID
= LOWORD(EXPECT_VIDPID
),
70 .ProductID
= HIWORD(EXPECT_VIDPID
),
71 .VersionNumber
= 0x0100,
73 const WCHAR expect_vidpid_str
[] = L
"VID_1209&PID_0001";
74 const GUID expect_guid_product
= {EXPECT_VIDPID
, 0x0000, 0x0000, {0x00, 0x00, 'P', 'I', 'D', 'V', 'I', 'D'}};
75 const WCHAR expect_path
[] = L
"\\\\?\\hid#vid_1209&pid_0001#2&";
76 const WCHAR expect_path_end
[] = L
"&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
77 static HANDLE device_added
, device_removed
;
79 static struct winetest_shared_data
*test_data
;
80 static HANDLE monitor_thread
, monitor_stop
;
81 static HANDLE test_data_mapping
;
84 static HRESULT (WINAPI
*pSignerSign
)( SIGNER_SUBJECT_INFO
*subject
, SIGNER_CERT
*cert
,
85 SIGNER_SIGNATURE_INFO
*signature
, SIGNER_PROVIDER_INFO
*provider
,
86 const WCHAR
*timestamp
, CRYPT_ATTRIBUTES
*attr
, void *sip_data
);
88 static const WCHAR container_name
[] = L
"wine_testsign";
90 static const CERT_CONTEXT
*testsign_sign( const WCHAR
*filename
)
92 BYTE encoded_name
[100], encoded_key_id
[200], public_key_info_buffer
[1000];
93 BYTE hash_buffer
[16], cert_buffer
[1000], provider_nameA
[100], serial
[16];
94 CERT_PUBLIC_KEY_INFO
*public_key_info
= (CERT_PUBLIC_KEY_INFO
*)public_key_info_buffer
;
95 SIGNER_SIGNATURE_INFO signature
= {sizeof(SIGNER_SIGNATURE_INFO
)};
96 SIGNER_CERT_STORE_INFO store
= {sizeof(SIGNER_CERT_STORE_INFO
)};
97 SIGNER_ATTR_AUTHCODE authcode
= {sizeof(SIGNER_ATTR_AUTHCODE
)};
98 SIGNER_SUBJECT_INFO subject
= {sizeof(SIGNER_SUBJECT_INFO
)};
99 SIGNER_FILE_INFO file
= {sizeof(SIGNER_FILE_INFO
)};
100 SIGNER_CERT signer
= {sizeof(SIGNER_CERT
)};
101 CRYPT_KEY_PROV_INFO provider_info
= {0};
102 CRYPT_ALGORITHM_IDENTIFIER algid
= {0};
103 CERT_AUTHORITY_KEY_ID_INFO key_info
;
104 HCERTSTORE root_store
, pub_store
;
105 CERT_INFO cert_info
= {0};
106 WCHAR provider_nameW
[100];
107 const CERT_CONTEXT
*cert
;
108 CERT_EXTENSION extension
;
109 DWORD size
, index
= 0;
115 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
116 if (!ret
&& GetLastError() == NTE_EXISTS
)
118 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
119 ok( ret
, "Failed to delete container, error %#lx\n", GetLastError() );
120 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
122 ok( ret
, "Failed to create container, error %#lx\n", GetLastError() );
124 ret
= CryptGenKey( provider
, AT_SIGNATURE
, CRYPT_EXPORTABLE
, &key
);
125 ok( ret
, "Failed to create key, error %#lx\n", GetLastError() );
126 ret
= CryptDestroyKey( key
);
127 ok( ret
, "Failed to destroy key, error %#lx\n", GetLastError() );
128 ret
= CryptGetUserKey( provider
, AT_SIGNATURE
, &key
);
129 ok( ret
, "Failed to get user key, error %#lx\n", GetLastError() );
130 ret
= CryptDestroyKey( key
);
131 ok( ret
, "Failed to destroy key, error %#lx\n", GetLastError() );
133 size
= sizeof(encoded_name
);
134 ret
= CertStrToNameW( X509_ASN_ENCODING
, L
"CN=winetest_cert", CERT_X500_NAME_STR
, NULL
,
135 encoded_name
, &size
, NULL
);
136 ok( ret
, "Failed to convert name, error %#lx\n", GetLastError() );
137 key_info
.CertIssuer
.cbData
= size
;
138 key_info
.CertIssuer
.pbData
= encoded_name
;
140 size
= sizeof(public_key_info_buffer
);
141 ret
= CryptExportPublicKeyInfo( provider
, AT_SIGNATURE
, X509_ASN_ENCODING
, public_key_info
, &size
);
142 ok( ret
, "Failed to export public key, error %#lx\n", GetLastError() );
143 cert_info
.SubjectPublicKeyInfo
= *public_key_info
;
145 size
= sizeof(hash_buffer
);
146 ret
= CryptHashPublicKeyInfo( provider
, CALG_MD5
, 0, X509_ASN_ENCODING
, public_key_info
, hash_buffer
, &size
);
147 ok( ret
, "Failed to hash public key, error %#lx\n", GetLastError() );
149 key_info
.KeyId
.cbData
= size
;
150 key_info
.KeyId
.pbData
= hash_buffer
;
152 RtlGenRandom( serial
, sizeof(serial
) );
153 key_info
.CertSerialNumber
.cbData
= sizeof(serial
);
154 key_info
.CertSerialNumber
.pbData
= serial
;
156 size
= sizeof(encoded_key_id
);
157 ret
= CryptEncodeObject( X509_ASN_ENCODING
, X509_AUTHORITY_KEY_ID
, &key_info
, encoded_key_id
, &size
);
158 ok( ret
, "Failed to convert name, error %#lx\n", GetLastError() );
160 extension
.pszObjId
= (char *)szOID_AUTHORITY_KEY_IDENTIFIER
;
161 extension
.fCritical
= TRUE
;
162 extension
.Value
.cbData
= size
;
163 extension
.Value
.pbData
= encoded_key_id
;
165 cert_info
.dwVersion
= CERT_V3
;
166 cert_info
.SerialNumber
= key_info
.CertSerialNumber
;
167 cert_info
.SignatureAlgorithm
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
168 cert_info
.Issuer
= key_info
.CertIssuer
;
169 GetSystemTimeAsFileTime( &cert_info
.NotBefore
);
170 GetSystemTimeAsFileTime( &cert_info
.NotAfter
);
171 cert_info
.NotAfter
.dwHighDateTime
+= 1;
172 cert_info
.Subject
= key_info
.CertIssuer
;
173 cert_info
.cExtension
= 1;
174 cert_info
.rgExtension
= &extension
;
175 algid
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
176 size
= sizeof(cert_buffer
);
177 ret
= CryptSignAndEncodeCertificate( provider
, AT_SIGNATURE
, X509_ASN_ENCODING
, X509_CERT_TO_BE_SIGNED
,
178 &cert_info
, &algid
, NULL
, cert_buffer
, &size
);
179 ok( ret
, "Failed to create certificate, error %#lx\n", GetLastError() );
181 cert
= CertCreateCertificateContext( X509_ASN_ENCODING
, cert_buffer
, size
);
182 ok( !!cert
, "Failed to create context, error %#lx\n", GetLastError() );
184 size
= sizeof(provider_nameA
);
185 ret
= CryptGetProvParam( provider
, PP_NAME
, provider_nameA
, &size
, 0 );
186 ok( ret
, "Failed to get prov param, error %#lx\n", GetLastError() );
187 MultiByteToWideChar( CP_ACP
, 0, (char *)provider_nameA
, -1, provider_nameW
, ARRAY_SIZE(provider_nameW
) );
189 provider_info
.pwszContainerName
= (WCHAR
*)container_name
;
190 provider_info
.pwszProvName
= provider_nameW
;
191 provider_info
.dwProvType
= PROV_RSA_FULL
;
192 provider_info
.dwKeySpec
= AT_SIGNATURE
;
193 ret
= CertSetCertificateContextProperty( cert
, CERT_KEY_PROV_INFO_PROP_ID
, 0, &provider_info
);
194 ok( ret
, "Failed to set provider info, error %#lx\n", GetLastError() );
196 ret
= CryptReleaseContext( provider
, 0 );
197 ok( ret
, "failed to release context, error %lu\n", GetLastError() );
199 root_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"root" );
200 if (!root_store
&& GetLastError() == ERROR_ACCESS_DENIED
)
202 win_skip( "Failed to open root store.\n" );
203 ret
= CertFreeCertificateContext( cert
);
204 ok( ret
, "Failed to free certificate, error %lu\n", GetLastError() );
207 ok( !!root_store
, "Failed to open store, error %lu\n", GetLastError() );
208 ret
= CertAddCertificateContextToStore( root_store
, cert
, CERT_STORE_ADD_ALWAYS
, NULL
);
209 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
211 win_skip( "Failed to add self-signed certificate to store.\n" );
212 ret
= CertFreeCertificateContext( cert
);
213 ok( ret
, "Failed to free certificate, error %lu\n", GetLastError() );
214 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
215 ok( ret
, "Failed to close store, error %lu\n", GetLastError() );
218 ok( ret
, "Failed to add certificate, error %lu\n", GetLastError() );
219 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
220 ok( ret
, "Failed to close store, error %lu\n", GetLastError() );
222 pub_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0,
223 CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"trustedpublisher" );
224 ok( !!pub_store
, "Failed to open store, error %lu\n", GetLastError() );
225 ret
= CertAddCertificateContextToStore( pub_store
, cert
, CERT_STORE_ADD_ALWAYS
, NULL
);
226 ok( ret
, "Failed to add certificate, error %lu\n", GetLastError() );
227 ret
= CertCloseStore( pub_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
228 ok( ret
, "Failed to close store, error %lu\n", GetLastError() );
230 subject
.dwSubjectChoice
= 1;
231 subject
.pdwIndex
= &index
;
232 subject
.pSignerFileInfo
= &file
;
233 file
.pwszFileName
= (WCHAR
*)filename
;
234 signer
.dwCertChoice
= 2;
235 signer
.pCertStoreInfo
= &store
;
236 store
.pSigningCert
= cert
;
237 store
.dwCertPolicy
= 0;
238 signature
.algidHash
= CALG_SHA_256
;
239 signature
.dwAttrChoice
= SIGNER_AUTHCODE_ATTR
;
240 signature
.pAttrAuthcode
= &authcode
;
241 authcode
.pwszName
= L
"";
242 authcode
.pwszInfo
= L
"";
243 hr
= pSignerSign( &subject
, &signer
, &signature
, NULL
, NULL
, NULL
, NULL
);
245 ok( hr
== S_OK
|| broken( hr
== NTE_BAD_ALGID
) /* < 7 */, "Failed to sign, hr %#lx\n", hr
);
250 static void testsign_cleanup( const CERT_CONTEXT
*cert
)
252 HCERTSTORE root_store
, pub_store
;
253 const CERT_CONTEXT
*store_cert
;
257 root_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"root" );
258 ok( !!root_store
, "Failed to open store, error %lu\n", GetLastError() );
259 store_cert
= CertFindCertificateInStore( root_store
, X509_ASN_ENCODING
, 0, CERT_FIND_EXISTING
, cert
, NULL
);
260 ok( !!store_cert
, "Failed to find root certificate, error %lu\n", GetLastError() );
261 ret
= CertDeleteCertificateFromStore( store_cert
);
262 ok( ret
, "Failed to remove certificate, error %lu\n", GetLastError() );
263 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
264 ok( ret
, "Failed to close store, error %lu\n", GetLastError() );
266 pub_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0,
267 CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"trustedpublisher" );
268 ok( !!pub_store
, "Failed to open store, error %lu\n", GetLastError() );
269 store_cert
= CertFindCertificateInStore( pub_store
, X509_ASN_ENCODING
, 0, CERT_FIND_EXISTING
, cert
, NULL
);
270 ok( !!store_cert
, "Failed to find publisher certificate, error %lu\n", GetLastError() );
271 ret
= CertDeleteCertificateFromStore( store_cert
);
272 ok( ret
, "Failed to remove certificate, error %lu\n", GetLastError() );
273 ret
= CertCloseStore( pub_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
274 ok( ret
, "Failed to close store, error %lu\n", GetLastError() );
276 ret
= CertFreeCertificateContext( cert
);
277 ok( ret
, "Failed to free certificate, error %lu\n", GetLastError() );
279 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
280 ok( ret
, "Failed to delete container, error %#lx\n", GetLastError() );
283 static void load_resource( const WCHAR
*name
, WCHAR
*filename
)
285 static WCHAR path
[MAX_PATH
];
291 GetTempPathW( ARRAY_SIZE(path
), path
);
292 GetTempFileNameW( path
, name
, 0, filename
);
294 file
= CreateFileW( filename
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
295 ok( file
!= INVALID_HANDLE_VALUE
, "failed to create %s, error %lu\n", debugstr_w(filename
), GetLastError() );
297 res
= FindResourceW( NULL
, name
, L
"TESTDLL" );
298 ok( res
!= 0, "couldn't find resource\n" );
299 ptr
= LockResource( LoadResource( GetModuleHandleW( NULL
), res
) );
300 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleW( NULL
), res
), &written
, NULL
);
301 ok( written
== SizeofResource( GetModuleHandleW( NULL
), res
), "couldn't write resource\n" );
307 #elif defined(__x86_64__)
309 #elif defined(__arm__)
311 #elif defined(__aarch64__)
317 static const char inf_text
[] =
319 "Signature=$Chicago$\n"
320 "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n"
321 "CatalogFile=winetest.cat\n"
322 "DriverVer=09/21/2006,6.0.5736.1\n"
325 "Wine=mfg_section,NT" EXT
"\n"
327 "[mfg_section.NT" EXT
"]\n"
328 "Wine Test Bus Device=bus_section,WINETEST\\BUS\n"
329 "Wine Test HID Device=hid_section,WINETEST\\WINE_COMP_HID\n"
330 "Wine Test HID Polled Device=hid_poll_section,WINETEST\\WINE_COMP_POLLHID\n"
332 "[bus_section.NT" EXT
"]\n"
333 "CopyFiles=file_section\n"
335 "[bus_section.NT" EXT
".Services]\n"
336 "AddService=winetest_bus,0x2,bus_service\n"
338 "[hid_section.NT" EXT
"]\n"
339 "CopyFiles=file_section\n"
341 "[hid_section.NT" EXT
".Services]\n"
342 "AddService=winetest_hid,0x2,hid_service\n"
344 "[hid_poll_section.NT" EXT
"]\n"
345 "CopyFiles=file_section\n"
347 "[hid_poll_section.NT" EXT
".Services]\n"
348 "AddService=winetest_hid_poll,0x2,hid_poll_service\n"
353 "winetest_hid_poll.sys\n"
355 "[SourceDisksFiles]\n"
356 "winetest_bus.sys=1\n"
357 "winetest_hid.sys=1\n"
358 "winetest_hid_poll.sys=1\n"
360 "[SourceDisksNames]\n"
361 "1=,winetest_bus.sys\n"
362 "1=,winetest_hid.sys\n"
363 "1=,winetest_hid_poll.sys\n"
365 "[DestinationDirs]\n"
366 "DefaultDestDir=12\n"
369 "ServiceBinary=%12%\\winetest_bus.sys\n"
373 "LoadOrderGroup=WinePlugPlay\n"
374 "DisplayName=\"Wine Test Bus Driver\"\n"
377 "ServiceBinary=%12%\\winetest_hid.sys\n"
381 "LoadOrderGroup=WinePlugPlay\n"
382 "DisplayName=\"Wine Test HID Driver\"\n"
384 "[hid_poll_service]\n"
385 "ServiceBinary=%12%\\winetest_hid_poll.sys\n"
389 "LoadOrderGroup=WinePlugPlay\n"
390 "DisplayName=\"Wine Test HID Polled Driver\"\n"
391 "; they don't sleep anymore, on the beach\n";
393 static void add_file_to_catalog( HANDLE catalog
, const WCHAR
*file
)
395 SIP_SUBJECTINFO subject_info
= {sizeof(SIP_SUBJECTINFO
)};
396 SIP_INDIRECT_DATA
*indirect_data
;
397 const WCHAR
*filepart
= file
;
398 CRYPTCATMEMBER
*member
;
399 WCHAR hash_buffer
[100];
405 ret
= CryptSIPRetrieveSubjectGuidForCatalogFile( file
, NULL
, &subject_guid
);
407 ok( ret
, "Failed to get subject guid, error %lu\n", GetLastError() );
410 subject_info
.pgSubjectType
= &subject_guid
;
411 subject_info
.pwsFileName
= file
;
412 subject_info
.DigestAlgorithm
.pszObjId
= (char *)szOID_OIWSEC_sha1
;
413 subject_info
.dwFlags
= SPC_INC_PE_RESOURCES_FLAG
| SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG
|
414 SPC_EXC_PE_PAGE_HASHES_FLAG
| 0x10000;
415 ret
= CryptSIPCreateIndirectData( &subject_info
, &size
, NULL
);
417 ok( ret
, "Failed to get indirect data size, error %lu\n", GetLastError() );
419 indirect_data
= malloc( size
);
420 ret
= CryptSIPCreateIndirectData( &subject_info
, &size
, indirect_data
);
422 ok( ret
, "Failed to get indirect data, error %lu\n", GetLastError() );
425 memset( hash_buffer
, 0, sizeof(hash_buffer
) );
426 for (i
= 0; i
< indirect_data
->Digest
.cbData
; ++i
)
427 swprintf( &hash_buffer
[i
* 2], 2, L
"%02X", indirect_data
->Digest
.pbData
[i
] );
429 member
= CryptCATPutMemberInfo( catalog
, (WCHAR
*)file
, hash_buffer
, &subject_guid
,
430 0, size
, (BYTE
*)indirect_data
);
431 ok( !!member
, "Failed to write member, error %lu\n", GetLastError() );
433 if (wcsrchr( file
, '\\' )) filepart
= wcsrchr( file
, '\\' ) + 1;
435 ret
= !!CryptCATPutAttrInfo( catalog
, member
, (WCHAR
*)L
"File",
436 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
437 (wcslen( filepart
) + 1) * 2, (BYTE
*)filepart
);
438 ok( ret
, "Failed to write attr, error %lu\n", GetLastError() );
440 ret
= !!CryptCATPutAttrInfo( catalog
, member
, (WCHAR
*)L
"OSAttr",
441 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
442 sizeof(L
"2:6.0"), (BYTE
*)L
"2:6.0" );
443 ok( ret
, "Failed to write attr, error %lu\n", GetLastError() );
445 free( indirect_data
);
448 static void unload_driver( SC_HANDLE service
)
450 SERVICE_STATUS status
;
452 ControlService( service
, SERVICE_CONTROL_STOP
, &status
);
453 while (status
.dwCurrentState
== SERVICE_STOP_PENDING
)
457 ret
= QueryServiceStatus( service
, &status
);
458 ok( ret
, "QueryServiceStatus failed: %lu\n", GetLastError() );
460 ok( status
.dwCurrentState
== SERVICE_STOPPED
|| !status
.dwCurrentState
,
461 "expected SERVICE_STOPPED, got %lu\n", status
.dwCurrentState
);
463 DeleteService( service
);
464 CloseServiceHandle( service
);
467 void bus_device_stop(void)
469 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
470 WCHAR path
[MAX_PATH
], dest
[MAX_PATH
], *filepart
;
471 const WCHAR
*service_name
= L
"winetest_bus";
472 SC_HANDLE manager
, service
;
479 if (!test_data
) return;
481 set
= SetupDiCreateDeviceInfoList( NULL
, NULL
);
482 ok( set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %lu\n", GetLastError() );
484 ret
= SetupDiOpenDeviceInfoW( set
, L
"root\\winetest\\0", NULL
, 0, &device
);
485 if (!ret
&& GetLastError() == ERROR_NO_SUCH_DEVINST
)
487 ret
= SetupDiDestroyDeviceInfoList( set
);
488 ok( ret
, "failed to destroy set, error %lu\n", GetLastError() );
491 ok( ret
, "failed to open device, error %lu\n", GetLastError() );
493 ret
= SetupDiCallClassInstaller( DIF_REMOVE
, set
, &device
);
494 ok( ret
, "failed to remove device, error %lu\n", GetLastError() );
496 file
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
497 NULL
, OPEN_EXISTING
, 0, NULL
);
498 ok( file
== INVALID_HANDLE_VALUE
, "expected failure\n" );
499 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %lu\n", GetLastError() );
501 ret
= SetupDiDestroyDeviceInfoList( set
);
502 ok( ret
, "failed to destroy set, error %lu\n", GetLastError() );
504 /* Windows stops the service but does not delete it. */
505 manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_CONNECT
);
506 ok( !!manager
, "failed to open service manager, error %lu\n", GetLastError() );
508 service
= OpenServiceW( manager
, service_name
, SERVICE_STOP
| DELETE
);
509 if (service
) unload_driver( service
);
510 else ok( GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "got error %lu\n", GetLastError() );
512 CloseServiceHandle( manager
);
514 SetFilePointer( okfile
, 0, NULL
, FILE_BEGIN
);
517 ReadFile( okfile
, buffer
, sizeof(buffer
), &size
, NULL
);
518 printf( "%.*s", (int)size
, buffer
);
519 } while (size
== sizeof(buffer
));
520 SetFilePointer( okfile
, 0, NULL
, FILE_BEGIN
);
521 SetEndOfFile( okfile
);
523 winetest_add_failures( InterlockedExchange( &test_data
->failures
, 0 ) );
524 winetest_add_failures( InterlockedExchange( &test_data
->todo_failures
, 0 ) );
526 GetFullPathNameW( L
"winetest.inf", ARRAY_SIZE(path
), path
, NULL
);
527 ret
= SetupCopyOEMInfW( path
, NULL
, 0, 0, dest
, ARRAY_SIZE(dest
), NULL
, &filepart
);
528 ok( ret
, "Failed to copy INF, error %lu\n", GetLastError() );
529 ret
= SetupUninstallOEMInfW( filepart
, SUOI_FORCEDELETE
, NULL
);
530 ok( ret
, "Failed to uninstall INF, error %lx\n", GetLastError() );
532 ret
= DeleteFileW( L
"winetest.cat" );
533 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
534 ret
= DeleteFileW( L
"winetest.inf" );
535 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
536 ret
= DeleteFileW( L
"winetest_bus.sys" );
537 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
538 ret
= DeleteFileW( L
"winetest_hid.sys" );
539 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
540 ret
= DeleteFileW( L
"winetest_hid_poll.sys" );
541 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
542 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
543 ret
= DeleteFileW( L
"C:/windows/system32/drivers/winetest_bus.sys" );
544 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %lu\n", GetLastError() );
545 ret
= DeleteFileW( L
"C:/windows/system32/drivers/winetest_hid.sys" );
546 todo_wine_if(!ret
&& GetLastError() == ERROR_ACCESS_DENIED
) /* Wine doesn't unload device drivers correctly */
547 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %lu\n", GetLastError() );
548 ret
= DeleteFileW( L
"C:/windows/system32/drivers/winetest_hid_poll.sys" );
549 todo_wine_if(!ret
&& GetLastError() == ERROR_ACCESS_DENIED
) /* Wine doesn't unload device drivers correctly */
550 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %lu\n", GetLastError() );
553 static BOOL
find_hid_device_path( WCHAR
*device_path
)
555 char buffer
[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W
, DevicePath
[MAX_PATH
] )] = {0};
556 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(SP_DEVICE_INTERFACE_DATA
)};
557 SP_DEVICE_INTERFACE_DETAIL_DATA_W
*iface_detail
= (void *)buffer
;
558 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
559 ULONG i
, len
= wcslen( device_path
);
563 set
= SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
564 ok( set
!= INVALID_HANDLE_VALUE
, "Failed to get device list, error %#lx\n", GetLastError() );
566 for (i
= 0; SetupDiEnumDeviceInfo( set
, i
, &device
); ++i
)
568 SetLastError( 0xdeadbeef );
569 ret
= SetupDiEnumDeviceInterfaces( set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
570 todo_wine_if(!ret
&& GetLastError() == ERROR_NO_MORE_ITEMS
) /* Wine doesn't unload device drivers correctly */
571 ok( ret
, "Failed to get interface, error %#lx\n", GetLastError() );
573 ok( IsEqualGUID( &iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
), "wrong class %s\n",
574 debugstr_guid( &iface
.InterfaceClassGuid
) );
575 ok( iface
.Flags
== SPINT_ACTIVE
, "got flags %#lx\n", iface
.Flags
);
577 iface_detail
->cbSize
= sizeof(*iface_detail
);
578 ret
= SetupDiGetDeviceInterfaceDetailW( set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
579 ok( ret
, "Failed to get interface path, error %#lx\n", GetLastError() );
581 if (!wcsncmp( iface_detail
->DevicePath
, device_path
, len
)) break;
584 ret
= SetupDiDestroyDeviceInfoList( set
);
585 ok( ret
, "Failed to destroy set, error %lu\n", GetLastError() );
587 ret
= !wcsncmp( iface_detail
->DevicePath
, device_path
, len
);
588 if (ret
) wcscpy( device_path
, iface_detail
->DevicePath
);
592 BOOL
bus_device_start(void)
594 static const WCHAR bus_hardware_ids
[] = L
"WINETEST\\BUS\0";
595 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
596 const WCHAR
*service_name
= L
"winetest_bus";
597 WCHAR path
[MAX_PATH
], filename
[MAX_PATH
];
598 SC_HANDLE manager
, service
;
599 const CERT_CONTEXT
*cert
;
600 int old_mute_threshold
;
601 BOOL ret
, need_reboot
;
606 if (!test_data
) return FALSE
;
608 old_mute_threshold
= winetest_mute_threshold
;
609 winetest_mute_threshold
= 1;
611 load_resource( L
"driver_bus.dll", filename
);
612 ret
= MoveFileExW( filename
, L
"winetest_bus.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
613 ok( ret
, "failed to move file, error %lu\n", GetLastError() );
615 load_resource( L
"driver_hid.dll", filename
);
616 ret
= MoveFileExW( filename
, L
"winetest_hid.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
617 ok( ret
, "failed to move file, error %lu\n", GetLastError() );
619 load_resource( L
"driver_hid_poll.dll", filename
);
620 ret
= MoveFileExW( filename
, L
"winetest_hid_poll.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
621 ok( ret
, "failed to move file, error %lu\n", GetLastError() );
623 f
= fopen( "winetest.inf", "w" );
624 ok( !!f
, "failed to open winetest.inf: %s\n", strerror( errno
) );
625 fputs( inf_text
, f
);
628 /* Create the catalog file. */
630 catalog
= CryptCATOpen( (WCHAR
*)L
"winetest.cat", CRYPTCAT_OPEN_CREATENEW
, 0, CRYPTCAT_VERSION_1
, 0 );
631 ok( catalog
!= INVALID_HANDLE_VALUE
, "Failed to create catalog, error %lu\n", GetLastError() );
633 add_file_to_catalog( catalog
, L
"winetest_bus.sys" );
634 add_file_to_catalog( catalog
, L
"winetest_hid.sys" );
635 add_file_to_catalog( catalog
, L
"winetest_hid_poll.sys" );
636 add_file_to_catalog( catalog
, L
"winetest.inf" );
638 ret
= CryptCATPersistStore( catalog
);
640 ok( ret
, "Failed to write catalog, error %lu\n", GetLastError() );
642 ret
= CryptCATClose( catalog
);
643 ok( ret
, "Failed to close catalog, error %lu\n", GetLastError() );
645 if (!(cert
= testsign_sign( L
"winetest.cat" )))
647 ret
= DeleteFileW( L
"winetest.cat" );
648 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
649 ret
= DeleteFileW( L
"winetest.inf" );
650 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
651 ret
= DeleteFileW( L
"winetest_bus.sys" );
652 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
653 ret
= DeleteFileW( L
"winetest_hid.sys" );
654 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
655 ret
= DeleteFileW( L
"winetest_hid_poll.sys" );
656 ok( ret
, "Failed to delete file, error %lu\n", GetLastError() );
657 winetest_mute_threshold
= old_mute_threshold
;
661 /* Install the driver. */
663 set
= SetupDiCreateDeviceInfoList( NULL
, NULL
);
664 ok( set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %lu\n", GetLastError() );
666 ret
= SetupDiCreateDeviceInfoW( set
, L
"root\\winetest\\0", &GUID_NULL
, NULL
, NULL
, 0, &device
);
667 ok( ret
, "failed to create device, error %#lx\n", GetLastError() );
669 ret
= SetupDiSetDeviceRegistryPropertyW( set
, &device
, SPDRP_HARDWAREID
, (const BYTE
*)bus_hardware_ids
, sizeof(bus_hardware_ids
) );
670 ok( ret
, "failed to create set hardware ID, error %lu\n", GetLastError() );
672 ret
= SetupDiCallClassInstaller( DIF_REGISTERDEVICE
, set
, &device
);
673 ok( ret
, "failed to register device, error %lu\n", GetLastError() );
675 ret
= SetupDiDestroyDeviceInfoList( set
);
676 ok( ret
, "failed to destroy set, error %lu\n", GetLastError() );
678 GetFullPathNameW( L
"winetest.inf", ARRAY_SIZE(path
), path
, NULL
);
680 ret
= UpdateDriverForPlugAndPlayDevicesW( NULL
, bus_hardware_ids
, path
, INSTALLFLAG_FORCE
, &need_reboot
);
681 ok( ret
, "failed to install device, error %lu\n", GetLastError() );
682 ok( !need_reboot
, "expected no reboot necessary\n" );
684 testsign_cleanup( cert
);
686 /* Check that the service is created and started. */
687 manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_CONNECT
);
688 ok( !!manager
, "failed to open service manager, error %lu\n", GetLastError() );
690 service
= OpenServiceW( manager
, service_name
, SERVICE_START
);
691 ok( !!service
, "failed to open service, error %lu\n", GetLastError() );
693 ret
= StartServiceW( service
, 0, NULL
);
694 ok( !ret
, "service didn't start automatically\n" );
695 if (!ret
&& GetLastError() != ERROR_SERVICE_ALREADY_RUNNING
)
697 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
698 ok( GetLastError() == ERROR_DRIVER_BLOCKED
|| GetLastError() == ERROR_INVALID_IMAGE_HASH
,
699 "unexpected error %lu\n", GetLastError() );
700 win_skip( "Failed to start service; probably your machine doesn't accept unsigned drivers.\n" );
703 CloseServiceHandle( service
);
704 CloseServiceHandle( manager
);
706 winetest_mute_threshold
= old_mute_threshold
;
707 return ret
|| GetLastError() == ERROR_SERVICE_ALREADY_RUNNING
;
710 void hid_device_stop( struct hid_device_desc
*desc
, UINT count
)
715 control
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
716 NULL
, OPEN_EXISTING
, 0, NULL
);
717 ok( control
!= INVALID_HANDLE_VALUE
, "CreateFile failed, error %lu\n", GetLastError() );
718 ret
= sync_ioctl( control
, IOCTL_WINETEST_REMOVE_DEVICE
, desc
, sizeof(*desc
), NULL
, 0, 5000 );
719 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "IOCTL_WINETEST_REMOVE_DEVICE failed, last error %lu\n", GetLastError() );
720 CloseHandle( control
);
724 ret
= WaitForSingleObject( device_removed
, 5000 );
725 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
727 for (i
= 0; i
< count
; ++i
)
729 ret
= WaitForSingleObject( device_removed
, i
> 0 ? 500 : 5000 );
731 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
735 BOOL
hid_device_start( struct hid_device_desc
*desc
, UINT count
)
740 control
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
741 NULL
, OPEN_EXISTING
, 0, NULL
);
742 ok( control
!= INVALID_HANDLE_VALUE
, "CreateFile failed, error %lu\n", GetLastError() );
743 ret
= sync_ioctl( control
, IOCTL_WINETEST_CREATE_DEVICE
, desc
, sizeof(*desc
), NULL
, 0, 5000 );
744 ok( ret
, "IOCTL_WINETEST_CREATE_DEVICE failed, last error %lu\n", GetLastError() );
745 CloseHandle( control
);
747 ret
= WaitForSingleObject( device_added
, 5000 );
748 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
750 if (ret
) return FALSE
;
752 for (i
= 0; i
< count
; ++i
)
754 ret
= WaitForSingleObject( device_added
, 1000 );
756 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
762 #define check_hidp_caps( a, b ) check_hidp_caps_( __LINE__, a, b )
763 static inline void check_hidp_caps_( int line
, HIDP_CAPS
*caps
, const HIDP_CAPS
*exp
)
765 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Usage
);
766 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
767 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", InputReportByteLength
);
768 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", OutputReportByteLength
);
769 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", FeatureReportByteLength
);
770 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberLinkCollectionNodes
);
771 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputButtonCaps
);
772 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputValueCaps
);
773 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputDataIndices
);
774 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputButtonCaps
);
775 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputValueCaps
);
776 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputDataIndices
);
777 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureButtonCaps
);
778 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureValueCaps
);
779 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureDataIndices
);
782 #define check_hidp_link_collection_node( a, b ) check_hidp_link_collection_node_( __LINE__, a, b )
783 static inline void check_hidp_link_collection_node_( int line
, HIDP_LINK_COLLECTION_NODE
*node
,
784 const HIDP_LINK_COLLECTION_NODE
*exp
)
786 check_member_( __FILE__
, line
, *node
, *exp
, "%04x", LinkUsage
);
787 check_member_( __FILE__
, line
, *node
, *exp
, "%04x", LinkUsagePage
);
788 check_member_( __FILE__
, line
, *node
, *exp
, "%d", Parent
);
789 check_member_( __FILE__
, line
, *node
, *exp
, "%d", NumberOfChildren
);
790 check_member_( __FILE__
, line
, *node
, *exp
, "%d", NextSibling
);
791 check_member_( __FILE__
, line
, *node
, *exp
, "%d", FirstChild
);
792 check_member_( __FILE__
, line
, *node
, *exp
, "%d", CollectionType
);
793 check_member_( __FILE__
, line
, *node
, *exp
, "%d", IsAlias
);
796 #define check_hidp_button_caps( a, b ) check_hidp_button_caps_( __LINE__, a, b )
797 static inline void check_hidp_button_caps_( int line
, HIDP_BUTTON_CAPS
*caps
, const HIDP_BUTTON_CAPS
*exp
)
799 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
800 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
801 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
802 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitField
);
803 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
804 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", LinkUsage
);
805 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", LinkUsagePage
);
806 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
807 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
808 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
809 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
811 if (!caps
->IsRange
&& !exp
->IsRange
)
813 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
814 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
816 else if (caps
->IsRange
&& exp
->IsRange
)
818 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
819 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
820 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
821 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
824 if (!caps
->IsRange
&& !exp
->IsRange
)
825 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
826 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
828 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
829 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
832 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
833 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
834 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
836 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
837 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
841 #define check_hidp_value_caps( a, b ) check_hidp_value_caps_( __LINE__, a, b )
842 static inline void check_hidp_value_caps_( int line
, HIDP_VALUE_CAPS
*caps
, const HIDP_VALUE_CAPS
*exp
)
844 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
845 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
846 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
847 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitField
);
848 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
849 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkUsage
);
850 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkUsagePage
);
851 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
852 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
853 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
854 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
856 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", HasNull
);
857 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitSize
);
858 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportCount
);
859 check_member_( __FILE__
, line
, *caps
, *exp
, "%ld", UnitsExp
);
860 check_member_( __FILE__
, line
, *caps
, *exp
, "%ld", Units
);
861 check_member_( __FILE__
, line
, *caps
, *exp
, "%ld", LogicalMin
);
862 check_member_( __FILE__
, line
, *caps
, *exp
, "%ld", LogicalMax
);
863 check_member_( __FILE__
, line
, *caps
, *exp
, "%ld", PhysicalMin
);
864 check_member_( __FILE__
, line
, *caps
, *exp
, "%ld", PhysicalMax
);
866 if (!caps
->IsRange
&& !exp
->IsRange
)
868 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
869 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
871 else if (caps
->IsRange
&& exp
->IsRange
)
873 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
874 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
875 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
876 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
879 if (!caps
->IsRange
&& !exp
->IsRange
)
880 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
881 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
883 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
884 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
887 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
888 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
889 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
891 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
892 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
896 BOOL
sync_ioctl_( const char *file
, int line
, HANDLE device
, DWORD code
, void *in_buf
, DWORD in_len
,
897 void *out_buf
, DWORD
*ret_len
, DWORD timeout
)
899 DWORD res
, out_len
= ret_len
? *ret_len
: 0;
900 OVERLAPPED ovl
= {0};
903 ovl
.hEvent
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
904 ret
= DeviceIoControl( device
, code
, in_buf
, in_len
, out_buf
, out_len
, &out_len
, &ovl
);
905 if (!ret
&& GetLastError() == ERROR_IO_PENDING
)
907 res
= WaitForSingleObject( ovl
.hEvent
, timeout
);
908 ok_(file
, line
)( !res
, "WaitForSingleObject returned %#lx\n", res
);
909 ret
= GetOverlappedResult( device
, &ovl
, &out_len
, FALSE
);
910 ok_(file
, line
)( ret
, "GetOverlappedResult returned %lu\n", GetLastError() );
913 CancelIoEx( device
, &ovl
);
914 res
= WaitForSingleObject( ovl
.hEvent
, timeout
);
915 ok_(file
, line
)( !res
, "WaitForSingleObject returned %#lx\n", res
);
918 CloseHandle( ovl
.hEvent
);
920 if (ret_len
) *ret_len
= out_len
;
924 void fill_context_( const char *file
, int line
, char *buffer
, SIZE_T size
)
926 const char *source_file
;
927 source_file
= strrchr( file
, '/' );
928 if (!source_file
) source_file
= strrchr( file
, '\\' );
929 if (!source_file
) source_file
= file
;
931 snprintf( buffer
, size
, "%s:%d", source_file
, line
);
934 void set_hid_expect_( const char *file
, int line
, HANDLE device
, struct hid_device_desc
*desc
,
935 struct hid_expect
*expect
, DWORD expect_size
)
937 char buffer
[sizeof(*desc
) + EXPECT_QUEUE_BUFFER_SIZE
];
941 if (desc
) memcpy( buffer
, desc
, sizeof(*desc
) );
942 else memset( buffer
, 0, sizeof(*desc
) );
944 fill_context_( file
, line
, buffer
+ sizeof(*desc
), ARRAY_SIZE(buffer
) - sizeof(*desc
) );
945 size
= sizeof(*desc
) + strlen( buffer
+ sizeof(*desc
) ) + 1;
946 ret
= sync_ioctl_( file
, line
, device
, IOCTL_WINETEST_HID_SET_CONTEXT
, buffer
, size
, NULL
, 0, 5000 );
947 ok_(file
, line
)( ret
, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %lu\n", GetLastError() );
949 if (expect
) memcpy( buffer
+ sizeof(*desc
), expect
, expect_size
);
950 else memset( buffer
+ sizeof(*desc
), 0, expect_size
);
952 size
= sizeof(*desc
) + expect_size
;
953 ret
= sync_ioctl_( file
, line
, device
, IOCTL_WINETEST_HID_SET_EXPECT
, buffer
, size
, NULL
, 0, 5000 );
954 ok_(file
, line
)( ret
, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %lu\n", GetLastError() );
957 void wait_hid_expect_( const char *file
, int line
, HANDLE device
, struct hid_device_desc
*desc
,
958 DWORD timeout
, BOOL wait_pending
, BOOL todo
)
960 struct wait_expect_params params
= {.wait_pending
= wait_pending
};
961 char buffer
[sizeof(*desc
) + sizeof(params
)];
964 if (desc
) memcpy( buffer
, desc
, sizeof(*desc
) );
965 else memset( buffer
, 0, sizeof(*desc
) );
967 memcpy( buffer
+ sizeof(*desc
), ¶ms
, sizeof(params
) );
968 size
= sizeof(*desc
) + sizeof(params
);
971 BOOL ret
= sync_ioctl_( file
, line
, device
, IOCTL_WINETEST_HID_WAIT_EXPECT
, buffer
, size
, NULL
, 0, timeout
);
972 ok_(file
, line
)( ret
, "IOCTL_WINETEST_HID_WAIT_EXPECT failed, last error %lu\n", GetLastError() );
975 set_hid_expect_( file
, line
, device
, desc
, NULL
, 0 );
978 void send_hid_input_( const char *file
, int line
, HANDLE device
, struct hid_device_desc
*desc
,
979 struct hid_expect
*expect
, DWORD expect_size
)
981 char buffer
[sizeof(*desc
) + EXPECT_QUEUE_BUFFER_SIZE
];
985 if (desc
) memcpy( buffer
, desc
, sizeof(*desc
) );
986 else memset( buffer
, 0, sizeof(*desc
) );
988 fill_context_( file
, line
, buffer
+ sizeof(*desc
), ARRAY_SIZE(buffer
) - sizeof(*desc
) );
989 size
= sizeof(*desc
) + strlen( buffer
+ sizeof(*desc
) ) + 1;
990 ret
= sync_ioctl_( file
, line
, device
, IOCTL_WINETEST_HID_SET_CONTEXT
, buffer
, size
, NULL
, 0, 5000 );
991 ok_(file
, line
)( ret
, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %lu\n", GetLastError() );
993 if (expect
) memcpy( buffer
+ sizeof(*desc
), expect
, expect_size
);
994 else memset( buffer
+ sizeof(*desc
), 0, expect_size
);
996 size
= sizeof(*desc
) + expect_size
;
997 ret
= sync_ioctl_( file
, line
, device
, IOCTL_WINETEST_HID_SEND_INPUT
, buffer
, size
, NULL
, 0, 5000 );
998 ok_(file
, line
)( ret
, "IOCTL_WINETEST_HID_SEND_INPUT failed, last error %lu\n", GetLastError() );
1001 static void test_hidp_get_input( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1003 struct hid_expect expect
[] =
1006 .code
= IOCTL_HID_GET_INPUT_REPORT
,
1007 .report_id
= report_id
,
1008 .report_len
= report_len
- (report_id
? 0 : 1),
1009 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,2},
1011 .ret_status
= STATUS_SUCCESS
,
1014 .code
= IOCTL_HID_GET_INPUT_REPORT
,
1015 .report_id
= report_id
,
1016 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
1017 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,1},
1019 .ret_status
= STATUS_SUCCESS
,
1023 char buffer
[200], report
[200];
1028 memset( report
, 0xcd, sizeof(report
) );
1029 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed
, report
, report_len
);
1030 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#lx\n", status
);
1032 SetLastError( 0xdeadbeef );
1033 ret
= HidD_GetInputReport( file
, report
, 0 );
1034 ok( !ret
, "HidD_GetInputReport succeeded\n" );
1035 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetInputReport returned error %lu\n", GetLastError() );
1037 SetLastError( 0xdeadbeef );
1038 ret
= HidD_GetInputReport( file
, report
, report_len
- 1 );
1039 ok( !ret
, "HidD_GetInputReport succeeded\n" );
1040 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1041 "HidD_GetInputReport returned error %lu\n", GetLastError() );
1045 struct hid_expect broken_expect
=
1047 .code
= IOCTL_HID_GET_INPUT_REPORT
,
1049 .report_len
= report_len
- 1,
1052 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1053 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1054 0x5a,0x5a,0x5a,0x5a,0x5a,
1057 .ret_status
= STATUS_SUCCESS
,
1060 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1063 SetLastError( 0xdeadbeef );
1064 memset( buffer
, 0x5a, sizeof(buffer
) );
1065 ret
= HidD_GetInputReport( file
, buffer
, report_len
);
1066 if (report_id
|| broken( !ret
) /* w7u */)
1068 ok( !ret
, "HidD_GetInputReport succeeded, last error %lu\n", GetLastError() );
1069 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1070 "HidD_GetInputReport returned error %lu\n", GetLastError() );
1074 ok( ret
, "HidD_GetInputReport failed, last error %lu\n", GetLastError() );
1075 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
1078 set_hid_expect( file
, expect
, sizeof(expect
) );
1080 SetLastError( 0xdeadbeef );
1081 ret
= HidD_GetInputReport( file
, report
, report_len
);
1082 ok( ret
, "HidD_GetInputReport failed, last error %lu\n", GetLastError() );
1083 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
1085 SetLastError( 0xdeadbeef );
1086 length
= report_len
* 2;
1087 ret
= sync_ioctl( file
, IOCTL_HID_GET_INPUT_REPORT
, NULL
, 0, report
, &length
, 5000 );
1088 ok( ret
, "IOCTL_HID_GET_INPUT_REPORT failed, last error %lu\n", GetLastError() );
1089 ok( length
== 3, "got length %lu, expected 3\n", length
);
1090 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
1092 set_hid_expect( file
, NULL
, 0 );
1095 static void test_hidp_get_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1097 struct hid_expect expect
[] =
1100 .code
= IOCTL_HID_GET_FEATURE
,
1101 .report_id
= report_id
,
1102 .report_len
= report_len
- (report_id
? 0 : 1),
1103 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
1105 .ret_status
= STATUS_SUCCESS
,
1108 .code
= IOCTL_HID_GET_FEATURE
,
1109 .report_id
= report_id
,
1110 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
1111 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
1113 .ret_status
= STATUS_SUCCESS
,
1117 char buffer
[200], report
[200];
1122 memset( report
, 0xcd, sizeof(report
) );
1123 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
1124 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#lx\n", status
);
1126 SetLastError( 0xdeadbeef );
1127 ret
= HidD_GetFeature( file
, report
, 0 );
1128 ok( !ret
, "HidD_GetFeature succeeded\n" );
1129 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetFeature returned error %lu\n", GetLastError() );
1131 SetLastError( 0xdeadbeef );
1132 ret
= HidD_GetFeature( file
, report
, report_len
- 1 );
1133 ok( !ret
, "HidD_GetFeature succeeded\n" );
1134 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1135 "HidD_GetFeature returned error %lu\n", GetLastError() );
1139 struct hid_expect broken_expect
=
1141 .code
= IOCTL_HID_GET_FEATURE
,
1143 .report_len
= report_len
- 1,
1146 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1147 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1148 0x5a,0x5a,0x5a,0x5a,0x5a,
1151 .ret_status
= STATUS_SUCCESS
,
1154 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1157 SetLastError( 0xdeadbeef );
1158 memset( buffer
, 0x5a, sizeof(buffer
) );
1159 ret
= HidD_GetFeature( file
, buffer
, report_len
);
1160 if (report_id
|| broken( !ret
))
1162 ok( !ret
, "HidD_GetFeature succeeded, last error %lu\n", GetLastError() );
1163 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1164 "HidD_GetFeature returned error %lu\n", GetLastError() );
1168 ok( ret
, "HidD_GetFeature failed, last error %lu\n", GetLastError() );
1169 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
1172 set_hid_expect( file
, expect
, sizeof(expect
) );
1174 SetLastError( 0xdeadbeef );
1175 ret
= HidD_GetFeature( file
, report
, report_len
);
1176 ok( ret
, "HidD_GetFeature failed, last error %lu\n", GetLastError() );
1177 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
1179 length
= report_len
* 2;
1180 SetLastError( 0xdeadbeef );
1181 ret
= sync_ioctl( file
, IOCTL_HID_GET_FEATURE
, NULL
, 0, report
, &length
, 5000 );
1182 ok( ret
, "IOCTL_HID_GET_FEATURE failed, last error %lu\n", GetLastError() );
1183 ok( length
== 3, "got length %lu, expected 3\n", length
);
1184 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
1186 set_hid_expect( file
, NULL
, 0 );
1189 static void test_hidp_set_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1191 struct hid_expect expect
[] =
1194 .code
= IOCTL_HID_SET_FEATURE
,
1195 .report_id
= report_id
,
1196 .report_len
= report_len
- (report_id
? 0 : 1),
1197 .report_buf
= {report_id
},
1199 .ret_status
= STATUS_SUCCESS
,
1202 .code
= IOCTL_HID_SET_FEATURE
,
1203 .report_id
= report_id
,
1204 .report_len
= report_len
- (report_id
? 0 : 1),
1207 report_id
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1208 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1209 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
1212 .ret_status
= STATUS_SUCCESS
,
1215 char buffer
[200], report
[200];
1220 memset( report
, 0xcd, sizeof(report
) );
1221 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
1222 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#lx\n", status
);
1224 SetLastError( 0xdeadbeef );
1225 ret
= HidD_SetFeature( file
, report
, 0 );
1226 ok( !ret
, "HidD_SetFeature succeeded\n" );
1227 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetFeature returned error %lu\n", GetLastError() );
1229 SetLastError( 0xdeadbeef );
1230 ret
= HidD_SetFeature( file
, report
, report_len
- 1 );
1231 ok( !ret
, "HidD_SetFeature succeeded\n" );
1232 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1233 "HidD_SetFeature returned error %lu\n", GetLastError() );
1237 struct hid_expect broken_expect
=
1239 .code
= IOCTL_HID_SET_FEATURE
,
1241 .report_len
= report_len
- 1,
1244 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1245 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1246 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1247 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1250 .ret_status
= STATUS_SUCCESS
,
1253 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1256 SetLastError( 0xdeadbeef );
1257 memset( buffer
, 0x5a, sizeof(buffer
) );
1258 ret
= HidD_SetFeature( file
, buffer
, report_len
);
1259 if (report_id
|| broken( !ret
))
1261 ok( !ret
, "HidD_SetFeature succeeded, last error %lu\n", GetLastError() );
1262 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1263 "HidD_SetFeature returned error %lu\n", GetLastError() );
1267 ok( ret
, "HidD_SetFeature failed, last error %lu\n", GetLastError() );
1270 set_hid_expect( file
, expect
, sizeof(expect
) );
1272 SetLastError( 0xdeadbeef );
1273 ret
= HidD_SetFeature( file
, report
, report_len
);
1274 ok( ret
, "HidD_SetFeature failed, last error %lu\n", GetLastError() );
1276 length
= report_len
* 2;
1277 SetLastError( 0xdeadbeef );
1278 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, NULL
, 0, report
, &length
, 5000 );
1279 ok( !ret
, "IOCTL_HID_SET_FEATURE succeeded\n" );
1280 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_FEATURE returned error %lu\n",
1283 SetLastError( 0xdeadbeef );
1284 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, report
, report_len
* 2, NULL
, &length
, 5000 );
1285 ok( ret
, "IOCTL_HID_SET_FEATURE failed, last error %lu\n", GetLastError() );
1286 ok( length
== 3, "got length %lu, expected 3\n", length
);
1288 set_hid_expect( file
, NULL
, 0 );
1291 static void test_hidp_set_output( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1293 struct hid_expect expect
[] =
1296 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1297 .report_id
= report_id
,
1298 .report_len
= report_len
- (report_id
? 0 : 1),
1299 .report_buf
= {report_id
},
1301 .ret_status
= STATUS_SUCCESS
,
1304 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1305 .report_id
= report_id
,
1306 .report_len
= report_len
- (report_id
? 0 : 1),
1307 .report_buf
= {report_id
,0,0xcd,0xcd,0xcd},
1309 .ret_status
= STATUS_SUCCESS
,
1313 char buffer
[200], report
[200];
1318 memset( report
, 0xcd, sizeof(report
) );
1319 status
= HidP_InitializeReportForID( HidP_Output
, report_id
, preparsed
, report
, report_len
);
1320 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#lx\n", status
);
1321 memset( report
, 0, report_len
);
1322 report
[0] = report_id
;
1324 SetLastError( 0xdeadbeef );
1325 ret
= HidD_SetOutputReport( file
, report
, 0 );
1326 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1327 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetOutputReport returned error %lu\n",
1330 SetLastError( 0xdeadbeef );
1331 ret
= HidD_SetOutputReport( file
, report
, report_len
- 1 );
1332 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1333 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1334 "HidD_SetOutputReport returned error %lu\n", GetLastError() );
1338 struct hid_expect broken_expect
=
1340 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1342 .report_len
= report_len
- 1,
1343 .report_buf
= {0x5a,0x5a},
1345 .ret_status
= STATUS_SUCCESS
,
1348 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1351 SetLastError( 0xdeadbeef );
1352 memset( buffer
, 0x5a, sizeof(buffer
) );
1353 ret
= HidD_SetOutputReport( file
, buffer
, report_len
);
1354 if (report_id
|| broken( !ret
))
1356 ok( !ret
, "HidD_SetOutputReport succeeded, last error %lu\n", GetLastError() );
1357 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1358 "HidD_SetOutputReport returned error %lu\n", GetLastError() );
1362 ok( ret
, "HidD_SetOutputReport failed, last error %lu\n", GetLastError() );
1365 set_hid_expect( file
, expect
, sizeof(expect
) );
1367 SetLastError( 0xdeadbeef );
1368 ret
= HidD_SetOutputReport( file
, report
, report_len
);
1369 ok( ret
, "HidD_SetOutputReport failed, last error %lu\n", GetLastError() );
1371 length
= report_len
* 2;
1372 SetLastError( 0xdeadbeef );
1373 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, NULL
, 0, report
, &length
, 5000 );
1374 ok( !ret
, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n" );
1375 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
,
1376 "IOCTL_HID_SET_OUTPUT_REPORT returned error %lu\n", GetLastError() );
1378 SetLastError( 0xdeadbeef );
1379 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, report
, report_len
* 2, NULL
, &length
, 5000 );
1380 ok( ret
, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %lu\n", GetLastError() );
1381 ok( length
== 3, "got length %lu, expected 3\n", length
);
1383 set_hid_expect( file
, NULL
, 0 );
1386 static void test_write_file( HANDLE file
, int report_id
, ULONG report_len
)
1388 struct hid_expect expect
=
1390 .code
= IOCTL_HID_WRITE_REPORT
,
1391 .report_id
= report_id
,
1392 .report_len
= report_len
- (report_id
? 0 : 1),
1393 .report_buf
= {report_id
? report_id
: 0xcd,0xcd,0xcd,0xcd,0xcd},
1395 .ret_status
= STATUS_SUCCESS
,
1402 SetLastError( 0xdeadbeef );
1403 ret
= WriteFile( file
, report
, 0, &length
, NULL
);
1404 ok( !ret
, "WriteFile succeeded\n" );
1405 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "WriteFile returned error %lu\n", GetLastError() );
1406 ok( length
== 0, "WriteFile returned %#lx\n", length
);
1407 SetLastError( 0xdeadbeef );
1408 ret
= WriteFile( file
, report
, report_len
- 1, &length
, NULL
);
1409 ok( !ret
, "WriteFile succeeded\n" );
1410 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_USER_BUFFER
,
1411 "WriteFile returned error %lu\n", GetLastError() );
1412 ok( length
== 0, "WriteFile returned %#lx\n", length
);
1414 set_hid_expect( file
, &expect
, sizeof(expect
) );
1416 memset( report
, 0xcd, sizeof(report
) );
1418 SetLastError( 0xdeadbeef );
1419 ret
= WriteFile( file
, report
, report_len
* 2, &length
, NULL
);
1420 if (report_id
|| broken( !ret
) /* w7u */)
1422 ok( !ret
, "WriteFile succeeded\n" );
1423 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "WriteFile returned error %lu\n", GetLastError() );
1424 ok( length
== 0, "WriteFile wrote %lu\n", length
);
1425 SetLastError( 0xdeadbeef );
1426 report
[0] = report_id
;
1427 ret
= WriteFile( file
, report
, report_len
, &length
, NULL
);
1432 ok( ret
, "WriteFile failed, last error %lu\n", GetLastError() );
1433 ok( length
== 2, "WriteFile wrote %lu\n", length
);
1437 ok( ret
, "WriteFile failed, last error %lu\n", GetLastError() );
1438 ok( length
== 3, "WriteFile wrote %lu\n", length
);
1441 set_hid_expect( file
, NULL
, 0 );
1444 static void test_hidp( HANDLE file
, HANDLE async_file
, int report_id
, BOOL polled
, const HIDP_CAPS
*expect_caps
)
1446 const HIDP_BUTTON_CAPS expect_button_caps
[] =
1449 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1450 .ReportID
= report_id
,
1452 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1453 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1454 .LinkCollection
= 1,
1457 .Range
.UsageMin
= 1,
1458 .Range
.UsageMax
= 8,
1459 .Range
.DataIndexMin
= 2,
1460 .Range
.DataIndexMax
= 9,
1463 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1464 .ReportID
= report_id
,
1466 .LinkCollection
= 1,
1467 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1468 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1471 .Range
.UsageMin
= 0x18,
1472 .Range
.UsageMax
= 0x1f,
1473 .Range
.DataIndexMin
= 10,
1474 .Range
.DataIndexMax
= 17,
1477 .UsagePage
= HID_USAGE_PAGE_KEYBOARD
,
1478 .ReportID
= report_id
,
1480 .LinkCollection
= 1,
1481 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1482 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1484 .IsAbsolute
= FALSE
,
1485 .Range
.UsageMin
= 0x8,
1486 .Range
.UsageMax
= 0xf,
1487 .Range
.DataIndexMin
= 18,
1488 .Range
.DataIndexMax
= 25,
1491 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1492 .ReportID
= report_id
,
1494 .LinkCollection
= 1,
1495 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1496 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1499 .NotRange
.Usage
= 0x20,
1500 .NotRange
.Reserved1
= 0x20,
1501 .NotRange
.DataIndex
= 26,
1502 .NotRange
.Reserved4
= 26,
1505 const HIDP_VALUE_CAPS expect_value_caps
[] =
1508 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1509 .ReportID
= report_id
,
1511 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1512 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1513 .LinkCollection
= 1,
1519 .NotRange
.Usage
= HID_USAGE_GENERIC_Y
,
1520 .NotRange
.Reserved1
= HID_USAGE_GENERIC_Y
,
1523 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1524 .ReportID
= report_id
,
1526 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1527 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1528 .LinkCollection
= 1,
1534 .NotRange
.Usage
= HID_USAGE_GENERIC_X
,
1535 .NotRange
.Reserved1
= HID_USAGE_GENERIC_X
,
1536 .NotRange
.DataIndex
= 1,
1537 .NotRange
.Reserved4
= 1,
1540 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1541 .ReportID
= report_id
,
1543 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1544 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1545 .LinkCollection
= 1,
1550 .Range
.UsageMin
= 0x21,
1551 .Range
.UsageMax
= 0x22,
1552 .Range
.DataIndexMin
= 27,
1553 .Range
.DataIndexMax
= 28,
1556 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1557 .ReportID
= report_id
,
1559 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1560 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1561 .LinkCollection
= 1,
1567 .NotRange
.Usage
= HID_USAGE_GENERIC_HATSWITCH
,
1568 .NotRange
.Reserved1
= HID_USAGE_GENERIC_HATSWITCH
,
1569 .NotRange
.DataIndex
= 29,
1570 .NotRange
.Reserved4
= 29,
1573 static const HIDP_LINK_COLLECTION_NODE expect_collections
[] =
1576 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1577 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1578 .CollectionType
= 1,
1579 .NumberOfChildren
= 8,
1583 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1584 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1585 .CollectionType
= 2,
1588 static const HIDP_DATA expect_data
[] =
1590 { .DataIndex
= 0, },
1591 { .DataIndex
= 1, },
1592 { .DataIndex
= 5, .RawValue
= 1, },
1593 { .DataIndex
= 7, .RawValue
= 1, },
1594 { .DataIndex
= 19, .RawValue
= 1, },
1595 { .DataIndex
= 21, .RawValue
= 1, },
1596 { .DataIndex
= 30, },
1597 { .DataIndex
= 31, },
1598 { .DataIndex
= 32, .RawValue
= 0xfeedcafe, },
1599 { .DataIndex
= 37, .RawValue
= 1, },
1600 { .DataIndex
= 39, .RawValue
= 1, },
1603 DWORD waveform_list
, collection_count
, generic_output_list
;
1604 OVERLAPPED overlapped
= {0}, overlapped2
= {0};
1605 HIDP_LINK_COLLECTION_NODE collections
[16];
1606 PHIDP_PREPARSED_DATA preparsed_data
;
1607 USAGE_AND_PAGE usage_and_pages
[16];
1608 HIDP_BUTTON_CAPS button_caps
[32];
1609 HIDP_VALUE_CAPS value_caps
[16];
1610 char buffer
[200], report
[200];
1620 SetLastError( 0xdeadbeef );
1621 ret
= HidD_GetPhysicalDescriptor( file
, buffer
, sizeof(buffer
) );
1622 ok( !ret
, "HidD_GetPhysicalDescriptor succeeded\n" );
1623 ok( GetLastError() == ERROR_NOT_SUPPORTED
, "got error %lu\n", GetLastError() );
1625 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
1626 ok( ret
, "HidD_GetPreparsedData failed with error %lu\n", GetLastError() );
1628 memset( buffer
, 0, sizeof(buffer
) );
1629 status
= HidP_GetCaps( (PHIDP_PREPARSED_DATA
)buffer
, &caps
);
1630 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetCaps returned %#lx\n", status
);
1631 status
= HidP_GetCaps( preparsed_data
, &caps
);
1632 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetCaps returned %#lx\n", status
);
1633 check_hidp_caps( &caps
, expect_caps
);
1635 collection_count
= 0;
1636 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1637 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetLinkCollectionNodes returned %#lx\n", status
);
1638 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1639 "got %ld collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1640 collection_count
= ARRAY_SIZE(collections
);
1641 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, (PHIDP_PREPARSED_DATA
)buffer
);
1642 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetLinkCollectionNodes returned %#lx\n", status
);
1643 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1644 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetLinkCollectionNodes returned %#lx\n", status
);
1645 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1646 "got %ld collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1648 for (i
= 0; i
< ARRAY_SIZE(expect_collections
); ++i
)
1650 winetest_push_context( "collections[%d]", i
);
1651 check_hidp_link_collection_node( &collections
[i
], &expect_collections
[i
] );
1652 winetest_pop_context();
1655 count
= ARRAY_SIZE(button_caps
);
1656 status
= HidP_GetButtonCaps( HidP_Output
, button_caps
, &count
, preparsed_data
);
1657 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetButtonCaps returned %#lx\n", status
);
1658 status
= HidP_GetButtonCaps( HidP_Feature
+ 1, button_caps
, &count
, preparsed_data
);
1659 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetButtonCaps returned %#lx\n", status
);
1661 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1662 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetButtonCaps returned %#lx\n", status
);
1663 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1664 count
, caps
.NumberInputButtonCaps
);
1665 count
= ARRAY_SIZE(button_caps
);
1666 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1667 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetButtonCaps returned %#lx\n", status
);
1668 memset( button_caps
, 0, sizeof(button_caps
) );
1669 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1670 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetButtonCaps returned %#lx\n", status
);
1671 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1672 count
, caps
.NumberInputButtonCaps
);
1674 for (i
= 0; i
< ARRAY_SIZE(expect_button_caps
); ++i
)
1676 winetest_push_context( "button_caps[%d]", i
);
1677 check_hidp_button_caps( &button_caps
[i
], &expect_button_caps
[i
] );
1678 winetest_pop_context();
1681 count
= ARRAY_SIZE(button_caps
) - 1;
1682 status
= HidP_GetSpecificButtonCaps( HidP_Output
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1683 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1684 status
= HidP_GetSpecificButtonCaps( HidP_Feature
+ 1, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1685 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1687 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1688 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1689 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1690 count
, caps
.NumberInputButtonCaps
);
1691 count
= ARRAY_SIZE(button_caps
) - 1;
1692 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1693 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1695 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
+ 1, &count
, preparsed_data
);
1696 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1697 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1698 count
, caps
.NumberInputButtonCaps
);
1699 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1701 status
= HidP_GetSpecificButtonCaps( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, 5, button_caps
+ 1,
1702 &count
, preparsed_data
);
1703 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1704 ok( count
== 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 1 );
1705 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1708 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0xfffe, 0, 0, button_caps
, &count
, preparsed_data
);
1709 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1710 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1712 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0xfffe, 0, button_caps
, &count
, preparsed_data
);
1713 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1714 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1716 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0xfffe, button_caps
, &count
, preparsed_data
);
1717 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#lx\n", status
);
1718 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1720 count
= ARRAY_SIZE(value_caps
);
1721 status
= HidP_GetValueCaps( HidP_Output
, value_caps
, &count
, preparsed_data
);
1722 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetValueCaps returned %#lx\n", status
);
1723 status
= HidP_GetValueCaps( HidP_Feature
+ 1, value_caps
, &count
, preparsed_data
);
1724 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetValueCaps returned %#lx\n", status
);
1726 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1727 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetValueCaps returned %#lx\n", status
);
1728 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1729 count
, caps
.NumberInputValueCaps
);
1730 count
= ARRAY_SIZE(value_caps
);
1731 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1732 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetValueCaps returned %#lx\n", status
);
1733 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1734 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetValueCaps returned %#lx\n", status
);
1735 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1736 count
, caps
.NumberInputValueCaps
);
1738 for (i
= 0; i
< ARRAY_SIZE(expect_value_caps
); ++i
)
1740 winetest_push_context( "value_caps[%d]", i
);
1741 check_hidp_value_caps( &value_caps
[i
], &expect_value_caps
[i
] );
1742 winetest_pop_context();
1745 count
= ARRAY_SIZE(value_caps
) - 4;
1746 status
= HidP_GetSpecificValueCaps( HidP_Output
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1747 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1748 status
= HidP_GetSpecificValueCaps( HidP_Feature
+ 1, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1749 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1751 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1752 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1753 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1754 count
, caps
.NumberInputValueCaps
);
1755 count
= ARRAY_SIZE(value_caps
) - 4;
1756 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1757 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1759 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, preparsed_data
);
1760 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1761 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1762 count
, caps
.NumberInputValueCaps
);
1763 check_hidp_value_caps( &value_caps
[4], &value_caps
[0] );
1764 check_hidp_value_caps( &value_caps
[5], &value_caps
[1] );
1765 check_hidp_value_caps( &value_caps
[6], &value_caps
[2] );
1766 check_hidp_value_caps( &value_caps
[7], &value_caps
[3] );
1769 status
= HidP_GetSpecificValueCaps( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1770 value_caps
+ 4, &count
, preparsed_data
);
1771 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1772 ok( count
== 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 1 );
1773 check_hidp_value_caps( &value_caps
[4], &value_caps
[3] );
1776 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0xfffe, 0, 0, value_caps
, &count
, preparsed_data
);
1777 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1778 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1780 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0xfffe, 0, value_caps
, &count
, preparsed_data
);
1781 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1782 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1784 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0xfffe, value_caps
, &count
, preparsed_data
);
1785 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#lx\n", status
);
1786 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1788 status
= HidP_InitializeReportForID( HidP_Input
, 0, (PHIDP_PREPARSED_DATA
)buffer
, report
, sizeof(report
) );
1789 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_InitializeReportForID returned %#lx\n", status
);
1790 status
= HidP_InitializeReportForID( HidP_Feature
+ 1, 0, preparsed_data
, report
, sizeof(report
) );
1791 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_InitializeReportForID returned %#lx\n", status
);
1792 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, sizeof(report
) );
1793 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#lx\n", status
);
1794 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, caps
.InputReportByteLength
+ 1 );
1795 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#lx\n", status
);
1796 status
= HidP_InitializeReportForID( HidP_Input
, 1 - report_id
, preparsed_data
, report
,
1797 caps
.InputReportByteLength
);
1798 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#lx\n", status
);
1800 memset( report
, 0xcd, sizeof(report
) );
1801 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
1802 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#lx\n", status
);
1804 memset( buffer
, 0xcd, sizeof(buffer
) );
1805 memset( buffer
, 0, caps
.InputReportByteLength
);
1806 buffer
[0] = report_id
;
1807 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1809 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1810 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1811 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValueArray returned %#lx\n", status
);
1812 memset( buffer
, 0xa5, sizeof(buffer
) );
1813 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1814 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1815 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#lx\n", status
);
1816 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1817 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1818 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#lx\n", status
);
1819 ok( report
[16] == (char)0xa5, "got report value %d\n", report
[16] );
1820 ok( report
[17] == (char)0xa5, "got report value %d\n", report
[17] );
1824 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1825 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1826 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1827 ok( report
[16] == (char)8, "got value %#x\n", report
[16] );
1828 ok( report
[17] == (char)0, "got value %#x\n", report
[17] );
1830 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1831 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1832 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_GetUsageValueArray returned %#lx\n", status
);
1833 memset( buffer
, 0xa5, sizeof(buffer
) );
1834 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1835 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1836 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#lx\n", status
);
1839 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1840 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1841 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#lx\n", status
);
1842 ok( buffer
[0] == (char)0xcd, "got report value %#x\n", buffer
[0] );
1843 ok( buffer
[1] == (char)0xcd, "got report value %#x\n", buffer
[1] );
1845 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, 0, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1846 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#lx\n", status
);
1847 status
= HidP_GetUsageValue( HidP_Input
, 0, 0, HID_USAGE_GENERIC_X
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1848 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#lx\n", status
);
1852 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1853 &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1854 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
1855 ok( value
== 0xffff, "got value %ld\n", value
);
1858 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1859 preparsed_data
, report
, caps
.InputReportByteLength
);
1860 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1862 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, &value
,
1863 preparsed_data
, report
, caps
.InputReportByteLength
);
1864 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
1865 ok( value
== 0x80, "got value %#lx, expected %#x\n", value
, 0x80 );
1867 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1868 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1869 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1870 ok( value
== -128, "got value %#lx, expected %#x\n", value
, -128 );
1873 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1874 preparsed_data
, report
, caps
.InputReportByteLength
);
1875 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1877 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1878 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1879 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1880 ok( value
== 127, "got value %#lx, expected %#x\n", value
, 127 );
1883 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1884 preparsed_data
, report
, caps
.InputReportByteLength
);
1885 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1887 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1888 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1889 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1890 ok( value
== 0, "got value %#lx, expected %#x\n", value
, 0 );
1893 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1894 preparsed_data
, report
, caps
.InputReportByteLength
);
1895 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1897 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1898 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1899 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1900 ok( value
== 0, "got value %#lx, expected %#x\n", value
, 0 );
1902 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, &value
,
1903 preparsed_data
, report
, caps
.InputReportByteLength
);
1904 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
1905 ok( value
== 0x7fffffff, "got value %#lx, expected %#x\n", value
, 0x7fffffff );
1908 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1909 preparsed_data
, report
, caps
.InputReportByteLength
);
1910 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1912 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1913 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1914 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1915 ok( value
== 0x7fffffff, "got value %#lx, expected %#x\n", value
, 0x7fffffff );
1918 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1919 preparsed_data
, report
, caps
.InputReportByteLength
);
1920 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1922 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1923 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1924 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1925 ok( value
== 0x80000000, "got value %#lx, expected %#x\n", value
, 0x80000000 );
1928 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
, value
,
1929 preparsed_data
, report
, caps
.InputReportByteLength
);
1930 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1932 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
1933 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1934 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1935 ok( value
== 0, "got value %#lx, expected %#x\n", value
, 0 );
1938 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
, value
,
1939 preparsed_data
, report
, caps
.InputReportByteLength
);
1940 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
1942 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1943 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1944 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1945 ok( value
== 0, "got value %#lx, expected %#x\n", value
, 0 );
1946 status
= HidP_SetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1947 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1948 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
1950 value
= HidP_MaxUsageListLength( HidP_Feature
+ 1, 0, preparsed_data
);
1951 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %ld, expected %d\n", value
, 0 );
1952 value
= HidP_MaxUsageListLength( HidP_Input
, 0, preparsed_data
);
1953 ok( value
== 50, "HidP_MaxUsageListLength(HidP_Input, 0) returned %ld, expected %d\n", value
, 50 );
1954 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1955 ok( value
== 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %ld, expected %d\n",
1957 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_LED
, preparsed_data
);
1958 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %ld, expected %d\n",
1960 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1961 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %ld, expected %d\n",
1963 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_LED
, preparsed_data
);
1964 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %ld, expected %d\n",
1969 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1970 report
, caps
.InputReportByteLength
);
1971 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#lx\n", status
);
1975 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1976 report
, caps
.InputReportByteLength
);
1977 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#lx\n", status
);
1981 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1982 report
, caps
.InputReportByteLength
);
1983 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#lx\n", status
);
1987 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
1988 report
, caps
.InputReportByteLength
);
1989 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#lx\n", status
);
1991 value
= ARRAY_SIZE(usages
);
1992 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1993 report
, caps
.InputReportByteLength
);
1994 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#lx\n", status
);
1995 ok( value
== 0, "got usage count %ld, expected %d\n", value
, 2 );
2001 ok( report
[6] == 0, "got report[6] %x expected 0\n", report
[6] );
2002 ok( report
[7] == 0, "got report[7] %x expected 0\n", report
[7] );
2003 memcpy( buffer
, report
, caps
.InputReportByteLength
);
2004 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
2005 report
, caps
.InputReportByteLength
);
2006 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsages returned %#lx\n", status
);
2009 ok( !memcmp( buffer
, report
, caps
.InputReportByteLength
), "unexpected report data\n" );
2011 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, 1, preparsed_data
, report
,
2012 caps
.InputReportByteLength
);
2013 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#lx\n", status
);
2016 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, &value
, preparsed_data
,
2017 report
, caps
.InputReportByteLength
);
2018 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#lx\n", status
);
2019 ok( value
== 0xdeadbeef, "got value %#lx, expected %#x\n", value
, 0xdeadbeef );
2022 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
2023 report
, caps
.InputReportByteLength
);
2024 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsages returned %#lx\n", status
);
2025 ok( value
== 2, "got usage count %ld, expected %d\n", value
, 2 );
2026 value
= ARRAY_SIZE(usages
);
2027 memset( usages
, 0xcd, sizeof(usages
) );
2028 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
2029 report
, caps
.InputReportByteLength
);
2030 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#lx\n", status
);
2031 ok( value
== 2, "got usage count %ld, expected %d\n", value
, 2 );
2032 ok( usages
[0] == 4, "got usages[0] %x, expected %x\n", usages
[0], 4 );
2033 ok( usages
[1] == 6, "got usages[1] %x, expected %x\n", usages
[1], 6 );
2035 value
= ARRAY_SIZE(usages
);
2036 memset( usages
, 0xcd, sizeof(usages
) );
2037 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
2038 report
, caps
.InputReportByteLength
);
2039 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#lx\n", status
);
2040 ok( value
== 2, "got usage count %ld, expected %d\n", value
, 2 );
2041 ok( usages
[0] == 6, "got usages[0] %x, expected %x\n", usages
[0], 6 );
2042 ok( usages
[1] == 4, "got usages[1] %x, expected %x\n", usages
[1], 4 );
2044 value
= ARRAY_SIZE(usage_and_pages
);
2045 memset( usage_and_pages
, 0xcd, sizeof(usage_and_pages
) );
2046 status
= HidP_GetUsagesEx( HidP_Input
, 0, usage_and_pages
, &value
, preparsed_data
, report
,
2047 caps
.InputReportByteLength
);
2048 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsagesEx returned %#lx\n", status
);
2049 ok( value
== 6, "got usage count %ld, expected %d\n", value
, 4 );
2050 ok( usage_and_pages
[0].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[0] UsagePage %x, expected %x\n",
2051 usage_and_pages
[0].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2052 ok( usage_and_pages
[1].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[1] UsagePage %x, expected %x\n",
2053 usage_and_pages
[1].UsagePage
, HID_USAGE_PAGE_BUTTON
);
2054 ok( usage_and_pages
[2].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[2] UsagePage %x, expected %x\n",
2055 usage_and_pages
[2].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
2056 ok( usage_and_pages
[3].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[3] UsagePage %x, expected %x\n",
2057 usage_and_pages
[3].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
2058 ok( usage_and_pages
[4].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[4] UsagePage %x, expected %x\n",
2059 usage_and_pages
[4].UsagePage
, HID_USAGE_PAGE_LED
);
2060 ok( usage_and_pages
[5].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[5] UsagePage %x, expected %x\n",
2061 usage_and_pages
[5].UsagePage
, HID_USAGE_PAGE_LED
);
2062 ok( usage_and_pages
[0].Usage
== 4, "got usage_and_pages[0] Usage %x, expected %x\n",
2063 usage_and_pages
[0].Usage
, 4 );
2064 ok( usage_and_pages
[1].Usage
== 6, "got usage_and_pages[1] Usage %x, expected %x\n",
2065 usage_and_pages
[1].Usage
, 6 );
2066 ok( usage_and_pages
[2].Usage
== 9, "got usage_and_pages[2] Usage %x, expected %x\n",
2067 usage_and_pages
[2].Usage
, 9 );
2068 ok( usage_and_pages
[3].Usage
== 11, "got usage_and_pages[3] Usage %x, expected %x\n",
2069 usage_and_pages
[3].Usage
, 11 );
2070 ok( usage_and_pages
[4].Usage
== 6, "got usage_and_pages[4] Usage %x, expected %x\n",
2071 usage_and_pages
[4].Usage
, 6 );
2072 ok( usage_and_pages
[5].Usage
== 4, "got usage_and_pages[5] Usage %x, expected %x\n",
2073 usage_and_pages
[5].Usage
, 4 );
2075 value
= HidP_MaxDataListLength( HidP_Feature
+ 1, preparsed_data
);
2076 ok( value
== 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %ld, expected %d\n", value
, 0 );
2077 value
= HidP_MaxDataListLength( HidP_Input
, preparsed_data
);
2078 ok( value
== 58, "HidP_MaxDataListLength(HidP_Input) returned %ld, expected %d\n", value
, 58 );
2079 value
= HidP_MaxDataListLength( HidP_Output
, preparsed_data
);
2080 ok( value
== 0, "HidP_MaxDataListLength(HidP_Output) returned %ld, expected %d\n", value
, 0 );
2081 value
= HidP_MaxDataListLength( HidP_Feature
, preparsed_data
);
2082 ok( value
== 24, "HidP_MaxDataListLength(HidP_Feature) returned %ld, expected %d\n", value
, 24 );
2085 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2086 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetData returned %#lx\n", status
);
2087 ok( value
== 11, "got data count %ld, expected %d\n", value
, 11 );
2088 memset( data
, 0, sizeof(data
) );
2089 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
2090 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetData returned %#lx\n", status
);
2091 for (i
= 0; i
< ARRAY_SIZE(expect_data
); ++i
)
2093 winetest_push_context( "data[%d]", i
);
2094 check_member( data
[i
], expect_data
[i
], "%d", DataIndex
);
2095 check_member( data
[i
], expect_data
[i
], "%ld", RawValue
);
2096 winetest_pop_context();
2099 /* HID nary usage collections are set with 1-based usage index in their declaration order */
2101 memset( report
, 0, caps
.InputReportByteLength
);
2102 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
2103 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#lx\n", status
);
2107 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
2108 report
, caps
.InputReportByteLength
);
2109 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#lx\n", status
);
2110 ok( report
[caps
.InputReportByteLength
- 2] == 3, "unexpected usage index %d, expected 3\n",
2111 report
[caps
.InputReportByteLength
- 2] );
2112 ok( report
[caps
.InputReportByteLength
- 1] == 4, "unexpected usage index %d, expected 4\n",
2113 report
[caps
.InputReportByteLength
- 1] );
2114 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
2115 preparsed_data
, report
, caps
.InputReportByteLength
);
2116 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_UnsetUsages returned %#lx\n", status
);
2117 ok( report
[caps
.InputReportByteLength
- 2] == 0, "unexpected usage index %d, expected 0\n",
2118 report
[caps
.InputReportByteLength
- 2] );
2119 ok( report
[caps
.InputReportByteLength
- 1] == 0, "unexpected usage index %d, expected 0\n",
2120 report
[caps
.InputReportByteLength
- 1] );
2121 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
2122 preparsed_data
, report
, caps
.InputReportByteLength
);
2123 ok( status
== HIDP_STATUS_BUTTON_NOT_PRESSED
, "HidP_UnsetUsages returned %#lx\n", status
);
2126 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
2127 report
, caps
.InputReportByteLength
);
2128 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#lx\n", status
);
2129 ok( report
[caps
.InputReportByteLength
- 2] == 1, "unexpected usage index %d, expected 1\n",
2130 report
[caps
.InputReportByteLength
- 2] );
2132 memset( report
, 0xcd, sizeof(report
) );
2133 status
= HidP_InitializeReportForID( HidP_Feature
, 3, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2134 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#lx\n", status
);
2136 memset( report
, 0xcd, sizeof(report
) );
2137 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed_data
, report
,
2138 caps
.FeatureReportByteLength
);
2139 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#lx\n", status
);
2141 memset( buffer
, 0xcd, sizeof(buffer
) );
2142 memset( buffer
, 0, caps
.FeatureReportByteLength
);
2143 buffer
[0] = report_id
;
2144 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
2146 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
2148 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_HAPTICS
) continue;
2149 if (collections
[i
].LinkUsage
== HID_USAGE_HAPTICS_WAVEFORM_LIST
) break;
2151 ok( i
< caps
.NumberLinkCollectionNodes
,
2152 "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n" );
2155 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2156 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, (PHIDP_PREPARSED_DATA
)buffer
,
2157 report
, caps
.FeatureReportByteLength
);
2158 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_SetUsageValue returned %#lx\n", status
);
2159 status
= HidP_SetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2160 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2161 caps
.FeatureReportByteLength
);
2162 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_SetUsageValue returned %#lx\n", status
);
2163 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2164 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2165 caps
.FeatureReportByteLength
+ 1 );
2166 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_SetUsageValue returned %#lx\n", status
);
2167 report
[0] = 1 - report_id
;
2168 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2169 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2170 caps
.FeatureReportByteLength
);
2171 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2172 "HidP_SetUsageValue returned %#lx\n", status
);
2174 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2175 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2176 caps
.FeatureReportByteLength
);
2177 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_SetUsageValue returned %#lx\n", status
);
2178 report
[0] = report_id
;
2179 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
,
2180 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2181 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#lx\n", status
);
2183 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
2184 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
2185 caps
.FeatureReportByteLength
);
2186 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
2188 memset( buffer
, 0xcd, sizeof(buffer
) );
2189 memset( buffer
, 0, caps
.FeatureReportByteLength
);
2190 buffer
[0] = report_id
;
2191 value
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
2192 memcpy( buffer
+ 1, &value
, 2 );
2193 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
2195 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2196 (PHIDP_PREPARSED_DATA
)buffer
, report
, caps
.FeatureReportByteLength
);
2197 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetUsageValue returned %#lx\n", status
);
2198 status
= HidP_GetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2199 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2200 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetUsageValue returned %#lx\n", status
);
2201 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2202 preparsed_data
, report
, caps
.FeatureReportByteLength
+ 1 );
2203 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_GetUsageValue returned %#lx\n", status
);
2204 report
[0] = 1 - report_id
;
2205 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2206 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2207 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
2208 "HidP_GetUsageValue returned %#lx\n", status
);
2210 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2211 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2212 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_GetUsageValue returned %#lx\n", status
);
2213 report
[0] = report_id
;
2214 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, &value
,
2215 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2216 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#lx\n", status
);
2219 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2220 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2221 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
2222 ok( value
== HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, "got value %#lx, expected %#x\n", value
,
2223 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
);
2225 memset( buffer
, 0xff, sizeof(buffer
) );
2226 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2227 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
2228 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2229 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#lx\n", status
);
2230 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2231 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
2232 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2233 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#lx\n", status
);
2234 ok( !memcmp( report
+ 9, buffer
, 8 ), "unexpected report data\n" );
2236 memset( buffer
, 0, sizeof(buffer
) );
2237 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2238 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
2239 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2240 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#lx\n", status
);
2241 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2242 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
2243 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2244 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#lx\n", status
);
2245 memset( buffer
+ 16, 0xff, 8 );
2246 ok( !memcmp( buffer
, buffer
+ 16, 16 ), "unexpected report value\n" );
2249 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2250 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2251 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
2253 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2254 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2255 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
2256 ok( value
== 0, "got value %#lx, expected %#x\n", value
, 0 );
2258 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2259 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2260 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
2261 ok( value
== 0x7fffffff, "got value %#lx, expected %#x\n", value
, 0x7fffffff );
2264 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2265 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2266 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
2268 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2269 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2270 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
2271 ok( value
== 0x0003ffff, "got value %#lx, expected %#x\n", value
, 0x0003ffff );
2274 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2275 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2276 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
2278 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2279 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2280 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
2281 ok( value
== 0xfff90000, "got value %#lx, expected %#x\n", value
, 0xfff90000 );
2282 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2283 0x1000, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2284 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#lx\n", status
);
2286 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2287 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2288 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
2289 ok( value
== 0xfffff518, "got value %#lx, expected %#x\n", value
, 0xfffff518 );
2290 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2291 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2292 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#lx\n", status
);
2294 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2295 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2296 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
2297 ok( value
== 0xfffff45e, "got value %#lx, expected %#x\n", value
, 0xfffff45e );
2298 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2299 0xdead, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2300 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#lx\n", status
);
2302 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2303 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2304 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
2305 ok( value
== 0xfffffe7d, "got value %#lx, expected %#x\n", value
, 0xfffffe7d );
2306 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2307 0xbeef, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2308 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#lx\n", status
);
2310 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2311 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2312 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#lx\n", status
);
2313 ok( value
== 0xfffffd0b, "got value %#lx, expected %#x\n", value
, 0xfffffd0b );
2315 memset( report
, 0xcd, sizeof(report
) );
2316 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed_data
, report
,
2317 caps
.FeatureReportByteLength
);
2318 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#lx\n", status
);
2320 memset( buffer
, 0xcd, sizeof(buffer
) );
2321 memset( buffer
, 0, caps
.FeatureReportByteLength
);
2322 buffer
[0] = report_id
;
2323 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
2325 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
2327 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_GENERIC
) continue;
2328 if (collections
[i
].LinkUsage
== HID_USAGE_GENERIC_SYSTEM_CTL
) break;
2330 ok( i
< caps
.NumberLinkCollectionNodes
, "HID_USAGE_GENERIC_SYSTEM_CTL collection not found\n" );
2331 generic_output_list
= i
;
2333 for (i
= 0; i
< 5; ++i
)
2335 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, generic_output_list
, i
+ 1,
2336 i
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2337 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
2339 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, generic_output_list
, i
+ 1,
2340 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2341 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#lx\n", status
);
2342 ok( value
== i
, "got value %#lx, expected %#x\n", value
, i
);
2344 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, generic_output_list
, i
+ 1, (void *)&value
,
2345 sizeof(value
), preparsed_data
, report
, caps
.FeatureReportByteLength
);
2346 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValue returned %#lx\n", status
);
2347 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, generic_output_list
, i
+ 1, (void *)&value
,
2348 sizeof(value
), preparsed_data
, report
, caps
.FeatureReportByteLength
);
2349 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValue returned %#lx\n", status
);
2353 for (i
= 5; i
< 10; ++i
)
2355 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, generic_output_list
, i
+ 1,
2356 i
* 16, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2357 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#lx\n", status
);
2359 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, generic_output_list
, i
+ 1,
2360 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2361 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#lx\n", status
);
2362 ok( value
== i
* 16, "got value %#lx, expected %#x\n", value
, i
* 16 );
2366 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
2368 test_hidp_get_input( file
, report_id
, caps
.InputReportByteLength
, preparsed_data
);
2369 test_hidp_get_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2370 test_hidp_set_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2371 test_hidp_set_output( file
, report_id
, caps
.OutputReportByteLength
, preparsed_data
);
2372 test_write_file( file
, report_id
, caps
.OutputReportByteLength
);
2374 memset( report
, 0xcd, sizeof(report
) );
2375 SetLastError( 0xdeadbeef );
2376 ret
= ReadFile( file
, report
, 0, &value
, NULL
);
2377 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %lu\n",
2379 ok( value
== 0, "ReadFile returned %lx\n", value
);
2380 SetLastError( 0xdeadbeef );
2381 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
- 1, &value
, NULL
);
2382 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %lu\n",
2384 ok( value
== 0, "ReadFile returned %lx\n", value
);
2388 struct hid_expect expect
[] =
2391 .code
= IOCTL_HID_READ_REPORT
,
2392 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2393 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0},
2395 .ret_status
= STATUS_SUCCESS
,
2398 .code
= IOCTL_HID_READ_REPORT
,
2399 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2400 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,1},
2402 .ret_status
= STATUS_SUCCESS
,
2405 struct hid_expect expect_small
[] =
2408 .code
= IOCTL_HID_READ_REPORT
,
2409 .report_len
= report_id
? 2 : caps
.InputReportByteLength
- 1,
2410 .report_buf
= {report_id
? report_id
+ 1 : 0x5a,0x5a,0x5a},
2411 .ret_length
= report_id
? 2 : caps
.InputReportByteLength
- 1,
2412 .ret_status
= STATUS_SUCCESS
,
2416 send_hid_input( file
, expect
, sizeof(expect
) );
2418 memset( report
, 0xcd, sizeof(report
) );
2419 SetLastError( 0xdeadbeef );
2420 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
, &value
, NULL
);
2421 ok( ret
, "ReadFile failed, last error %lu\n", GetLastError() );
2422 ok( value
== (report_id
? 3 : 4), "ReadFile returned %lx\n", value
);
2423 ok( report
[0] == report_id
, "unexpected report data\n" );
2425 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2426 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2428 /* drain available input reports */
2429 SetLastError( 0xdeadbeef );
2430 while (ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
))
2431 ResetEvent( overlapped
.hEvent
);
2432 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2433 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2434 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2435 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %lu, expected %u\n",
2436 value
, (report_id
? 3 : 4) );
2437 ResetEvent( overlapped
.hEvent
);
2439 memcpy( buffer
, report
, caps
.InputReportByteLength
);
2440 memcpy( buffer
+ caps
.InputReportByteLength
, report
, caps
.InputReportByteLength
);
2442 SetLastError( 0xdeadbeef );
2443 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2444 ok( !ret
, "ReadFile succeeded\n" );
2445 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2447 SetLastError( 0xdeadbeef );
2448 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2449 ok( !ret
, "ReadFile succeeded\n" );
2450 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2452 /* wait for second report to be ready */
2453 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2454 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2455 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %lu, expected %u\n",
2456 value
, (report_id
? 3 : 4) );
2457 /* first report should be ready and the same */
2458 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2459 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2460 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %lu, expected %u\n",
2461 value
, (report_id
? 3 : 4) );
2462 ok( memcmp( report
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
),
2463 "expected different report\n" );
2464 ok( !memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected identical reports\n" );
2467 SetLastError( 0xdeadbeef );
2468 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &value
, sizeof(ULONG
), NULL
, NULL
, 5000 );
2469 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2473 SetLastError( 0xdeadbeef );
2474 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2475 ok( !ret
, "ReadFile succeeded\n" );
2476 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2478 SetLastError( 0xdeadbeef );
2479 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2480 ok( !ret
, "ReadFile succeeded\n" );
2481 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2483 /* wait for second report to be ready */
2484 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2485 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2486 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %lu, expected %u\n",
2487 value
, (report_id
? 3 : 4) );
2488 /* first report should be ready */
2489 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2490 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2491 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %lu, expected %u\n",
2492 value
, (report_id
? 3 : 4) );
2494 send_hid_input( file
, expect_small
, sizeof(expect_small
) );
2498 SetLastError( 0xdeadbeef );
2499 memset( report
, 0, sizeof(report
) );
2500 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2501 ok( !ret
, "ReadFile succeeded\n" );
2502 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2504 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2505 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2506 ok( value
== report_id
? 2 : caps
.InputReportByteLength
- 1,
2507 "got length %lu, expected %u\n", value
, report_id
? 2 : caps
.InputReportByteLength
- 1 );
2509 CloseHandle( overlapped
.hEvent
);
2510 CloseHandle( overlapped2
.hEvent
);
2514 struct hid_expect expect
[] =
2517 .code
= IOCTL_HID_READ_REPORT
,
2518 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2519 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
2521 .ret_status
= STATUS_SUCCESS
,
2524 .code
= IOCTL_HID_READ_REPORT
,
2525 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2526 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5,0xa5,0xa5},
2527 .ret_length
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2528 .ret_status
= STATUS_SUCCESS
,
2531 struct hid_expect expect_small
[] =
2534 .code
= IOCTL_HID_READ_REPORT
,
2535 .report_len
= report_id
? 2 : caps
.InputReportByteLength
- 1,
2536 .report_buf
= {report_id
? report_id
+ 1 : 0x5a,0x5a,0x5a},
2537 .ret_length
= report_id
? 2 : caps
.InputReportByteLength
- 1,
2538 .ret_status
= STATUS_SUCCESS
,
2542 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2543 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2545 SetLastError( 0xdeadbeef );
2546 memset( report
, 0, sizeof(report
) );
2547 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2548 ok( !ret
, "ReadFile succeeded\n" );
2549 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2551 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2552 ok( !ret
, "GetOverlappedResult succeeded\n" );
2553 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %lu\n", GetLastError() );
2555 SetLastError( 0xdeadbeef );
2556 memset( buffer
, 0, sizeof(buffer
) );
2557 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2558 ok( !ret
, "ReadFile succeeded\n" );
2559 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2561 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2562 ok( !ret
, "GetOverlappedResult succeeded\n" );
2563 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %lu\n", GetLastError() );
2565 memset( report
+ caps
.InputReportByteLength
, 0xa5, 5 );
2566 if (report_id
) report
[caps
.InputReportByteLength
] = report_id
;
2568 send_hid_input( file
, expect
, sizeof(expect
) );
2570 /* first read should be completed */
2571 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2572 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2573 ok( value
== caps
.InputReportByteLength
, "got length %lu, expected %u\n", value
, caps
.InputReportByteLength
);
2574 /* second read should still be pending */
2576 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2577 ok( !ret
, "GetOverlappedResult succeeded\n" );
2578 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %lu\n", GetLastError() );
2580 memset( buffer
+ caps
.InputReportByteLength
, 0x3b, 5 );
2581 if (report_id
) buffer
[caps
.InputReportByteLength
] = report_id
;
2582 memset( expect
[1].report_buf
, 0x3b, 5 );
2583 if (report_id
) expect
[1].report_buf
[0] = report_id
;
2585 send_hid_input( file
, expect
, sizeof(expect
) );
2587 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2588 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2589 ok( value
== caps
.InputReportByteLength
, "got length %lu, expected %u\n", value
, caps
.InputReportByteLength
);
2591 off
= report_id
? 0 : 1;
2592 ok( memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected different report\n" );
2593 ok( !memcmp( report
+ off
, report
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2594 "expected identical reports\n" );
2595 ok( !memcmp( buffer
+ off
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2596 "expected identical reports\n" );
2598 SetLastError( 0xdeadbeef );
2599 memset( report
, 0, sizeof(report
) );
2600 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2601 ok( !ret
, "ReadFile succeeded\n" );
2602 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %lu\n", GetLastError() );
2604 send_hid_input( file
, expect_small
, sizeof(expect_small
) );
2606 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2607 ok( ret
, "GetOverlappedResult failed, last error %lu\n", GetLastError() );
2608 ok( value
== caps
.InputReportByteLength
, "got length %lu, expected %u\n", value
, caps
.InputReportByteLength
);
2610 CloseHandle( overlapped
.hEvent
);
2611 CloseHandle( overlapped2
.hEvent
);
2614 HidD_FreePreparsedData( preparsed_data
);
2617 static void test_hid_device( DWORD report_id
, DWORD polled
, const HIDP_CAPS
*expect_caps
, WORD vid
, WORD pid
)
2619 ULONG count
, poll_freq
, out_len
;
2620 WCHAR device_path
[MAX_PATH
];
2621 HANDLE file
, async_file
;
2624 winetest_push_context( "id %ld%s", report_id
, polled
? " poll" : "" );
2626 /* Win7 has a spurious device removal event with polled HID devices */
2627 if (!polled
|| !strcmp(winetest_platform
, "wine")) ret
= WAIT_TIMEOUT
;
2628 else if (!(ret
= WaitForSingleObject( device_removed
, 2000 )))
2630 ret
= WaitForSingleObject( device_added
, 5000 );
2631 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
2634 swprintf( device_path
, MAX_PATH
, L
"\\\\?\\hid#vid_%04x&pid_%04x", vid
, pid
);
2635 ret
= find_hid_device_path( device_path
);
2636 ok( ret
, "Failed to find HID device matching %s\n", debugstr_w( device_path
) );
2638 file
= CreateFileW( device_path
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2639 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
2640 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
2643 SetLastError( 0xdeadbeef );
2644 ret
= HidD_GetNumInputBuffers( file
, &count
);
2645 ok( ret
, "HidD_GetNumInputBuffers failed last error %lu\n", GetLastError() );
2646 ok( count
== 32, "HidD_GetNumInputBuffers returned %lu\n", count
);
2648 SetLastError( 0xdeadbeef );
2649 ret
= HidD_SetNumInputBuffers( file
, 1 );
2650 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2651 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %lu\n",
2653 SetLastError( 0xdeadbeef );
2654 ret
= HidD_SetNumInputBuffers( file
, 513 );
2655 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2656 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %lu\n",
2659 SetLastError( 0xdeadbeef );
2660 ret
= HidD_SetNumInputBuffers( file
, 16 );
2661 ok( ret
, "HidD_SetNumInputBuffers failed last error %lu\n", GetLastError() );
2664 SetLastError( 0xdeadbeef );
2665 ret
= HidD_GetNumInputBuffers( file
, &count
);
2666 ok( ret
, "HidD_GetNumInputBuffers failed last error %lu\n", GetLastError() );
2667 ok( count
== 16, "HidD_GetNumInputBuffers returned %lu\n", count
);
2669 async_file
= CreateFileW( device_path
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2670 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
2671 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
2672 ok( async_file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
2675 SetLastError( 0xdeadbeef );
2676 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2677 ok( ret
, "HidD_GetNumInputBuffers failed last error %lu\n", GetLastError() );
2678 ok( count
== 32, "HidD_GetNumInputBuffers returned %lu\n", count
);
2680 SetLastError( 0xdeadbeef );
2681 ret
= HidD_SetNumInputBuffers( async_file
, 2 );
2682 ok( ret
, "HidD_SetNumInputBuffers failed last error %lu\n", GetLastError() );
2685 SetLastError( 0xdeadbeef );
2686 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2687 ok( ret
, "HidD_GetNumInputBuffers failed last error %lu\n", GetLastError() );
2688 ok( count
== 2, "HidD_GetNumInputBuffers returned %lu\n", count
);
2690 SetLastError( 0xdeadbeef );
2691 ret
= HidD_GetNumInputBuffers( file
, &count
);
2692 ok( ret
, "HidD_GetNumInputBuffers failed last error %lu\n", GetLastError() );
2693 ok( count
== 16, "HidD_GetNumInputBuffers returned %lu\n", count
);
2697 out_len
= sizeof(ULONG
);
2698 SetLastError( 0xdeadbeef );
2699 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, 5000 );
2700 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2701 ok( out_len
== sizeof(ULONG
), "got out_len %lu, expected sizeof(ULONG)\n", out_len
);
2703 ok( poll_freq
== 5, "got poll_freq %lu, expected 5\n", poll_freq
);
2707 SetLastError( 0xdeadbeef );
2708 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, 5000 );
2709 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2710 ok( out_len
== 0, "got out_len %lu, expected 0\n", out_len
);
2714 SetLastError( 0xdeadbeef );
2715 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, 5000 );
2716 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2717 ok( out_len
== 0, "got out_len %lu, expected 0\n", out_len
);
2721 SetLastError( 0xdeadbeef );
2722 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, 5000 );
2723 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2724 ok( out_len
== 0, "got out_len %lu, expected 0\n", out_len
);
2726 out_len
= sizeof(ULONG
);
2727 SetLastError( 0xdeadbeef );
2728 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, 5000 );
2729 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2730 ok( out_len
== sizeof(ULONG
), "got out_len %lu, expected sizeof(ULONG)\n", out_len
);
2731 ok( poll_freq
== 10000, "got poll_freq %lu, expected 10000\n", poll_freq
);
2735 SetLastError( 0xdeadbeef );
2736 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, 5000 );
2737 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2738 ok( out_len
== 0, "got out_len %lu, expected 0\n", out_len
);
2740 out_len
= sizeof(ULONG
);
2741 SetLastError( 0xdeadbeef );
2742 ret
= sync_ioctl( async_file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, 5000 );
2743 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %lu\n", GetLastError() );
2744 ok( out_len
== sizeof(ULONG
), "got out_len %lu, expected sizeof(ULONG)\n", out_len
);
2745 ok( poll_freq
== 500, "got poll_freq %lu, expected 500\n", poll_freq
);
2748 test_hidp( file
, async_file
, report_id
, polled
, expect_caps
);
2750 CloseHandle( async_file
);
2751 CloseHandle( file
);
2753 winetest_pop_context();
2756 static void test_hid_driver( DWORD report_id
, DWORD polled
)
2758 #include "psh_hid_macros.h"
2759 /* Replace REPORT_ID with USAGE_PAGE when id is 0 */
2760 #define REPORT_ID_OR_USAGE_PAGE(size, id, off) SHORT_ITEM_1((id ? 8 : 0), 1, (id + off))
2761 const unsigned char report_desc
[] =
2763 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2764 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2765 COLLECTION(1, Application
),
2766 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2767 COLLECTION(1, Logical
),
2768 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2769 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2770 USAGE(1, HID_USAGE_GENERIC_X
),
2771 USAGE(1, HID_USAGE_GENERIC_Y
),
2772 LOGICAL_MINIMUM(1, -128),
2773 LOGICAL_MAXIMUM(1, 127),
2776 INPUT(1, Data
|Var
|Abs
),
2778 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2779 USAGE_MINIMUM(1, 1),
2780 USAGE_MAXIMUM(1, 8),
2781 LOGICAL_MINIMUM(1, 0),
2782 LOGICAL_MAXIMUM(1, 1),
2785 INPUT(1, Data
|Var
|Abs
),
2787 USAGE_MINIMUM(1, 0x18),
2788 USAGE_MAXIMUM(1, 0x1f),
2789 LOGICAL_MINIMUM(1, 0),
2790 LOGICAL_MAXIMUM(1, 1),
2793 INPUT(1, Cnst
|Var
|Abs
),
2795 INPUT(1, Cnst
|Var
|Abs
),
2796 /* needs to be 8 bit aligned as next has Buff */
2798 USAGE_MINIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8),
2799 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0xf),
2800 LOGICAL_MINIMUM(1, 0),
2801 LOGICAL_MAXIMUM(1, 8),
2804 INPUT(2, Data
|Ary
|Rel
|Wrap
|Lin
|Pref
|Null
|Vol
|Buff
),
2806 /* needs to be 8 bit aligned as previous has Buff */
2808 LOGICAL_MINIMUM(1, 0),
2809 LOGICAL_MAXIMUM(1, 1),
2812 INPUT(1, Data
|Var
|Abs
),
2813 USAGE_MINIMUM(1, 0x21),
2814 USAGE_MAXIMUM(1, 0x22),
2817 INPUT(1, Data
|Var
|Abs
),
2821 INPUT(1, Data
|Var
|Abs
),
2823 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2824 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
2825 LOGICAL_MINIMUM(1, 1),
2826 LOGICAL_MAXIMUM(1, 8),
2829 INPUT(1, Data
|Var
|Abs
),
2831 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2832 USAGE(1, HID_USAGE_GENERIC_Z
),
2833 LOGICAL_MINIMUM(4, 0x00000000),
2834 LOGICAL_MAXIMUM(4, 0x3fffffff),
2835 PHYSICAL_MINIMUM(4, 0x80000000),
2836 PHYSICAL_MAXIMUM(4, 0x7fffffff),
2839 INPUT(1, Data
|Var
|Abs
),
2841 /* reset physical range to its default interpretation */
2842 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2843 USAGE(1, HID_USAGE_GENERIC_RX
),
2844 PHYSICAL_MINIMUM(4, 0),
2845 PHYSICAL_MAXIMUM(4, 0),
2848 INPUT(1, Data
|Var
|Abs
),
2850 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2851 USAGE(1, HID_USAGE_GENERIC_RY
),
2852 LOGICAL_MINIMUM(4, 0x7fff),
2853 LOGICAL_MAXIMUM(4, 0x0000),
2854 PHYSICAL_MINIMUM(4, 0x0000),
2855 PHYSICAL_MAXIMUM(4, 0x7fff),
2858 INPUT(1, Data
|Var
|Abs
),
2861 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2862 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2863 COLLECTION(1, Report
),
2864 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2865 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2866 USAGE_MINIMUM(1, 9),
2867 USAGE_MAXIMUM(1, 10),
2868 LOGICAL_MINIMUM(1, 0),
2869 LOGICAL_MAXIMUM(1, 1),
2872 INPUT(1, Data
|Var
|Abs
),
2875 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2876 USAGE(1, HID_USAGE_LED_GREEN
),
2877 COLLECTION(1, Report
),
2878 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2879 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2888 LOGICAL_MINIMUM(1, 0),
2889 LOGICAL_MAXIMUM(1, 1),
2890 PHYSICAL_MINIMUM(1, 0),
2891 PHYSICAL_MAXIMUM(1, 1),
2894 INPUT(1, Data
|Var
|Abs
),
2896 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8c),
2897 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8d),
2898 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8e),
2899 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8f),
2900 LOGICAL_MINIMUM(1, 1),
2901 LOGICAL_MAXIMUM(1, 16),
2904 INPUT(1, Data
|Ary
|Abs
),
2907 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2908 USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER
),
2909 COLLECTION(1, Logical
),
2910 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2911 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2913 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST
),
2914 COLLECTION(1, NamedArray
),
2915 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2916 USAGE(1, 3), /* HID_USAGE_HAPTICS_WAVEFORM_RUMBLE */
2917 USAGE(1, 4), /* HID_USAGE_HAPTICS_WAVEFORM_BUZZ */
2918 LOGICAL_MINIMUM(2, 0x0000),
2919 LOGICAL_MAXIMUM(2, 0xffff),
2922 FEATURE(1, Data
|Var
|Abs
|Null
),
2925 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2926 USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST
),
2927 COLLECTION(1, NamedArray
),
2928 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2929 USAGE(1, 3), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) */
2930 USAGE(1, 4), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_BUZZ) */
2931 LOGICAL_MINIMUM(2, 0x0000),
2932 LOGICAL_MAXIMUM(2, 0xffff),
2935 FEATURE(1, Data
|Var
|Abs
|Null
),
2938 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2939 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
),
2940 UNIT(2, 0x1001), /* seconds */
2941 UNIT_EXPONENT(1, -3), /* 10^-3 */
2942 LOGICAL_MINIMUM(2, 0x8000),
2943 LOGICAL_MAXIMUM(2, 0x7fff),
2944 PHYSICAL_MINIMUM(4, 0x00000000),
2945 PHYSICAL_MAXIMUM(4, 0xffffffff),
2948 FEATURE(1, Data
|Var
|Abs
),
2949 /* reset global items */
2950 UNIT(1, 0), /* None */
2951 UNIT_EXPONENT(1, 0),
2953 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2954 USAGE(1, HID_USAGE_GENERIC_Z
),
2955 LOGICAL_MINIMUM(4, 0x0000),
2956 LOGICAL_MAXIMUM(4, 0x7fff),
2957 PHYSICAL_MINIMUM(4, 0xfff90000),
2958 PHYSICAL_MAXIMUM(4, 0x0003ffff),
2961 FEATURE(1, Data
|Var
|Abs
),
2964 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2965 USAGE(1, HID_USAGE_GENERIC_SYSTEM_CTL
),
2966 COLLECTION(1, Report
),
2967 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2968 REPORT_COUNT(1, 10),
2970 LOGICAL_MINIMUM(2, 0x0000),
2971 LOGICAL_MAXIMUM(2, 0x00ff),
2972 PHYSICAL_MINIMUM(2, 0x0000),
2973 PHYSICAL_MAXIMUM(2, 0x0ff0),
2974 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2975 STRING_MINIMUM(1, 6),
2976 STRING_MAXIMUM(1, 16),
2977 USAGE_MINIMUM(1, 1), /* Instance 1 */
2978 USAGE_MAXIMUM(1, 10), /* Instance 10 */
2979 FEATURE(1, Data
|Var
|Abs
),
2980 PHYSICAL_MINIMUM(1, 0),
2981 PHYSICAL_MAXIMUM(1, 0),
2984 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2985 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2986 COLLECTION(1, Report
),
2987 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2988 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2989 USAGE_MINIMUM(1, 9),
2990 USAGE_MAXIMUM(1, 10),
2991 LOGICAL_MINIMUM(1, 0),
2992 LOGICAL_MAXIMUM(1, 1),
2993 PHYSICAL_MINIMUM(1, 0),
2994 PHYSICAL_MAXIMUM(1, 1),
2997 FEATURE(1, Data
|Var
|Abs
),
3000 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
3001 USAGE(1, HID_USAGE_LED_GREEN
),
3002 COLLECTION(1, Report
),
3003 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
3004 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
3007 OUTPUT(1, Cnst
|Var
|Abs
),
3010 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
3011 USAGE(1, HID_USAGE_LED_RED
),
3012 COLLECTION(1, Report
),
3013 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
3014 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
3017 OUTPUT(1, Cnst
|Var
|Abs
),
3021 #undef REPORT_ID_OR_USAGE_PAGE
3022 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3023 #include "pop_hid_macros.h"
3025 const HIDP_CAPS caps
=
3027 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
3028 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
3029 .InputReportByteLength
= report_id
? 37 : 38,
3030 .OutputReportByteLength
= report_id
? 2 : 3,
3031 .FeatureReportByteLength
= report_id
? 31 : 32,
3032 .NumberLinkCollectionNodes
= 11,
3033 .NumberInputButtonCaps
= 17,
3034 .NumberInputValueCaps
= 7,
3035 .NumberInputDataIndices
= 47,
3036 .NumberFeatureButtonCaps
= 1,
3037 .NumberFeatureValueCaps
= 7,
3038 .NumberFeatureDataIndices
= 18,
3040 const struct hid_expect expect_in
=
3042 .code
= IOCTL_HID_READ_REPORT
,
3043 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
3044 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
3046 .ret_status
= STATUS_SUCCESS
,
3048 struct hid_device_desc desc
=
3050 .is_polled
= polled
,
3051 .use_report_id
= report_id
,
3053 .attributes
= default_attributes
,
3056 desc
.report_descriptor_len
= sizeof(report_desc
);
3057 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
3058 desc
.input_size
= polled
? sizeof(expect_in
) : 0;
3059 memcpy( desc
.input
, &expect_in
, sizeof(expect_in
) );
3060 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
3062 if (hid_device_start( &desc
, 1 )) test_hid_device( report_id
, polled
, &caps
, desc
.attributes
.VendorID
, desc
.attributes
.ProductID
);
3063 hid_device_stop( &desc
, 1 );
3066 /* undocumented HID internal preparsed data structure */
3068 struct hidp_kdr_caps
3074 USHORT report_count
;
3079 USHORT link_collection
;
3080 USAGE link_usage_page
;
3088 USHORT designator_min
;
3089 USHORT designator_max
;
3090 USHORT data_index_min
;
3091 USHORT data_index_max
;
3102 /* named array continues on next caps */
3103 #define HIDP_KDR_CAPS_ARRAY_HAS_MORE 0x01
3104 #define HIDP_KDR_CAPS_IS_CONSTANT 0x02
3105 #define HIDP_KDR_CAPS_IS_BUTTON 0x04
3106 #define HIDP_KDR_CAPS_IS_ABSOLUTE 0x08
3107 #define HIDP_KDR_CAPS_IS_RANGE 0x10
3108 #define HIDP_KDR_CAPS_IS_STRING_RANGE 0x40
3109 #define HIDP_KDR_CAPS_IS_DESIGNATOR_RANGE 0x80
3111 struct hidp_kdr_node
3116 USHORT number_of_children
;
3117 USHORT next_sibling
;
3119 ULONG collection_type
;
3128 USHORT input_caps_start
;
3129 USHORT input_caps_count
;
3130 USHORT input_caps_end
;
3131 USHORT input_report_byte_length
;
3132 USHORT output_caps_start
;
3133 USHORT output_caps_count
;
3134 USHORT output_caps_end
;
3135 USHORT output_report_byte_length
;
3136 USHORT feature_caps_start
;
3137 USHORT feature_caps_count
;
3138 USHORT feature_caps_end
;
3139 USHORT feature_report_byte_length
;
3141 USHORT number_link_collection_nodes
;
3142 struct hidp_kdr_caps caps
[1];
3143 /* struct hidp_kdr_node nodes[1] */
3146 static void check_preparsed_data( HANDLE file
, const struct hidp_kdr
*expect_kdr
,
3147 UINT expect_caps_count
, const struct hidp_kdr_caps
*expect_caps
,
3148 UINT expect_nodes_count
, const struct hidp_kdr_node
*expect_nodes
)
3150 PHIDP_PREPARSED_DATA preparsed_data
;
3151 struct hidp_kdr
*kdr
;
3155 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
3156 ok( ret
, "HidD_GetPreparsedData failed with error %lu\n", GetLastError() );
3158 kdr
= (struct hidp_kdr
*)preparsed_data
;
3159 ok( !strncmp( kdr
->magic
, expect_kdr
->magic
, 8 ), "got %s expected %s\n",
3160 debugstr_an(kdr
->magic
, 8), debugstr_an(expect_kdr
->magic
, 8) );
3162 if (!strncmp( kdr
->magic
, expect_kdr
->magic
, 8 ))
3164 check_member( *kdr
, *expect_kdr
, "%04x", usage
);
3165 check_member( *kdr
, *expect_kdr
, "%04x", usage_page
);
3166 check_member( *kdr
, *expect_kdr
, "%#x", unknown
[0] );
3167 check_member( *kdr
, *expect_kdr
, "%#x", unknown
[1] );
3168 check_member( *kdr
, *expect_kdr
, "%d", input_caps_start
);
3169 check_member( *kdr
, *expect_kdr
, "%d", input_caps_count
);
3170 check_member( *kdr
, *expect_kdr
, "%d", input_caps_end
);
3171 check_member( *kdr
, *expect_kdr
, "%d", input_report_byte_length
);
3172 check_member( *kdr
, *expect_kdr
, "%d", output_caps_start
);
3173 check_member( *kdr
, *expect_kdr
, "%d", output_caps_count
);
3174 check_member( *kdr
, *expect_kdr
, "%d", output_caps_end
);
3175 check_member( *kdr
, *expect_kdr
, "%d", output_report_byte_length
);
3176 check_member( *kdr
, *expect_kdr
, "%d", feature_caps_start
);
3177 check_member( *kdr
, *expect_kdr
, "%d", feature_caps_count
);
3178 check_member( *kdr
, *expect_kdr
, "%d", feature_caps_end
);
3179 check_member( *kdr
, *expect_kdr
, "%d", feature_report_byte_length
);
3180 check_member( *kdr
, *expect_kdr
, "%d", caps_size
);
3181 check_member( *kdr
, *expect_kdr
, "%d", number_link_collection_nodes
);
3183 for (i
= 0; i
< min( expect_caps_count
, kdr
->caps_size
/ sizeof(struct hidp_kdr_caps
) ); ++i
)
3185 winetest_push_context( "caps[%u]", i
);
3186 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_page
);
3187 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_id
);
3188 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_bit
);
3189 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", bit_size
);
3190 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_count
);
3191 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_byte
);
3192 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", total_bits
);
3193 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", bit_field
);
3194 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", end_byte
);
3195 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", link_collection
);
3196 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage_page
);
3197 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage
);
3198 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", flags
);
3199 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[0] );
3200 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[1] );
3201 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[2] );
3202 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[3] );
3203 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[4] );
3204 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[5] );
3205 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[6] );
3206 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", padding
[7] );
3207 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_min
);
3208 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_max
);
3209 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_min
);
3210 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_max
);
3211 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_min
);
3212 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_max
);
3213 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_min
);
3214 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_max
);
3215 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", null_value
);
3216 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", unknown
);
3217 check_member( kdr
->caps
[i
], expect_caps
[i
], "%ld", logical_min
);
3218 check_member( kdr
->caps
[i
], expect_caps
[i
], "%ld", logical_max
);
3219 check_member( kdr
->caps
[i
], expect_caps
[i
], "%ld", physical_min
);
3220 check_member( kdr
->caps
[i
], expect_caps
[i
], "%ld", physical_max
);
3221 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", units
);
3222 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#lx", units_exp
);
3223 winetest_pop_context();
3226 for (i
= 0; i
< expect_nodes_count
; ++i
)
3228 struct hidp_kdr_node
*nodes
= (struct hidp_kdr_node
*)((char *)kdr
->caps
+ kdr
->caps_size
);
3229 winetest_push_context( "nodes[%u]", i
);
3230 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage
);
3231 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage_page
);
3232 check_member( nodes
[i
], expect_nodes
[i
], "%d", parent
);
3233 check_member( nodes
[i
], expect_nodes
[i
], "%d", number_of_children
);
3234 check_member( nodes
[i
], expect_nodes
[i
], "%d", next_sibling
);
3235 check_member( nodes
[i
], expect_nodes
[i
], "%d", first_child
);
3236 check_member( nodes
[i
], expect_nodes
[i
], "%#lx", collection_type
);
3237 winetest_pop_context();
3241 HidD_FreePreparsedData( preparsed_data
);
3244 static void test_hidp_kdr(void)
3246 #include "psh_hid_macros.h"
3247 const unsigned char report_desc
[] =
3249 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3250 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3251 COLLECTION(1, Application
),
3252 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3253 LOGICAL_MINIMUM(1, 1),
3254 LOGICAL_MAXIMUM(1, 127),
3255 PHYSICAL_MINIMUM(1, -128),
3256 PHYSICAL_MAXIMUM(1, 127),
3258 USAGE(1, HID_USAGE_GENERIC_RZ
),
3261 FEATURE(1, Data
|Var
|Abs
),
3262 USAGE(1, HID_USAGE_GENERIC_SLIDER
),
3265 FEATURE(1, Data
|Var
|Abs
),
3267 USAGE(1, HID_USAGE_GENERIC_X
),
3271 UNIT_EXPONENT(1, -3),
3272 INPUT(1, Data
|Var
|Abs
),
3273 UNIT_EXPONENT(1, 0),
3275 USAGE(1, HID_USAGE_GENERIC_Y
),
3276 DESIGNATOR_MINIMUM(1, 1),
3277 DESIGNATOR_MAXIMUM(1, 4),
3280 INPUT(1, Cnst
|Var
|Abs
),
3281 USAGE(1, HID_USAGE_GENERIC_Z
),
3284 INPUT(1, Data
|Var
|Rel
),
3285 USAGE(1, HID_USAGE_GENERIC_RX
),
3286 USAGE(1, HID_USAGE_GENERIC_RY
),
3289 LOGICAL_MINIMUM(1, 7),
3290 INPUT(1, Data
|Var
|Abs
|Null
),
3292 COLLECTION(1, Application
),
3293 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|1),
3294 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|2),
3297 LOGICAL_MINIMUM(1, 0),
3298 LOGICAL_MAXIMUM(1, 1),
3299 INPUT(1, Data
|Var
|Abs
),
3301 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|3),
3302 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|8),
3305 LOGICAL_MINIMUM(1, 3),
3306 LOGICAL_MAXIMUM(1, 8),
3307 INPUT(1, Data
|Ary
|Abs
),
3309 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|9),
3310 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|12),
3313 LOGICAL_MINIMUM(1, 9),
3314 LOGICAL_MAXIMUM(1, 12),
3315 INPUT(2, Data
|Ary
|Abs
|Buff
),
3317 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|13),
3318 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|14),
3319 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|15),
3320 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|16),
3323 LOGICAL_MINIMUM(1, 13),
3324 LOGICAL_MAXIMUM(1, 16),
3325 INPUT(1, Data
|Ary
|Abs
),
3329 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3330 #include "pop_hid_macros.h"
3332 struct hid_device_desc desc
=
3334 .caps
= { .InputReportByteLength
= 15 },
3335 .attributes
= default_attributes
,
3337 static const struct hidp_kdr expect_kdr
=
3339 .magic
= "HidP KDR",
3342 .input_caps_count
= 13,
3343 .input_caps_end
= 13,
3344 .input_report_byte_length
= 15,
3345 .output_caps_start
= 13,
3346 .output_caps_end
= 13,
3347 .feature_caps_start
= 13,
3348 .feature_caps_count
= 2,
3349 .feature_caps_end
= 14,
3350 .feature_report_byte_length
= 3,
3352 .number_link_collection_nodes
= 2,
3354 static const struct hidp_kdr_caps expect_caps
[] =
3357 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x08,
3358 .bit_field
= 0x002, .end_byte
= 0x2, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3359 .usage_min
= 0x30, .usage_max
= 0x30, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
3360 .physical_max
= 127, .units
= 0xe, .units_exp
= -3
3363 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x2, .total_bits
= 0x08,
3364 .bit_field
= 0x003, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x8a,
3365 .usage_min
= 0x31, .usage_max
= 0x31, .designator_min
= 1, .designator_max
= 4, .data_index_min
= 0x01,
3366 .data_index_max
= 0x01, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3369 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x3, .total_bits
= 0x08,
3370 .bit_field
= 0x006, .end_byte
= 0x4, .link_usage_page
= 0x01, .link_usage
= 0x04, .usage_min
= 0x32,
3371 .usage_max
= 0x32, .data_index_min
= 0x02, .data_index_max
= 0x02, .logical_min
= 1, .logical_max
= 127,
3372 .physical_min
= -128, .physical_max
= 127
3375 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x6, .total_bits
= 0x10,
3376 .bit_field
= 0x042, .end_byte
= 0x8, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3377 .usage_min
= 0x34, .usage_max
= 0x34, .data_index_min
= 0x03, .data_index_max
= 0x03, .null_value
= 1,
3378 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3381 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x4, .total_bits
= 0x10,
3382 .bit_field
= 0x042, .end_byte
= 0x6, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3383 .usage_min
= 0x33, .usage_max
= 0x33, .data_index_min
= 0x04, .data_index_max
= 0x04, .null_value
= 1,
3384 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3387 .usage_page
= 0x09, .start_bit
= 1, .bit_size
= 0x01, .report_count
= 0x7, .start_byte
= 0x8, .total_bits
= 0x07,
3388 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3389 .usage_min
= 0x02, .usage_max
= 0x02, .data_index_min
= 0x05, .data_index_max
= 0x05,
3392 .usage_page
= 0x09, .bit_size
= 0x01, .report_count
= 0x1, .start_byte
= 0x8, .total_bits
= 0x01,
3393 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3394 .usage_min
= 0x01, .usage_max
= 0x01, .data_index_min
= 0x06, .data_index_max
= 0x06,
3397 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x9, .total_bits
= 0x08,
3398 .bit_field
= 0x000, .end_byte
= 0xa, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
3399 .usage_min
= 0x03, .usage_max
= 0x08, .data_index_min
= 0x07, .data_index_max
= 0x0c, .null_value
= 3,
3403 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x4, .start_byte
= 0xa, .total_bits
= 0x20,
3404 .bit_field
= 0x100, .end_byte
= 0xe, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
3405 .usage_min
= 0x09, .usage_max
= 0x0c, .data_index_min
= 0x0d, .data_index_max
= 0x10, .null_value
= 9,
3409 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3410 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3411 .usage_min
= 0x10, .usage_max
= 0x10, .data_index_min
= 0x14, .data_index_max
= 0x14, .null_value
= 13,
3415 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3416 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3417 .usage_min
= 0x0f, .usage_max
= 0x0f, .data_index_min
= 0x13, .data_index_max
= 0x13, .null_value
= 13,
3421 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3422 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3423 .usage_min
= 0x0e, .usage_max
= 0x0e, .data_index_min
= 0x12, .data_index_max
= 0x12, .null_value
= 13,
3427 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3428 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3429 .usage_min
= 0x0d, .usage_max
= 0x0d, .data_index_min
= 0x11, .data_index_max
= 0x11, .null_value
= 13,
3433 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x10,
3434 .bit_field
= 0x002, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3435 .usage_min
= 0x36, .usage_max
= 0x36, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
3441 static const struct hidp_kdr_node expect_nodes
[] =
3447 .number_of_children
= 0x1,
3450 .collection_type
= 0x1,
3456 .number_of_children
= 0,
3459 .collection_type
= 0x1,
3463 WCHAR device_path
[MAX_PATH
];
3467 desc
.report_descriptor_len
= sizeof(report_desc
);
3468 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
3469 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
3471 if (!hid_device_start( &desc
, 1 )) goto done
;
3473 swprintf( device_path
, MAX_PATH
, L
"\\\\?\\hid#vid_%04x&pid_%04x", desc
.attributes
.VendorID
,
3474 desc
.attributes
.ProductID
);
3475 ret
= find_hid_device_path( device_path
);
3476 ok( ret
, "Failed to find HID device matching %s\n", debugstr_w( device_path
) );
3478 file
= CreateFileW( device_path
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
3479 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
3480 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
3482 check_preparsed_data( file
, &expect_kdr
, ARRAY_SIZE(expect_caps
), expect_caps
,
3483 ARRAY_SIZE(expect_nodes
), expect_nodes
);
3485 CloseHandle( file
);
3488 hid_device_stop( &desc
, 1 );
3491 void cleanup_registry_keys(void)
3493 static const WCHAR joystick_oem_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3494 "PrivateProperties\\Joystick\\OEM";
3495 static const WCHAR dinput_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3496 "PrivateProperties\\DirectInput";
3499 /* These keys are automatically created by DInput and they store the
3500 list of supported force-feedback effects. OEM drivers are supposed
3501 to provide a list in HKLM for the vendor-specific force-feedback
3504 We need to clean them up, or DInput will not refresh the list of
3505 effects from the PID report changes.
3507 RegCreateKeyExW( HKEY_CURRENT_USER
, joystick_oem_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3508 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3509 RegCloseKey( root_key
);
3511 RegCreateKeyExW( HKEY_CURRENT_USER
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3512 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3513 RegCloseKey( root_key
);
3515 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, joystick_oem_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3516 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3517 RegCloseKey( root_key
);
3519 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3520 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3521 RegCloseKey( root_key
);
3524 static LRESULT CALLBACK
monitor_wndproc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
3526 if (msg
== WM_DEVICECHANGE
)
3528 DEV_BROADCAST_DEVICEINTERFACE_W
*iface
= (DEV_BROADCAST_DEVICEINTERFACE_W
*)lparam
;
3530 if (!IsEqualGUID( &iface
->dbcc_classguid
, &control_class
) && !IsEqualGUID( &iface
->dbcc_classguid
, &GUID_DEVINTERFACE_HID
))
3531 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
3532 if (!wcsnicmp( iface
->dbcc_name
, L
"\\\\?\\root#winetest", 17 ))
3533 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
3535 if (wparam
== DBT_DEVICEREMOVECOMPLETE
) ReleaseSemaphore( device_removed
, 1, NULL
);
3536 if (wparam
== DBT_DEVICEARRIVAL
) ReleaseSemaphore( device_added
, 1, NULL
);
3539 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
3542 DWORD WINAPI
monitor_thread_proc( void *stop_event
)
3544 DEV_BROADCAST_DEVICEINTERFACE_A iface_filter_a
=
3546 .dbcc_size
= sizeof(DEV_BROADCAST_DEVICEINTERFACE_A
),
3547 .dbcc_devicetype
= DBT_DEVTYP_DEVICEINTERFACE
,
3551 .cbSize
= sizeof(WNDCLASSEXW
),
3552 .hInstance
= GetModuleHandleW( NULL
),
3553 .lpszClassName
= L
"device_monitor",
3554 .lpfnWndProc
= monitor_wndproc
,
3556 HDEVNOTIFY devnotify
;
3560 RegisterClassExW( &class );
3561 hwnd
= CreateWindowW( class.lpszClassName
, NULL
, 0, 0, 0, 0, 0, HWND_MESSAGE
, NULL
, NULL
, NULL
);
3562 ok( !!hwnd
, "CreateWindowW failed, error %lu\n", GetLastError() );
3563 devnotify
= RegisterDeviceNotificationA( hwnd
, &iface_filter_a
, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
);
3564 ok( !!devnotify
, "RegisterDeviceNotificationA failed, error %lu\n", GetLastError() );
3568 while (PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
))
3570 TranslateMessage( &msg
);
3571 DispatchMessageW( &msg
);
3573 } while (MsgWaitForMultipleObjects( 1, &stop_event
, FALSE
, INFINITE
, QS_ALLINPUT
));
3575 UnregisterDeviceNotification( devnotify
);
3576 DestroyWindow( hwnd
);
3577 UnregisterClassW( class.lpszClassName
, class.hInstance
);
3579 CloseHandle( stop_event
);
3583 void dinput_test_init_( const char *file
, int line
)
3587 monitor_stop
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
3588 ok_(file
, line
)( !!monitor_stop
, "CreateEventW failed, error %lu\n", GetLastError() );
3589 device_added
= CreateSemaphoreW( NULL
, 0, LONG_MAX
, NULL
);
3590 ok_(file
, line
)( !!device_added
, "CreateSemaphoreW failed, error %lu\n", GetLastError() );
3591 device_removed
= CreateSemaphoreW( NULL
, 0, LONG_MAX
, NULL
);
3592 ok_(file
, line
)( !!device_removed
, "CreateSemaphoreW failed, error %lu\n", GetLastError() );
3593 monitor_thread
= CreateThread( NULL
, 0, monitor_thread_proc
, monitor_stop
, 0, NULL
);
3594 ok_(file
, line
)( !!monitor_thread
, "CreateThread failed, error %lu\n", GetLastError() );
3596 CoInitialize( NULL
);
3598 instance
= GetModuleHandleW( NULL
);
3599 localized
= GetUserDefaultLCID() != MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
);
3600 pSignerSign
= (void *)GetProcAddress( LoadLibraryW( L
"mssign32" ), "SignerSign" );
3602 if (IsWow64Process( GetCurrentProcess(), &is_wow64
) && is_wow64
)
3604 skip_(file
, line
)( "Skipping driver tests: running in wow64.\n" );
3608 test_data_mapping
= CreateFileMappingW( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0,
3609 sizeof(*test_data
), L
"Global\\winetest_dinput_section" );
3610 if (!test_data_mapping
&& GetLastError() == ERROR_ACCESS_DENIED
)
3612 win_skip_(file
, line
)( "Skipping driver tests: failed to create mapping.\n" );
3615 ok_(file
, line
)( !!test_data_mapping
, "got error %lu\n", GetLastError() );
3617 test_data
= MapViewOfFile( test_data_mapping
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 1024 );
3618 ok_(file
, line
)( !!test_data
, "MapViewOfFile failed, error %lu\n", GetLastError() );
3619 test_data
->running_under_wine
= !strcmp( winetest_platform
, "wine" );
3620 test_data
->winetest_report_success
= winetest_report_success
;
3621 test_data
->winetest_debug
= winetest_debug
;
3623 okfile
= CreateFileW( L
"C:\\windows\\winetest_dinput_okfile", GENERIC_READ
| GENERIC_WRITE
,
3624 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
3625 ok_(file
, line
)( okfile
!= INVALID_HANDLE_VALUE
, "failed to create file, error %lu\n", GetLastError() );
3627 subtest_(file
, line
)( "hid" );
3628 subtest_(file
, line
)( "driver" );
3629 subtest_(file
, line
)( "driver_bus" );
3630 subtest_(file
, line
)( "driver_hid" );
3631 subtest_(file
, line
)( "driver_hid_poll" );
3634 void dinput_test_exit(void)
3638 UnmapViewOfFile( test_data
);
3639 CloseHandle( test_data_mapping
);
3640 CloseHandle( okfile
);
3641 DeleteFileW( L
"C:\\windows\\winetest_dinput_okfile" );
3643 SetEvent( monitor_stop
);
3644 ret
= WaitForSingleObject( monitor_thread
, 5000 );
3645 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
3646 CloseHandle( monitor_thread
);
3647 CloseHandle( monitor_stop
);
3648 CloseHandle( device_removed
);
3649 CloseHandle( device_added
);
3654 BOOL CALLBACK
find_test_device( const DIDEVICEINSTANCEW
*devinst
, void *context
)
3656 if (IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3657 *(DIDEVICEINSTANCEW
*)context
= *devinst
;
3658 return DIENUM_CONTINUE
;
3661 HRESULT
dinput_test_create_device( DWORD version
, DIDEVICEINSTANCEW
*devinst
, IDirectInputDevice8W
**device
)
3663 IDirectInput8W
*di8
;
3668 if (version
>= 0x800)
3670 hr
= DirectInput8Create( instance
, version
, &IID_IDirectInput8W
, (void **)&di8
, NULL
);
3673 win_skip( "DirectInput8Create returned %#lx\n", hr
);
3677 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, find_test_device
, devinst
, DIEDFL_ALLDEVICES
);
3678 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
3679 if (!IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3681 win_skip( "device not found, skipping tests\n" );
3682 ref
= IDirectInput8_Release( di8
);
3683 ok( ref
== 0, "Release returned %ld\n", ref
);
3684 return DIERR_DEVICENOTREG
;
3687 hr
= IDirectInput8_CreateDevice( di8
, &expect_guid_product
, device
, NULL
);
3688 ok( hr
== DI_OK
, "CreateDevice returned %#lx\n", hr
);
3690 ref
= IDirectInput8_Release( di8
);
3691 ok( ref
== 0, "Release returned %ld\n", ref
);
3695 hr
= DirectInputCreateEx( instance
, version
, &IID_IDirectInput2W
, (void **)&di
, NULL
);
3698 win_skip( "DirectInputCreateEx returned %#lx\n", hr
);
3702 hr
= IDirectInput_EnumDevices( di
, 0, find_test_device
, devinst
, DIEDFL_ALLDEVICES
);
3703 ok( hr
== DI_OK
, "EnumDevices returned: %#lx\n", hr
);
3704 if (!IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3706 win_skip( "device not found, skipping tests\n" );
3708 ref
= IDirectInput_Release( di
);
3709 ok( ref
== 0, "Release returned %ld\n", ref
);
3710 return DIERR_DEVICENOTREG
;
3713 hr
= IDirectInput_CreateDevice( di
, &expect_guid_product
, (IDirectInputDeviceW
**)device
, NULL
);
3714 ok( hr
== DI_OK
, "CreateDevice returned %#lx\n", hr
);
3716 ref
= IDirectInput_Release( di
);
3717 ok( ref
== 0, "Release returned %ld\n", ref
);
3723 DWORD WINAPI
dinput_test_device_thread( void *stop_event
)
3725 #include "psh_hid_macros.h"
3726 static const unsigned char gamepad_desc
[] =
3728 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3729 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
3730 COLLECTION(1, Application
),
3731 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
3732 COLLECTION(1, Physical
),
3733 USAGE(1, HID_USAGE_GENERIC_X
),
3734 USAGE(1, HID_USAGE_GENERIC_Y
),
3735 LOGICAL_MINIMUM(1, 0),
3736 LOGICAL_MAXIMUM(1, 127),
3737 PHYSICAL_MINIMUM(1, 0),
3738 PHYSICAL_MAXIMUM(1, 127),
3741 INPUT(1, Data
|Var
|Abs
),
3743 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3744 USAGE_MINIMUM(1, 1),
3745 USAGE_MAXIMUM(1, 6),
3746 LOGICAL_MINIMUM(1, 0),
3747 LOGICAL_MAXIMUM(1, 1),
3748 PHYSICAL_MINIMUM(1, 0),
3749 PHYSICAL_MAXIMUM(1, 1),
3752 INPUT(1, Data
|Var
|Abs
),
3756 C_ASSERT(sizeof(gamepad_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3757 #include "pop_hid_macros.h"
3758 static const HID_DEVICE_ATTRIBUTES attributes
=
3760 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
3761 .VendorID
= LOWORD(EXPECT_VIDPID
),
3762 .ProductID
= HIWORD(EXPECT_VIDPID
),
3763 .VersionNumber
= 0x0100,
3765 static const HIDP_CAPS caps
=
3767 .InputReportByteLength
= 3,
3769 struct hid_device_desc desc
=
3771 .use_report_id
= TRUE
,
3773 .attributes
= attributes
,
3777 desc
.report_descriptor_len
= sizeof(gamepad_desc
);
3778 memcpy( desc
.report_descriptor_buf
, gamepad_desc
, sizeof(gamepad_desc
) );
3779 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
3781 hid_device_start( &desc
, 1 );
3782 ret
= WaitForSingleObject( stop_event
, 5000 );
3783 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
3784 hid_device_stop( &desc
, 1 );
3789 static void test_bus_driver(void)
3791 #include "psh_hid_macros.h"
3792 const unsigned char report_desc
[] =
3794 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3795 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3796 COLLECTION(1, Application
),
3797 USAGE(1, HID_USAGE_GENERIC_X
),
3800 INPUT(1, Data
|Var
|Abs
),
3803 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3804 #include "pop_hid_macros.h"
3806 static const HID_DEVICE_ATTRIBUTES attributes
=
3808 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
3809 .VendorID
= LOWORD(EXPECT_VIDPID
),
3810 .ProductID
= HIWORD(EXPECT_VIDPID
),
3811 .VersionNumber
= 0x0100,
3813 const HIDP_CAPS caps
=
3815 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
3816 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
3817 .InputReportByteLength
= 2,
3818 .NumberLinkCollectionNodes
= 1,
3819 .NumberInputValueCaps
= 1,
3820 .NumberInputDataIndices
= 1,
3822 struct hid_device_desc desc
= { .caps
= caps
, .attributes
= attributes
, };
3824 WCHAR device_path
[MAX_PATH
];
3828 if (!bus_device_start()) goto done
;
3830 control
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
3831 NULL
, OPEN_EXISTING
, 0, NULL
);
3832 ok( control
!= INVALID_HANDLE_VALUE
, "CreateFile failed, error %lu\n", GetLastError() );
3833 CloseHandle( control
);
3837 control
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
3838 NULL
, OPEN_EXISTING
, 0, NULL
);
3839 ok( control
== INVALID_HANDLE_VALUE
, "CreateFile succeeded\n" );
3843 desc
.report_descriptor_len
= sizeof(report_desc
);
3844 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
3846 control
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
3847 NULL
, OPEN_EXISTING
, 0, NULL
);
3848 ok( control
!= INVALID_HANDLE_VALUE
, "CreateFile failed, error %lu\n", GetLastError() );
3849 ret
= sync_ioctl( control
, IOCTL_WINETEST_CREATE_DEVICE
, &desc
, sizeof(desc
), NULL
, 0, 5000 );
3850 ok( ret
, "IOCTL_WINETEST_CREATE_DEVICE failed, last error %lu\n", GetLastError() );
3852 ret
= WaitForSingleObject( device_added
, 5000 );
3853 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
3854 ret
= WaitForSingleObject( device_added
, 1000 );
3855 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
3857 swprintf( device_path
, MAX_PATH
, L
"\\\\?\\hid#vid_%04x&pid_%04x", LOWORD(EXPECT_VIDPID
), HIWORD(EXPECT_VIDPID
) );
3858 ret
= find_hid_device_path( device_path
);
3859 ok( ret
, "Failed to find HID device matching %s\n", debugstr_w(device_path
) );
3861 ret
= sync_ioctl( control
, IOCTL_WINETEST_REMOVE_DEVICE
, &desc
, sizeof(desc
), NULL
, 0, 5000 );
3862 ok( ret
, "IOCTL_WINETEST_REMOVE_DEVICE failed, last error %lu\n", GetLastError() );
3863 CloseHandle( control
);
3865 ret
= WaitForSingleObject( device_removed
, 5000 );
3866 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
3867 ret
= WaitForSingleObject( device_removed
, 1000 );
3868 ok( !ret
, "WaitForSingleObject returned %#lx\n", ret
);
3874 static void test_hid_multiple_tlc(void)
3876 #include "psh_hid_macros.h"
3877 const unsigned char report_desc
[] =
3879 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3880 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3881 COLLECTION(1, Application
),
3882 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3883 COLLECTION(1, Physical
),
3886 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3887 USAGE_MINIMUM(1, 1),
3888 USAGE_MAXIMUM(1, 2),
3889 LOGICAL_MINIMUM(1, 0),
3890 LOGICAL_MAXIMUM(1, 1),
3893 INPUT(1, Data
|Var
|Abs
),
3895 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3896 USAGE(1, HID_USAGE_GENERIC_X
),
3897 USAGE(1, HID_USAGE_GENERIC_Y
),
3900 LOGICAL_MINIMUM(2, -10),
3901 LOGICAL_MAXIMUM(2, +10),
3902 INPUT(1, Data
|Var
|Rel
),
3906 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3907 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
3908 COLLECTION(1, Application
),
3909 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
3910 COLLECTION(1, Physical
),
3913 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3914 USAGE_MINIMUM(1, 1),
3915 USAGE_MAXIMUM(1, 40),
3916 LOGICAL_MINIMUM(1, 0),
3917 LOGICAL_MAXIMUM(1, 1),
3919 REPORT_COUNT(1, 40),
3920 INPUT(1, Data
|Var
|Abs
),
3924 C_ASSERT(sizeof(report_desc
) < MAX_HID_DESCRIPTOR_LEN
);
3925 #include "pop_hid_macros.h"
3927 struct hid_device_desc desc
=
3929 .caps
= { .InputReportByteLength
= 7 },
3930 .attributes
= default_attributes
,
3933 static const struct hidp_kdr expect_kdr_joystick
=
3935 .magic
= "HidP KDR",
3938 .input_caps_count
= 3,
3939 .input_caps_end
= 3,
3940 .input_report_byte_length
= 6,
3941 .output_caps_start
= 3,
3942 .output_caps_end
= 3,
3943 .feature_caps_start
= 3,
3944 .feature_caps_end
= 3,
3946 .number_link_collection_nodes
= 2,
3948 static const struct hidp_kdr expect_kdr_gamepad
=
3950 .magic
= "HidP KDR",
3953 .input_caps_count
= 1,
3954 .input_caps_end
= 1,
3955 .input_report_byte_length
= 6,
3956 .output_caps_start
= 1,
3957 .output_caps_end
= 1,
3958 .feature_caps_start
= 1,
3959 .feature_caps_end
= 1,
3961 .number_link_collection_nodes
= 2,
3963 static const struct hidp_kdr_caps expect_caps_joystick
[] =
3966 .usage_page
= 9, .report_id
= 1, .bit_size
= 1, .report_count
= 8, .start_byte
= 1, .total_bits
= 8,
3967 .bit_field
= 2, .end_byte
= 2, .link_collection
= 1, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x1c,
3968 .usage_min
= 1, .usage_max
= 2, .data_index_max
= 1,
3971 .usage_page
= 1, .report_id
= 1, .bit_size
= 16, .report_count
= 1, .start_byte
= 4, .total_bits
= 16,
3972 .bit_field
= 6, .end_byte
= 6, .link_collection
= 1, .link_usage_page
= 0x01, .link_usage
= 0x04,
3973 .usage_min
= 0x31, .usage_max
= 0x31, .data_index_min
= 2, .data_index_max
= 2, .logical_min
= -10, .logical_max
= +10,
3976 .usage_page
= 1, .report_id
= 1, .bit_size
= 16, .report_count
= 1, .start_byte
= 2, .total_bits
= 16,
3977 .bit_field
= 6, .end_byte
= 4, .link_collection
= 1, .link_usage_page
= 0x01, .link_usage
= 0x04,
3978 .usage_min
= 0x30, .usage_max
= 0x30, .data_index_min
= 3, .data_index_max
= 3, .logical_min
= -10, .logical_max
= +10,
3981 static const struct hidp_kdr_caps expect_caps_gamepad
[] =
3984 .usage_page
= 9, .report_id
= 2, .bit_size
= 1, .report_count
= 40, .start_byte
= 1, .total_bits
= 40,
3985 .bit_field
= 2, .end_byte
= 6, .link_collection
= 1, .link_usage_page
= 0x01, .link_usage
= 0x05, .flags
= 0x1c,
3986 .usage_min
= 0x01, .usage_max
= 0x28, .data_index_max
= 0x27,
3989 static const struct hidp_kdr_node expect_nodes_joystick
[] =
3994 .number_of_children
= 1,
3996 .collection_type
= 0x1,
4003 static const struct hidp_kdr_node expect_nodes_gamepad
[] =
4008 .number_of_children
= 1,
4010 .collection_type
= 1,
4018 WCHAR device_path
[MAX_PATH
];
4022 desc
.report_descriptor_len
= sizeof(report_desc
);
4023 memcpy( desc
.report_descriptor_buf
, report_desc
, sizeof(report_desc
) );
4024 fill_context( desc
.context
, ARRAY_SIZE(desc
.context
) );
4026 if (!hid_device_start( &desc
, 2 )) goto done
;
4028 swprintf( device_path
, MAX_PATH
, L
"\\\\?\\hid#vid_%04x&pid_%04x&col01", desc
.attributes
.VendorID
,
4029 desc
.attributes
.ProductID
);
4030 ret
= find_hid_device_path( device_path
);
4032 ok( ret
, "Failed to find HID device matching %s\n", debugstr_w( device_path
) );
4033 if (!ret
) goto done
;
4035 file
= CreateFileW( device_path
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
4036 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
4037 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
4038 check_preparsed_data( file
, &expect_kdr_joystick
, ARRAY_SIZE(expect_caps_joystick
), expect_caps_joystick
,
4039 ARRAY_SIZE(expect_nodes_joystick
), expect_nodes_joystick
);
4040 CloseHandle( file
);
4042 swprintf( device_path
, MAX_PATH
, L
"\\\\?\\hid#vid_%04x&pid_%04x&col02", desc
.attributes
.VendorID
,
4043 desc
.attributes
.ProductID
);
4044 ret
= find_hid_device_path( device_path
);
4045 ok( ret
, "Failed to find HID device matching %s\n", debugstr_w( device_path
) );
4047 file
= CreateFileW( device_path
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
4048 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
4049 ok( file
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError() );
4050 check_preparsed_data( file
, &expect_kdr_gamepad
, ARRAY_SIZE(expect_caps_gamepad
), expect_caps_gamepad
,
4051 ARRAY_SIZE(expect_nodes_gamepad
), expect_nodes_gamepad
);
4052 CloseHandle( file
);
4054 swprintf( device_path
, MAX_PATH
, L
"\\\\?\\hid#vid_%04x&pid_%04x&col03", desc
.attributes
.VendorID
,
4055 desc
.attributes
.ProductID
);
4056 ret
= find_hid_device_path( device_path
);
4057 ok( !ret
, "Failed to find HID device matching %s\n", debugstr_w( device_path
) );
4060 hid_device_stop( &desc
, 2 );
4069 if (!bus_device_start()) goto done
;
4071 test_hid_driver( 0, FALSE
);
4072 test_hid_driver( 1, FALSE
);
4073 test_hid_driver( 0, TRUE
);
4074 test_hid_driver( 1, TRUE
);
4075 test_hid_multiple_tlc();