2 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define DIRECTINPUT_VERSION 0x0800
25 #define WIN32_NO_STATUS
51 #include "ddk/hidclass.h"
52 #include "ddk/hidsdi.h"
53 #include "ddk/hidpi.h"
54 #include "ddk/hidport.h"
58 #include "wine/test.h"
59 #include "wine/mssign.h"
61 #include "driver_hid.h"
63 static HINSTANCE instance
;
64 static BOOL localized
; /* object names get translated */
66 #define EXPECT_VIDPID MAKELONG( 0x1209, 0x0001 )
67 static const WCHAR expect_vidpid_str
[] = L
"VID_1209&PID_0001";
68 static const GUID expect_guid_product
= {EXPECT_VIDPID
,0x0000,0x0000,{0x00,0x00,'P','I','D','V','I','D'}};
69 static const WCHAR expect_path
[] = L
"\\\\?\\hid#winetest#1&2fafeb0&";
70 static const WCHAR expect_path_end
[] = L
"&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
72 static struct winetest_shared_data
*test_data
;
75 static HRESULT (WINAPI
*pSignerSign
)( SIGNER_SUBJECT_INFO
*subject
, SIGNER_CERT
*cert
,
76 SIGNER_SIGNATURE_INFO
*signature
, SIGNER_PROVIDER_INFO
*provider
,
77 const WCHAR
*timestamp
, CRYPT_ATTRIBUTES
*attr
, void *sip_data
);
79 static const WCHAR container_name
[] = L
"wine_testsign";
81 static const CERT_CONTEXT
*testsign_sign( const WCHAR
*filename
)
83 BYTE encoded_name
[100], encoded_key_id
[200], public_key_info_buffer
[1000];
84 BYTE hash_buffer
[16], cert_buffer
[1000], provider_nameA
[100], serial
[16];
85 CERT_PUBLIC_KEY_INFO
*public_key_info
= (CERT_PUBLIC_KEY_INFO
*)public_key_info_buffer
;
86 SIGNER_SIGNATURE_INFO signature
= {sizeof(SIGNER_SIGNATURE_INFO
)};
87 SIGNER_CERT_STORE_INFO store
= {sizeof(SIGNER_CERT_STORE_INFO
)};
88 SIGNER_ATTR_AUTHCODE authcode
= {sizeof(SIGNER_ATTR_AUTHCODE
)};
89 SIGNER_SUBJECT_INFO subject
= {sizeof(SIGNER_SUBJECT_INFO
)};
90 SIGNER_FILE_INFO file
= {sizeof(SIGNER_FILE_INFO
)};
91 SIGNER_CERT signer
= {sizeof(SIGNER_CERT
)};
92 CRYPT_KEY_PROV_INFO provider_info
= {0};
93 CRYPT_ALGORITHM_IDENTIFIER algid
= {0};
94 CERT_AUTHORITY_KEY_ID_INFO key_info
;
95 HCERTSTORE root_store
, pub_store
;
96 CERT_INFO cert_info
= {0};
97 WCHAR provider_nameW
[100];
98 const CERT_CONTEXT
*cert
;
99 CERT_EXTENSION extension
;
100 DWORD size
, index
= 0;
106 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
107 if (!ret
&& GetLastError() == NTE_EXISTS
)
109 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
110 ok( ret
, "Failed to delete container, error %#x\n", GetLastError() );
111 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
113 ok( ret
, "Failed to create container, error %#x\n", GetLastError() );
115 ret
= CryptGenKey( provider
, AT_SIGNATURE
, CRYPT_EXPORTABLE
, &key
);
116 ok( ret
, "Failed to create key, error %#x\n", GetLastError() );
117 ret
= CryptDestroyKey( key
);
118 ok( ret
, "Failed to destroy key, error %#x\n", GetLastError() );
119 ret
= CryptGetUserKey( provider
, AT_SIGNATURE
, &key
);
120 ok( ret
, "Failed to get user key, error %#x\n", GetLastError() );
121 ret
= CryptDestroyKey( key
);
122 ok( ret
, "Failed to destroy key, error %#x\n", GetLastError() );
124 size
= sizeof(encoded_name
);
125 ret
= CertStrToNameW( X509_ASN_ENCODING
, L
"CN=winetest_cert", CERT_X500_NAME_STR
, NULL
,
126 encoded_name
, &size
, NULL
);
127 ok( ret
, "Failed to convert name, error %#x\n", GetLastError() );
128 key_info
.CertIssuer
.cbData
= size
;
129 key_info
.CertIssuer
.pbData
= encoded_name
;
131 size
= sizeof(public_key_info_buffer
);
132 ret
= CryptExportPublicKeyInfo( provider
, AT_SIGNATURE
, X509_ASN_ENCODING
, public_key_info
, &size
);
133 ok( ret
, "Failed to export public key, error %#x\n", GetLastError() );
134 cert_info
.SubjectPublicKeyInfo
= *public_key_info
;
136 size
= sizeof(hash_buffer
);
137 ret
= CryptHashPublicKeyInfo( provider
, CALG_MD5
, 0, X509_ASN_ENCODING
, public_key_info
, hash_buffer
, &size
);
138 ok( ret
, "Failed to hash public key, error %#x\n", GetLastError() );
140 key_info
.KeyId
.cbData
= size
;
141 key_info
.KeyId
.pbData
= hash_buffer
;
143 RtlGenRandom( serial
, sizeof(serial
) );
144 key_info
.CertSerialNumber
.cbData
= sizeof(serial
);
145 key_info
.CertSerialNumber
.pbData
= serial
;
147 size
= sizeof(encoded_key_id
);
148 ret
= CryptEncodeObject( X509_ASN_ENCODING
, X509_AUTHORITY_KEY_ID
, &key_info
, encoded_key_id
, &size
);
149 ok( ret
, "Failed to convert name, error %#x\n", GetLastError() );
151 extension
.pszObjId
= (char *)szOID_AUTHORITY_KEY_IDENTIFIER
;
152 extension
.fCritical
= TRUE
;
153 extension
.Value
.cbData
= size
;
154 extension
.Value
.pbData
= encoded_key_id
;
156 cert_info
.dwVersion
= CERT_V3
;
157 cert_info
.SerialNumber
= key_info
.CertSerialNumber
;
158 cert_info
.SignatureAlgorithm
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
159 cert_info
.Issuer
= key_info
.CertIssuer
;
160 GetSystemTimeAsFileTime( &cert_info
.NotBefore
);
161 GetSystemTimeAsFileTime( &cert_info
.NotAfter
);
162 cert_info
.NotAfter
.dwHighDateTime
+= 1;
163 cert_info
.Subject
= key_info
.CertIssuer
;
164 cert_info
.cExtension
= 1;
165 cert_info
.rgExtension
= &extension
;
166 algid
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
167 size
= sizeof(cert_buffer
);
168 ret
= CryptSignAndEncodeCertificate( provider
, AT_SIGNATURE
, X509_ASN_ENCODING
, X509_CERT_TO_BE_SIGNED
,
169 &cert_info
, &algid
, NULL
, cert_buffer
, &size
);
170 ok( ret
, "Failed to create certificate, error %#x\n", GetLastError() );
172 cert
= CertCreateCertificateContext( X509_ASN_ENCODING
, cert_buffer
, size
);
173 ok( !!cert
, "Failed to create context, error %#x\n", GetLastError() );
175 size
= sizeof(provider_nameA
);
176 ret
= CryptGetProvParam( provider
, PP_NAME
, provider_nameA
, &size
, 0 );
177 ok( ret
, "Failed to get prov param, error %#x\n", GetLastError() );
178 MultiByteToWideChar( CP_ACP
, 0, (char *)provider_nameA
, -1, provider_nameW
, ARRAY_SIZE(provider_nameW
) );
180 provider_info
.pwszContainerName
= (WCHAR
*)container_name
;
181 provider_info
.pwszProvName
= provider_nameW
;
182 provider_info
.dwProvType
= PROV_RSA_FULL
;
183 provider_info
.dwKeySpec
= AT_SIGNATURE
;
184 ret
= CertSetCertificateContextProperty( cert
, CERT_KEY_PROV_INFO_PROP_ID
, 0, &provider_info
);
185 ok( ret
, "Failed to set provider info, error %#x\n", GetLastError() );
187 ret
= CryptReleaseContext( provider
, 0 );
188 ok( ret
, "failed to release context, error %u\n", GetLastError() );
190 root_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"root" );
191 if (!root_store
&& GetLastError() == ERROR_ACCESS_DENIED
)
193 win_skip( "Failed to open root store.\n" );
194 ret
= CertFreeCertificateContext( cert
);
195 ok( ret
, "Failed to free certificate, error %u\n", GetLastError() );
198 ok( !!root_store
, "Failed to open store, error %u\n", GetLastError() );
199 ret
= CertAddCertificateContextToStore( root_store
, cert
, CERT_STORE_ADD_ALWAYS
, NULL
);
200 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
202 win_skip( "Failed to add self-signed certificate to store.\n" );
203 ret
= CertFreeCertificateContext( cert
);
204 ok( ret
, "Failed to free certificate, error %u\n", GetLastError() );
205 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
206 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
209 ok( ret
, "Failed to add certificate, error %u\n", GetLastError() );
210 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
211 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
213 pub_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0,
214 CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"trustedpublisher" );
215 ok( !!pub_store
, "Failed to open store, error %u\n", GetLastError() );
216 ret
= CertAddCertificateContextToStore( pub_store
, cert
, CERT_STORE_ADD_ALWAYS
, NULL
);
217 ok( ret
, "Failed to add certificate, error %u\n", GetLastError() );
218 ret
= CertCloseStore( pub_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
219 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
221 subject
.dwSubjectChoice
= 1;
222 subject
.pdwIndex
= &index
;
223 subject
.pSignerFileInfo
= &file
;
224 file
.pwszFileName
= (WCHAR
*)filename
;
225 signer
.dwCertChoice
= 2;
226 signer
.pCertStoreInfo
= &store
;
227 store
.pSigningCert
= cert
;
228 store
.dwCertPolicy
= 0;
229 signature
.algidHash
= CALG_SHA_256
;
230 signature
.dwAttrChoice
= SIGNER_AUTHCODE_ATTR
;
231 signature
.pAttrAuthcode
= &authcode
;
232 authcode
.pwszName
= L
"";
233 authcode
.pwszInfo
= L
"";
234 hr
= pSignerSign( &subject
, &signer
, &signature
, NULL
, NULL
, NULL
, NULL
);
236 ok( hr
== S_OK
|| broken( hr
== NTE_BAD_ALGID
) /* < 7 */, "Failed to sign, hr %#x\n", hr
);
241 static void testsign_cleanup( const CERT_CONTEXT
*cert
)
243 HCERTSTORE root_store
, pub_store
;
244 const CERT_CONTEXT
*store_cert
;
248 root_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"root" );
249 ok( !!root_store
, "Failed to open store, error %u\n", GetLastError() );
250 store_cert
= CertFindCertificateInStore( root_store
, X509_ASN_ENCODING
, 0, CERT_FIND_EXISTING
, cert
, NULL
);
251 ok( !!store_cert
, "Failed to find root certificate, error %u\n", GetLastError() );
252 ret
= CertDeleteCertificateFromStore( store_cert
);
253 ok( ret
, "Failed to remove certificate, error %u\n", GetLastError() );
254 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
255 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
257 pub_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0,
258 CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"trustedpublisher" );
259 ok( !!pub_store
, "Failed to open store, error %u\n", GetLastError() );
260 store_cert
= CertFindCertificateInStore( pub_store
, X509_ASN_ENCODING
, 0, CERT_FIND_EXISTING
, cert
, NULL
);
261 ok( !!store_cert
, "Failed to find publisher certificate, error %u\n", GetLastError() );
262 ret
= CertDeleteCertificateFromStore( store_cert
);
263 ok( ret
, "Failed to remove certificate, error %u\n", GetLastError() );
264 ret
= CertCloseStore( pub_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
265 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
267 ret
= CertFreeCertificateContext( cert
);
268 ok( ret
, "Failed to free certificate, error %u\n", GetLastError() );
270 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
271 ok( ret
, "Failed to delete container, error %#x\n", GetLastError() );
274 static void load_resource( const WCHAR
*name
, WCHAR
*filename
)
276 static WCHAR path
[MAX_PATH
];
282 GetTempPathW( ARRAY_SIZE(path
), path
);
283 GetTempFileNameW( path
, name
, 0, filename
);
285 file
= CreateFileW( filename
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
286 ok( file
!= INVALID_HANDLE_VALUE
, "failed to create %s, error %u\n", debugstr_w(filename
), GetLastError() );
288 res
= FindResourceW( NULL
, name
, L
"TESTDLL" );
289 ok( res
!= 0, "couldn't find resource\n" );
290 ptr
= LockResource( LoadResource( GetModuleHandleW( NULL
), res
) );
291 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleW( NULL
), res
), &written
, NULL
);
292 ok( written
== SizeofResource( GetModuleHandleW( NULL
), res
), "couldn't write resource\n" );
298 #elif defined(__x86_64__)
300 #elif defined(__arm__)
302 #elif defined(__aarch64__)
308 static const char inf_text
[] =
310 "Signature=$Chicago$\n"
311 "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n"
312 "CatalogFile=winetest.cat\n"
313 "DriverVer=09/21/2006,6.0.5736.1\n"
316 "Wine=mfg_section,NT" EXT
"\n"
318 "[mfg_section.NT" EXT
"]\n"
319 "Wine test root driver=device_section,test_hardware_id\n"
321 "[device_section.NT" EXT
"]\n"
322 "CopyFiles=file_section\n"
324 "[device_section.NT" EXT
".Services]\n"
325 "AddService=winetest,0x2,svc_section\n"
330 "[SourceDisksFiles]\n"
333 "[SourceDisksNames]\n"
336 "[DestinationDirs]\n"
337 "DefaultDestDir=12\n"
340 "ServiceBinary=%12%\\winetest.sys\n"
344 "LoadOrderGroup=Extended Base\n"
345 "DisplayName=\"winetest bus driver\"\n"
346 "; they don't sleep anymore, on the beach\n";
348 static void add_file_to_catalog( HANDLE catalog
, const WCHAR
*file
)
350 SIP_SUBJECTINFO subject_info
= {sizeof(SIP_SUBJECTINFO
)};
351 SIP_INDIRECT_DATA
*indirect_data
;
352 const WCHAR
*filepart
= file
;
353 CRYPTCATMEMBER
*member
;
354 WCHAR hash_buffer
[100];
360 ret
= CryptSIPRetrieveSubjectGuidForCatalogFile( file
, NULL
, &subject_guid
);
362 ok( ret
, "Failed to get subject guid, error %u\n", GetLastError() );
365 subject_info
.pgSubjectType
= &subject_guid
;
366 subject_info
.pwsFileName
= file
;
367 subject_info
.DigestAlgorithm
.pszObjId
= (char *)szOID_OIWSEC_sha1
;
368 subject_info
.dwFlags
= SPC_INC_PE_RESOURCES_FLAG
| SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG
|
369 SPC_EXC_PE_PAGE_HASHES_FLAG
| 0x10000;
370 ret
= CryptSIPCreateIndirectData( &subject_info
, &size
, NULL
);
372 ok( ret
, "Failed to get indirect data size, error %u\n", GetLastError() );
374 indirect_data
= malloc( size
);
375 ret
= CryptSIPCreateIndirectData( &subject_info
, &size
, indirect_data
);
377 ok( ret
, "Failed to get indirect data, error %u\n", GetLastError() );
380 memset( hash_buffer
, 0, sizeof(hash_buffer
) );
381 for (i
= 0; i
< indirect_data
->Digest
.cbData
; ++i
)
382 swprintf( &hash_buffer
[i
* 2], 2, L
"%02X", indirect_data
->Digest
.pbData
[i
] );
384 member
= CryptCATPutMemberInfo( catalog
, (WCHAR
*)file
, hash_buffer
, &subject_guid
,
385 0, size
, (BYTE
*)indirect_data
);
386 ok( !!member
, "Failed to write member, error %u\n", GetLastError() );
388 if (wcsrchr( file
, '\\' )) filepart
= wcsrchr( file
, '\\' ) + 1;
390 ret
= !!CryptCATPutAttrInfo( catalog
, member
, (WCHAR
*)L
"File",
391 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
392 (wcslen( filepart
) + 1) * 2, (BYTE
*)filepart
);
393 ok( ret
, "Failed to write attr, error %u\n", GetLastError() );
395 ret
= !!CryptCATPutAttrInfo( catalog
, member
, (WCHAR
*)L
"OSAttr",
396 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
397 sizeof(L
"2:6.0"), (BYTE
*)L
"2:6.0" );
398 ok( ret
, "Failed to write attr, error %u\n", GetLastError() );
402 static void unload_driver( SC_HANDLE service
)
404 SERVICE_STATUS status
;
406 ControlService( service
, SERVICE_CONTROL_STOP
, &status
);
407 while (status
.dwCurrentState
== SERVICE_STOP_PENDING
)
411 ret
= QueryServiceStatus( service
, &status
);
412 ok( ret
, "QueryServiceStatus failed: %u\n", GetLastError() );
414 ok( status
.dwCurrentState
== SERVICE_STOPPED
, "expected SERVICE_STOPPED, got %d\n", status
.dwCurrentState
);
416 DeleteService( service
);
417 CloseServiceHandle( service
);
420 static void pnp_driver_stop(void)
422 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
423 WCHAR path
[MAX_PATH
], dest
[MAX_PATH
], *filepart
;
424 SC_HANDLE manager
, service
;
431 set
= SetupDiCreateDeviceInfoList( NULL
, NULL
);
432 ok( set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %u\n", GetLastError() );
434 ret
= SetupDiOpenDeviceInfoW( set
, L
"root\\winetest\\0", NULL
, 0, &device
);
435 if (!ret
&& GetLastError() == ERROR_NO_SUCH_DEVINST
)
437 ret
= SetupDiDestroyDeviceInfoList( set
);
438 ok( ret
, "failed to destroy set, error %u\n", GetLastError() );
441 ok( ret
, "failed to open device, error %u\n", GetLastError() );
443 ret
= SetupDiCallClassInstaller( DIF_REMOVE
, set
, &device
);
444 ok( ret
, "failed to remove device, error %u\n", GetLastError() );
446 file
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
447 NULL
, OPEN_EXISTING
, 0, NULL
);
448 ok( file
== INVALID_HANDLE_VALUE
, "expected failure\n" );
449 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %u\n", GetLastError() );
451 ret
= SetupDiDestroyDeviceInfoList( set
);
452 ok( ret
, "failed to destroy set, error %u\n", GetLastError() );
454 /* Windows stops the service but does not delete it. */
455 manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_CONNECT
);
456 ok( !!manager
, "failed to open service manager, error %u\n", GetLastError() );
458 service
= OpenServiceW( manager
, L
"winetest", SERVICE_STOP
| DELETE
);
459 if (service
) unload_driver( service
);
460 else ok( GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "got error %u\n", GetLastError() );
462 CloseServiceHandle( manager
);
464 SetFilePointer( okfile
, 0, NULL
, FILE_BEGIN
);
467 ReadFile( okfile
, buffer
, sizeof(buffer
), &size
, NULL
);
468 printf( "%.*s", size
, buffer
);
469 } while (size
== sizeof(buffer
));
470 SetFilePointer( okfile
, 0, NULL
, FILE_BEGIN
);
471 SetEndOfFile( okfile
);
473 winetest_add_failures( InterlockedExchange( &test_data
->failures
, 0 ) );
474 winetest_add_failures( InterlockedExchange( &test_data
->todo_failures
, 0 ) );
476 GetFullPathNameW( L
"winetest.inf", ARRAY_SIZE(path
), path
, NULL
);
477 ret
= SetupCopyOEMInfW( path
, NULL
, 0, 0, dest
, ARRAY_SIZE(dest
), NULL
, &filepart
);
478 ok( ret
, "Failed to copy INF, error %u\n", GetLastError() );
479 ret
= SetupUninstallOEMInfW( filepart
, 0, NULL
);
480 ok( ret
, "Failed to uninstall INF, error %u\n", GetLastError() );
482 ret
= DeleteFileW( L
"winetest.cat" );
483 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
484 ret
= DeleteFileW( L
"winetest.inf" );
485 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
486 ret
= DeleteFileW( L
"winetest.sys" );
487 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
488 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
489 ret
= DeleteFileW( L
"C:/windows/system32/drivers/winetest.sys" );
490 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %u\n", GetLastError() );
493 static BOOL
pnp_driver_start( const WCHAR
*resource
)
495 static const WCHAR hardware_id
[] = L
"test_hardware_id\0";
496 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
497 WCHAR path
[MAX_PATH
], filename
[MAX_PATH
];
498 SC_HANDLE manager
, service
;
499 const CERT_CONTEXT
*cert
;
500 BOOL ret
, need_reboot
;
505 load_resource( resource
, filename
);
506 ret
= MoveFileExW( filename
, L
"winetest.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
507 ok( ret
, "failed to move file, error %u\n", GetLastError() );
509 f
= fopen( "winetest.inf", "w" );
510 ok( !!f
, "failed to open winetest.inf: %s\n", strerror( errno
) );
511 fputs( inf_text
, f
);
514 /* Create the catalog file. */
516 catalog
= CryptCATOpen( (WCHAR
*)L
"winetest.cat", CRYPTCAT_OPEN_CREATENEW
, 0, CRYPTCAT_VERSION_1
, 0 );
517 ok( catalog
!= INVALID_HANDLE_VALUE
, "Failed to create catalog, error %u\n", GetLastError() );
519 add_file_to_catalog( catalog
, L
"winetest.sys" );
520 add_file_to_catalog( catalog
, L
"winetest.inf" );
522 ret
= CryptCATPersistStore( catalog
);
524 ok( ret
, "Failed to write catalog, error %u\n", GetLastError() );
526 ret
= CryptCATClose( catalog
);
527 ok( ret
, "Failed to close catalog, error %u\n", GetLastError() );
529 if (!(cert
= testsign_sign( L
"winetest.cat" )))
531 ret
= DeleteFileW( L
"winetest.cat" );
532 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
533 ret
= DeleteFileW( L
"winetest.inf" );
534 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
535 ret
= DeleteFileW( L
"winetest.sys" );
536 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
540 /* Install the driver. */
542 set
= SetupDiCreateDeviceInfoList( NULL
, NULL
);
543 ok( set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %u\n", GetLastError() );
545 ret
= SetupDiCreateDeviceInfoW( set
, L
"root\\winetest\\0", &GUID_NULL
, NULL
, NULL
, 0, &device
);
546 ok( ret
, "failed to create device, error %#x\n", GetLastError() );
548 ret
= SetupDiSetDeviceRegistryPropertyW( set
, &device
, SPDRP_HARDWAREID
, (const BYTE
*)hardware_id
,
549 sizeof(hardware_id
) );
550 ok( ret
, "failed to create set hardware ID, error %u\n", GetLastError() );
552 ret
= SetupDiCallClassInstaller( DIF_REGISTERDEVICE
, set
, &device
);
553 ok( ret
, "failed to register device, error %u\n", GetLastError() );
555 ret
= SetupDiDestroyDeviceInfoList( set
);
556 ok( ret
, "failed to destroy set, error %u\n", GetLastError() );
558 GetFullPathNameW( L
"winetest.inf", ARRAY_SIZE(path
), path
, NULL
);
560 ret
= UpdateDriverForPlugAndPlayDevicesW( NULL
, hardware_id
, path
, INSTALLFLAG_FORCE
, &need_reboot
);
561 ok( ret
, "failed to install device, error %u\n", GetLastError() );
562 ok( !need_reboot
, "expected no reboot necessary\n" );
564 testsign_cleanup( cert
);
566 /* Check that the service is created and started. */
567 manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_CONNECT
);
568 ok( !!manager
, "failed to open service manager, error %u\n", GetLastError() );
570 service
= OpenServiceW( manager
, L
"winetest", SERVICE_START
);
571 ok( !!service
, "failed to open service, error %u\n", GetLastError() );
573 ret
= StartServiceW( service
, 0, NULL
);
574 ok( !ret
, "service didn't start automatically\n" );
575 if (!ret
&& GetLastError() != ERROR_SERVICE_ALREADY_RUNNING
)
577 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
578 ok( GetLastError() == ERROR_DRIVER_BLOCKED
|| GetLastError() == ERROR_INVALID_IMAGE_HASH
,
579 "unexpected error %u\n", GetLastError() );
580 win_skip( "Failed to start service; probably your machine doesn't accept unsigned drivers.\n" );
583 CloseServiceHandle( service
);
584 CloseServiceHandle( manager
);
585 return ret
|| GetLastError() == ERROR_SERVICE_ALREADY_RUNNING
;
588 #define check_member_( file, line, val, exp, fmt, member ) \
589 ok_( file, line )((val).member == (exp).member, "got " #member " " fmt ", expected " fmt "\n", \
590 (val).member, (exp).member)
591 #define check_member( val, exp, fmt, member ) \
592 check_member_( __FILE__, __LINE__, val, exp, fmt, member )
594 #define check_member_guid_( file, line, val, exp, member ) \
595 ok_( file, line )(IsEqualGUID( &(val).member, &(exp).member ), "got " #member " %s, expected %s\n", \
596 debugstr_guid( &(val).member ), debugstr_guid( &(exp).member ))
597 #define check_member_guid( val, exp, member ) \
598 check_member_guid_( __FILE__, __LINE__, val, exp, member )
600 #define check_member_wstr_( file, line, val, exp, member ) \
601 ok_( file, line )(!wcscmp( (val).member, (exp).member ), "got " #member " %s, expected %s\n", \
602 debugstr_w((val).member), debugstr_w((exp).member))
603 #define check_member_wstr( val, exp, member ) \
604 check_member_wstr_( __FILE__, __LINE__, val, exp, member )
606 #define check_hidp_caps( a, b ) check_hidp_caps_( __LINE__, a, b )
607 static inline void check_hidp_caps_( int line
, HIDP_CAPS
*caps
, const HIDP_CAPS
*exp
)
609 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Usage
);
610 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
611 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", InputReportByteLength
);
612 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", OutputReportByteLength
);
613 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", FeatureReportByteLength
);
614 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberLinkCollectionNodes
);
615 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputButtonCaps
);
616 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputValueCaps
);
617 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputDataIndices
);
618 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputButtonCaps
);
619 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputValueCaps
);
620 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputDataIndices
);
621 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureButtonCaps
);
622 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureValueCaps
);
623 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureDataIndices
);
626 #define check_hidp_link_collection_node( a, b ) check_hidp_link_collection_node_( __LINE__, a, b )
627 static inline void check_hidp_link_collection_node_( int line
, HIDP_LINK_COLLECTION_NODE
*node
,
628 const HIDP_LINK_COLLECTION_NODE
*exp
)
630 check_member_( __FILE__
, line
, *node
, *exp
, "%04x", LinkUsage
);
631 check_member_( __FILE__
, line
, *node
, *exp
, "%04x", LinkUsagePage
);
632 check_member_( __FILE__
, line
, *node
, *exp
, "%d", Parent
);
633 check_member_( __FILE__
, line
, *node
, *exp
, "%d", NumberOfChildren
);
634 check_member_( __FILE__
, line
, *node
, *exp
, "%d", NextSibling
);
635 check_member_( __FILE__
, line
, *node
, *exp
, "%d", FirstChild
);
636 check_member_( __FILE__
, line
, *node
, *exp
, "%d", CollectionType
);
637 check_member_( __FILE__
, line
, *node
, *exp
, "%d", IsAlias
);
640 #define check_hidp_button_caps( a, b ) check_hidp_button_caps_( __LINE__, a, b )
641 static inline void check_hidp_button_caps_( int line
, HIDP_BUTTON_CAPS
*caps
, const HIDP_BUTTON_CAPS
*exp
)
643 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
644 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
645 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
646 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitField
);
647 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
648 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", LinkUsage
);
649 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", LinkUsagePage
);
650 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
651 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
652 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
653 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
655 if (!caps
->IsRange
&& !exp
->IsRange
)
657 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
658 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
660 else if (caps
->IsRange
&& exp
->IsRange
)
662 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
663 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
664 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
665 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
668 if (!caps
->IsRange
&& !exp
->IsRange
)
669 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
670 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
672 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
673 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
676 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
677 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
678 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
680 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
681 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
685 #define check_hidp_value_caps( a, b ) check_hidp_value_caps_( __LINE__, a, b )
686 static inline void check_hidp_value_caps_( int line
, HIDP_VALUE_CAPS
*caps
, const HIDP_VALUE_CAPS
*exp
)
688 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
689 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
690 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
691 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitField
);
692 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
693 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkUsage
);
694 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkUsagePage
);
695 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
696 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
697 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
698 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
700 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", HasNull
);
701 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitSize
);
702 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportCount
);
703 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", UnitsExp
);
704 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Units
);
705 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LogicalMin
);
706 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LogicalMax
);
707 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", PhysicalMin
);
708 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", PhysicalMax
);
710 if (!caps
->IsRange
&& !exp
->IsRange
)
712 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
713 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
715 else if (caps
->IsRange
&& exp
->IsRange
)
717 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
718 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
719 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
720 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
723 if (!caps
->IsRange
&& !exp
->IsRange
)
724 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
725 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
727 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
728 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
731 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
732 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
733 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
735 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
736 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
740 static BOOL
sync_ioctl( HANDLE file
, DWORD code
, void *in_buf
, DWORD in_len
, void *out_buf
, DWORD
*ret_len
)
742 OVERLAPPED ovl
= {0};
743 DWORD out_len
= ret_len
? *ret_len
: 0;
746 ovl
.hEvent
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
747 ret
= DeviceIoControl( file
, code
, in_buf
, in_len
, out_buf
, out_len
, &out_len
, &ovl
);
748 if (!ret
&& GetLastError() == ERROR_IO_PENDING
)
749 ret
= GetOverlappedResult( file
, &ovl
, &out_len
, TRUE
);
750 CloseHandle( ovl
.hEvent
);
752 if (ret_len
) *ret_len
= out_len
;
756 #define set_hid_expect( a, b, c ) set_hid_expect_( __LINE__, a, b, c )
757 static void set_hid_expect_( int line
, HANDLE file
, struct hid_expect
*expect
, DWORD expect_size
)
759 const char *source_file
;
763 source_file
= strrchr( __FILE__
, '/' );
764 if (!source_file
) source_file
= strrchr( __FILE__
, '\\' );
765 if (!source_file
) source_file
= __FILE__
;
768 for (i
= 0; i
< expect_size
/ sizeof(struct hid_expect
); ++i
)
769 snprintf( expect
[i
].context
, ARRAY_SIZE(expect
[i
].context
), "%s:%d", source_file
, line
);
771 ret
= sync_ioctl( file
, IOCTL_WINETEST_HID_SET_EXPECT
, expect
, expect_size
, NULL
, 0 );
772 ok( ret
, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u\n", GetLastError() );
775 #define send_hid_input( a, b, c ) send_hid_input_( __LINE__, a, b, c )
776 static void send_hid_input_( int line
, HANDLE file
, struct hid_expect
*expect
, DWORD expect_size
)
778 const char *source_file
;
782 source_file
= strrchr( __FILE__
, '/' );
783 if (!source_file
) source_file
= strrchr( __FILE__
, '\\' );
784 if (!source_file
) source_file
= __FILE__
;
787 for (i
= 0; i
< expect_size
/ sizeof(struct hid_expect
); ++i
)
788 snprintf( expect
[i
].context
, ARRAY_SIZE(expect
[i
].context
), "%s:%d", source_file
, line
);
790 ret
= sync_ioctl( file
, IOCTL_WINETEST_HID_SEND_INPUT
, expect
, expect_size
, NULL
, 0 );
791 ok( ret
, "IOCTL_WINETEST_HID_SEND_INPUT failed, last error %u\n", GetLastError() );
794 static void test_hidp_get_input( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
796 struct hid_expect expect
[] =
799 .code
= IOCTL_HID_GET_INPUT_REPORT
,
800 .report_id
= report_id
,
801 .report_len
= report_len
- (report_id
? 0 : 1),
802 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,2},
804 .ret_status
= STATUS_SUCCESS
,
807 .code
= IOCTL_HID_GET_INPUT_REPORT
,
808 .report_id
= report_id
,
809 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
810 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,1},
812 .ret_status
= STATUS_SUCCESS
,
816 char buffer
[200], report
[200];
821 memset( report
, 0xcd, sizeof(report
) );
822 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed
, report
, report_len
);
823 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
825 SetLastError( 0xdeadbeef );
826 ret
= HidD_GetInputReport( file
, report
, 0 );
827 ok( !ret
, "HidD_GetInputReport succeeded\n" );
828 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetInputReport returned error %u\n", GetLastError() );
830 SetLastError( 0xdeadbeef );
831 ret
= HidD_GetInputReport( file
, report
, report_len
- 1 );
832 ok( !ret
, "HidD_GetInputReport succeeded\n" );
833 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
834 "HidD_GetInputReport returned error %u\n", GetLastError() );
838 struct hid_expect broken_expect
=
840 .code
= IOCTL_HID_GET_INPUT_REPORT
,
842 .report_len
= report_len
- 1,
845 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
846 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
847 0x5a,0x5a,0x5a,0x5a,0x5a,
850 .ret_status
= STATUS_SUCCESS
,
853 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
856 SetLastError( 0xdeadbeef );
857 memset( buffer
, 0x5a, sizeof(buffer
) );
858 ret
= HidD_GetInputReport( file
, buffer
, report_len
);
859 if (report_id
|| broken( !ret
) /* w7u */)
861 ok( !ret
, "HidD_GetInputReport succeeded, last error %u\n", GetLastError() );
862 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
863 "HidD_GetInputReport returned error %u\n", GetLastError() );
867 ok( ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError() );
868 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
871 set_hid_expect( file
, expect
, sizeof(expect
) );
873 SetLastError( 0xdeadbeef );
874 ret
= HidD_GetInputReport( file
, report
, report_len
);
875 ok( ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError() );
876 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
878 SetLastError( 0xdeadbeef );
879 length
= report_len
* 2;
880 ret
= sync_ioctl( file
, IOCTL_HID_GET_INPUT_REPORT
, NULL
, 0, report
, &length
);
881 ok( ret
, "IOCTL_HID_GET_INPUT_REPORT failed, last error %u\n", GetLastError() );
882 ok( length
== 3, "got length %u, expected 3\n", length
);
883 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
885 set_hid_expect( file
, NULL
, 0 );
888 static void test_hidp_get_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
890 struct hid_expect expect
[] =
893 .code
= IOCTL_HID_GET_FEATURE
,
894 .report_id
= report_id
,
895 .report_len
= report_len
- (report_id
? 0 : 1),
896 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
898 .ret_status
= STATUS_SUCCESS
,
901 .code
= IOCTL_HID_GET_FEATURE
,
902 .report_id
= report_id
,
903 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
904 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
906 .ret_status
= STATUS_SUCCESS
,
910 char buffer
[200], report
[200];
915 memset( report
, 0xcd, sizeof(report
) );
916 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
917 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
919 SetLastError( 0xdeadbeef );
920 ret
= HidD_GetFeature( file
, report
, 0 );
921 ok( !ret
, "HidD_GetFeature succeeded\n" );
922 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetFeature returned error %u\n", GetLastError() );
924 SetLastError( 0xdeadbeef );
925 ret
= HidD_GetFeature( file
, report
, report_len
- 1 );
926 ok( !ret
, "HidD_GetFeature succeeded\n" );
927 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
928 "HidD_GetFeature returned error %u\n", GetLastError() );
932 struct hid_expect broken_expect
=
934 .code
= IOCTL_HID_GET_FEATURE
,
936 .report_len
= report_len
- 1,
939 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
940 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
941 0x5a,0x5a,0x5a,0x5a,0x5a,
944 .ret_status
= STATUS_SUCCESS
,
947 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
950 SetLastError( 0xdeadbeef );
951 memset( buffer
, 0x5a, sizeof(buffer
) );
952 ret
= HidD_GetFeature( file
, buffer
, report_len
);
953 if (report_id
|| broken( !ret
))
955 ok( !ret
, "HidD_GetFeature succeeded, last error %u\n", GetLastError() );
956 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
957 "HidD_GetFeature returned error %u\n", GetLastError() );
961 ok( ret
, "HidD_GetFeature failed, last error %u\n", GetLastError() );
962 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
965 set_hid_expect( file
, expect
, sizeof(expect
) );
967 SetLastError( 0xdeadbeef );
968 ret
= HidD_GetFeature( file
, report
, report_len
);
969 ok( ret
, "HidD_GetFeature failed, last error %u\n", GetLastError() );
970 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
972 length
= report_len
* 2;
973 SetLastError( 0xdeadbeef );
974 ret
= sync_ioctl( file
, IOCTL_HID_GET_FEATURE
, NULL
, 0, report
, &length
);
975 ok( ret
, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError() );
976 ok( length
== 3, "got length %u, expected 3\n", length
);
977 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
979 set_hid_expect( file
, NULL
, 0 );
982 static void test_hidp_set_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
984 struct hid_expect expect
[] =
987 .code
= IOCTL_HID_SET_FEATURE
,
988 .report_id
= report_id
,
989 .report_len
= report_len
- (report_id
? 0 : 1),
990 .report_buf
= {report_id
},
992 .ret_status
= STATUS_SUCCESS
,
995 .code
= IOCTL_HID_SET_FEATURE
,
996 .report_id
= report_id
,
997 .report_len
= report_len
- (report_id
? 0 : 1),
1000 report_id
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1001 0,0,0,0,0,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
1002 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
1005 .ret_status
= STATUS_SUCCESS
,
1008 char buffer
[200], report
[200];
1013 memset( report
, 0xcd, sizeof(report
) );
1014 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
1015 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1017 SetLastError( 0xdeadbeef );
1018 ret
= HidD_SetFeature( file
, report
, 0 );
1019 ok( !ret
, "HidD_SetFeature succeeded\n" );
1020 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetFeature returned error %u\n", GetLastError() );
1022 SetLastError( 0xdeadbeef );
1023 ret
= HidD_SetFeature( file
, report
, report_len
- 1 );
1024 ok( !ret
, "HidD_SetFeature succeeded\n" );
1025 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1026 "HidD_SetFeature returned error %u\n", GetLastError() );
1030 struct hid_expect broken_expect
=
1032 .code
= IOCTL_HID_SET_FEATURE
,
1034 .report_len
= report_len
- 1,
1037 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1038 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1039 0x5a,0x5a,0x5a,0x5a,0x5a,
1042 .ret_status
= STATUS_SUCCESS
,
1045 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1048 SetLastError( 0xdeadbeef );
1049 memset( buffer
, 0x5a, sizeof(buffer
) );
1050 ret
= HidD_SetFeature( file
, buffer
, report_len
);
1051 if (report_id
|| broken( !ret
))
1053 ok( !ret
, "HidD_SetFeature succeeded, last error %u\n", GetLastError() );
1054 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1055 "HidD_SetFeature returned error %u\n", GetLastError() );
1059 ok( ret
, "HidD_SetFeature failed, last error %u\n", GetLastError() );
1062 set_hid_expect( file
, expect
, sizeof(expect
) );
1064 SetLastError( 0xdeadbeef );
1065 ret
= HidD_SetFeature( file
, report
, report_len
);
1066 ok( ret
, "HidD_SetFeature failed, last error %u\n", GetLastError() );
1068 length
= report_len
* 2;
1069 SetLastError( 0xdeadbeef );
1070 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, NULL
, 0, report
, &length
);
1071 ok( !ret
, "IOCTL_HID_SET_FEATURE succeeded\n" );
1072 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_FEATURE returned error %u\n",
1075 SetLastError( 0xdeadbeef );
1076 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, report
, report_len
* 2, NULL
, &length
);
1077 ok( ret
, "IOCTL_HID_SET_FEATURE failed, last error %u\n", GetLastError() );
1078 ok( length
== 3, "got length %u, expected 3\n", length
);
1080 set_hid_expect( file
, NULL
, 0 );
1083 static void test_hidp_set_output( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1085 struct hid_expect expect
[] =
1088 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1089 .report_id
= report_id
,
1090 .report_len
= report_len
- (report_id
? 0 : 1),
1091 .report_buf
= {report_id
},
1093 .ret_status
= STATUS_SUCCESS
,
1096 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1097 .report_id
= report_id
,
1098 .report_len
= report_len
- (report_id
? 0 : 1),
1099 .report_buf
= {report_id
,0,0xcd,0xcd,0xcd},
1101 .ret_status
= STATUS_SUCCESS
,
1105 char buffer
[200], report
[200];
1110 memset( report
, 0xcd, sizeof(report
) );
1111 status
= HidP_InitializeReportForID( HidP_Output
, report_id
, preparsed
, report
, report_len
);
1112 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1113 memset( report
, 0, report_len
);
1114 report
[0] = report_id
;
1116 SetLastError( 0xdeadbeef );
1117 ret
= HidD_SetOutputReport( file
, report
, 0 );
1118 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1119 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetOutputReport returned error %u\n",
1122 SetLastError( 0xdeadbeef );
1123 ret
= HidD_SetOutputReport( file
, report
, report_len
- 1 );
1124 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1125 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1126 "HidD_SetOutputReport returned error %u\n", GetLastError() );
1130 struct hid_expect broken_expect
=
1132 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1134 .report_len
= report_len
- 1,
1135 .report_buf
= {0x5a,0x5a},
1137 .ret_status
= STATUS_SUCCESS
,
1140 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1143 SetLastError( 0xdeadbeef );
1144 memset( buffer
, 0x5a, sizeof(buffer
) );
1145 ret
= HidD_SetOutputReport( file
, buffer
, report_len
);
1146 if (report_id
|| broken( !ret
))
1148 ok( !ret
, "HidD_SetOutputReport succeeded, last error %u\n", GetLastError() );
1149 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1150 "HidD_SetOutputReport returned error %u\n", GetLastError() );
1154 ok( ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError() );
1157 set_hid_expect( file
, expect
, sizeof(expect
) );
1159 SetLastError( 0xdeadbeef );
1160 ret
= HidD_SetOutputReport( file
, report
, report_len
);
1161 ok( ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError() );
1163 length
= report_len
* 2;
1164 SetLastError( 0xdeadbeef );
1165 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, NULL
, 0, report
, &length
);
1166 ok( !ret
, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n" );
1167 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
,
1168 "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError() );
1170 SetLastError( 0xdeadbeef );
1171 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, report
, report_len
* 2, NULL
, &length
);
1172 ok( ret
, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError() );
1173 ok( length
== 3, "got length %u, expected 3\n", length
);
1175 set_hid_expect( file
, NULL
, 0 );
1178 static void test_write_file( HANDLE file
, int report_id
, ULONG report_len
)
1180 struct hid_expect expect
=
1182 .code
= IOCTL_HID_WRITE_REPORT
,
1183 .report_id
= report_id
,
1184 .report_len
= report_len
- (report_id
? 0 : 1),
1185 .report_buf
= {report_id
? report_id
: 0xcd,0xcd,0xcd,0xcd,0xcd},
1187 .ret_status
= STATUS_SUCCESS
,
1194 SetLastError( 0xdeadbeef );
1195 ret
= WriteFile( file
, report
, 0, &length
, NULL
);
1196 ok( !ret
, "WriteFile succeeded\n" );
1197 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "WriteFile returned error %u\n", GetLastError() );
1198 ok( length
== 0, "WriteFile returned %x\n", length
);
1199 SetLastError( 0xdeadbeef );
1200 ret
= WriteFile( file
, report
, report_len
- 1, &length
, NULL
);
1201 ok( !ret
, "WriteFile succeeded\n" );
1202 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_USER_BUFFER
,
1203 "WriteFile returned error %u\n", GetLastError() );
1204 ok( length
== 0, "WriteFile returned %x\n", length
);
1206 set_hid_expect( file
, &expect
, sizeof(expect
) );
1208 memset( report
, 0xcd, sizeof(report
) );
1210 SetLastError( 0xdeadbeef );
1211 ret
= WriteFile( file
, report
, report_len
* 2, &length
, NULL
);
1212 if (report_id
|| broken( !ret
) /* w7u */)
1214 ok( !ret
, "WriteFile succeeded\n" );
1215 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "WriteFile returned error %u\n", GetLastError() );
1216 ok( length
== 0, "WriteFile wrote %u\n", length
);
1217 SetLastError( 0xdeadbeef );
1218 report
[0] = report_id
;
1219 ret
= WriteFile( file
, report
, report_len
, &length
, NULL
);
1224 ok( ret
, "WriteFile failed, last error %u\n", GetLastError() );
1225 ok( length
== 2, "WriteFile wrote %u\n", length
);
1229 ok( ret
, "WriteFile failed, last error %u\n", GetLastError() );
1230 ok( length
== 3, "WriteFile wrote %u\n", length
);
1233 set_hid_expect( file
, NULL
, 0 );
1236 static void test_hidp( HANDLE file
, HANDLE async_file
, int report_id
, BOOL polled
, const HIDP_CAPS
*expect_caps
)
1238 const HIDP_BUTTON_CAPS expect_button_caps
[] =
1241 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1242 .ReportID
= report_id
,
1244 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1245 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1246 .LinkCollection
= 1,
1249 .Range
.UsageMin
= 1,
1250 .Range
.UsageMax
= 8,
1251 .Range
.DataIndexMin
= 2,
1252 .Range
.DataIndexMax
= 9,
1255 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1256 .ReportID
= report_id
,
1258 .LinkCollection
= 1,
1259 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1260 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1263 .Range
.UsageMin
= 0x18,
1264 .Range
.UsageMax
= 0x1f,
1265 .Range
.DataIndexMin
= 10,
1266 .Range
.DataIndexMax
= 17,
1269 .UsagePage
= HID_USAGE_PAGE_KEYBOARD
,
1270 .ReportID
= report_id
,
1272 .LinkCollection
= 1,
1273 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1274 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1276 .IsAbsolute
= FALSE
,
1277 .Range
.UsageMin
= 0x8,
1278 .Range
.UsageMax
= 0xf,
1279 .Range
.DataIndexMin
= 18,
1280 .Range
.DataIndexMax
= 25,
1283 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1284 .ReportID
= report_id
,
1286 .LinkCollection
= 1,
1287 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1288 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1291 .NotRange
.Usage
= 0x20,
1292 .NotRange
.Reserved1
= 0x20,
1293 .NotRange
.DataIndex
= 26,
1294 .NotRange
.Reserved4
= 26,
1297 const HIDP_VALUE_CAPS expect_value_caps
[] =
1300 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1301 .ReportID
= report_id
,
1303 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1304 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1305 .LinkCollection
= 1,
1311 .NotRange
.Usage
= HID_USAGE_GENERIC_Y
,
1312 .NotRange
.Reserved1
= HID_USAGE_GENERIC_Y
,
1315 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1316 .ReportID
= report_id
,
1318 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1319 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1320 .LinkCollection
= 1,
1326 .NotRange
.Usage
= HID_USAGE_GENERIC_X
,
1327 .NotRange
.Reserved1
= HID_USAGE_GENERIC_X
,
1328 .NotRange
.DataIndex
= 1,
1329 .NotRange
.Reserved4
= 1,
1332 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1333 .ReportID
= report_id
,
1335 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1336 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1337 .LinkCollection
= 1,
1342 .Range
.UsageMin
= 0x21,
1343 .Range
.UsageMax
= 0x22,
1344 .Range
.DataIndexMin
= 27,
1345 .Range
.DataIndexMax
= 28,
1348 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1349 .ReportID
= report_id
,
1351 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1352 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1353 .LinkCollection
= 1,
1359 .NotRange
.Usage
= HID_USAGE_GENERIC_HATSWITCH
,
1360 .NotRange
.Reserved1
= HID_USAGE_GENERIC_HATSWITCH
,
1361 .NotRange
.DataIndex
= 29,
1362 .NotRange
.Reserved4
= 29,
1365 static const HIDP_LINK_COLLECTION_NODE expect_collections
[] =
1368 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1369 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1370 .CollectionType
= 1,
1371 .NumberOfChildren
= 7,
1375 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1376 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1377 .CollectionType
= 2,
1380 static const HIDP_DATA expect_data
[] =
1382 { .DataIndex
= 0, },
1383 { .DataIndex
= 1, },
1384 { .DataIndex
= 5, .RawValue
= 1, },
1385 { .DataIndex
= 7, .RawValue
= 1, },
1386 { .DataIndex
= 19, .RawValue
= 1, },
1387 { .DataIndex
= 21, .RawValue
= 1, },
1388 { .DataIndex
= 30, },
1389 { .DataIndex
= 31, },
1390 { .DataIndex
= 32, .RawValue
= 0xfeedcafe, },
1391 { .DataIndex
= 37, .RawValue
= 1, },
1392 { .DataIndex
= 39, .RawValue
= 1, },
1395 OVERLAPPED overlapped
= {0}, overlapped2
= {0};
1396 HIDP_LINK_COLLECTION_NODE collections
[16];
1397 PHIDP_PREPARSED_DATA preparsed_data
;
1398 USAGE_AND_PAGE usage_and_pages
[16];
1399 HIDP_BUTTON_CAPS button_caps
[32];
1400 HIDP_VALUE_CAPS value_caps
[16];
1401 char buffer
[200], report
[200];
1402 DWORD collection_count
;
1403 DWORD waveform_list
;
1413 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
1414 ok( ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
1416 memset( buffer
, 0, sizeof(buffer
) );
1417 status
= HidP_GetCaps( (PHIDP_PREPARSED_DATA
)buffer
, &caps
);
1418 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetCaps returned %#x\n", status
);
1419 status
= HidP_GetCaps( preparsed_data
, &caps
);
1420 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetCaps returned %#x\n", status
);
1421 check_hidp_caps( &caps
, expect_caps
);
1423 collection_count
= 0;
1424 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1425 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1426 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1427 "got %d collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1428 collection_count
= ARRAY_SIZE(collections
);
1429 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, (PHIDP_PREPARSED_DATA
)buffer
);
1430 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1431 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1432 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1433 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1434 "got %d collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1436 for (i
= 0; i
< ARRAY_SIZE(expect_collections
); ++i
)
1438 winetest_push_context( "collections[%d]", i
);
1439 check_hidp_link_collection_node( &collections
[i
], &expect_collections
[i
] );
1440 winetest_pop_context();
1443 count
= ARRAY_SIZE(button_caps
);
1444 status
= HidP_GetButtonCaps( HidP_Output
, button_caps
, &count
, preparsed_data
);
1445 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetButtonCaps returned %#x\n", status
);
1446 status
= HidP_GetButtonCaps( HidP_Feature
+ 1, button_caps
, &count
, preparsed_data
);
1447 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetButtonCaps returned %#x\n", status
);
1449 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1450 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetButtonCaps returned %#x\n", status
);
1451 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1452 count
, caps
.NumberInputButtonCaps
);
1453 count
= ARRAY_SIZE(button_caps
);
1454 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1455 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetButtonCaps returned %#x\n", status
);
1456 memset( button_caps
, 0, sizeof(button_caps
) );
1457 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1458 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetButtonCaps returned %#x\n", status
);
1459 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1460 count
, caps
.NumberInputButtonCaps
);
1462 for (i
= 0; i
< ARRAY_SIZE(expect_button_caps
); ++i
)
1464 winetest_push_context( "button_caps[%d]", i
);
1465 check_hidp_button_caps( &button_caps
[i
], &expect_button_caps
[i
] );
1466 winetest_pop_context();
1469 count
= ARRAY_SIZE(button_caps
) - 1;
1470 status
= HidP_GetSpecificButtonCaps( HidP_Output
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1471 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1472 status
= HidP_GetSpecificButtonCaps( HidP_Feature
+ 1, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1473 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1475 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1476 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1477 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1478 count
, caps
.NumberInputButtonCaps
);
1479 count
= ARRAY_SIZE(button_caps
) - 1;
1480 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1481 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1483 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
+ 1, &count
, preparsed_data
);
1484 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1485 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1486 count
, caps
.NumberInputButtonCaps
);
1487 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1489 status
= HidP_GetSpecificButtonCaps( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, 5, button_caps
+ 1,
1490 &count
, preparsed_data
);
1491 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1492 ok( count
== 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 1 );
1493 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1496 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0xfffe, 0, 0, button_caps
, &count
, preparsed_data
);
1497 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1498 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1500 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0xfffe, 0, button_caps
, &count
, preparsed_data
);
1501 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1502 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1504 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0xfffe, button_caps
, &count
, preparsed_data
);
1505 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1506 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1508 count
= ARRAY_SIZE(value_caps
);
1509 status
= HidP_GetValueCaps( HidP_Output
, value_caps
, &count
, preparsed_data
);
1510 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetValueCaps returned %#x\n", status
);
1511 status
= HidP_GetValueCaps( HidP_Feature
+ 1, value_caps
, &count
, preparsed_data
);
1512 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetValueCaps returned %#x\n", status
);
1514 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1515 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetValueCaps returned %#x\n", status
);
1516 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1517 count
, caps
.NumberInputValueCaps
);
1518 count
= ARRAY_SIZE(value_caps
);
1519 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1520 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetValueCaps returned %#x\n", status
);
1521 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1522 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetValueCaps returned %#x\n", status
);
1523 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1524 count
, caps
.NumberInputValueCaps
);
1526 for (i
= 0; i
< ARRAY_SIZE(expect_value_caps
); ++i
)
1528 winetest_push_context( "value_caps[%d]", i
);
1529 check_hidp_value_caps( &value_caps
[i
], &expect_value_caps
[i
] );
1530 winetest_pop_context();
1533 count
= ARRAY_SIZE(value_caps
) - 4;
1534 status
= HidP_GetSpecificValueCaps( HidP_Output
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1535 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1536 status
= HidP_GetSpecificValueCaps( HidP_Feature
+ 1, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1537 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1539 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1540 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1541 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1542 count
, caps
.NumberInputValueCaps
);
1543 count
= ARRAY_SIZE(value_caps
) - 4;
1544 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1545 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1547 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, preparsed_data
);
1548 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1549 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1550 count
, caps
.NumberInputValueCaps
);
1551 check_hidp_value_caps( &value_caps
[4], &value_caps
[0] );
1552 check_hidp_value_caps( &value_caps
[5], &value_caps
[1] );
1553 check_hidp_value_caps( &value_caps
[6], &value_caps
[2] );
1554 check_hidp_value_caps( &value_caps
[7], &value_caps
[3] );
1557 status
= HidP_GetSpecificValueCaps( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1558 value_caps
+ 4, &count
, preparsed_data
);
1559 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1560 ok( count
== 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 1 );
1561 check_hidp_value_caps( &value_caps
[4], &value_caps
[3] );
1564 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0xfffe, 0, 0, value_caps
, &count
, preparsed_data
);
1565 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1566 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1568 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0xfffe, 0, value_caps
, &count
, preparsed_data
);
1569 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1570 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1572 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0xfffe, value_caps
, &count
, preparsed_data
);
1573 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1574 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1576 status
= HidP_InitializeReportForID( HidP_Input
, 0, (PHIDP_PREPARSED_DATA
)buffer
, report
, sizeof(report
) );
1577 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_InitializeReportForID returned %#x\n", status
);
1578 status
= HidP_InitializeReportForID( HidP_Feature
+ 1, 0, preparsed_data
, report
, sizeof(report
) );
1579 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_InitializeReportForID returned %#x\n", status
);
1580 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, sizeof(report
) );
1581 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
1582 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, caps
.InputReportByteLength
+ 1 );
1583 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
1584 status
= HidP_InitializeReportForID( HidP_Input
, 1 - report_id
, preparsed_data
, report
,
1585 caps
.InputReportByteLength
);
1586 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1588 memset( report
, 0xcd, sizeof(report
) );
1589 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
1590 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1592 memset( buffer
, 0xcd, sizeof(buffer
) );
1593 memset( buffer
, 0, caps
.InputReportByteLength
);
1594 buffer
[0] = report_id
;
1595 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1597 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1598 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1599 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValueArray returned %#x\n", status
);
1600 memset( buffer
, 0xcd, sizeof(buffer
) );
1601 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1602 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1603 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
1604 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1605 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1607 ok( status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_SetUsageValueArray returned %#x\n", status
);
1609 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1610 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1611 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_GetUsageValueArray returned %#x\n", status
);
1612 memset( buffer
, 0xcd, sizeof(buffer
) );
1613 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1614 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1615 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
1616 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1617 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1619 ok( status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_GetUsageValueArray returned %#x\n", status
);
1622 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1623 preparsed_data
, report
, caps
.InputReportByteLength
);
1624 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1626 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, &value
,
1627 preparsed_data
, report
, caps
.InputReportByteLength
);
1628 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
1629 ok( value
== 0x80, "got value %x, expected %#x\n", value
, 0x80 );
1631 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1632 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1633 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1634 ok( value
== -128, "got value %x, expected %#x\n", value
, -128 );
1637 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1638 preparsed_data
, report
, caps
.InputReportByteLength
);
1639 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1641 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1642 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1643 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1644 ok( value
== 127, "got value %x, expected %#x\n", value
, 127 );
1647 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1648 preparsed_data
, report
, caps
.InputReportByteLength
);
1649 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1651 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1652 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1653 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1654 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1657 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1658 preparsed_data
, report
, caps
.InputReportByteLength
);
1659 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1661 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1662 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1663 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1664 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1666 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, &value
,
1667 preparsed_data
, report
, caps
.InputReportByteLength
);
1668 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
1669 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
1672 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1673 preparsed_data
, report
, caps
.InputReportByteLength
);
1674 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1676 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1677 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1678 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1679 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
1682 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1683 preparsed_data
, report
, caps
.InputReportByteLength
);
1684 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1686 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1687 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1688 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1689 ok( value
== 0x80000000, "got value %x, expected %#x\n", value
, 0x80000000 );
1692 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
, value
,
1693 preparsed_data
, report
, caps
.InputReportByteLength
);
1694 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1696 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
1697 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1698 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1699 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1702 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
, value
,
1703 preparsed_data
, report
, caps
.InputReportByteLength
);
1704 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1706 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1707 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1708 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1709 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1710 status
= HidP_SetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1711 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1712 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1713 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1715 value
= HidP_MaxUsageListLength( HidP_Feature
+ 1, 0, preparsed_data
);
1716 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value
, 0 );
1717 value
= HidP_MaxUsageListLength( HidP_Input
, 0, preparsed_data
);
1718 ok( value
== 50, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value
, 50 );
1719 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1720 ok( value
== 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n",
1722 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_LED
, preparsed_data
);
1723 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n",
1725 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1726 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n",
1728 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_LED
, preparsed_data
);
1729 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n",
1734 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1735 report
, caps
.InputReportByteLength
);
1736 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
1740 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1741 report
, caps
.InputReportByteLength
);
1742 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
1746 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1747 report
, caps
.InputReportByteLength
);
1748 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1752 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
1753 report
, caps
.InputReportByteLength
);
1754 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1756 value
= ARRAY_SIZE(usages
);
1757 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1758 report
, caps
.InputReportByteLength
);
1759 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1760 ok( value
== 0, "got usage count %d, expected %d\n", value
, 2 );
1766 ok( report
[6] == 0, "got report[6] %x expected 0\n", report
[6] );
1767 ok( report
[7] == 0, "got report[7] %x expected 0\n", report
[7] );
1768 memcpy( buffer
, report
, caps
.InputReportByteLength
);
1769 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1770 report
, caps
.InputReportByteLength
);
1771 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsages returned %#x\n", status
);
1774 ok( !memcmp( buffer
, report
, caps
.InputReportByteLength
), "unexpected report data\n" );
1776 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, 1, preparsed_data
, report
,
1777 caps
.InputReportByteLength
);
1778 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1781 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, &value
, preparsed_data
,
1782 report
, caps
.InputReportByteLength
);
1783 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1784 ok( value
== 0xdeadbeef, "got value %x, expected %#x\n", value
, 0xdeadbeef );
1787 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1788 report
, caps
.InputReportByteLength
);
1789 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsages returned %#x\n", status
);
1790 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1791 value
= ARRAY_SIZE(usages
);
1792 memset( usages
, 0xcd, sizeof(usages
) );
1793 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1794 report
, caps
.InputReportByteLength
);
1795 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1796 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1797 ok( usages
[0] == 4, "got usages[0] %x, expected %x\n", usages
[0], 4 );
1798 ok( usages
[1] == 6, "got usages[1] %x, expected %x\n", usages
[1], 6 );
1800 value
= ARRAY_SIZE(usages
);
1801 memset( usages
, 0xcd, sizeof(usages
) );
1802 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
1803 report
, caps
.InputReportByteLength
);
1804 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1805 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1806 ok( usages
[0] == 6, "got usages[0] %x, expected %x\n", usages
[0], 6 );
1807 ok( usages
[1] == 4, "got usages[1] %x, expected %x\n", usages
[1], 4 );
1809 value
= ARRAY_SIZE(usage_and_pages
);
1810 memset( usage_and_pages
, 0xcd, sizeof(usage_and_pages
) );
1811 status
= HidP_GetUsagesEx( HidP_Input
, 0, usage_and_pages
, &value
, preparsed_data
, report
,
1812 caps
.InputReportByteLength
);
1813 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsagesEx returned %#x\n", status
);
1814 ok( value
== 6, "got usage count %d, expected %d\n", value
, 4 );
1815 ok( usage_and_pages
[0].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[0] UsagePage %x, expected %x\n",
1816 usage_and_pages
[0].UsagePage
, HID_USAGE_PAGE_BUTTON
);
1817 ok( usage_and_pages
[1].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[1] UsagePage %x, expected %x\n",
1818 usage_and_pages
[1].UsagePage
, HID_USAGE_PAGE_BUTTON
);
1819 ok( usage_and_pages
[2].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[2] UsagePage %x, expected %x\n",
1820 usage_and_pages
[2].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
1821 ok( usage_and_pages
[3].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[3] UsagePage %x, expected %x\n",
1822 usage_and_pages
[3].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
1823 ok( usage_and_pages
[4].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[4] UsagePage %x, expected %x\n",
1824 usage_and_pages
[4].UsagePage
, HID_USAGE_PAGE_LED
);
1825 ok( usage_and_pages
[5].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[5] UsagePage %x, expected %x\n",
1826 usage_and_pages
[5].UsagePage
, HID_USAGE_PAGE_LED
);
1827 ok( usage_and_pages
[0].Usage
== 4, "got usage_and_pages[0] Usage %x, expected %x\n",
1828 usage_and_pages
[0].Usage
, 4 );
1829 ok( usage_and_pages
[1].Usage
== 6, "got usage_and_pages[1] Usage %x, expected %x\n",
1830 usage_and_pages
[1].Usage
, 6 );
1831 ok( usage_and_pages
[2].Usage
== 9, "got usage_and_pages[2] Usage %x, expected %x\n",
1832 usage_and_pages
[2].Usage
, 9 );
1833 ok( usage_and_pages
[3].Usage
== 11, "got usage_and_pages[3] Usage %x, expected %x\n",
1834 usage_and_pages
[3].Usage
, 11 );
1835 ok( usage_and_pages
[4].Usage
== 6, "got usage_and_pages[4] Usage %x, expected %x\n",
1836 usage_and_pages
[4].Usage
, 6 );
1837 ok( usage_and_pages
[5].Usage
== 4, "got usage_and_pages[5] Usage %x, expected %x\n",
1838 usage_and_pages
[5].Usage
, 4 );
1840 value
= HidP_MaxDataListLength( HidP_Feature
+ 1, preparsed_data
);
1841 ok( value
== 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value
, 0 );
1842 value
= HidP_MaxDataListLength( HidP_Input
, preparsed_data
);
1843 ok( value
== 58, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value
, 58 );
1844 value
= HidP_MaxDataListLength( HidP_Output
, preparsed_data
);
1845 ok( value
== 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value
, 0 );
1846 value
= HidP_MaxDataListLength( HidP_Feature
, preparsed_data
);
1847 ok( value
== 14, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value
, 14 );
1850 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1851 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetData returned %#x\n", status
);
1852 ok( value
== 11, "got data count %d, expected %d\n", value
, 11 );
1853 memset( data
, 0, sizeof(data
) );
1854 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1855 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetData returned %#x\n", status
);
1856 for (i
= 0; i
< ARRAY_SIZE(expect_data
); ++i
)
1858 winetest_push_context( "data[%d]", i
);
1859 check_member( data
[i
], expect_data
[i
], "%d", DataIndex
);
1860 check_member( data
[i
], expect_data
[i
], "%d", RawValue
);
1861 winetest_pop_context();
1864 /* HID nary usage collections are set with 1-based usage index in their declaration order */
1866 memset( report
, 0, caps
.InputReportByteLength
);
1867 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
1868 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1872 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1873 report
, caps
.InputReportByteLength
);
1874 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1875 ok( report
[caps
.InputReportByteLength
- 2] == 3, "unexpected usage index %d, expected 3\n",
1876 report
[caps
.InputReportByteLength
- 2] );
1877 ok( report
[caps
.InputReportByteLength
- 1] == 4, "unexpected usage index %d, expected 4\n",
1878 report
[caps
.InputReportByteLength
- 1] );
1879 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
1880 preparsed_data
, report
, caps
.InputReportByteLength
);
1881 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_UnsetUsages returned %#x\n", status
);
1882 ok( report
[caps
.InputReportByteLength
- 2] == 0, "unexpected usage index %d, expected 0\n",
1883 report
[caps
.InputReportByteLength
- 2] );
1884 ok( report
[caps
.InputReportByteLength
- 1] == 0, "unexpected usage index %d, expected 0\n",
1885 report
[caps
.InputReportByteLength
- 1] );
1886 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
1887 preparsed_data
, report
, caps
.InputReportByteLength
);
1888 ok( status
== HIDP_STATUS_BUTTON_NOT_PRESSED
, "HidP_UnsetUsages returned %#x\n", status
);
1891 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1892 report
, caps
.InputReportByteLength
);
1893 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1894 ok( report
[caps
.InputReportByteLength
- 2] == 1, "unexpected usage index %d, expected 1\n",
1895 report
[caps
.InputReportByteLength
- 2] );
1897 memset( report
, 0xcd, sizeof(report
) );
1898 status
= HidP_InitializeReportForID( HidP_Feature
, 3, preparsed_data
, report
, caps
.FeatureReportByteLength
);
1899 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1901 memset( report
, 0xcd, sizeof(report
) );
1902 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed_data
, report
,
1903 caps
.FeatureReportByteLength
);
1904 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1906 memset( buffer
, 0xcd, sizeof(buffer
) );
1907 memset( buffer
, 0, caps
.FeatureReportByteLength
);
1908 buffer
[0] = report_id
;
1909 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1911 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
1913 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_HAPTICS
) continue;
1914 if (collections
[i
].LinkUsage
== HID_USAGE_HAPTICS_WAVEFORM_LIST
) break;
1916 ok( i
< caps
.NumberLinkCollectionNodes
,
1917 "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n" );
1920 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1921 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, (PHIDP_PREPARSED_DATA
)buffer
,
1922 report
, caps
.FeatureReportByteLength
);
1923 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_SetUsageValue returned %#x\n", status
);
1924 status
= HidP_SetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1925 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1926 caps
.FeatureReportByteLength
);
1927 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_SetUsageValue returned %#x\n", status
);
1928 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1929 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1930 caps
.FeatureReportByteLength
+ 1 );
1931 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_SetUsageValue returned %#x\n", status
);
1932 report
[0] = 1 - report_id
;
1933 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1934 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1935 caps
.FeatureReportByteLength
);
1936 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
1937 "HidP_SetUsageValue returned %#x\n", status
);
1939 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1940 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1941 caps
.FeatureReportByteLength
);
1942 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_SetUsageValue returned %#x\n", status
);
1943 report
[0] = report_id
;
1944 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
,
1945 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1946 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1948 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1949 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1950 caps
.FeatureReportByteLength
);
1951 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1953 memset( buffer
, 0xcd, sizeof(buffer
) );
1954 memset( buffer
, 0, caps
.FeatureReportByteLength
);
1955 buffer
[0] = report_id
;
1956 value
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
1957 memcpy( buffer
+ 1, &value
, 2 );
1958 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1960 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1961 (PHIDP_PREPARSED_DATA
)buffer
, report
, caps
.FeatureReportByteLength
);
1962 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetUsageValue returned %#x\n", status
);
1963 status
= HidP_GetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1964 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1965 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetUsageValue returned %#x\n", status
);
1966 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1967 preparsed_data
, report
, caps
.FeatureReportByteLength
+ 1 );
1968 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_GetUsageValue returned %#x\n", status
);
1969 report
[0] = 1 - report_id
;
1970 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1971 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1972 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
1973 "HidP_GetUsageValue returned %#x\n", status
);
1975 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1976 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1977 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_GetUsageValue returned %#x\n", status
);
1978 report
[0] = report_id
;
1979 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, &value
,
1980 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1981 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#x\n", status
);
1984 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1985 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1986 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
1987 ok( value
== HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, "got value %x, expected %#x\n", value
,
1988 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
);
1990 memset( buffer
, 0xff, sizeof(buffer
) );
1991 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
1992 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
1993 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1994 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
1995 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
1996 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
1997 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1998 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#x\n", status
);
1999 ok( !memcmp( report
+ 9, buffer
, 8 ), "unexpected report data\n" );
2001 memset( buffer
, 0, sizeof(buffer
) );
2002 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2003 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
2004 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2005 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2006 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2007 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
2008 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2009 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#x\n", status
);
2010 memset( buffer
+ 16, 0xff, 8 );
2011 ok( !memcmp( buffer
, buffer
+ 16, 16 ), "unexpected report value\n" );
2014 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2015 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2016 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2018 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2019 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2020 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2021 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
2023 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2024 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2025 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2026 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
2029 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2030 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2031 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2033 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2034 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2035 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2036 ok( value
== 0x0003ffff, "got value %x, expected %#x\n", value
, 0x0003ffff );
2039 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2040 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2041 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2043 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2044 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2045 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2046 ok( value
== 0xfff90000, "got value %x, expected %#x\n", value
, 0xfff90000 );
2047 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2048 0x1000, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2049 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2051 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2052 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2053 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2054 ok( value
== 0xfffff518, "got value %x, expected %#x\n", value
, 0xfffff518 );
2055 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2056 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2057 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2059 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2060 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2061 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2062 ok( value
== 0xfffff45e, "got value %x, expected %#x\n", value
, 0xfffff45e );
2063 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2064 0xdead, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2065 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2067 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2068 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2069 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2070 ok( value
== 0xfffffe7d, "got value %x, expected %#x\n", value
, 0xfffffe7d );
2071 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2072 0xbeef, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2073 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2075 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2076 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2077 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2078 ok( value
== 0xfffffd0b, "got value %x, expected %#x\n", value
, 0xfffffd0b );
2080 test_hidp_get_input( file
, report_id
, caps
.InputReportByteLength
, preparsed_data
);
2081 test_hidp_get_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2082 test_hidp_set_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2083 test_hidp_set_output( file
, report_id
, caps
.OutputReportByteLength
, preparsed_data
);
2084 test_write_file( file
, report_id
, caps
.OutputReportByteLength
);
2086 memset( report
, 0xcd, sizeof(report
) );
2087 SetLastError( 0xdeadbeef );
2088 ret
= ReadFile( file
, report
, 0, &value
, NULL
);
2089 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n",
2091 ok( value
== 0, "ReadFile returned %x\n", value
);
2092 SetLastError( 0xdeadbeef );
2093 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
- 1, &value
, NULL
);
2094 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n",
2096 ok( value
== 0, "ReadFile returned %x\n", value
);
2100 struct hid_expect expect
[] =
2103 .code
= IOCTL_HID_READ_REPORT
,
2104 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2105 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0},
2107 .ret_status
= STATUS_SUCCESS
,
2110 .code
= IOCTL_HID_READ_REPORT
,
2111 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2112 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,1},
2114 .ret_status
= STATUS_SUCCESS
,
2118 send_hid_input( file
, expect
, sizeof(expect
) );
2120 memset( report
, 0xcd, sizeof(report
) );
2121 SetLastError( 0xdeadbeef );
2122 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
, &value
, NULL
);
2123 ok( ret
, "ReadFile failed, last error %u\n", GetLastError() );
2124 ok( value
== (report_id
? 3 : 4), "ReadFile returned %x\n", value
);
2125 ok( report
[0] == report_id
, "unexpected report data\n" );
2127 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2128 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2130 /* drain available input reports */
2131 SetLastError( 0xdeadbeef );
2132 while (ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
))
2133 ResetEvent( overlapped
.hEvent
);
2134 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2135 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2136 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2137 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2138 value
, (report_id
? 3 : 4) );
2139 ResetEvent( overlapped
.hEvent
);
2141 memcpy( buffer
, report
, caps
.InputReportByteLength
);
2142 memcpy( buffer
+ caps
.InputReportByteLength
, report
, caps
.InputReportByteLength
);
2144 SetLastError( 0xdeadbeef );
2145 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2146 ok( !ret
, "ReadFile succeeded\n" );
2147 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2149 SetLastError( 0xdeadbeef );
2150 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2151 ok( !ret
, "ReadFile succeeded\n" );
2152 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2154 /* wait for second report to be ready */
2155 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2156 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2157 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2158 value
, (report_id
? 3 : 4) );
2159 /* first report should be ready and the same */
2160 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2161 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2162 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2163 value
, (report_id
? 3 : 4) );
2164 ok( memcmp( report
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
),
2165 "expected different report\n" );
2166 ok( !memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected identical reports\n" );
2168 CloseHandle( overlapped
.hEvent
);
2169 CloseHandle( overlapped2
.hEvent
);
2173 struct hid_expect expect
[] =
2176 .code
= IOCTL_HID_READ_REPORT
,
2177 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2178 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
2180 .ret_status
= STATUS_SUCCESS
,
2183 .code
= IOCTL_HID_READ_REPORT
,
2184 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2185 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5,0xa5,0xa5},
2186 .ret_length
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2187 .ret_status
= STATUS_SUCCESS
,
2191 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2192 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2194 SetLastError( 0xdeadbeef );
2195 memset( report
, 0, sizeof(report
) );
2196 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2197 ok( !ret
, "ReadFile succeeded\n" );
2198 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2200 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2201 ok( !ret
, "GetOverlappedResult succeeded\n" );
2202 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2204 SetLastError( 0xdeadbeef );
2205 memset( buffer
, 0, sizeof(buffer
) );
2206 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2207 ok( !ret
, "ReadFile succeeded\n" );
2208 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2210 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2211 ok( !ret
, "GetOverlappedResult succeeded\n" );
2212 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2214 memset( report
+ caps
.InputReportByteLength
, 0xa5, 5 );
2215 if (report_id
) report
[caps
.InputReportByteLength
] = report_id
;
2217 send_hid_input( file
, expect
, sizeof(expect
) );
2219 /* first read should be completed */
2220 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2221 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2222 ok( value
== caps
.InputReportByteLength
, "got length %u, expected %u\n", value
, caps
.InputReportByteLength
);
2223 /* second read should still be pending */
2225 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2226 ok( !ret
, "GetOverlappedResult succeeded\n" );
2227 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2229 memset( buffer
+ caps
.InputReportByteLength
, 0x3b, 5 );
2230 if (report_id
) buffer
[caps
.InputReportByteLength
] = report_id
;
2231 memset( expect
[1].report_buf
, 0x3b, 5 );
2232 if (report_id
) expect
[1].report_buf
[0] = report_id
;
2234 send_hid_input( file
, expect
, sizeof(expect
) );
2236 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2237 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2238 ok( value
== caps
.InputReportByteLength
, "got length %u, expected %u\n", value
, caps
.InputReportByteLength
);
2240 off
= report_id
? 0 : 1;
2241 ok( memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected different report\n" );
2242 ok( !memcmp( report
+ off
, report
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2243 "expected identical reports\n" );
2244 ok( !memcmp( buffer
+ off
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2245 "expected identical reports\n" );
2247 CloseHandle( overlapped
.hEvent
);
2248 CloseHandle( overlapped2
.hEvent
);
2251 HidD_FreePreparsedData( preparsed_data
);
2254 static void test_hid_device( DWORD report_id
, DWORD polled
, const HIDP_CAPS
*expect_caps
)
2256 char buffer
[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W
, DevicePath
[MAX_PATH
] )];
2257 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(SP_DEVICE_INTERFACE_DATA
)};
2258 SP_DEVICE_INTERFACE_DETAIL_DATA_W
*iface_detail
= (void *)buffer
;
2259 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
2260 ULONG count
, poll_freq
, out_len
;
2261 HANDLE file
, async_file
;
2262 BOOL ret
, found
= FALSE
;
2263 OBJECT_ATTRIBUTES attr
;
2264 UNICODE_STRING string
;
2270 winetest_push_context( "id %d%s", report_id
, polled
? " poll" : "" );
2272 set
= SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
2273 ok( set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError() );
2275 for (i
= 0; SetupDiEnumDeviceInfo( set
, i
, &device
); ++i
)
2277 ret
= SetupDiEnumDeviceInterfaces( set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
2278 ok( ret
, "failed to get interface, error %#x\n", GetLastError() );
2279 ok( IsEqualGUID( &iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
), "wrong class %s\n",
2280 debugstr_guid( &iface
.InterfaceClassGuid
) );
2281 ok( iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
2283 iface_detail
->cbSize
= sizeof(*iface_detail
);
2284 ret
= SetupDiGetDeviceInterfaceDetailW( set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
2285 ok( ret
, "failed to get interface path, error %#x\n", GetLastError() );
2287 if (wcsstr( iface_detail
->DevicePath
, L
"\\\\?\\hid#winetest#1" ))
2294 SetupDiDestroyDeviceInfoList( set
);
2297 ok( found
, "didn't find device\n" );
2299 file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2300 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
2301 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
2304 SetLastError( 0xdeadbeef );
2305 ret
= HidD_GetNumInputBuffers( file
, &count
);
2306 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2307 ok( count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2309 SetLastError( 0xdeadbeef );
2310 ret
= HidD_SetNumInputBuffers( file
, 1 );
2311 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2312 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n",
2314 SetLastError( 0xdeadbeef );
2315 ret
= HidD_SetNumInputBuffers( file
, 513 );
2316 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2317 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n",
2320 SetLastError( 0xdeadbeef );
2321 ret
= HidD_SetNumInputBuffers( file
, 16 );
2322 ok( ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError() );
2325 SetLastError( 0xdeadbeef );
2326 ret
= HidD_GetNumInputBuffers( file
, &count
);
2327 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2328 ok( count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2330 async_file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2331 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
2332 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
2333 ok( async_file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
2336 SetLastError( 0xdeadbeef );
2337 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2338 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2339 ok( count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2341 SetLastError( 0xdeadbeef );
2342 ret
= HidD_SetNumInputBuffers( async_file
, 2 );
2343 ok( ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError() );
2346 SetLastError( 0xdeadbeef );
2347 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2348 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2349 ok( count
== 2, "HidD_GetNumInputBuffers returned %u\n", count
);
2351 SetLastError( 0xdeadbeef );
2352 ret
= HidD_GetNumInputBuffers( file
, &count
);
2353 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2354 ok( count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2358 out_len
= sizeof(ULONG
);
2359 SetLastError( 0xdeadbeef );
2360 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
);
2361 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2362 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2364 ok( poll_freq
== 5, "got poll_freq %u, expected 5\n", poll_freq
);
2368 SetLastError( 0xdeadbeef );
2369 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
);
2370 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2371 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2375 SetLastError( 0xdeadbeef );
2376 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
);
2377 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2378 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2382 SetLastError( 0xdeadbeef );
2383 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
);
2384 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2385 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2387 out_len
= sizeof(ULONG
);
2388 SetLastError( 0xdeadbeef );
2389 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
);
2390 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2391 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2392 ok( poll_freq
== 10000, "got poll_freq %u, expected 10000\n", poll_freq
);
2396 SetLastError( 0xdeadbeef );
2397 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
);
2398 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2399 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2401 out_len
= sizeof(ULONG
);
2402 SetLastError( 0xdeadbeef );
2403 ret
= sync_ioctl( async_file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
);
2404 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2405 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2406 ok( poll_freq
== 500, "got poll_freq %u, expected 500\n", poll_freq
);
2409 test_hidp( file
, async_file
, report_id
, polled
, expect_caps
);
2411 CloseHandle( async_file
);
2412 CloseHandle( file
);
2414 RtlInitUnicodeString( &string
, L
"\\??\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}" );
2415 InitializeObjectAttributes( &attr
, &string
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
2416 status
= NtOpenFile( &file
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
2418 ok( status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
2420 winetest_pop_context();
2423 static void test_hid_driver( DWORD report_id
, DWORD polled
)
2425 #include "psh_hid_macros.h"
2426 /* Replace REPORT_ID with USAGE_PAGE when id is 0 */
2427 #define REPORT_ID_OR_USAGE_PAGE(size, id, off) SHORT_ITEM_1((id ? 8 : 0), 1, (id + off))
2428 const unsigned char report_desc
[] =
2430 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2431 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2432 COLLECTION(1, Application
),
2433 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2434 COLLECTION(1, Logical
),
2435 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2436 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2437 USAGE(1, HID_USAGE_GENERIC_X
),
2438 USAGE(1, HID_USAGE_GENERIC_Y
),
2439 LOGICAL_MINIMUM(1, -128),
2440 LOGICAL_MAXIMUM(1, 127),
2443 INPUT(1, Data
|Var
|Abs
),
2445 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2446 USAGE_MINIMUM(1, 1),
2447 USAGE_MAXIMUM(1, 8),
2448 LOGICAL_MINIMUM(1, 0),
2449 LOGICAL_MAXIMUM(1, 1),
2452 INPUT(1, Data
|Var
|Abs
),
2454 USAGE_MINIMUM(1, 0x18),
2455 USAGE_MAXIMUM(1, 0x1f),
2456 LOGICAL_MINIMUM(1, 0),
2457 LOGICAL_MAXIMUM(1, 1),
2460 INPUT(1, Cnst
|Var
|Abs
),
2463 INPUT(1, Cnst
|Var
|Abs
),
2464 /* needs to be 8 bit aligned as next has Buff */
2466 USAGE_MINIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8),
2467 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0xf),
2468 LOGICAL_MINIMUM(1, 0),
2469 LOGICAL_MAXIMUM(1, 8),
2472 INPUT(2, Data
|Ary
|Rel
|Wrap
|Lin
|Pref
|Null
|Vol
|Buff
),
2474 /* needs to be 8 bit aligned as previous has Buff */
2476 LOGICAL_MINIMUM(1, 0),
2477 LOGICAL_MAXIMUM(1, 1),
2480 INPUT(1, Data
|Var
|Abs
),
2481 USAGE_MINIMUM(1, 0x21),
2482 USAGE_MAXIMUM(1, 0x22),
2485 INPUT(1, Data
|Var
|Abs
),
2489 INPUT(1, Data
|Var
|Abs
),
2491 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2492 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
2493 LOGICAL_MINIMUM(1, 1),
2494 LOGICAL_MAXIMUM(1, 8),
2497 INPUT(1, Data
|Var
|Abs
),
2499 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2500 USAGE(1, HID_USAGE_GENERIC_Z
),
2501 LOGICAL_MINIMUM(4, 0x00000000),
2502 LOGICAL_MAXIMUM(4, 0x3fffffff),
2503 PHYSICAL_MINIMUM(4, 0x80000000),
2504 PHYSICAL_MAXIMUM(4, 0x7fffffff),
2507 INPUT(1, Data
|Var
|Abs
),
2509 /* reset physical range to its default interpretation */
2510 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2511 USAGE(1, HID_USAGE_GENERIC_RX
),
2512 PHYSICAL_MINIMUM(4, 0),
2513 PHYSICAL_MAXIMUM(4, 0),
2516 INPUT(1, Data
|Var
|Abs
),
2518 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2519 USAGE(1, HID_USAGE_GENERIC_RY
),
2520 LOGICAL_MINIMUM(4, 0x7fff),
2521 LOGICAL_MAXIMUM(4, 0x0000),
2522 PHYSICAL_MINIMUM(4, 0x0000),
2523 PHYSICAL_MAXIMUM(4, 0x7fff),
2526 INPUT(1, Data
|Var
|Abs
),
2529 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2530 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2531 COLLECTION(1, Report
),
2532 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2533 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2534 USAGE_MINIMUM(1, 9),
2535 USAGE_MAXIMUM(1, 10),
2536 LOGICAL_MINIMUM(1, 0),
2537 LOGICAL_MAXIMUM(1, 1),
2540 INPUT(1, Data
|Var
|Abs
),
2543 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2544 USAGE(1, HID_USAGE_LED_GREEN
),
2545 COLLECTION(1, Report
),
2546 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2547 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2556 LOGICAL_MINIMUM(1, 0),
2557 LOGICAL_MAXIMUM(1, 1),
2558 PHYSICAL_MINIMUM(1, 0),
2559 PHYSICAL_MAXIMUM(1, 1),
2562 INPUT(1, Data
|Var
|Abs
),
2564 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8c),
2565 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8d),
2566 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8e),
2567 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8f),
2568 LOGICAL_MINIMUM(1, 1),
2569 LOGICAL_MAXIMUM(1, 16),
2572 INPUT(1, Data
|Ary
|Abs
),
2575 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2576 USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER
),
2577 COLLECTION(1, Logical
),
2578 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2579 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2581 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST
),
2582 COLLECTION(1, NamedArray
),
2583 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2584 USAGE(1, 3), /* HID_USAGE_HAPTICS_WAVEFORM_RUMBLE */
2585 USAGE(1, 4), /* HID_USAGE_HAPTICS_WAVEFORM_BUZZ */
2586 LOGICAL_MINIMUM(2, 0x0000),
2587 LOGICAL_MAXIMUM(2, 0xffff),
2590 FEATURE(1, Data
|Var
|Abs
|Null
),
2593 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2594 USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST
),
2595 COLLECTION(1, NamedArray
),
2596 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2597 USAGE(1, 3), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) */
2598 USAGE(1, 4), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_BUZZ) */
2599 LOGICAL_MINIMUM(2, 0x0000),
2600 LOGICAL_MAXIMUM(2, 0xffff),
2603 FEATURE(1, Data
|Var
|Abs
|Null
),
2606 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2607 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
),
2608 UNIT(2, 0x1001), /* seconds */
2609 UNIT_EXPONENT(1, -3), /* 10^-3 */
2610 LOGICAL_MINIMUM(2, 0x8000),
2611 LOGICAL_MAXIMUM(2, 0x7fff),
2612 PHYSICAL_MINIMUM(4, 0x00000000),
2613 PHYSICAL_MAXIMUM(4, 0xffffffff),
2616 FEATURE(1, Data
|Var
|Abs
),
2617 /* reset global items */
2618 UNIT(1, 0), /* None */
2619 UNIT_EXPONENT(1, 0),
2621 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2622 USAGE(1, HID_USAGE_GENERIC_Z
),
2623 LOGICAL_MINIMUM(4, 0x0000),
2624 LOGICAL_MAXIMUM(4, 0x7fff),
2625 PHYSICAL_MINIMUM(4, 0xfff90000),
2626 PHYSICAL_MAXIMUM(4, 0x0003ffff),
2629 FEATURE(1, Data
|Var
|Abs
),
2632 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2633 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2634 COLLECTION(1, Report
),
2635 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2636 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2637 USAGE_MINIMUM(1, 9),
2638 USAGE_MAXIMUM(1, 10),
2639 LOGICAL_MINIMUM(1, 0),
2640 LOGICAL_MAXIMUM(1, 1),
2641 PHYSICAL_MINIMUM(1, 0),
2642 PHYSICAL_MAXIMUM(1, 1),
2645 FEATURE(1, Data
|Var
|Abs
),
2648 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2649 USAGE(1, HID_USAGE_LED_GREEN
),
2650 COLLECTION(1, Report
),
2651 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2652 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2655 OUTPUT(1, Cnst
|Var
|Abs
),
2658 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2659 USAGE(1, HID_USAGE_LED_RED
),
2660 COLLECTION(1, Report
),
2661 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2662 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2665 OUTPUT(1, Cnst
|Var
|Abs
),
2669 #undef REPORT_ID_OR_USAGE_PAGE
2670 #include "pop_hid_macros.h"
2672 static const HID_DEVICE_ATTRIBUTES attributes
=
2674 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
2676 .ProductID
= 0x0001,
2677 .VersionNumber
= 0x0100,
2679 const HIDP_CAPS caps
=
2681 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
2682 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
2683 .InputReportByteLength
= report_id
? 25 : 26,
2684 .OutputReportByteLength
= report_id
? 2 : 3,
2685 .FeatureReportByteLength
= report_id
? 21 : 22,
2686 .NumberLinkCollectionNodes
= 10,
2687 .NumberInputButtonCaps
= 17,
2688 .NumberInputValueCaps
= 7,
2689 .NumberInputDataIndices
= 47,
2690 .NumberFeatureButtonCaps
= 1,
2691 .NumberFeatureValueCaps
= 6,
2692 .NumberFeatureDataIndices
= 8,
2694 const struct hid_expect expect_in
=
2696 .code
= IOCTL_HID_READ_REPORT
,
2697 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2698 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
2700 .ret_status
= STATUS_SUCCESS
,
2703 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
2707 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
2708 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
2709 SetCurrentDirectoryW( tempdir
);
2711 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
2712 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
2713 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
2715 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
2716 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2718 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
2719 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2721 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)report_desc
, sizeof(report_desc
) );
2722 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2724 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
2725 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2727 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)&caps
, sizeof(caps
) );
2728 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2730 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, NULL
, 0 );
2731 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2733 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, (void *)&expect_in
, polled
? sizeof(expect_in
) : 0 );
2734 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2736 if (pnp_driver_start( L
"driver_hid.dll" )) test_hid_device( report_id
, polled
, &caps
);
2739 SetCurrentDirectoryW( cwd
);
2742 /* undocumented HID internal preparsed data structure */
2744 struct hidp_kdr_caps
2750 USHORT report_count
;
2755 USHORT link_collection
;
2756 USAGE link_usage_page
;
2764 USHORT designator_min
;
2765 USHORT designator_max
;
2766 USHORT data_index_min
;
2767 USHORT data_index_max
;
2778 /* named array continues on next caps */
2779 #define HIDP_KDR_CAPS_ARRAY_HAS_MORE 0x01
2780 #define HIDP_KDR_CAPS_IS_CONSTANT 0x02
2781 #define HIDP_KDR_CAPS_IS_BUTTON 0x04
2782 #define HIDP_KDR_CAPS_IS_ABSOLUTE 0x08
2783 #define HIDP_KDR_CAPS_IS_RANGE 0x10
2784 #define HIDP_KDR_CAPS_IS_STRING_RANGE 0x40
2785 #define HIDP_KDR_CAPS_IS_DESIGNATOR_RANGE 0x80
2787 struct hidp_kdr_node
2792 USHORT number_of_children
;
2793 USHORT next_sibling
;
2795 ULONG collection_type
;
2804 USHORT input_caps_start
;
2805 USHORT input_caps_count
;
2806 USHORT input_caps_end
;
2807 USHORT input_report_byte_length
;
2808 USHORT output_caps_start
;
2809 USHORT output_caps_count
;
2810 USHORT output_caps_end
;
2811 USHORT output_report_byte_length
;
2812 USHORT feature_caps_start
;
2813 USHORT feature_caps_count
;
2814 USHORT feature_caps_end
;
2815 USHORT feature_report_byte_length
;
2817 USHORT number_link_collection_nodes
;
2818 struct hidp_kdr_caps caps
[1];
2819 /* struct hidp_kdr_node nodes[1] */
2822 static void test_hidp_kdr(void)
2824 #include "psh_hid_macros.h"
2825 const unsigned char report_desc
[] =
2827 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2828 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2829 COLLECTION(1, Application
),
2830 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2831 LOGICAL_MINIMUM(1, 1),
2832 LOGICAL_MAXIMUM(1, 127),
2833 PHYSICAL_MINIMUM(1, -128),
2834 PHYSICAL_MAXIMUM(1, 127),
2836 USAGE(1, HID_USAGE_GENERIC_RZ
),
2839 FEATURE(1, Data
|Var
|Abs
),
2840 USAGE(1, HID_USAGE_GENERIC_SLIDER
),
2843 FEATURE(1, Data
|Var
|Abs
),
2845 USAGE(1, HID_USAGE_GENERIC_X
),
2849 UNIT_EXPONENT(1, -3),
2850 INPUT(1, Data
|Var
|Abs
),
2851 UNIT_EXPONENT(1, 0),
2853 USAGE(1, HID_USAGE_GENERIC_Y
),
2854 DESIGNATOR_MINIMUM(1, 1),
2855 DESIGNATOR_MAXIMUM(1, 4),
2858 INPUT(1, Cnst
|Var
|Abs
),
2859 USAGE(1, HID_USAGE_GENERIC_Z
),
2862 INPUT(1, Data
|Var
|Rel
),
2863 USAGE(1, HID_USAGE_GENERIC_RX
),
2864 USAGE(1, HID_USAGE_GENERIC_RY
),
2867 LOGICAL_MINIMUM(1, 7),
2868 INPUT(1, Data
|Var
|Abs
|Null
),
2870 COLLECTION(1, Application
),
2871 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|1),
2872 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|2),
2875 LOGICAL_MINIMUM(1, 0),
2876 LOGICAL_MAXIMUM(1, 1),
2877 INPUT(1, Data
|Var
|Abs
),
2879 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|3),
2880 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|8),
2883 LOGICAL_MINIMUM(1, 3),
2884 LOGICAL_MAXIMUM(1, 8),
2885 INPUT(1, Data
|Ary
|Abs
),
2887 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|9),
2888 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|12),
2891 LOGICAL_MINIMUM(1, 9),
2892 LOGICAL_MAXIMUM(1, 12),
2893 INPUT(2, Data
|Ary
|Abs
|Buff
),
2895 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|13),
2896 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|14),
2897 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|15),
2898 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|16),
2901 LOGICAL_MINIMUM(1, 13),
2902 LOGICAL_MAXIMUM(1, 16),
2903 INPUT(1, Data
|Ary
|Abs
),
2907 #include "pop_hid_macros.h"
2909 static const HIDP_CAPS expect_hidp_caps
=
2911 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
2912 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
2913 .InputReportByteLength
= 15,
2915 static const HID_DEVICE_ATTRIBUTES attributes
=
2917 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
2919 .ProductID
= 0x0001,
2920 .VersionNumber
= 0x0100,
2922 static const struct hidp_kdr expect_kdr
=
2924 .magic
= "HidP KDR",
2927 .input_caps_count
= 13,
2928 .input_caps_end
= 13,
2929 .input_report_byte_length
= 15,
2930 .output_caps_start
= 13,
2931 .output_caps_end
= 13,
2932 .feature_caps_start
= 13,
2933 .feature_caps_count
= 2,
2934 .feature_caps_end
= 14,
2935 .feature_report_byte_length
= 3,
2937 .number_link_collection_nodes
= 2,
2939 static const struct hidp_kdr_caps expect_caps
[] =
2942 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x08,
2943 .bit_field
= 0x002, .end_byte
= 0x2, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
2944 .usage_min
= 0x30, .usage_max
= 0x30, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
2945 .physical_max
= 127, .units
= 0xe, .units_exp
= -3
2948 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x2, .total_bits
= 0x08,
2949 .bit_field
= 0x003, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x8a,
2950 .usage_min
= 0x31, .usage_max
= 0x31, .designator_min
= 1, .designator_max
= 4, .data_index_min
= 0x01,
2951 .data_index_max
= 0x01, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
2954 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x3, .total_bits
= 0x08,
2955 .bit_field
= 0x006, .end_byte
= 0x4, .link_usage_page
= 0x01, .link_usage
= 0x04, .usage_min
= 0x32,
2956 .usage_max
= 0x32, .data_index_min
= 0x02, .data_index_max
= 0x02, .logical_min
= 1, .logical_max
= 127,
2957 .physical_min
= -128, .physical_max
= 127
2960 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x6, .total_bits
= 0x10,
2961 .bit_field
= 0x042, .end_byte
= 0x8, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
2962 .usage_min
= 0x34, .usage_max
= 0x34, .data_index_min
= 0x03, .data_index_max
= 0x03, .null_value
= 1,
2963 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
2966 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x4, .total_bits
= 0x10,
2967 .bit_field
= 0x042, .end_byte
= 0x6, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
2968 .usage_min
= 0x33, .usage_max
= 0x33, .data_index_min
= 0x04, .data_index_max
= 0x04, .null_value
= 1,
2969 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
2972 .usage_page
= 0x09, .start_bit
= 1, .bit_size
= 0x01, .report_count
= 0x7, .start_byte
= 0x8, .total_bits
= 0x07,
2973 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
2974 .usage_min
= 0x02, .usage_max
= 0x02, .data_index_min
= 0x05, .data_index_max
= 0x05,
2977 .usage_page
= 0x09, .bit_size
= 0x01, .report_count
= 0x1, .start_byte
= 0x8, .total_bits
= 0x01,
2978 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
2979 .usage_min
= 0x01, .usage_max
= 0x01, .data_index_min
= 0x06, .data_index_max
= 0x06,
2982 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x9, .total_bits
= 0x08,
2983 .bit_field
= 0x000, .end_byte
= 0xa, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
2984 .usage_min
= 0x03, .usage_max
= 0x08, .data_index_min
= 0x07, .data_index_max
= 0x0c, .null_value
= 3,
2988 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x4, .start_byte
= 0xa, .total_bits
= 0x20,
2989 .bit_field
= 0x100, .end_byte
= 0xe, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
2990 .usage_min
= 0x09, .usage_max
= 0x0c, .data_index_min
= 0x0d, .data_index_max
= 0x10, .null_value
= 9,
2994 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
2995 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
2996 .usage_min
= 0x10, .usage_max
= 0x10, .data_index_min
= 0x14, .data_index_max
= 0x14, .null_value
= 13,
3000 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3001 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3002 .usage_min
= 0x0f, .usage_max
= 0x0f, .data_index_min
= 0x13, .data_index_max
= 0x13, .null_value
= 13,
3006 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3007 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3008 .usage_min
= 0x0e, .usage_max
= 0x0e, .data_index_min
= 0x12, .data_index_max
= 0x12, .null_value
= 13,
3012 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3013 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3014 .usage_min
= 0x0d, .usage_max
= 0x0d, .data_index_min
= 0x11, .data_index_max
= 0x11, .null_value
= 13,
3018 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x10,
3019 .bit_field
= 0x002, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3020 .usage_min
= 0x36, .usage_max
= 0x36, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
3026 static const struct hidp_kdr_node expect_nodes
[] =
3032 .number_of_children
= 0x1,
3035 .collection_type
= 0x1,
3041 .number_of_children
= 0,
3044 .collection_type
= 0x1,
3048 char buffer
[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W
, DevicePath
[MAX_PATH
] )];
3049 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(SP_DEVICE_INTERFACE_DATA
)};
3050 SP_DEVICE_INTERFACE_DETAIL_DATA_W
*iface_detail
= (void *)buffer
;
3051 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
3052 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
3053 PHIDP_PREPARSED_DATA preparsed_data
;
3054 DWORD i
, report_id
= 0, polled
= 0;
3055 struct hidp_kdr
*kdr
;
3062 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
3063 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
3064 SetCurrentDirectoryW( tempdir
);
3066 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
3067 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
3068 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
3070 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
3071 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3073 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
3074 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3076 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)report_desc
, sizeof(report_desc
) );
3077 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3079 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
3080 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3082 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)&expect_hidp_caps
, sizeof(expect_hidp_caps
) );
3083 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3085 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, NULL
, 0 );
3086 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3088 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, NULL
, 0 );
3089 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3091 if (!pnp_driver_start( L
"driver_hid.dll" )) goto done
;
3093 set
= SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
3094 ok( set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError() );
3095 for (i
= 0; SetupDiEnumDeviceInfo( set
, i
, &device
); ++i
)
3097 ret
= SetupDiEnumDeviceInterfaces( set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
3098 ok( ret
, "failed to get interface, error %#x\n", GetLastError() );
3099 ok( IsEqualGUID( &iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
), "wrong class %s\n",
3100 debugstr_guid( &iface
.InterfaceClassGuid
) );
3101 ok( iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
3103 iface_detail
->cbSize
= sizeof(*iface_detail
);
3104 ret
= SetupDiGetDeviceInterfaceDetailW( set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
3105 ok( ret
, "failed to get interface path, error %#x\n", GetLastError() );
3107 if (wcsstr( iface_detail
->DevicePath
, L
"\\\\?\\hid#winetest#1" )) break;
3109 SetupDiDestroyDeviceInfoList( set
);
3111 file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
3112 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
3113 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
3115 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
3116 ok( ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
3118 kdr
= (struct hidp_kdr
*)preparsed_data
;
3120 ok( !strncmp( kdr
->magic
, expect_kdr
.magic
, 8 ), "got %s expected %s\n",
3121 debugstr_an(kdr
->magic
, 8), debugstr_an(expect_kdr
.magic
, 8) );
3123 if (!strncmp( kdr
->magic
, expect_kdr
.magic
, 8 ))
3125 check_member( *kdr
, expect_kdr
, "%04x", usage
);
3126 check_member( *kdr
, expect_kdr
, "%04x", usage_page
);
3127 check_member( *kdr
, expect_kdr
, "%#x", unknown
[0] );
3128 check_member( *kdr
, expect_kdr
, "%#x", unknown
[1] );
3129 check_member( *kdr
, expect_kdr
, "%d", input_caps_start
);
3130 check_member( *kdr
, expect_kdr
, "%d", input_caps_count
);
3131 check_member( *kdr
, expect_kdr
, "%d", input_caps_end
);
3132 check_member( *kdr
, expect_kdr
, "%d", input_report_byte_length
);
3133 check_member( *kdr
, expect_kdr
, "%d", output_caps_start
);
3134 check_member( *kdr
, expect_kdr
, "%d", output_caps_count
);
3135 check_member( *kdr
, expect_kdr
, "%d", output_caps_end
);
3136 check_member( *kdr
, expect_kdr
, "%d", output_report_byte_length
);
3137 check_member( *kdr
, expect_kdr
, "%d", feature_caps_start
);
3138 check_member( *kdr
, expect_kdr
, "%d", feature_caps_count
);
3139 check_member( *kdr
, expect_kdr
, "%d", feature_caps_end
);
3140 check_member( *kdr
, expect_kdr
, "%d", feature_report_byte_length
);
3141 check_member( *kdr
, expect_kdr
, "%d", caps_size
);
3142 check_member( *kdr
, expect_kdr
, "%d", number_link_collection_nodes
);
3144 for (i
= 0; i
< ARRAY_SIZE(expect_caps
); ++i
)
3146 winetest_push_context( "caps[%d]", i
);
3147 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_page
);
3148 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_id
);
3149 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_bit
);
3150 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", bit_size
);
3151 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_count
);
3152 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_byte
);
3153 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", total_bits
);
3154 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", bit_field
);
3155 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", end_byte
);
3156 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", link_collection
);
3157 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage_page
);
3158 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage
);
3159 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", flags
);
3160 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[0] );
3161 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[1] );
3162 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[2] );
3163 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[3] );
3164 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[4] );
3165 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[5] );
3166 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[6] );
3167 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[7] );
3168 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_min
);
3169 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_max
);
3170 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_min
);
3171 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_max
);
3172 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_min
);
3173 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_max
);
3174 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_min
);
3175 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_max
);
3176 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", null_value
);
3177 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", unknown
);
3178 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", logical_min
);
3179 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", logical_max
);
3180 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", physical_min
);
3181 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", physical_max
);
3182 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", units
);
3183 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", units_exp
);
3184 winetest_pop_context();
3187 for (i
= 0; i
< ARRAY_SIZE(expect_nodes
); ++i
)
3189 struct hidp_kdr_node
*nodes
= (struct hidp_kdr_node
*)((char *)kdr
->caps
+ kdr
->caps_size
);
3190 winetest_push_context( "nodes[%d]", i
);
3191 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage
);
3192 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage_page
);
3193 check_member( nodes
[i
], expect_nodes
[i
], "%d", parent
);
3194 check_member( nodes
[i
], expect_nodes
[i
], "%d", number_of_children
);
3195 check_member( nodes
[i
], expect_nodes
[i
], "%d", next_sibling
);
3196 check_member( nodes
[i
], expect_nodes
[i
], "%d", first_child
);
3197 check_member( nodes
[i
], expect_nodes
[i
], "%#x", collection_type
);
3198 winetest_pop_context();
3202 HidD_FreePreparsedData( preparsed_data
);
3204 CloseHandle( file
);
3208 SetCurrentDirectoryW( cwd
);
3211 static void cleanup_registry_keys(void)
3213 static const WCHAR joystick_oem_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3214 "PrivateProperties\\Joystick\\OEM";
3215 static const WCHAR dinput_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3216 "PrivateProperties\\DirectInput";
3219 /* These keys are automatically created by DInput and they store the
3220 list of supported force-feedback effects. OEM drivers are supposed
3221 to provide a list in HKLM for the vendor-specific force-feedback
3224 We need to clean them up, or DInput will not refresh the list of
3225 effects from the PID report changes.
3227 RegCreateKeyExW( HKEY_CURRENT_USER
, joystick_oem_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3228 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3229 RegCloseKey( root_key
);
3231 RegCreateKeyExW( HKEY_CURRENT_USER
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3232 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3233 RegCloseKey( root_key
);
3235 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, joystick_oem_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3236 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3237 RegCloseKey( root_key
);
3239 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3240 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3241 RegCloseKey( root_key
);
3244 static BOOL
dinput_driver_start( const BYTE
*desc_buf
, ULONG desc_len
, const HIDP_CAPS
*caps
)
3246 static const HID_DEVICE_ATTRIBUTES attributes
=
3248 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
3249 .VendorID
= LOWORD( EXPECT_VIDPID
),
3250 .ProductID
= HIWORD( EXPECT_VIDPID
),
3251 .VersionNumber
= 0x0100,
3253 DWORD report_id
= 1;
3258 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
3259 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
3260 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
3261 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
3262 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3263 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
3264 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3265 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)desc_buf
, desc_len
);
3266 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3267 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
3268 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3269 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)caps
, sizeof(*caps
) );
3270 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3271 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, NULL
, 0 );
3272 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3273 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, NULL
, 0 );
3274 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3276 return pnp_driver_start( L
"driver_hid.dll" );
3279 static BOOL CALLBACK
find_test_device( const DIDEVICEINSTANCEW
*devinst
, void *context
)
3281 if (IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3282 *(DIDEVICEINSTANCEW
*)context
= *devinst
;
3283 return DIENUM_CONTINUE
;
3286 struct check_objects_todos
3290 BOOL collection_number
;
3293 struct check_objects_params
3297 const DIDEVICEOBJECTINSTANCEW
*expect_objs
;
3298 const struct check_objects_todos
*todo_objs
;
3301 static BOOL CALLBACK
check_objects( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
3303 static const DIDEVICEOBJECTINSTANCEW unexpected_obj
= {0};
3304 struct check_objects_params
*params
= args
;
3305 const DIDEVICEOBJECTINSTANCEW
*exp
= params
->expect_objs
+ params
->index
;
3306 const struct check_objects_todos
*todo
= params
->todo_objs
+ params
->index
;
3308 winetest_push_context( "obj[%d]", params
->index
);
3310 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
3311 if (params
->index
>= params
->expect_count
) exp
= &unexpected_obj
;
3313 check_member( *obj
, *exp
, "%u", dwSize
);
3314 check_member_guid( *obj
, *exp
, guidType
);
3315 todo_wine_if( todo
->ofs
)
3316 check_member( *obj
, *exp
, "%#x", dwOfs
);
3317 todo_wine_if( todo
->type
)
3318 check_member( *obj
, *exp
, "%#x", dwType
);
3319 check_member( *obj
, *exp
, "%#x", dwFlags
);
3320 if (!localized
) todo_wine
check_member_wstr( *obj
, *exp
, tszName
);
3321 check_member( *obj
, *exp
, "%u", dwFFMaxForce
);
3322 check_member( *obj
, *exp
, "%u", dwFFForceResolution
);
3323 todo_wine_if( todo
->collection_number
)
3324 check_member( *obj
, *exp
, "%u", wCollectionNumber
);
3325 check_member( *obj
, *exp
, "%u", wDesignatorIndex
);
3326 check_member( *obj
, *exp
, "%#04x", wUsagePage
);
3327 check_member( *obj
, *exp
, "%#04x", wUsage
);
3328 check_member( *obj
, *exp
, "%#04x", dwDimension
);
3329 check_member( *obj
, *exp
, "%#04x", wExponent
);
3330 check_member( *obj
, *exp
, "%u", wReportId
);
3332 winetest_pop_context();
3335 return DIENUM_CONTINUE
;
3338 static BOOL CALLBACK
check_object_count( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
3340 DWORD
*count
= args
;
3341 *count
= *count
+ 1;
3342 return DIENUM_CONTINUE
;
3345 static void test_simple_joystick(void)
3347 #include "psh_hid_macros.h"
3348 static const unsigned char report_desc
[] =
3350 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3351 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3352 COLLECTION(1, Application
),
3353 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3354 COLLECTION(1, Report
),
3357 USAGE(1, HID_USAGE_GENERIC_X
),
3358 USAGE(1, HID_USAGE_GENERIC_Y
),
3359 LOGICAL_MINIMUM(1, 0xe7),
3360 LOGICAL_MAXIMUM(1, 0x38),
3361 PHYSICAL_MINIMUM(1, 0xe7),
3362 PHYSICAL_MAXIMUM(1, 0x38),
3365 INPUT(1, Data
|Var
|Abs
),
3367 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
3368 LOGICAL_MINIMUM(1, 1),
3369 LOGICAL_MAXIMUM(1, 8),
3370 PHYSICAL_MINIMUM(1, 0),
3371 PHYSICAL_MAXIMUM(1, 8),
3374 INPUT(1, Data
|Var
|Abs
|Null
),
3376 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3377 USAGE_MINIMUM(1, 1),
3378 USAGE_MAXIMUM(1, 2),
3379 LOGICAL_MINIMUM(1, 0),
3380 LOGICAL_MAXIMUM(1, 1),
3381 PHYSICAL_MINIMUM(1, 0),
3382 PHYSICAL_MAXIMUM(1, 1),
3385 INPUT(1, Data
|Var
|Abs
),
3389 #undef REPORT_ID_OR_USAGE_PAGE
3390 #include "pop_hid_macros.h"
3392 static const HIDP_CAPS hid_caps
=
3394 .InputReportByteLength
= 4,
3396 static const DIDEVCAPS expect_caps
=
3398 .dwSize
= sizeof(DIDEVCAPS
),
3399 .dwFlags
= DIDC_ATTACHED
| DIDC_EMULATED
,
3400 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
,
3405 struct hid_expect injected_input
[] =
3408 .code
= IOCTL_HID_READ_REPORT
,
3409 .report_buf
= {1,0x10,0x10,0},
3412 .code
= IOCTL_HID_READ_REPORT
,
3413 .report_buf
= {1,0x38,0x38,0xf8},
3416 .code
= IOCTL_HID_READ_REPORT
,
3417 .report_buf
= {1,0x01,0x01,0x00},
3420 .code
= IOCTL_HID_READ_REPORT
,
3421 .report_buf
= {1,0x01,0x01,0x00},
3424 .code
= IOCTL_HID_READ_REPORT
,
3425 .report_buf
= {1,0x80,0x80,0xff},
3428 .code
= IOCTL_HID_READ_REPORT
,
3429 .report_buf
= {1,0x10,0xee,0x54},
3432 static const struct DIJOYSTATE2 expect_state
[] =
3434 {.lX
= 32767, .lY
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3435 {.lX
= 32767, .lY
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3436 {.lX
= 65535, .lY
= 65535, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3437 {.lX
= 20779, .lY
= 20779, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3438 {.lX
= 20779, .lY
= 20779, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3439 {.lX
= 0, .lY
= 0, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3440 {.lX
= 32767, .lY
= 5594, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3442 static const struct DIJOYSTATE2 expect_state_abs
[] =
3444 {.lX
= -9000, .lY
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3445 {.lX
= -9000, .lY
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3446 {.lX
= -4000, .lY
= 51000, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3447 {.lX
= -10667, .lY
= 12905, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3448 {.lX
= -10667, .lY
= 12905, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3449 {.lX
= -14000, .lY
= 1000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3450 {.lX
= -9000, .lY
= 1000, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3452 static const struct DIJOYSTATE2 expect_state_rel
[] =
3454 {.lX
= 0, .lY
= 0, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80, 0}},
3455 {.lX
= 9016, .lY
= -984, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3456 {.lX
= 40, .lY
= 40, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3457 {.lX
= -55, .lY
= -55, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3458 {.lX
= 0, .lY
= 0, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3459 {.lX
= -129, .lY
= -129, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3460 {.lX
= 144, .lY
= 110, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3462 static const DIDEVICEOBJECTDATA expect_objdata
[] =
3464 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
3465 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
3466 {.dwOfs
= 0, .dwData
= 0xffff, .dwSequence
= 0xa},
3467 {.dwOfs
= 0x20, .dwData
= 31500, .dwSequence
= 0xa},
3468 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xa},
3469 {.dwOfs
= 0x4, .dwData
= 0x512b, .dwSequence
= 0xd},
3470 {.dwOfs
= 0, .dwData
= 0x512b, .dwSequence
= 0xd},
3471 {.dwOfs
= 0x20, .dwData
= -1, .dwSequence
= 0xd},
3472 {.dwOfs
= 0x30, .dwData
= 0, .dwSequence
= 0xd},
3473 {.dwOfs
= 0x31, .dwData
= 0, .dwSequence
= 0xd},
3474 {.dwOfs
= 0x4, .dwData
= 0, .dwSequence
= 0xf},
3475 {.dwOfs
= 0, .dwData
= 0, .dwSequence
= 0xf},
3476 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xf},
3477 {.dwOfs
= 0x31, .dwData
= 0x80, .dwSequence
= 0xf},
3480 const DIDEVICEINSTANCEW expect_devinst
=
3482 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3483 .guidInstance
= expect_guid_product
,
3484 .guidProduct
= expect_guid_product
,
3485 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
,
3486 .tszInstanceName
= L
"Wine test root driver",
3487 .tszProductName
= L
"Wine test root driver",
3488 .guidFFDriver
= GUID_NULL
,
3489 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3490 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3492 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
3495 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3496 .guidType
= GUID_YAxis
,
3497 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1),
3498 .dwFlags
= DIDOI_ASPECTPOSITION
,
3499 .tszName
= L
"Y Axis",
3500 .wCollectionNumber
= 1,
3501 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3502 .wUsage
= HID_USAGE_GENERIC_Y
,
3506 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3507 .guidType
= GUID_XAxis
,
3509 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0),
3510 .dwFlags
= DIDOI_ASPECTPOSITION
,
3511 .tszName
= L
"X Axis",
3512 .wCollectionNumber
= 1,
3513 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3514 .wUsage
= HID_USAGE_GENERIC_X
,
3518 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3519 .guidType
= GUID_POV
,
3521 .dwType
= DIDFT_POV
|DIDFT_MAKEINSTANCE(0),
3522 .tszName
= L
"Hat Switch",
3523 .wCollectionNumber
= 1,
3524 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3525 .wUsage
= HID_USAGE_GENERIC_HATSWITCH
,
3529 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3530 .guidType
= GUID_Button
,
3532 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0),
3533 .tszName
= L
"Button 0",
3534 .wCollectionNumber
= 1,
3535 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
3540 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3541 .guidType
= GUID_Button
,
3543 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1),
3544 .tszName
= L
"Button 1",
3545 .wCollectionNumber
= 1,
3546 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
3551 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3552 .guidType
= GUID_Unknown
,
3553 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
3554 .tszName
= L
"Collection 0 - Joystick",
3555 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3556 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3559 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3560 .guidType
= GUID_Unknown
,
3561 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
3562 .tszName
= L
"Collection 1 - Joystick",
3563 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3564 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3567 const struct check_objects_todos objects_todos
[ARRAY_SIZE(expect_objects
)] =
3569 {.ofs
= TRUE
, .type
= TRUE
, .collection_number
= TRUE
},
3570 {.ofs
= TRUE
, .type
= TRUE
, .collection_number
= TRUE
},
3571 {.ofs
= TRUE
, .collection_number
= TRUE
},
3572 {.ofs
= TRUE
, .collection_number
= TRUE
},
3573 {.ofs
= TRUE
, .collection_number
= TRUE
},
3578 struct check_objects_params check_objects_params
=
3580 .expect_count
= ARRAY_SIZE(expect_objects
),
3581 .expect_objs
= expect_objects
,
3582 .todo_objs
= objects_todos
,
3584 DIPROPGUIDANDPATH prop_guid_path
=
3588 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
3589 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3590 .dwHow
= DIPH_DEVICE
,
3593 DIPROPSTRING prop_string
=
3597 .dwSize
= sizeof(DIPROPSTRING
),
3598 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3599 .dwHow
= DIPH_DEVICE
,
3602 DIPROPDWORD prop_dword
=
3606 .dwSize
= sizeof(DIPROPDWORD
),
3607 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3608 .dwHow
= DIPH_DEVICE
,
3611 DIPROPRANGE prop_range
=
3615 .dwSize
= sizeof(DIPROPRANGE
),
3616 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3617 .dwHow
= DIPH_DEVICE
,
3620 DIPROPPOINTER prop_pointer
=
3624 .dwSize
= sizeof(DIPROPPOINTER
),
3625 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3628 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
3629 DIDEVICEOBJECTDATA objdata
[32] = {{0}};
3630 DIDEVICEINSTANCEW devinst
= {0};
3631 DIDATAFORMAT dataformat
= {0};
3632 IDirectInputDevice8W
*device
;
3633 DIDEVCAPS caps
= {0};
3642 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
3643 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
3644 SetCurrentDirectoryW( tempdir
);
3646 cleanup_registry_keys();
3647 if (!dinput_driver_start( report_desc
, sizeof(report_desc
), &hid_caps
)) goto done
;
3649 hr
= DirectInput8Create( instance
, DIRECTINPUT_VERSION
, &IID_IDirectInput8W
, (void **)&di
, NULL
);
3652 win_skip( "DirectInput8Create returned %#x\n", hr
);
3656 hr
= IDirectInput8_EnumDevices( di
, DI8DEVCLASS_ALL
, find_test_device
, &devinst
, DIEDFL_ALLDEVICES
);
3657 ok( hr
== DI_OK
, "IDirectInput8_EnumDevices returned: %#x\n", hr
);
3658 if (!IsEqualGUID( &devinst
.guidProduct
, &expect_guid_product
))
3660 win_skip( "device not found, skipping tests\n" );
3661 IDirectInput8_Release( di
);
3665 check_member( devinst
, expect_devinst
, "%d", dwSize
);
3666 check_member_guid( devinst
, expect_devinst
, guidProduct
);
3668 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
3670 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
3672 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
3673 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
3674 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
3675 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
3677 hr
= IDirectInput8_CreateDevice( di
, &devinst
.guidInstance
, NULL
, NULL
);
3678 ok( hr
== E_POINTER
, "IDirectInput8_CreateDevice returned %#x\n", hr
);
3679 hr
= IDirectInput8_CreateDevice( di
, NULL
, &device
, NULL
);
3680 ok( hr
== E_POINTER
, "IDirectInput8_CreateDevice returned %#x\n", hr
);
3681 hr
= IDirectInput8_CreateDevice( di
, &GUID_NULL
, &device
, NULL
);
3682 ok( hr
== DIERR_DEVICENOTREG
, "IDirectInput8_CreateDevice returned %#x\n", hr
);
3683 hr
= IDirectInput8_CreateDevice( di
, &devinst
.guidInstance
, &device
, NULL
);
3684 ok( hr
== DI_OK
, "IDirectInput8_CreateDevice returned %#x\n", hr
);
3686 prop_dword
.dwData
= 0xdeadbeef;
3687 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
3688 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_VIDPID returned %#x\n", hr
);
3689 /* Wine may get the wrong device here, because the test driver creates another instance of
3690 hidclass.sys, and gets duplicate rawinput handles, which we use in the guidInstance */
3691 todo_wine_if( prop_dword
.dwData
!= EXPECT_VIDPID
)
3692 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#x expected %#x\n", prop_dword
.dwData
, EXPECT_VIDPID
);
3694 ref
= IDirectInputDevice8_Release( device
);
3695 ok( ref
== 0, "IDirectInputDeviceW_Release returned %d\n", ref
);
3697 hr
= IDirectInput8_CreateDevice( di
, &expect_guid_product
, &device
, NULL
);
3698 ok( hr
== DI_OK
, "IDirectInput8_CreateDevice returned %#x\n", hr
);
3700 hr
= IDirectInputDevice8_GetDeviceInfo( device
, NULL
);
3701 ok( hr
== E_POINTER
, "IDirectInputDevice8_GetDeviceInfo returned %#x\n", hr
);
3702 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
) + 1;
3703 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
3704 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetDeviceInfo returned %#x\n", hr
);
3706 devinst
.dwSize
= sizeof(DIDEVICEINSTANCE_DX3W
);
3707 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
3708 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceInfo returned %#x\n", hr
);
3710 check_member_guid( devinst
, expect_devinst
, guidInstance
);
3711 check_member_guid( devinst
, expect_devinst
, guidProduct
);
3713 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
3715 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
3717 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
3719 memset( &devinst
, 0, sizeof(devinst
) );
3720 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
3721 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
3722 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceInfo returned %#x\n", hr
);
3723 check_member( devinst
, expect_devinst
, "%d", dwSize
);
3725 check_member_guid( devinst
, expect_devinst
, guidInstance
);
3726 check_member_guid( devinst
, expect_devinst
, guidProduct
);
3728 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
3730 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
3732 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
3733 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
3734 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
3735 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
3737 hr
= IDirectInputDevice8_GetCapabilities( device
, NULL
);
3738 ok( hr
== E_POINTER
, "IDirectInputDevice8_GetCapabilities returned %#x\n", hr
);
3739 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
3741 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetCapabilities returned %#x\n", hr
);
3742 caps
.dwSize
= sizeof(DIDEVCAPS
);
3743 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
3744 ok( hr
== DI_OK
, "IDirectInputDevice8_GetCapabilities returned %#x\n", hr
);
3745 check_member( caps
, expect_caps
, "%d", dwSize
);
3746 check_member( caps
, expect_caps
, "%#x", dwFlags
);
3748 check_member( caps
, expect_caps
, "%#x", dwDevType
);
3749 check_member( caps
, expect_caps
, "%d", dwAxes
);
3750 check_member( caps
, expect_caps
, "%d", dwButtons
);
3751 check_member( caps
, expect_caps
, "%d", dwPOVs
);
3752 check_member( caps
, expect_caps
, "%d", dwFFSamplePeriod
);
3753 check_member( caps
, expect_caps
, "%d", dwFFMinTimeResolution
);
3754 check_member( caps
, expect_caps
, "%d", dwFirmwareRevision
);
3755 check_member( caps
, expect_caps
, "%d", dwHardwareRevision
);
3756 check_member( caps
, expect_caps
, "%d", dwFFDriverVersion
);
3758 hr
= IDirectInputDevice8_GetProperty( device
, NULL
, NULL
);
3759 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetProperty returned %#x\n", hr
);
3760 hr
= IDirectInputDevice8_GetProperty( device
, &GUID_NULL
, NULL
);
3761 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetProperty returned %#x\n", hr
);
3762 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, NULL
);
3763 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetProperty returned %#x\n", hr
);
3764 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
3766 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetProperty returned %#x\n", hr
);
3767 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
) - 1;
3768 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
3770 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetProperty returned %#x\n", hr
);
3771 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
3773 prop_dword
.dwData
= 0xdeadbeef;
3774 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
3775 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_VIDPID returned %#x\n", hr
);
3776 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#x expected %#x\n", prop_dword
.dwData
, EXPECT_VIDPID
);
3778 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
3779 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
3781 ok( IsEqualGUID( &prop_guid_path
.guidClass
, &GUID_DEVCLASS_HIDCLASS
), "got guid %s\n",
3782 debugstr_guid( &prop_guid_path
.guidClass
) );
3784 ok( !wcsncmp( prop_guid_path
.wszPath
, expect_path
, wcslen( expect_path
) ), "got path %s\n",
3785 debugstr_w(prop_guid_path
.wszPath
) );
3786 if (!(tmp
= wcsrchr( prop_guid_path
.wszPath
, '&' )))
3787 todo_wine
ok( 0, "got path %s\n", debugstr_w(prop_guid_path
.wszPath
) );
3790 ok( !wcscmp( wcsrchr( prop_guid_path
.wszPath
, '&' ), expect_path_end
), "got path %s\n",
3791 debugstr_w(prop_guid_path
.wszPath
) );
3794 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
3795 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_INSTANCENAME returned %#x\n", hr
);
3797 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszInstanceName
), "got instance %s\n",
3798 debugstr_w(prop_string
.wsz
) );
3799 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
3800 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
3802 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
3803 debugstr_w(prop_string
.wsz
) );
3804 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
3806 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_TYPENAME returned %#x\n", hr
);
3808 ok( !wcscmp( prop_string
.wsz
, expect_vidpid_str
), "got type %s\n", debugstr_w(prop_string
.wsz
) );
3809 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
3810 ok( hr
== S_FALSE
, "IDirectInputDevice8_GetProperty DIPROP_USERNAME returned %#x\n", hr
);
3812 ok( !wcscmp( prop_string
.wsz
, L
"" ), "got user %s\n", debugstr_w(prop_string
.wsz
) );
3814 prop_dword
.dwData
= 0xdeadbeef;
3815 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
3816 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
3818 ok( prop_dword
.dwData
== 0, "got %#x expected %#x\n", prop_dword
.dwData
, 0 );
3820 prop_dword
.dwData
= 0xdeadbeef;
3821 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
3823 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_AXISMODE returned %#x\n", hr
);
3825 ok( prop_dword
.dwData
== DIPROPAXISMODE_ABS
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_ABS
);
3826 prop_dword
.dwData
= 0xdeadbeef;
3827 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
3828 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
3829 ok( prop_dword
.dwData
== 0, "got %#x expected %#x\n", prop_dword
.dwData
, 0 );
3830 prop_dword
.dwData
= 0xdeadbeef;
3831 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
3833 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_FFGAIN returned %#x\n", hr
);
3835 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
3837 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
3838 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetProperty DIPROP_CALIBRATION returned %#x\n", hr
);
3839 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
3841 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
3842 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
3844 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
3845 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
3847 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
3848 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
3850 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
3851 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
3853 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr
);
3854 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
3856 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
3858 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
3859 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
3860 prop_dword
.dwData
= 0xdeadbeef;
3861 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
3863 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
3865 ok( prop_dword
.dwData
== 0, "got %u expected %u\n", prop_dword
.dwData
, 0 );
3866 prop_dword
.dwData
= 0xdeadbeef;
3867 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
3869 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
3871 ok( prop_dword
.dwData
== 1, "got %u expected %u\n", prop_dword
.dwData
, 1 );
3872 prop_dword
.dwData
= 0xdeadbeef;
3873 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
3875 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr
);
3877 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
3879 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
3880 prop_range
.diph
.dwObj
= MAKELONG( 0, 0 );
3881 prop_range
.lMin
= 0xdeadbeef;
3882 prop_range
.lMax
= 0xdeadbeef;
3883 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
3885 ok( hr
== DIERR_NOTFOUND
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
3886 prop_range
.diph
.dwObj
= MAKELONG( 0, HID_USAGE_PAGE_GENERIC
);
3887 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
3889 ok( hr
== DIERR_NOTFOUND
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
3890 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_PAGE_GENERIC
, HID_USAGE_GENERIC_X
);
3891 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
3893 ok( hr
== DIERR_NOTFOUND
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
3894 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
3895 prop_range
.lMin
= 0xdeadbeef;
3896 prop_range
.lMax
= 0xdeadbeef;
3897 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
3898 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
3900 ok( prop_range
.lMin
== 0, "got %d expected %d\n", prop_range
.lMin
, 0 );
3902 ok( prop_range
.lMax
== 65535, "got %d expected %d\n", prop_range
.lMax
, 65535 );
3904 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
3905 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
3906 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
3908 ok( hr
== DIERR_NOTINITIALIZED
, "IDirectInputDevice8_GetProperty DIPROP_APPDATA returned %#x\n", hr
);
3910 hr
= IDirectInputDevice8_EnumObjects( device
, NULL
, NULL
, DIDFT_ALL
);
3911 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_EnumObjects returned %#x\n", hr
);
3912 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, 0x20 );
3914 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_EnumObjects returned %#x\n", hr
);
3916 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, DIDFT_AXIS
| DIDFT_PSHBUTTON
);
3917 ok( hr
== DI_OK
, "IDirectInputDevice8_EnumObjects returned %#x\n", hr
);
3918 ok( res
== 4, "got %u expected %u\n", res
, 4 );
3919 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
3920 ok( hr
== DI_OK
, "IDirectInputDevice8_EnumObjects returned %#x\n", hr
);
3921 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
3922 check_objects_params
.expect_count
- check_objects_params
.index
);
3924 hr
= IDirectInputDevice8_SetDataFormat( device
, NULL
);
3925 ok( hr
== E_POINTER
, "IDirectInputDevice8_SetDataFormat returned: %#x\n", hr
);
3926 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
3927 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetDataFormat returned: %#x\n", hr
);
3928 dataformat
.dwSize
= sizeof(DIDATAFORMAT
);
3929 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
3931 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetDataFormat returned: %#x\n", hr
);
3932 dataformat
.dwObjSize
= sizeof(DIOBJECTDATAFORMAT
);
3933 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
3934 ok( hr
== DI_OK
, "IDirectInputDevice8_SetDataFormat returned: %#x\n", hr
);
3935 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
3936 ok( hr
== DI_OK
, "IDirectInputDevice8_SetDataFormat returned: %#x\n", hr
);
3938 hr
= IDirectInputDevice8_SetEventNotification( device
, (HANDLE
)0xdeadbeef );
3940 ok( hr
== E_HANDLE
, "IDirectInputDevice8_SetEventNotification returned: %#x\n", hr
);
3941 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
3942 ok( event
!= NULL
, "CreateEventW failed, last error %u\n", GetLastError() );
3943 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
3944 ok( hr
== DI_OK
, "IDirectInputDevice8_SetEventNotification returned: %#x\n", hr
);
3946 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
3947 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
3948 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
3950 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, 0 );
3951 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3952 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
);
3953 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3954 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
3955 ok( hr
== E_HANDLE
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3956 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
3957 ok( hr
== E_HANDLE
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3958 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
3959 ok( hr
== E_HANDLE
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3961 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
3962 NULL
, NULL
, NULL
, NULL
);
3964 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
3965 ok( hr
== DI_OK
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3966 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
3967 ok( hr
== DI_OK
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3968 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
3969 ok( hr
== DI_OK
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3971 hr
= IDirectInputDevice8_Unacquire( device
);
3972 ok( hr
== DI_NOEFFECT
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
3973 hr
= IDirectInputDevice8_Acquire( device
);
3974 ok( hr
== DI_OK
, "IDirectInputDevice8_Acquire returned: %#x\n", hr
);
3975 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
3977 ok( hr
== DIERR_ACQUIRED
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3978 hr
= IDirectInputDevice8_Unacquire( device
);
3979 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
3981 DestroyWindow( hwnd
);
3983 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
3984 ok( hr
== DI_OK
, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr
);
3986 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
3988 ok( hr
== DIERR_NOTACQUIRED
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
3990 hr
= IDirectInputDevice8_Poll( device
);
3991 ok( hr
== DIERR_NOTACQUIRED
, "IDirectInputDevice8_Poll returned: %#x\n", hr
);
3993 hr
= IDirectInputDevice8_Acquire( device
);
3994 ok( hr
== DI_OK
, "IDirectInputDevice8_Acquire returned: %#x\n", hr
);
3996 hr
= IDirectInputDevice8_Poll( device
);
3998 ok( hr
== DI_NOEFFECT
, "IDirectInputDevice8_Poll returned: %#x\n", hr
);
4000 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
) + 1, &state
);
4002 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4004 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
4006 winetest_push_context( "state[%d]", i
);
4007 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4008 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4009 todo_wine_if( i
!= 2 )
4010 check_member( state
, expect_state
[i
], "%d", lX
);
4011 todo_wine_if( i
!= 2 )
4012 check_member( state
, expect_state
[i
], "%d", lY
);
4013 check_member( state
, expect_state
[i
], "%d", lZ
);
4014 todo_wine_if( i
== 0 )
4015 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[0] );
4016 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[1] );
4017 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
4018 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
4019 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
4021 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
4023 res
= WaitForSingleObject( event
, 100 );
4024 if (i
== 0 || i
== 3) todo_wine_if( i
== 0 )
4025 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
4026 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" ); ResetEvent( event
);
4027 winetest_pop_context();
4030 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4031 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4032 winetest_push_context( "state[%d]", i
);
4034 check_member( state
, expect_state
[i
], "%d", lX
);
4036 check_member( state
, expect_state
[i
], "%d", lY
);
4037 check_member( state
, expect_state
[i
], "%d", lZ
);
4038 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[0] );
4039 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[1] );
4040 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
4041 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
4042 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
4043 winetest_pop_context();
4046 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
) - 1, objdata
, &res
, DIGDD_PEEK
);
4048 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4050 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4051 ok( hr
== DIERR_NOTBUFFERED
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4053 hr
= IDirectInputDevice8_Unacquire( device
);
4054 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
4055 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4056 prop_dword
.diph
.dwObj
= 0;
4057 prop_dword
.dwData
= 1;
4058 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4059 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4060 hr
= IDirectInputDevice8_Acquire( device
);
4061 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
4064 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4065 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4066 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4068 send_hid_input( file
, &injected_input
[0], sizeof(*injected_input
) );
4069 res
= WaitForSingleObject( event
, 100 );
4070 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4071 ResetEvent( event
);
4074 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4075 ok( hr
== DI_BUFFEROVERFLOW
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4076 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4078 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4080 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4081 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4083 hr
= IDirectInputDevice8_Unacquire( device
);
4084 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
4085 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4086 prop_dword
.diph
.dwObj
= 0;
4087 prop_dword
.dwData
= 10;
4088 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4089 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4090 hr
= IDirectInputDevice8_Acquire( device
);
4091 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
4093 send_hid_input( file
, &injected_input
[1], sizeof(*injected_input
) );
4094 res
= WaitForSingleObject( event
, 100 );
4095 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4096 ResetEvent( event
);
4099 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4100 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4101 ok( res
== 1, "got %u expected %u\n", res
, 1 );
4102 check_member( objdata
[0], expect_objdata
[0], "%#x", dwOfs
);
4103 check_member( objdata
[0], expect_objdata
[0], "%#x", dwData
);
4105 check_member( objdata
[0], expect_objdata
[0], "%#x", dwSequence
);
4106 ok( objdata
[0].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[0].uAppData
, (void *)-1 );
4108 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4109 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4110 ok( res
== 4, "got %u expected %u\n", res
, 4 );
4111 for (i
= 0; i
< 4; ++i
)
4113 winetest_push_context( "objdata[%d]", i
);
4114 check_member( objdata
[i
], expect_objdata
[1 + i
], "%#x", dwOfs
);
4115 check_member( objdata
[i
], expect_objdata
[1 + i
], "%#x", dwData
);
4117 check_member( objdata
[i
], expect_objdata
[1 + i
], "%#x", dwSequence
);
4118 ok( objdata
[i
].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[i
].uAppData
, (void *)-1 );
4119 winetest_pop_context();
4122 send_hid_input( file
, &injected_input
[2], sizeof(*injected_input
) );
4123 res
= WaitForSingleObject( event
, 100 );
4124 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4125 ResetEvent( event
);
4126 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4127 res
= WaitForSingleObject( event
, 100 );
4128 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4129 ResetEvent( event
);
4132 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4133 ok( hr
== DI_BUFFEROVERFLOW
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4134 ok( res
== 1, "got %u expected %u\n", res
, 1 );
4136 check_member( objdata
[0], expect_objdata
[5], "%#x", dwOfs
);
4138 check_member( objdata
[0], expect_objdata
[5], "%#x", dwData
);
4139 ok( objdata
[0].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[0].uAppData
, (void *)-1 );
4140 res
= ARRAY_SIZE(objdata
);
4141 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4142 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr
);
4143 ok( res
== 8, "got %u expected %u\n", res
, 8 );
4144 for (i
= 0; i
< 8; ++i
)
4146 winetest_push_context( "objdata[%d]", i
);
4148 check_member( objdata
[i
], expect_objdata
[6 + i
], "%#x", dwOfs
);
4149 todo_wine_if( i
!= 3 && i
!= 4 && i
!= 7 )
4150 check_member( objdata
[i
], expect_objdata
[6 + i
], "%#x", dwData
);
4151 ok( objdata
[i
].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[i
].uAppData
, (void *)-1 );
4152 winetest_pop_context();
4155 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
4156 res
= WaitForSingleObject( event
, 100 );
4157 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4158 ResetEvent( event
);
4160 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4161 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4163 check_member( state
, expect_state
[3], "%d", lX
);
4165 check_member( state
, expect_state
[3], "%d", lY
);
4166 check_member( state
, expect_state
[3], "%d", lZ
);
4167 check_member( state
, expect_state
[3], "%d", rgdwPOV
[0] );
4168 check_member( state
, expect_state
[3], "%d", rgdwPOV
[1] );
4169 check_member( state
, expect_state
[3], "%#x", rgbButtons
[0] );
4170 check_member( state
, expect_state
[3], "%#x", rgbButtons
[1] );
4171 check_member( state
, expect_state
[3], "%#x", rgbButtons
[2] );
4173 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
4174 prop_range
.diph
.dwObj
= 0;
4175 prop_range
.lMin
= 1000;
4176 prop_range
.lMax
= 51000;
4177 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4178 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_RANGE returned %#x\n", hr
);
4179 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4180 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4181 prop_range
.lMin
= -4000;
4182 prop_range
.lMax
= -14000;
4183 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4185 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_RANGE returned %#x\n", hr
);
4186 prop_range
.lMin
= -14000;
4187 prop_range
.lMax
= -4000;
4188 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4189 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_RANGE returned %#x\n", hr
);
4191 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
4192 prop_range
.diph
.dwObj
= 0;
4193 prop_range
.lMin
= 0xdeadbeef;
4194 prop_range
.lMax
= 0xdeadbeef;
4195 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4197 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
4198 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4199 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4200 prop_range
.lMin
= 0xdeadbeef;
4201 prop_range
.lMax
= 0xdeadbeef;
4202 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4203 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
4205 ok( prop_range
.lMin
== -14000, "got %d expected %d\n", prop_range
.lMin
, -14000 );
4207 ok( prop_range
.lMax
== -4000, "got %d expected %d\n", prop_range
.lMax
, -4000 );
4208 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4209 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
4210 prop_range
.lMin
= 0xdeadbeef;
4211 prop_range
.lMax
= 0xdeadbeef;
4212 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4213 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr
);
4215 ok( prop_range
.lMin
== 1000, "got %d expected %d\n", prop_range
.lMin
, 1000 );
4217 ok( prop_range
.lMax
== 51000, "got %d expected %d\n", prop_range
.lMax
, 51000 );
4219 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4220 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4222 check_member( state
, expect_state_abs
[1], "%d", lX
);
4224 check_member( state
, expect_state_abs
[1], "%d", lY
);
4225 check_member( state
, expect_state_abs
[1], "%d", lZ
);
4226 check_member( state
, expect_state_abs
[1], "%d", rgdwPOV
[0] );
4227 check_member( state
, expect_state_abs
[1], "%d", rgdwPOV
[1] );
4228 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[0] );
4229 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[1] );
4230 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[2] );
4232 hr
= IDirectInputDevice8_SetProperty( device
, NULL
, NULL
);
4233 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty returned %#x\n", hr
);
4234 hr
= IDirectInputDevice8_SetProperty( device
, &GUID_NULL
, NULL
);
4235 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty returned %#x\n", hr
);
4236 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, NULL
);
4237 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty returned %#x\n", hr
);
4238 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
4240 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty returned %#x\n", hr
);
4242 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4243 prop_dword
.diph
.dwObj
= 0;
4244 prop_dword
.dwData
= 0xdeadbeef;
4245 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
4247 ok( hr
== DIERR_READONLY
, "IDirectInputDevice8_SetProperty DIPROP_VIDPID returned %#x\n", hr
);
4248 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
4250 ok( hr
== DIERR_READONLY
, "IDirectInputDevice8_SetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
4252 prop_string
.diph
.dwHow
= DIPH_DEVICE
;
4253 prop_string
.diph
.dwObj
= 0;
4254 wcscpy( prop_string
.wsz
, L
"instance name" );
4255 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
4256 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_SetProperty DIPROP_INSTANCENAME returned %#x\n", hr
);
4258 wcscpy( prop_string
.wsz
, L
"product name" );
4259 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4261 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4262 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4263 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4265 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
4266 debugstr_w(prop_string
.wsz
) );
4268 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
4270 ok( hr
== DIERR_READONLY
, "IDirectInputDevice8_SetProperty DIPROP_TYPENAME returned %#x\n", hr
);
4271 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
4273 ok( hr
== DIERR_READONLY
, "IDirectInputDevice8_SetProperty DIPROP_USERNAME returned %#x\n", hr
);
4274 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4276 ok( hr
== DIERR_READONLY
, "IDirectInputDevice8_SetProperty DIPROP_FFLOAD returned %#x\n", hr
);
4277 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
4279 ok( hr
== DIERR_READONLY
, "IDirectInputDevice8_SetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
4281 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
4283 ok( hr
== DIERR_ACQUIRED
, "IDirectInputDevice8_SetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
4284 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4285 ok( hr
== DIERR_ACQUIRED
, "IDirectInputDevice8_SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4286 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4287 ok( hr
== DIERR_ACQUIRED
, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4288 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
4290 ok( hr
== DIERR_ACQUIRED
, "IDirectInputDevice8_SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
4291 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
4292 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4293 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
4295 ok( hr
== DIERR_ACQUIRED
, "IDirectInputDevice8_SetProperty DIPROP_APPDATA returned %#x\n", hr
);
4297 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4298 prop_dword
.diph
.dwObj
= 0;
4299 prop_dword
.dwData
= 10001;
4300 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4302 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4303 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4305 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4306 prop_dword
.dwData
= 1000;
4307 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4309 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4310 prop_dword
.dwData
= 6000;
4311 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4313 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4315 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4317 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4318 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4320 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4322 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4323 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4324 prop_dword
.dwData
= 2000;
4325 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4327 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4328 ok( prop_dword
.dwData
== 2000, "got %u expected %u\n", prop_dword
.dwData
, 2000 );
4329 prop_dword
.dwData
= 7000;
4330 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4332 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4334 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4335 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4336 prop_dword
.dwData
= 0xdeadbeef;
4337 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4339 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4341 ok( prop_dword
.dwData
== 2000, "got %u expected %u\n", prop_dword
.dwData
, 2000 );
4342 prop_dword
.dwData
= 0xdeadbeef;
4343 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4345 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4347 ok( prop_dword
.dwData
== 7000, "got %u expected %u\n", prop_dword
.dwData
, 7000 );
4349 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4350 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
4351 prop_dword
.dwData
= 0xdeadbeef;
4352 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4354 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4356 ok( prop_dword
.dwData
== 1000, "got %u expected %u\n", prop_dword
.dwData
, 1000 );
4357 prop_dword
.dwData
= 0xdeadbeef;
4358 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4360 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4362 ok( prop_dword
.dwData
== 6000, "got %u expected %u\n", prop_dword
.dwData
, 6000 );
4364 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
4366 winetest_push_context( "state[%d]", i
);
4367 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4368 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4369 if (broken( state
.lX
== -10750 )) win_skip( "Ignoring 32-bit rounding\n" );
4373 check_member( state
, expect_state_abs
[i
], "%d", lX
);
4374 todo_wine_if( i
!= 2 )
4375 check_member( state
, expect_state_abs
[i
], "%d", lY
);
4377 check_member( state
, expect_state_abs
[i
], "%d", lZ
);
4378 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[0] );
4379 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[1] );
4380 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
4381 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
4382 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
4384 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
4386 res
= WaitForSingleObject( event
, 100 );
4387 if (i
== 0 || i
== 3) todo_wine_if( i
== 0 )
4388 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
4389 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" ); ResetEvent( event
);
4390 winetest_pop_context();
4393 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4394 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4395 winetest_push_context( "state[%d]", i
);
4397 check_member( state
, expect_state_abs
[i
], "%d", lX
);
4399 check_member( state
, expect_state_abs
[i
], "%d", lY
);
4400 check_member( state
, expect_state_abs
[i
], "%d", lZ
);
4401 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[0] );
4402 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[1] );
4403 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
4404 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
4405 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
4406 winetest_pop_context();
4408 hr
= IDirectInputDevice8_Unacquire( device
);
4409 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
4411 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4412 prop_dword
.diph
.dwObj
= 0;
4413 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
4414 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_SetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
4415 prop_dword
.dwData
= 0x1000;
4416 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4417 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4418 prop_dword
.dwData
= 0xdeadbeef;
4419 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
4421 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
4422 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
4423 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
4424 ok( hr
== DIERR_UNSUPPORTED
, "IDirectInputDevice8_SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
4425 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
4426 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4427 prop_pointer
.uData
= 0xfeedcafe;
4428 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
4430 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_APPDATA returned %#x\n", hr
);
4432 prop_dword
.dwData
= 0xdeadbeef;
4433 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4435 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4436 prop_dword
.dwData
= DIPROPAXISMODE_REL
;
4437 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4438 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4440 hr
= IDirectInputDevice8_Acquire( device
);
4441 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
4443 prop_dword
.dwData
= 0xdeadbeef;
4444 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4446 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4448 ok( prop_dword
.dwData
== DIPROPAXISMODE_REL
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_REL
);
4450 prop_dword
.dwData
= 0xdeadbeef;
4451 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4452 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4453 ok( prop_dword
.dwData
== 0x1000, "got %#x expected %#x\n", prop_dword
.dwData
, 0x1000 );
4455 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
4456 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4457 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
4459 ok( hr
== DI_OK
, "IDirectInputDevice8_GetProperty DIPROP_APPDATA returned %#x\n", hr
);
4460 ok( prop_pointer
.uData
== 0xfeedcafe, "got %p expected %p\n", (void *)prop_pointer
.uData
, (void *)0xfeedcafe );
4462 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4463 prop_dword
.diph
.dwObj
= 0;
4464 prop_dword
.dwData
= 0xdeadbeef;
4465 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
4467 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
4468 prop_dword
.dwData
= 1000;
4469 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
4471 ok( hr
== DI_OK
, "IDirectInputDevice8_SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
4473 prop_dword
.dwData
= 0xdeadbeef;
4474 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
4476 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_CALIBRATION returned %#x\n", hr
);
4477 prop_dword
.dwData
= 0xdeadbeef;
4478 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4480 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4481 prop_dword
.dwData
= 0xdeadbeef;
4482 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4484 ok( hr
== DIERR_INVALIDPARAM
, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4486 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
4488 winetest_push_context( "state[%d]", i
);
4489 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4490 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4492 check_member( state
, expect_state_rel
[i
], "%d", lX
);
4494 check_member( state
, expect_state_rel
[i
], "%d", lY
);
4495 check_member( state
, expect_state_rel
[i
], "%d", lZ
);
4496 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[0] );
4497 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[1] );
4498 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
4499 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
4500 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
4502 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
4504 res
= WaitForSingleObject( event
, 100 );
4505 if (i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
4506 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4507 ResetEvent( event
);
4508 winetest_pop_context();
4511 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4512 ok( hr
== DI_OK
, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr
);
4513 winetest_push_context( "state[%d]", i
);
4515 check_member( state
, expect_state_rel
[i
], "%d", lX
);
4517 check_member( state
, expect_state_rel
[i
], "%d", lY
);
4518 check_member( state
, expect_state_rel
[i
], "%d", lZ
);
4519 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[0] );
4520 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[1] );
4521 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
4522 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
4523 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
4524 winetest_pop_context();
4526 hr
= IDirectInputDevice8_Unacquire( device
);
4527 ok( hr
== DI_OK
, "IDirectInputDevice8_Unacquire returned: %#x\n", hr
);
4529 /* FIXME: we have to wait a bit because Wine DInput internal thread keeps a reference */
4532 ref
= IDirectInputDevice8_Release( device
);
4533 ok( ref
== 0, "IDirectInputDeviceW_Release returned %d\n", ref
);
4535 CloseHandle( event
);
4536 CloseHandle( file
);
4538 ref
= IDirectInput8_Release( di
);
4539 ok( ref
== 0, "IDirectInput8_Release returned %d\n", ref
);
4543 cleanup_registry_keys();
4544 SetCurrentDirectoryW( cwd
);
4552 instance
= GetModuleHandleW( NULL
);
4553 localized
= GetUserDefaultLCID() != MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
);
4554 pSignerSign
= (void *)GetProcAddress( LoadLibraryW( L
"mssign32" ), "SignerSign" );
4556 if (IsWow64Process( GetCurrentProcess(), &is_wow64
) && is_wow64
)
4558 skip( "Running in WoW64.\n" );
4562 mapping
= CreateFileMappingW( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, sizeof(*test_data
),
4563 L
"Global\\winetest_dinput_section" );
4564 if (!mapping
&& GetLastError() == ERROR_ACCESS_DENIED
)
4566 win_skip( "Failed to create test data mapping.\n" );
4569 ok( !!mapping
, "got error %u\n", GetLastError() );
4570 test_data
= MapViewOfFile( mapping
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 1024 );
4571 test_data
->running_under_wine
= !strcmp( winetest_platform
, "wine" );
4572 test_data
->winetest_report_success
= winetest_report_success
;
4573 test_data
->winetest_debug
= winetest_debug
;
4575 okfile
= CreateFileW( L
"C:\\windows\\winetest_dinput_okfile", GENERIC_READ
| GENERIC_WRITE
,
4576 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
4577 ok( okfile
!= INVALID_HANDLE_VALUE
, "failed to create file, error %u\n", GetLastError() );
4579 subtest( "driver_hid" );
4581 test_hid_driver( 0, FALSE
);
4582 test_hid_driver( 1, FALSE
);
4583 test_hid_driver( 0, TRUE
);
4584 test_hid_driver( 1, TRUE
);
4586 CoInitialize( NULL
);
4587 test_simple_joystick();
4590 UnmapViewOfFile( test_data
);
4591 CloseHandle( mapping
);
4592 CloseHandle( okfile
);
4593 DeleteFileW( L
"C:\\windows\\winetest_dinput_okfile" );