dinput/tests: Add a zero-terminator for hardware ids (Valgrind).
[wine.git] / dlls / dinput / tests / hid.c
blob9a27f8e93ac76b309200089f3f4e3c3f2fbe4081
1 /*
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
21 #include <stdarg.h>
22 #include <stddef.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winioctl.h"
29 #include "winternl.h"
30 #include "wincrypt.h"
31 #include "winreg.h"
32 #include "winsvc.h"
33 #include "winuser.h"
34 #include "winnls.h"
36 #include "mscat.h"
37 #include "mssip.h"
38 #include "ntsecapi.h"
39 #include "setupapi.h"
40 #include "cfgmgr32.h"
41 #include "newdev.h"
42 #include "dbt.h"
43 #include "devguid.h"
45 #include "objbase.h"
47 #define COBJMACROS
49 #include "initguid.h"
50 #include "ddk/wdm.h"
51 #include "ddk/hidclass.h"
52 #include "ddk/hidsdi.h"
53 #include "ddk/hidpi.h"
54 #include "ddk/hidport.h"
55 #include "dinput.h"
56 #include "dinputd.h"
57 #include "hidusage.h"
59 #include "wine/mssign.h"
61 #include "dinput_test.h"
63 HINSTANCE instance;
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;
82 static HANDLE okfile;
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;
110 HCRYPTPROV provider;
111 HCRYPTKEY key;
112 HRESULT hr;
113 BOOL ret;
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() );
205 return NULL;
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() );
216 return NULL;
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 );
244 todo_wine
245 ok( hr == S_OK || broken( hr == NTE_BAD_ALGID ) /* < 7 */, "Failed to sign, hr %#lx\n", hr );
247 return cert;
250 static void testsign_cleanup( const CERT_CONTEXT *cert )
252 HCERTSTORE root_store, pub_store;
253 const CERT_CONTEXT *store_cert;
254 HCRYPTPROV provider;
255 BOOL ret;
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];
286 DWORD written;
287 HANDLE file;
288 HRSRC res;
289 void *ptr;
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" );
302 CloseHandle( file );
305 #ifdef __i386__
306 #define EXT "x86"
307 #elif defined(__x86_64__)
308 #define EXT "amd64"
309 #elif defined(__arm__)
310 #define EXT "arm"
311 #elif defined(__aarch64__)
312 #define EXT "arm64"
313 #else
314 #define EXT
315 #endif
317 static const char inf_text[] =
318 "[Version]\n"
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"
324 "[Manufacturer]\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"
350 "[file_section]\n"
351 "winetest_bus.sys\n"
352 "winetest_hid.sys\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"
368 "[bus_service]\n"
369 "ServiceBinary=%12%\\winetest_bus.sys\n"
370 "ServiceType=1\n"
371 "StartType=3\n"
372 "ErrorControl=1\n"
373 "LoadOrderGroup=WinePlugPlay\n"
374 "DisplayName=\"Wine Test Bus Driver\"\n"
376 "[hid_service]\n"
377 "ServiceBinary=%12%\\winetest_hid.sys\n"
378 "ServiceType=1\n"
379 "StartType=3\n"
380 "ErrorControl=1\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"
386 "ServiceType=1\n"
387 "StartType=3\n"
388 "ErrorControl=1\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];
400 GUID subject_guid;
401 unsigned int i;
402 DWORD size;
403 BOOL ret;
405 ret = CryptSIPRetrieveSubjectGuidForCatalogFile( file, NULL, &subject_guid );
406 todo_wine
407 ok( ret, "Failed to get subject guid, error %lu\n", GetLastError() );
409 size = 0;
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 );
416 todo_wine
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 );
421 todo_wine
422 ok( ret, "Failed to get indirect data, error %lu\n", GetLastError() );
423 if (ret)
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)
455 BOOL ret;
456 Sleep( 100 );
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;
473 char buffer[512];
474 HDEVINFO set;
475 HANDLE file;
476 DWORD size;
477 BOOL ret;
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() );
489 return;
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 );
560 HDEVINFO set;
561 BOOL ret;
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() );
572 if (!ret) continue;
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 );
589 return ret;
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;
602 HANDLE catalog;
603 HDEVINFO set;
604 FILE *f;
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 );
626 fclose( 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 );
639 todo_wine
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;
658 return FALSE;
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 )
712 HANDLE control;
713 DWORD ret, i;
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 );
722 if (!ret) return;
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 );
730 todo_wine_if(i > 0)
731 ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
735 BOOL hid_device_start( struct hid_device_desc *desc, UINT count )
737 HANDLE control;
738 DWORD ret, i;
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 );
755 todo_wine_if(i > 0)
756 ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
759 return TRUE;
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};
901 BOOL ret;
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() );
911 if (!ret)
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;
921 return ret;
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;
930 else source_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];
938 SIZE_T size;
939 BOOL ret;
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)];
962 SIZE_T size;
964 if (desc) memcpy( buffer, desc, sizeof(*desc) );
965 else memset( buffer, 0, sizeof(*desc) );
967 memcpy( buffer + sizeof(*desc), &params, sizeof(params) );
968 size = sizeof(*desc) + sizeof(params);
970 todo_wine_if(todo) {
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];
982 SIZE_T size;
983 BOOL ret;
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},
1010 .ret_length = 3,
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},
1018 .ret_length = 3,
1019 .ret_status = STATUS_SUCCESS,
1023 char buffer[200], report[200];
1024 NTSTATUS status;
1025 ULONG length;
1026 BOOL ret;
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() );
1043 if (!report_id)
1045 struct hid_expect broken_expect =
1047 .code = IOCTL_HID_GET_INPUT_REPORT,
1048 .broken = TRUE,
1049 .report_len = report_len - 1,
1050 .report_buf =
1052 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1053 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1054 0x5a,0x5a,0x5a,0x5a,0x5a,
1056 .ret_length = 3,
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() );
1072 else
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},
1104 .ret_length = 3,
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},
1112 .ret_length = 3,
1113 .ret_status = STATUS_SUCCESS,
1117 char buffer[200], report[200];
1118 NTSTATUS status;
1119 ULONG length;
1120 BOOL ret;
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() );
1137 if (!report_id)
1139 struct hid_expect broken_expect =
1141 .code = IOCTL_HID_GET_FEATURE,
1142 .broken = TRUE,
1143 .report_len = report_len - 1,
1144 .report_buf =
1146 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1147 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1148 0x5a,0x5a,0x5a,0x5a,0x5a,
1150 .ret_length = 3,
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() );
1166 else
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},
1198 .ret_length = 3,
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),
1205 .report_buf =
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,
1211 .ret_length = 3,
1212 .ret_status = STATUS_SUCCESS,
1215 char buffer[200], report[200];
1216 NTSTATUS status;
1217 ULONG length;
1218 BOOL ret;
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() );
1235 if (!report_id)
1237 struct hid_expect broken_expect =
1239 .code = IOCTL_HID_SET_FEATURE,
1240 .broken = TRUE,
1241 .report_len = report_len - 1,
1242 .report_buf =
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,
1249 .ret_length = 3,
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() );
1265 else
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",
1281 GetLastError() );
1282 length = 0;
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},
1300 .ret_length = 3,
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},
1308 .ret_length = 3,
1309 .ret_status = STATUS_SUCCESS,
1313 char buffer[200], report[200];
1314 NTSTATUS status;
1315 ULONG length;
1316 BOOL ret;
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",
1328 GetLastError() );
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() );
1336 if (!report_id)
1338 struct hid_expect broken_expect =
1340 .code = IOCTL_HID_SET_OUTPUT_REPORT,
1341 .broken = TRUE,
1342 .report_len = report_len - 1,
1343 .report_buf = {0x5a,0x5a},
1344 .ret_length = 3,
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() );
1360 else
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() );
1377 length = 0;
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},
1394 .ret_length = 3,
1395 .ret_status = STATUS_SUCCESS,
1398 char report[200];
1399 ULONG length;
1400 BOOL ret;
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) );
1417 report[0] = 0xa5;
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 );
1430 if (report_id)
1432 ok( ret, "WriteFile failed, last error %lu\n", GetLastError() );
1433 ok( length == 2, "WriteFile wrote %lu\n", length );
1435 else
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,
1451 .BitField = 2,
1452 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1453 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1454 .LinkCollection = 1,
1455 .IsRange = TRUE,
1456 .IsAbsolute = TRUE,
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,
1465 .BitField = 3,
1466 .LinkCollection = 1,
1467 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1468 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1469 .IsRange = TRUE,
1470 .IsAbsolute = TRUE,
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,
1479 .BitField = 0x1fc,
1480 .LinkCollection = 1,
1481 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1482 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1483 .IsRange = TRUE,
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,
1493 .BitField = 2,
1494 .LinkCollection = 1,
1495 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1496 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1497 .IsRange = FALSE,
1498 .IsAbsolute = TRUE,
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,
1510 .BitField = 2,
1511 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1512 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1513 .LinkCollection = 1,
1514 .IsAbsolute = TRUE,
1515 .BitSize = 8,
1516 .ReportCount = 1,
1517 .LogicalMin = -128,
1518 .LogicalMax = 127,
1519 .NotRange.Usage = HID_USAGE_GENERIC_Y,
1520 .NotRange.Reserved1 = HID_USAGE_GENERIC_Y,
1523 .UsagePage = HID_USAGE_PAGE_GENERIC,
1524 .ReportID = report_id,
1525 .BitField = 2,
1526 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1527 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1528 .LinkCollection = 1,
1529 .IsAbsolute = TRUE,
1530 .BitSize = 8,
1531 .ReportCount = 1,
1532 .LogicalMin = -128,
1533 .LogicalMax = 127,
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,
1542 .BitField = 2,
1543 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1544 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1545 .LinkCollection = 1,
1546 .IsAbsolute = TRUE,
1547 .ReportCount = 1,
1548 .LogicalMax = 1,
1549 .IsRange = TRUE,
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,
1558 .BitField = 2,
1559 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1560 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1561 .LinkCollection = 1,
1562 .IsAbsolute = TRUE,
1563 .BitSize = 24,
1564 .ReportCount = 2,
1565 .LogicalMin = 1,
1566 .LogicalMax = 8,
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,
1580 .FirstChild = 10,
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];
1611 HIDP_DATA data[64];
1612 USAGE usages[16];
1613 ULONG off, value;
1614 NTSTATUS status;
1615 HIDP_CAPS caps;
1616 unsigned int i;
1617 USHORT count;
1618 BOOL ret;
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 );
1660 count = 0;
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 );
1686 count = 0;
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] );
1707 count = 0xbeef;
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 );
1711 count = 0xbeef;
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 );
1715 count = 0xbeef;
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 );
1725 count = 0;
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 );
1750 count = 0;
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] );
1768 count = 1;
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] );
1775 count = 0xdead;
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 );
1779 count = 0xdead;
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 );
1783 count = 0xdead;
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] );
1822 report[16] = 0xa5;
1823 report[17] = 0xa5;
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 );
1837 report[16] = 0xcd;
1838 report[17] = 0xcd;
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 );
1850 report[16] = 0xff;
1851 report[17] = 0xff;
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 );
1857 value = -128;
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 );
1861 value = 0xdeadbeef;
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 );
1866 value = 0xdeadbeef;
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 );
1872 value = 127;
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 );
1876 value = 0xdeadbeef;
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 );
1882 value = 0;
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 );
1886 value = 0xdeadbeef;
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 );
1892 value = 0x7fffffff;
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 );
1896 value = 0xdeadbeef;
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 );
1901 value = 0xdeadbeef;
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 );
1907 value = 0x3fffffff;
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 );
1911 value = 0xdeadbeef;
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 );
1917 value = 0;
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 );
1921 value = 0xdeadbeef;
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 );
1927 value = 0;
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 );
1931 value = 0xdeadbeef;
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 );
1937 value = 0xfeedcafe;
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 );
1941 value = 0xdeadbeef;
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",
1956 value, 32 );
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",
1959 value, 8 );
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",
1962 value, 8 );
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",
1965 value, 0 );
1967 usages[0] = 0xff;
1968 value = 1;
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 );
1972 usages[1] = 2;
1973 usages[2] = 0xff;
1974 value = 3;
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 );
1978 usages[0] = 4;
1979 usages[1] = 6;
1980 value = 2;
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 );
1984 usages[0] = 4;
1985 usages[1] = 6;
1986 value = 2;
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 );
1997 usages[0] = 0x9;
1998 usages[1] = 0xb;
1999 usages[2] = 0xa;
2000 value = 3;
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 );
2007 buffer[13] = 2;
2008 buffer[14] = 4;
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 );
2015 value = 0xdeadbeef;
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 );
2021 value = 1;
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 );
2084 value = 1;
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 );
2104 value = 2;
2105 usages[0] = 0x8e;
2106 usages[1] = 0x8f;
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 );
2124 value = 1;
2125 usages[0] = 0x8c;
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" );
2153 waveform_list = i;
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 );
2173 report[0] = 2;
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 );
2209 report[0] = 2;
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 );
2218 value = 0xdeadbeef;
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" );
2248 value = 0x7fffffff;
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 );
2252 value = 0xdeadbeef;
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 );
2257 value = 0xdeadbeef;
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 );
2263 value = 0x7fff;
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 );
2267 value = 0xdeadbeef;
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 );
2273 value = 0;
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 );
2277 value = 0xdeadbeef;
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 );
2285 value = 0;
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 );
2293 value = 0;
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 );
2301 value = 0;
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 );
2309 value = 0;
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 );
2351 buffer[i + 21] = i;
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 );
2364 buffer[i + 21] = i;
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",
2378 GetLastError() );
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",
2383 GetLastError() );
2384 ok( value == 0, "ReadFile returned %lx\n", value );
2386 if (polled)
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},
2394 .ret_length = 3,
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},
2401 .ret_length = 3,
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" );
2466 value = 10;
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() );
2471 Sleep( 600 );
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) );
2496 Sleep( 600 );
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 );
2512 else
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},
2520 .ret_length = 3,
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() );
2550 Sleep( 50 );
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() );
2560 Sleep( 50 );
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 */
2575 Sleep( 50 );
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;
2622 DWORD ret;
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() );
2642 count = 0xdeadbeef;
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",
2652 GetLastError() );
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",
2657 GetLastError() );
2659 SetLastError( 0xdeadbeef );
2660 ret = HidD_SetNumInputBuffers( file, 16 );
2661 ok( ret, "HidD_SetNumInputBuffers failed last error %lu\n", GetLastError() );
2663 count = 0xdeadbeef;
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() );
2674 count = 0xdeadbeef;
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() );
2684 count = 0xdeadbeef;
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 );
2689 count = 0xdeadbeef;
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 );
2695 if (polled)
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 );
2702 todo_wine
2703 ok( poll_freq == 5, "got poll_freq %lu, expected 5\n", poll_freq );
2705 out_len = 0;
2706 poll_freq = 500;
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 );
2712 out_len = 0;
2713 poll_freq = 10001;
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 );
2719 out_len = 0;
2720 poll_freq = 0;
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 );
2733 out_len = 0;
2734 poll_freq = 500;
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),
2774 REPORT_SIZE(1, 8),
2775 REPORT_COUNT(1, 2),
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),
2783 REPORT_COUNT(1, 8),
2784 REPORT_SIZE(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),
2791 REPORT_COUNT(1, 8),
2792 REPORT_SIZE(1, 1),
2793 INPUT(1, Cnst|Var|Abs),
2794 REPORT_SIZE(1, 8),
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),
2802 REPORT_COUNT(1, 2),
2803 REPORT_SIZE(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 */
2807 USAGE(1, 0x20),
2808 LOGICAL_MINIMUM(1, 0),
2809 LOGICAL_MAXIMUM(1, 1),
2810 REPORT_COUNT(1, 8),
2811 REPORT_SIZE(1, 1),
2812 INPUT(1, Data|Var|Abs),
2813 USAGE_MINIMUM(1, 0x21),
2814 USAGE_MAXIMUM(1, 0x22),
2815 REPORT_COUNT(1, 2),
2816 REPORT_SIZE(1, 0),
2817 INPUT(1, Data|Var|Abs),
2818 USAGE(1, 0x23),
2819 REPORT_COUNT(1, 0),
2820 REPORT_SIZE(1, 1),
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),
2827 REPORT_SIZE(1, 24),
2828 REPORT_COUNT(1, 2),
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),
2837 REPORT_SIZE(1, 32),
2838 REPORT_COUNT(1, 1),
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),
2846 REPORT_SIZE(1, 32),
2847 REPORT_COUNT(1, 1),
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),
2856 REPORT_SIZE(1, 32),
2857 REPORT_COUNT(1, 1),
2858 INPUT(1, Data|Var|Abs),
2859 END_COLLECTION,
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),
2870 REPORT_COUNT(1, 8),
2871 REPORT_SIZE(1, 1),
2872 INPUT(1, Data|Var|Abs),
2873 END_COLLECTION,
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),
2880 USAGE(1, 1),
2881 USAGE(1, 2),
2882 USAGE(1, 3),
2883 USAGE(1, 4),
2884 USAGE(1, 5),
2885 USAGE(1, 6),
2886 USAGE(1, 7),
2887 USAGE(1, 8),
2888 LOGICAL_MINIMUM(1, 0),
2889 LOGICAL_MAXIMUM(1, 1),
2890 PHYSICAL_MINIMUM(1, 0),
2891 PHYSICAL_MAXIMUM(1, 1),
2892 REPORT_COUNT(1, 8),
2893 REPORT_SIZE(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),
2902 REPORT_COUNT(1, 2),
2903 REPORT_SIZE(1, 8),
2904 INPUT(1, Data|Ary|Abs),
2905 END_COLLECTION,
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),
2920 REPORT_COUNT(1, 2),
2921 REPORT_SIZE(1, 16),
2922 FEATURE(1, Data|Var|Abs|Null),
2923 END_COLLECTION,
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),
2933 REPORT_COUNT(1, 2),
2934 REPORT_SIZE(1, 16),
2935 FEATURE(1, Data|Var|Abs|Null),
2936 END_COLLECTION,
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),
2946 REPORT_SIZE(1, 32),
2947 REPORT_COUNT(1, 2),
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),
2959 REPORT_SIZE(1, 32),
2960 REPORT_COUNT(1, 1),
2961 FEATURE(1, Data|Var|Abs),
2962 END_COLLECTION,
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),
2969 REPORT_SIZE(1, 8),
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),
2982 END_COLLECTION,
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),
2995 REPORT_COUNT(1, 8),
2996 REPORT_SIZE(1, 1),
2997 FEATURE(1, Data|Var|Abs),
2998 END_COLLECTION,
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),
3005 REPORT_COUNT(1, 8),
3006 REPORT_SIZE(1, 1),
3007 OUTPUT(1, Cnst|Var|Abs),
3008 END_COLLECTION,
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),
3015 REPORT_COUNT(1, 8),
3016 REPORT_SIZE(1, 1),
3017 OUTPUT(1, Cnst|Var|Abs),
3018 END_COLLECTION,
3019 END_COLLECTION,
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},
3045 .ret_length = 3,
3046 .ret_status = STATUS_SUCCESS,
3048 struct hid_device_desc desc =
3050 .is_polled = polled,
3051 .use_report_id = report_id,
3052 .caps = caps,
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
3070 USHORT usage_page;
3071 UCHAR report_id;
3072 UCHAR start_bit;
3073 USHORT bit_size;
3074 USHORT report_count;
3075 USHORT start_byte;
3076 USHORT total_bits;
3077 ULONG bit_field;
3078 USHORT end_byte;
3079 USHORT link_collection;
3080 USAGE link_usage_page;
3081 USAGE link_usage;
3082 ULONG flags;
3083 ULONG padding[8];
3084 USAGE usage_min;
3085 USAGE usage_max;
3086 USHORT string_min;
3087 USHORT string_max;
3088 USHORT designator_min;
3089 USHORT designator_max;
3090 USHORT data_index_min;
3091 USHORT data_index_max;
3092 USHORT null_value;
3093 USHORT unknown;
3094 LONG logical_min;
3095 LONG logical_max;
3096 LONG physical_min;
3097 LONG physical_max;
3098 LONG units;
3099 LONG units_exp;
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
3113 USAGE usage;
3114 USAGE usage_page;
3115 USHORT parent;
3116 USHORT number_of_children;
3117 USHORT next_sibling;
3118 USHORT first_child;
3119 ULONG collection_type;
3122 struct hidp_kdr
3124 char magic[8];
3125 USAGE usage;
3126 USAGE usage_page;
3127 USHORT unknown[2];
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;
3140 USHORT caps_size;
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;
3152 BOOL ret;
3153 UINT i;
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),
3259 REPORT_SIZE(1, 16),
3260 REPORT_COUNT(1, 0),
3261 FEATURE(1, Data|Var|Abs),
3262 USAGE(1, HID_USAGE_GENERIC_SLIDER),
3263 REPORT_SIZE(1, 16),
3264 REPORT_COUNT(1, 1),
3265 FEATURE(1, Data|Var|Abs),
3267 USAGE(1, HID_USAGE_GENERIC_X),
3268 REPORT_SIZE(1, 8),
3269 REPORT_COUNT(1, 1),
3270 UNIT(1, 0x100e),
3271 UNIT_EXPONENT(1, -3),
3272 INPUT(1, Data|Var|Abs),
3273 UNIT_EXPONENT(1, 0),
3274 UNIT(1, 0),
3275 USAGE(1, HID_USAGE_GENERIC_Y),
3276 DESIGNATOR_MINIMUM(1, 1),
3277 DESIGNATOR_MAXIMUM(1, 4),
3278 REPORT_SIZE(1, 8),
3279 REPORT_COUNT(1, 1),
3280 INPUT(1, Cnst|Var|Abs),
3281 USAGE(1, HID_USAGE_GENERIC_Z),
3282 REPORT_SIZE(1, 8),
3283 REPORT_COUNT(1, 1),
3284 INPUT(1, Data|Var|Rel),
3285 USAGE(1, HID_USAGE_GENERIC_RX),
3286 USAGE(1, HID_USAGE_GENERIC_RY),
3287 REPORT_SIZE(1, 16),
3288 REPORT_COUNT(1, 2),
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),
3295 REPORT_SIZE(1, 1),
3296 REPORT_COUNT(1, 8),
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),
3303 REPORT_SIZE(1, 8),
3304 REPORT_COUNT(1, 1),
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),
3311 REPORT_SIZE(1, 8),
3312 REPORT_COUNT(1, 4),
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),
3321 REPORT_SIZE(1, 8),
3322 REPORT_COUNT(1, 1),
3323 LOGICAL_MINIMUM(1, 13),
3324 LOGICAL_MAXIMUM(1, 16),
3325 INPUT(1, Data|Ary|Abs),
3326 END_COLLECTION,
3327 END_COLLECTION,
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",
3340 .usage = 0x04,
3341 .usage_page = 0x01,
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,
3351 .caps_size = 1560,
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,
3400 .logical_min = 8
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,
3406 .logical_min = 12
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,
3412 .logical_min = 16
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,
3418 .logical_min = 16
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,
3424 .logical_min = 16
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,
3430 .logical_min = 16
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,
3436 .physical_max = 127
3441 static const struct hidp_kdr_node expect_nodes[] =
3444 .usage = 0x04,
3445 .usage_page = 0x01,
3446 .parent = 0,
3447 .number_of_children = 0x1,
3448 .next_sibling = 0,
3449 .first_child = 0x1,
3450 .collection_type = 0x1,
3453 .usage = 0x00,
3454 .usage_page = 0x01,
3455 .parent = 0,
3456 .number_of_children = 0,
3457 .next_sibling = 0,
3458 .first_child = 0,
3459 .collection_type = 0x1,
3463 WCHAR device_path[MAX_PATH];
3464 HANDLE file;
3465 BOOL ret;
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 );
3487 done:
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";
3497 HKEY root_key;
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
3502 support.
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,
3549 WNDCLASSEXW class =
3551 .cbSize = sizeof(WNDCLASSEXW),
3552 .hInstance = GetModuleHandleW( NULL ),
3553 .lpszClassName = L"device_monitor",
3554 .lpfnWndProc = monitor_wndproc,
3556 HDEVNOTIFY devnotify;
3557 HANDLE hwnd;
3558 MSG msg;
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 );
3580 return 0;
3583 void dinput_test_init_( const char *file, int line )
3585 BOOL is_wow64;
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" );
3605 return;
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" );
3613 return;
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)
3636 DWORD ret;
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 );
3651 CoUninitialize();
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;
3664 IDirectInputW *di;
3665 HRESULT hr;
3666 ULONG ref;
3668 if (version >= 0x800)
3670 hr = DirectInput8Create( instance, version, &IID_IDirectInput8W, (void **)&di8, NULL );
3671 if (FAILED(hr))
3673 win_skip( "DirectInput8Create returned %#lx\n", hr );
3674 return 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 );
3693 else
3695 hr = DirectInputCreateEx( instance, version, &IID_IDirectInput2W, (void **)&di, NULL );
3696 if (FAILED(hr))
3698 win_skip( "DirectInputCreateEx returned %#lx\n", hr );
3699 return 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 );
3720 return DI_OK;
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),
3739 REPORT_SIZE(1, 8),
3740 REPORT_COUNT(1, 2),
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),
3750 REPORT_SIZE(1, 1),
3751 REPORT_COUNT(1, 8),
3752 INPUT(1, Data|Var|Abs),
3753 END_COLLECTION,
3754 END_COLLECTION,
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,
3772 .caps = caps,
3773 .attributes = attributes,
3775 DWORD ret;
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 );
3786 return 0;
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),
3798 REPORT_SIZE(1, 8),
3799 REPORT_COUNT(1, 1),
3800 INPUT(1, Data|Var|Abs),
3801 END_COLLECTION,
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];
3825 HANDLE control;
3826 DWORD ret;
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 );
3835 bus_device_stop();
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" );
3841 bus_device_start();
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 );
3870 done:
3871 bus_device_stop();
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),
3884 REPORT_ID(1, 1),
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),
3891 REPORT_SIZE(1, 1),
3892 REPORT_COUNT(1, 8),
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),
3898 REPORT_SIZE(1, 16),
3899 REPORT_COUNT(1, 2),
3900 LOGICAL_MINIMUM(2, -10),
3901 LOGICAL_MAXIMUM(2, +10),
3902 INPUT(1, Data|Var|Rel),
3903 END_COLLECTION,
3904 END_COLLECTION,
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),
3911 REPORT_ID(1, 2),
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),
3918 REPORT_SIZE(1, 1),
3919 REPORT_COUNT(1, 40),
3920 INPUT(1, Data|Var|Abs),
3921 END_COLLECTION,
3922 END_COLLECTION,
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",
3936 .usage = 0x04,
3937 .usage_page = 0x01,
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,
3945 .caps_size = 312,
3946 .number_link_collection_nodes = 2,
3948 static const struct hidp_kdr expect_kdr_gamepad =
3950 .magic = "HidP KDR",
3951 .usage = 0x05,
3952 .usage_page = 0x01,
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,
3960 .caps_size = 104,
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[] =
3992 .usage = 0x04,
3993 .usage_page = 0x01,
3994 .number_of_children = 1,
3995 .first_child = 1,
3996 .collection_type = 0x1,
3999 .usage = 0x04,
4000 .usage_page = 0x01,
4003 static const struct hidp_kdr_node expect_nodes_gamepad[] =
4006 .usage = 0x05,
4007 .usage_page = 0x01,
4008 .number_of_children = 1,
4009 .first_child = 1,
4010 .collection_type = 1,
4013 .usage = 0x05,
4014 .usage_page = 0x01,
4018 WCHAR device_path[MAX_PATH];
4019 HANDLE file;
4020 BOOL ret;
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 );
4031 todo_wine
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 ) );
4059 done:
4060 hid_device_stop( &desc, 2 );
4063 START_TEST( hid )
4065 dinput_test_init();
4067 test_bus_driver();
4069 if (!bus_device_start()) goto done;
4070 test_hidp_kdr();
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();
4077 done:
4078 bus_device_stop();
4079 dinput_test_exit();