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
52 #include "ddk/hidclass.h"
53 #include "ddk/hidsdi.h"
54 #include "ddk/hidpi.h"
55 #include "ddk/hidport.h"
59 #include "wine/test.h"
60 #include "wine/mssign.h"
63 #include "driver_hid.h"
65 static HINSTANCE instance
;
66 static BOOL localized
; /* object names get translated */
68 #define EXPECT_VIDPID MAKELONG( 0x1209, 0x0001 )
69 static const WCHAR expect_vidpid_str
[] = L
"VID_1209&PID_0001";
70 static const GUID expect_guid_product
= {EXPECT_VIDPID
,0x0000,0x0000,{0x00,0x00,'P','I','D','V','I','D'}};
71 static const WCHAR expect_path
[] = L
"\\\\?\\hid#winetest#1&2fafeb0&";
72 static const WCHAR expect_path_end
[] = L
"&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
74 static struct winetest_shared_data
*test_data
;
77 static HRESULT (WINAPI
*pSignerSign
)( SIGNER_SUBJECT_INFO
*subject
, SIGNER_CERT
*cert
,
78 SIGNER_SIGNATURE_INFO
*signature
, SIGNER_PROVIDER_INFO
*provider
,
79 const WCHAR
*timestamp
, CRYPT_ATTRIBUTES
*attr
, void *sip_data
);
81 static const WCHAR container_name
[] = L
"wine_testsign";
83 static const CERT_CONTEXT
*testsign_sign( const WCHAR
*filename
)
85 BYTE encoded_name
[100], encoded_key_id
[200], public_key_info_buffer
[1000];
86 BYTE hash_buffer
[16], cert_buffer
[1000], provider_nameA
[100], serial
[16];
87 CERT_PUBLIC_KEY_INFO
*public_key_info
= (CERT_PUBLIC_KEY_INFO
*)public_key_info_buffer
;
88 SIGNER_SIGNATURE_INFO signature
= {sizeof(SIGNER_SIGNATURE_INFO
)};
89 SIGNER_CERT_STORE_INFO store
= {sizeof(SIGNER_CERT_STORE_INFO
)};
90 SIGNER_ATTR_AUTHCODE authcode
= {sizeof(SIGNER_ATTR_AUTHCODE
)};
91 SIGNER_SUBJECT_INFO subject
= {sizeof(SIGNER_SUBJECT_INFO
)};
92 SIGNER_FILE_INFO file
= {sizeof(SIGNER_FILE_INFO
)};
93 SIGNER_CERT signer
= {sizeof(SIGNER_CERT
)};
94 CRYPT_KEY_PROV_INFO provider_info
= {0};
95 CRYPT_ALGORITHM_IDENTIFIER algid
= {0};
96 CERT_AUTHORITY_KEY_ID_INFO key_info
;
97 HCERTSTORE root_store
, pub_store
;
98 CERT_INFO cert_info
= {0};
99 WCHAR provider_nameW
[100];
100 const CERT_CONTEXT
*cert
;
101 CERT_EXTENSION extension
;
102 DWORD size
, index
= 0;
108 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
109 if (!ret
&& GetLastError() == NTE_EXISTS
)
111 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
112 ok( ret
, "Failed to delete container, error %#x\n", GetLastError() );
113 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
115 ok( ret
, "Failed to create container, error %#x\n", GetLastError() );
117 ret
= CryptGenKey( provider
, AT_SIGNATURE
, CRYPT_EXPORTABLE
, &key
);
118 ok( ret
, "Failed to create key, error %#x\n", GetLastError() );
119 ret
= CryptDestroyKey( key
);
120 ok( ret
, "Failed to destroy key, error %#x\n", GetLastError() );
121 ret
= CryptGetUserKey( provider
, AT_SIGNATURE
, &key
);
122 ok( ret
, "Failed to get user key, error %#x\n", GetLastError() );
123 ret
= CryptDestroyKey( key
);
124 ok( ret
, "Failed to destroy key, error %#x\n", GetLastError() );
126 size
= sizeof(encoded_name
);
127 ret
= CertStrToNameW( X509_ASN_ENCODING
, L
"CN=winetest_cert", CERT_X500_NAME_STR
, NULL
,
128 encoded_name
, &size
, NULL
);
129 ok( ret
, "Failed to convert name, error %#x\n", GetLastError() );
130 key_info
.CertIssuer
.cbData
= size
;
131 key_info
.CertIssuer
.pbData
= encoded_name
;
133 size
= sizeof(public_key_info_buffer
);
134 ret
= CryptExportPublicKeyInfo( provider
, AT_SIGNATURE
, X509_ASN_ENCODING
, public_key_info
, &size
);
135 ok( ret
, "Failed to export public key, error %#x\n", GetLastError() );
136 cert_info
.SubjectPublicKeyInfo
= *public_key_info
;
138 size
= sizeof(hash_buffer
);
139 ret
= CryptHashPublicKeyInfo( provider
, CALG_MD5
, 0, X509_ASN_ENCODING
, public_key_info
, hash_buffer
, &size
);
140 ok( ret
, "Failed to hash public key, error %#x\n", GetLastError() );
142 key_info
.KeyId
.cbData
= size
;
143 key_info
.KeyId
.pbData
= hash_buffer
;
145 RtlGenRandom( serial
, sizeof(serial
) );
146 key_info
.CertSerialNumber
.cbData
= sizeof(serial
);
147 key_info
.CertSerialNumber
.pbData
= serial
;
149 size
= sizeof(encoded_key_id
);
150 ret
= CryptEncodeObject( X509_ASN_ENCODING
, X509_AUTHORITY_KEY_ID
, &key_info
, encoded_key_id
, &size
);
151 ok( ret
, "Failed to convert name, error %#x\n", GetLastError() );
153 extension
.pszObjId
= (char *)szOID_AUTHORITY_KEY_IDENTIFIER
;
154 extension
.fCritical
= TRUE
;
155 extension
.Value
.cbData
= size
;
156 extension
.Value
.pbData
= encoded_key_id
;
158 cert_info
.dwVersion
= CERT_V3
;
159 cert_info
.SerialNumber
= key_info
.CertSerialNumber
;
160 cert_info
.SignatureAlgorithm
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
161 cert_info
.Issuer
= key_info
.CertIssuer
;
162 GetSystemTimeAsFileTime( &cert_info
.NotBefore
);
163 GetSystemTimeAsFileTime( &cert_info
.NotAfter
);
164 cert_info
.NotAfter
.dwHighDateTime
+= 1;
165 cert_info
.Subject
= key_info
.CertIssuer
;
166 cert_info
.cExtension
= 1;
167 cert_info
.rgExtension
= &extension
;
168 algid
.pszObjId
= (char *)szOID_RSA_SHA1RSA
;
169 size
= sizeof(cert_buffer
);
170 ret
= CryptSignAndEncodeCertificate( provider
, AT_SIGNATURE
, X509_ASN_ENCODING
, X509_CERT_TO_BE_SIGNED
,
171 &cert_info
, &algid
, NULL
, cert_buffer
, &size
);
172 ok( ret
, "Failed to create certificate, error %#x\n", GetLastError() );
174 cert
= CertCreateCertificateContext( X509_ASN_ENCODING
, cert_buffer
, size
);
175 ok( !!cert
, "Failed to create context, error %#x\n", GetLastError() );
177 size
= sizeof(provider_nameA
);
178 ret
= CryptGetProvParam( provider
, PP_NAME
, provider_nameA
, &size
, 0 );
179 ok( ret
, "Failed to get prov param, error %#x\n", GetLastError() );
180 MultiByteToWideChar( CP_ACP
, 0, (char *)provider_nameA
, -1, provider_nameW
, ARRAY_SIZE(provider_nameW
) );
182 provider_info
.pwszContainerName
= (WCHAR
*)container_name
;
183 provider_info
.pwszProvName
= provider_nameW
;
184 provider_info
.dwProvType
= PROV_RSA_FULL
;
185 provider_info
.dwKeySpec
= AT_SIGNATURE
;
186 ret
= CertSetCertificateContextProperty( cert
, CERT_KEY_PROV_INFO_PROP_ID
, 0, &provider_info
);
187 ok( ret
, "Failed to set provider info, error %#x\n", GetLastError() );
189 ret
= CryptReleaseContext( provider
, 0 );
190 ok( ret
, "failed to release context, error %u\n", GetLastError() );
192 root_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"root" );
193 if (!root_store
&& GetLastError() == ERROR_ACCESS_DENIED
)
195 win_skip( "Failed to open root store.\n" );
196 ret
= CertFreeCertificateContext( cert
);
197 ok( ret
, "Failed to free certificate, error %u\n", GetLastError() );
200 ok( !!root_store
, "Failed to open store, error %u\n", GetLastError() );
201 ret
= CertAddCertificateContextToStore( root_store
, cert
, CERT_STORE_ADD_ALWAYS
, NULL
);
202 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
204 win_skip( "Failed to add self-signed certificate to store.\n" );
205 ret
= CertFreeCertificateContext( cert
);
206 ok( ret
, "Failed to free certificate, error %u\n", GetLastError() );
207 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
208 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
211 ok( ret
, "Failed to add certificate, error %u\n", GetLastError() );
212 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
213 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
215 pub_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0,
216 CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"trustedpublisher" );
217 ok( !!pub_store
, "Failed to open store, error %u\n", GetLastError() );
218 ret
= CertAddCertificateContextToStore( pub_store
, cert
, CERT_STORE_ADD_ALWAYS
, NULL
);
219 ok( ret
, "Failed to add certificate, error %u\n", GetLastError() );
220 ret
= CertCloseStore( pub_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
221 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
223 subject
.dwSubjectChoice
= 1;
224 subject
.pdwIndex
= &index
;
225 subject
.pSignerFileInfo
= &file
;
226 file
.pwszFileName
= (WCHAR
*)filename
;
227 signer
.dwCertChoice
= 2;
228 signer
.pCertStoreInfo
= &store
;
229 store
.pSigningCert
= cert
;
230 store
.dwCertPolicy
= 0;
231 signature
.algidHash
= CALG_SHA_256
;
232 signature
.dwAttrChoice
= SIGNER_AUTHCODE_ATTR
;
233 signature
.pAttrAuthcode
= &authcode
;
234 authcode
.pwszName
= L
"";
235 authcode
.pwszInfo
= L
"";
236 hr
= pSignerSign( &subject
, &signer
, &signature
, NULL
, NULL
, NULL
, NULL
);
238 ok( hr
== S_OK
|| broken( hr
== NTE_BAD_ALGID
) /* < 7 */, "Failed to sign, hr %#x\n", hr
);
243 static void testsign_cleanup( const CERT_CONTEXT
*cert
)
245 HCERTSTORE root_store
, pub_store
;
246 const CERT_CONTEXT
*store_cert
;
250 root_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"root" );
251 ok( !!root_store
, "Failed to open store, error %u\n", GetLastError() );
252 store_cert
= CertFindCertificateInStore( root_store
, X509_ASN_ENCODING
, 0, CERT_FIND_EXISTING
, cert
, NULL
);
253 ok( !!store_cert
, "Failed to find root certificate, error %u\n", GetLastError() );
254 ret
= CertDeleteCertificateFromStore( store_cert
);
255 ok( ret
, "Failed to remove certificate, error %u\n", GetLastError() );
256 ret
= CertCloseStore( root_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
257 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
259 pub_store
= CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0,
260 CERT_SYSTEM_STORE_LOCAL_MACHINE
, L
"trustedpublisher" );
261 ok( !!pub_store
, "Failed to open store, error %u\n", GetLastError() );
262 store_cert
= CertFindCertificateInStore( pub_store
, X509_ASN_ENCODING
, 0, CERT_FIND_EXISTING
, cert
, NULL
);
263 ok( !!store_cert
, "Failed to find publisher certificate, error %u\n", GetLastError() );
264 ret
= CertDeleteCertificateFromStore( store_cert
);
265 ok( ret
, "Failed to remove certificate, error %u\n", GetLastError() );
266 ret
= CertCloseStore( pub_store
, CERT_CLOSE_STORE_CHECK_FLAG
);
267 ok( ret
, "Failed to close store, error %u\n", GetLastError() );
269 ret
= CertFreeCertificateContext( cert
);
270 ok( ret
, "Failed to free certificate, error %u\n", GetLastError() );
272 ret
= CryptAcquireContextW( &provider
, container_name
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
273 ok( ret
, "Failed to delete container, error %#x\n", GetLastError() );
276 static void load_resource( const WCHAR
*name
, WCHAR
*filename
)
278 static WCHAR path
[MAX_PATH
];
284 GetTempPathW( ARRAY_SIZE(path
), path
);
285 GetTempFileNameW( path
, name
, 0, filename
);
287 file
= CreateFileW( filename
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
288 ok( file
!= INVALID_HANDLE_VALUE
, "failed to create %s, error %u\n", debugstr_w(filename
), GetLastError() );
290 res
= FindResourceW( NULL
, name
, L
"TESTDLL" );
291 ok( res
!= 0, "couldn't find resource\n" );
292 ptr
= LockResource( LoadResource( GetModuleHandleW( NULL
), res
) );
293 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleW( NULL
), res
), &written
, NULL
);
294 ok( written
== SizeofResource( GetModuleHandleW( NULL
), res
), "couldn't write resource\n" );
300 #elif defined(__x86_64__)
302 #elif defined(__arm__)
304 #elif defined(__aarch64__)
310 static const char inf_text
[] =
312 "Signature=$Chicago$\n"
313 "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n"
314 "CatalogFile=winetest.cat\n"
315 "DriverVer=09/21/2006,6.0.5736.1\n"
318 "Wine=mfg_section,NT" EXT
"\n"
320 "[mfg_section.NT" EXT
"]\n"
321 "Wine test root driver=device_section,test_hardware_id\n"
323 "[device_section.NT" EXT
"]\n"
324 "CopyFiles=file_section\n"
326 "[device_section.NT" EXT
".Services]\n"
327 "AddService=winetest,0x2,svc_section\n"
332 "[SourceDisksFiles]\n"
335 "[SourceDisksNames]\n"
338 "[DestinationDirs]\n"
339 "DefaultDestDir=12\n"
342 "ServiceBinary=%12%\\winetest.sys\n"
346 "LoadOrderGroup=Extended Base\n"
347 "DisplayName=\"winetest bus driver\"\n"
348 "; they don't sleep anymore, on the beach\n";
350 static void add_file_to_catalog( HANDLE catalog
, const WCHAR
*file
)
352 SIP_SUBJECTINFO subject_info
= {sizeof(SIP_SUBJECTINFO
)};
353 SIP_INDIRECT_DATA
*indirect_data
;
354 const WCHAR
*filepart
= file
;
355 CRYPTCATMEMBER
*member
;
356 WCHAR hash_buffer
[100];
362 ret
= CryptSIPRetrieveSubjectGuidForCatalogFile( file
, NULL
, &subject_guid
);
364 ok( ret
, "Failed to get subject guid, error %u\n", GetLastError() );
367 subject_info
.pgSubjectType
= &subject_guid
;
368 subject_info
.pwsFileName
= file
;
369 subject_info
.DigestAlgorithm
.pszObjId
= (char *)szOID_OIWSEC_sha1
;
370 subject_info
.dwFlags
= SPC_INC_PE_RESOURCES_FLAG
| SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG
|
371 SPC_EXC_PE_PAGE_HASHES_FLAG
| 0x10000;
372 ret
= CryptSIPCreateIndirectData( &subject_info
, &size
, NULL
);
374 ok( ret
, "Failed to get indirect data size, error %u\n", GetLastError() );
376 indirect_data
= malloc( size
);
377 ret
= CryptSIPCreateIndirectData( &subject_info
, &size
, indirect_data
);
379 ok( ret
, "Failed to get indirect data, error %u\n", GetLastError() );
382 memset( hash_buffer
, 0, sizeof(hash_buffer
) );
383 for (i
= 0; i
< indirect_data
->Digest
.cbData
; ++i
)
384 swprintf( &hash_buffer
[i
* 2], 2, L
"%02X", indirect_data
->Digest
.pbData
[i
] );
386 member
= CryptCATPutMemberInfo( catalog
, (WCHAR
*)file
, hash_buffer
, &subject_guid
,
387 0, size
, (BYTE
*)indirect_data
);
388 ok( !!member
, "Failed to write member, error %u\n", GetLastError() );
390 if (wcsrchr( file
, '\\' )) filepart
= wcsrchr( file
, '\\' ) + 1;
392 ret
= !!CryptCATPutAttrInfo( catalog
, member
, (WCHAR
*)L
"File",
393 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
394 (wcslen( filepart
) + 1) * 2, (BYTE
*)filepart
);
395 ok( ret
, "Failed to write attr, error %u\n", GetLastError() );
397 ret
= !!CryptCATPutAttrInfo( catalog
, member
, (WCHAR
*)L
"OSAttr",
398 CRYPTCAT_ATTR_NAMEASCII
| CRYPTCAT_ATTR_DATAASCII
| CRYPTCAT_ATTR_AUTHENTICATED
,
399 sizeof(L
"2:6.0"), (BYTE
*)L
"2:6.0" );
400 ok( ret
, "Failed to write attr, error %u\n", GetLastError() );
404 static void unload_driver( SC_HANDLE service
)
406 SERVICE_STATUS status
;
408 ControlService( service
, SERVICE_CONTROL_STOP
, &status
);
409 while (status
.dwCurrentState
== SERVICE_STOP_PENDING
)
413 ret
= QueryServiceStatus( service
, &status
);
414 ok( ret
, "QueryServiceStatus failed: %u\n", GetLastError() );
416 ok( status
.dwCurrentState
== SERVICE_STOPPED
, "expected SERVICE_STOPPED, got %d\n", status
.dwCurrentState
);
418 DeleteService( service
);
419 CloseServiceHandle( service
);
422 static void pnp_driver_stop(void)
424 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
425 WCHAR path
[MAX_PATH
], dest
[MAX_PATH
], *filepart
;
426 SC_HANDLE manager
, service
;
433 set
= SetupDiCreateDeviceInfoList( NULL
, NULL
);
434 ok( set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %u\n", GetLastError() );
436 ret
= SetupDiOpenDeviceInfoW( set
, L
"root\\winetest\\0", NULL
, 0, &device
);
437 if (!ret
&& GetLastError() == ERROR_NO_SUCH_DEVINST
)
439 ret
= SetupDiDestroyDeviceInfoList( set
);
440 ok( ret
, "failed to destroy set, error %u\n", GetLastError() );
443 ok( ret
, "failed to open device, error %u\n", GetLastError() );
445 ret
= SetupDiCallClassInstaller( DIF_REMOVE
, set
, &device
);
446 ok( ret
, "failed to remove device, error %u\n", GetLastError() );
448 file
= CreateFileW( L
"\\\\?\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0,
449 NULL
, OPEN_EXISTING
, 0, NULL
);
450 ok( file
== INVALID_HANDLE_VALUE
, "expected failure\n" );
451 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %u\n", GetLastError() );
453 ret
= SetupDiDestroyDeviceInfoList( set
);
454 ok( ret
, "failed to destroy set, error %u\n", GetLastError() );
456 /* Windows stops the service but does not delete it. */
457 manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_CONNECT
);
458 ok( !!manager
, "failed to open service manager, error %u\n", GetLastError() );
460 service
= OpenServiceW( manager
, L
"winetest", SERVICE_STOP
| DELETE
);
461 if (service
) unload_driver( service
);
462 else ok( GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "got error %u\n", GetLastError() );
464 CloseServiceHandle( manager
);
466 SetFilePointer( okfile
, 0, NULL
, FILE_BEGIN
);
469 ReadFile( okfile
, buffer
, sizeof(buffer
), &size
, NULL
);
470 printf( "%.*s", size
, buffer
);
471 } while (size
== sizeof(buffer
));
472 SetFilePointer( okfile
, 0, NULL
, FILE_BEGIN
);
473 SetEndOfFile( okfile
);
475 winetest_add_failures( InterlockedExchange( &test_data
->failures
, 0 ) );
476 winetest_add_failures( InterlockedExchange( &test_data
->todo_failures
, 0 ) );
478 GetFullPathNameW( L
"winetest.inf", ARRAY_SIZE(path
), path
, NULL
);
479 ret
= SetupCopyOEMInfW( path
, NULL
, 0, 0, dest
, ARRAY_SIZE(dest
), NULL
, &filepart
);
480 ok( ret
, "Failed to copy INF, error %u\n", GetLastError() );
481 ret
= SetupUninstallOEMInfW( filepart
, 0, NULL
);
482 ok( ret
, "Failed to uninstall INF, error %u\n", GetLastError() );
484 ret
= DeleteFileW( L
"winetest.cat" );
485 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
486 ret
= DeleteFileW( L
"winetest.inf" );
487 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
488 ret
= DeleteFileW( L
"winetest.sys" );
489 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
490 /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
491 ret
= DeleteFileW( L
"C:/windows/system32/drivers/winetest.sys" );
492 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
, "Failed to delete file, error %u\n", GetLastError() );
495 static BOOL
pnp_driver_start( const WCHAR
*resource
)
497 static const WCHAR hardware_id
[] = L
"test_hardware_id\0";
498 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
499 WCHAR path
[MAX_PATH
], filename
[MAX_PATH
];
500 SC_HANDLE manager
, service
;
501 const CERT_CONTEXT
*cert
;
502 int old_mute_threshold
;
503 BOOL ret
, need_reboot
;
508 old_mute_threshold
= winetest_mute_threshold
;
509 winetest_mute_threshold
= 1;
511 load_resource( resource
, filename
);
512 ret
= MoveFileExW( filename
, L
"winetest.sys", MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
);
513 ok( ret
, "failed to move file, error %u\n", GetLastError() );
515 f
= fopen( "winetest.inf", "w" );
516 ok( !!f
, "failed to open winetest.inf: %s\n", strerror( errno
) );
517 fputs( inf_text
, f
);
520 /* Create the catalog file. */
522 catalog
= CryptCATOpen( (WCHAR
*)L
"winetest.cat", CRYPTCAT_OPEN_CREATENEW
, 0, CRYPTCAT_VERSION_1
, 0 );
523 ok( catalog
!= INVALID_HANDLE_VALUE
, "Failed to create catalog, error %u\n", GetLastError() );
525 add_file_to_catalog( catalog
, L
"winetest.sys" );
526 add_file_to_catalog( catalog
, L
"winetest.inf" );
528 ret
= CryptCATPersistStore( catalog
);
530 ok( ret
, "Failed to write catalog, error %u\n", GetLastError() );
532 ret
= CryptCATClose( catalog
);
533 ok( ret
, "Failed to close catalog, error %u\n", GetLastError() );
535 if (!(cert
= testsign_sign( L
"winetest.cat" )))
537 ret
= DeleteFileW( L
"winetest.cat" );
538 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
539 ret
= DeleteFileW( L
"winetest.inf" );
540 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
541 ret
= DeleteFileW( L
"winetest.sys" );
542 ok( ret
, "Failed to delete file, error %u\n", GetLastError() );
543 winetest_mute_threshold
= old_mute_threshold
;
547 /* Install the driver. */
549 set
= SetupDiCreateDeviceInfoList( NULL
, NULL
);
550 ok( set
!= INVALID_HANDLE_VALUE
, "failed to create device list, error %u\n", GetLastError() );
552 ret
= SetupDiCreateDeviceInfoW( set
, L
"root\\winetest\\0", &GUID_NULL
, NULL
, NULL
, 0, &device
);
553 ok( ret
, "failed to create device, error %#x\n", GetLastError() );
555 ret
= SetupDiSetDeviceRegistryPropertyW( set
, &device
, SPDRP_HARDWAREID
, (const BYTE
*)hardware_id
,
556 sizeof(hardware_id
) );
557 ok( ret
, "failed to create set hardware ID, error %u\n", GetLastError() );
559 ret
= SetupDiCallClassInstaller( DIF_REGISTERDEVICE
, set
, &device
);
560 ok( ret
, "failed to register device, error %u\n", GetLastError() );
562 ret
= SetupDiDestroyDeviceInfoList( set
);
563 ok( ret
, "failed to destroy set, error %u\n", GetLastError() );
565 GetFullPathNameW( L
"winetest.inf", ARRAY_SIZE(path
), path
, NULL
);
567 ret
= UpdateDriverForPlugAndPlayDevicesW( NULL
, hardware_id
, path
, INSTALLFLAG_FORCE
, &need_reboot
);
568 ok( ret
, "failed to install device, error %u\n", GetLastError() );
569 ok( !need_reboot
, "expected no reboot necessary\n" );
571 testsign_cleanup( cert
);
573 /* Check that the service is created and started. */
574 manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_CONNECT
);
575 ok( !!manager
, "failed to open service manager, error %u\n", GetLastError() );
577 service
= OpenServiceW( manager
, L
"winetest", SERVICE_START
);
578 ok( !!service
, "failed to open service, error %u\n", GetLastError() );
580 ret
= StartServiceW( service
, 0, NULL
);
581 ok( !ret
, "service didn't start automatically\n" );
582 if (!ret
&& GetLastError() != ERROR_SERVICE_ALREADY_RUNNING
)
584 /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */
585 ok( GetLastError() == ERROR_DRIVER_BLOCKED
|| GetLastError() == ERROR_INVALID_IMAGE_HASH
,
586 "unexpected error %u\n", GetLastError() );
587 win_skip( "Failed to start service; probably your machine doesn't accept unsigned drivers.\n" );
590 CloseServiceHandle( service
);
591 CloseServiceHandle( manager
);
593 winetest_mute_threshold
= old_mute_threshold
;
594 return ret
|| GetLastError() == ERROR_SERVICE_ALREADY_RUNNING
;
597 #define check_member_( file, line, val, exp, fmt, member ) \
598 ok_(file, line)( (val).member == (exp).member, "got " #member " " fmt "\n", (val).member )
599 #define check_member( val, exp, fmt, member ) \
600 check_member_( __FILE__, __LINE__, val, exp, fmt, member )
602 #define check_member_guid_( file, line, val, exp, member ) \
603 ok_(file, line)( IsEqualGUID( &(val).member, &(exp).member ), "got " #member " %s\n", debugstr_guid(&(val).member) )
604 #define check_member_guid( val, exp, member ) \
605 check_member_guid_( __FILE__, __LINE__, val, exp, member )
607 #define check_member_wstr_( file, line, val, exp, member ) \
608 ok_(file, line)( !wcscmp( (val).member, (exp).member ), "got " #member " %s\n", debugstr_w((val).member) )
609 #define check_member_wstr( val, exp, member ) \
610 check_member_wstr_( __FILE__, __LINE__, val, exp, member )
612 #define check_hidp_caps( a, b ) check_hidp_caps_( __LINE__, a, b )
613 static inline void check_hidp_caps_( int line
, HIDP_CAPS
*caps
, const HIDP_CAPS
*exp
)
615 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Usage
);
616 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
617 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", InputReportByteLength
);
618 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", OutputReportByteLength
);
619 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", FeatureReportByteLength
);
620 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberLinkCollectionNodes
);
621 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputButtonCaps
);
622 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputValueCaps
);
623 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberInputDataIndices
);
624 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputButtonCaps
);
625 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputValueCaps
);
626 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberOutputDataIndices
);
627 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureButtonCaps
);
628 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureValueCaps
);
629 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NumberFeatureDataIndices
);
632 #define check_hidp_link_collection_node( a, b ) check_hidp_link_collection_node_( __LINE__, a, b )
633 static inline void check_hidp_link_collection_node_( int line
, HIDP_LINK_COLLECTION_NODE
*node
,
634 const HIDP_LINK_COLLECTION_NODE
*exp
)
636 check_member_( __FILE__
, line
, *node
, *exp
, "%04x", LinkUsage
);
637 check_member_( __FILE__
, line
, *node
, *exp
, "%04x", LinkUsagePage
);
638 check_member_( __FILE__
, line
, *node
, *exp
, "%d", Parent
);
639 check_member_( __FILE__
, line
, *node
, *exp
, "%d", NumberOfChildren
);
640 check_member_( __FILE__
, line
, *node
, *exp
, "%d", NextSibling
);
641 check_member_( __FILE__
, line
, *node
, *exp
, "%d", FirstChild
);
642 check_member_( __FILE__
, line
, *node
, *exp
, "%d", CollectionType
);
643 check_member_( __FILE__
, line
, *node
, *exp
, "%d", IsAlias
);
646 #define check_hidp_button_caps( a, b ) check_hidp_button_caps_( __LINE__, a, b )
647 static inline void check_hidp_button_caps_( int line
, HIDP_BUTTON_CAPS
*caps
, const HIDP_BUTTON_CAPS
*exp
)
649 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
650 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
651 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
652 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitField
);
653 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
654 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", LinkUsage
);
655 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", LinkUsagePage
);
656 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
657 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
658 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
659 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
661 if (!caps
->IsRange
&& !exp
->IsRange
)
663 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
664 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
666 else if (caps
->IsRange
&& exp
->IsRange
)
668 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
669 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
670 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
671 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
674 if (!caps
->IsRange
&& !exp
->IsRange
)
675 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
676 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
678 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
679 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
682 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
683 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
684 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
686 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
687 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
691 #define check_hidp_value_caps( a, b ) check_hidp_value_caps_( __LINE__, a, b )
692 static inline void check_hidp_value_caps_( int line
, HIDP_VALUE_CAPS
*caps
, const HIDP_VALUE_CAPS
*exp
)
694 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", UsagePage
);
695 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportID
);
696 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAlias
);
697 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitField
);
698 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkCollection
);
699 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkUsage
);
700 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LinkUsagePage
);
701 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsRange
);
702 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsStringRange
);
703 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsDesignatorRange
);
704 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", IsAbsolute
);
706 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", HasNull
);
707 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", BitSize
);
708 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", ReportCount
);
709 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", UnitsExp
);
710 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Units
);
711 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LogicalMin
);
712 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", LogicalMax
);
713 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", PhysicalMin
);
714 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", PhysicalMax
);
716 if (!caps
->IsRange
&& !exp
->IsRange
)
718 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", NotRange
.Usage
);
719 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DataIndex
);
721 else if (caps
->IsRange
&& exp
->IsRange
)
723 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMin
);
724 check_member_( __FILE__
, line
, *caps
, *exp
, "%04x", Range
.UsageMax
);
725 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMin
);
726 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DataIndexMax
);
729 if (!caps
->IsRange
&& !exp
->IsRange
)
730 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.StringIndex
);
731 else if (caps
->IsStringRange
&& exp
->IsStringRange
)
733 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMin
);
734 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.StringMax
);
737 if (!caps
->IsDesignatorRange
&& !exp
->IsDesignatorRange
)
738 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", NotRange
.DesignatorIndex
);
739 else if (caps
->IsDesignatorRange
&& exp
->IsDesignatorRange
)
741 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMin
);
742 check_member_( __FILE__
, line
, *caps
, *exp
, "%d", Range
.DesignatorMax
);
746 #define sync_ioctl( a, b, c, d, e, f, g ) sync_ioctl_( __LINE__, a, b, c, d, e, f, g )
747 static BOOL
sync_ioctl_( int line
, HANDLE file
, DWORD code
, void *in_buf
, DWORD in_len
, void *out_buf
, DWORD
*ret_len
, DWORD timeout
)
749 DWORD res
, out_len
= ret_len
? *ret_len
: 0;
750 OVERLAPPED ovl
= {0};
753 ovl
.hEvent
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
754 ret
= DeviceIoControl( file
, code
, in_buf
, in_len
, out_buf
, out_len
, &out_len
, &ovl
);
755 if (!ret
&& GetLastError() == ERROR_IO_PENDING
)
757 res
= WaitForSingleObject( ovl
.hEvent
, timeout
);
758 ok_(__FILE__
, line
)( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
759 ret
= GetOverlappedResult( file
, &ovl
, &out_len
, FALSE
);
760 ok_(__FILE__
, line
)( ret
, "GetOverlappedResult returned %u\n", GetLastError() );
762 CloseHandle( ovl
.hEvent
);
764 if (ret_len
) *ret_len
= out_len
;
768 #define set_hid_expect( a, b, c ) set_hid_expect_( __LINE__, a, b, c )
769 static void set_hid_expect_( int line
, HANDLE file
, struct hid_expect
*expect
, DWORD expect_size
)
771 const char *source_file
;
775 source_file
= strrchr( __FILE__
, '/' );
776 if (!source_file
) source_file
= strrchr( __FILE__
, '\\' );
777 if (!source_file
) source_file
= __FILE__
;
780 for (i
= 0; i
< expect_size
/ sizeof(struct hid_expect
); ++i
)
781 snprintf( expect
[i
].context
, ARRAY_SIZE(expect
[i
].context
), "%s:%d", source_file
, line
);
783 ret
= sync_ioctl_( line
, file
, IOCTL_WINETEST_HID_SET_EXPECT
, expect
, expect_size
, NULL
, 0, INFINITE
);
784 ok_(__FILE__
, line
)( ret
, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u\n", GetLastError() );
787 #define wait_hid_expect( a, b ) wait_hid_expect_( __LINE__, a, b )
788 static void wait_hid_expect_( int line
, HANDLE file
, DWORD timeout
)
790 BOOL ret
= sync_ioctl_( line
, file
, IOCTL_WINETEST_HID_WAIT_EXPECT
, NULL
, 0, NULL
, 0, timeout
);
791 ok_(__FILE__
, line
)( ret
, "IOCTL_WINETEST_HID_WAIT_EXPECT failed, last error %u\n", GetLastError() );
793 set_hid_expect_( line
, file
, NULL
, 0 );
796 #define send_hid_input( a, b, c ) send_hid_input_( __LINE__, a, b, c )
797 static void send_hid_input_( int line
, HANDLE file
, struct hid_expect
*expect
, DWORD expect_size
)
799 const char *source_file
;
803 source_file
= strrchr( __FILE__
, '/' );
804 if (!source_file
) source_file
= strrchr( __FILE__
, '\\' );
805 if (!source_file
) source_file
= __FILE__
;
808 for (i
= 0; i
< expect_size
/ sizeof(struct hid_expect
); ++i
)
809 snprintf( expect
[i
].context
, ARRAY_SIZE(expect
[i
].context
), "%s:%d", source_file
, line
);
811 ret
= sync_ioctl( file
, IOCTL_WINETEST_HID_SEND_INPUT
, expect
, expect_size
, NULL
, 0, INFINITE
);
812 ok( ret
, "IOCTL_WINETEST_HID_SEND_INPUT failed, last error %u\n", GetLastError() );
815 static void test_hidp_get_input( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
817 struct hid_expect expect
[] =
820 .code
= IOCTL_HID_GET_INPUT_REPORT
,
821 .report_id
= report_id
,
822 .report_len
= report_len
- (report_id
? 0 : 1),
823 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,2},
825 .ret_status
= STATUS_SUCCESS
,
828 .code
= IOCTL_HID_GET_INPUT_REPORT
,
829 .report_id
= report_id
,
830 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
831 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,1},
833 .ret_status
= STATUS_SUCCESS
,
837 char buffer
[200], report
[200];
842 memset( report
, 0xcd, sizeof(report
) );
843 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed
, report
, report_len
);
844 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
846 SetLastError( 0xdeadbeef );
847 ret
= HidD_GetInputReport( file
, report
, 0 );
848 ok( !ret
, "HidD_GetInputReport succeeded\n" );
849 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetInputReport returned error %u\n", GetLastError() );
851 SetLastError( 0xdeadbeef );
852 ret
= HidD_GetInputReport( file
, report
, report_len
- 1 );
853 ok( !ret
, "HidD_GetInputReport succeeded\n" );
854 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
855 "HidD_GetInputReport returned error %u\n", GetLastError() );
859 struct hid_expect broken_expect
=
861 .code
= IOCTL_HID_GET_INPUT_REPORT
,
863 .report_len
= report_len
- 1,
866 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
867 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
868 0x5a,0x5a,0x5a,0x5a,0x5a,
871 .ret_status
= STATUS_SUCCESS
,
874 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
877 SetLastError( 0xdeadbeef );
878 memset( buffer
, 0x5a, sizeof(buffer
) );
879 ret
= HidD_GetInputReport( file
, buffer
, report_len
);
880 if (report_id
|| broken( !ret
) /* w7u */)
882 ok( !ret
, "HidD_GetInputReport succeeded, last error %u\n", GetLastError() );
883 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
884 "HidD_GetInputReport returned error %u\n", GetLastError() );
888 ok( ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError() );
889 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
892 set_hid_expect( file
, expect
, sizeof(expect
) );
894 SetLastError( 0xdeadbeef );
895 ret
= HidD_GetInputReport( file
, report
, report_len
);
896 ok( ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError() );
897 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
899 SetLastError( 0xdeadbeef );
900 length
= report_len
* 2;
901 ret
= sync_ioctl( file
, IOCTL_HID_GET_INPUT_REPORT
, NULL
, 0, report
, &length
, INFINITE
);
902 ok( ret
, "IOCTL_HID_GET_INPUT_REPORT failed, last error %u\n", GetLastError() );
903 ok( length
== 3, "got length %u, expected 3\n", length
);
904 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
906 set_hid_expect( file
, NULL
, 0 );
909 static void test_hidp_get_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
911 struct hid_expect expect
[] =
914 .code
= IOCTL_HID_GET_FEATURE
,
915 .report_id
= report_id
,
916 .report_len
= report_len
- (report_id
? 0 : 1),
917 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
919 .ret_status
= STATUS_SUCCESS
,
922 .code
= IOCTL_HID_GET_FEATURE
,
923 .report_id
= report_id
,
924 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
925 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
927 .ret_status
= STATUS_SUCCESS
,
931 char buffer
[200], report
[200];
936 memset( report
, 0xcd, sizeof(report
) );
937 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
938 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
940 SetLastError( 0xdeadbeef );
941 ret
= HidD_GetFeature( file
, report
, 0 );
942 ok( !ret
, "HidD_GetFeature succeeded\n" );
943 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetFeature returned error %u\n", GetLastError() );
945 SetLastError( 0xdeadbeef );
946 ret
= HidD_GetFeature( file
, report
, report_len
- 1 );
947 ok( !ret
, "HidD_GetFeature succeeded\n" );
948 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
949 "HidD_GetFeature returned error %u\n", GetLastError() );
953 struct hid_expect broken_expect
=
955 .code
= IOCTL_HID_GET_FEATURE
,
957 .report_len
= report_len
- 1,
960 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
961 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
962 0x5a,0x5a,0x5a,0x5a,0x5a,
965 .ret_status
= STATUS_SUCCESS
,
968 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
971 SetLastError( 0xdeadbeef );
972 memset( buffer
, 0x5a, sizeof(buffer
) );
973 ret
= HidD_GetFeature( file
, buffer
, report_len
);
974 if (report_id
|| broken( !ret
))
976 ok( !ret
, "HidD_GetFeature succeeded, last error %u\n", GetLastError() );
977 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
978 "HidD_GetFeature returned error %u\n", GetLastError() );
982 ok( ret
, "HidD_GetFeature failed, last error %u\n", GetLastError() );
983 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
986 set_hid_expect( file
, expect
, sizeof(expect
) );
988 SetLastError( 0xdeadbeef );
989 ret
= HidD_GetFeature( file
, report
, report_len
);
990 ok( ret
, "HidD_GetFeature failed, last error %u\n", GetLastError() );
991 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
993 length
= report_len
* 2;
994 SetLastError( 0xdeadbeef );
995 ret
= sync_ioctl( file
, IOCTL_HID_GET_FEATURE
, NULL
, 0, report
, &length
, INFINITE
);
996 ok( ret
, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError() );
997 ok( length
== 3, "got length %u, expected 3\n", length
);
998 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
1000 set_hid_expect( file
, NULL
, 0 );
1003 static void test_hidp_set_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1005 struct hid_expect expect
[] =
1008 .code
= IOCTL_HID_SET_FEATURE
,
1009 .report_id
= report_id
,
1010 .report_len
= report_len
- (report_id
? 0 : 1),
1011 .report_buf
= {report_id
},
1013 .ret_status
= STATUS_SUCCESS
,
1016 .code
= IOCTL_HID_SET_FEATURE
,
1017 .report_id
= report_id
,
1018 .report_len
= report_len
- (report_id
? 0 : 1),
1021 report_id
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1022 0,0,0,0,0,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
1023 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
1026 .ret_status
= STATUS_SUCCESS
,
1029 char buffer
[200], report
[200];
1034 memset( report
, 0xcd, sizeof(report
) );
1035 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
1036 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1038 SetLastError( 0xdeadbeef );
1039 ret
= HidD_SetFeature( file
, report
, 0 );
1040 ok( !ret
, "HidD_SetFeature succeeded\n" );
1041 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetFeature returned error %u\n", GetLastError() );
1043 SetLastError( 0xdeadbeef );
1044 ret
= HidD_SetFeature( file
, report
, report_len
- 1 );
1045 ok( !ret
, "HidD_SetFeature succeeded\n" );
1046 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1047 "HidD_SetFeature returned error %u\n", GetLastError() );
1051 struct hid_expect broken_expect
=
1053 .code
= IOCTL_HID_SET_FEATURE
,
1055 .report_len
= report_len
- 1,
1058 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1059 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1060 0x5a,0x5a,0x5a,0x5a,0x5a,
1063 .ret_status
= STATUS_SUCCESS
,
1066 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1069 SetLastError( 0xdeadbeef );
1070 memset( buffer
, 0x5a, sizeof(buffer
) );
1071 ret
= HidD_SetFeature( file
, buffer
, report_len
);
1072 if (report_id
|| broken( !ret
))
1074 ok( !ret
, "HidD_SetFeature succeeded, last error %u\n", GetLastError() );
1075 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1076 "HidD_SetFeature returned error %u\n", GetLastError() );
1080 ok( ret
, "HidD_SetFeature failed, last error %u\n", GetLastError() );
1083 set_hid_expect( file
, expect
, sizeof(expect
) );
1085 SetLastError( 0xdeadbeef );
1086 ret
= HidD_SetFeature( file
, report
, report_len
);
1087 ok( ret
, "HidD_SetFeature failed, last error %u\n", GetLastError() );
1089 length
= report_len
* 2;
1090 SetLastError( 0xdeadbeef );
1091 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, NULL
, 0, report
, &length
, INFINITE
);
1092 ok( !ret
, "IOCTL_HID_SET_FEATURE succeeded\n" );
1093 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_FEATURE returned error %u\n",
1096 SetLastError( 0xdeadbeef );
1097 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, report
, report_len
* 2, NULL
, &length
, INFINITE
);
1098 ok( ret
, "IOCTL_HID_SET_FEATURE failed, last error %u\n", GetLastError() );
1099 ok( length
== 3, "got length %u, expected 3\n", length
);
1101 set_hid_expect( file
, NULL
, 0 );
1104 static void test_hidp_set_output( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1106 struct hid_expect expect
[] =
1109 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1110 .report_id
= report_id
,
1111 .report_len
= report_len
- (report_id
? 0 : 1),
1112 .report_buf
= {report_id
},
1114 .ret_status
= STATUS_SUCCESS
,
1117 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1118 .report_id
= report_id
,
1119 .report_len
= report_len
- (report_id
? 0 : 1),
1120 .report_buf
= {report_id
,0,0xcd,0xcd,0xcd},
1122 .ret_status
= STATUS_SUCCESS
,
1126 char buffer
[200], report
[200];
1131 memset( report
, 0xcd, sizeof(report
) );
1132 status
= HidP_InitializeReportForID( HidP_Output
, report_id
, preparsed
, report
, report_len
);
1133 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1134 memset( report
, 0, report_len
);
1135 report
[0] = report_id
;
1137 SetLastError( 0xdeadbeef );
1138 ret
= HidD_SetOutputReport( file
, report
, 0 );
1139 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1140 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetOutputReport returned error %u\n",
1143 SetLastError( 0xdeadbeef );
1144 ret
= HidD_SetOutputReport( file
, report
, report_len
- 1 );
1145 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1146 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1147 "HidD_SetOutputReport returned error %u\n", GetLastError() );
1151 struct hid_expect broken_expect
=
1153 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1155 .report_len
= report_len
- 1,
1156 .report_buf
= {0x5a,0x5a},
1158 .ret_status
= STATUS_SUCCESS
,
1161 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1164 SetLastError( 0xdeadbeef );
1165 memset( buffer
, 0x5a, sizeof(buffer
) );
1166 ret
= HidD_SetOutputReport( file
, buffer
, report_len
);
1167 if (report_id
|| broken( !ret
))
1169 ok( !ret
, "HidD_SetOutputReport succeeded, last error %u\n", GetLastError() );
1170 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1171 "HidD_SetOutputReport returned error %u\n", GetLastError() );
1175 ok( ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError() );
1178 set_hid_expect( file
, expect
, sizeof(expect
) );
1180 SetLastError( 0xdeadbeef );
1181 ret
= HidD_SetOutputReport( file
, report
, report_len
);
1182 ok( ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError() );
1184 length
= report_len
* 2;
1185 SetLastError( 0xdeadbeef );
1186 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, NULL
, 0, report
, &length
, INFINITE
);
1187 ok( !ret
, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n" );
1188 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
,
1189 "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError() );
1191 SetLastError( 0xdeadbeef );
1192 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, report
, report_len
* 2, NULL
, &length
, INFINITE
);
1193 ok( ret
, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError() );
1194 ok( length
== 3, "got length %u, expected 3\n", length
);
1196 set_hid_expect( file
, NULL
, 0 );
1199 static void test_write_file( HANDLE file
, int report_id
, ULONG report_len
)
1201 struct hid_expect expect
=
1203 .code
= IOCTL_HID_WRITE_REPORT
,
1204 .report_id
= report_id
,
1205 .report_len
= report_len
- (report_id
? 0 : 1),
1206 .report_buf
= {report_id
? report_id
: 0xcd,0xcd,0xcd,0xcd,0xcd},
1208 .ret_status
= STATUS_SUCCESS
,
1215 SetLastError( 0xdeadbeef );
1216 ret
= WriteFile( file
, report
, 0, &length
, NULL
);
1217 ok( !ret
, "WriteFile succeeded\n" );
1218 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "WriteFile returned error %u\n", GetLastError() );
1219 ok( length
== 0, "WriteFile returned %x\n", length
);
1220 SetLastError( 0xdeadbeef );
1221 ret
= WriteFile( file
, report
, report_len
- 1, &length
, NULL
);
1222 ok( !ret
, "WriteFile succeeded\n" );
1223 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_USER_BUFFER
,
1224 "WriteFile returned error %u\n", GetLastError() );
1225 ok( length
== 0, "WriteFile returned %x\n", length
);
1227 set_hid_expect( file
, &expect
, sizeof(expect
) );
1229 memset( report
, 0xcd, sizeof(report
) );
1231 SetLastError( 0xdeadbeef );
1232 ret
= WriteFile( file
, report
, report_len
* 2, &length
, NULL
);
1233 if (report_id
|| broken( !ret
) /* w7u */)
1235 ok( !ret
, "WriteFile succeeded\n" );
1236 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "WriteFile returned error %u\n", GetLastError() );
1237 ok( length
== 0, "WriteFile wrote %u\n", length
);
1238 SetLastError( 0xdeadbeef );
1239 report
[0] = report_id
;
1240 ret
= WriteFile( file
, report
, report_len
, &length
, NULL
);
1245 ok( ret
, "WriteFile failed, last error %u\n", GetLastError() );
1246 ok( length
== 2, "WriteFile wrote %u\n", length
);
1250 ok( ret
, "WriteFile failed, last error %u\n", GetLastError() );
1251 ok( length
== 3, "WriteFile wrote %u\n", length
);
1254 set_hid_expect( file
, NULL
, 0 );
1257 static void test_hidp( HANDLE file
, HANDLE async_file
, int report_id
, BOOL polled
, const HIDP_CAPS
*expect_caps
)
1259 const HIDP_BUTTON_CAPS expect_button_caps
[] =
1262 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1263 .ReportID
= report_id
,
1265 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1266 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1267 .LinkCollection
= 1,
1270 .Range
.UsageMin
= 1,
1271 .Range
.UsageMax
= 8,
1272 .Range
.DataIndexMin
= 2,
1273 .Range
.DataIndexMax
= 9,
1276 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1277 .ReportID
= report_id
,
1279 .LinkCollection
= 1,
1280 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1281 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1284 .Range
.UsageMin
= 0x18,
1285 .Range
.UsageMax
= 0x1f,
1286 .Range
.DataIndexMin
= 10,
1287 .Range
.DataIndexMax
= 17,
1290 .UsagePage
= HID_USAGE_PAGE_KEYBOARD
,
1291 .ReportID
= report_id
,
1293 .LinkCollection
= 1,
1294 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1295 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1297 .IsAbsolute
= FALSE
,
1298 .Range
.UsageMin
= 0x8,
1299 .Range
.UsageMax
= 0xf,
1300 .Range
.DataIndexMin
= 18,
1301 .Range
.DataIndexMax
= 25,
1304 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1305 .ReportID
= report_id
,
1307 .LinkCollection
= 1,
1308 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1309 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1312 .NotRange
.Usage
= 0x20,
1313 .NotRange
.Reserved1
= 0x20,
1314 .NotRange
.DataIndex
= 26,
1315 .NotRange
.Reserved4
= 26,
1318 const HIDP_VALUE_CAPS expect_value_caps
[] =
1321 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1322 .ReportID
= report_id
,
1324 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1325 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1326 .LinkCollection
= 1,
1332 .NotRange
.Usage
= HID_USAGE_GENERIC_Y
,
1333 .NotRange
.Reserved1
= HID_USAGE_GENERIC_Y
,
1336 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1337 .ReportID
= report_id
,
1339 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1340 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1341 .LinkCollection
= 1,
1347 .NotRange
.Usage
= HID_USAGE_GENERIC_X
,
1348 .NotRange
.Reserved1
= HID_USAGE_GENERIC_X
,
1349 .NotRange
.DataIndex
= 1,
1350 .NotRange
.Reserved4
= 1,
1353 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1354 .ReportID
= report_id
,
1356 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1357 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1358 .LinkCollection
= 1,
1363 .Range
.UsageMin
= 0x21,
1364 .Range
.UsageMax
= 0x22,
1365 .Range
.DataIndexMin
= 27,
1366 .Range
.DataIndexMax
= 28,
1369 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1370 .ReportID
= report_id
,
1372 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1373 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1374 .LinkCollection
= 1,
1380 .NotRange
.Usage
= HID_USAGE_GENERIC_HATSWITCH
,
1381 .NotRange
.Reserved1
= HID_USAGE_GENERIC_HATSWITCH
,
1382 .NotRange
.DataIndex
= 29,
1383 .NotRange
.Reserved4
= 29,
1386 static const HIDP_LINK_COLLECTION_NODE expect_collections
[] =
1389 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1390 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1391 .CollectionType
= 1,
1392 .NumberOfChildren
= 7,
1396 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1397 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1398 .CollectionType
= 2,
1401 static const HIDP_DATA expect_data
[] =
1403 { .DataIndex
= 0, },
1404 { .DataIndex
= 1, },
1405 { .DataIndex
= 5, .RawValue
= 1, },
1406 { .DataIndex
= 7, .RawValue
= 1, },
1407 { .DataIndex
= 19, .RawValue
= 1, },
1408 { .DataIndex
= 21, .RawValue
= 1, },
1409 { .DataIndex
= 30, },
1410 { .DataIndex
= 31, },
1411 { .DataIndex
= 32, .RawValue
= 0xfeedcafe, },
1412 { .DataIndex
= 37, .RawValue
= 1, },
1413 { .DataIndex
= 39, .RawValue
= 1, },
1416 OVERLAPPED overlapped
= {0}, overlapped2
= {0};
1417 HIDP_LINK_COLLECTION_NODE collections
[16];
1418 PHIDP_PREPARSED_DATA preparsed_data
;
1419 USAGE_AND_PAGE usage_and_pages
[16];
1420 HIDP_BUTTON_CAPS button_caps
[32];
1421 HIDP_VALUE_CAPS value_caps
[16];
1422 char buffer
[200], report
[200];
1423 DWORD collection_count
;
1424 DWORD waveform_list
;
1434 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
1435 ok( ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
1437 memset( buffer
, 0, sizeof(buffer
) );
1438 status
= HidP_GetCaps( (PHIDP_PREPARSED_DATA
)buffer
, &caps
);
1439 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetCaps returned %#x\n", status
);
1440 status
= HidP_GetCaps( preparsed_data
, &caps
);
1441 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetCaps returned %#x\n", status
);
1442 check_hidp_caps( &caps
, expect_caps
);
1444 collection_count
= 0;
1445 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1446 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1447 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1448 "got %d collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1449 collection_count
= ARRAY_SIZE(collections
);
1450 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, (PHIDP_PREPARSED_DATA
)buffer
);
1451 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1452 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1453 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1454 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1455 "got %d collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1457 for (i
= 0; i
< ARRAY_SIZE(expect_collections
); ++i
)
1459 winetest_push_context( "collections[%d]", i
);
1460 check_hidp_link_collection_node( &collections
[i
], &expect_collections
[i
] );
1461 winetest_pop_context();
1464 count
= ARRAY_SIZE(button_caps
);
1465 status
= HidP_GetButtonCaps( HidP_Output
, button_caps
, &count
, preparsed_data
);
1466 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetButtonCaps returned %#x\n", status
);
1467 status
= HidP_GetButtonCaps( HidP_Feature
+ 1, button_caps
, &count
, preparsed_data
);
1468 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetButtonCaps returned %#x\n", status
);
1470 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1471 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetButtonCaps returned %#x\n", status
);
1472 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1473 count
, caps
.NumberInputButtonCaps
);
1474 count
= ARRAY_SIZE(button_caps
);
1475 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1476 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetButtonCaps returned %#x\n", status
);
1477 memset( button_caps
, 0, sizeof(button_caps
) );
1478 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1479 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetButtonCaps returned %#x\n", status
);
1480 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1481 count
, caps
.NumberInputButtonCaps
);
1483 for (i
= 0; i
< ARRAY_SIZE(expect_button_caps
); ++i
)
1485 winetest_push_context( "button_caps[%d]", i
);
1486 check_hidp_button_caps( &button_caps
[i
], &expect_button_caps
[i
] );
1487 winetest_pop_context();
1490 count
= ARRAY_SIZE(button_caps
) - 1;
1491 status
= HidP_GetSpecificButtonCaps( HidP_Output
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1492 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1493 status
= HidP_GetSpecificButtonCaps( HidP_Feature
+ 1, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1494 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1496 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1497 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1498 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1499 count
, caps
.NumberInputButtonCaps
);
1500 count
= ARRAY_SIZE(button_caps
) - 1;
1501 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1502 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1504 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
+ 1, &count
, preparsed_data
);
1505 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1506 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1507 count
, caps
.NumberInputButtonCaps
);
1508 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1510 status
= HidP_GetSpecificButtonCaps( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, 5, button_caps
+ 1,
1511 &count
, preparsed_data
);
1512 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1513 ok( count
== 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 1 );
1514 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1517 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0xfffe, 0, 0, button_caps
, &count
, preparsed_data
);
1518 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1519 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1521 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0xfffe, 0, button_caps
, &count
, preparsed_data
);
1522 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1523 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1525 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0xfffe, button_caps
, &count
, preparsed_data
);
1526 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1527 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1529 count
= ARRAY_SIZE(value_caps
);
1530 status
= HidP_GetValueCaps( HidP_Output
, value_caps
, &count
, preparsed_data
);
1531 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetValueCaps returned %#x\n", status
);
1532 status
= HidP_GetValueCaps( HidP_Feature
+ 1, value_caps
, &count
, preparsed_data
);
1533 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetValueCaps returned %#x\n", status
);
1535 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1536 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetValueCaps returned %#x\n", status
);
1537 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1538 count
, caps
.NumberInputValueCaps
);
1539 count
= ARRAY_SIZE(value_caps
);
1540 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1541 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetValueCaps returned %#x\n", status
);
1542 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1543 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetValueCaps returned %#x\n", status
);
1544 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1545 count
, caps
.NumberInputValueCaps
);
1547 for (i
= 0; i
< ARRAY_SIZE(expect_value_caps
); ++i
)
1549 winetest_push_context( "value_caps[%d]", i
);
1550 check_hidp_value_caps( &value_caps
[i
], &expect_value_caps
[i
] );
1551 winetest_pop_context();
1554 count
= ARRAY_SIZE(value_caps
) - 4;
1555 status
= HidP_GetSpecificValueCaps( HidP_Output
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1556 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1557 status
= HidP_GetSpecificValueCaps( HidP_Feature
+ 1, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1558 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1560 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1561 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1562 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1563 count
, caps
.NumberInputValueCaps
);
1564 count
= ARRAY_SIZE(value_caps
) - 4;
1565 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1566 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1568 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, preparsed_data
);
1569 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1570 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1571 count
, caps
.NumberInputValueCaps
);
1572 check_hidp_value_caps( &value_caps
[4], &value_caps
[0] );
1573 check_hidp_value_caps( &value_caps
[5], &value_caps
[1] );
1574 check_hidp_value_caps( &value_caps
[6], &value_caps
[2] );
1575 check_hidp_value_caps( &value_caps
[7], &value_caps
[3] );
1578 status
= HidP_GetSpecificValueCaps( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1579 value_caps
+ 4, &count
, preparsed_data
);
1580 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1581 ok( count
== 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 1 );
1582 check_hidp_value_caps( &value_caps
[4], &value_caps
[3] );
1585 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0xfffe, 0, 0, value_caps
, &count
, preparsed_data
);
1586 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1587 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1589 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0xfffe, 0, value_caps
, &count
, preparsed_data
);
1590 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1591 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1593 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0xfffe, value_caps
, &count
, preparsed_data
);
1594 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1595 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1597 status
= HidP_InitializeReportForID( HidP_Input
, 0, (PHIDP_PREPARSED_DATA
)buffer
, report
, sizeof(report
) );
1598 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_InitializeReportForID returned %#x\n", status
);
1599 status
= HidP_InitializeReportForID( HidP_Feature
+ 1, 0, preparsed_data
, report
, sizeof(report
) );
1600 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_InitializeReportForID returned %#x\n", status
);
1601 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, sizeof(report
) );
1602 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
1603 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, caps
.InputReportByteLength
+ 1 );
1604 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
1605 status
= HidP_InitializeReportForID( HidP_Input
, 1 - report_id
, preparsed_data
, report
,
1606 caps
.InputReportByteLength
);
1607 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1609 memset( report
, 0xcd, sizeof(report
) );
1610 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
1611 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1613 memset( buffer
, 0xcd, sizeof(buffer
) );
1614 memset( buffer
, 0, caps
.InputReportByteLength
);
1615 buffer
[0] = report_id
;
1616 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1618 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1619 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1620 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValueArray returned %#x\n", status
);
1621 memset( buffer
, 0xcd, sizeof(buffer
) );
1622 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1623 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1624 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
1625 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1626 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1628 ok( status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_SetUsageValueArray returned %#x\n", status
);
1630 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1631 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1632 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_GetUsageValueArray returned %#x\n", status
);
1633 memset( buffer
, 0xcd, sizeof(buffer
) );
1634 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1635 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1636 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
1637 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1638 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1640 ok( status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_GetUsageValueArray returned %#x\n", status
);
1643 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1644 preparsed_data
, report
, caps
.InputReportByteLength
);
1645 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1647 status
= HidP_GetUsageValue( 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_GetUsageValue returned %#x\n", status
);
1650 ok( value
== 0x80, "got value %x, expected %#x\n", value
, 0x80 );
1652 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1653 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1654 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1655 ok( value
== -128, "got value %x, expected %#x\n", value
, -128 );
1658 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1659 preparsed_data
, report
, caps
.InputReportByteLength
);
1660 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1662 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1663 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1664 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1665 ok( value
== 127, "got value %x, expected %#x\n", value
, 127 );
1668 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1669 preparsed_data
, report
, caps
.InputReportByteLength
);
1670 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1672 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1673 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1674 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1675 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1678 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1679 preparsed_data
, report
, caps
.InputReportByteLength
);
1680 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1682 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1683 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1684 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1685 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1687 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, &value
,
1688 preparsed_data
, report
, caps
.InputReportByteLength
);
1689 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
1690 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
1693 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1694 preparsed_data
, report
, caps
.InputReportByteLength
);
1695 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1697 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1698 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1699 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1700 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
1703 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1704 preparsed_data
, report
, caps
.InputReportByteLength
);
1705 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1707 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1708 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1709 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1710 ok( value
== 0x80000000, "got value %x, expected %#x\n", value
, 0x80000000 );
1713 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
, value
,
1714 preparsed_data
, report
, caps
.InputReportByteLength
);
1715 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1717 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
1718 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1719 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1720 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1723 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
, value
,
1724 preparsed_data
, report
, caps
.InputReportByteLength
);
1725 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1727 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1728 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1729 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1730 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1731 status
= HidP_SetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1732 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1733 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1734 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1736 value
= HidP_MaxUsageListLength( HidP_Feature
+ 1, 0, preparsed_data
);
1737 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value
, 0 );
1738 value
= HidP_MaxUsageListLength( HidP_Input
, 0, preparsed_data
);
1739 ok( value
== 50, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value
, 50 );
1740 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1741 ok( value
== 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n",
1743 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_LED
, preparsed_data
);
1744 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n",
1746 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1747 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n",
1749 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_LED
, preparsed_data
);
1750 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n",
1755 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1756 report
, caps
.InputReportByteLength
);
1757 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
1761 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1762 report
, caps
.InputReportByteLength
);
1763 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
1767 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1768 report
, caps
.InputReportByteLength
);
1769 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1773 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
1774 report
, caps
.InputReportByteLength
);
1775 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1777 value
= ARRAY_SIZE(usages
);
1778 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1779 report
, caps
.InputReportByteLength
);
1780 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1781 ok( value
== 0, "got usage count %d, expected %d\n", value
, 2 );
1787 ok( report
[6] == 0, "got report[6] %x expected 0\n", report
[6] );
1788 ok( report
[7] == 0, "got report[7] %x expected 0\n", report
[7] );
1789 memcpy( buffer
, report
, caps
.InputReportByteLength
);
1790 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1791 report
, caps
.InputReportByteLength
);
1792 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsages returned %#x\n", status
);
1795 ok( !memcmp( buffer
, report
, caps
.InputReportByteLength
), "unexpected report data\n" );
1797 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, 1, preparsed_data
, report
,
1798 caps
.InputReportByteLength
);
1799 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1802 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, &value
, preparsed_data
,
1803 report
, caps
.InputReportByteLength
);
1804 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1805 ok( value
== 0xdeadbeef, "got value %x, expected %#x\n", value
, 0xdeadbeef );
1808 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1809 report
, caps
.InputReportByteLength
);
1810 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsages returned %#x\n", status
);
1811 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1812 value
= ARRAY_SIZE(usages
);
1813 memset( usages
, 0xcd, sizeof(usages
) );
1814 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1815 report
, caps
.InputReportByteLength
);
1816 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1817 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1818 ok( usages
[0] == 4, "got usages[0] %x, expected %x\n", usages
[0], 4 );
1819 ok( usages
[1] == 6, "got usages[1] %x, expected %x\n", usages
[1], 6 );
1821 value
= ARRAY_SIZE(usages
);
1822 memset( usages
, 0xcd, sizeof(usages
) );
1823 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
1824 report
, caps
.InputReportByteLength
);
1825 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1826 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1827 ok( usages
[0] == 6, "got usages[0] %x, expected %x\n", usages
[0], 6 );
1828 ok( usages
[1] == 4, "got usages[1] %x, expected %x\n", usages
[1], 4 );
1830 value
= ARRAY_SIZE(usage_and_pages
);
1831 memset( usage_and_pages
, 0xcd, sizeof(usage_and_pages
) );
1832 status
= HidP_GetUsagesEx( HidP_Input
, 0, usage_and_pages
, &value
, preparsed_data
, report
,
1833 caps
.InputReportByteLength
);
1834 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsagesEx returned %#x\n", status
);
1835 ok( value
== 6, "got usage count %d, expected %d\n", value
, 4 );
1836 ok( usage_and_pages
[0].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[0] UsagePage %x, expected %x\n",
1837 usage_and_pages
[0].UsagePage
, HID_USAGE_PAGE_BUTTON
);
1838 ok( usage_and_pages
[1].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[1] UsagePage %x, expected %x\n",
1839 usage_and_pages
[1].UsagePage
, HID_USAGE_PAGE_BUTTON
);
1840 ok( usage_and_pages
[2].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[2] UsagePage %x, expected %x\n",
1841 usage_and_pages
[2].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
1842 ok( usage_and_pages
[3].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[3] UsagePage %x, expected %x\n",
1843 usage_and_pages
[3].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
1844 ok( usage_and_pages
[4].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[4] UsagePage %x, expected %x\n",
1845 usage_and_pages
[4].UsagePage
, HID_USAGE_PAGE_LED
);
1846 ok( usage_and_pages
[5].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[5] UsagePage %x, expected %x\n",
1847 usage_and_pages
[5].UsagePage
, HID_USAGE_PAGE_LED
);
1848 ok( usage_and_pages
[0].Usage
== 4, "got usage_and_pages[0] Usage %x, expected %x\n",
1849 usage_and_pages
[0].Usage
, 4 );
1850 ok( usage_and_pages
[1].Usage
== 6, "got usage_and_pages[1] Usage %x, expected %x\n",
1851 usage_and_pages
[1].Usage
, 6 );
1852 ok( usage_and_pages
[2].Usage
== 9, "got usage_and_pages[2] Usage %x, expected %x\n",
1853 usage_and_pages
[2].Usage
, 9 );
1854 ok( usage_and_pages
[3].Usage
== 11, "got usage_and_pages[3] Usage %x, expected %x\n",
1855 usage_and_pages
[3].Usage
, 11 );
1856 ok( usage_and_pages
[4].Usage
== 6, "got usage_and_pages[4] Usage %x, expected %x\n",
1857 usage_and_pages
[4].Usage
, 6 );
1858 ok( usage_and_pages
[5].Usage
== 4, "got usage_and_pages[5] Usage %x, expected %x\n",
1859 usage_and_pages
[5].Usage
, 4 );
1861 value
= HidP_MaxDataListLength( HidP_Feature
+ 1, preparsed_data
);
1862 ok( value
== 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value
, 0 );
1863 value
= HidP_MaxDataListLength( HidP_Input
, preparsed_data
);
1864 ok( value
== 58, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value
, 58 );
1865 value
= HidP_MaxDataListLength( HidP_Output
, preparsed_data
);
1866 ok( value
== 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value
, 0 );
1867 value
= HidP_MaxDataListLength( HidP_Feature
, preparsed_data
);
1868 ok( value
== 14, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value
, 14 );
1871 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1872 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetData returned %#x\n", status
);
1873 ok( value
== 11, "got data count %d, expected %d\n", value
, 11 );
1874 memset( data
, 0, sizeof(data
) );
1875 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1876 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetData returned %#x\n", status
);
1877 for (i
= 0; i
< ARRAY_SIZE(expect_data
); ++i
)
1879 winetest_push_context( "data[%d]", i
);
1880 check_member( data
[i
], expect_data
[i
], "%d", DataIndex
);
1881 check_member( data
[i
], expect_data
[i
], "%d", RawValue
);
1882 winetest_pop_context();
1885 /* HID nary usage collections are set with 1-based usage index in their declaration order */
1887 memset( report
, 0, caps
.InputReportByteLength
);
1888 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
1889 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1893 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1894 report
, caps
.InputReportByteLength
);
1895 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1896 ok( report
[caps
.InputReportByteLength
- 2] == 3, "unexpected usage index %d, expected 3\n",
1897 report
[caps
.InputReportByteLength
- 2] );
1898 ok( report
[caps
.InputReportByteLength
- 1] == 4, "unexpected usage index %d, expected 4\n",
1899 report
[caps
.InputReportByteLength
- 1] );
1900 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
1901 preparsed_data
, report
, caps
.InputReportByteLength
);
1902 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_UnsetUsages returned %#x\n", status
);
1903 ok( report
[caps
.InputReportByteLength
- 2] == 0, "unexpected usage index %d, expected 0\n",
1904 report
[caps
.InputReportByteLength
- 2] );
1905 ok( report
[caps
.InputReportByteLength
- 1] == 0, "unexpected usage index %d, expected 0\n",
1906 report
[caps
.InputReportByteLength
- 1] );
1907 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
1908 preparsed_data
, report
, caps
.InputReportByteLength
);
1909 ok( status
== HIDP_STATUS_BUTTON_NOT_PRESSED
, "HidP_UnsetUsages returned %#x\n", status
);
1912 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1913 report
, caps
.InputReportByteLength
);
1914 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1915 ok( report
[caps
.InputReportByteLength
- 2] == 1, "unexpected usage index %d, expected 1\n",
1916 report
[caps
.InputReportByteLength
- 2] );
1918 memset( report
, 0xcd, sizeof(report
) );
1919 status
= HidP_InitializeReportForID( HidP_Feature
, 3, preparsed_data
, report
, caps
.FeatureReportByteLength
);
1920 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1922 memset( report
, 0xcd, sizeof(report
) );
1923 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed_data
, report
,
1924 caps
.FeatureReportByteLength
);
1925 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1927 memset( buffer
, 0xcd, sizeof(buffer
) );
1928 memset( buffer
, 0, caps
.FeatureReportByteLength
);
1929 buffer
[0] = report_id
;
1930 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1932 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
1934 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_HAPTICS
) continue;
1935 if (collections
[i
].LinkUsage
== HID_USAGE_HAPTICS_WAVEFORM_LIST
) break;
1937 ok( i
< caps
.NumberLinkCollectionNodes
,
1938 "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n" );
1941 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1942 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, (PHIDP_PREPARSED_DATA
)buffer
,
1943 report
, caps
.FeatureReportByteLength
);
1944 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_SetUsageValue returned %#x\n", status
);
1945 status
= HidP_SetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1946 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1947 caps
.FeatureReportByteLength
);
1948 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_SetUsageValue returned %#x\n", status
);
1949 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1950 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1951 caps
.FeatureReportByteLength
+ 1 );
1952 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_SetUsageValue returned %#x\n", status
);
1953 report
[0] = 1 - report_id
;
1954 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1955 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1956 caps
.FeatureReportByteLength
);
1957 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
1958 "HidP_SetUsageValue returned %#x\n", status
);
1960 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1961 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1962 caps
.FeatureReportByteLength
);
1963 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_SetUsageValue returned %#x\n", status
);
1964 report
[0] = report_id
;
1965 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
,
1966 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1967 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1969 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1970 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1971 caps
.FeatureReportByteLength
);
1972 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1974 memset( buffer
, 0xcd, sizeof(buffer
) );
1975 memset( buffer
, 0, caps
.FeatureReportByteLength
);
1976 buffer
[0] = report_id
;
1977 value
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
1978 memcpy( buffer
+ 1, &value
, 2 );
1979 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1981 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1982 (PHIDP_PREPARSED_DATA
)buffer
, report
, caps
.FeatureReportByteLength
);
1983 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetUsageValue returned %#x\n", status
);
1984 status
= HidP_GetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1985 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1986 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetUsageValue returned %#x\n", status
);
1987 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1988 preparsed_data
, report
, caps
.FeatureReportByteLength
+ 1 );
1989 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_GetUsageValue returned %#x\n", status
);
1990 report
[0] = 1 - report_id
;
1991 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1992 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1993 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
1994 "HidP_GetUsageValue returned %#x\n", status
);
1996 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1997 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1998 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_GetUsageValue returned %#x\n", status
);
1999 report
[0] = report_id
;
2000 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, &value
,
2001 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2002 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#x\n", status
);
2005 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2006 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2007 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2008 ok( value
== HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, "got value %x, expected %#x\n", value
,
2009 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
);
2011 memset( buffer
, 0xff, sizeof(buffer
) );
2012 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2013 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
2014 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2015 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2016 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2017 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
2018 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2019 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#x\n", status
);
2020 ok( !memcmp( report
+ 9, buffer
, 8 ), "unexpected report data\n" );
2022 memset( buffer
, 0, sizeof(buffer
) );
2023 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2024 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
2025 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2026 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2027 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2028 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
2029 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2030 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#x\n", status
);
2031 memset( buffer
+ 16, 0xff, 8 );
2032 ok( !memcmp( buffer
, buffer
+ 16, 16 ), "unexpected report value\n" );
2035 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2036 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2037 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2039 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2040 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2041 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2042 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
2044 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2045 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2046 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2047 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
2050 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2051 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2052 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2054 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2055 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2056 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2057 ok( value
== 0x0003ffff, "got value %x, expected %#x\n", value
, 0x0003ffff );
2060 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2061 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2062 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2064 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2065 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2066 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2067 ok( value
== 0xfff90000, "got value %x, expected %#x\n", value
, 0xfff90000 );
2068 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2069 0x1000, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2070 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2072 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2073 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2074 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2075 ok( value
== 0xfffff518, "got value %x, expected %#x\n", value
, 0xfffff518 );
2076 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2077 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2078 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2080 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2081 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2082 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2083 ok( value
== 0xfffff45e, "got value %x, expected %#x\n", value
, 0xfffff45e );
2084 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2085 0xdead, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2086 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2088 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2089 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2090 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2091 ok( value
== 0xfffffe7d, "got value %x, expected %#x\n", value
, 0xfffffe7d );
2092 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2093 0xbeef, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2094 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2096 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2097 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2098 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2099 ok( value
== 0xfffffd0b, "got value %x, expected %#x\n", value
, 0xfffffd0b );
2101 test_hidp_get_input( file
, report_id
, caps
.InputReportByteLength
, preparsed_data
);
2102 test_hidp_get_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2103 test_hidp_set_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2104 test_hidp_set_output( file
, report_id
, caps
.OutputReportByteLength
, preparsed_data
);
2105 test_write_file( file
, report_id
, caps
.OutputReportByteLength
);
2107 memset( report
, 0xcd, sizeof(report
) );
2108 SetLastError( 0xdeadbeef );
2109 ret
= ReadFile( file
, report
, 0, &value
, NULL
);
2110 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n",
2112 ok( value
== 0, "ReadFile returned %x\n", value
);
2113 SetLastError( 0xdeadbeef );
2114 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
- 1, &value
, NULL
);
2115 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n",
2117 ok( value
== 0, "ReadFile returned %x\n", value
);
2121 struct hid_expect expect
[] =
2124 .code
= IOCTL_HID_READ_REPORT
,
2125 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2126 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0},
2128 .ret_status
= STATUS_SUCCESS
,
2131 .code
= IOCTL_HID_READ_REPORT
,
2132 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2133 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,1},
2135 .ret_status
= STATUS_SUCCESS
,
2139 send_hid_input( file
, expect
, sizeof(expect
) );
2141 memset( report
, 0xcd, sizeof(report
) );
2142 SetLastError( 0xdeadbeef );
2143 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
, &value
, NULL
);
2144 ok( ret
, "ReadFile failed, last error %u\n", GetLastError() );
2145 ok( value
== (report_id
? 3 : 4), "ReadFile returned %x\n", value
);
2146 ok( report
[0] == report_id
, "unexpected report data\n" );
2148 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2149 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2151 /* drain available input reports */
2152 SetLastError( 0xdeadbeef );
2153 while (ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
))
2154 ResetEvent( overlapped
.hEvent
);
2155 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2156 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2157 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2158 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2159 value
, (report_id
? 3 : 4) );
2160 ResetEvent( overlapped
.hEvent
);
2162 memcpy( buffer
, report
, caps
.InputReportByteLength
);
2163 memcpy( buffer
+ caps
.InputReportByteLength
, report
, caps
.InputReportByteLength
);
2165 SetLastError( 0xdeadbeef );
2166 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2167 ok( !ret
, "ReadFile succeeded\n" );
2168 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2170 SetLastError( 0xdeadbeef );
2171 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2172 ok( !ret
, "ReadFile succeeded\n" );
2173 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2175 /* wait for second report to be ready */
2176 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2177 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2178 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2179 value
, (report_id
? 3 : 4) );
2180 /* first report should be ready and the same */
2181 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2182 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2183 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2184 value
, (report_id
? 3 : 4) );
2185 ok( memcmp( report
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
),
2186 "expected different report\n" );
2187 ok( !memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected identical reports\n" );
2190 SetLastError( 0xdeadbeef );
2191 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &value
, sizeof(ULONG
), NULL
, NULL
, INFINITE
);
2192 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2196 SetLastError( 0xdeadbeef );
2197 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2198 ok( !ret
, "ReadFile succeeded\n" );
2199 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2201 SetLastError( 0xdeadbeef );
2202 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2203 ok( !ret
, "ReadFile succeeded\n" );
2204 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2206 /* wait for second report to be ready */
2207 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2208 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2209 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2210 value
, (report_id
? 3 : 4) );
2211 /* first report should be ready and the same */
2212 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2213 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2214 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2215 value
, (report_id
? 3 : 4) );
2216 ok( !memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected identical reports\n" );
2218 CloseHandle( overlapped
.hEvent
);
2219 CloseHandle( overlapped2
.hEvent
);
2223 struct hid_expect expect
[] =
2226 .code
= IOCTL_HID_READ_REPORT
,
2227 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2228 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
2230 .ret_status
= STATUS_SUCCESS
,
2233 .code
= IOCTL_HID_READ_REPORT
,
2234 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2235 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5,0xa5,0xa5},
2236 .ret_length
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2237 .ret_status
= STATUS_SUCCESS
,
2241 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2242 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2244 SetLastError( 0xdeadbeef );
2245 memset( report
, 0, sizeof(report
) );
2246 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2247 ok( !ret
, "ReadFile succeeded\n" );
2248 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2250 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2251 ok( !ret
, "GetOverlappedResult succeeded\n" );
2252 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2254 SetLastError( 0xdeadbeef );
2255 memset( buffer
, 0, sizeof(buffer
) );
2256 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2257 ok( !ret
, "ReadFile succeeded\n" );
2258 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2260 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2261 ok( !ret
, "GetOverlappedResult succeeded\n" );
2262 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2264 memset( report
+ caps
.InputReportByteLength
, 0xa5, 5 );
2265 if (report_id
) report
[caps
.InputReportByteLength
] = report_id
;
2267 send_hid_input( file
, expect
, sizeof(expect
) );
2269 /* first read should be completed */
2270 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2271 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2272 ok( value
== caps
.InputReportByteLength
, "got length %u, expected %u\n", value
, caps
.InputReportByteLength
);
2273 /* second read should still be pending */
2275 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2276 ok( !ret
, "GetOverlappedResult succeeded\n" );
2277 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2279 memset( buffer
+ caps
.InputReportByteLength
, 0x3b, 5 );
2280 if (report_id
) buffer
[caps
.InputReportByteLength
] = report_id
;
2281 memset( expect
[1].report_buf
, 0x3b, 5 );
2282 if (report_id
) expect
[1].report_buf
[0] = report_id
;
2284 send_hid_input( file
, expect
, sizeof(expect
) );
2286 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2287 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2288 ok( value
== caps
.InputReportByteLength
, "got length %u, expected %u\n", value
, caps
.InputReportByteLength
);
2290 off
= report_id
? 0 : 1;
2291 ok( memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected different report\n" );
2292 ok( !memcmp( report
+ off
, report
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2293 "expected identical reports\n" );
2294 ok( !memcmp( buffer
+ off
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2295 "expected identical reports\n" );
2297 CloseHandle( overlapped
.hEvent
);
2298 CloseHandle( overlapped2
.hEvent
);
2301 HidD_FreePreparsedData( preparsed_data
);
2304 static void test_hid_device( DWORD report_id
, DWORD polled
, const HIDP_CAPS
*expect_caps
)
2306 char buffer
[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W
, DevicePath
[MAX_PATH
] )];
2307 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(SP_DEVICE_INTERFACE_DATA
)};
2308 SP_DEVICE_INTERFACE_DETAIL_DATA_W
*iface_detail
= (void *)buffer
;
2309 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
2310 ULONG count
, poll_freq
, out_len
;
2311 HANDLE file
, async_file
;
2312 BOOL ret
, found
= FALSE
;
2313 OBJECT_ATTRIBUTES attr
;
2314 UNICODE_STRING string
;
2320 winetest_push_context( "id %d%s", report_id
, polled
? " poll" : "" );
2322 set
= SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
2323 ok( set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError() );
2325 for (i
= 0; SetupDiEnumDeviceInfo( set
, i
, &device
); ++i
)
2327 ret
= SetupDiEnumDeviceInterfaces( set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
2328 ok( ret
, "failed to get interface, error %#x\n", GetLastError() );
2329 ok( IsEqualGUID( &iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
), "wrong class %s\n",
2330 debugstr_guid( &iface
.InterfaceClassGuid
) );
2331 ok( iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
2333 iface_detail
->cbSize
= sizeof(*iface_detail
);
2334 ret
= SetupDiGetDeviceInterfaceDetailW( set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
2335 ok( ret
, "failed to get interface path, error %#x\n", GetLastError() );
2337 if (wcsstr( iface_detail
->DevicePath
, L
"\\\\?\\hid#winetest#1" ))
2344 SetupDiDestroyDeviceInfoList( set
);
2347 ok( found
, "didn't find device\n" );
2349 file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2350 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
2351 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
2354 SetLastError( 0xdeadbeef );
2355 ret
= HidD_GetNumInputBuffers( file
, &count
);
2356 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2357 ok( count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2359 SetLastError( 0xdeadbeef );
2360 ret
= HidD_SetNumInputBuffers( file
, 1 );
2361 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2362 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n",
2364 SetLastError( 0xdeadbeef );
2365 ret
= HidD_SetNumInputBuffers( file
, 513 );
2366 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2367 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n",
2370 SetLastError( 0xdeadbeef );
2371 ret
= HidD_SetNumInputBuffers( file
, 16 );
2372 ok( ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError() );
2375 SetLastError( 0xdeadbeef );
2376 ret
= HidD_GetNumInputBuffers( file
, &count
);
2377 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2378 ok( count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2380 async_file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2381 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
2382 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
2383 ok( async_file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
2386 SetLastError( 0xdeadbeef );
2387 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2388 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2389 ok( count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2391 SetLastError( 0xdeadbeef );
2392 ret
= HidD_SetNumInputBuffers( async_file
, 2 );
2393 ok( ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError() );
2396 SetLastError( 0xdeadbeef );
2397 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2398 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2399 ok( count
== 2, "HidD_GetNumInputBuffers returned %u\n", count
);
2401 SetLastError( 0xdeadbeef );
2402 ret
= HidD_GetNumInputBuffers( file
, &count
);
2403 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2404 ok( count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2408 out_len
= sizeof(ULONG
);
2409 SetLastError( 0xdeadbeef );
2410 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, INFINITE
);
2411 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2412 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2414 ok( poll_freq
== 5, "got poll_freq %u, expected 5\n", poll_freq
);
2418 SetLastError( 0xdeadbeef );
2419 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2420 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2421 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2425 SetLastError( 0xdeadbeef );
2426 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2427 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2428 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2432 SetLastError( 0xdeadbeef );
2433 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2434 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2435 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2437 out_len
= sizeof(ULONG
);
2438 SetLastError( 0xdeadbeef );
2439 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, INFINITE
);
2440 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2441 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2442 ok( poll_freq
== 10000, "got poll_freq %u, expected 10000\n", poll_freq
);
2446 SetLastError( 0xdeadbeef );
2447 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2448 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2449 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2451 out_len
= sizeof(ULONG
);
2452 SetLastError( 0xdeadbeef );
2453 ret
= sync_ioctl( async_file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, INFINITE
);
2454 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2455 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2456 ok( poll_freq
== 500, "got poll_freq %u, expected 500\n", poll_freq
);
2459 test_hidp( file
, async_file
, report_id
, polled
, expect_caps
);
2461 CloseHandle( async_file
);
2462 CloseHandle( file
);
2464 RtlInitUnicodeString( &string
, L
"\\??\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}" );
2465 InitializeObjectAttributes( &attr
, &string
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
2466 status
= NtOpenFile( &file
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
2468 ok( status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
2470 winetest_pop_context();
2473 static void test_hid_driver( DWORD report_id
, DWORD polled
)
2475 #include "psh_hid_macros.h"
2476 /* Replace REPORT_ID with USAGE_PAGE when id is 0 */
2477 #define REPORT_ID_OR_USAGE_PAGE(size, id, off) SHORT_ITEM_1((id ? 8 : 0), 1, (id + off))
2478 const unsigned char report_desc
[] =
2480 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2481 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2482 COLLECTION(1, Application
),
2483 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2484 COLLECTION(1, Logical
),
2485 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2486 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2487 USAGE(1, HID_USAGE_GENERIC_X
),
2488 USAGE(1, HID_USAGE_GENERIC_Y
),
2489 LOGICAL_MINIMUM(1, -128),
2490 LOGICAL_MAXIMUM(1, 127),
2493 INPUT(1, Data
|Var
|Abs
),
2495 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2496 USAGE_MINIMUM(1, 1),
2497 USAGE_MAXIMUM(1, 8),
2498 LOGICAL_MINIMUM(1, 0),
2499 LOGICAL_MAXIMUM(1, 1),
2502 INPUT(1, Data
|Var
|Abs
),
2504 USAGE_MINIMUM(1, 0x18),
2505 USAGE_MAXIMUM(1, 0x1f),
2506 LOGICAL_MINIMUM(1, 0),
2507 LOGICAL_MAXIMUM(1, 1),
2510 INPUT(1, Cnst
|Var
|Abs
),
2512 INPUT(1, Cnst
|Var
|Abs
),
2513 /* needs to be 8 bit aligned as next has Buff */
2515 USAGE_MINIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8),
2516 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0xf),
2517 LOGICAL_MINIMUM(1, 0),
2518 LOGICAL_MAXIMUM(1, 8),
2521 INPUT(2, Data
|Ary
|Rel
|Wrap
|Lin
|Pref
|Null
|Vol
|Buff
),
2523 /* needs to be 8 bit aligned as previous has Buff */
2525 LOGICAL_MINIMUM(1, 0),
2526 LOGICAL_MAXIMUM(1, 1),
2529 INPUT(1, Data
|Var
|Abs
),
2530 USAGE_MINIMUM(1, 0x21),
2531 USAGE_MAXIMUM(1, 0x22),
2534 INPUT(1, Data
|Var
|Abs
),
2538 INPUT(1, Data
|Var
|Abs
),
2540 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2541 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
2542 LOGICAL_MINIMUM(1, 1),
2543 LOGICAL_MAXIMUM(1, 8),
2546 INPUT(1, Data
|Var
|Abs
),
2548 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2549 USAGE(1, HID_USAGE_GENERIC_Z
),
2550 LOGICAL_MINIMUM(4, 0x00000000),
2551 LOGICAL_MAXIMUM(4, 0x3fffffff),
2552 PHYSICAL_MINIMUM(4, 0x80000000),
2553 PHYSICAL_MAXIMUM(4, 0x7fffffff),
2556 INPUT(1, Data
|Var
|Abs
),
2558 /* reset physical range to its default interpretation */
2559 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2560 USAGE(1, HID_USAGE_GENERIC_RX
),
2561 PHYSICAL_MINIMUM(4, 0),
2562 PHYSICAL_MAXIMUM(4, 0),
2565 INPUT(1, Data
|Var
|Abs
),
2567 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2568 USAGE(1, HID_USAGE_GENERIC_RY
),
2569 LOGICAL_MINIMUM(4, 0x7fff),
2570 LOGICAL_MAXIMUM(4, 0x0000),
2571 PHYSICAL_MINIMUM(4, 0x0000),
2572 PHYSICAL_MAXIMUM(4, 0x7fff),
2575 INPUT(1, Data
|Var
|Abs
),
2578 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2579 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2580 COLLECTION(1, Report
),
2581 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2582 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2583 USAGE_MINIMUM(1, 9),
2584 USAGE_MAXIMUM(1, 10),
2585 LOGICAL_MINIMUM(1, 0),
2586 LOGICAL_MAXIMUM(1, 1),
2589 INPUT(1, Data
|Var
|Abs
),
2592 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2593 USAGE(1, HID_USAGE_LED_GREEN
),
2594 COLLECTION(1, Report
),
2595 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2596 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2605 LOGICAL_MINIMUM(1, 0),
2606 LOGICAL_MAXIMUM(1, 1),
2607 PHYSICAL_MINIMUM(1, 0),
2608 PHYSICAL_MAXIMUM(1, 1),
2611 INPUT(1, Data
|Var
|Abs
),
2613 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8c),
2614 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8d),
2615 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8e),
2616 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8f),
2617 LOGICAL_MINIMUM(1, 1),
2618 LOGICAL_MAXIMUM(1, 16),
2621 INPUT(1, Data
|Ary
|Abs
),
2624 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2625 USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER
),
2626 COLLECTION(1, Logical
),
2627 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2628 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2630 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST
),
2631 COLLECTION(1, NamedArray
),
2632 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2633 USAGE(1, 3), /* HID_USAGE_HAPTICS_WAVEFORM_RUMBLE */
2634 USAGE(1, 4), /* HID_USAGE_HAPTICS_WAVEFORM_BUZZ */
2635 LOGICAL_MINIMUM(2, 0x0000),
2636 LOGICAL_MAXIMUM(2, 0xffff),
2639 FEATURE(1, Data
|Var
|Abs
|Null
),
2642 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2643 USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST
),
2644 COLLECTION(1, NamedArray
),
2645 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2646 USAGE(1, 3), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) */
2647 USAGE(1, 4), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_BUZZ) */
2648 LOGICAL_MINIMUM(2, 0x0000),
2649 LOGICAL_MAXIMUM(2, 0xffff),
2652 FEATURE(1, Data
|Var
|Abs
|Null
),
2655 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2656 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
),
2657 UNIT(2, 0x1001), /* seconds */
2658 UNIT_EXPONENT(1, -3), /* 10^-3 */
2659 LOGICAL_MINIMUM(2, 0x8000),
2660 LOGICAL_MAXIMUM(2, 0x7fff),
2661 PHYSICAL_MINIMUM(4, 0x00000000),
2662 PHYSICAL_MAXIMUM(4, 0xffffffff),
2665 FEATURE(1, Data
|Var
|Abs
),
2666 /* reset global items */
2667 UNIT(1, 0), /* None */
2668 UNIT_EXPONENT(1, 0),
2670 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2671 USAGE(1, HID_USAGE_GENERIC_Z
),
2672 LOGICAL_MINIMUM(4, 0x0000),
2673 LOGICAL_MAXIMUM(4, 0x7fff),
2674 PHYSICAL_MINIMUM(4, 0xfff90000),
2675 PHYSICAL_MAXIMUM(4, 0x0003ffff),
2678 FEATURE(1, Data
|Var
|Abs
),
2681 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2682 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2683 COLLECTION(1, Report
),
2684 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2685 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2686 USAGE_MINIMUM(1, 9),
2687 USAGE_MAXIMUM(1, 10),
2688 LOGICAL_MINIMUM(1, 0),
2689 LOGICAL_MAXIMUM(1, 1),
2690 PHYSICAL_MINIMUM(1, 0),
2691 PHYSICAL_MAXIMUM(1, 1),
2694 FEATURE(1, Data
|Var
|Abs
),
2697 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2698 USAGE(1, HID_USAGE_LED_GREEN
),
2699 COLLECTION(1, Report
),
2700 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2701 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2704 OUTPUT(1, Cnst
|Var
|Abs
),
2707 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2708 USAGE(1, HID_USAGE_LED_RED
),
2709 COLLECTION(1, Report
),
2710 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2711 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2714 OUTPUT(1, Cnst
|Var
|Abs
),
2718 #undef REPORT_ID_OR_USAGE_PAGE
2719 #include "pop_hid_macros.h"
2721 static const HID_DEVICE_ATTRIBUTES attributes
=
2723 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
2725 .ProductID
= 0x0001,
2726 .VersionNumber
= 0x0100,
2728 const HIDP_CAPS caps
=
2730 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
2731 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
2732 .InputReportByteLength
= report_id
? 32 : 33,
2733 .OutputReportByteLength
= report_id
? 2 : 3,
2734 .FeatureReportByteLength
= report_id
? 21 : 22,
2735 .NumberLinkCollectionNodes
= 10,
2736 .NumberInputButtonCaps
= 17,
2737 .NumberInputValueCaps
= 7,
2738 .NumberInputDataIndices
= 47,
2739 .NumberFeatureButtonCaps
= 1,
2740 .NumberFeatureValueCaps
= 6,
2741 .NumberFeatureDataIndices
= 8,
2743 const struct hid_expect expect_in
=
2745 .code
= IOCTL_HID_READ_REPORT
,
2746 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2747 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
2749 .ret_status
= STATUS_SUCCESS
,
2752 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
2756 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
2757 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
2758 SetCurrentDirectoryW( tempdir
);
2760 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
2761 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
2762 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
2764 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
2765 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2767 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
2768 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2770 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)report_desc
, sizeof(report_desc
) );
2771 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2773 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
2774 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2776 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)&caps
, sizeof(caps
) );
2777 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2779 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, NULL
, 0 );
2780 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2782 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, (void *)&expect_in
, polled
? sizeof(expect_in
) : 0 );
2783 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2785 if (pnp_driver_start( L
"driver_hid.dll" )) test_hid_device( report_id
, polled
, &caps
);
2788 SetCurrentDirectoryW( cwd
);
2791 /* undocumented HID internal preparsed data structure */
2793 struct hidp_kdr_caps
2799 USHORT report_count
;
2804 USHORT link_collection
;
2805 USAGE link_usage_page
;
2813 USHORT designator_min
;
2814 USHORT designator_max
;
2815 USHORT data_index_min
;
2816 USHORT data_index_max
;
2827 /* named array continues on next caps */
2828 #define HIDP_KDR_CAPS_ARRAY_HAS_MORE 0x01
2829 #define HIDP_KDR_CAPS_IS_CONSTANT 0x02
2830 #define HIDP_KDR_CAPS_IS_BUTTON 0x04
2831 #define HIDP_KDR_CAPS_IS_ABSOLUTE 0x08
2832 #define HIDP_KDR_CAPS_IS_RANGE 0x10
2833 #define HIDP_KDR_CAPS_IS_STRING_RANGE 0x40
2834 #define HIDP_KDR_CAPS_IS_DESIGNATOR_RANGE 0x80
2836 struct hidp_kdr_node
2841 USHORT number_of_children
;
2842 USHORT next_sibling
;
2844 ULONG collection_type
;
2853 USHORT input_caps_start
;
2854 USHORT input_caps_count
;
2855 USHORT input_caps_end
;
2856 USHORT input_report_byte_length
;
2857 USHORT output_caps_start
;
2858 USHORT output_caps_count
;
2859 USHORT output_caps_end
;
2860 USHORT output_report_byte_length
;
2861 USHORT feature_caps_start
;
2862 USHORT feature_caps_count
;
2863 USHORT feature_caps_end
;
2864 USHORT feature_report_byte_length
;
2866 USHORT number_link_collection_nodes
;
2867 struct hidp_kdr_caps caps
[1];
2868 /* struct hidp_kdr_node nodes[1] */
2871 static void test_hidp_kdr(void)
2873 #include "psh_hid_macros.h"
2874 const unsigned char report_desc
[] =
2876 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2877 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2878 COLLECTION(1, Application
),
2879 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2880 LOGICAL_MINIMUM(1, 1),
2881 LOGICAL_MAXIMUM(1, 127),
2882 PHYSICAL_MINIMUM(1, -128),
2883 PHYSICAL_MAXIMUM(1, 127),
2885 USAGE(1, HID_USAGE_GENERIC_RZ
),
2888 FEATURE(1, Data
|Var
|Abs
),
2889 USAGE(1, HID_USAGE_GENERIC_SLIDER
),
2892 FEATURE(1, Data
|Var
|Abs
),
2894 USAGE(1, HID_USAGE_GENERIC_X
),
2898 UNIT_EXPONENT(1, -3),
2899 INPUT(1, Data
|Var
|Abs
),
2900 UNIT_EXPONENT(1, 0),
2902 USAGE(1, HID_USAGE_GENERIC_Y
),
2903 DESIGNATOR_MINIMUM(1, 1),
2904 DESIGNATOR_MAXIMUM(1, 4),
2907 INPUT(1, Cnst
|Var
|Abs
),
2908 USAGE(1, HID_USAGE_GENERIC_Z
),
2911 INPUT(1, Data
|Var
|Rel
),
2912 USAGE(1, HID_USAGE_GENERIC_RX
),
2913 USAGE(1, HID_USAGE_GENERIC_RY
),
2916 LOGICAL_MINIMUM(1, 7),
2917 INPUT(1, Data
|Var
|Abs
|Null
),
2919 COLLECTION(1, Application
),
2920 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|1),
2921 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|2),
2924 LOGICAL_MINIMUM(1, 0),
2925 LOGICAL_MAXIMUM(1, 1),
2926 INPUT(1, Data
|Var
|Abs
),
2928 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|3),
2929 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|8),
2932 LOGICAL_MINIMUM(1, 3),
2933 LOGICAL_MAXIMUM(1, 8),
2934 INPUT(1, Data
|Ary
|Abs
),
2936 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|9),
2937 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|12),
2940 LOGICAL_MINIMUM(1, 9),
2941 LOGICAL_MAXIMUM(1, 12),
2942 INPUT(2, Data
|Ary
|Abs
|Buff
),
2944 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|13),
2945 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|14),
2946 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|15),
2947 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|16),
2950 LOGICAL_MINIMUM(1, 13),
2951 LOGICAL_MAXIMUM(1, 16),
2952 INPUT(1, Data
|Ary
|Abs
),
2956 #include "pop_hid_macros.h"
2958 static const HIDP_CAPS expect_hidp_caps
=
2960 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
2961 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
2962 .InputReportByteLength
= 15,
2964 static const HID_DEVICE_ATTRIBUTES attributes
=
2966 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
2968 .ProductID
= 0x0001,
2969 .VersionNumber
= 0x0100,
2971 static const struct hidp_kdr expect_kdr
=
2973 .magic
= "HidP KDR",
2976 .input_caps_count
= 13,
2977 .input_caps_end
= 13,
2978 .input_report_byte_length
= 15,
2979 .output_caps_start
= 13,
2980 .output_caps_end
= 13,
2981 .feature_caps_start
= 13,
2982 .feature_caps_count
= 2,
2983 .feature_caps_end
= 14,
2984 .feature_report_byte_length
= 3,
2986 .number_link_collection_nodes
= 2,
2988 static const struct hidp_kdr_caps expect_caps
[] =
2991 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x08,
2992 .bit_field
= 0x002, .end_byte
= 0x2, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
2993 .usage_min
= 0x30, .usage_max
= 0x30, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
2994 .physical_max
= 127, .units
= 0xe, .units_exp
= -3
2997 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x2, .total_bits
= 0x08,
2998 .bit_field
= 0x003, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x8a,
2999 .usage_min
= 0x31, .usage_max
= 0x31, .designator_min
= 1, .designator_max
= 4, .data_index_min
= 0x01,
3000 .data_index_max
= 0x01, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3003 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x3, .total_bits
= 0x08,
3004 .bit_field
= 0x006, .end_byte
= 0x4, .link_usage_page
= 0x01, .link_usage
= 0x04, .usage_min
= 0x32,
3005 .usage_max
= 0x32, .data_index_min
= 0x02, .data_index_max
= 0x02, .logical_min
= 1, .logical_max
= 127,
3006 .physical_min
= -128, .physical_max
= 127
3009 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x6, .total_bits
= 0x10,
3010 .bit_field
= 0x042, .end_byte
= 0x8, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3011 .usage_min
= 0x34, .usage_max
= 0x34, .data_index_min
= 0x03, .data_index_max
= 0x03, .null_value
= 1,
3012 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3015 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x4, .total_bits
= 0x10,
3016 .bit_field
= 0x042, .end_byte
= 0x6, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3017 .usage_min
= 0x33, .usage_max
= 0x33, .data_index_min
= 0x04, .data_index_max
= 0x04, .null_value
= 1,
3018 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3021 .usage_page
= 0x09, .start_bit
= 1, .bit_size
= 0x01, .report_count
= 0x7, .start_byte
= 0x8, .total_bits
= 0x07,
3022 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3023 .usage_min
= 0x02, .usage_max
= 0x02, .data_index_min
= 0x05, .data_index_max
= 0x05,
3026 .usage_page
= 0x09, .bit_size
= 0x01, .report_count
= 0x1, .start_byte
= 0x8, .total_bits
= 0x01,
3027 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3028 .usage_min
= 0x01, .usage_max
= 0x01, .data_index_min
= 0x06, .data_index_max
= 0x06,
3031 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x9, .total_bits
= 0x08,
3032 .bit_field
= 0x000, .end_byte
= 0xa, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
3033 .usage_min
= 0x03, .usage_max
= 0x08, .data_index_min
= 0x07, .data_index_max
= 0x0c, .null_value
= 3,
3037 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x4, .start_byte
= 0xa, .total_bits
= 0x20,
3038 .bit_field
= 0x100, .end_byte
= 0xe, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
3039 .usage_min
= 0x09, .usage_max
= 0x0c, .data_index_min
= 0x0d, .data_index_max
= 0x10, .null_value
= 9,
3043 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3044 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3045 .usage_min
= 0x10, .usage_max
= 0x10, .data_index_min
= 0x14, .data_index_max
= 0x14, .null_value
= 13,
3049 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3050 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3051 .usage_min
= 0x0f, .usage_max
= 0x0f, .data_index_min
= 0x13, .data_index_max
= 0x13, .null_value
= 13,
3055 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3056 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3057 .usage_min
= 0x0e, .usage_max
= 0x0e, .data_index_min
= 0x12, .data_index_max
= 0x12, .null_value
= 13,
3061 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3062 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3063 .usage_min
= 0x0d, .usage_max
= 0x0d, .data_index_min
= 0x11, .data_index_max
= 0x11, .null_value
= 13,
3067 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x10,
3068 .bit_field
= 0x002, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3069 .usage_min
= 0x36, .usage_max
= 0x36, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
3075 static const struct hidp_kdr_node expect_nodes
[] =
3081 .number_of_children
= 0x1,
3084 .collection_type
= 0x1,
3090 .number_of_children
= 0,
3093 .collection_type
= 0x1,
3097 char buffer
[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W
, DevicePath
[MAX_PATH
] )];
3098 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(SP_DEVICE_INTERFACE_DATA
)};
3099 SP_DEVICE_INTERFACE_DETAIL_DATA_W
*iface_detail
= (void *)buffer
;
3100 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
3101 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
3102 PHIDP_PREPARSED_DATA preparsed_data
;
3103 DWORD i
, report_id
= 0, polled
= 0;
3104 struct hidp_kdr
*kdr
;
3111 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
3112 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
3113 SetCurrentDirectoryW( tempdir
);
3115 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
3116 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
3117 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
3119 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
3120 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3122 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
3123 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3125 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)report_desc
, sizeof(report_desc
) );
3126 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3128 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
3129 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3131 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)&expect_hidp_caps
, sizeof(expect_hidp_caps
) );
3132 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3134 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, NULL
, 0 );
3135 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3137 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, NULL
, 0 );
3138 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3140 if (!pnp_driver_start( L
"driver_hid.dll" )) goto done
;
3142 set
= SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
3143 ok( set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError() );
3144 for (i
= 0; SetupDiEnumDeviceInfo( set
, i
, &device
); ++i
)
3146 ret
= SetupDiEnumDeviceInterfaces( set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
3147 ok( ret
, "failed to get interface, error %#x\n", GetLastError() );
3148 ok( IsEqualGUID( &iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
), "wrong class %s\n",
3149 debugstr_guid( &iface
.InterfaceClassGuid
) );
3150 ok( iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
3152 iface_detail
->cbSize
= sizeof(*iface_detail
);
3153 ret
= SetupDiGetDeviceInterfaceDetailW( set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
3154 ok( ret
, "failed to get interface path, error %#x\n", GetLastError() );
3156 if (wcsstr( iface_detail
->DevicePath
, L
"\\\\?\\hid#winetest#1" )) break;
3158 SetupDiDestroyDeviceInfoList( set
);
3160 file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
3161 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
3162 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
3164 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
3165 ok( ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
3167 kdr
= (struct hidp_kdr
*)preparsed_data
;
3168 ok( !strncmp( kdr
->magic
, expect_kdr
.magic
, 8 ), "got %s expected %s\n",
3169 debugstr_an(kdr
->magic
, 8), debugstr_an(expect_kdr
.magic
, 8) );
3171 if (!strncmp( kdr
->magic
, expect_kdr
.magic
, 8 ))
3173 check_member( *kdr
, expect_kdr
, "%04x", usage
);
3174 check_member( *kdr
, expect_kdr
, "%04x", usage_page
);
3175 check_member( *kdr
, expect_kdr
, "%#x", unknown
[0] );
3176 check_member( *kdr
, expect_kdr
, "%#x", unknown
[1] );
3177 check_member( *kdr
, expect_kdr
, "%d", input_caps_start
);
3178 check_member( *kdr
, expect_kdr
, "%d", input_caps_count
);
3179 check_member( *kdr
, expect_kdr
, "%d", input_caps_end
);
3180 check_member( *kdr
, expect_kdr
, "%d", input_report_byte_length
);
3181 check_member( *kdr
, expect_kdr
, "%d", output_caps_start
);
3182 check_member( *kdr
, expect_kdr
, "%d", output_caps_count
);
3183 check_member( *kdr
, expect_kdr
, "%d", output_caps_end
);
3184 check_member( *kdr
, expect_kdr
, "%d", output_report_byte_length
);
3185 check_member( *kdr
, expect_kdr
, "%d", feature_caps_start
);
3187 check_member( *kdr
, expect_kdr
, "%d", feature_caps_count
);
3188 check_member( *kdr
, expect_kdr
, "%d", feature_caps_end
);
3189 check_member( *kdr
, expect_kdr
, "%d", feature_report_byte_length
);
3191 check_member( *kdr
, expect_kdr
, "%d", caps_size
);
3192 check_member( *kdr
, expect_kdr
, "%d", number_link_collection_nodes
);
3194 for (i
= 0; i
< min( ARRAY_SIZE(expect_caps
), kdr
->caps_size
/ sizeof(struct hidp_kdr_caps
) ); ++i
)
3196 winetest_push_context( "caps[%d]", i
);
3197 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_page
);
3198 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_id
);
3199 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_bit
);
3200 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", bit_size
);
3201 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_count
);
3202 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_byte
);
3203 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", total_bits
);
3204 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", bit_field
);
3205 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", end_byte
);
3206 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", link_collection
);
3207 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage_page
);
3208 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage
);
3209 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", flags
);
3210 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[0] );
3211 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[1] );
3212 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[2] );
3213 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[3] );
3214 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[4] );
3215 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[5] );
3216 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[6] );
3217 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[7] );
3218 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_min
);
3219 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_max
);
3220 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_min
);
3221 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_max
);
3222 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_min
);
3223 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_max
);
3224 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_min
);
3225 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_max
);
3226 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", null_value
);
3227 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", unknown
);
3228 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", logical_min
);
3229 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", logical_max
);
3230 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", physical_min
);
3231 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", physical_max
);
3232 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", units
);
3233 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", units_exp
);
3234 winetest_pop_context();
3237 for (i
= 0; i
< ARRAY_SIZE(expect_nodes
); ++i
)
3239 struct hidp_kdr_node
*nodes
= (struct hidp_kdr_node
*)((char *)kdr
->caps
+ kdr
->caps_size
);
3240 winetest_push_context( "nodes[%d]", i
);
3241 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage
);
3242 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage_page
);
3243 check_member( nodes
[i
], expect_nodes
[i
], "%d", parent
);
3244 check_member( nodes
[i
], expect_nodes
[i
], "%d", number_of_children
);
3245 check_member( nodes
[i
], expect_nodes
[i
], "%d", next_sibling
);
3246 check_member( nodes
[i
], expect_nodes
[i
], "%d", first_child
);
3247 check_member( nodes
[i
], expect_nodes
[i
], "%#x", collection_type
);
3248 winetest_pop_context();
3252 HidD_FreePreparsedData( preparsed_data
);
3254 CloseHandle( file
);
3258 SetCurrentDirectoryW( cwd
);
3261 static void cleanup_registry_keys(void)
3263 static const WCHAR joystick_oem_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3264 "PrivateProperties\\Joystick\\OEM";
3265 static const WCHAR dinput_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3266 "PrivateProperties\\DirectInput";
3269 /* These keys are automatically created by DInput and they store the
3270 list of supported force-feedback effects. OEM drivers are supposed
3271 to provide a list in HKLM for the vendor-specific force-feedback
3274 We need to clean them up, or DInput will not refresh the list of
3275 effects from the PID report changes.
3277 RegCreateKeyExW( HKEY_CURRENT_USER
, joystick_oem_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3278 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3279 RegCloseKey( root_key
);
3281 RegCreateKeyExW( HKEY_CURRENT_USER
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3282 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3283 RegCloseKey( root_key
);
3285 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, joystick_oem_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3286 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3287 RegCloseKey( root_key
);
3289 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3290 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3291 RegCloseKey( root_key
);
3294 static BOOL
dinput_driver_start( const BYTE
*desc_buf
, ULONG desc_len
, const HIDP_CAPS
*caps
,
3295 struct hid_expect
*expect
, ULONG expect_size
)
3297 static const HID_DEVICE_ATTRIBUTES attributes
=
3299 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
3300 .VendorID
= LOWORD( EXPECT_VIDPID
),
3301 .ProductID
= HIWORD( EXPECT_VIDPID
),
3302 .VersionNumber
= 0x0100,
3304 DWORD report_id
= 1;
3309 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
3310 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
3311 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
3312 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
3313 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3314 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
3315 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3316 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)desc_buf
, desc_len
);
3317 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3318 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
3319 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3320 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)caps
, sizeof(*caps
) );
3321 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3322 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, (void *)expect
, expect_size
);
3323 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3324 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, NULL
, 0 );
3325 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3327 return pnp_driver_start( L
"driver_hid.dll" );
3330 static BOOL CALLBACK
find_test_device( const DIDEVICEINSTANCEW
*devinst
, void *context
)
3332 if (IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3333 *(DIDEVICEINSTANCEW
*)context
= *devinst
;
3334 return DIENUM_CONTINUE
;
3337 struct check_objects_todos
3345 struct check_objects_params
3350 const DIDEVICEOBJECTINSTANCEW
*expect_objs
;
3351 const struct check_objects_todos
*todo_objs
;
3355 static BOOL CALLBACK
check_objects( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
3357 static const DIDEVICEOBJECTINSTANCEW unexpected_obj
= {0};
3358 static const struct check_objects_todos todo_none
= {0};
3359 struct check_objects_params
*params
= args
;
3360 const DIDEVICEOBJECTINSTANCEW
*exp
= params
->expect_objs
+ params
->index
;
3361 const struct check_objects_todos
*todo
;
3363 if (!params
->todo_objs
) todo
= &todo_none
;
3364 else todo
= params
->todo_objs
+ params
->index
;
3366 todo_wine_if( params
->todo_extra
&& params
->index
>= params
->expect_count
)
3367 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
3368 if (params
->index
>= params
->expect_count
) return DIENUM_STOP
;
3370 winetest_push_context( "obj[%d]", params
->index
);
3372 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
3373 if (params
->index
>= params
->expect_count
) exp
= &unexpected_obj
;
3375 check_member( *obj
, *exp
, "%u", dwSize
);
3376 todo_wine_if( todo
->guid
)
3377 check_member_guid( *obj
, *exp
, guidType
);
3378 todo_wine_if( params
->version
< 0x700 && (obj
->dwType
& DIDFT_BUTTON
) )
3379 check_member( *obj
, *exp
, "%#x", dwOfs
);
3380 todo_wine_if( todo
->type
)
3381 check_member( *obj
, *exp
, "%#x", dwType
);
3382 check_member( *obj
, *exp
, "%#x", dwFlags
);
3383 if (!localized
) todo_wine_if( todo
->name
)check_member_wstr( *obj
, *exp
, tszName
);
3384 check_member( *obj
, *exp
, "%u", dwFFMaxForce
);
3385 check_member( *obj
, *exp
, "%u", dwFFForceResolution
);
3386 check_member( *obj
, *exp
, "%u", wCollectionNumber
);
3387 check_member( *obj
, *exp
, "%u", wDesignatorIndex
);
3388 check_member( *obj
, *exp
, "%#04x", wUsagePage
);
3389 todo_wine_if( todo
->usage
)
3390 check_member( *obj
, *exp
, "%#04x", wUsage
);
3391 check_member( *obj
, *exp
, "%#04x", dwDimension
);
3392 check_member( *obj
, *exp
, "%#04x", wExponent
);
3393 check_member( *obj
, *exp
, "%u", wReportId
);
3395 winetest_pop_context();
3398 return DIENUM_CONTINUE
;
3401 static BOOL CALLBACK
check_object_count( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
3403 DWORD
*count
= args
;
3404 *count
= *count
+ 1;
3405 return DIENUM_CONTINUE
;
3408 struct check_effects_params
3412 const DIEFFECTINFOW
*expect_effects
;
3415 static BOOL CALLBACK
check_effects( const DIEFFECTINFOW
*effect
, void *args
)
3417 static const DIEFFECTINFOW unexpected_effect
= {0};
3418 struct check_effects_params
*params
= args
;
3419 const DIEFFECTINFOW
*exp
= params
->expect_effects
+ params
->index
;
3421 winetest_push_context( "effect[%d]", params
->index
);
3423 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
3424 if (params
->index
>= params
->expect_count
) exp
= &unexpected_effect
;
3426 check_member( *effect
, *exp
, "%u", dwSize
);
3427 check_member_guid( *effect
, *exp
, guid
);
3428 check_member( *effect
, *exp
, "%#x", dwEffType
);
3429 check_member( *effect
, *exp
, "%#x", dwStaticParams
);
3430 check_member( *effect
, *exp
, "%#x", dwDynamicParams
);
3431 check_member_wstr( *effect
, *exp
, tszName
);
3433 winetest_pop_context();
3436 return DIENUM_CONTINUE
;
3439 static BOOL CALLBACK
check_effect_count( const DIEFFECTINFOW
*effect
, void *args
)
3441 DWORD
*count
= args
;
3442 *count
= *count
+ 1;
3443 return DIENUM_CONTINUE
;
3446 static BOOL CALLBACK
check_no_created_effect_objects( IDirectInputEffect
*effect
, void *context
)
3448 ok( 0, "unexpected effect %p\n", effect
);
3449 return DIENUM_CONTINUE
;
3452 struct check_created_effect_params
3454 IDirectInputEffect
*expect_effect
;
3458 static BOOL CALLBACK
check_created_effect_objects( IDirectInputEffect
*effect
, void *context
)
3460 struct check_created_effect_params
*params
= context
;
3463 ok( effect
== params
->expect_effect
, "got effect %p, expected %p\n", effect
, params
->expect_effect
);
3466 IDirectInputEffect_AddRef( effect
);
3467 ref
= IDirectInputEffect_Release( effect
);
3468 ok( ref
== 1, "got ref %u, expected 1\n", ref
);
3469 return DIENUM_CONTINUE
;
3472 static BOOL CALLBACK
enum_device_count( const DIDEVICEINSTANCEW
*devinst
, void *context
)
3474 DWORD
*count
= context
;
3475 *count
= *count
+ 1;
3476 return DIENUM_CONTINUE
;
3479 static HRESULT
create_dinput_device( DWORD version
, DIDEVICEINSTANCEW
*devinst
, IDirectInputDevice8W
**device
)
3481 DIPROPDWORD prop_dword
=
3485 .dwSize
= sizeof(DIPROPDWORD
),
3486 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3487 .dwHow
= DIPH_DEVICE
,
3490 IDirectInput8W
*di8
;
3495 if (version
>= 0x800)
3497 hr
= DirectInput8Create( instance
, version
, &IID_IDirectInput8W
, (void **)&di8
, NULL
);
3500 win_skip( "DirectInput8Create returned %#x\n", hr
);
3504 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, find_test_device
, devinst
, DIEDFL_ALLDEVICES
);
3505 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3506 if (!IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3508 win_skip( "device not found, skipping tests\n" );
3509 ref
= IDirectInput8_Release( di8
);
3510 ok( ref
== 0, "Release returned %d\n", ref
);
3511 return DIERR_DEVICENOTREG
;
3514 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, NULL
, NULL
, DIEDFL_ALLDEVICES
);
3515 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3516 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, 0xdeadbeef );
3517 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3518 hr
= IDirectInput8_EnumDevices( di8
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3519 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3522 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3523 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3524 ok( count
== 3, "got count %u, expected 0\n", count
);
3526 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3527 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3528 ok( count
== 0, "got count %u, expected 0\n", count
);
3530 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_POINTER
, enum_device_count
, &count
,
3531 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
3532 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3534 ok( count
== 3, "got count %u, expected 3\n", count
);
3536 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_KEYBOARD
, enum_device_count
, &count
,
3537 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
3538 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3540 ok( count
== 3, "got count %u, expected 3\n", count
);
3542 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_GAMECTRL
, enum_device_count
, &count
,
3543 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
3544 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3545 ok( count
== 1, "got count %u, expected 1\n", count
);
3548 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3549 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3550 ok( count
== 1, "got count %u, expected 1\n", count
);
3553 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
3554 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3555 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %u, expected 0\n", count
);
3556 else ok( count
== 1, "got count %u, expected 1\n", count
);
3559 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff) + 1, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3560 if ((devinst
->dwDevType
& 0xff) != DI8DEVTYPE_SUPPLEMENTAL
) ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3561 else ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3562 ok( count
== 0, "got count %u, expected 0\n", count
);
3564 hr
= IDirectInput8_CreateDevice( di8
, &devinst
->guidInstance
, NULL
, NULL
);
3565 ok( hr
== E_POINTER
, "CreateDevice returned %#x\n", hr
);
3566 hr
= IDirectInput8_CreateDevice( di8
, NULL
, device
, NULL
);
3567 ok( hr
== E_POINTER
, "CreateDevice returned %#x\n", hr
);
3568 hr
= IDirectInput8_CreateDevice( di8
, &GUID_NULL
, device
, NULL
);
3569 ok( hr
== DIERR_DEVICENOTREG
, "CreateDevice returned %#x\n", hr
);
3570 hr
= IDirectInput8_CreateDevice( di8
, &devinst
->guidInstance
, device
, NULL
);
3571 ok( hr
== DI_OK
, "CreateDevice returned %#x\n", hr
);
3573 prop_dword
.dwData
= 0xdeadbeef;
3574 hr
= IDirectInputDevice8_GetProperty( *device
, DIPROP_VIDPID
, &prop_dword
.diph
);
3575 ok( hr
== DI_OK
, "GetProperty DIPROP_VIDPID returned %#x\n", hr
);
3576 /* Wine may get the wrong device here, because the test driver creates another instance of
3577 hidclass.sys, and gets duplicate rawinput handles, which we use in the guidInstance */
3578 todo_wine_if( prop_dword
.dwData
!= EXPECT_VIDPID
)
3579 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#x expected %#x\n", prop_dword
.dwData
, EXPECT_VIDPID
);
3581 ref
= IDirectInputDevice8_Release( *device
);
3582 ok( ref
== 0, "Release returned %d\n", ref
);
3584 hr
= IDirectInput8_CreateDevice( di8
, &expect_guid_product
, device
, NULL
);
3585 ok( hr
== DI_OK
, "CreateDevice returned %#x\n", hr
);
3587 ref
= IDirectInput8_Release( di8
);
3589 ok( ref
== 0, "Release returned %d\n", ref
);
3593 hr
= DirectInputCreateEx( instance
, version
, &IID_IDirectInput2W
, (void **)&di
, NULL
);
3596 win_skip( "DirectInputCreateEx returned %#x\n", hr
);
3600 hr
= IDirectInput_EnumDevices( di
, 0, find_test_device
, devinst
, DIEDFL_ALLDEVICES
);
3601 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3602 if (!IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3604 win_skip( "device not found, skipping tests\n" );
3606 ref
= IDirectInput_Release( di
);
3607 ok( ref
== 0, "Release returned %d\n", ref
);
3608 return DIERR_DEVICENOTREG
;
3611 hr
= IDirectInput_EnumDevices( di
, 0, NULL
, NULL
, DIEDFL_ALLDEVICES
);
3612 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3613 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, 0xdeadbeef );
3614 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3615 hr
= IDirectInput_EnumDevices( di
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3616 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3617 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_INCLUDEHIDDEN
);
3618 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3621 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3622 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3623 ok( count
== 3, "got count %u, expected 0\n", count
);
3625 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3626 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3627 ok( count
== 0, "got count %u, expected 0\n", count
);
3629 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_MOUSE
, enum_device_count
, &count
,
3630 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
3631 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3633 ok( count
== 3, "got count %u, expected 3\n", count
);
3635 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_KEYBOARD
, enum_device_count
, &count
,
3636 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
3637 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3639 ok( count
== 3, "got count %u, expected 3\n", count
);
3641 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_JOYSTICK
, enum_device_count
, &count
,
3642 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
3643 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3644 ok( count
== 1, "got count %u, expected 1\n", count
);
3647 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3648 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3649 ok( count
== 1, "got count %u, expected 1\n", count
);
3652 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
3653 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3654 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %u, expected 0\n", count
);
3655 else ok( count
== 1, "got count %u, expected 1\n", count
);
3657 hr
= IDirectInput_EnumDevices( di
, 0x14, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3658 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3660 hr
= IDirectInput_CreateDevice( di
, &expect_guid_product
, (IDirectInputDeviceW
**)device
, NULL
);
3661 ok( hr
== DI_OK
, "CreateDevice returned %#x\n", hr
);
3663 ref
= IDirectInput_Release( di
);
3665 ok( ref
== 0, "Release returned %d\n", ref
);
3671 static void test_simple_joystick(void)
3673 #include "psh_hid_macros.h"
3674 static const unsigned char report_desc
[] =
3676 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3677 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3678 COLLECTION(1, Application
),
3679 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3680 COLLECTION(1, Report
),
3683 USAGE(1, HID_USAGE_GENERIC_WHEEL
),
3684 USAGE(4, (0xff01u
<<16)|(0x1234)),
3685 USAGE(1, HID_USAGE_GENERIC_X
),
3686 USAGE(1, HID_USAGE_GENERIC_Y
),
3687 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_RUDDER
),
3688 USAGE(4, (HID_USAGE_PAGE_DIGITIZER
<<16)|HID_USAGE_DIGITIZER_TIP_PRESSURE
),
3689 USAGE(4, (HID_USAGE_PAGE_CONSUMER
<<16)|HID_USAGE_CONSUMER_VOLUME
),
3690 LOGICAL_MINIMUM(1, 0xe7),
3691 LOGICAL_MAXIMUM(1, 0x38),
3692 PHYSICAL_MINIMUM(1, 0xe7),
3693 PHYSICAL_MAXIMUM(1, 0x38),
3696 INPUT(1, Data
|Var
|Abs
),
3698 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
3699 LOGICAL_MINIMUM(1, 1),
3700 LOGICAL_MAXIMUM(1, 8),
3701 PHYSICAL_MINIMUM(1, 0),
3702 PHYSICAL_MAXIMUM(1, 8),
3705 INPUT(1, Data
|Var
|Abs
|Null
),
3707 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3708 USAGE_MINIMUM(1, 1),
3709 USAGE_MAXIMUM(1, 2),
3710 LOGICAL_MINIMUM(1, 0),
3711 LOGICAL_MAXIMUM(1, 1),
3712 PHYSICAL_MINIMUM(1, 0),
3713 PHYSICAL_MAXIMUM(1, 1),
3716 INPUT(1, Data
|Var
|Abs
),
3720 #undef REPORT_ID_OR_USAGE_PAGE
3721 #include "pop_hid_macros.h"
3723 static const HIDP_CAPS hid_caps
=
3725 .InputReportByteLength
= 9,
3727 static const DIDEVCAPS expect_caps
=
3729 .dwSize
= sizeof(DIDEVCAPS
),
3730 .dwFlags
= DIDC_ATTACHED
| DIDC_EMULATED
,
3731 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
,
3736 struct hid_expect injected_input
[] =
3739 .code
= IOCTL_HID_READ_REPORT
,
3740 .report_buf
= {1,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0},
3743 .code
= IOCTL_HID_READ_REPORT
,
3744 .report_buf
= {1,0x10,0x10,0x38,0x38,0x10,0x10,0x10,0xf8},
3747 .code
= IOCTL_HID_READ_REPORT
,
3748 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
3751 .code
= IOCTL_HID_READ_REPORT
,
3752 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
3755 .code
= IOCTL_HID_READ_REPORT
,
3756 .report_buf
= {1,0x10,0x10,0x80,0x80,0x10,0x10,0x10,0xff},
3759 .code
= IOCTL_HID_READ_REPORT
,
3760 .report_buf
= {1,0x10,0x10,0x10,0xee,0x10,0x10,0x10,0x54},
3763 static const struct DIJOYSTATE2 expect_state
[] =
3765 {.lX
= 32767, .lY
= 32767, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3766 {.lX
= 32767, .lY
= 32767, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3767 {.lX
= 65535, .lY
= 65535, .lZ
= 32767, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3768 {.lX
= 20779, .lY
= 20779, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3769 {.lX
= 20779, .lY
= 20779, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3770 {.lX
= 0, .lY
= 0, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3771 {.lX
= 32767, .lY
= 5594, .lZ
= 32767, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3773 static const struct DIJOYSTATE2 expect_state_abs
[] =
3775 {.lX
= -9000, .lY
= 26000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3776 {.lX
= -9000, .lY
= 26000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3777 {.lX
= -4000, .lY
= 51000, .lZ
= 26000, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3778 {.lX
= -10667, .lY
= 12905, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3779 {.lX
= -10667, .lY
= 12905, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3780 {.lX
= -14000, .lY
= 1000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3781 {.lX
= -9000, .lY
= 1000, .lZ
= 26000, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3783 static const struct DIJOYSTATE2 expect_state_rel
[] =
3785 {.lX
= 0, .lY
= 0, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80, 0}},
3786 {.lX
= 9016, .lY
= -984, .lZ
= -25984, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3787 {.lX
= 40, .lY
= 40, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3788 {.lX
= -55, .lY
= -55, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3789 {.lX
= 0, .lY
= 0, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3790 {.lX
= -129, .lY
= -129, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3791 {.lX
= 144, .lY
= 110, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3793 static const DIDEVICEOBJECTDATA expect_objdata
[] =
3795 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
3796 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
3797 {.dwOfs
= 0, .dwData
= 0xffff, .dwSequence
= 0xa},
3798 {.dwOfs
= 0x20, .dwData
= 31500, .dwSequence
= 0xa},
3799 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xa},
3800 {.dwOfs
= 0x4, .dwData
= 0x512b, .dwSequence
= 0xd},
3801 {.dwOfs
= 0, .dwData
= 0x512b, .dwSequence
= 0xd},
3802 {.dwOfs
= 0x20, .dwData
= -1, .dwSequence
= 0xd},
3803 {.dwOfs
= 0x30, .dwData
= 0, .dwSequence
= 0xd},
3804 {.dwOfs
= 0x31, .dwData
= 0, .dwSequence
= 0xd},
3805 {.dwOfs
= 0x4, .dwData
= 0, .dwSequence
= 0xf},
3806 {.dwOfs
= 0, .dwData
= 0, .dwSequence
= 0xf},
3807 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xf},
3808 {.dwOfs
= 0x31, .dwData
= 0x80, .dwSequence
= 0xf},
3811 const DIDEVICEINSTANCEW expect_devinst
=
3813 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3814 .guidInstance
= expect_guid_product
,
3815 .guidProduct
= expect_guid_product
,
3816 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
,
3817 .tszInstanceName
= L
"Wine test root driver",
3818 .tszProductName
= L
"Wine test root driver",
3819 .guidFFDriver
= GUID_NULL
,
3820 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3821 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3823 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
3826 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3827 .guidType
= GUID_Unknown
,
3828 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(6),
3829 .tszName
= L
"Volume",
3830 .wCollectionNumber
= 1,
3831 .wUsagePage
= HID_USAGE_PAGE_CONSUMER
,
3832 .wUsage
= HID_USAGE_CONSUMER_VOLUME
,
3836 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3837 .guidType
= GUID_Unknown
,
3839 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(7),
3840 .tszName
= L
"Tip Pressure",
3841 .wCollectionNumber
= 1,
3842 .wUsagePage
= HID_USAGE_PAGE_DIGITIZER
,
3843 .wUsage
= HID_USAGE_DIGITIZER_TIP_PRESSURE
,
3847 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3848 .guidType
= GUID_RzAxis
,
3850 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(5),
3851 .dwFlags
= DIDOI_ASPECTPOSITION
,
3852 .tszName
= L
"Rudder",
3853 .wCollectionNumber
= 1,
3854 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
3855 .wUsage
= HID_USAGE_SIMULATION_RUDDER
,
3859 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3860 .guidType
= GUID_YAxis
,
3862 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1),
3863 .dwFlags
= DIDOI_ASPECTPOSITION
,
3864 .tszName
= L
"Y Axis",
3865 .wCollectionNumber
= 1,
3866 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3867 .wUsage
= HID_USAGE_GENERIC_Y
,
3871 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3872 .guidType
= GUID_XAxis
,
3874 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0),
3875 .dwFlags
= DIDOI_ASPECTPOSITION
,
3876 .tszName
= L
"X Axis",
3877 .wCollectionNumber
= 1,
3878 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3879 .wUsage
= HID_USAGE_GENERIC_X
,
3883 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3884 .guidType
= GUID_ZAxis
,
3886 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2),
3887 .dwFlags
= DIDOI_ASPECTPOSITION
,
3888 .tszName
= L
"Wheel",
3889 .wCollectionNumber
= 1,
3890 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3891 .wUsage
= HID_USAGE_GENERIC_WHEEL
,
3895 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3896 .guidType
= GUID_POV
,
3898 .dwType
= DIDFT_POV
|DIDFT_MAKEINSTANCE(0),
3899 .tszName
= L
"Hat Switch",
3900 .wCollectionNumber
= 1,
3901 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3902 .wUsage
= HID_USAGE_GENERIC_HATSWITCH
,
3906 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3907 .guidType
= GUID_Button
,
3909 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0),
3910 .tszName
= L
"Button 0",
3911 .wCollectionNumber
= 1,
3912 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
3917 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3918 .guidType
= GUID_Button
,
3920 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1),
3921 .tszName
= L
"Button 1",
3922 .wCollectionNumber
= 1,
3923 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
3928 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3929 .guidType
= GUID_Unknown
,
3930 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
3931 .tszName
= L
"Collection 0 - Joystick",
3932 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3933 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3936 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3937 .guidType
= GUID_Unknown
,
3938 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
3939 .tszName
= L
"Collection 1 - Joystick",
3940 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3941 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3944 const DIEFFECTINFOW expect_effects
[] = {};
3946 struct check_objects_params check_objects_params
=
3948 .version
= DIRECTINPUT_VERSION
,
3949 .expect_count
= ARRAY_SIZE(expect_objects
),
3950 .expect_objs
= expect_objects
,
3952 struct check_effects_params check_effects_params
=
3954 .expect_count
= ARRAY_SIZE(expect_effects
),
3955 .expect_effects
= expect_effects
,
3957 DIPROPGUIDANDPATH prop_guid_path
=
3961 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
3962 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3963 .dwHow
= DIPH_DEVICE
,
3966 DIPROPSTRING prop_string
=
3970 .dwSize
= sizeof(DIPROPSTRING
),
3971 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3972 .dwHow
= DIPH_DEVICE
,
3975 DIPROPDWORD prop_dword
=
3979 .dwSize
= sizeof(DIPROPDWORD
),
3980 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3981 .dwHow
= DIPH_DEVICE
,
3984 DIPROPRANGE prop_range
=
3988 .dwSize
= sizeof(DIPROPRANGE
),
3989 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3990 .dwHow
= DIPH_DEVICE
,
3993 DIPROPPOINTER prop_pointer
=
3997 .dwSize
= sizeof(DIPROPPOINTER
),
3998 .dwHeaderSize
= sizeof(DIPROPHEADER
),
4001 DIOBJECTDATAFORMAT objdataformat
[32] = {{0}};
4002 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
4003 DIDEVICEOBJECTDATA objdata
[32] = {{0}};
4004 DIDEVICEOBJECTINSTANCEW objinst
= {0};
4005 DIDEVICEINSTANCEW devinst
= {0};
4006 DIEFFECTINFOW effectinfo
= {0};
4007 DIDATAFORMAT dataformat
= {0};
4008 IDirectInputDevice8W
*device
;
4009 IDirectInputEffect
*effect
;
4010 DIEFFESCAPE escape
= {0};
4011 DIDEVCAPS caps
= {0};
4021 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
4022 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
4023 SetCurrentDirectoryW( tempdir
);
4025 cleanup_registry_keys();
4026 if (!dinput_driver_start( report_desc
, sizeof(report_desc
), &hid_caps
, NULL
, 0 )) goto done
;
4027 if (FAILED(hr
= create_dinput_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
4029 hr
= IDirectInputDevice8_Initialize( device
, instance
, 0x0700, &GUID_NULL
);
4031 ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#x\n", hr
);
4032 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, NULL
);
4034 ok( hr
== E_POINTER
, "Initialize returned %#x\n", hr
);
4035 hr
= IDirectInputDevice8_Initialize( device
, NULL
, DIRECTINPUT_VERSION
, &GUID_NULL
);
4037 ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#x\n", hr
);
4038 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, &GUID_NULL
);
4040 ok( hr
== REGDB_E_CLASSNOTREG
, "Initialize returned %#x\n", hr
);
4042 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, &devinst
.guidInstance
);
4043 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
4044 guid
= devinst
.guidInstance
;
4045 memset( &devinst
, 0, sizeof(devinst
) );
4046 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
4047 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4048 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
4049 ok( IsEqualGUID( &guid
, &devinst
.guidInstance
), "got %s expected %s\n", debugstr_guid( &guid
),
4050 debugstr_guid( &devinst
.guidInstance
) );
4051 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, &devinst
.guidProduct
);
4052 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
4054 hr
= IDirectInputDevice8_GetDeviceInfo( device
, NULL
);
4055 ok( hr
== E_POINTER
, "GetDeviceInfo returned %#x\n", hr
);
4056 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
) + 1;
4057 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4058 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceInfo returned %#x\n", hr
);
4060 devinst
.dwSize
= sizeof(DIDEVICEINSTANCE_DX3W
);
4061 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4062 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
4064 check_member_guid( devinst
, expect_devinst
, guidInstance
);
4065 check_member_guid( devinst
, expect_devinst
, guidProduct
);
4066 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
4068 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
4070 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
4072 memset( &devinst
, 0, sizeof(devinst
) );
4073 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
4074 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4075 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
4076 check_member( devinst
, expect_devinst
, "%d", dwSize
);
4078 check_member_guid( devinst
, expect_devinst
, guidInstance
);
4079 check_member_guid( devinst
, expect_devinst
, guidProduct
);
4080 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
4082 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
4084 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
4085 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
4086 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
4087 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
4089 hr
= IDirectInputDevice8_GetCapabilities( device
, NULL
);
4090 ok( hr
== E_POINTER
, "GetCapabilities returned %#x\n", hr
);
4091 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4092 ok( hr
== DIERR_INVALIDPARAM
, "GetCapabilities returned %#x\n", hr
);
4093 caps
.dwSize
= sizeof(DIDEVCAPS
);
4094 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4095 ok( hr
== DI_OK
, "GetCapabilities returned %#x\n", hr
);
4096 check_member( caps
, expect_caps
, "%d", dwSize
);
4097 check_member( caps
, expect_caps
, "%#x", dwFlags
);
4098 check_member( caps
, expect_caps
, "%#x", dwDevType
);
4099 check_member( caps
, expect_caps
, "%d", dwAxes
);
4100 check_member( caps
, expect_caps
, "%d", dwButtons
);
4101 check_member( caps
, expect_caps
, "%d", dwPOVs
);
4102 check_member( caps
, expect_caps
, "%d", dwFFSamplePeriod
);
4103 check_member( caps
, expect_caps
, "%d", dwFFMinTimeResolution
);
4104 check_member( caps
, expect_caps
, "%d", dwFirmwareRevision
);
4105 check_member( caps
, expect_caps
, "%d", dwHardwareRevision
);
4106 check_member( caps
, expect_caps
, "%d", dwFFDriverVersion
);
4108 hr
= IDirectInputDevice8_GetProperty( device
, NULL
, NULL
);
4109 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4110 hr
= IDirectInputDevice8_GetProperty( device
, &GUID_NULL
, NULL
);
4111 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4112 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, NULL
);
4113 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4114 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
4115 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4116 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
) - 1;
4117 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
4118 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4119 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
4121 prop_dword
.dwData
= 0xdeadbeef;
4122 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
4123 ok( hr
== DI_OK
, "GetProperty DIPROP_VIDPID returned %#x\n", hr
);
4124 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#x expected %#x\n", prop_dword
.dwData
, EXPECT_VIDPID
);
4126 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
4127 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
4129 ok( IsEqualGUID( &prop_guid_path
.guidClass
, &GUID_DEVCLASS_HIDCLASS
), "got guid %s\n",
4130 debugstr_guid( &prop_guid_path
.guidClass
) );
4132 ok( !wcsncmp( prop_guid_path
.wszPath
, expect_path
, wcslen( expect_path
) ), "got path %s\n",
4133 debugstr_w(prop_guid_path
.wszPath
) );
4134 if (!(tmp
= wcsrchr( prop_guid_path
.wszPath
, '&' )))
4135 todo_wine
ok( 0, "got path %s\n", debugstr_w(prop_guid_path
.wszPath
) );
4138 ok( !wcscmp( wcsrchr( prop_guid_path
.wszPath
, '&' ), expect_path_end
), "got path %s\n",
4139 debugstr_w(prop_guid_path
.wszPath
) );
4142 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
4143 ok( hr
== DI_OK
, "GetProperty DIPROP_INSTANCENAME returned %#x\n", hr
);
4145 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszInstanceName
), "got instance %s\n",
4146 debugstr_w(prop_string
.wsz
) );
4147 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4148 ok( hr
== DI_OK
, "GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4150 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
4151 debugstr_w(prop_string
.wsz
) );
4152 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
4154 ok( hr
== DI_OK
, "GetProperty DIPROP_TYPENAME returned %#x\n", hr
);
4156 ok( !wcscmp( prop_string
.wsz
, expect_vidpid_str
), "got type %s\n", debugstr_w(prop_string
.wsz
) );
4157 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
4158 ok( hr
== S_FALSE
, "GetProperty DIPROP_USERNAME returned %#x\n", hr
);
4160 ok( !wcscmp( prop_string
.wsz
, L
"" ), "got user %s\n", debugstr_w(prop_string
.wsz
) );
4162 prop_dword
.dwData
= 0xdeadbeef;
4163 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
4164 ok( hr
== DI_OK
, "GetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
4166 ok( prop_dword
.dwData
== 0, "got %#x expected %#x\n", prop_dword
.dwData
, 0 );
4168 prop_dword
.dwData
= 0xdeadbeef;
4169 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4171 ok( hr
== DI_OK
, "GetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4173 ok( prop_dword
.dwData
== DIPROPAXISMODE_ABS
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_ABS
);
4174 prop_dword
.dwData
= 0xdeadbeef;
4175 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4176 ok( hr
== DI_OK
, "GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4177 ok( prop_dword
.dwData
== 0, "got %#x expected %#x\n", prop_dword
.dwData
, 0 );
4178 prop_dword
.dwData
= 0xdeadbeef;
4179 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
4180 ok( hr
== DI_OK
, "GetProperty DIPROP_FFGAIN returned %#x\n", hr
);
4181 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
4183 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
4184 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty DIPROP_CALIBRATION returned %#x\n", hr
);
4185 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
4186 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
4187 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4188 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4189 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4190 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
4191 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
4192 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
4193 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4194 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4195 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4196 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4197 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4198 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4199 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4200 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4201 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4202 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4203 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4204 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4206 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4207 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4208 prop_dword
.dwData
= 0xdeadbeef;
4209 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4210 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4211 ok( prop_dword
.dwData
== 0, "got %u expected %u\n", prop_dword
.dwData
, 0 );
4212 prop_dword
.dwData
= 0xdeadbeef;
4213 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
4214 ok( hr
== DI_OK
, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
4215 ok( prop_dword
.dwData
== 1, "got %u expected %u\n", prop_dword
.dwData
, 1 );
4216 prop_dword
.dwData
= 0xdeadbeef;
4217 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4218 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4219 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
4220 prop_dword
.dwData
= 0xdeadbeef;
4221 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4222 ok( hr
== DI_OK
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4223 ok( prop_dword
.dwData
== DIPROPCALIBRATIONMODE_COOKED
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPCALIBRATIONMODE_COOKED
);
4225 prop_string
.diph
.dwHow
= DIPH_BYUSAGE
;
4226 prop_string
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4227 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4228 ok( hr
== DI_OK
, "GetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4229 ok( !wcscmp( prop_string
.wsz
, expect_objects
[4].tszName
), "got DIPROP_KEYNAME %s\n",
4230 debugstr_w( prop_string
.wsz
) );
4231 prop_string
.diph
.dwObj
= MAKELONG( 0x1, HID_USAGE_PAGE_BUTTON
);
4232 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4234 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4235 prop_string
.diph
.dwHow
= DIPH_BYUSAGE
;
4236 prop_string
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4237 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4238 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4240 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4241 prop_range
.diph
.dwObj
= MAKELONG( 0, 0 );
4242 prop_range
.lMin
= 0xdeadbeef;
4243 prop_range
.lMax
= 0xdeadbeef;
4244 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4245 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4246 prop_range
.diph
.dwObj
= MAKELONG( 0, HID_USAGE_PAGE_GENERIC
);
4247 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4248 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4249 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_PAGE_GENERIC
, HID_USAGE_GENERIC_X
);
4250 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4251 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4252 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4253 prop_range
.lMin
= 0xdeadbeef;
4254 prop_range
.lMax
= 0xdeadbeef;
4255 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4256 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4257 ok( prop_range
.lMin
== 0, "got %d expected %d\n", prop_range
.lMin
, 0 );
4258 ok( prop_range
.lMax
== 65535, "got %d expected %d\n", prop_range
.lMax
, 65535 );
4259 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4260 ok( hr
== DI_OK
, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4261 ok( prop_range
.lMin
== -25, "got %d expected %d\n", prop_range
.lMin
, -25 );
4262 ok( prop_range
.lMax
== 56, "got %d expected %d\n", prop_range
.lMax
, 56 );
4263 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4264 ok( hr
== DI_OK
, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4265 ok( prop_range
.lMin
== -25, "got %d expected %d\n", prop_range
.lMin
, -25 );
4266 ok( prop_range
.lMax
== 56, "got %d expected %d\n", prop_range
.lMax
, 56 );
4268 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
4269 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4270 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
4272 ok( hr
== DIERR_NOTINITIALIZED
, "GetProperty DIPROP_APPDATA returned %#x\n", hr
);
4274 hr
= IDirectInputDevice8_EnumObjects( device
, NULL
, NULL
, DIDFT_ALL
);
4275 ok( hr
== DIERR_INVALIDPARAM
, "EnumObjects returned %#x\n", hr
);
4276 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, 0x20 );
4277 ok( hr
== DIERR_INVALIDPARAM
, "EnumObjects returned %#x\n", hr
);
4279 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, DIDFT_AXIS
| DIDFT_PSHBUTTON
);
4280 ok( hr
== DI_OK
, "EnumObjects returned %#x\n", hr
);
4281 ok( res
== 8, "got %u expected %u\n", res
, 8 );
4282 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
4283 ok( hr
== DI_OK
, "EnumObjects returned %#x\n", hr
);
4284 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
4285 check_objects_params
.expect_count
- check_objects_params
.index
);
4287 hr
= IDirectInputDevice8_GetObjectInfo( device
, NULL
, 0, DIPH_DEVICE
);
4288 ok( hr
== E_POINTER
, "GetObjectInfo returned: %#x\n", hr
);
4289 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_DEVICE
);
4290 ok( hr
== DIERR_INVALIDPARAM
, "GetObjectInfo returned: %#x\n", hr
);
4291 objinst
.dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
);
4292 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_DEVICE
);
4293 ok( hr
== DIERR_INVALIDPARAM
, "GetObjectInfo returned: %#x\n", hr
);
4295 res
= MAKELONG( HID_USAGE_GENERIC_Z
, HID_USAGE_PAGE_GENERIC
);
4296 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYUSAGE
);
4297 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4298 res
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4299 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYUSAGE
);
4300 ok( hr
== DI_OK
, "GetObjectInfo returned: %#x\n", hr
);
4302 check_member( objinst
, expect_objects
[4], "%u", dwSize
);
4303 check_member_guid( objinst
, expect_objects
[4], guidType
);
4304 check_member( objinst
, expect_objects
[4], "%#x", dwOfs
);
4305 check_member( objinst
, expect_objects
[4], "%#x", dwType
);
4306 check_member( objinst
, expect_objects
[4], "%#x", dwFlags
);
4307 if (!localized
) check_member_wstr( objinst
, expect_objects
[4], tszName
);
4308 check_member( objinst
, expect_objects
[4], "%u", dwFFMaxForce
);
4309 check_member( objinst
, expect_objects
[4], "%u", dwFFForceResolution
);
4310 check_member( objinst
, expect_objects
[4], "%u", wCollectionNumber
);
4311 check_member( objinst
, expect_objects
[4], "%u", wDesignatorIndex
);
4312 check_member( objinst
, expect_objects
[4], "%#04x", wUsagePage
);
4313 check_member( objinst
, expect_objects
[4], "%#04x", wUsage
);
4314 check_member( objinst
, expect_objects
[4], "%#04x", dwDimension
);
4315 check_member( objinst
, expect_objects
[4], "%#04x", wExponent
);
4316 check_member( objinst
, expect_objects
[4], "%u", wReportId
);
4318 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0x14, DIPH_BYOFFSET
);
4319 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4320 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_BYOFFSET
);
4321 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4322 res
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 3 );
4323 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYID
);
4324 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4325 res
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 1 );
4326 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYID
);
4327 ok( hr
== DI_OK
, "GetObjectInfo returned: %#x\n", hr
);
4329 check_member( objinst
, expect_objects
[8], "%u", dwSize
);
4330 check_member_guid( objinst
, expect_objects
[8], guidType
);
4331 check_member( objinst
, expect_objects
[8], "%#x", dwOfs
);
4332 check_member( objinst
, expect_objects
[8], "%#x", dwType
);
4333 check_member( objinst
, expect_objects
[8], "%#x", dwFlags
);
4334 if (!localized
) check_member_wstr( objinst
, expect_objects
[8], tszName
);
4335 check_member( objinst
, expect_objects
[8], "%u", dwFFMaxForce
);
4336 check_member( objinst
, expect_objects
[8], "%u", dwFFForceResolution
);
4337 check_member( objinst
, expect_objects
[8], "%u", wCollectionNumber
);
4338 check_member( objinst
, expect_objects
[8], "%u", wDesignatorIndex
);
4339 check_member( objinst
, expect_objects
[8], "%#04x", wUsagePage
);
4340 check_member( objinst
, expect_objects
[8], "%#04x", wUsage
);
4341 check_member( objinst
, expect_objects
[8], "%#04x", dwDimension
);
4342 check_member( objinst
, expect_objects
[8], "%#04x", wExponent
);
4343 check_member( objinst
, expect_objects
[8], "%u", wReportId
);
4345 hr
= IDirectInputDevice8_EnumEffects( device
, NULL
, NULL
, DIEFT_ALL
);
4346 ok( hr
== DIERR_INVALIDPARAM
, "EnumEffects returned %#x\n", hr
);
4348 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, 0xfe );
4349 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
4350 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4352 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, DIEFT_PERIODIC
);
4353 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
4354 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4355 hr
= IDirectInputDevice8_EnumEffects( device
, check_effects
, &check_effects_params
, DIEFT_ALL
);
4356 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
4357 ok( check_effects_params
.index
>= check_effects_params
.expect_count
, "missing %u effects\n",
4358 check_effects_params
.expect_count
- check_effects_params
.index
);
4360 hr
= IDirectInputDevice8_GetEffectInfo( device
, NULL
, &GUID_Sine
);
4361 ok( hr
== E_POINTER
, "GetEffectInfo returned %#x\n", hr
);
4362 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
) + 1;
4363 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
4364 ok( hr
== DIERR_INVALIDPARAM
, "GetEffectInfo returned %#x\n", hr
);
4365 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
);
4366 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_NULL
);
4367 ok( hr
== DIERR_DEVICENOTREG
, "GetEffectInfo returned %#x\n", hr
);
4368 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
4369 ok( hr
== DIERR_DEVICENOTREG
, "GetEffectInfo returned %#x\n", hr
);
4371 hr
= IDirectInputDevice8_SetDataFormat( device
, NULL
);
4372 ok( hr
== E_POINTER
, "SetDataFormat returned: %#x\n", hr
);
4373 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4374 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4375 dataformat
.dwSize
= sizeof(DIDATAFORMAT
);
4376 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4377 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4378 dataformat
.dwObjSize
= sizeof(DIOBJECTDATAFORMAT
);
4379 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4380 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4381 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
4382 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4384 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, DIJOFS_Y
, DIPH_BYOFFSET
);
4385 ok( hr
== DI_OK
, "GetObjectInfo returned: %#x\n", hr
);
4387 check_member( objinst
, expect_objects
[3], "%u", dwSize
);
4388 check_member_guid( objinst
, expect_objects
[3], guidType
);
4389 check_member( objinst
, expect_objects
[3], "%#x", dwOfs
);
4390 check_member( objinst
, expect_objects
[3], "%#x", dwType
);
4391 check_member( objinst
, expect_objects
[3], "%#x", dwFlags
);
4392 if (!localized
) check_member_wstr( objinst
, expect_objects
[3], tszName
);
4393 check_member( objinst
, expect_objects
[3], "%u", dwFFMaxForce
);
4394 check_member( objinst
, expect_objects
[3], "%u", dwFFForceResolution
);
4395 check_member( objinst
, expect_objects
[3], "%u", wCollectionNumber
);
4396 check_member( objinst
, expect_objects
[3], "%u", wDesignatorIndex
);
4397 check_member( objinst
, expect_objects
[3], "%#04x", wUsagePage
);
4398 check_member( objinst
, expect_objects
[3], "%#04x", wUsage
);
4399 check_member( objinst
, expect_objects
[3], "%#04x", dwDimension
);
4400 check_member( objinst
, expect_objects
[3], "%#04x", wExponent
);
4401 check_member( objinst
, expect_objects
[3], "%u", wReportId
);
4403 hr
= IDirectInputDevice8_SetEventNotification( device
, (HANDLE
)0xdeadbeef );
4405 ok( hr
== E_HANDLE
, "SetEventNotification returned: %#x\n", hr
);
4406 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
4407 ok( event
!= NULL
, "CreateEventW failed, last error %u\n", GetLastError() );
4408 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
4409 ok( hr
== DI_OK
, "SetEventNotification returned: %#x\n", hr
);
4411 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
4412 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
4413 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
4414 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
4416 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, 0 );
4417 ok( hr
== DIERR_INVALIDPARAM
, "SetCooperativeLevel returned: %#x\n", hr
);
4418 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
);
4419 ok( hr
== DIERR_INVALIDPARAM
, "SetCooperativeLevel returned: %#x\n", hr
);
4420 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
4421 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#x\n", hr
);
4422 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
4423 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#x\n", hr
);
4424 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
4425 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#x\n", hr
);
4427 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
4428 NULL
, NULL
, NULL
, NULL
);
4429 SetForegroundWindow( hwnd
);
4431 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
4432 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4433 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
4434 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4435 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
4436 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4438 hr
= IDirectInputDevice8_Unacquire( device
);
4439 ok( hr
== DI_NOEFFECT
, "Unacquire returned: %#x\n", hr
);
4440 hr
= IDirectInputDevice8_Acquire( device
);
4441 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
4442 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
4443 ok( hr
== DIERR_ACQUIRED
, "SetCooperativeLevel returned: %#x\n", hr
);
4444 hr
= IDirectInputDevice8_Unacquire( device
);
4445 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4447 DestroyWindow( hwnd
);
4449 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
4450 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4452 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4453 ok( hr
== DIERR_NOTACQUIRED
, "GetDeviceState returned: %#x\n", hr
);
4455 hr
= IDirectInputDevice8_Poll( device
);
4456 ok( hr
== DIERR_NOTACQUIRED
, "Poll returned: %#x\n", hr
);
4458 hr
= IDirectInputDevice8_Acquire( device
);
4459 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
4461 hr
= IDirectInputDevice8_Poll( device
);
4462 ok( hr
== DI_NOEFFECT
, "Poll returned: %#x\n", hr
);
4464 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
) + 1, &state
);
4465 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceState returned: %#x\n", hr
);
4467 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
4469 winetest_push_context( "state[%d]", i
);
4470 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4471 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4472 check_member( state
, expect_state
[i
], "%d", lX
);
4473 check_member( state
, expect_state
[i
], "%d", lY
);
4474 check_member( state
, expect_state
[i
], "%d", lZ
);
4475 check_member( state
, expect_state
[i
], "%d", lRx
);
4476 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[0] );
4477 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[1] );
4478 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
4479 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
4480 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
4482 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
4484 res
= WaitForSingleObject( event
, 100 );
4485 if (i
== 0 || i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
4486 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4487 ResetEvent( event
);
4488 winetest_pop_context();
4491 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4492 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4493 winetest_push_context( "state[%d]", i
);
4494 check_member( state
, expect_state
[i
], "%d", lX
);
4495 check_member( state
, expect_state
[i
], "%d", lY
);
4496 check_member( state
, expect_state
[i
], "%d", lZ
);
4497 check_member( state
, expect_state
[i
], "%d", lRx
);
4498 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[0] );
4499 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[1] );
4500 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
4501 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
4502 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
4503 winetest_pop_context();
4506 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
) - 1, objdata
, &res
, DIGDD_PEEK
);
4508 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceData returned %#x\n", hr
);
4510 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4511 ok( hr
== DIERR_NOTBUFFERED
, "GetDeviceData returned %#x\n", hr
);
4513 hr
= IDirectInputDevice8_Unacquire( device
);
4514 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4515 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4516 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4517 prop_dword
.dwData
= 1;
4518 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4519 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4520 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4521 prop_dword
.diph
.dwObj
= 0;
4522 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4523 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4524 hr
= IDirectInputDevice8_Acquire( device
);
4525 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4528 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4529 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4530 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4532 send_hid_input( file
, &injected_input
[0], sizeof(*injected_input
) );
4533 res
= WaitForSingleObject( event
, 100 );
4534 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4535 ResetEvent( event
);
4538 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4539 ok( hr
== DI_BUFFEROVERFLOW
, "GetDeviceData returned %#x\n", hr
);
4540 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4542 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4544 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4545 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4547 hr
= IDirectInputDevice8_Unacquire( device
);
4548 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4549 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4550 prop_dword
.diph
.dwObj
= 0;
4551 prop_dword
.dwData
= 10;
4552 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4553 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4554 hr
= IDirectInputDevice8_Acquire( device
);
4555 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4557 send_hid_input( file
, &injected_input
[1], sizeof(*injected_input
) );
4558 res
= WaitForSingleObject( event
, 100 );
4559 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4560 ResetEvent( event
);
4563 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4564 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4565 ok( res
== 1, "got %u expected %u\n", res
, 1 );
4566 check_member( objdata
[0], expect_objdata
[0], "%#x", dwOfs
);
4567 check_member( objdata
[0], expect_objdata
[0], "%#x", dwData
);
4568 ok( objdata
[0].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[0].uAppData
, (void *)-1 );
4570 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4571 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4572 ok( res
== 4, "got %u expected %u\n", res
, 4 );
4573 for (i
= 0; i
< 4; ++i
)
4575 winetest_push_context( "objdata[%d]", i
);
4576 check_member( objdata
[i
], expect_objdata
[1 + i
], "%#x", dwOfs
);
4577 check_member( objdata
[i
], expect_objdata
[1 + i
], "%#x", dwData
);
4578 ok( objdata
[i
].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[i
].uAppData
, (void *)-1 );
4579 winetest_pop_context();
4582 send_hid_input( file
, &injected_input
[2], sizeof(*injected_input
) );
4583 res
= WaitForSingleObject( event
, 100 );
4584 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4585 ResetEvent( event
);
4586 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4587 res
= WaitForSingleObject( event
, 100 );
4588 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4589 ResetEvent( event
);
4592 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4593 ok( hr
== DI_BUFFEROVERFLOW
, "GetDeviceData returned %#x\n", hr
);
4594 ok( res
== 1, "got %u expected %u\n", res
, 1 );
4596 check_member( objdata
[0], expect_objdata
[5], "%#x", dwOfs
);
4598 check_member( objdata
[0], expect_objdata
[5], "%#x", dwData
);
4599 ok( objdata
[0].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[0].uAppData
, (void *)-1 );
4600 res
= ARRAY_SIZE(objdata
);
4601 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4602 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4603 ok( res
== 8, "got %u expected %u\n", res
, 8 );
4604 for (i
= 0; i
< 8; ++i
)
4606 winetest_push_context( "objdata[%d]", i
);
4608 check_member( objdata
[i
], expect_objdata
[6 + i
], "%#x", dwOfs
);
4609 todo_wine_if( i
== 1 || i
== 2 || i
== 6 )
4610 check_member( objdata
[i
], expect_objdata
[6 + i
], "%#x", dwData
);
4611 ok( objdata
[i
].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[i
].uAppData
, (void *)-1 );
4612 winetest_pop_context();
4615 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
4616 res
= WaitForSingleObject( event
, 100 );
4617 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4618 ResetEvent( event
);
4620 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4621 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4622 check_member( state
, expect_state
[3], "%d", lX
);
4623 check_member( state
, expect_state
[3], "%d", lY
);
4624 check_member( state
, expect_state
[3], "%d", lZ
);
4625 check_member( state
, expect_state
[3], "%d", lRx
);
4626 check_member( state
, expect_state
[3], "%d", rgdwPOV
[0] );
4627 check_member( state
, expect_state
[3], "%d", rgdwPOV
[1] );
4628 check_member( state
, expect_state
[3], "%#x", rgbButtons
[0] );
4629 check_member( state
, expect_state
[3], "%#x", rgbButtons
[1] );
4630 check_member( state
, expect_state
[3], "%#x", rgbButtons
[2] );
4632 hr
= IDirectInputDevice8_Unacquire( device
);
4633 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4635 dataformat
.dwSize
= sizeof(DIDATAFORMAT
);
4636 dataformat
.dwObjSize
= sizeof(DIOBJECTDATAFORMAT
);
4637 dataformat
.dwFlags
= DIDF_ABSAXIS
;
4638 dataformat
.dwDataSize
= sizeof(buffer
);
4639 dataformat
.dwNumObjs
= 0;
4640 dataformat
.rgodf
= objdataformat
;
4641 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4642 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4644 dataformat
.dwNumObjs
= 1;
4645 dataformat
.dwDataSize
= 8;
4646 objdataformat
[0].pguid
= NULL
;
4647 objdataformat
[0].dwOfs
= 2;
4648 objdataformat
[0].dwType
= DIDFT_AXIS
|DIDFT_ANYINSTANCE
;
4649 objdataformat
[0].dwFlags
= 0;
4650 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4652 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4653 objdataformat
[0].dwOfs
= 4;
4654 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4655 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4656 dataformat
.dwDataSize
= 10;
4657 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4659 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4660 dataformat
.dwDataSize
= 8;
4661 objdataformat
[0].dwOfs
= 2;
4662 objdataformat
[0].dwType
= DIDFT_OPTIONAL
|0xff|DIDFT_ANYINSTANCE
;
4663 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4665 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4667 dataformat
.dwNumObjs
= 2;
4668 dataformat
.dwDataSize
= 5;
4669 objdataformat
[0].pguid
= NULL
;
4670 objdataformat
[0].dwOfs
= 4;
4671 objdataformat
[0].dwType
= DIDFT_BUTTON
|DIDFT_ANYINSTANCE
;
4672 objdataformat
[0].dwFlags
= 0;
4673 objdataformat
[1].pguid
= NULL
;
4674 objdataformat
[1].dwOfs
= 0;
4675 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4676 objdataformat
[1].dwFlags
= 0;
4677 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4679 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4680 dataformat
.dwDataSize
= 8;
4681 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4682 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4684 dataformat
.dwNumObjs
= 4;
4685 dataformat
.dwDataSize
= 12;
4686 objdataformat
[0].pguid
= NULL
;
4687 objdataformat
[0].dwOfs
= 0;
4688 objdataformat
[0].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4689 objdataformat
[0].dwFlags
= 0;
4690 objdataformat
[1].pguid
= NULL
;
4691 objdataformat
[1].dwOfs
= 0;
4692 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4693 objdataformat
[1].dwFlags
= 0;
4694 objdataformat
[2].pguid
= &GUID_ZAxis
;
4695 objdataformat
[2].dwOfs
= 8;
4696 objdataformat
[2].dwType
= 0xff|DIDFT_ANYINSTANCE
;
4697 objdataformat
[2].dwFlags
= 0;
4698 objdataformat
[3].pguid
= &GUID_POV
;
4699 objdataformat
[3].dwOfs
= 0;
4700 objdataformat
[3].dwType
= 0xff|DIDFT_ANYINSTANCE
;
4701 objdataformat
[3].dwFlags
= 0;
4702 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4703 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4704 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 12 );
4705 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4706 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4707 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0xff );
4708 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4709 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4710 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 1 );
4711 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4712 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4713 objdataformat
[1].pguid
= &GUID_RzAxis
;
4714 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4715 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4716 objdataformat
[1].pguid
= &GUID_Unknown
;
4717 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4718 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4719 objdataformat
[1].pguid
= &GUID_YAxis
;
4720 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4721 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4722 objdataformat
[1].pguid
= NULL
;
4723 objdataformat
[1].dwType
= DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4724 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4725 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4727 dataformat
.dwNumObjs
= 0;
4728 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4729 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4730 hr
= IDirectInputDevice8_Acquire( device
);
4731 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4733 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4734 res
= WaitForSingleObject( event
, 100 );
4736 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject failed\n" );
4737 ResetEvent( event
);
4739 hr
= IDirectInputDevice8_GetDeviceState( device
, dataformat
.dwDataSize
, buffer
);
4740 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4741 hr
= IDirectInputDevice8_Unacquire( device
);
4742 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4744 dataformat
.dwNumObjs
= 4;
4745 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4746 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4747 hr
= IDirectInputDevice8_Acquire( device
);
4748 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4750 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4751 res
= WaitForSingleObject( event
, 100 );
4753 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4754 ResetEvent( event
);
4755 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
4756 res
= WaitForSingleObject( event
, 100 );
4757 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4758 ResetEvent( event
);
4760 hr
= IDirectInputDevice8_GetDeviceState( device
, dataformat
.dwDataSize
, buffer
);
4761 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4762 ok( ((ULONG
*)buffer
)[0] == 0x512b, "got %#x, expected %#x\n", ((ULONG
*)buffer
)[0], 0x512b );
4763 ok( ((ULONG
*)buffer
)[1] == 0, "got %#x, expected %#x\n", ((ULONG
*)buffer
)[1], 0 );
4764 ok( ((ULONG
*)buffer
)[2] == 0x7fff, "got %#x, expected %#x\n", ((ULONG
*)buffer
)[2], 0x7fff );
4765 hr
= IDirectInputDevice8_Unacquire( device
);
4766 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4768 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
4769 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4770 hr
= IDirectInputDevice8_Acquire( device
);
4771 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4773 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4774 res
= WaitForSingleObject( event
, 100 );
4775 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4776 ResetEvent( event
);
4777 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
4778 res
= WaitForSingleObject( event
, 100 );
4779 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4780 ResetEvent( event
);
4782 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4783 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4784 check_member( state
, expect_state
[3], "%d", lX
);
4785 check_member( state
, expect_state
[3], "%d", lY
);
4786 check_member( state
, expect_state
[3], "%d", lZ
);
4787 check_member( state
, expect_state
[3], "%d", lRx
);
4788 check_member( state
, expect_state
[3], "%d", rgdwPOV
[0] );
4789 check_member( state
, expect_state
[3], "%d", rgdwPOV
[1] );
4790 check_member( state
, expect_state
[3], "%#x", rgbButtons
[0] );
4791 check_member( state
, expect_state
[3], "%#x", rgbButtons
[1] );
4792 check_member( state
, expect_state
[3], "%#x", rgbButtons
[2] );
4794 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
4795 prop_range
.diph
.dwObj
= 0;
4796 prop_range
.lMin
= 1000;
4797 prop_range
.lMax
= 51000;
4798 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4799 ok( hr
== DI_OK
, "SetProperty DIPROP_RANGE returned %#x\n", hr
);
4800 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4801 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4802 prop_range
.lMin
= -4000;
4803 prop_range
.lMax
= -14000;
4804 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4805 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_RANGE returned %#x\n", hr
);
4806 prop_range
.lMin
= -14000;
4807 prop_range
.lMax
= -4000;
4808 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4809 ok( hr
== DI_OK
, "SetProperty DIPROP_RANGE returned %#x\n", hr
);
4810 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4811 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4812 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4813 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4815 hr
= IDirectInputDevice8_Unacquire( device
);
4816 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4817 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4818 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4819 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4820 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4821 hr
= IDirectInputDevice8_Acquire( device
);
4822 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4824 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
4825 prop_range
.diph
.dwObj
= 0;
4826 prop_range
.lMin
= 0xdeadbeef;
4827 prop_range
.lMax
= 0xdeadbeef;
4828 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4829 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4830 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4831 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4832 prop_range
.lMin
= 0xdeadbeef;
4833 prop_range
.lMax
= 0xdeadbeef;
4834 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4835 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4836 ok( prop_range
.lMin
== -14000, "got %d expected %d\n", prop_range
.lMin
, -14000 );
4837 ok( prop_range
.lMax
== -4000, "got %d expected %d\n", prop_range
.lMax
, -4000 );
4838 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4839 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
4840 prop_range
.lMin
= 0xdeadbeef;
4841 prop_range
.lMax
= 0xdeadbeef;
4842 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4843 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4844 ok( prop_range
.lMin
== 1000, "got %d expected %d\n", prop_range
.lMin
, 1000 );
4845 ok( prop_range
.lMax
== 51000, "got %d expected %d\n", prop_range
.lMax
, 51000 );
4847 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4848 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4849 check_member( state
, expect_state_abs
[1], "%d", lX
);
4850 check_member( state
, expect_state_abs
[1], "%d", lY
);
4851 check_member( state
, expect_state_abs
[1], "%d", lZ
);
4852 check_member( state
, expect_state_abs
[1], "%d", lRx
);
4853 check_member( state
, expect_state_abs
[1], "%d", rgdwPOV
[0] );
4854 check_member( state
, expect_state_abs
[1], "%d", rgdwPOV
[1] );
4855 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[0] );
4856 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[1] );
4857 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[2] );
4859 hr
= IDirectInputDevice8_SetProperty( device
, NULL
, NULL
);
4860 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4861 hr
= IDirectInputDevice8_SetProperty( device
, &GUID_NULL
, NULL
);
4862 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4863 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, NULL
);
4864 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4865 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
4866 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4868 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4869 prop_dword
.diph
.dwObj
= 0;
4870 prop_dword
.dwData
= 0xdeadbeef;
4871 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
4872 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_VIDPID returned %#x\n", hr
);
4873 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
4874 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
4876 prop_string
.diph
.dwHow
= DIPH_DEVICE
;
4877 prop_string
.diph
.dwObj
= 0;
4878 wcscpy( prop_string
.wsz
, L
"instance name" );
4879 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
4880 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_INSTANCENAME returned %#x\n", hr
);
4882 wcscpy( prop_string
.wsz
, L
"product name" );
4883 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4885 ok( hr
== DI_OK
, "SetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4886 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4887 ok( hr
== DI_OK
, "GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4889 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
4890 debugstr_w(prop_string
.wsz
) );
4892 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
4893 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_TYPENAME returned %#x\n", hr
);
4894 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
4895 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_USERNAME returned %#x\n", hr
);
4896 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4897 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_FFLOAD returned %#x\n", hr
);
4898 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
4899 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
4901 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
4903 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
4904 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4905 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4906 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4907 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4908 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
4909 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
4910 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
4911 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4912 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
4914 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_APPDATA returned %#x\n", hr
);
4916 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4917 prop_dword
.diph
.dwObj
= 0;
4918 prop_dword
.dwData
= 10001;
4919 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4920 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4921 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4922 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4923 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4924 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4925 prop_dword
.dwData
= 1000;
4926 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4927 ok( hr
== DI_OK
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4928 prop_dword
.dwData
= 6000;
4929 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4930 ok( hr
== DI_OK
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4931 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_COOKED
;
4932 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4933 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4935 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4936 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4937 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4938 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4939 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4940 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4942 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4943 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4944 prop_dword
.dwData
= 2000;
4945 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4946 ok( hr
== DI_OK
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4947 ok( prop_dword
.dwData
== 2000, "got %u expected %u\n", prop_dword
.dwData
, 2000 );
4948 prop_dword
.dwData
= 7000;
4949 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4950 ok( hr
== DI_OK
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4952 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4953 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4954 prop_dword
.dwData
= 0xdeadbeef;
4955 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4956 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4957 ok( prop_dword
.dwData
== 2000, "got %u expected %u\n", prop_dword
.dwData
, 2000 );
4958 prop_dword
.dwData
= 0xdeadbeef;
4959 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4960 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4961 ok( prop_dword
.dwData
== 7000, "got %u expected %u\n", prop_dword
.dwData
, 7000 );
4963 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4964 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
4965 prop_dword
.dwData
= 0xdeadbeef;
4966 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4967 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4968 ok( prop_dword
.dwData
== 1000, "got %u expected %u\n", prop_dword
.dwData
, 1000 );
4969 prop_dword
.dwData
= 0xdeadbeef;
4970 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4971 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4972 ok( prop_dword
.dwData
== 6000, "got %u expected %u\n", prop_dword
.dwData
, 6000 );
4974 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
4976 winetest_push_context( "state[%d]", i
);
4977 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4978 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4979 if (broken( state
.lX
== -10750 )) win_skip( "Ignoring 32-bit rounding\n" );
4982 check_member( state
, expect_state_abs
[i
], "%d", lX
);
4983 check_member( state
, expect_state_abs
[i
], "%d", lY
);
4985 check_member( state
, expect_state_abs
[i
], "%d", lZ
);
4986 check_member( state
, expect_state_abs
[i
], "%d", lRx
);
4987 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[0] );
4988 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[1] );
4989 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
4990 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
4991 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
4993 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
4995 res
= WaitForSingleObject( event
, 100 );
4996 if (i
== 0 || i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
4997 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4998 ResetEvent( event
);
4999 winetest_pop_context();
5002 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5003 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5004 winetest_push_context( "state[%d]", i
);
5005 check_member( state
, expect_state_abs
[i
], "%d", lX
);
5006 check_member( state
, expect_state_abs
[i
], "%d", lY
);
5007 check_member( state
, expect_state_abs
[i
], "%d", lZ
);
5008 check_member( state
, expect_state_abs
[i
], "%d", lRx
);
5009 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[0] );
5010 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[1] );
5011 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
5012 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
5013 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
5014 winetest_pop_context();
5016 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
5017 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
5018 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_RAW
;
5019 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
5020 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
5021 prop_dword
.dwData
= 0xdeadbeef;
5022 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
5023 ok( hr
== DI_OK
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
5024 ok( prop_dword
.dwData
== DIPROPCALIBRATIONMODE_RAW
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPCALIBRATIONMODE_RAW
);
5026 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5027 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5028 winetest_push_context( "state[%d]", i
);
5030 ok( state
.lX
== 15, "got lX %d, expected %d\n" , state
.lX
, 15 );
5031 check_member( state
, expect_state_abs
[0], "%d", lY
);
5032 check_member( state
, expect_state_abs
[0], "%d", lZ
);
5033 check_member( state
, expect_state_abs
[0], "%d", lRx
);
5034 check_member( state
, expect_state_abs
[0], "%d", rgdwPOV
[0] );
5035 check_member( state
, expect_state_abs
[0], "%d", rgdwPOV
[1] );
5036 winetest_pop_context();
5038 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_COOKED
;
5039 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
5040 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
5042 send_hid_input( file
, &injected_input
[ARRAY_SIZE(injected_input
) - 1], sizeof(*injected_input
) );
5043 res
= WaitForSingleObject( event
, 100 );
5044 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
5046 hr
= IDirectInputDevice8_Unacquire( device
);
5047 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5049 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
5050 prop_dword
.diph
.dwObj
= 0;
5051 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
5052 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
5053 prop_dword
.dwData
= 0x1000;
5054 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
5055 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
5056 prop_dword
.dwData
= 0xdeadbeef;
5057 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
5058 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
5059 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
5060 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
5061 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
5062 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
5063 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
5064 prop_pointer
.uData
= 0xfeedcafe;
5065 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
5066 ok( hr
== DI_OK
, "SetProperty DIPROP_APPDATA returned %#x\n", hr
);
5068 prop_dword
.dwData
= 0xdeadbeef;
5069 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
5070 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
5071 prop_dword
.dwData
= DIPROPAXISMODE_REL
;
5072 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
5073 ok( hr
== DI_OK
, "SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
5075 hr
= IDirectInputDevice8_Acquire( device
);
5076 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5078 prop_dword
.dwData
= 0xdeadbeef;
5079 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
5081 ok( hr
== DI_OK
, "GetProperty DIPROP_AXISMODE returned %#x\n", hr
);
5083 ok( prop_dword
.dwData
== DIPROPAXISMODE_REL
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_REL
);
5085 prop_dword
.dwData
= 0xdeadbeef;
5086 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
5087 ok( hr
== DI_OK
, "GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
5088 ok( prop_dword
.dwData
== 0x1000, "got %#x expected %#x\n", prop_dword
.dwData
, 0x1000 );
5090 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
5091 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
5092 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
5094 ok( hr
== DI_OK
, "GetProperty DIPROP_APPDATA returned %#x\n", hr
);
5095 ok( prop_pointer
.uData
== 0xfeedcafe, "got %p expected %p\n", (void *)prop_pointer
.uData
, (void *)0xfeedcafe );
5097 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
5098 prop_dword
.diph
.dwObj
= 0;
5099 prop_dword
.dwData
= 0xdeadbeef;
5100 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
5101 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
5102 prop_dword
.dwData
= 1000;
5103 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
5104 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
5106 prop_dword
.dwData
= 0xdeadbeef;
5107 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
5109 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_CALIBRATION returned %#x\n", hr
);
5110 prop_dword
.dwData
= 0xdeadbeef;
5111 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
5112 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
5113 prop_dword
.dwData
= 0xdeadbeef;
5114 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
5115 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
5117 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
5119 winetest_push_context( "state[%d]", i
);
5120 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5121 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5123 check_member( state
, expect_state_rel
[i
], "%d", lX
);
5125 check_member( state
, expect_state_rel
[i
], "%d", lY
);
5127 check_member( state
, expect_state_rel
[i
], "%d", lZ
);
5128 check_member( state
, expect_state_rel
[i
], "%d", lRx
);
5129 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[0] );
5130 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[1] );
5131 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
5132 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
5133 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
5135 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
5137 res
= WaitForSingleObject( event
, 100 );
5138 if (i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
5139 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
5140 ResetEvent( event
);
5141 winetest_pop_context();
5144 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5145 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5146 winetest_push_context( "state[%d]", i
);
5148 check_member( state
, expect_state_rel
[i
], "%d", lX
);
5150 check_member( state
, expect_state_rel
[i
], "%d", lY
);
5152 check_member( state
, expect_state_rel
[i
], "%d", lZ
);
5153 check_member( state
, expect_state_rel
[i
], "%d", lRx
);
5154 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[0] );
5155 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[1] );
5156 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
5157 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
5158 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
5159 winetest_pop_context();
5161 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, NULL
);
5162 ok( hr
== E_POINTER
, "GetForceFeedbackState returned %#x\n", hr
);
5164 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
5165 ok( hr
== DIERR_UNSUPPORTED
, "GetForceFeedbackState returned %#x\n", hr
);
5167 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, 0xdeadbeef );
5168 ok( hr
== DIERR_INVALIDPARAM
, "SendForceFeedbackCommand returned %#x\n", hr
);
5169 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
5170 ok( hr
== DIERR_UNSUPPORTED
, "SendForceFeedbackCommand returned %#x\n", hr
);
5172 objdata
[0].dwOfs
= 0xd;
5173 objdata
[0].dwData
= 0x80;
5175 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0xdeadbeef );
5177 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
5179 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 1 /*DISDD_CONTINUE*/ );
5181 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
5183 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
5185 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
5187 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, NULL
, NULL
);
5188 ok( hr
== E_POINTER
, "CreateEffect returned %#x\n", hr
);
5189 hr
= IDirectInputDevice8_CreateEffect( device
, NULL
, NULL
, &effect
, NULL
);
5190 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5191 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_NULL
, NULL
, &effect
, NULL
);
5192 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5193 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
5194 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5196 hr
= IDirectInputDevice8_Unacquire( device
);
5197 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5199 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
5200 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5202 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, NULL
, effect
, 0 );
5203 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5204 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, effect
, 0xdeadbeef );
5205 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5206 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, (void *)0xdeadbeef, 0 );
5207 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5209 hr
= IDirectInputDevice8_Escape( device
, NULL
);
5211 ok( hr
== E_POINTER
, "Escape returned: %#x\n", hr
);
5212 hr
= IDirectInputDevice8_Escape( device
, &escape
);
5214 ok( hr
== DIERR_INVALIDPARAM
, "Escape returned: %#x\n", hr
);
5215 escape
.dwSize
= sizeof(DIEFFESCAPE
) + 1;
5216 hr
= IDirectInputDevice8_Escape( device
, &escape
);
5218 ok( hr
== DIERR_INVALIDPARAM
, "Escape returned: %#x\n", hr
);
5219 escape
.dwSize
= sizeof(DIEFFESCAPE
);
5220 escape
.dwCommand
= 0;
5221 escape
.lpvInBuffer
= buffer
;
5222 escape
.cbInBuffer
= 10;
5223 escape
.lpvOutBuffer
= buffer
+ 10;
5224 escape
.cbOutBuffer
= 10;
5225 hr
= IDirectInputDevice8_Escape( device
, &escape
);
5227 ok( hr
== DIERR_UNSUPPORTED
, "Escape returned: %#x\n", hr
);
5229 ref
= IDirectInputDevice8_Release( device
);
5230 ok( ref
== 0, "Release returned %d\n", ref
);
5232 CloseHandle( event
);
5233 CloseHandle( file
);
5237 cleanup_registry_keys();
5238 SetCurrentDirectoryW( cwd
);
5243 const BYTE
*report_desc_buf
;
5244 ULONG report_desc_len
;
5248 static BOOL
test_device_types( DWORD version
)
5250 #include "psh_hid_macros.h"
5251 static const unsigned char unknown_desc
[] =
5253 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5254 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5255 COLLECTION(1, Application
),
5256 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5257 COLLECTION(1, Physical
),
5258 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5259 USAGE_MINIMUM(1, 1),
5260 USAGE_MAXIMUM(1, 6),
5261 LOGICAL_MINIMUM(1, 0),
5262 LOGICAL_MAXIMUM(1, 1),
5263 PHYSICAL_MINIMUM(1, 0),
5264 PHYSICAL_MAXIMUM(1, 1),
5267 INPUT(1, Data
|Var
|Abs
),
5271 static const unsigned char limited_desc
[] =
5273 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5274 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5275 COLLECTION(1, Application
),
5276 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5277 COLLECTION(1, Physical
),
5278 USAGE(1, HID_USAGE_GENERIC_X
),
5279 USAGE(1, HID_USAGE_GENERIC_Y
),
5280 LOGICAL_MINIMUM(1, 0),
5281 LOGICAL_MAXIMUM(1, 127),
5282 PHYSICAL_MINIMUM(1, 0),
5283 PHYSICAL_MAXIMUM(1, 127),
5286 INPUT(1, Data
|Var
|Abs
),
5288 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5289 USAGE_MINIMUM(1, 1),
5290 USAGE_MAXIMUM(1, 6),
5291 LOGICAL_MINIMUM(1, 0),
5292 LOGICAL_MAXIMUM(1, 1),
5293 PHYSICAL_MINIMUM(1, 0),
5294 PHYSICAL_MAXIMUM(1, 1),
5297 INPUT(1, Data
|Var
|Abs
),
5301 static const unsigned char gamepad_desc
[] =
5303 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5304 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
5305 COLLECTION(1, Application
),
5306 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
5307 COLLECTION(1, Physical
),
5308 USAGE(1, HID_USAGE_GENERIC_X
),
5309 USAGE(1, HID_USAGE_GENERIC_Y
),
5310 LOGICAL_MINIMUM(1, 0),
5311 LOGICAL_MAXIMUM(1, 127),
5312 PHYSICAL_MINIMUM(1, 0),
5313 PHYSICAL_MAXIMUM(1, 127),
5316 INPUT(1, Data
|Var
|Abs
),
5318 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5319 USAGE_MINIMUM(1, 1),
5320 USAGE_MAXIMUM(1, 6),
5321 LOGICAL_MINIMUM(1, 0),
5322 LOGICAL_MAXIMUM(1, 1),
5323 PHYSICAL_MINIMUM(1, 0),
5324 PHYSICAL_MAXIMUM(1, 1),
5327 INPUT(1, Data
|Var
|Abs
),
5331 static const unsigned char joystick_desc
[] =
5333 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5334 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5335 COLLECTION(1, Application
),
5336 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5337 COLLECTION(1, Physical
),
5338 USAGE(1, HID_USAGE_GENERIC_X
),
5339 USAGE(1, HID_USAGE_GENERIC_Y
),
5340 USAGE(1, HID_USAGE_GENERIC_Z
),
5341 LOGICAL_MINIMUM(1, 0),
5342 LOGICAL_MAXIMUM(1, 127),
5343 PHYSICAL_MINIMUM(1, 0),
5344 PHYSICAL_MAXIMUM(1, 127),
5347 INPUT(1, Data
|Var
|Abs
),
5349 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
5350 LOGICAL_MINIMUM(1, 1),
5351 LOGICAL_MAXIMUM(1, 8),
5352 PHYSICAL_MINIMUM(1, 0),
5353 PHYSICAL_MAXIMUM(1, 8),
5356 INPUT(1, Data
|Var
|Abs
|Null
),
5358 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5359 USAGE_MINIMUM(1, 1),
5360 USAGE_MAXIMUM(1, 5),
5361 LOGICAL_MINIMUM(1, 0),
5362 LOGICAL_MAXIMUM(1, 1),
5363 PHYSICAL_MINIMUM(1, 0),
5364 PHYSICAL_MAXIMUM(1, 1),
5367 INPUT(1, Data
|Var
|Abs
),
5371 #include "pop_hid_macros.h"
5373 static struct device_desc device_desc
[] =
5376 .report_desc_buf
= unknown_desc
,
5377 .report_desc_len
= sizeof(unknown_desc
),
5380 .InputReportByteLength
= 1,
5384 .report_desc_buf
= limited_desc
,
5385 .report_desc_len
= sizeof(limited_desc
),
5388 .InputReportByteLength
= 3,
5392 .report_desc_buf
= gamepad_desc
,
5393 .report_desc_len
= sizeof(gamepad_desc
),
5396 .InputReportByteLength
= 3,
5400 .report_desc_buf
= joystick_desc
,
5401 .report_desc_len
= sizeof(joystick_desc
),
5404 .InputReportByteLength
= 5,
5408 const DIDEVCAPS expect_caps
[] =
5411 .dwSize
= sizeof(DIDEVCAPS
),
5412 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5413 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPESUPPLEMENTAL_UNKNOWN
<< 8)|DI8DEVTYPE_SUPPLEMENTAL
5414 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5418 .dwSize
= sizeof(DIDEVCAPS
),
5419 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5420 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_LIMITED
<< 8)|DI8DEVTYPE_JOYSTICK
5421 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5426 .dwSize
= sizeof(DIDEVCAPS
),
5427 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5428 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEGAMEPAD_STANDARD
<< 8)|DI8DEVTYPE_GAMEPAD
5429 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_GAMEPAD
<< 8)|DIDEVTYPE_JOYSTICK
,
5434 .dwSize
= sizeof(DIDEVCAPS
),
5435 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5436 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_STANDARD
<< 8)|DI8DEVTYPE_JOYSTICK
5437 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5444 const DIDEVICEINSTANCEW expect_devinst
[] =
5447 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5448 .guidInstance
= expect_guid_product
,
5449 .guidProduct
= expect_guid_product
,
5450 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPESUPPLEMENTAL_UNKNOWN
<< 8)|DI8DEVTYPE_SUPPLEMENTAL
5451 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5452 .tszInstanceName
= L
"Wine test root driver",
5453 .tszProductName
= L
"Wine test root driver",
5454 .guidFFDriver
= GUID_NULL
,
5455 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5456 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
5459 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5460 .guidInstance
= expect_guid_product
,
5461 .guidProduct
= expect_guid_product
,
5462 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_LIMITED
<< 8)|DI8DEVTYPE_JOYSTICK
5463 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5464 .tszInstanceName
= L
"Wine test root driver",
5465 .tszProductName
= L
"Wine test root driver",
5466 .guidFFDriver
= GUID_NULL
,
5467 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5468 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
5471 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5472 .guidInstance
= expect_guid_product
,
5473 .guidProduct
= expect_guid_product
,
5474 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEGAMEPAD_STANDARD
<< 8)|DI8DEVTYPE_GAMEPAD
5475 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_GAMEPAD
<< 8)|DIDEVTYPE_JOYSTICK
,
5476 .tszInstanceName
= L
"Wine test root driver",
5477 .tszProductName
= L
"Wine test root driver",
5478 .guidFFDriver
= GUID_NULL
,
5479 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5480 .wUsage
= HID_USAGE_GENERIC_GAMEPAD
,
5483 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5484 .guidInstance
= expect_guid_product
,
5485 .guidProduct
= expect_guid_product
,
5486 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_STANDARD
<< 8)|DI8DEVTYPE_JOYSTICK
5487 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5488 .tszInstanceName
= L
"Wine test root driver",
5489 .tszProductName
= L
"Wine test root driver",
5490 .guidFFDriver
= GUID_NULL
,
5491 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5492 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
5496 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
5497 DIDEVCAPS caps
= {.dwSize
= sizeof(DIDEVCAPS
)};
5498 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
5499 IDirectInputDevice8W
*device
;
5500 BOOL success
= TRUE
;
5504 winetest_push_context( "version %#x", version
);
5506 for (i
= 0; i
< ARRAY_SIZE(device_desc
) && success
; ++i
)
5508 winetest_push_context( "desc[%d]", i
);
5509 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
5510 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
5511 SetCurrentDirectoryW( tempdir
);
5513 cleanup_registry_keys();
5514 if (!dinput_driver_start( device_desc
[i
].report_desc_buf
, device_desc
[i
].report_desc_len
,
5515 &device_desc
[i
].hid_caps
, NULL
, 0 ))
5521 if (FAILED(hr
= create_dinput_device( version
, &devinst
, &device
)))
5527 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
5528 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
5529 check_member( devinst
, expect_devinst
[i
], "%d", dwSize
);
5531 check_member_guid( devinst
, expect_devinst
[i
], guidInstance
);
5532 check_member_guid( devinst
, expect_devinst
[i
], guidProduct
);
5533 todo_wine_if( version
<= 0x700 && i
== 3 )
5534 check_member( devinst
, expect_devinst
[i
], "%#x", dwDevType
);
5536 check_member_wstr( devinst
, expect_devinst
[i
], tszInstanceName
);
5538 check_member_wstr( devinst
, expect_devinst
[i
], tszProductName
);
5539 check_member_guid( devinst
, expect_devinst
[i
], guidFFDriver
);
5540 check_member( devinst
, expect_devinst
[i
], "%04x", wUsagePage
);
5541 check_member( devinst
, expect_devinst
[i
], "%04x", wUsage
);
5543 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
5544 ok( hr
== DI_OK
, "GetCapabilities returned %#x\n", hr
);
5545 check_member( caps
, expect_caps
[i
], "%d", dwSize
);
5546 check_member( caps
, expect_caps
[i
], "%#x", dwFlags
);
5547 todo_wine_if( version
<= 0x700 && i
== 3 )
5548 check_member( caps
, expect_caps
[i
], "%#x", dwDevType
);
5549 check_member( caps
, expect_caps
[i
], "%d", dwAxes
);
5550 check_member( caps
, expect_caps
[i
], "%d", dwButtons
);
5551 check_member( caps
, expect_caps
[i
], "%d", dwPOVs
);
5552 check_member( caps
, expect_caps
[i
], "%d", dwFFSamplePeriod
);
5553 check_member( caps
, expect_caps
[i
], "%d", dwFFMinTimeResolution
);
5554 check_member( caps
, expect_caps
[i
], "%d", dwFirmwareRevision
);
5555 check_member( caps
, expect_caps
[i
], "%d", dwHardwareRevision
);
5556 check_member( caps
, expect_caps
[i
], "%d", dwFFDriverVersion
);
5558 ref
= IDirectInputDevice8_Release( device
);
5559 ok( ref
== 0, "Release returned %d\n", ref
);
5563 cleanup_registry_keys();
5564 SetCurrentDirectoryW( cwd
);
5565 winetest_pop_context();
5568 winetest_pop_context();
5573 static void test_periodic_effect( IDirectInputDevice8W
*device
, HANDLE file
, DWORD version
)
5575 struct hid_expect expect_download
[] =
5579 .code
= IOCTL_HID_WRITE_REPORT
,
5582 .report_buf
= {0x05,0x19},
5586 .code
= IOCTL_HID_WRITE_REPORT
,
5589 .report_buf
= {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
5593 .code
= IOCTL_HID_WRITE_REPORT
,
5596 .report_buf
= {0x03,0x01,0x01,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5598 /* start command when DIEP_START is set */
5600 .code
= IOCTL_HID_WRITE_REPORT
,
5603 .report_buf
= {0x02,0x01,0x01,0x01},
5606 struct hid_expect expect_download_2
[] =
5610 .code
= IOCTL_HID_WRITE_REPORT
,
5613 .report_buf
= {0x05,0x19},
5617 .code
= IOCTL_HID_WRITE_REPORT
,
5620 .report_buf
= {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
5624 .code
= IOCTL_HID_WRITE_REPORT
,
5627 .report_buf
= {0x03,0x01,0x02,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5630 struct hid_expect expect_update
[] =
5634 .code
= IOCTL_HID_WRITE_REPORT
,
5637 .report_buf
= {0x03,0x01,0x02,0x08,0xff,0xff,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5640 struct hid_expect expect_set_envelope
[] =
5644 .code
= IOCTL_HID_WRITE_REPORT
,
5647 .report_buf
= {0x06,0x19,0x4c,0x01,0x00,0x04,0x00},
5650 struct hid_expect expect_start
=
5652 .code
= IOCTL_HID_WRITE_REPORT
,
5655 .report_buf
= {0x02, 0x01, 0x01, 0x01},
5657 struct hid_expect expect_start_solo
=
5659 .code
= IOCTL_HID_WRITE_REPORT
,
5662 .report_buf
= {0x02, 0x01, 0x02, 0x01},
5664 struct hid_expect expect_start_0
=
5666 .code
= IOCTL_HID_WRITE_REPORT
,
5669 .report_buf
= {0x02, 0x01, 0x01, 0x00},
5671 struct hid_expect expect_start_4
=
5673 .code
= IOCTL_HID_WRITE_REPORT
,
5676 .report_buf
= {0x02, 0x01, 0x01, 0x04},
5678 struct hid_expect expect_stop
=
5680 .code
= IOCTL_HID_WRITE_REPORT
,
5683 .report_buf
= {0x02, 0x01, 0x03, 0x00},
5685 struct hid_expect expect_unload
[] =
5688 .code
= IOCTL_HID_WRITE_REPORT
,
5691 .report_buf
= {0x02,0x01,0x03,0x00},
5693 /* device reset, when unloaded from Unacquire */
5695 .code
= IOCTL_HID_WRITE_REPORT
,
5698 .report_buf
= {1,0x01},
5701 struct hid_expect expect_acquire
[] =
5704 .code
= IOCTL_HID_WRITE_REPORT
,
5707 .report_buf
= {1, 0x01},
5710 .code
= IOCTL_HID_WRITE_REPORT
,
5713 .report_buf
= {8, 0x19},
5716 struct hid_expect expect_reset
[] =
5719 .code
= IOCTL_HID_WRITE_REPORT
,
5722 .report_buf
= {1, 0x01},
5725 static const DWORD expect_axes_init
[2] = {0};
5726 const DIEFFECT expect_desc_init
=
5728 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
5729 .dwTriggerButton
= -1,
5730 .rgdwAxes
= (void *)expect_axes_init
,
5732 static const DWORD expect_axes
[3] =
5734 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
5735 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
5736 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
5738 static const LONG expect_directions
[3] =
5744 static const DIENVELOPE expect_envelope
=
5746 .dwSize
= sizeof(DIENVELOPE
),
5747 .dwAttackLevel
= 1000,
5748 .dwAttackTime
= 2000,
5749 .dwFadeLevel
= 3000,
5752 static const DIPERIODIC expect_periodic
=
5754 .dwMagnitude
= 1000,
5759 const DIEFFECT expect_desc
=
5761 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
5762 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
5764 .dwSamplePeriod
= 2000,
5766 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
5767 .dwTriggerRepeatInterval
= 5000,
5769 .rgdwAxes
= (void *)expect_axes
,
5770 .rglDirection
= (void *)expect_directions
,
5771 .lpEnvelope
= (void *)&expect_envelope
,
5772 .cbTypeSpecificParams
= sizeof(DIPERIODIC
),
5773 .lpvTypeSpecificParams
= (void *)&expect_periodic
,
5774 .dwStartDelay
= 6000,
5776 struct check_created_effect_params check_params
= {0};
5777 IDirectInputEffect
*effect
;
5778 DIPERIODIC periodic
= {0};
5779 DIENVELOPE envelope
= {0};
5780 LONG directions
[4] = {0};
5781 DIEFFECT desc
= {0};
5782 DWORD axes
[4] = {0};
5783 ULONG i
, ref
, flags
;
5787 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, NULL
, NULL
);
5788 ok( hr
== E_POINTER
, "CreateEffect returned %#x\n", hr
);
5789 hr
= IDirectInputDevice8_CreateEffect( device
, NULL
, NULL
, &effect
, NULL
);
5790 ok( hr
== E_POINTER
, "CreateEffect returned %#x\n", hr
);
5791 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_NULL
, NULL
, &effect
, NULL
);
5792 ok( hr
== DIERR_DEVICENOTREG
, "CreateEffect returned %#x\n", hr
);
5794 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
5795 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
5796 if (hr
!= DI_OK
) return;
5798 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, effect
, 0xdeadbeef );
5799 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5800 check_params
.expect_effect
= effect
;
5801 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_created_effect_objects
, &check_params
, 0 );
5802 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5803 ok( check_params
.count
== 1, "got count %u, expected 1\n", check_params
.count
);
5805 hr
= IDirectInputEffect_Initialize( effect
, NULL
, version
, &GUID_Sine
);
5806 ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#x\n", hr
);
5807 hr
= IDirectInputEffect_Initialize( effect
, instance
, 0x800 - (version
- 0x700), &GUID_Sine
);
5808 if (version
== 0x800)
5811 ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#x\n", hr
);
5816 ok( hr
== DIERR_OLDDIRECTINPUTVERSION
, "Initialize returned %#x\n", hr
);
5818 hr
= IDirectInputEffect_Initialize( effect
, instance
, 0, &GUID_Sine
);
5820 ok( hr
== DIERR_NOTINITIALIZED
, "Initialize returned %#x\n", hr
);
5821 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, NULL
);
5822 ok( hr
== E_POINTER
, "Initialize returned %#x\n", hr
);
5824 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_NULL
);
5825 ok( hr
== DIERR_DEVICENOTREG
, "Initialize returned %#x\n", hr
);
5826 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_Sine
);
5827 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
5828 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_Square
);
5829 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
5831 hr
= IDirectInputEffect_GetEffectGuid( effect
, NULL
);
5832 ok( hr
== E_POINTER
, "GetEffectGuid returned %#x\n", hr
);
5833 hr
= IDirectInputEffect_GetEffectGuid( effect
, &guid
);
5834 ok( hr
== DI_OK
, "GetEffectGuid returned %#x\n", hr
);
5835 ok( IsEqualGUID( &guid
, &GUID_Square
), "got guid %s, expected %s\n", debugstr_guid( &guid
),
5836 debugstr_guid( &GUID_Square
) );
5838 hr
= IDirectInputEffect_GetParameters( effect
, NULL
, 0 );
5839 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5840 hr
= IDirectInputEffect_GetParameters( effect
, NULL
, DIEP_DURATION
);
5841 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5842 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5843 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5844 desc
.dwSize
= sizeof(DIEFFECT_DX5
) + 2;
5845 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5846 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5847 desc
.dwSize
= sizeof(DIEFFECT_DX5
);
5848 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5849 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5850 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_STARTDELAY
);
5851 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5852 desc
.dwSize
= sizeof(DIEFFECT_DX6
);
5853 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5854 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5856 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
5857 hr
= IDirectInputDevice8_Unacquire( device
);
5858 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5859 set_hid_expect( file
, NULL
, 0 );
5860 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
5861 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5862 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
5863 hr
= IDirectInputDevice8_Acquire( device
);
5864 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
5865 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
5867 desc
.dwDuration
= 0xdeadbeef;
5868 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
5869 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5870 check_member( desc
, expect_desc_init
, "%u", dwDuration
);
5871 memset( &desc
, 0xcd, sizeof(desc
) );
5872 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
5874 desc
.dwStartDelay
= 0xdeadbeef;
5875 flags
= DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
|
5876 (version
>= 0x700 ? DIEP_STARTDELAY
: 0);
5877 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, flags
);
5878 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5879 check_member( desc
, expect_desc_init
, "%u", dwSamplePeriod
);
5880 check_member( desc
, expect_desc_init
, "%u", dwGain
);
5881 if (version
>= 0x700) check_member( desc
, expect_desc_init
, "%u", dwStartDelay
);
5882 else ok( desc
.dwStartDelay
== 0xdeadbeef, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
5883 check_member( desc
, expect_desc_init
, "%u", dwTriggerRepeatInterval
);
5885 memset( &desc
, 0xcd, sizeof(desc
) );
5886 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
5888 desc
.lpEnvelope
= NULL
;
5889 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
5890 ok( hr
== E_POINTER
, "GetParameters returned %#x\n", hr
);
5891 desc
.lpEnvelope
= &envelope
;
5892 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
5893 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5894 envelope
.dwSize
= sizeof(DIENVELOPE
);
5895 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
5896 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5900 desc
.rgdwAxes
= NULL
;
5901 desc
.rglDirection
= NULL
;
5902 desc
.lpEnvelope
= NULL
;
5903 desc
.cbTypeSpecificParams
= 0;
5904 desc
.lpvTypeSpecificParams
= NULL
;
5905 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
5906 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5907 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
5908 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5909 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
5910 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5911 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
5912 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5913 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5914 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
5915 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5916 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
5917 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
5918 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5919 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5920 desc
.dwFlags
= DIEFF_OBJECTIDS
;
5921 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5922 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5923 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
5924 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5925 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
5926 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
5927 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5928 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5929 desc
.dwFlags
|= DIEFF_CARTESIAN
;
5930 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5931 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5932 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5933 desc
.dwFlags
|= DIEFF_POLAR
;
5934 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5935 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5936 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5937 desc
.dwFlags
|= DIEFF_SPHERICAL
;
5938 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5939 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5940 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5941 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5943 desc
.dwFlags
|= DIEFF_SPHERICAL
;
5945 desc
.rgdwAxes
= axes
;
5946 desc
.rglDirection
= directions
;
5947 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_DIRECTION
);
5948 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5949 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5950 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[0] );
5951 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[1] );
5952 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
5953 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5955 desc
.dwFlags
|= DIEFF_SPHERICAL
;
5956 desc
.lpEnvelope
= &envelope
;
5957 desc
.cbTypeSpecificParams
= sizeof(periodic
);
5958 desc
.lpvTypeSpecificParams
= &periodic
;
5959 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
5960 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5961 check_member( desc
, expect_desc_init
, "%u", dwDuration
);
5962 check_member( desc
, expect_desc_init
, "%u", dwSamplePeriod
);
5963 check_member( desc
, expect_desc_init
, "%u", dwGain
);
5964 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
5965 check_member( desc
, expect_desc_init
, "%u", dwTriggerRepeatInterval
);
5966 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5967 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[0] );
5968 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[1] );
5969 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
5971 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
5973 check_member( desc
, expect_desc_init
, "%u", cbTypeSpecificParams
);
5974 if (version
>= 0x700) check_member( desc
, expect_desc_init
, "%u", dwStartDelay
);
5975 else ok( desc
.dwStartDelay
== 0xcdcdcdcd, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
5977 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
5978 hr
= IDirectInputDevice8_Unacquire( device
);
5979 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5980 set_hid_expect( file
, NULL
, 0 );
5981 hr
= IDirectInputEffect_Download( effect
);
5982 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Download returned %#x\n", hr
);
5983 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
5984 hr
= IDirectInputDevice8_Acquire( device
);
5985 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
5986 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
5988 hr
= IDirectInputEffect_Download( effect
);
5989 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
5990 hr
= IDirectInputEffect_Unload( effect
);
5991 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
5993 hr
= IDirectInputEffect_SetParameters( effect
, NULL
, DIEP_NODOWNLOAD
);
5994 ok( hr
== E_POINTER
, "SetParameters returned %#x\n", hr
);
5995 memset( &desc
, 0, sizeof(desc
) );
5996 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
);
5997 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
5998 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
5999 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
);
6000 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6002 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
6003 hr
= IDirectInputDevice8_Unacquire( device
);
6004 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
6005 set_hid_expect( file
, NULL
, 0 );
6006 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DURATION
);
6007 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6008 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
6009 hr
= IDirectInputDevice8_Acquire( device
);
6010 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6011 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
6013 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DURATION
| DIEP_NODOWNLOAD
);
6014 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6016 desc
.dwTriggerButton
= -1;
6017 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
6018 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6019 check_member( desc
, expect_desc
, "%u", dwDuration
);
6020 check_member( desc
, expect_desc_init
, "%u", dwSamplePeriod
);
6021 check_member( desc
, expect_desc_init
, "%u", dwGain
);
6022 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
6023 check_member( desc
, expect_desc_init
, "%u", dwTriggerRepeatInterval
);
6024 check_member( desc
, expect_desc_init
, "%u", cAxes
);
6025 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
6026 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
6027 check_member( desc
, expect_desc_init
, "%u", cbTypeSpecificParams
);
6028 check_member( desc
, expect_desc_init
, "%u", dwStartDelay
);
6030 hr
= IDirectInputEffect_Download( effect
);
6031 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6032 hr
= IDirectInputEffect_Unload( effect
);
6033 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6035 flags
= DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
| DIEP_NODOWNLOAD
;
6036 if (version
>= 0x700) flags
|= DIEP_STARTDELAY
;
6037 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
);
6038 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6039 desc
.dwDuration
= 0;
6040 flags
= DIEP_DURATION
| DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
;
6041 if (version
>= 0x700) flags
|= DIEP_STARTDELAY
;
6042 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, flags
);
6043 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6044 check_member( desc
, expect_desc
, "%u", dwDuration
);
6045 check_member( desc
, expect_desc
, "%u", dwSamplePeriod
);
6046 check_member( desc
, expect_desc
, "%u", dwGain
);
6047 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
6048 check_member( desc
, expect_desc
, "%u", dwTriggerRepeatInterval
);
6049 check_member( desc
, expect_desc_init
, "%u", cAxes
);
6050 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
6051 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
6052 check_member( desc
, expect_desc_init
, "%u", cbTypeSpecificParams
);
6053 if (version
>= 0x700) check_member( desc
, expect_desc
, "%u", dwStartDelay
);
6054 else ok( desc
.dwStartDelay
== 0, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
6056 hr
= IDirectInputEffect_Download( effect
);
6057 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6058 hr
= IDirectInputEffect_Unload( effect
);
6059 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6061 desc
.lpEnvelope
= NULL
;
6062 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
6063 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6064 desc
.lpEnvelope
= &envelope
;
6065 envelope
.dwSize
= 0;
6066 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
6067 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6069 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
6070 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6072 desc
.lpEnvelope
= &envelope
;
6073 envelope
.dwSize
= sizeof(DIENVELOPE
);
6074 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
6075 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6076 check_member( envelope
, expect_envelope
, "%u", dwAttackLevel
);
6077 check_member( envelope
, expect_envelope
, "%u", dwAttackTime
);
6078 check_member( envelope
, expect_envelope
, "%u", dwFadeLevel
);
6079 check_member( envelope
, expect_envelope
, "%u", dwFadeTime
);
6081 hr
= IDirectInputEffect_Download( effect
);
6082 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6083 hr
= IDirectInputEffect_Unload( effect
);
6084 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6088 desc
.rgdwAxes
= NULL
;
6089 desc
.rglDirection
= NULL
;
6090 desc
.lpEnvelope
= NULL
;
6091 desc
.cbTypeSpecificParams
= 0;
6092 desc
.lpvTypeSpecificParams
= NULL
;
6093 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
6094 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, flags
| DIEP_NODOWNLOAD
);
6095 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6096 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
6097 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6098 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_NODOWNLOAD
);
6099 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6101 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
6103 desc
.rgdwAxes
= axes
;
6104 desc
.rgdwAxes
[0] = DIJOFS_X
;
6105 desc
.dwTriggerButton
= DIJOFS_BUTTON( 1 );
6106 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6107 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6108 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
6109 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6110 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
6111 ok( hr
== DIERR_ALREADYINITIALIZED
, "SetParameters returned %#x\n", hr
);
6114 desc
.dwFlags
= DIEFF_OBJECTIDS
;
6115 desc
.rgdwAxes
= axes
;
6116 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
6117 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6118 check_member( desc
, expect_desc
, "%u", cAxes
);
6119 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
6120 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6121 check_member( desc
, expect_desc
, "%#x", dwTriggerButton
);
6122 check_member( desc
, expect_desc
, "%u", cAxes
);
6123 check_member( desc
, expect_desc
, "%u", rgdwAxes
[0] );
6124 check_member( desc
, expect_desc
, "%u", rgdwAxes
[1] );
6125 check_member( desc
, expect_desc
, "%u", rgdwAxes
[2] );
6127 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
6128 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
6129 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6130 ok( desc
.dwTriggerButton
== 0x30, "got %#x expected %#x\n", desc
.dwTriggerButton
, 0x30 );
6131 ok( desc
.rgdwAxes
[0] == 8, "got %#x expected %#x\n", desc
.rgdwAxes
[0], 8 );
6132 ok( desc
.rgdwAxes
[1] == 0, "got %#x expected %#x\n", desc
.rgdwAxes
[1], 0 );
6133 ok( desc
.rgdwAxes
[2] == 4, "got %#x expected %#x\n", desc
.rgdwAxes
[2], 4 );
6135 hr
= IDirectInputEffect_Download( effect
);
6136 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6137 hr
= IDirectInputEffect_Unload( effect
);
6138 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6140 desc
.dwFlags
= DIEFF_CARTESIAN
;
6142 desc
.rglDirection
= directions
;
6143 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6144 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6146 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6147 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6148 desc
.dwFlags
= DIEFF_POLAR
;
6150 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6151 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6153 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6154 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6156 desc
.dwFlags
= DIEFF_SPHERICAL
;
6158 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6159 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6160 ok( desc
.dwFlags
== DIEFF_SPHERICAL
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_SPHERICAL
);
6161 check_member( desc
, expect_desc
, "%u", cAxes
);
6162 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6163 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6164 check_member( desc
, expect_desc
, "%u", cAxes
);
6165 ok( desc
.rglDirection
[0] == 3000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 3000 );
6166 ok( desc
.rglDirection
[1] == 30000, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 30000 );
6167 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6168 desc
.dwFlags
= DIEFF_CARTESIAN
;
6170 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6171 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6172 ok( desc
.dwFlags
== DIEFF_CARTESIAN
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_CARTESIAN
);
6173 check_member( desc
, expect_desc
, "%u", cAxes
);
6174 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6175 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6176 check_member( desc
, expect_desc
, "%u", cAxes
);
6177 ok( desc
.rglDirection
[0] == 4330, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 4330 );
6178 ok( desc
.rglDirection
[1] == 2500, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 2500 );
6179 ok( desc
.rglDirection
[2] == -8660, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], -8660 );
6180 desc
.dwFlags
= DIEFF_POLAR
;
6182 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6183 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
6185 hr
= IDirectInputEffect_Download( effect
);
6186 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6187 hr
= IDirectInputEffect_Unload( effect
);
6188 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6190 desc
.cbTypeSpecificParams
= 0;
6191 desc
.lpvTypeSpecificParams
= &periodic
;
6192 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
6193 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6194 desc
.cbTypeSpecificParams
= sizeof(DIPERIODIC
);
6195 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
6196 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6197 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
6198 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6200 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
);
6201 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6202 check_member( periodic
, expect_periodic
, "%u", dwMagnitude
);
6203 check_member( periodic
, expect_periodic
, "%d", lOffset
);
6204 check_member( periodic
, expect_periodic
, "%u", dwPhase
);
6205 check_member( periodic
, expect_periodic
, "%u", dwPeriod
);
6207 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
6208 ok( hr
== DIERR_NOTDOWNLOADED
, "Start returned %#x\n", hr
);
6209 hr
= IDirectInputEffect_Stop( effect
);
6210 ok( hr
== DIERR_NOTDOWNLOADED
, "Stop returned %#x\n", hr
);
6212 set_hid_expect( file
, expect_download
, 3 * sizeof(struct hid_expect
) );
6213 hr
= IDirectInputEffect_Download( effect
);
6214 ok( hr
== DI_OK
, "Download returned %#x\n", hr
);
6215 set_hid_expect( file
, NULL
, 0 );
6217 hr
= IDirectInputEffect_Download( effect
);
6218 ok( hr
== DI_NOEFFECT
, "Download returned %#x\n", hr
);
6220 hr
= IDirectInputEffect_Start( effect
, 1, 0xdeadbeef );
6221 ok( hr
== DIERR_INVALIDPARAM
, "Start returned %#x\n", hr
);
6223 set_hid_expect( file
, &expect_start_solo
, sizeof(expect_start_solo
) );
6224 hr
= IDirectInputEffect_Start( effect
, 1, DIES_SOLO
);
6225 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6226 set_hid_expect( file
, NULL
, 0 );
6228 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
6229 hr
= IDirectInputEffect_Stop( effect
);
6230 ok( hr
== DI_OK
, "Stop returned %#x\n", hr
);
6231 set_hid_expect( file
, NULL
, 0 );
6233 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
6234 hr
= IDirectInputEffect_Start( effect
, 1, 0 );
6235 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6236 set_hid_expect( file
, NULL
, 0 );
6238 set_hid_expect( file
, &expect_start_4
, sizeof(expect_start_4
) );
6239 hr
= IDirectInputEffect_Start( effect
, 4, 0 );
6240 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6241 set_hid_expect( file
, NULL
, 0 );
6243 set_hid_expect( file
, &expect_start_0
, sizeof(expect_start_4
) );
6244 hr
= IDirectInputEffect_Start( effect
, 0, 0 );
6245 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6246 set_hid_expect( file
, NULL
, 0 );
6248 set_hid_expect( file
, expect_unload
, sizeof(struct hid_expect
) );
6249 hr
= IDirectInputEffect_Unload( effect
);
6250 ok( hr
== DI_OK
, "Unload returned %#x\n", hr
);
6251 set_hid_expect( file
, NULL
, 0 );
6253 set_hid_expect( file
, expect_download
, 4 * sizeof(struct hid_expect
) );
6254 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_START
);
6255 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6256 set_hid_expect( file
, NULL
, 0 );
6258 set_hid_expect( file
, expect_unload
, sizeof(struct hid_expect
) );
6259 hr
= IDirectInputEffect_Unload( effect
);
6260 ok( hr
== DI_OK
, "Unload returned %#x\n", hr
);
6261 set_hid_expect( file
, NULL
, 0 );
6263 set_hid_expect( file
, expect_download
, 3 * sizeof(struct hid_expect
) );
6264 hr
= IDirectInputEffect_Download( effect
);
6265 ok( hr
== DI_OK
, "Download returned %#x\n", hr
);
6266 set_hid_expect( file
, NULL
, 0 );
6268 set_hid_expect( file
, expect_unload
, 2 * sizeof(struct hid_expect
) );
6269 hr
= IDirectInputDevice8_Unacquire( device
);
6270 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
6271 set_hid_expect( file
, NULL
, 0 );
6273 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
6274 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Start returned %#x\n", hr
);
6275 hr
= IDirectInputEffect_Stop( effect
);
6276 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Stop returned %#x\n", hr
);
6278 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
6279 hr
= IDirectInputDevice8_Acquire( device
);
6280 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6281 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
6283 hr
= IDirectInputEffect_Unload( effect
);
6284 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6286 ref
= IDirectInputEffect_Release( effect
);
6287 ok( ref
== 0, "Release returned %d\n", ref
);
6289 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
6290 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6292 desc
.dwFlags
= DIEFF_POLAR
| DIEFF_OBJECTIDS
;
6294 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
6295 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
;
6296 desc
.rglDirection
[0] = 3000;
6297 desc
.rglDirection
[1] = 0;
6298 desc
.rglDirection
[2] = 0;
6299 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6300 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6301 desc
.rglDirection
[0] = 0;
6303 desc
.dwFlags
= DIEFF_SPHERICAL
;
6305 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6306 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6307 ok( desc
.dwFlags
== DIEFF_SPHERICAL
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_SPHERICAL
);
6308 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6309 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6310 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6311 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6312 ok( desc
.rglDirection
[0] == 30000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 30000 );
6313 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 0 );
6314 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6316 desc
.dwFlags
= DIEFF_CARTESIAN
;
6318 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6319 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6320 ok( desc
.dwFlags
== DIEFF_CARTESIAN
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_CARTESIAN
);
6321 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6322 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6323 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6324 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6325 ok( desc
.rglDirection
[0] == 5000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 5000 );
6326 ok( desc
.rglDirection
[1] == -8660, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], -8660 );
6327 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6329 desc
.dwFlags
= DIEFF_POLAR
;
6331 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6332 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6333 ok( desc
.dwFlags
== DIEFF_POLAR
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_POLAR
);
6334 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6335 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6336 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6337 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6338 ok( desc
.rglDirection
[0] == 3000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 3000 );
6339 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 0 );
6340 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6342 ref
= IDirectInputEffect_Release( effect
);
6343 ok( ref
== 0, "Release returned %d\n", ref
);
6345 for (i
= 1; i
< 4; i
++)
6347 winetest_push_context( "%u axes", i
);
6348 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
6349 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6351 desc
.dwFlags
= DIEFF_OBJECTIDS
;
6353 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
6354 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
;
6355 desc
.rgdwAxes
[2] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
;
6356 desc
.rglDirection
[0] = 0;
6357 desc
.rglDirection
[1] = 0;
6358 desc
.rglDirection
[2] = 0;
6359 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_NODOWNLOAD
);
6360 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6362 desc
.dwFlags
= DIEFF_CARTESIAN
;
6363 desc
.cAxes
= i
== 3 ? 2 : 3;
6364 desc
.rglDirection
[0] = 1000;
6365 desc
.rglDirection
[1] = 2000;
6366 desc
.rglDirection
[2] = 3000;
6367 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6368 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6370 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6371 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6373 desc
.dwFlags
= DIEFF_SPHERICAL
;
6375 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6376 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6378 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
6379 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6380 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6381 ok( desc
.cAxes
== i
, "got cAxes %u expected 2\n", desc
.cAxes
);
6384 ok( desc
.rglDirection
[0] == 0, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 0 );
6385 ok( desc
.rglDirection
[1] == 0xcdcdcdcd, "got rglDirection[1] %d expected %d\n",
6386 desc
.rglDirection
[1], 0xcdcdcdcd );
6387 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6388 desc
.rglDirection
[2], 0xcdcdcdcd );
6392 ok( desc
.rglDirection
[0] == 6343, "got rglDirection[0] %d expected %d\n",
6393 desc
.rglDirection
[0], 6343 );
6396 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n",
6397 desc
.rglDirection
[1], 0 );
6398 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6399 desc
.rglDirection
[2], 0xcdcdcdcd );
6403 ok( desc
.rglDirection
[1] == 5330, "got rglDirection[1] %d expected %d\n",
6404 desc
.rglDirection
[1], 5330 );
6405 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n",
6406 desc
.rglDirection
[2], 0 );
6410 desc
.dwFlags
= DIEFF_CARTESIAN
;
6412 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6413 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6415 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
6416 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6417 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6418 ok( desc
.cAxes
== i
, "got cAxes %u expected 2\n", desc
.cAxes
);
6419 ok( desc
.rglDirection
[0] == 1000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 1000 );
6421 ok( desc
.rglDirection
[1] == 0xcdcdcdcd, "got rglDirection[1] %d expected %d\n",
6422 desc
.rglDirection
[1], 0xcdcdcdcd );
6424 ok( desc
.rglDirection
[1] == 2000, "got rglDirection[1] %d expected %d\n",
6425 desc
.rglDirection
[1], 2000 );
6427 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6428 desc
.rglDirection
[2], 0xcdcdcdcd );
6430 ok( desc
.rglDirection
[2] == 3000, "got rglDirection[2] %d expected %d\n",
6431 desc
.rglDirection
[2], 3000 );
6433 desc
.dwFlags
= DIEFF_POLAR
;
6435 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6436 if (i
!= 2) ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
6437 else ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6439 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
6440 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6441 if (i
!= 2) ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
6444 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6445 ok( desc
.cAxes
== i
, "got cAxes %u expected 2\n", desc
.cAxes
);
6446 ok( desc
.rglDirection
[0] == 15343, "got rglDirection[0] %d expected %d\n",
6447 desc
.rglDirection
[0], 15343 );
6448 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 0 );
6449 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6450 desc
.rglDirection
[2], 0xcdcdcdcd );
6453 ref
= IDirectInputEffect_Release( effect
);
6454 ok( ref
== 0, "Release returned %d\n", ref
);
6455 winetest_pop_context();
6458 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
6459 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6461 set_hid_expect( file
, expect_download_2
, sizeof(expect_download_2
) );
6462 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
6463 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
);
6464 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6465 set_hid_expect( file
, NULL
, 0 );
6467 desc
.dwDuration
= INFINITE
;
6468 desc
.dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
6469 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
|DIEP_DURATION
|DIEP_TRIGGERBUTTON
);
6470 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6471 set_hid_expect( file
, expect_update
, sizeof(expect_update
) );
6472 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
6473 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6474 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
6476 desc
.dwDuration
= INFINITE
;
6477 desc
.dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
6478 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
|DIEP_DURATION
|DIEP_TRIGGERBUTTON
);
6479 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6480 set_hid_expect( file
, expect_update
, sizeof(expect_update
) );
6481 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
6482 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6483 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
6486 desc
.lpEnvelope
= &envelope
;
6487 desc
.lpEnvelope
->dwAttackTime
= 1000;
6488 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
|DIEP_ENVELOPE
);
6489 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6490 set_hid_expect( file
, expect_set_envelope
, sizeof(expect_set_envelope
) );
6491 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
6492 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6493 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
6495 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
6496 ref
= IDirectInputEffect_Release( effect
);
6497 ok( ref
== 0, "Release returned %d\n", ref
);
6498 set_hid_expect( file
, NULL
, 0 );
6500 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
6501 hr
= IDirectInputDevice8_Unacquire( device
);
6502 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6503 set_hid_expect( file
, NULL
, 0 );
6504 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, &expect_desc
, &effect
, NULL
);
6505 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6506 ref
= IDirectInputEffect_Release( effect
);
6507 ok( ref
== 0, "Release returned %d\n", ref
);
6508 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
6509 hr
= IDirectInputDevice8_Acquire( device
);
6510 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6511 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
6514 static void test_condition_effect( IDirectInputDevice8W
*device
, HANDLE file
, DWORD version
)
6516 struct hid_expect expect_create
[] =
6520 .code
= IOCTL_HID_WRITE_REPORT
,
6523 .report_buf
= {0x07,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
6527 .code
= IOCTL_HID_WRITE_REPORT
,
6530 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6534 .code
= IOCTL_HID_WRITE_REPORT
,
6537 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
6540 struct hid_expect expect_create_1
[] =
6544 .code
= IOCTL_HID_WRITE_REPORT
,
6547 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6551 .code
= IOCTL_HID_WRITE_REPORT
,
6554 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x3f,0x00},
6557 struct hid_expect expect_create_2
[] =
6561 .code
= IOCTL_HID_WRITE_REPORT
,
6564 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6568 .code
= IOCTL_HID_WRITE_REPORT
,
6571 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xf1},
6574 struct hid_expect expect_create_3
[] =
6578 .code
= IOCTL_HID_WRITE_REPORT
,
6581 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6585 .code
= IOCTL_HID_WRITE_REPORT
,
6588 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
6591 struct hid_expect expect_destroy
=
6593 .code
= IOCTL_HID_WRITE_REPORT
,
6596 .report_buf
= {0x02, 0x01, 0x03, 0x00},
6598 static const DWORD expect_axes
[3] =
6600 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
6601 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
6602 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
6604 static const LONG expect_directions
[3] = {
6609 static const DIENVELOPE expect_envelope
=
6611 .dwSize
= sizeof(DIENVELOPE
),
6612 .dwAttackLevel
= 1000,
6613 .dwAttackTime
= 2000,
6614 .dwFadeLevel
= 3000,
6617 static const DICONDITION expect_condition
[3] =
6621 .lPositiveCoefficient
= 2000,
6622 .lNegativeCoefficient
= -3000,
6623 .dwPositiveSaturation
= -4000,
6624 .dwNegativeSaturation
= -5000,
6629 .lPositiveCoefficient
= 5000,
6630 .lNegativeCoefficient
= -4000,
6631 .dwPositiveSaturation
= 3000,
6632 .dwNegativeSaturation
= 2000,
6637 .lPositiveCoefficient
= -8000,
6638 .lNegativeCoefficient
= 9000,
6639 .dwPositiveSaturation
= 10000,
6640 .dwNegativeSaturation
= 11000,
6641 .lDeadBand
= -12000,
6644 const DIEFFECT expect_desc
=
6646 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
6647 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
6649 .dwSamplePeriod
= 2000,
6651 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
6652 .dwTriggerRepeatInterval
= 5000,
6654 .rgdwAxes
= (void *)expect_axes
,
6655 .rglDirection
= (void *)expect_directions
,
6656 .lpEnvelope
= (void *)&expect_envelope
,
6657 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
6658 .lpvTypeSpecificParams
= (void *)expect_condition
,
6659 .dwStartDelay
= 6000,
6661 struct check_created_effect_params check_params
= {0};
6662 DIENVELOPE envelope
=
6663 {.dwSize
= sizeof(DIENVELOPE
)};
6664 DICONDITION condition
[2] = {0};
6665 IDirectInputEffect
*effect
;
6666 LONG directions
[4] = {0};
6667 DWORD axes
[4] = {0};
6670 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
6671 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
6674 .rglDirection
= directions
,
6675 .lpEnvelope
= &envelope
,
6676 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
6677 .lpvTypeSpecificParams
= condition
,
6683 set_hid_expect( file
, expect_create
, sizeof(expect_create
) );
6684 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &expect_desc
, &effect
, NULL
);
6685 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6686 set_hid_expect( file
, NULL
, 0 );
6688 check_params
.expect_effect
= effect
;
6689 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_created_effect_objects
, &check_params
, 0 );
6690 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#x\n", hr
);
6691 ok( check_params
.count
== 1, "got count %u, expected 1\n", check_params
.count
);
6693 hr
= IDirectInputEffect_GetEffectGuid( effect
, &guid
);
6694 ok( hr
== DI_OK
, "GetEffectGuid returned %#x\n", hr
);
6695 ok( IsEqualGUID( &guid
, &GUID_Spring
), "got guid %s, expected %s\n", debugstr_guid( &guid
),
6696 debugstr_guid( &GUID_Spring
) );
6698 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
6699 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6700 check_member( desc
, expect_desc
, "%u", dwDuration
);
6701 check_member( desc
, expect_desc
, "%u", dwSamplePeriod
);
6702 check_member( desc
, expect_desc
, "%u", dwGain
);
6703 check_member( desc
, expect_desc
, "%#x", dwTriggerButton
);
6704 check_member( desc
, expect_desc
, "%u", dwTriggerRepeatInterval
);
6705 check_member( desc
, expect_desc
, "%u", cAxes
);
6706 check_member( desc
, expect_desc
, "%#x", rgdwAxes
[0] );
6707 check_member( desc
, expect_desc
, "%#x", rgdwAxes
[1] );
6708 check_member( desc
, expect_desc
, "%d", rglDirection
[0] );
6709 check_member( desc
, expect_desc
, "%d", rglDirection
[1] );
6710 check_member( desc
, expect_desc
, "%u", cbTypeSpecificParams
);
6711 if (version
>= 0x700) check_member( desc
, expect_desc
, "%u", dwStartDelay
);
6712 else ok( desc
.dwStartDelay
== 0, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
6713 check_member( envelope
, expect_envelope
, "%u", dwAttackLevel
);
6714 check_member( envelope
, expect_envelope
, "%u", dwAttackTime
);
6715 check_member( envelope
, expect_envelope
, "%u", dwFadeLevel
);
6716 check_member( envelope
, expect_envelope
, "%u", dwFadeTime
);
6717 check_member( condition
[0], expect_condition
[0], "%d", lOffset
);
6718 check_member( condition
[0], expect_condition
[0], "%d", lPositiveCoefficient
);
6719 check_member( condition
[0], expect_condition
[0], "%d", lNegativeCoefficient
);
6720 check_member( condition
[0], expect_condition
[0], "%u", dwPositiveSaturation
);
6721 check_member( condition
[0], expect_condition
[0], "%u", dwNegativeSaturation
);
6722 check_member( condition
[0], expect_condition
[0], "%d", lDeadBand
);
6723 check_member( condition
[1], expect_condition
[1], "%d", lOffset
);
6724 check_member( condition
[1], expect_condition
[1], "%d", lPositiveCoefficient
);
6725 check_member( condition
[1], expect_condition
[1], "%d", lNegativeCoefficient
);
6726 check_member( condition
[1], expect_condition
[1], "%u", dwPositiveSaturation
);
6727 check_member( condition
[1], expect_condition
[1], "%u", dwNegativeSaturation
);
6728 check_member( condition
[1], expect_condition
[1], "%d", lDeadBand
);
6730 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6731 ref
= IDirectInputEffect_Release( effect
);
6732 ok( ref
== 0, "Release returned %d\n", ref
);
6733 set_hid_expect( file
, NULL
, 0 );
6737 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6738 ok( hr
== DIERR_INVALIDPARAM
, "CreateEffect returned %#x\n", hr
);
6739 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
6740 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
6741 set_hid_expect( file
, expect_create_1
, sizeof(expect_create_1
) );
6742 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6743 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6744 set_hid_expect( file
, NULL
, 0 );
6746 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6747 ref
= IDirectInputEffect_Release( effect
);
6748 ok( ref
== 0, "Release returned %d\n", ref
);
6749 set_hid_expect( file
, NULL
, 0 );
6753 desc
.rglDirection
= directions
;
6754 desc
.rglDirection
[0] = +3000;
6755 desc
.rglDirection
[1] = -2000;
6756 desc
.rglDirection
[2] = +1000;
6757 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
6758 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
6759 set_hid_expect( file
, expect_create_2
, sizeof(expect_create_2
) );
6760 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6761 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6762 set_hid_expect( file
, NULL
, 0 );
6764 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6765 ref
= IDirectInputEffect_Release( effect
);
6766 ok( ref
== 0, "Release returned %d\n", ref
);
6767 set_hid_expect( file
, NULL
, 0 );
6771 desc
.rgdwAxes
= axes
;
6772 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
;
6773 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
6774 desc
.rglDirection
= directions
;
6775 desc
.rglDirection
[0] = +3000;
6776 desc
.rglDirection
[1] = -2000;
6777 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
6778 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
6779 set_hid_expect( file
, expect_create_3
, sizeof(expect_create_3
) );
6780 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6781 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6782 set_hid_expect( file
, NULL
, 0 );
6784 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6785 ref
= IDirectInputEffect_Release( effect
);
6786 ok( ref
== 0, "Release returned %d\n", ref
);
6787 set_hid_expect( file
, NULL
, 0 );
6790 static void test_force_feedback_joystick( DWORD version
)
6792 #include "psh_hid_macros.h"
6793 const unsigned char report_descriptor
[] = {
6794 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
6795 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
6796 COLLECTION(1, Application
),
6797 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
6798 COLLECTION(1, Report
),
6801 USAGE(1, HID_USAGE_GENERIC_X
),
6802 USAGE(1, HID_USAGE_GENERIC_Y
),
6803 USAGE(1, HID_USAGE_GENERIC_Z
),
6804 LOGICAL_MINIMUM(1, 0),
6805 LOGICAL_MAXIMUM(1, 0x7f),
6806 PHYSICAL_MINIMUM(1, 0),
6807 PHYSICAL_MAXIMUM(1, 0x7f),
6810 INPUT(1, Data
|Var
|Abs
),
6812 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
6813 USAGE_MINIMUM(1, 1),
6814 USAGE_MAXIMUM(1, 2),
6815 LOGICAL_MINIMUM(1, 0),
6816 LOGICAL_MAXIMUM(1, 1),
6817 PHYSICAL_MINIMUM(1, 0),
6818 PHYSICAL_MAXIMUM(1, 1),
6821 INPUT(1, Data
|Var
|Abs
),
6823 INPUT(1, Cnst
|Var
|Abs
),
6826 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
6827 USAGE(1, PID_USAGE_STATE_REPORT
),
6828 COLLECTION(1, Report
),
6831 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
6832 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
6833 USAGE(1, PID_USAGE_SAFETY_SWITCH
),
6834 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH
),
6835 USAGE(1, PID_USAGE_ACTUATOR_POWER
),
6836 LOGICAL_MINIMUM(1, 0),
6837 LOGICAL_MAXIMUM(1, 1),
6838 PHYSICAL_MINIMUM(1, 0),
6839 PHYSICAL_MAXIMUM(1, 1),
6842 INPUT(1, Data
|Var
|Abs
),
6844 INPUT(1, Cnst
|Var
|Abs
),
6846 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
6847 LOGICAL_MINIMUM(1, 0),
6848 LOGICAL_MAXIMUM(1, 1),
6849 PHYSICAL_MINIMUM(1, 0),
6850 PHYSICAL_MAXIMUM(1, 1),
6853 INPUT(1, Data
|Var
|Abs
),
6855 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
6856 LOGICAL_MAXIMUM(1, 0x7f),
6857 LOGICAL_MINIMUM(1, 0x00),
6860 INPUT(1, Data
|Var
|Abs
),
6863 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
6864 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
6865 COLLECTION(1, Report
),
6868 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
6869 COLLECTION(1, Logical
),
6870 USAGE(1, PID_USAGE_DC_DEVICE_RESET
),
6871 LOGICAL_MINIMUM(1, 1),
6872 LOGICAL_MAXIMUM(1, 2),
6873 PHYSICAL_MINIMUM(1, 1),
6874 PHYSICAL_MAXIMUM(1, 2),
6877 OUTPUT(1, Data
|Ary
|Abs
),
6881 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
6882 COLLECTION(1, Report
),
6885 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
6886 LOGICAL_MINIMUM(1, 0),
6887 LOGICAL_MAXIMUM(1, 0x7f),
6888 PHYSICAL_MINIMUM(1, 0),
6889 PHYSICAL_MAXIMUM(1, 0x7f),
6892 OUTPUT(1, Data
|Var
|Abs
),
6894 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
6895 COLLECTION(1, NamedArray
),
6896 USAGE(1, PID_USAGE_OP_EFFECT_START
),
6897 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO
),
6898 USAGE(1, PID_USAGE_OP_EFFECT_STOP
),
6899 LOGICAL_MINIMUM(1, 1),
6900 LOGICAL_MAXIMUM(1, 3),
6901 PHYSICAL_MINIMUM(1, 1),
6902 PHYSICAL_MAXIMUM(1, 3),
6905 OUTPUT(1, Data
|Ary
|Abs
),
6908 USAGE(1, PID_USAGE_LOOP_COUNT
),
6909 LOGICAL_MINIMUM(1, 0),
6910 LOGICAL_MAXIMUM(1, 0x7f),
6911 PHYSICAL_MINIMUM(1, 0),
6912 PHYSICAL_MAXIMUM(1, 0x7f),
6915 OUTPUT(1, Data
|Var
|Abs
),
6918 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
6919 COLLECTION(1, Report
),
6922 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
6923 LOGICAL_MINIMUM(1, 0),
6924 LOGICAL_MAXIMUM(1, 0x7f),
6925 PHYSICAL_MINIMUM(1, 0),
6926 PHYSICAL_MAXIMUM(1, 0x7f),
6929 OUTPUT(1, Data
|Var
|Abs
),
6931 USAGE(1, PID_USAGE_EFFECT_TYPE
),
6932 COLLECTION(1, NamedArray
),
6933 USAGE(1, PID_USAGE_ET_SQUARE
),
6934 USAGE(1, PID_USAGE_ET_SINE
),
6935 USAGE(1, PID_USAGE_ET_SPRING
),
6936 LOGICAL_MINIMUM(1, 1),
6937 LOGICAL_MAXIMUM(1, 3),
6938 PHYSICAL_MINIMUM(1, 1),
6939 PHYSICAL_MAXIMUM(1, 3),
6942 OUTPUT(1, Data
|Ary
|Abs
),
6945 USAGE(1, PID_USAGE_AXES_ENABLE
),
6946 COLLECTION(1, Logical
),
6947 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_X
),
6948 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Y
),
6949 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Z
),
6950 LOGICAL_MINIMUM(1, 0),
6951 LOGICAL_MAXIMUM(1, 1),
6952 PHYSICAL_MINIMUM(1, 0),
6953 PHYSICAL_MAXIMUM(1, 1),
6956 OUTPUT(1, Data
|Var
|Abs
),
6958 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
6960 OUTPUT(1, Data
|Var
|Abs
),
6962 OUTPUT(1, Cnst
|Var
|Abs
),
6964 USAGE(1, PID_USAGE_DURATION
),
6965 USAGE(1, PID_USAGE_START_DELAY
),
6966 UNIT(2, 0x1003), /* Eng Lin:Time */
6967 UNIT_EXPONENT(1, -3), /* 10^-3 */
6968 LOGICAL_MINIMUM(1, 0),
6969 LOGICAL_MAXIMUM(2, 0x7fff),
6970 PHYSICAL_MINIMUM(1, 0),
6971 PHYSICAL_MAXIMUM(2, 0x7fff),
6974 OUTPUT(1, Data
|Var
|Abs
),
6976 UNIT_EXPONENT(1, 0),
6978 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
6979 LOGICAL_MINIMUM(1, 1),
6980 LOGICAL_MAXIMUM(1, 0x08),
6981 PHYSICAL_MINIMUM(1, 1),
6982 PHYSICAL_MAXIMUM(1, 0x08),
6985 OUTPUT(1, Data
|Var
|Abs
),
6987 USAGE(1, PID_USAGE_DIRECTION
),
6988 COLLECTION(1, Logical
),
6989 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
6990 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
6991 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
6992 UNIT_EXPONENT(1, -2), /* 10^-2 */
6993 LOGICAL_MINIMUM(1, 0),
6994 LOGICAL_MAXIMUM(2, 0x00ff),
6995 PHYSICAL_MINIMUM(1, 0),
6996 PHYSICAL_MAXIMUM(4, 0x00008ca0),
7000 OUTPUT(1, Data
|Var
|Abs
),
7001 UNIT_EXPONENT(1, 0),
7006 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT
),
7007 COLLECTION(1, Logical
),
7010 USAGE(1, PID_USAGE_MAGNITUDE
),
7011 LOGICAL_MINIMUM(1, 0),
7012 LOGICAL_MAXIMUM(2, 0x00ff),
7013 PHYSICAL_MINIMUM(1, 0),
7014 PHYSICAL_MAXIMUM(2, 0x2710),
7017 OUTPUT(1, Data
|Var
|Abs
),
7020 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT
),
7021 COLLECTION(1, Logical
),
7024 USAGE(1, PID_USAGE_ATTACK_LEVEL
),
7025 USAGE(1, PID_USAGE_FADE_LEVEL
),
7026 LOGICAL_MINIMUM(1, 0),
7027 LOGICAL_MAXIMUM(2, 0x00ff),
7028 PHYSICAL_MINIMUM(1, 0),
7029 PHYSICAL_MAXIMUM(2, 0x2710),
7032 OUTPUT(1, Data
|Var
|Abs
),
7034 USAGE(1, PID_USAGE_ATTACK_TIME
),
7035 USAGE(1, PID_USAGE_FADE_TIME
),
7036 UNIT(2, 0x1003), /* Eng Lin:Time */
7037 UNIT_EXPONENT(1, -3), /* 10^-3 */
7038 LOGICAL_MINIMUM(1, 0),
7039 LOGICAL_MAXIMUM(2, 0x7fff),
7040 PHYSICAL_MINIMUM(1, 0),
7041 PHYSICAL_MAXIMUM(2, 0x7fff),
7044 OUTPUT(1, Data
|Var
|Abs
),
7045 PHYSICAL_MAXIMUM(1, 0),
7046 UNIT_EXPONENT(1, 0),
7051 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
7052 COLLECTION(1, Logical
),
7055 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
),
7056 COLLECTION(1, Logical
),
7057 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
7058 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
7059 LOGICAL_MINIMUM(1, 0),
7060 LOGICAL_MAXIMUM(1, 1),
7061 PHYSICAL_MINIMUM(1, 0),
7062 PHYSICAL_MAXIMUM(1, 1),
7065 OUTPUT(1, Data
|Var
|Abs
),
7069 OUTPUT(1, Cnst
|Var
|Abs
),
7071 USAGE(1, PID_USAGE_CP_OFFSET
),
7072 LOGICAL_MINIMUM(1, 0x80),
7073 LOGICAL_MAXIMUM(1, 0x7f),
7074 PHYSICAL_MINIMUM(2, 0xd8f0),
7075 PHYSICAL_MAXIMUM(2, 0x2710),
7078 OUTPUT(1, Data
|Var
|Abs
),
7080 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
7081 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
7082 LOGICAL_MINIMUM(1, 0x80),
7083 LOGICAL_MAXIMUM(1, 0x7f),
7084 PHYSICAL_MINIMUM(2, 0xd8f0),
7085 PHYSICAL_MAXIMUM(2, 0x2710),
7088 OUTPUT(1, Data
|Var
|Abs
),
7090 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
7091 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
7092 LOGICAL_MINIMUM(1, 0),
7093 LOGICAL_MAXIMUM(2, 0x00ff),
7094 PHYSICAL_MINIMUM(1, 0),
7095 PHYSICAL_MAXIMUM(2, 0x2710),
7098 OUTPUT(1, Data
|Var
|Abs
),
7100 USAGE(1, PID_USAGE_DEAD_BAND
),
7101 LOGICAL_MINIMUM(1, 0),
7102 LOGICAL_MAXIMUM(2, 0x00ff),
7103 PHYSICAL_MINIMUM(1, 0),
7104 PHYSICAL_MAXIMUM(2, 0x2710),
7107 OUTPUT(1, Data
|Var
|Abs
),
7111 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT
),
7112 COLLECTION(1, Logical
),
7115 USAGE(1, PID_USAGE_DEVICE_GAIN
),
7116 LOGICAL_MINIMUM(1, 0),
7117 LOGICAL_MAXIMUM(2, 0x00ff),
7118 PHYSICAL_MINIMUM(1, 0),
7119 PHYSICAL_MAXIMUM(2, 0x2710),
7122 OUTPUT(1, Data
|Var
|Abs
),
7126 #undef REPORT_ID_OR_USAGE_PAGE
7127 #include "pop_hid_macros.h"
7129 static const HIDP_CAPS hid_caps
=
7131 .InputReportByteLength
= 5,
7133 const DIDEVCAPS expect_caps
=
7135 .dwSize
= sizeof(DIDEVCAPS
),
7136 .dwFlags
= DIDC_FORCEFEEDBACK
| DIDC_ATTACHED
| DIDC_EMULATED
| DIDC_STARTDELAY
|
7137 DIDC_FFFADE
| DIDC_FFATTACK
| DIDC_DEADBAND
| DIDC_SATURATION
,
7138 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
7139 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_UNKNOWN
<< 8) | DIDEVTYPE_JOYSTICK
,
7142 .dwFFSamplePeriod
= 1000000,
7143 .dwFFMinTimeResolution
= 1000000,
7144 .dwHardwareRevision
= 1,
7145 .dwFFDriverVersion
= 1,
7147 struct hid_expect expect_acquire
[] =
7150 .code
= IOCTL_HID_WRITE_REPORT
,
7153 .report_buf
= {1, 0x01},
7156 .code
= IOCTL_HID_WRITE_REPORT
,
7159 .report_buf
= {8, 0x19},
7162 struct hid_expect expect_reset
[] =
7165 .code
= IOCTL_HID_WRITE_REPORT
,
7168 .report_buf
= {1, 0x01},
7171 struct hid_expect expect_set_device_gain_1
=
7173 .code
= IOCTL_HID_WRITE_REPORT
,
7176 .report_buf
= {8, 0x19},
7178 struct hid_expect expect_set_device_gain_2
=
7180 .code
= IOCTL_HID_WRITE_REPORT
,
7183 .report_buf
= {8, 0x33},
7186 const DIDEVICEINSTANCEW expect_devinst
=
7188 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
7189 .guidInstance
= expect_guid_product
,
7190 .guidProduct
= expect_guid_product
,
7191 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
7192 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_UNKNOWN
<< 8) | DIDEVTYPE_JOYSTICK
,
7193 .tszInstanceName
= L
"Wine test root driver",
7194 .tszProductName
= L
"Wine test root driver",
7195 .guidFFDriver
= IID_IDirectInputPIDDriver
,
7196 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7197 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
7199 const DIDEVICEOBJECTINSTANCEW expect_objects_5
[] =
7202 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7203 .guidType
= GUID_XAxis
,
7204 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR
,
7205 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7206 .tszName
= L
"X Axis",
7207 .wCollectionNumber
= 1,
7208 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7209 .wUsage
= HID_USAGE_GENERIC_X
,
7213 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7214 .guidType
= GUID_YAxis
,
7216 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR
,
7217 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7218 .tszName
= L
"Y Axis",
7219 .wCollectionNumber
= 1,
7220 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7221 .wUsage
= HID_USAGE_GENERIC_Y
,
7225 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7226 .guidType
= GUID_ZAxis
,
7228 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR
,
7229 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7230 .tszName
= L
"Z Axis",
7231 .wCollectionNumber
= 1,
7232 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7233 .wUsage
= HID_USAGE_GENERIC_Z
,
7237 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7238 .guidType
= GUID_Button
,
7240 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER
,
7241 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7242 .tszName
= L
"Button 0",
7243 .wCollectionNumber
= 1,
7244 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7249 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7250 .guidType
= GUID_Button
,
7252 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER
,
7253 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7254 .tszName
= L
"Button 1",
7255 .wCollectionNumber
= 1,
7256 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7261 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
7264 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7265 .guidType
= GUID_ZAxis
,
7266 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR
,
7267 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7268 .tszName
= L
"Z Axis",
7269 .wCollectionNumber
= 1,
7270 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7271 .wUsage
= HID_USAGE_GENERIC_Z
,
7275 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7276 .guidType
= GUID_YAxis
,
7278 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR
,
7279 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7280 .tszName
= L
"Y Axis",
7281 .wCollectionNumber
= 1,
7282 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7283 .wUsage
= HID_USAGE_GENERIC_Y
,
7287 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7288 .guidType
= GUID_XAxis
,
7290 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR
,
7291 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7292 .tszName
= L
"X Axis",
7293 .wCollectionNumber
= 1,
7294 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7295 .wUsage
= HID_USAGE_GENERIC_X
,
7299 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7300 .guidType
= GUID_Button
,
7301 .dwOfs
= version
>= 0x800 ? 0x68 : 0x10,
7302 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER
,
7303 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7304 .tszName
= L
"Button 0",
7305 .wCollectionNumber
= 1,
7306 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7311 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7312 .guidType
= GUID_Button
,
7313 .dwOfs
= version
>= 0x800 ? 0x69 : 0x11,
7314 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER
,
7315 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7316 .tszName
= L
"Button 1",
7317 .wCollectionNumber
= 1,
7318 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7323 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7324 .guidType
= GUID_Unknown
,
7325 .dwOfs
= version
>= 0x800 ? 0x70 : 0,
7326 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(12)|DIDFT_OUTPUT
,
7327 .dwFlags
= 0x80008000,
7328 .tszName
= L
"DC Device Reset",
7329 .wCollectionNumber
= 4,
7330 .wUsagePage
= HID_USAGE_PAGE_PID
,
7331 .wUsage
= PID_USAGE_DC_DEVICE_RESET
,
7335 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7336 .guidType
= GUID_Unknown
,
7337 .dwOfs
= version
>= 0x800 ? 0x10 : 0,
7338 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(13)|DIDFT_OUTPUT
,
7339 .dwFlags
= 0x80008000,
7340 .tszName
= L
"Effect Block Index",
7341 .wCollectionNumber
= 5,
7342 .wUsagePage
= HID_USAGE_PAGE_PID
,
7343 .wUsage
= PID_USAGE_EFFECT_BLOCK_INDEX
,
7347 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7348 .guidType
= GUID_Unknown
,
7349 .dwOfs
= version
>= 0x800 ? 0x71 : 0,
7350 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(14)|DIDFT_OUTPUT
,
7351 .dwFlags
= 0x80008000,
7352 .tszName
= L
"Op Effect Start",
7353 .wCollectionNumber
= 6,
7354 .wUsagePage
= HID_USAGE_PAGE_PID
,
7355 .wUsage
= PID_USAGE_OP_EFFECT_START
,
7359 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7360 .guidType
= GUID_Unknown
,
7361 .dwOfs
= version
>= 0x800 ? 0x72 : 0,
7362 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(15)|DIDFT_OUTPUT
,
7363 .dwFlags
= 0x80008000,
7364 .tszName
= L
"Op Effect Start Solo",
7365 .wCollectionNumber
= 6,
7366 .wUsagePage
= HID_USAGE_PAGE_PID
,
7367 .wUsage
= PID_USAGE_OP_EFFECT_START_SOLO
,
7371 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7372 .guidType
= GUID_Unknown
,
7373 .dwOfs
= version
>= 0x800 ? 0x73 : 0,
7374 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(16)|DIDFT_OUTPUT
,
7375 .dwFlags
= 0x80008000,
7376 .tszName
= L
"Op Effect Stop",
7377 .wCollectionNumber
= 6,
7378 .wUsagePage
= HID_USAGE_PAGE_PID
,
7379 .wUsage
= PID_USAGE_OP_EFFECT_STOP
,
7383 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7384 .guidType
= GUID_Unknown
,
7385 .dwOfs
= version
>= 0x800 ? 0x14 : 0,
7386 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(17)|DIDFT_OUTPUT
,
7387 .dwFlags
= 0x80008000,
7388 .tszName
= L
"Loop Count",
7389 .wCollectionNumber
= 5,
7390 .wUsagePage
= HID_USAGE_PAGE_PID
,
7391 .wUsage
= PID_USAGE_LOOP_COUNT
,
7395 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7396 .guidType
= GUID_Unknown
,
7397 .dwOfs
= version
>= 0x800 ? 0x18 : 0,
7398 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(18)|DIDFT_OUTPUT
,
7399 .dwFlags
= 0x80008000,
7400 .tszName
= L
"Effect Block Index",
7401 .wCollectionNumber
= 7,
7402 .wUsagePage
= HID_USAGE_PAGE_PID
,
7403 .wUsage
= PID_USAGE_EFFECT_BLOCK_INDEX
,
7407 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7408 .guidType
= GUID_Unknown
,
7409 .dwOfs
= version
>= 0x800 ? 0x74 : 0,
7410 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(19)|DIDFT_OUTPUT
,
7411 .dwFlags
= 0x80008000,
7412 .tszName
= L
"ET Square",
7413 .wCollectionNumber
= 8,
7414 .wUsagePage
= HID_USAGE_PAGE_PID
,
7415 .wUsage
= PID_USAGE_ET_SQUARE
,
7419 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7420 .guidType
= GUID_Unknown
,
7421 .dwOfs
= version
>= 0x800 ? 0x75 : 0,
7422 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(20)|DIDFT_OUTPUT
,
7423 .dwFlags
= 0x80008000,
7424 .tszName
= L
"ET Sine",
7425 .wCollectionNumber
= 8,
7426 .wUsagePage
= HID_USAGE_PAGE_PID
,
7427 .wUsage
= PID_USAGE_ET_SINE
,
7431 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7432 .guidType
= GUID_Unknown
,
7433 .dwOfs
= version
>= 0x800 ? 0x76 : 0,
7434 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(21)|DIDFT_OUTPUT
,
7435 .dwFlags
= 0x80008000,
7436 .tszName
= L
"ET Spring",
7437 .wCollectionNumber
= 8,
7438 .wUsagePage
= HID_USAGE_PAGE_PID
,
7439 .wUsage
= PID_USAGE_ET_SPRING
,
7443 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7444 .guidType
= GUID_Unknown
,
7445 .dwOfs
= version
>= 0x800 ? 0x77 : 0,
7446 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(22)|DIDFT_OUTPUT
,
7447 .dwFlags
= 0x80008000,
7448 .tszName
= L
"Z Axis",
7449 .wCollectionNumber
= 9,
7450 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7451 .wUsage
= HID_USAGE_GENERIC_Z
,
7455 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7456 .guidType
= GUID_Unknown
,
7457 .dwOfs
= version
>= 0x800 ? 0x78 : 0,
7458 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(23)|DIDFT_OUTPUT
,
7459 .dwFlags
= 0x80008000,
7460 .tszName
= L
"Y Axis",
7461 .wCollectionNumber
= 9,
7462 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7463 .wUsage
= HID_USAGE_GENERIC_Y
,
7467 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7468 .guidType
= GUID_Unknown
,
7469 .dwOfs
= version
>= 0x800 ? 0x79 : 0,
7470 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(24)|DIDFT_OUTPUT
,
7471 .dwFlags
= 0x80008000,
7472 .tszName
= L
"X Axis",
7473 .wCollectionNumber
= 9,
7474 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7475 .wUsage
= HID_USAGE_GENERIC_X
,
7479 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7480 .guidType
= GUID_Unknown
,
7481 .dwOfs
= version
>= 0x800 ? 0x7a : 0,
7482 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(25)|DIDFT_OUTPUT
,
7483 .dwFlags
= 0x80008000,
7484 .tszName
= L
"Direction Enable",
7485 .wCollectionNumber
= 7,
7486 .wUsagePage
= HID_USAGE_PAGE_PID
,
7487 .wUsage
= PID_USAGE_DIRECTION_ENABLE
,
7491 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7492 .guidType
= GUID_Unknown
,
7493 .dwOfs
= version
>= 0x800 ? 0x1c : 0,
7494 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(26)|DIDFT_OUTPUT
,
7495 .dwFlags
= 0x80008000,
7496 .tszName
= L
"Start Delay",
7497 .wCollectionNumber
= 7,
7498 .wUsagePage
= HID_USAGE_PAGE_PID
,
7499 .wUsage
= PID_USAGE_START_DELAY
,
7501 .dwDimension
= 0x1003,
7505 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7506 .guidType
= GUID_Unknown
,
7507 .dwOfs
= version
>= 0x800 ? 0x20 : 0,
7508 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(27)|DIDFT_OUTPUT
,
7509 .dwFlags
= 0x80008000,
7510 .tszName
= L
"Duration",
7511 .wCollectionNumber
= 7,
7512 .wUsagePage
= HID_USAGE_PAGE_PID
,
7513 .wUsage
= PID_USAGE_DURATION
,
7515 .dwDimension
= 0x1003,
7519 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7520 .guidType
= GUID_Unknown
,
7521 .dwOfs
= version
>= 0x800 ? 0x24 : 0,
7522 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(28)|DIDFT_OUTPUT
,
7523 .dwFlags
= 0x80008000,
7524 .tszName
= L
"Trigger Button",
7525 .wCollectionNumber
= 7,
7526 .wUsagePage
= HID_USAGE_PAGE_PID
,
7527 .wUsage
= PID_USAGE_TRIGGER_BUTTON
,
7531 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7532 .guidType
= GUID_Unknown
,
7533 .dwOfs
= version
>= 0x800 ? 0x28 : 0,
7534 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(29)|DIDFT_OUTPUT
,
7535 .dwFlags
= 0x80008000,
7536 .tszName
= L
"Unknown 29",
7537 .wCollectionNumber
= 10,
7538 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7544 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7545 .guidType
= GUID_Unknown
,
7546 .dwOfs
= version
>= 0x800 ? 0x2c : 0,
7547 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(30)|DIDFT_OUTPUT
,
7548 .dwFlags
= 0x80008000,
7549 .tszName
= L
"Unknown 30",
7550 .wCollectionNumber
= 10,
7551 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7557 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7558 .guidType
= GUID_Unknown
,
7559 .dwOfs
= version
>= 0x800 ? 0x30 : 0,
7560 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(31)|DIDFT_OUTPUT
,
7561 .dwFlags
= 0x80008000,
7562 .tszName
= L
"Magnitude",
7563 .wCollectionNumber
= 11,
7564 .wUsagePage
= HID_USAGE_PAGE_PID
,
7565 .wUsage
= PID_USAGE_MAGNITUDE
,
7569 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7570 .guidType
= GUID_Unknown
,
7571 .dwOfs
= version
>= 0x800 ? 0x34 : 0,
7572 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(32)|DIDFT_OUTPUT
,
7573 .dwFlags
= 0x80008000,
7574 .tszName
= L
"Fade Level",
7575 .wCollectionNumber
= 12,
7576 .wUsagePage
= HID_USAGE_PAGE_PID
,
7577 .wUsage
= PID_USAGE_FADE_LEVEL
,
7581 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7582 .guidType
= GUID_Unknown
,
7583 .dwOfs
= version
>= 0x800 ? 0x38 : 0,
7584 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(33)|DIDFT_OUTPUT
,
7585 .dwFlags
= 0x80008000,
7586 .tszName
= L
"Attack Level",
7587 .wCollectionNumber
= 12,
7588 .wUsagePage
= HID_USAGE_PAGE_PID
,
7589 .wUsage
= PID_USAGE_ATTACK_LEVEL
,
7593 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7594 .guidType
= GUID_Unknown
,
7595 .dwOfs
= version
>= 0x800 ? 0x3c : 0,
7596 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(34)|DIDFT_OUTPUT
,
7597 .dwFlags
= 0x80008000,
7598 .tszName
= L
"Fade Time",
7599 .wCollectionNumber
= 12,
7600 .wUsagePage
= HID_USAGE_PAGE_PID
,
7601 .wUsage
= PID_USAGE_FADE_TIME
,
7603 .dwDimension
= 0x1003,
7607 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7608 .guidType
= GUID_Unknown
,
7609 .dwOfs
= version
>= 0x800 ? 0x40 : 0,
7610 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(35)|DIDFT_OUTPUT
,
7611 .dwFlags
= 0x80008000,
7612 .tszName
= L
"Attack Time",
7613 .wCollectionNumber
= 12,
7614 .wUsagePage
= HID_USAGE_PAGE_PID
,
7615 .wUsage
= PID_USAGE_ATTACK_TIME
,
7617 .dwDimension
= 0x1003,
7621 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7622 .guidType
= GUID_Unknown
,
7623 .dwOfs
= version
>= 0x800 ? 0x44 : 0,
7624 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(36)|DIDFT_OUTPUT
,
7625 .dwFlags
= 0x80008000,
7626 .tszName
= L
"Unknown 36",
7627 .wCollectionNumber
= 14,
7628 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7633 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7634 .guidType
= GUID_Unknown
,
7635 .dwOfs
= version
>= 0x800 ? 0x48 : 0,
7636 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(37)|DIDFT_OUTPUT
,
7637 .dwFlags
= 0x80008000,
7638 .tszName
= L
"Unknown 37",
7639 .wCollectionNumber
= 14,
7640 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7645 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7646 .guidType
= GUID_Unknown
,
7647 .dwOfs
= version
>= 0x800 ? 0x4c : 0,
7648 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(38)|DIDFT_OUTPUT
,
7649 .dwFlags
= 0x80008000,
7650 .tszName
= L
"CP Offset",
7651 .wCollectionNumber
= 13,
7652 .wUsagePage
= HID_USAGE_PAGE_PID
,
7653 .wUsage
= PID_USAGE_CP_OFFSET
,
7657 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7658 .guidType
= GUID_Unknown
,
7659 .dwOfs
= version
>= 0x800 ? 0x50 : 0,
7660 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(39)|DIDFT_OUTPUT
,
7661 .dwFlags
= 0x80008000,
7662 .tszName
= L
"Negative Coefficient",
7663 .wCollectionNumber
= 13,
7664 .wUsagePage
= HID_USAGE_PAGE_PID
,
7665 .wUsage
= PID_USAGE_NEGATIVE_COEFFICIENT
,
7669 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7670 .guidType
= GUID_Unknown
,
7671 .dwOfs
= version
>= 0x800 ? 0x54 : 0,
7672 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(40)|DIDFT_OUTPUT
,
7673 .dwFlags
= 0x80008000,
7674 .tszName
= L
"Positive Coefficient",
7675 .wCollectionNumber
= 13,
7676 .wUsagePage
= HID_USAGE_PAGE_PID
,
7677 .wUsage
= PID_USAGE_POSITIVE_COEFFICIENT
,
7681 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7682 .guidType
= GUID_Unknown
,
7683 .dwOfs
= version
>= 0x800 ? 0x58 : 0,
7684 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(41)|DIDFT_OUTPUT
,
7685 .dwFlags
= 0x80008000,
7686 .tszName
= L
"Negative Saturation",
7687 .wCollectionNumber
= 13,
7688 .wUsagePage
= HID_USAGE_PAGE_PID
,
7689 .wUsage
= PID_USAGE_NEGATIVE_SATURATION
,
7693 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7694 .guidType
= GUID_Unknown
,
7695 .dwOfs
= version
>= 0x800 ? 0x5c : 0,
7696 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(42)|DIDFT_OUTPUT
,
7697 .dwFlags
= 0x80008000,
7698 .tszName
= L
"Positive Saturation",
7699 .wCollectionNumber
= 13,
7700 .wUsagePage
= HID_USAGE_PAGE_PID
,
7701 .wUsage
= PID_USAGE_POSITIVE_SATURATION
,
7705 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7706 .guidType
= GUID_Unknown
,
7707 .dwOfs
= version
>= 0x800 ? 0x60 : 0,
7708 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(43)|DIDFT_OUTPUT
,
7709 .dwFlags
= 0x80008000,
7710 .tszName
= L
"Dead Band",
7711 .wCollectionNumber
= 13,
7712 .wUsagePage
= HID_USAGE_PAGE_PID
,
7713 .wUsage
= PID_USAGE_DEAD_BAND
,
7717 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7718 .guidType
= GUID_Unknown
,
7719 .dwOfs
= version
>= 0x800 ? 0x64 : 0,
7720 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(44)|DIDFT_OUTPUT
,
7721 .dwFlags
= 0x80008000,
7722 .tszName
= L
"Device Gain",
7723 .wCollectionNumber
= 15,
7724 .wUsagePage
= HID_USAGE_PAGE_PID
,
7725 .wUsage
= PID_USAGE_DEVICE_GAIN
,
7729 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7730 .guidType
= GUID_Unknown
,
7731 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
7732 .tszName
= L
"Collection 0 - Joystick",
7733 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7734 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
7737 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7738 .guidType
= GUID_Unknown
,
7739 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
7740 .tszName
= L
"Collection 1 - Joystick",
7741 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7742 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
7745 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7746 .guidType
= GUID_Unknown
,
7747 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(2),
7748 .tszName
= L
"Collection 2 - PID State Report",
7749 .wUsagePage
= HID_USAGE_PAGE_PID
,
7750 .wUsage
= PID_USAGE_STATE_REPORT
,
7753 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7754 .guidType
= GUID_Unknown
,
7755 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(3),
7756 .tszName
= L
"Collection 3 - PID Device Control Report",
7757 .wUsagePage
= HID_USAGE_PAGE_PID
,
7758 .wUsage
= PID_USAGE_DEVICE_CONTROL_REPORT
,
7761 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7762 .guidType
= GUID_Unknown
,
7763 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(4),
7764 .tszName
= L
"Collection 4 - PID Device Control",
7765 .wCollectionNumber
= 3,
7766 .wUsagePage
= HID_USAGE_PAGE_PID
,
7767 .wUsage
= PID_USAGE_DEVICE_CONTROL
,
7770 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7771 .guidType
= GUID_Unknown
,
7772 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(5),
7773 .tszName
= L
"Collection 5 - Effect Operation Report",
7774 .wUsagePage
= HID_USAGE_PAGE_PID
,
7775 .wUsage
= PID_USAGE_EFFECT_OPERATION_REPORT
,
7778 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7779 .guidType
= GUID_Unknown
,
7780 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(6),
7781 .tszName
= L
"Collection 6 - Effect Operation",
7782 .wCollectionNumber
= 5,
7783 .wUsagePage
= HID_USAGE_PAGE_PID
,
7784 .wUsage
= PID_USAGE_EFFECT_OPERATION
,
7787 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7788 .guidType
= GUID_Unknown
,
7789 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(7),
7790 .tszName
= L
"Collection 7 - Set Effect Report",
7791 .wUsagePage
= HID_USAGE_PAGE_PID
,
7792 .wUsage
= PID_USAGE_SET_EFFECT_REPORT
,
7795 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7796 .guidType
= GUID_Unknown
,
7797 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(8),
7798 .tszName
= L
"Collection 8 - Effect Type",
7799 .wCollectionNumber
= 7,
7800 .wUsagePage
= HID_USAGE_PAGE_PID
,
7801 .wUsage
= PID_USAGE_EFFECT_TYPE
,
7804 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7805 .guidType
= GUID_Unknown
,
7806 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(9),
7807 .tszName
= L
"Collection 9 - Axes Enable",
7808 .wCollectionNumber
= 7,
7809 .wUsagePage
= HID_USAGE_PAGE_PID
,
7810 .wUsage
= PID_USAGE_AXES_ENABLE
,
7813 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7814 .guidType
= GUID_Unknown
,
7815 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(10),
7816 .tszName
= L
"Collection 10 - Direction",
7817 .wCollectionNumber
= 7,
7818 .wUsagePage
= HID_USAGE_PAGE_PID
,
7819 .wUsage
= PID_USAGE_DIRECTION
,
7822 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7823 .guidType
= GUID_Unknown
,
7824 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(11),
7825 .tszName
= L
"Collection 11 - Set Periodic Report",
7826 .wUsagePage
= HID_USAGE_PAGE_PID
,
7827 .wUsage
= PID_USAGE_SET_PERIODIC_REPORT
,
7830 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7831 .guidType
= GUID_Unknown
,
7832 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(12),
7833 .tszName
= L
"Collection 12 - Set Envelope Report",
7834 .wUsagePage
= HID_USAGE_PAGE_PID
,
7835 .wUsage
= PID_USAGE_SET_ENVELOPE_REPORT
,
7838 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7839 .guidType
= GUID_Unknown
,
7840 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(13),
7841 .tszName
= L
"Collection 13 - Set Condition Report",
7842 .wUsagePage
= HID_USAGE_PAGE_PID
,
7843 .wUsage
= PID_USAGE_SET_CONDITION_REPORT
,
7846 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7847 .guidType
= GUID_Unknown
,
7848 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(14),
7849 .tszName
= L
"Collection 14 - Type Specific Block Offset",
7850 .wCollectionNumber
= 13,
7851 .wUsagePage
= HID_USAGE_PAGE_PID
,
7852 .wUsage
= PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
,
7855 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7856 .guidType
= GUID_Unknown
,
7857 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(15),
7858 .tszName
= L
"Collection 15 - Device Gain Report",
7859 .wUsagePage
= HID_USAGE_PAGE_PID
,
7860 .wUsage
= PID_USAGE_DEVICE_GAIN_REPORT
,
7863 const DIEFFECTINFOW expect_effects
[] =
7866 .dwSize
= sizeof(DIEFFECTINFOW
),
7867 .guid
= GUID_Square
,
7868 .dwEffType
= DIEFT_PERIODIC
| DIEFT_STARTDELAY
| DIEFT_FFFADE
| DIEFT_FFATTACK
,
7869 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7870 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7871 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7872 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7873 .tszName
= L
"GUID_Square",
7876 .dwSize
= sizeof(DIEFFECTINFOW
),
7878 .dwEffType
= DIEFT_PERIODIC
| DIEFT_STARTDELAY
| DIEFT_FFFADE
| DIEFT_FFATTACK
,
7879 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7880 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7881 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7882 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7883 .tszName
= L
"GUID_Sine",
7886 .dwSize
= sizeof(DIEFFECTINFOW
),
7887 .guid
= GUID_Spring
,
7888 .dwEffType
= DIEFT_CONDITION
| DIEFT_STARTDELAY
| DIEFT_DEADBAND
| DIEFT_SATURATION
,
7889 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7891 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7893 .tszName
= L
"GUID_Spring",
7897 struct check_objects_todos todo_objects_5
[ARRAY_SIZE(expect_objects_5
)] =
7899 {.guid
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .name
= TRUE
},
7901 {.guid
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .name
= TRUE
},
7903 struct check_objects_params check_objects_params
=
7906 .expect_count
= version
< 0x700 ? ARRAY_SIZE(expect_objects_5
) : ARRAY_SIZE(expect_objects
),
7907 .expect_objs
= version
< 0x700 ? expect_objects_5
: expect_objects
,
7908 .todo_objs
= version
< 0x700 ? todo_objects_5
: NULL
,
7909 .todo_extra
= version
< 0x700 ? TRUE
: FALSE
,
7911 struct check_effects_params check_effects_params
=
7913 .expect_count
= ARRAY_SIZE(expect_effects
),
7914 .expect_effects
= expect_effects
,
7916 DIPROPDWORD prop_dword
=
7920 .dwSize
= sizeof(DIPROPDWORD
),
7921 .dwHeaderSize
= sizeof(DIPROPHEADER
),
7922 .dwHow
= DIPH_DEVICE
,
7925 DIPROPGUIDANDPATH prop_guid_path
=
7929 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
7930 .dwHeaderSize
= sizeof(DIPROPHEADER
),
7931 .dwHow
= DIPH_DEVICE
,
7934 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
7935 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
7936 DIDEVICEOBJECTDATA objdata
= {0};
7937 DIEFFECTINFOW effectinfo
= {0};
7938 IDirectInputDevice8W
*device
;
7939 DIEFFESCAPE escape
= {0};
7940 DIDEVCAPS caps
= {0};
7947 winetest_push_context( "version %#x", version
);
7949 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
7950 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
7951 SetCurrentDirectoryW( tempdir
);
7953 cleanup_registry_keys();
7954 if (!dinput_driver_start( report_descriptor
, sizeof(report_descriptor
), &hid_caps
, NULL
, 0 )) goto done
;
7955 if (FAILED(hr
= create_dinput_device( version
, &devinst
, &device
))) goto done
;
7957 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
7958 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
7959 check_member( devinst
, expect_devinst
, "%d", dwSize
);
7961 check_member_guid( devinst
, expect_devinst
, guidInstance
);
7962 check_member_guid( devinst
, expect_devinst
, guidProduct
);
7963 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
7965 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
7967 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
7968 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
7969 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
7970 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
7972 caps
.dwSize
= sizeof(DIDEVCAPS
);
7973 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
7974 ok( hr
== DI_OK
, "GetCapabilities returned %#x\n", hr
);
7975 check_member( caps
, expect_caps
, "%d", dwSize
);
7976 check_member( caps
, expect_caps
, "%#x", dwFlags
);
7977 check_member( caps
, expect_caps
, "%#x", dwDevType
);
7978 check_member( caps
, expect_caps
, "%d", dwAxes
);
7979 check_member( caps
, expect_caps
, "%d", dwButtons
);
7980 check_member( caps
, expect_caps
, "%d", dwPOVs
);
7981 check_member( caps
, expect_caps
, "%d", dwFFSamplePeriod
);
7982 check_member( caps
, expect_caps
, "%d", dwFFMinTimeResolution
);
7983 check_member( caps
, expect_caps
, "%d", dwFirmwareRevision
);
7984 check_member( caps
, expect_caps
, "%d", dwHardwareRevision
);
7985 check_member( caps
, expect_caps
, "%d", dwFFDriverVersion
);
7987 prop_dword
.dwData
= 0xdeadbeef;
7988 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
7989 ok( hr
== DI_OK
, "GetProperty DIPROP_FFGAIN returned %#x\n", hr
);
7990 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
7992 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
7993 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
7995 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
7996 ok( hr
== DI_OK
, "EnumObjects returned %#x\n", hr
);
7997 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
7998 check_objects_params
.expect_count
- check_objects_params
.index
);
8001 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, 0xfe );
8002 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
8003 ok( res
== 0, "got %u expected %u\n", res
, 0 );
8005 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, DIEFT_PERIODIC
);
8006 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
8007 ok( res
== 2, "got %u expected %u\n", res
, 2 );
8008 hr
= IDirectInputDevice8_EnumEffects( device
, check_effects
, &check_effects_params
, DIEFT_ALL
);
8009 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
8010 ok( check_effects_params
.index
>= check_effects_params
.expect_count
, "missing %u effects\n",
8011 check_effects_params
.expect_count
- check_effects_params
.index
);
8013 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
);
8014 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
8015 ok( hr
== DI_OK
, "GetEffectInfo returned %#x\n", hr
);
8016 check_member_guid( effectinfo
, expect_effects
[1], guid
);
8017 check_member( effectinfo
, expect_effects
[1], "%#x", dwEffType
);
8018 check_member( effectinfo
, expect_effects
[1], "%#x", dwStaticParams
);
8019 check_member( effectinfo
, expect_effects
[1], "%#x", dwDynamicParams
);
8020 check_member_wstr( effectinfo
, expect_effects
[1], tszName
);
8022 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
8023 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
8025 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
8026 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
8028 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
8029 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
8030 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
8031 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
8033 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
8034 NULL
, NULL
, NULL
, NULL
);
8036 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
8037 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
8039 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
8040 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
8041 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
8042 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
8043 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
8044 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
8045 prop_dword
.diph
.dwObj
= 0;
8046 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
8047 ok( hr
== DI_OK
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
8049 hr
= IDirectInputDevice8_Acquire( device
);
8050 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
8052 prop_dword
.dwData
= 0xdeadbeef;
8053 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8054 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8055 prop_dword
.dwData
= 1000;
8056 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8057 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8059 prop_dword
.dwData
= 0xdeadbeef;
8060 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8061 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8062 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8063 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8064 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8066 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetForceFeedbackState returned %#x\n", hr
);
8067 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
8068 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "SendForceFeedbackCommand returned %#x\n", hr
);
8070 escape
.dwSize
= sizeof(DIEFFESCAPE
);
8071 escape
.dwCommand
= 0;
8072 escape
.lpvInBuffer
= buffer
;
8073 escape
.cbInBuffer
= 10;
8074 escape
.lpvOutBuffer
= buffer
+ 10;
8075 escape
.cbOutBuffer
= 10;
8076 hr
= IDirectInputDevice8_Escape( device
, &escape
);
8078 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Escape returned: %#x\n", hr
);
8080 hr
= IDirectInputDevice8_Unacquire( device
);
8081 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
8082 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
8083 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
8085 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
8086 hr
= IDirectInputDevice8_Acquire( device
);
8087 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
8088 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8090 set_hid_expect( file
, &expect_set_device_gain_2
, sizeof(expect_set_device_gain_2
) );
8091 prop_dword
.dwData
= 2000;
8092 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8093 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8094 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8096 set_hid_expect( file
, &expect_set_device_gain_1
, sizeof(expect_set_device_gain_1
) );
8097 prop_dword
.dwData
= 1000;
8098 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8099 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8100 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8102 hr
= IDirectInputDevice8_Escape( device
, &escape
);
8104 ok( hr
== DIERR_UNSUPPORTED
, "Escape returned: %#x\n", hr
);
8106 prop_dword
.dwData
= 0xdeadbeef;
8107 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8109 ok( hr
== 0x80040301, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8111 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8113 ok( hr
== 0x80040301, "GetForceFeedbackState returned %#x\n", hr
);
8115 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, 0xdeadbeef );
8116 ok( hr
== DIERR_INVALIDPARAM
, "SendForceFeedbackCommand returned %#x\n", hr
);
8118 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
8119 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
8120 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#x\n", hr
);
8121 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8123 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_STOPALL
);
8124 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8125 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_PAUSE
);
8126 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8127 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_CONTINUE
);
8128 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8129 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSON
);
8130 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8131 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSOFF
);
8132 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8134 objdata
.dwOfs
= 0x1e;
8135 objdata
.dwData
= 0x80;
8137 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), &objdata
, &res
, 0 );
8138 if (version
< 0x800) ok( hr
== DI_OK
, "SendDeviceData returned %#x\n", hr
);
8139 else todo_wine
ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
8141 test_periodic_effect( device
, file
, version
);
8142 test_condition_effect( device
, file
, version
);
8144 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
8145 hr
= IDirectInputDevice8_Unacquire( device
);
8146 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
8147 set_hid_expect( file
, NULL
, 0 );
8149 ref
= IDirectInputDevice8_Release( device
);
8150 ok( ref
== 0, "Release returned %d\n", ref
);
8152 DestroyWindow( hwnd
);
8153 CloseHandle( file
);
8157 cleanup_registry_keys();
8158 SetCurrentDirectoryW( cwd
);
8159 winetest_pop_context();
8162 static void test_device_managed_effect(void)
8164 #include "psh_hid_macros.h"
8165 const unsigned char report_descriptor
[] = {
8166 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
8167 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
8168 COLLECTION(1, Application
),
8169 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
8170 COLLECTION(1, Report
),
8173 USAGE(1, HID_USAGE_GENERIC_X
),
8174 USAGE(1, HID_USAGE_GENERIC_Y
),
8175 USAGE(1, HID_USAGE_GENERIC_Z
),
8176 LOGICAL_MINIMUM(1, 0),
8177 LOGICAL_MAXIMUM(1, 0x7f),
8178 PHYSICAL_MINIMUM(1, 0),
8179 PHYSICAL_MAXIMUM(1, 0x7f),
8182 INPUT(1, Data
|Var
|Abs
),
8184 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
8185 USAGE_MINIMUM(1, 1),
8186 USAGE_MAXIMUM(1, 2),
8187 LOGICAL_MINIMUM(1, 0),
8188 LOGICAL_MAXIMUM(1, 1),
8189 PHYSICAL_MINIMUM(1, 0),
8190 PHYSICAL_MAXIMUM(1, 1),
8193 INPUT(1, Data
|Var
|Abs
),
8195 INPUT(1, Cnst
|Var
|Abs
),
8198 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
8199 USAGE(1, PID_USAGE_STATE_REPORT
),
8200 COLLECTION(1, Report
),
8203 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
8204 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
8205 USAGE(1, PID_USAGE_SAFETY_SWITCH
),
8206 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH
),
8207 USAGE(1, PID_USAGE_ACTUATOR_POWER
),
8208 LOGICAL_MINIMUM(1, 0),
8209 LOGICAL_MAXIMUM(1, 1),
8210 PHYSICAL_MINIMUM(1, 0),
8211 PHYSICAL_MAXIMUM(1, 1),
8214 INPUT(1, Data
|Var
|Abs
),
8216 INPUT(1, Cnst
|Var
|Abs
),
8218 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
8219 LOGICAL_MINIMUM(1, 0),
8220 LOGICAL_MAXIMUM(1, 1),
8221 PHYSICAL_MINIMUM(1, 0),
8222 PHYSICAL_MAXIMUM(1, 1),
8225 INPUT(1, Data
|Var
|Abs
),
8227 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8228 LOGICAL_MINIMUM(1, 1),
8229 LOGICAL_MAXIMUM(1, 0x7f),
8230 PHYSICAL_MINIMUM(1, 1),
8231 PHYSICAL_MAXIMUM(1, 0x7f),
8234 INPUT(1, Data
|Var
|Abs
),
8237 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
8238 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
8239 COLLECTION(1, Report
),
8242 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
8243 COLLECTION(1, Logical
),
8244 USAGE(1, PID_USAGE_DC_DEVICE_RESET
),
8245 LOGICAL_MINIMUM(1, 1),
8246 LOGICAL_MAXIMUM(1, 2),
8247 PHYSICAL_MINIMUM(1, 1),
8248 PHYSICAL_MAXIMUM(1, 2),
8251 OUTPUT(1, Data
|Ary
|Abs
),
8255 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
8256 COLLECTION(1, Report
),
8259 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8260 LOGICAL_MINIMUM(1, 1),
8261 LOGICAL_MAXIMUM(1, 0x7f),
8262 PHYSICAL_MINIMUM(1, 1),
8263 PHYSICAL_MAXIMUM(1, 0x7f),
8266 OUTPUT(1, Data
|Var
|Abs
),
8268 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
8269 COLLECTION(1, NamedArray
),
8270 USAGE(1, PID_USAGE_OP_EFFECT_START
),
8271 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO
),
8272 USAGE(1, PID_USAGE_OP_EFFECT_STOP
),
8273 LOGICAL_MINIMUM(1, 1),
8274 LOGICAL_MAXIMUM(1, 3),
8275 PHYSICAL_MINIMUM(1, 1),
8276 PHYSICAL_MAXIMUM(1, 3),
8279 OUTPUT(1, Data
|Ary
|Abs
),
8282 USAGE(1, PID_USAGE_LOOP_COUNT
),
8283 LOGICAL_MINIMUM(1, 0),
8284 LOGICAL_MAXIMUM(1, 0x7f),
8285 PHYSICAL_MINIMUM(1, 0),
8286 PHYSICAL_MAXIMUM(1, 0x7f),
8289 OUTPUT(1, Data
|Var
|Abs
),
8292 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
8293 COLLECTION(1, Report
),
8296 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8297 LOGICAL_MINIMUM(1, 1),
8298 LOGICAL_MAXIMUM(1, 0x7f),
8299 PHYSICAL_MINIMUM(1, 1),
8300 PHYSICAL_MAXIMUM(1, 0x7f),
8303 OUTPUT(1, Data
|Var
|Abs
),
8305 USAGE(1, PID_USAGE_EFFECT_TYPE
),
8306 COLLECTION(1, NamedArray
),
8307 USAGE(1, PID_USAGE_ET_SQUARE
),
8308 USAGE(1, PID_USAGE_ET_SINE
),
8309 USAGE(1, PID_USAGE_ET_SPRING
),
8310 LOGICAL_MINIMUM(1, 1),
8311 LOGICAL_MAXIMUM(1, 3),
8312 PHYSICAL_MINIMUM(1, 1),
8313 PHYSICAL_MAXIMUM(1, 3),
8316 OUTPUT(1, Data
|Ary
|Abs
),
8319 USAGE(1, PID_USAGE_AXES_ENABLE
),
8320 COLLECTION(1, Logical
),
8321 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_X
),
8322 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Y
),
8323 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Z
),
8324 LOGICAL_MINIMUM(1, 0),
8325 LOGICAL_MAXIMUM(1, 1),
8326 PHYSICAL_MINIMUM(1, 0),
8327 PHYSICAL_MAXIMUM(1, 1),
8330 OUTPUT(1, Data
|Var
|Abs
),
8332 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
8334 OUTPUT(1, Data
|Var
|Abs
),
8336 OUTPUT(1, Cnst
|Var
|Abs
),
8338 USAGE(1, PID_USAGE_DURATION
),
8339 USAGE(1, PID_USAGE_START_DELAY
),
8340 UNIT(2, 0x1003), /* Eng Lin:Time */
8341 UNIT_EXPONENT(1, -3), /* 10^-3 */
8342 LOGICAL_MINIMUM(1, 0),
8343 LOGICAL_MAXIMUM(2, 0x7fff),
8344 PHYSICAL_MINIMUM(1, 0),
8345 PHYSICAL_MAXIMUM(2, 0x7fff),
8348 OUTPUT(1, Data
|Var
|Abs
),
8350 UNIT_EXPONENT(1, 0),
8352 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
8353 LOGICAL_MINIMUM(1, 1),
8354 LOGICAL_MAXIMUM(1, 0x08),
8355 PHYSICAL_MINIMUM(1, 1),
8356 PHYSICAL_MAXIMUM(1, 0x08),
8359 OUTPUT(1, Data
|Var
|Abs
),
8361 USAGE(1, PID_USAGE_DIRECTION
),
8362 COLLECTION(1, Logical
),
8363 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
8364 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
8365 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
8366 UNIT_EXPONENT(1, -2), /* 10^-2 */
8367 LOGICAL_MINIMUM(1, 0),
8368 LOGICAL_MAXIMUM(2, 0x00ff),
8369 PHYSICAL_MINIMUM(1, 0),
8370 PHYSICAL_MAXIMUM(4, 0x00008ca0),
8374 OUTPUT(1, Data
|Var
|Abs
),
8375 UNIT_EXPONENT(1, 0),
8380 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
8381 COLLECTION(1, Logical
),
8384 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
),
8385 COLLECTION(1, Logical
),
8386 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
8387 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
8388 LOGICAL_MINIMUM(1, 0),
8389 LOGICAL_MAXIMUM(1, 1),
8390 PHYSICAL_MINIMUM(1, 0),
8391 PHYSICAL_MAXIMUM(1, 1),
8394 OUTPUT(1, Data
|Var
|Abs
),
8398 OUTPUT(1, Cnst
|Var
|Abs
),
8400 USAGE(1, PID_USAGE_CP_OFFSET
),
8401 LOGICAL_MINIMUM(1, 0x80),
8402 LOGICAL_MAXIMUM(1, 0x7f),
8403 PHYSICAL_MINIMUM(2, 0xd8f0),
8404 PHYSICAL_MAXIMUM(2, 0x2710),
8407 OUTPUT(1, Data
|Var
|Abs
),
8409 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
8410 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
8411 LOGICAL_MINIMUM(1, 0x80),
8412 LOGICAL_MAXIMUM(1, 0x7f),
8413 PHYSICAL_MINIMUM(2, 0xd8f0),
8414 PHYSICAL_MAXIMUM(2, 0x2710),
8417 OUTPUT(1, Data
|Var
|Abs
),
8419 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
8420 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
8421 LOGICAL_MINIMUM(1, 0),
8422 LOGICAL_MAXIMUM(2, 0x00ff),
8423 PHYSICAL_MINIMUM(1, 0),
8424 PHYSICAL_MAXIMUM(2, 0x2710),
8427 OUTPUT(1, Data
|Var
|Abs
),
8429 USAGE(1, PID_USAGE_DEAD_BAND
),
8430 LOGICAL_MINIMUM(1, 0),
8431 LOGICAL_MAXIMUM(2, 0x00ff),
8432 PHYSICAL_MINIMUM(1, 0),
8433 PHYSICAL_MAXIMUM(2, 0x2710),
8436 OUTPUT(1, Data
|Var
|Abs
),
8439 USAGE(1, PID_USAGE_BLOCK_FREE_REPORT
),
8440 COLLECTION(1, Logical
),
8443 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8444 LOGICAL_MINIMUM(1, 1),
8445 LOGICAL_MAXIMUM(1, 0x7f),
8446 PHYSICAL_MINIMUM(1, 1),
8447 PHYSICAL_MAXIMUM(1, 0x7f),
8450 OUTPUT(1, Data
|Var
|Abs
),
8453 USAGE(1, PID_USAGE_POOL_REPORT
),
8454 COLLECTION(1, Logical
),
8457 USAGE(1, PID_USAGE_RAM_POOL_SIZE
),
8458 LOGICAL_MINIMUM(1, 0),
8459 LOGICAL_MAXIMUM(4, 0xffff),
8460 PHYSICAL_MINIMUM(1, 0),
8461 PHYSICAL_MAXIMUM(4, 0xffff),
8464 FEATURE(1, Data
|Var
|Abs
),
8466 USAGE(1, PID_USAGE_SIMULTANEOUS_EFFECTS_MAX
),
8467 LOGICAL_MINIMUM(1, 0),
8468 LOGICAL_MAXIMUM(1, 0x7f),
8469 PHYSICAL_MINIMUM(1, 0),
8470 PHYSICAL_MAXIMUM(1, 0x7f),
8473 FEATURE(1, Data
|Var
|Abs
),
8475 USAGE(1, PID_USAGE_DEVICE_MANAGED_POOL
),
8476 USAGE(1, PID_USAGE_SHARED_PARAMETER_BLOCKS
),
8477 LOGICAL_MINIMUM(1, 0),
8478 LOGICAL_MAXIMUM(1, 1),
8479 PHYSICAL_MINIMUM(1, 0),
8480 PHYSICAL_MAXIMUM(1, 1),
8483 FEATURE(1, Data
|Var
|Abs
),
8486 USAGE(1, PID_USAGE_CREATE_NEW_EFFECT_REPORT
),
8487 COLLECTION(1, Logical
),
8490 USAGE(1, PID_USAGE_EFFECT_TYPE
),
8491 COLLECTION(1, NamedArray
),
8492 USAGE(1, PID_USAGE_ET_SQUARE
),
8493 USAGE(1, PID_USAGE_ET_SINE
),
8494 USAGE(1, PID_USAGE_ET_SPRING
),
8495 LOGICAL_MINIMUM(1, 1),
8496 LOGICAL_MAXIMUM(1, 3),
8497 PHYSICAL_MINIMUM(1, 1),
8498 PHYSICAL_MAXIMUM(1, 3),
8501 FEATURE(1, Data
|Ary
|Abs
),
8505 USAGE(1, PID_USAGE_BLOCK_LOAD_REPORT
),
8506 COLLECTION(1, Logical
),
8509 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8510 LOGICAL_MINIMUM(1, 1),
8511 LOGICAL_MAXIMUM(1, 0x7f),
8512 PHYSICAL_MINIMUM(1, 1),
8513 PHYSICAL_MAXIMUM(1, 0x7f),
8516 FEATURE(1, Data
|Var
|Abs
),
8518 USAGE(1, PID_USAGE_BLOCK_LOAD_STATUS
),
8519 COLLECTION(1, NamedArray
),
8520 USAGE(1, PID_USAGE_BLOCK_LOAD_SUCCESS
),
8521 USAGE(1, PID_USAGE_BLOCK_LOAD_FULL
),
8522 USAGE(1, PID_USAGE_BLOCK_LOAD_ERROR
),
8523 LOGICAL_MINIMUM(1, 1),
8524 LOGICAL_MAXIMUM(1, 3),
8525 PHYSICAL_MINIMUM(1, 1),
8526 PHYSICAL_MAXIMUM(1, 3),
8529 FEATURE(1, Data
|Ary
|Abs
),
8532 USAGE(1, PID_USAGE_RAM_POOL_AVAILABLE
),
8533 LOGICAL_MINIMUM(1, 0),
8534 LOGICAL_MAXIMUM(4, 0xffff),
8535 PHYSICAL_MINIMUM(1, 0),
8536 PHYSICAL_MAXIMUM(4, 0xffff),
8538 REPORT_COUNT(1, 16),
8539 FEATURE(1, Data
|Var
|Abs
),
8543 #include "pop_hid_macros.h"
8545 static const HIDP_CAPS hid_caps
=
8547 .InputReportByteLength
= 5,
8549 struct hid_expect expect_reset
[] =
8553 .code
= IOCTL_HID_WRITE_REPORT
,
8556 .report_buf
= {1, 0x01},
8559 struct hid_expect expect_create
[] =
8561 /* create new effect */
8563 .code
= IOCTL_HID_SET_FEATURE
,
8566 .report_buf
= {2,0x03},
8570 .code
= IOCTL_HID_GET_FEATURE
,
8573 .report_buf
= {3,0x01,0x01,0x00,0x00},
8577 .code
= IOCTL_HID_WRITE_REPORT
,
8580 .report_buf
= {4,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8584 .code
= IOCTL_HID_WRITE_REPORT
,
8587 .report_buf
= {4,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8591 .code
= IOCTL_HID_WRITE_REPORT
,
8594 .report_buf
= {3,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
8597 struct hid_expect expect_start
=
8599 /* effect control */
8600 .code
= IOCTL_HID_WRITE_REPORT
,
8603 .report_buf
= {2,0x01,0x01,0x01},
8605 struct hid_expect expect_stop
=
8607 /* effect control */
8608 .code
= IOCTL_HID_WRITE_REPORT
,
8611 .report_buf
= {2,0x01,0x03,0x00},
8613 struct hid_expect expect_destroy
[] =
8615 /* effect operation */
8617 .code
= IOCTL_HID_WRITE_REPORT
,
8620 .report_buf
= {2,0x01,0x03,0x00},
8624 .code
= IOCTL_HID_WRITE_REPORT
,
8627 .report_buf
= {5,0x01},
8630 struct hid_expect device_state_input
[] =
8634 .code
= IOCTL_HID_READ_REPORT
,
8637 .report_buf
= {2,0xff,0x00,0xff},
8641 .code
= IOCTL_HID_READ_REPORT
,
8644 .report_buf
= {1,0x12,0x34,0x56,0xff},
8647 struct hid_expect device_state_input_1
[] =
8651 .code
= IOCTL_HID_READ_REPORT
,
8654 .report_buf
= {2,0x00,0x01,0x00},
8658 .code
= IOCTL_HID_READ_REPORT
,
8661 .report_buf
= {1,0x65,0x43,0x21,0x00},
8664 struct hid_expect device_state_input_2
[] =
8668 .code
= IOCTL_HID_READ_REPORT
,
8671 .report_buf
= {2,0x03,0x00,0x00},
8675 .code
= IOCTL_HID_READ_REPORT
,
8678 .report_buf
= {1,0x12,0x34,0x56,0xff},
8681 struct hid_expect expect_pool
[] =
8685 .code
= IOCTL_HID_GET_FEATURE
,
8688 .report_buf
= {1,0x10,0x00,0x01,0x03},
8693 .code
= IOCTL_HID_GET_FEATURE
,
8696 .report_buf
= {1,0x10,0x00,0x01,0x03},
8700 static const DWORD expect_axes
[3] =
8702 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
8703 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
8704 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
8706 static const LONG expect_directions
[3] = {
8711 static const DIENVELOPE expect_envelope
=
8713 .dwSize
= sizeof(DIENVELOPE
),
8714 .dwAttackLevel
= 1000,
8715 .dwAttackTime
= 2000,
8716 .dwFadeLevel
= 3000,
8719 static const DICONDITION expect_condition
[3] =
8723 .lPositiveCoefficient
= 2000,
8724 .lNegativeCoefficient
= -3000,
8725 .dwPositiveSaturation
= -4000,
8726 .dwNegativeSaturation
= -5000,
8731 .lPositiveCoefficient
= 5000,
8732 .lNegativeCoefficient
= -4000,
8733 .dwPositiveSaturation
= 3000,
8734 .dwNegativeSaturation
= 2000,
8739 .lPositiveCoefficient
= -8000,
8740 .lNegativeCoefficient
= 9000,
8741 .dwPositiveSaturation
= 10000,
8742 .dwNegativeSaturation
= 11000,
8743 .lDeadBand
= -12000,
8746 const DIEFFECT expect_desc
=
8748 .dwSize
= sizeof(DIEFFECT_DX6
),
8749 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
8751 .dwSamplePeriod
= 2000,
8753 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
8754 .dwTriggerRepeatInterval
= 5000,
8756 .rgdwAxes
= (void *)expect_axes
,
8757 .rglDirection
= (void *)expect_directions
,
8758 .lpEnvelope
= (void *)&expect_envelope
,
8759 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
8760 .lpvTypeSpecificParams
= (void *)expect_condition
,
8761 .dwStartDelay
= 6000,
8763 DIPROPGUIDANDPATH prop_guid_path
=
8767 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
8768 .dwHeaderSize
= sizeof(DIPROPHEADER
),
8769 .dwHow
= DIPH_DEVICE
,
8772 DIPROPDWORD prop_dword
=
8776 .dwSize
= sizeof(DIPROPDWORD
),
8777 .dwHeaderSize
= sizeof(DIPROPHEADER
),
8778 .dwHow
= DIPH_DEVICE
,
8781 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
8782 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
8783 IDirectInputDevice8W
*device
;
8784 IDirectInputEffect
*effect
;
8791 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
8792 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
8793 SetCurrentDirectoryW( tempdir
);
8795 cleanup_registry_keys();
8796 if (!dinput_driver_start( report_descriptor
, sizeof(report_descriptor
), &hid_caps
,
8797 expect_pool
, sizeof(expect_pool
) )) goto done
;
8798 if (FAILED(hr
= create_dinput_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
8800 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
8801 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
8802 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
8803 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
8804 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
8805 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
8807 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
8808 NULL
, NULL
, NULL
, NULL
);
8810 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
8811 ok( event
!= NULL
, "CreateEventW failed, last error %u\n", GetLastError() );
8812 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
8813 ok( hr
== DI_OK
, "SetEventNotification returned: %#x\n", hr
);
8814 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
8815 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
8816 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
8817 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
8819 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8820 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8821 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8823 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetForceFeedbackState returned %#x\n", hr
);
8824 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
8825 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "SendForceFeedbackCommand returned %#x\n", hr
);
8827 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
8828 hr
= IDirectInputDevice8_Acquire( device
);
8829 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
8830 wait_hid_expect( file
, 100 );
8832 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8833 prop_dword
.dwData
= 0xdeadbeef;
8834 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8835 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8836 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#x\n", prop_dword
.dwData
);
8837 set_hid_expect( file
, NULL
, 0 );
8839 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8841 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8843 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
8844 flags
= DIGFFS_STOPPED
|DIGFFS_EMPTY
;
8846 ok( res
== flags
, "got state %#x\n", res
);
8847 set_hid_expect( file
, NULL
, 0 );
8849 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8850 prop_dword
.dwData
= 0xdeadbeef;
8851 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8852 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8853 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#x\n", prop_dword
.dwData
);
8854 set_hid_expect( file
, NULL
, 0 );
8856 send_hid_input( file
, device_state_input
, sizeof(struct hid_expect
) );
8857 res
= WaitForSingleObject( event
, 100 );
8858 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#x\n", res
);
8859 send_hid_input( file
, device_state_input
, sizeof(device_state_input
) );
8860 res
= WaitForSingleObject( event
, 100 );
8861 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
8863 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8865 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8867 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
8868 flags
= DIGFFS_PAUSED
|DIGFFS_EMPTY
|DIGFFS_ACTUATORSON
|DIGFFS_POWERON
|DIGFFS_SAFETYSWITCHON
|DIGFFS_USERFFSWITCHON
;
8870 ok( res
== flags
, "got state %#x\n", res
);
8871 set_hid_expect( file
, NULL
, 0 );
8873 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, NULL
, &effect
, NULL
);
8874 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
8876 hr
= IDirectInputEffect_GetEffectStatus( effect
, NULL
);
8877 ok( hr
== E_POINTER
, "GetEffectStatus returned %#x\n", hr
);
8879 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
8881 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#x\n", hr
);
8883 ok( res
== 0, "got status %#x\n", res
);
8885 flags
= DIEP_ALLPARAMS
;
8886 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
| DIEP_NODOWNLOAD
);
8887 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
8889 set_hid_expect( file
, expect_reset
, sizeof(struct hid_expect
) );
8890 hr
= IDirectInputDevice8_Unacquire( device
);
8891 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
8892 set_hid_expect( file
, NULL
, 0 );
8894 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
8896 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetEffectStatus returned %#x\n", hr
);
8898 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
8899 hr
= IDirectInputDevice8_Acquire( device
);
8900 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
8901 wait_hid_expect( file
, 100 );
8904 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
8906 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#x\n", hr
);
8908 ok( res
== 0, "got status %#x\n", res
);
8910 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8912 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8914 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
8915 flags
= DIGFFS_STOPPED
|DIGFFS_EMPTY
;
8917 ok( res
== flags
, "got state %#x\n", res
);
8918 set_hid_expect( file
, NULL
, 0 );
8920 set_hid_expect( file
, expect_create
, sizeof(expect_create
) );
8921 hr
= IDirectInputEffect_Download( effect
);
8922 ok( hr
== DI_OK
, "Download returned %#x\n", hr
);
8923 set_hid_expect( file
, NULL
, 0 );
8926 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
8928 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
8930 ok( res
== 0, "got status %#x\n", res
);
8931 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8933 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8935 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
8936 flags
= DIGFFS_STOPPED
;
8938 ok( res
== flags
, "got state %#x\n", res
);
8939 set_hid_expect( file
, NULL
, 0 );
8941 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8942 prop_dword
.dwData
= 0xdeadbeef;
8943 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8944 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8945 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#x\n", prop_dword
.dwData
);
8946 set_hid_expect( file
, NULL
, 0 );
8948 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
8949 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
8950 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
8951 set_hid_expect( file
, NULL
, 0 );
8954 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
8956 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
8958 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
8960 send_hid_input( file
, device_state_input_1
, sizeof(device_state_input_1
) );
8961 res
= WaitForSingleObject( event
, 100 );
8962 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
8964 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
8966 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
8968 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
8969 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8971 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8973 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
8974 flags
= DIGFFS_ACTUATORSOFF
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
8976 ok( res
== flags
, "got state %#x\n", res
);
8977 set_hid_expect( file
, NULL
, 0 );
8979 send_hid_input( file
, device_state_input_2
, sizeof(device_state_input_2
) );
8980 res
= WaitForSingleObject( event
, 100 );
8981 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
8983 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
8985 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
8987 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
8988 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
8990 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8992 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
8993 flags
= DIGFFS_PAUSED
|DIGFFS_ACTUATORSON
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
8995 ok( res
== flags
, "got state %#x\n", res
);
8996 set_hid_expect( file
, NULL
, 0 );
8998 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
8999 hr
= IDirectInputEffect_Stop( effect
);
9000 ok( hr
== DI_OK
, "Stop returned %#x\n", hr
);
9001 set_hid_expect( file
, NULL
, 0 );
9004 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9006 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9008 ok( res
== 0, "got status %#x\n", res
);
9009 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9011 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9013 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9014 flags
= DIGFFS_PAUSED
|DIGFFS_ACTUATORSON
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
9016 ok( res
== flags
, "got state %#x\n", res
);
9017 set_hid_expect( file
, NULL
, 0 );
9019 set_hid_expect( file
, expect_destroy
, sizeof(expect_destroy
) );
9020 hr
= IDirectInputEffect_Unload( effect
);
9021 ok( hr
== DI_OK
, "Unload returned %#x\n", hr
);
9022 set_hid_expect( file
, NULL
, 0 );
9025 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9027 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#x\n", hr
);
9029 ok( res
== 0, "got status %#x\n", res
);
9030 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9032 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9034 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9035 flags
= DIGFFS_EMPTY
|DIGFFS_PAUSED
|DIGFFS_ACTUATORSON
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
9037 ok( res
== flags
, "got state %#x\n", res
);
9038 set_hid_expect( file
, NULL
, 0 );
9040 ref
= IDirectInputEffect_Release( effect
);
9041 ok( ref
== 0, "Release returned %d\n", ref
);
9043 set_hid_expect( file
, expect_reset
, sizeof(struct hid_expect
) );
9044 hr
= IDirectInputDevice8_Unacquire( device
);
9045 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
9046 set_hid_expect( file
, NULL
, 0 );
9048 ref
= IDirectInputDevice8_Release( device
);
9049 ok( ref
== 0, "Release returned %d\n", ref
);
9051 DestroyWindow( hwnd
);
9052 CloseHandle( event
);
9053 CloseHandle( file
);
9057 cleanup_registry_keys();
9058 SetCurrentDirectoryW( cwd
);
9059 winetest_pop_context();
9067 instance
= GetModuleHandleW( NULL
);
9068 localized
= GetUserDefaultLCID() != MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
);
9069 pSignerSign
= (void *)GetProcAddress( LoadLibraryW( L
"mssign32" ), "SignerSign" );
9071 if (IsWow64Process( GetCurrentProcess(), &is_wow64
) && is_wow64
)
9073 skip( "Running in WoW64.\n" );
9077 mapping
= CreateFileMappingW( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, sizeof(*test_data
),
9078 L
"Global\\winetest_dinput_section" );
9079 if (!mapping
&& GetLastError() == ERROR_ACCESS_DENIED
)
9081 win_skip( "Failed to create test data mapping.\n" );
9084 ok( !!mapping
, "got error %u\n", GetLastError() );
9085 test_data
= MapViewOfFile( mapping
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 1024 );
9086 test_data
->running_under_wine
= !strcmp( winetest_platform
, "wine" );
9087 test_data
->winetest_report_success
= winetest_report_success
;
9088 test_data
->winetest_debug
= winetest_debug
;
9090 okfile
= CreateFileW( L
"C:\\windows\\winetest_dinput_okfile", GENERIC_READ
| GENERIC_WRITE
,
9091 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
9092 ok( okfile
!= INVALID_HANDLE_VALUE
, "failed to create file, error %u\n", GetLastError() );
9094 subtest( "driver_hid" );
9096 test_hid_driver( 0, FALSE
);
9097 test_hid_driver( 1, FALSE
);
9098 test_hid_driver( 0, TRUE
);
9099 test_hid_driver( 1, TRUE
);
9101 CoInitialize( NULL
);
9102 if (test_device_types( 0x800 ))
9104 test_device_types( 0x500 );
9105 test_device_types( 0x700 );
9107 test_simple_joystick();
9108 test_force_feedback_joystick( 0x500 );
9109 test_force_feedback_joystick( 0x700 );
9110 test_force_feedback_joystick( 0x800 );
9112 test_device_managed_effect();
9116 UnmapViewOfFile( test_data
);
9117 CloseHandle( mapping
);
9118 CloseHandle( okfile
);
9119 DeleteFileW( L
"C:\\windows\\winetest_dinput_okfile" );