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 fill_context( line, a, b ) \
770 const char *source_file; \
771 source_file = strrchr( __FILE__, '/' ); \
772 if (!source_file) source_file = strrchr( __FILE__, '\\' ); \
773 if (!source_file) source_file = __FILE__; \
774 else source_file++; \
775 snprintf( a, b, "%s:%d", source_file, line ); \
778 #define set_hid_expect( a, b, c ) set_hid_expect_( __LINE__, a, b, c )
779 static void set_hid_expect_( int line
, HANDLE file
, struct hid_expect
*expect
, DWORD expect_size
)
784 fill_context( line
, context
, ARRAY_SIZE(context
) );
785 ret
= sync_ioctl_( line
, file
, IOCTL_WINETEST_HID_SET_CONTEXT
, context
, ARRAY_SIZE(context
), NULL
, 0, INFINITE
);
786 ok_(__FILE__
, line
)( ret
, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %u\n", GetLastError() );
787 ret
= sync_ioctl_( line
, file
, IOCTL_WINETEST_HID_SET_EXPECT
, expect
, expect_size
, NULL
, 0, INFINITE
);
788 ok_(__FILE__
, line
)( ret
, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u\n", GetLastError() );
791 #define wait_hid_expect( a, b ) wait_hid_expect_( __LINE__, a, b )
792 static void wait_hid_expect_( int line
, HANDLE file
, DWORD timeout
)
794 BOOL ret
= sync_ioctl_( line
, file
, IOCTL_WINETEST_HID_WAIT_EXPECT
, NULL
, 0, NULL
, 0, timeout
);
795 ok_(__FILE__
, line
)( ret
, "IOCTL_WINETEST_HID_WAIT_EXPECT failed, last error %u\n", GetLastError() );
797 set_hid_expect_( line
, file
, NULL
, 0 );
800 #define send_hid_input( a, b, c ) send_hid_input_( __LINE__, a, b, c )
801 static void send_hid_input_( int line
, HANDLE file
, struct hid_expect
*expect
, DWORD expect_size
)
806 fill_context( line
, context
, ARRAY_SIZE(context
) );
807 ret
= sync_ioctl_( line
, file
, IOCTL_WINETEST_HID_SET_CONTEXT
, context
, ARRAY_SIZE(context
), NULL
, 0, INFINITE
);
808 ok_(__FILE__
, line
)( ret
, "IOCTL_WINETEST_HID_SET_CONTEXT failed, last error %u\n", GetLastError() );
809 ret
= sync_ioctl( file
, IOCTL_WINETEST_HID_SEND_INPUT
, expect
, expect_size
, NULL
, 0, INFINITE
);
810 ok( ret
, "IOCTL_WINETEST_HID_SEND_INPUT failed, last error %u\n", GetLastError() );
813 static void test_hidp_get_input( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
815 struct hid_expect expect
[] =
818 .code
= IOCTL_HID_GET_INPUT_REPORT
,
819 .report_id
= report_id
,
820 .report_len
= report_len
- (report_id
? 0 : 1),
821 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,2},
823 .ret_status
= STATUS_SUCCESS
,
826 .code
= IOCTL_HID_GET_INPUT_REPORT
,
827 .report_id
= report_id
,
828 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
829 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,1},
831 .ret_status
= STATUS_SUCCESS
,
835 char buffer
[200], report
[200];
840 memset( report
, 0xcd, sizeof(report
) );
841 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed
, report
, report_len
);
842 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
844 SetLastError( 0xdeadbeef );
845 ret
= HidD_GetInputReport( file
, report
, 0 );
846 ok( !ret
, "HidD_GetInputReport succeeded\n" );
847 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetInputReport returned error %u\n", GetLastError() );
849 SetLastError( 0xdeadbeef );
850 ret
= HidD_GetInputReport( file
, report
, report_len
- 1 );
851 ok( !ret
, "HidD_GetInputReport succeeded\n" );
852 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
853 "HidD_GetInputReport returned error %u\n", GetLastError() );
857 struct hid_expect broken_expect
=
859 .code
= IOCTL_HID_GET_INPUT_REPORT
,
861 .report_len
= report_len
- 1,
864 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
865 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
866 0x5a,0x5a,0x5a,0x5a,0x5a,
869 .ret_status
= STATUS_SUCCESS
,
872 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
875 SetLastError( 0xdeadbeef );
876 memset( buffer
, 0x5a, sizeof(buffer
) );
877 ret
= HidD_GetInputReport( file
, buffer
, report_len
);
878 if (report_id
|| broken( !ret
) /* w7u */)
880 ok( !ret
, "HidD_GetInputReport succeeded, last error %u\n", GetLastError() );
881 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
882 "HidD_GetInputReport returned error %u\n", GetLastError() );
886 ok( ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError() );
887 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
890 set_hid_expect( file
, expect
, sizeof(expect
) );
892 SetLastError( 0xdeadbeef );
893 ret
= HidD_GetInputReport( file
, report
, report_len
);
894 ok( ret
, "HidD_GetInputReport failed, last error %u\n", GetLastError() );
895 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
897 SetLastError( 0xdeadbeef );
898 length
= report_len
* 2;
899 ret
= sync_ioctl( file
, IOCTL_HID_GET_INPUT_REPORT
, NULL
, 0, report
, &length
, INFINITE
);
900 ok( ret
, "IOCTL_HID_GET_INPUT_REPORT failed, last error %u\n", GetLastError() );
901 ok( length
== 3, "got length %u, expected 3\n", length
);
902 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
904 set_hid_expect( file
, NULL
, 0 );
907 static void test_hidp_get_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
909 struct hid_expect expect
[] =
912 .code
= IOCTL_HID_GET_FEATURE
,
913 .report_id
= report_id
,
914 .report_len
= report_len
- (report_id
? 0 : 1),
915 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
917 .ret_status
= STATUS_SUCCESS
,
920 .code
= IOCTL_HID_GET_FEATURE
,
921 .report_id
= report_id
,
922 .report_len
= 2 * report_len
- (report_id
? 0 : 1),
923 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5},
925 .ret_status
= STATUS_SUCCESS
,
929 char buffer
[200], report
[200];
934 memset( report
, 0xcd, sizeof(report
) );
935 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
936 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
938 SetLastError( 0xdeadbeef );
939 ret
= HidD_GetFeature( file
, report
, 0 );
940 ok( !ret
, "HidD_GetFeature succeeded\n" );
941 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_GetFeature returned error %u\n", GetLastError() );
943 SetLastError( 0xdeadbeef );
944 ret
= HidD_GetFeature( file
, report
, report_len
- 1 );
945 ok( !ret
, "HidD_GetFeature succeeded\n" );
946 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
947 "HidD_GetFeature returned error %u\n", GetLastError() );
951 struct hid_expect broken_expect
=
953 .code
= IOCTL_HID_GET_FEATURE
,
955 .report_len
= report_len
- 1,
958 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
959 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
960 0x5a,0x5a,0x5a,0x5a,0x5a,
963 .ret_status
= STATUS_SUCCESS
,
966 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
969 SetLastError( 0xdeadbeef );
970 memset( buffer
, 0x5a, sizeof(buffer
) );
971 ret
= HidD_GetFeature( file
, buffer
, report_len
);
972 if (report_id
|| broken( !ret
))
974 ok( !ret
, "HidD_GetFeature succeeded, last error %u\n", GetLastError() );
975 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
976 "HidD_GetFeature returned error %u\n", GetLastError() );
980 ok( ret
, "HidD_GetFeature failed, last error %u\n", GetLastError() );
981 ok( buffer
[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE
)buffer
[0] );
984 set_hid_expect( file
, expect
, sizeof(expect
) );
986 SetLastError( 0xdeadbeef );
987 ret
= HidD_GetFeature( file
, report
, report_len
);
988 ok( ret
, "HidD_GetFeature failed, last error %u\n", GetLastError() );
989 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
991 length
= report_len
* 2;
992 SetLastError( 0xdeadbeef );
993 ret
= sync_ioctl( file
, IOCTL_HID_GET_FEATURE
, NULL
, 0, report
, &length
, INFINITE
);
994 ok( ret
, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError() );
995 ok( length
== 3, "got length %u, expected 3\n", length
);
996 ok( report
[0] == report_id
, "got report[0] %02x, expected %02x\n", report
[0], report_id
);
998 set_hid_expect( file
, NULL
, 0 );
1001 static void test_hidp_set_feature( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1003 struct hid_expect expect
[] =
1006 .code
= IOCTL_HID_SET_FEATURE
,
1007 .report_id
= report_id
,
1008 .report_len
= report_len
- (report_id
? 0 : 1),
1009 .report_buf
= {report_id
},
1011 .ret_status
= STATUS_SUCCESS
,
1014 .code
= IOCTL_HID_SET_FEATURE
,
1015 .report_id
= report_id
,
1016 .report_len
= report_len
- (report_id
? 0 : 1),
1019 report_id
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1020 0,0,0,0,0,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
1021 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
1024 .ret_status
= STATUS_SUCCESS
,
1027 char buffer
[200], report
[200];
1032 memset( report
, 0xcd, sizeof(report
) );
1033 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed
, report
, report_len
);
1034 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1036 SetLastError( 0xdeadbeef );
1037 ret
= HidD_SetFeature( file
, report
, 0 );
1038 ok( !ret
, "HidD_SetFeature succeeded\n" );
1039 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetFeature returned error %u\n", GetLastError() );
1041 SetLastError( 0xdeadbeef );
1042 ret
= HidD_SetFeature( file
, report
, report_len
- 1 );
1043 ok( !ret
, "HidD_SetFeature succeeded\n" );
1044 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1045 "HidD_SetFeature returned error %u\n", GetLastError() );
1049 struct hid_expect broken_expect
=
1051 .code
= IOCTL_HID_SET_FEATURE
,
1053 .report_len
= report_len
- 1,
1056 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1057 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1058 0x5a,0x5a,0x5a,0x5a,0x5a,
1061 .ret_status
= STATUS_SUCCESS
,
1064 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1067 SetLastError( 0xdeadbeef );
1068 memset( buffer
, 0x5a, sizeof(buffer
) );
1069 ret
= HidD_SetFeature( file
, buffer
, report_len
);
1070 if (report_id
|| broken( !ret
))
1072 ok( !ret
, "HidD_SetFeature succeeded, last error %u\n", GetLastError() );
1073 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1074 "HidD_SetFeature returned error %u\n", GetLastError() );
1078 ok( ret
, "HidD_SetFeature failed, last error %u\n", GetLastError() );
1081 set_hid_expect( file
, expect
, sizeof(expect
) );
1083 SetLastError( 0xdeadbeef );
1084 ret
= HidD_SetFeature( file
, report
, report_len
);
1085 ok( ret
, "HidD_SetFeature failed, last error %u\n", GetLastError() );
1087 length
= report_len
* 2;
1088 SetLastError( 0xdeadbeef );
1089 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, NULL
, 0, report
, &length
, INFINITE
);
1090 ok( !ret
, "IOCTL_HID_SET_FEATURE succeeded\n" );
1091 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "IOCTL_HID_SET_FEATURE returned error %u\n",
1094 SetLastError( 0xdeadbeef );
1095 ret
= sync_ioctl( file
, IOCTL_HID_SET_FEATURE
, report
, report_len
* 2, NULL
, &length
, INFINITE
);
1096 ok( ret
, "IOCTL_HID_SET_FEATURE failed, last error %u\n", GetLastError() );
1097 ok( length
== 3, "got length %u, expected 3\n", length
);
1099 set_hid_expect( file
, NULL
, 0 );
1102 static void test_hidp_set_output( HANDLE file
, int report_id
, ULONG report_len
, PHIDP_PREPARSED_DATA preparsed
)
1104 struct hid_expect expect
[] =
1107 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1108 .report_id
= report_id
,
1109 .report_len
= report_len
- (report_id
? 0 : 1),
1110 .report_buf
= {report_id
},
1112 .ret_status
= STATUS_SUCCESS
,
1115 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1116 .report_id
= report_id
,
1117 .report_len
= report_len
- (report_id
? 0 : 1),
1118 .report_buf
= {report_id
,0,0xcd,0xcd,0xcd},
1120 .ret_status
= STATUS_SUCCESS
,
1124 char buffer
[200], report
[200];
1129 memset( report
, 0xcd, sizeof(report
) );
1130 status
= HidP_InitializeReportForID( HidP_Output
, report_id
, preparsed
, report
, report_len
);
1131 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1132 memset( report
, 0, report_len
);
1133 report
[0] = report_id
;
1135 SetLastError( 0xdeadbeef );
1136 ret
= HidD_SetOutputReport( file
, report
, 0 );
1137 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1138 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "HidD_SetOutputReport returned error %u\n",
1141 SetLastError( 0xdeadbeef );
1142 ret
= HidD_SetOutputReport( file
, report
, report_len
- 1 );
1143 ok( !ret
, "HidD_SetOutputReport succeeded\n" );
1144 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1145 "HidD_SetOutputReport returned error %u\n", GetLastError() );
1149 struct hid_expect broken_expect
=
1151 .code
= IOCTL_HID_SET_OUTPUT_REPORT
,
1153 .report_len
= report_len
- 1,
1154 .report_buf
= {0x5a,0x5a},
1156 .ret_status
= STATUS_SUCCESS
,
1159 set_hid_expect( file
, &broken_expect
, sizeof(broken_expect
) );
1162 SetLastError( 0xdeadbeef );
1163 memset( buffer
, 0x5a, sizeof(buffer
) );
1164 ret
= HidD_SetOutputReport( file
, buffer
, report_len
);
1165 if (report_id
|| broken( !ret
))
1167 ok( !ret
, "HidD_SetOutputReport succeeded, last error %u\n", GetLastError() );
1168 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken( GetLastError() == ERROR_CRC
),
1169 "HidD_SetOutputReport returned error %u\n", GetLastError() );
1173 ok( ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError() );
1176 set_hid_expect( file
, expect
, sizeof(expect
) );
1178 SetLastError( 0xdeadbeef );
1179 ret
= HidD_SetOutputReport( file
, report
, report_len
);
1180 ok( ret
, "HidD_SetOutputReport failed, last error %u\n", GetLastError() );
1182 length
= report_len
* 2;
1183 SetLastError( 0xdeadbeef );
1184 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, NULL
, 0, report
, &length
, INFINITE
);
1185 ok( !ret
, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n" );
1186 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
,
1187 "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError() );
1189 SetLastError( 0xdeadbeef );
1190 ret
= sync_ioctl( file
, IOCTL_HID_SET_OUTPUT_REPORT
, report
, report_len
* 2, NULL
, &length
, INFINITE
);
1191 ok( ret
, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError() );
1192 ok( length
== 3, "got length %u, expected 3\n", length
);
1194 set_hid_expect( file
, NULL
, 0 );
1197 static void test_write_file( HANDLE file
, int report_id
, ULONG report_len
)
1199 struct hid_expect expect
=
1201 .code
= IOCTL_HID_WRITE_REPORT
,
1202 .report_id
= report_id
,
1203 .report_len
= report_len
- (report_id
? 0 : 1),
1204 .report_buf
= {report_id
? report_id
: 0xcd,0xcd,0xcd,0xcd,0xcd},
1206 .ret_status
= STATUS_SUCCESS
,
1213 SetLastError( 0xdeadbeef );
1214 ret
= WriteFile( file
, report
, 0, &length
, NULL
);
1215 ok( !ret
, "WriteFile succeeded\n" );
1216 ok( GetLastError() == ERROR_INVALID_USER_BUFFER
, "WriteFile returned error %u\n", GetLastError() );
1217 ok( length
== 0, "WriteFile returned %x\n", length
);
1218 SetLastError( 0xdeadbeef );
1219 ret
= WriteFile( file
, report
, report_len
- 1, &length
, NULL
);
1220 ok( !ret
, "WriteFile succeeded\n" );
1221 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_USER_BUFFER
,
1222 "WriteFile returned error %u\n", GetLastError() );
1223 ok( length
== 0, "WriteFile returned %x\n", length
);
1225 set_hid_expect( file
, &expect
, sizeof(expect
) );
1227 memset( report
, 0xcd, sizeof(report
) );
1229 SetLastError( 0xdeadbeef );
1230 ret
= WriteFile( file
, report
, report_len
* 2, &length
, NULL
);
1231 if (report_id
|| broken( !ret
) /* w7u */)
1233 ok( !ret
, "WriteFile succeeded\n" );
1234 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "WriteFile returned error %u\n", GetLastError() );
1235 ok( length
== 0, "WriteFile wrote %u\n", length
);
1236 SetLastError( 0xdeadbeef );
1237 report
[0] = report_id
;
1238 ret
= WriteFile( file
, report
, report_len
, &length
, NULL
);
1243 ok( ret
, "WriteFile failed, last error %u\n", GetLastError() );
1244 ok( length
== 2, "WriteFile wrote %u\n", length
);
1248 ok( ret
, "WriteFile failed, last error %u\n", GetLastError() );
1249 ok( length
== 3, "WriteFile wrote %u\n", length
);
1252 set_hid_expect( file
, NULL
, 0 );
1255 static void test_hidp( HANDLE file
, HANDLE async_file
, int report_id
, BOOL polled
, const HIDP_CAPS
*expect_caps
)
1257 const HIDP_BUTTON_CAPS expect_button_caps
[] =
1260 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1261 .ReportID
= report_id
,
1263 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1264 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1265 .LinkCollection
= 1,
1268 .Range
.UsageMin
= 1,
1269 .Range
.UsageMax
= 8,
1270 .Range
.DataIndexMin
= 2,
1271 .Range
.DataIndexMax
= 9,
1274 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1275 .ReportID
= report_id
,
1277 .LinkCollection
= 1,
1278 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1279 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1282 .Range
.UsageMin
= 0x18,
1283 .Range
.UsageMax
= 0x1f,
1284 .Range
.DataIndexMin
= 10,
1285 .Range
.DataIndexMax
= 17,
1288 .UsagePage
= HID_USAGE_PAGE_KEYBOARD
,
1289 .ReportID
= report_id
,
1291 .LinkCollection
= 1,
1292 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1293 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1295 .IsAbsolute
= FALSE
,
1296 .Range
.UsageMin
= 0x8,
1297 .Range
.UsageMax
= 0xf,
1298 .Range
.DataIndexMin
= 18,
1299 .Range
.DataIndexMax
= 25,
1302 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1303 .ReportID
= report_id
,
1305 .LinkCollection
= 1,
1306 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1307 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1310 .NotRange
.Usage
= 0x20,
1311 .NotRange
.Reserved1
= 0x20,
1312 .NotRange
.DataIndex
= 26,
1313 .NotRange
.Reserved4
= 26,
1316 const HIDP_VALUE_CAPS expect_value_caps
[] =
1319 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1320 .ReportID
= report_id
,
1322 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1323 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1324 .LinkCollection
= 1,
1330 .NotRange
.Usage
= HID_USAGE_GENERIC_Y
,
1331 .NotRange
.Reserved1
= HID_USAGE_GENERIC_Y
,
1334 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1335 .ReportID
= report_id
,
1337 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1338 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1339 .LinkCollection
= 1,
1345 .NotRange
.Usage
= HID_USAGE_GENERIC_X
,
1346 .NotRange
.Reserved1
= HID_USAGE_GENERIC_X
,
1347 .NotRange
.DataIndex
= 1,
1348 .NotRange
.Reserved4
= 1,
1351 .UsagePage
= HID_USAGE_PAGE_BUTTON
,
1352 .ReportID
= report_id
,
1354 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1355 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1356 .LinkCollection
= 1,
1361 .Range
.UsageMin
= 0x21,
1362 .Range
.UsageMax
= 0x22,
1363 .Range
.DataIndexMin
= 27,
1364 .Range
.DataIndexMax
= 28,
1367 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
1368 .ReportID
= report_id
,
1370 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1371 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1372 .LinkCollection
= 1,
1378 .NotRange
.Usage
= HID_USAGE_GENERIC_HATSWITCH
,
1379 .NotRange
.Reserved1
= HID_USAGE_GENERIC_HATSWITCH
,
1380 .NotRange
.DataIndex
= 29,
1381 .NotRange
.Reserved4
= 29,
1384 static const HIDP_LINK_COLLECTION_NODE expect_collections
[] =
1387 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1388 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1389 .CollectionType
= 1,
1390 .NumberOfChildren
= 7,
1394 .LinkUsage
= HID_USAGE_GENERIC_JOYSTICK
,
1395 .LinkUsagePage
= HID_USAGE_PAGE_GENERIC
,
1396 .CollectionType
= 2,
1399 static const HIDP_DATA expect_data
[] =
1401 { .DataIndex
= 0, },
1402 { .DataIndex
= 1, },
1403 { .DataIndex
= 5, .RawValue
= 1, },
1404 { .DataIndex
= 7, .RawValue
= 1, },
1405 { .DataIndex
= 19, .RawValue
= 1, },
1406 { .DataIndex
= 21, .RawValue
= 1, },
1407 { .DataIndex
= 30, },
1408 { .DataIndex
= 31, },
1409 { .DataIndex
= 32, .RawValue
= 0xfeedcafe, },
1410 { .DataIndex
= 37, .RawValue
= 1, },
1411 { .DataIndex
= 39, .RawValue
= 1, },
1414 OVERLAPPED overlapped
= {0}, overlapped2
= {0};
1415 HIDP_LINK_COLLECTION_NODE collections
[16];
1416 PHIDP_PREPARSED_DATA preparsed_data
;
1417 USAGE_AND_PAGE usage_and_pages
[16];
1418 HIDP_BUTTON_CAPS button_caps
[32];
1419 HIDP_VALUE_CAPS value_caps
[16];
1420 char buffer
[200], report
[200];
1421 DWORD collection_count
;
1422 DWORD waveform_list
;
1432 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
1433 ok( ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
1435 memset( buffer
, 0, sizeof(buffer
) );
1436 status
= HidP_GetCaps( (PHIDP_PREPARSED_DATA
)buffer
, &caps
);
1437 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetCaps returned %#x\n", status
);
1438 status
= HidP_GetCaps( preparsed_data
, &caps
);
1439 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetCaps returned %#x\n", status
);
1440 check_hidp_caps( &caps
, expect_caps
);
1442 collection_count
= 0;
1443 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1444 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1445 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1446 "got %d collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1447 collection_count
= ARRAY_SIZE(collections
);
1448 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, (PHIDP_PREPARSED_DATA
)buffer
);
1449 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1450 status
= HidP_GetLinkCollectionNodes( collections
, &collection_count
, preparsed_data
);
1451 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetLinkCollectionNodes returned %#x\n", status
);
1452 ok( collection_count
== caps
.NumberLinkCollectionNodes
,
1453 "got %d collection nodes, expected %d\n", collection_count
, caps
.NumberLinkCollectionNodes
);
1455 for (i
= 0; i
< ARRAY_SIZE(expect_collections
); ++i
)
1457 winetest_push_context( "collections[%d]", i
);
1458 check_hidp_link_collection_node( &collections
[i
], &expect_collections
[i
] );
1459 winetest_pop_context();
1462 count
= ARRAY_SIZE(button_caps
);
1463 status
= HidP_GetButtonCaps( HidP_Output
, button_caps
, &count
, preparsed_data
);
1464 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetButtonCaps returned %#x\n", status
);
1465 status
= HidP_GetButtonCaps( HidP_Feature
+ 1, button_caps
, &count
, preparsed_data
);
1466 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetButtonCaps returned %#x\n", status
);
1468 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1469 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetButtonCaps returned %#x\n", status
);
1470 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1471 count
, caps
.NumberInputButtonCaps
);
1472 count
= ARRAY_SIZE(button_caps
);
1473 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1474 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetButtonCaps returned %#x\n", status
);
1475 memset( button_caps
, 0, sizeof(button_caps
) );
1476 status
= HidP_GetButtonCaps( HidP_Input
, button_caps
, &count
, preparsed_data
);
1477 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetButtonCaps returned %#x\n", status
);
1478 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetButtonCaps returned count %d, expected %d\n",
1479 count
, caps
.NumberInputButtonCaps
);
1481 for (i
= 0; i
< ARRAY_SIZE(expect_button_caps
); ++i
)
1483 winetest_push_context( "button_caps[%d]", i
);
1484 check_hidp_button_caps( &button_caps
[i
], &expect_button_caps
[i
] );
1485 winetest_pop_context();
1488 count
= ARRAY_SIZE(button_caps
) - 1;
1489 status
= HidP_GetSpecificButtonCaps( HidP_Output
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1490 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1491 status
= HidP_GetSpecificButtonCaps( HidP_Feature
+ 1, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1492 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1494 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, preparsed_data
);
1495 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1496 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1497 count
, caps
.NumberInputButtonCaps
);
1498 count
= ARRAY_SIZE(button_caps
) - 1;
1499 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1500 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1502 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0, button_caps
+ 1, &count
, preparsed_data
);
1503 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1504 ok( count
== caps
.NumberInputButtonCaps
, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n",
1505 count
, caps
.NumberInputButtonCaps
);
1506 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1508 status
= HidP_GetSpecificButtonCaps( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, 5, button_caps
+ 1,
1509 &count
, preparsed_data
);
1510 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1511 ok( count
== 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 1 );
1512 check_hidp_button_caps( &button_caps
[1], &button_caps
[0] );
1515 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0xfffe, 0, 0, button_caps
, &count
, preparsed_data
);
1516 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1517 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1519 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0xfffe, 0, button_caps
, &count
, preparsed_data
);
1520 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1521 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1523 status
= HidP_GetSpecificButtonCaps( HidP_Input
, 0, 0, 0xfffe, button_caps
, &count
, preparsed_data
);
1524 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificButtonCaps returned %#x\n", status
);
1525 ok( count
== 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count
, 0 );
1527 count
= ARRAY_SIZE(value_caps
);
1528 status
= HidP_GetValueCaps( HidP_Output
, value_caps
, &count
, preparsed_data
);
1529 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetValueCaps returned %#x\n", status
);
1530 status
= HidP_GetValueCaps( HidP_Feature
+ 1, value_caps
, &count
, preparsed_data
);
1531 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetValueCaps returned %#x\n", status
);
1533 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1534 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetValueCaps returned %#x\n", status
);
1535 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1536 count
, caps
.NumberInputValueCaps
);
1537 count
= ARRAY_SIZE(value_caps
);
1538 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1539 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetValueCaps returned %#x\n", status
);
1540 status
= HidP_GetValueCaps( HidP_Input
, value_caps
, &count
, preparsed_data
);
1541 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetValueCaps returned %#x\n", status
);
1542 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetValueCaps returned count %d, expected %d\n",
1543 count
, caps
.NumberInputValueCaps
);
1545 for (i
= 0; i
< ARRAY_SIZE(expect_value_caps
); ++i
)
1547 winetest_push_context( "value_caps[%d]", i
);
1548 check_hidp_value_caps( &value_caps
[i
], &expect_value_caps
[i
] );
1549 winetest_pop_context();
1552 count
= ARRAY_SIZE(value_caps
) - 4;
1553 status
= HidP_GetSpecificValueCaps( HidP_Output
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1554 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1555 status
= HidP_GetSpecificValueCaps( HidP_Feature
+ 1, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1556 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1558 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
, &count
, preparsed_data
);
1559 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1560 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1561 count
, caps
.NumberInputValueCaps
);
1562 count
= ARRAY_SIZE(value_caps
) - 4;
1563 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, (PHIDP_PREPARSED_DATA
)buffer
);
1564 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1566 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0, value_caps
+ 4, &count
, preparsed_data
);
1567 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1568 ok( count
== caps
.NumberInputValueCaps
, "HidP_GetSpecificValueCaps returned count %d, expected %d\n",
1569 count
, caps
.NumberInputValueCaps
);
1570 check_hidp_value_caps( &value_caps
[4], &value_caps
[0] );
1571 check_hidp_value_caps( &value_caps
[5], &value_caps
[1] );
1572 check_hidp_value_caps( &value_caps
[6], &value_caps
[2] );
1573 check_hidp_value_caps( &value_caps
[7], &value_caps
[3] );
1576 status
= HidP_GetSpecificValueCaps( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1577 value_caps
+ 4, &count
, preparsed_data
);
1578 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1579 ok( count
== 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 1 );
1580 check_hidp_value_caps( &value_caps
[4], &value_caps
[3] );
1583 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0xfffe, 0, 0, value_caps
, &count
, preparsed_data
);
1584 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1585 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1587 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0xfffe, 0, value_caps
, &count
, preparsed_data
);
1588 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1589 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1591 status
= HidP_GetSpecificValueCaps( HidP_Input
, 0, 0, 0xfffe, value_caps
, &count
, preparsed_data
);
1592 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetSpecificValueCaps returned %#x\n", status
);
1593 ok( count
== 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count
, 0 );
1595 status
= HidP_InitializeReportForID( HidP_Input
, 0, (PHIDP_PREPARSED_DATA
)buffer
, report
, sizeof(report
) );
1596 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_InitializeReportForID returned %#x\n", status
);
1597 status
= HidP_InitializeReportForID( HidP_Feature
+ 1, 0, preparsed_data
, report
, sizeof(report
) );
1598 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_InitializeReportForID returned %#x\n", status
);
1599 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, sizeof(report
) );
1600 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
1601 status
= HidP_InitializeReportForID( HidP_Input
, 0, preparsed_data
, report
, caps
.InputReportByteLength
+ 1 );
1602 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_InitializeReportForID returned %#x\n", status
);
1603 status
= HidP_InitializeReportForID( HidP_Input
, 1 - report_id
, preparsed_data
, report
,
1604 caps
.InputReportByteLength
);
1605 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1607 memset( report
, 0xcd, sizeof(report
) );
1608 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
1609 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1611 memset( buffer
, 0xcd, sizeof(buffer
) );
1612 memset( buffer
, 0, caps
.InputReportByteLength
);
1613 buffer
[0] = report_id
;
1614 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1616 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1617 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1618 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_SetUsageValueArray returned %#x\n", status
);
1619 memset( buffer
, 0xcd, sizeof(buffer
) );
1620 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1621 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1622 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
1623 status
= HidP_SetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1624 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1626 ok( status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_SetUsageValueArray returned %#x\n", status
);
1628 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, buffer
,
1629 sizeof(buffer
), preparsed_data
, report
, caps
.InputReportByteLength
);
1630 ok( status
== HIDP_STATUS_NOT_VALUE_ARRAY
, "HidP_GetUsageValueArray returned %#x\n", status
);
1631 memset( buffer
, 0xcd, sizeof(buffer
) );
1632 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1633 buffer
, 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1634 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
1635 status
= HidP_GetUsageValueArray( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_HATSWITCH
,
1636 buffer
, 8, preparsed_data
, report
, caps
.InputReportByteLength
);
1638 ok( status
== HIDP_STATUS_NOT_IMPLEMENTED
, "HidP_GetUsageValueArray returned %#x\n", status
);
1641 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1642 preparsed_data
, report
, caps
.InputReportByteLength
);
1643 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1645 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, &value
,
1646 preparsed_data
, report
, caps
.InputReportByteLength
);
1647 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
1648 ok( value
== 0x80, "got value %x, expected %#x\n", value
, 0x80 );
1650 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1651 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1652 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1653 ok( value
== -128, "got value %x, expected %#x\n", value
, -128 );
1656 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1657 preparsed_data
, report
, caps
.InputReportByteLength
);
1658 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1660 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1661 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1662 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1663 ok( value
== 127, "got value %x, expected %#x\n", value
, 127 );
1666 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
, value
,
1667 preparsed_data
, report
, caps
.InputReportByteLength
);
1668 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1670 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_X
,
1671 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1672 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1673 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1676 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1677 preparsed_data
, report
, caps
.InputReportByteLength
);
1678 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1680 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1681 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1682 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1683 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1685 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, &value
,
1686 preparsed_data
, report
, caps
.InputReportByteLength
);
1687 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
1688 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
1691 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1692 preparsed_data
, report
, caps
.InputReportByteLength
);
1693 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1695 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1696 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1697 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1698 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
1701 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
, value
,
1702 preparsed_data
, report
, caps
.InputReportByteLength
);
1703 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1705 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
1706 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1707 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1708 ok( value
== 0x80000000, "got value %x, expected %#x\n", value
, 0x80000000 );
1711 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
, value
,
1712 preparsed_data
, report
, caps
.InputReportByteLength
);
1713 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1715 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RX
,
1716 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1717 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1718 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1721 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
, value
,
1722 preparsed_data
, report
, caps
.InputReportByteLength
);
1723 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1725 status
= HidP_GetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1726 (LONG
*)&value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1727 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1728 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1729 status
= HidP_SetScaledUsageValue( HidP_Input
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_RY
,
1730 0, preparsed_data
, report
, caps
.InputReportByteLength
);
1731 ok( status
== HIDP_STATUS_BAD_LOG_PHY_VALUES
, "HidP_GetScaledUsageValue returned %#x\n", status
);
1732 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
1734 value
= HidP_MaxUsageListLength( HidP_Feature
+ 1, 0, preparsed_data
);
1735 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value
, 0 );
1736 value
= HidP_MaxUsageListLength( HidP_Input
, 0, preparsed_data
);
1737 ok( value
== 50, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value
, 50 );
1738 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1739 ok( value
== 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n",
1741 value
= HidP_MaxUsageListLength( HidP_Input
, HID_USAGE_PAGE_LED
, preparsed_data
);
1742 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n",
1744 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_BUTTON
, preparsed_data
);
1745 ok( value
== 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n",
1747 value
= HidP_MaxUsageListLength( HidP_Feature
, HID_USAGE_PAGE_LED
, preparsed_data
);
1748 ok( value
== 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n",
1753 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1754 report
, caps
.InputReportByteLength
);
1755 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
1759 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1760 report
, caps
.InputReportByteLength
);
1761 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsages returned %#x\n", status
);
1765 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1766 report
, caps
.InputReportByteLength
);
1767 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1771 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
1772 report
, caps
.InputReportByteLength
);
1773 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1775 value
= ARRAY_SIZE(usages
);
1776 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1777 report
, caps
.InputReportByteLength
);
1778 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1779 ok( value
== 0, "got usage count %d, expected %d\n", value
, 2 );
1785 ok( report
[6] == 0, "got report[6] %x expected 0\n", report
[6] );
1786 ok( report
[7] == 0, "got report[7] %x expected 0\n", report
[7] );
1787 memcpy( buffer
, report
, caps
.InputReportByteLength
);
1788 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1789 report
, caps
.InputReportByteLength
);
1790 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsages returned %#x\n", status
);
1793 ok( !memcmp( buffer
, report
, caps
.InputReportByteLength
), "unexpected report data\n" );
1795 status
= HidP_SetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, 1, preparsed_data
, report
,
1796 caps
.InputReportByteLength
);
1797 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1800 status
= HidP_GetUsageValue( HidP_Input
, HID_USAGE_PAGE_LED
, 0, 6, &value
, preparsed_data
,
1801 report
, caps
.InputReportByteLength
);
1802 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1803 ok( value
== 0xdeadbeef, "got value %x, expected %#x\n", value
, 0xdeadbeef );
1806 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1807 report
, caps
.InputReportByteLength
);
1808 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsages returned %#x\n", status
);
1809 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1810 value
= ARRAY_SIZE(usages
);
1811 memset( usages
, 0xcd, sizeof(usages
) );
1812 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_BUTTON
, 0, usages
, &value
, preparsed_data
,
1813 report
, caps
.InputReportByteLength
);
1814 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1815 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1816 ok( usages
[0] == 4, "got usages[0] %x, expected %x\n", usages
[0], 4 );
1817 ok( usages
[1] == 6, "got usages[1] %x, expected %x\n", usages
[1], 6 );
1819 value
= ARRAY_SIZE(usages
);
1820 memset( usages
, 0xcd, sizeof(usages
) );
1821 status
= HidP_GetUsages( HidP_Input
, HID_USAGE_PAGE_LED
, 0, usages
, &value
, preparsed_data
,
1822 report
, caps
.InputReportByteLength
);
1823 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsages returned %#x\n", status
);
1824 ok( value
== 2, "got usage count %d, expected %d\n", value
, 2 );
1825 ok( usages
[0] == 6, "got usages[0] %x, expected %x\n", usages
[0], 6 );
1826 ok( usages
[1] == 4, "got usages[1] %x, expected %x\n", usages
[1], 4 );
1828 value
= ARRAY_SIZE(usage_and_pages
);
1829 memset( usage_and_pages
, 0xcd, sizeof(usage_and_pages
) );
1830 status
= HidP_GetUsagesEx( HidP_Input
, 0, usage_and_pages
, &value
, preparsed_data
, report
,
1831 caps
.InputReportByteLength
);
1832 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsagesEx returned %#x\n", status
);
1833 ok( value
== 6, "got usage count %d, expected %d\n", value
, 4 );
1834 ok( usage_and_pages
[0].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[0] UsagePage %x, expected %x\n",
1835 usage_and_pages
[0].UsagePage
, HID_USAGE_PAGE_BUTTON
);
1836 ok( usage_and_pages
[1].UsagePage
== HID_USAGE_PAGE_BUTTON
, "got usage_and_pages[1] UsagePage %x, expected %x\n",
1837 usage_and_pages
[1].UsagePage
, HID_USAGE_PAGE_BUTTON
);
1838 ok( usage_and_pages
[2].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[2] UsagePage %x, expected %x\n",
1839 usage_and_pages
[2].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
1840 ok( usage_and_pages
[3].UsagePage
== HID_USAGE_PAGE_KEYBOARD
, "got usage_and_pages[3] UsagePage %x, expected %x\n",
1841 usage_and_pages
[3].UsagePage
, HID_USAGE_PAGE_KEYBOARD
);
1842 ok( usage_and_pages
[4].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[4] UsagePage %x, expected %x\n",
1843 usage_and_pages
[4].UsagePage
, HID_USAGE_PAGE_LED
);
1844 ok( usage_and_pages
[5].UsagePage
== HID_USAGE_PAGE_LED
, "got usage_and_pages[5] UsagePage %x, expected %x\n",
1845 usage_and_pages
[5].UsagePage
, HID_USAGE_PAGE_LED
);
1846 ok( usage_and_pages
[0].Usage
== 4, "got usage_and_pages[0] Usage %x, expected %x\n",
1847 usage_and_pages
[0].Usage
, 4 );
1848 ok( usage_and_pages
[1].Usage
== 6, "got usage_and_pages[1] Usage %x, expected %x\n",
1849 usage_and_pages
[1].Usage
, 6 );
1850 ok( usage_and_pages
[2].Usage
== 9, "got usage_and_pages[2] Usage %x, expected %x\n",
1851 usage_and_pages
[2].Usage
, 9 );
1852 ok( usage_and_pages
[3].Usage
== 11, "got usage_and_pages[3] Usage %x, expected %x\n",
1853 usage_and_pages
[3].Usage
, 11 );
1854 ok( usage_and_pages
[4].Usage
== 6, "got usage_and_pages[4] Usage %x, expected %x\n",
1855 usage_and_pages
[4].Usage
, 6 );
1856 ok( usage_and_pages
[5].Usage
== 4, "got usage_and_pages[5] Usage %x, expected %x\n",
1857 usage_and_pages
[5].Usage
, 4 );
1859 value
= HidP_MaxDataListLength( HidP_Feature
+ 1, preparsed_data
);
1860 ok( value
== 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value
, 0 );
1861 value
= HidP_MaxDataListLength( HidP_Input
, preparsed_data
);
1862 ok( value
== 58, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value
, 58 );
1863 value
= HidP_MaxDataListLength( HidP_Output
, preparsed_data
);
1864 ok( value
== 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value
, 0 );
1865 value
= HidP_MaxDataListLength( HidP_Feature
, preparsed_data
);
1866 ok( value
== 14, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value
, 14 );
1869 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1870 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetData returned %#x\n", status
);
1871 ok( value
== 11, "got data count %d, expected %d\n", value
, 11 );
1872 memset( data
, 0, sizeof(data
) );
1873 status
= HidP_GetData( HidP_Input
, data
, &value
, preparsed_data
, report
, caps
.InputReportByteLength
);
1874 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetData returned %#x\n", status
);
1875 for (i
= 0; i
< ARRAY_SIZE(expect_data
); ++i
)
1877 winetest_push_context( "data[%d]", i
);
1878 check_member( data
[i
], expect_data
[i
], "%d", DataIndex
);
1879 check_member( data
[i
], expect_data
[i
], "%d", RawValue
);
1880 winetest_pop_context();
1883 /* HID nary usage collections are set with 1-based usage index in their declaration order */
1885 memset( report
, 0, caps
.InputReportByteLength
);
1886 status
= HidP_InitializeReportForID( HidP_Input
, report_id
, preparsed_data
, report
, caps
.InputReportByteLength
);
1887 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1891 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1892 report
, caps
.InputReportByteLength
);
1893 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1894 ok( report
[caps
.InputReportByteLength
- 2] == 3, "unexpected usage index %d, expected 3\n",
1895 report
[caps
.InputReportByteLength
- 2] );
1896 ok( report
[caps
.InputReportByteLength
- 1] == 4, "unexpected usage index %d, expected 4\n",
1897 report
[caps
.InputReportByteLength
- 1] );
1898 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
1899 preparsed_data
, report
, caps
.InputReportByteLength
);
1900 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_UnsetUsages returned %#x\n", status
);
1901 ok( report
[caps
.InputReportByteLength
- 2] == 0, "unexpected usage index %d, expected 0\n",
1902 report
[caps
.InputReportByteLength
- 2] );
1903 ok( report
[caps
.InputReportByteLength
- 1] == 0, "unexpected usage index %d, expected 0\n",
1904 report
[caps
.InputReportByteLength
- 1] );
1905 status
= HidP_UnsetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
,
1906 preparsed_data
, report
, caps
.InputReportByteLength
);
1907 ok( status
== HIDP_STATUS_BUTTON_NOT_PRESSED
, "HidP_UnsetUsages returned %#x\n", status
);
1910 status
= HidP_SetUsages( HidP_Input
, HID_USAGE_PAGE_KEYBOARD
, 0, usages
, &value
, preparsed_data
,
1911 report
, caps
.InputReportByteLength
);
1912 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsages returned %#x\n", status
);
1913 ok( report
[caps
.InputReportByteLength
- 2] == 1, "unexpected usage index %d, expected 1\n",
1914 report
[caps
.InputReportByteLength
- 2] );
1916 memset( report
, 0xcd, sizeof(report
) );
1917 status
= HidP_InitializeReportForID( HidP_Feature
, 3, preparsed_data
, report
, caps
.FeatureReportByteLength
);
1918 ok( status
== HIDP_STATUS_REPORT_DOES_NOT_EXIST
, "HidP_InitializeReportForID returned %#x\n", status
);
1920 memset( report
, 0xcd, sizeof(report
) );
1921 status
= HidP_InitializeReportForID( HidP_Feature
, report_id
, preparsed_data
, report
,
1922 caps
.FeatureReportByteLength
);
1923 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_InitializeReportForID returned %#x\n", status
);
1925 memset( buffer
, 0xcd, sizeof(buffer
) );
1926 memset( buffer
, 0, caps
.FeatureReportByteLength
);
1927 buffer
[0] = report_id
;
1928 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1930 for (i
= 0; i
< caps
.NumberLinkCollectionNodes
; ++i
)
1932 if (collections
[i
].LinkUsagePage
!= HID_USAGE_PAGE_HAPTICS
) continue;
1933 if (collections
[i
].LinkUsage
== HID_USAGE_HAPTICS_WAVEFORM_LIST
) break;
1935 ok( i
< caps
.NumberLinkCollectionNodes
,
1936 "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n" );
1939 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1940 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, (PHIDP_PREPARSED_DATA
)buffer
,
1941 report
, caps
.FeatureReportByteLength
);
1942 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_SetUsageValue returned %#x\n", status
);
1943 status
= HidP_SetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1944 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1945 caps
.FeatureReportByteLength
);
1946 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_SetUsageValue returned %#x\n", status
);
1947 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1948 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1949 caps
.FeatureReportByteLength
+ 1 );
1950 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_SetUsageValue returned %#x\n", status
);
1951 report
[0] = 1 - report_id
;
1952 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1953 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1954 caps
.FeatureReportByteLength
);
1955 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
1956 "HidP_SetUsageValue returned %#x\n", status
);
1958 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1959 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1960 caps
.FeatureReportByteLength
);
1961 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_SetUsageValue returned %#x\n", status
);
1962 report
[0] = report_id
;
1963 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
,
1964 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1965 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_SetUsageValue returned %#x\n", status
);
1967 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3,
1968 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, preparsed_data
, report
,
1969 caps
.FeatureReportByteLength
);
1970 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
1972 memset( buffer
, 0xcd, sizeof(buffer
) );
1973 memset( buffer
, 0, caps
.FeatureReportByteLength
);
1974 buffer
[0] = report_id
;
1975 value
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
1976 memcpy( buffer
+ 1, &value
, 2 );
1977 ok( !memcmp( buffer
, report
, sizeof(buffer
) ), "unexpected report data\n" );
1979 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1980 (PHIDP_PREPARSED_DATA
)buffer
, report
, caps
.FeatureReportByteLength
);
1981 ok( status
== HIDP_STATUS_INVALID_PREPARSED_DATA
, "HidP_GetUsageValue returned %#x\n", status
);
1982 status
= HidP_GetUsageValue( HidP_Feature
+ 1, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1983 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1984 ok( status
== HIDP_STATUS_INVALID_REPORT_TYPE
, "HidP_GetUsageValue returned %#x\n", status
);
1985 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1986 preparsed_data
, report
, caps
.FeatureReportByteLength
+ 1 );
1987 ok( status
== HIDP_STATUS_INVALID_REPORT_LENGTH
, "HidP_GetUsageValue returned %#x\n", status
);
1988 report
[0] = 1 - report_id
;
1989 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1990 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1991 ok( status
== (report_id
? HIDP_STATUS_SUCCESS
: HIDP_STATUS_INCOMPATIBLE_REPORT_ID
),
1992 "HidP_GetUsageValue returned %#x\n", status
);
1994 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
1995 preparsed_data
, report
, caps
.FeatureReportByteLength
);
1996 ok( status
== HIDP_STATUS_INCOMPATIBLE_REPORT_ID
, "HidP_GetUsageValue returned %#x\n", status
);
1997 report
[0] = report_id
;
1998 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, 0xdead, 3, &value
,
1999 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2000 ok( status
== HIDP_STATUS_USAGE_NOT_FOUND
, "HidP_GetUsageValue returned %#x\n", status
);
2003 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_ORDINAL
, waveform_list
, 3, &value
,
2004 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2005 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2006 ok( value
== HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
, "got value %x, expected %#x\n", value
,
2007 HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
);
2009 memset( buffer
, 0xff, sizeof(buffer
) );
2010 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2011 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
2012 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2013 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_SetUsageValueArray returned %#x\n", status
);
2014 status
= HidP_SetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2015 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
2016 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2017 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValueArray returned %#x\n", status
);
2018 ok( !memcmp( report
+ 9, buffer
, 8 ), "unexpected report data\n" );
2020 memset( buffer
, 0, sizeof(buffer
) );
2021 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2022 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 0,
2023 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2024 ok( status
== HIDP_STATUS_BUFFER_TOO_SMALL
, "HidP_GetUsageValueArray returned %#x\n", status
);
2025 status
= HidP_GetUsageValueArray( HidP_Feature
, HID_USAGE_PAGE_HAPTICS
, 0,
2026 HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
, buffer
, 64,
2027 preparsed_data
, report
, caps
.FeatureReportByteLength
);
2028 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValueArray returned %#x\n", status
);
2029 memset( buffer
+ 16, 0xff, 8 );
2030 ok( !memcmp( buffer
, buffer
+ 16, 16 ), "unexpected report value\n" );
2033 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2034 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2035 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2037 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2038 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2039 ok( status
== HIDP_STATUS_VALUE_OUT_OF_RANGE
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2040 ok( value
== 0, "got value %x, expected %#x\n", value
, 0 );
2042 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2043 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2044 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2045 ok( value
== 0x7fffffff, "got value %x, expected %#x\n", value
, 0x7fffffff );
2048 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2049 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2050 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2052 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2053 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2054 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2055 ok( value
== 0x0003ffff, "got value %x, expected %#x\n", value
, 0x0003ffff );
2058 status
= HidP_SetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2059 value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2060 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetUsageValue returned %#x\n", status
);
2062 status
= HidP_GetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2063 (LONG
*)&value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2064 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetScaledUsageValue returned %#x\n", status
);
2065 ok( value
== 0xfff90000, "got value %x, expected %#x\n", value
, 0xfff90000 );
2066 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2067 0x1000, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2068 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2070 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2071 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2072 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2073 ok( value
== 0xfffff518, "got value %x, expected %#x\n", value
, 0xfffff518 );
2074 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2075 0, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2076 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2078 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2079 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2080 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2081 ok( value
== 0xfffff45e, "got value %x, expected %#x\n", value
, 0xfffff45e );
2082 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2083 0xdead, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2084 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2086 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2087 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2088 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2089 ok( value
== 0xfffffe7d, "got value %x, expected %#x\n", value
, 0xfffffe7d );
2090 status
= HidP_SetScaledUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2091 0xbeef, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2092 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_SetScaledUsageValue returned %#x\n", status
);
2094 status
= HidP_GetUsageValue( HidP_Feature
, HID_USAGE_PAGE_GENERIC
, 0, HID_USAGE_GENERIC_Z
,
2095 &value
, preparsed_data
, report
, caps
.FeatureReportByteLength
);
2096 ok( status
== HIDP_STATUS_SUCCESS
, "HidP_GetUsageValue returned %#x\n", status
);
2097 ok( value
== 0xfffffd0b, "got value %x, expected %#x\n", value
, 0xfffffd0b );
2099 test_hidp_get_input( file
, report_id
, caps
.InputReportByteLength
, preparsed_data
);
2100 test_hidp_get_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2101 test_hidp_set_feature( file
, report_id
, caps
.FeatureReportByteLength
, preparsed_data
);
2102 test_hidp_set_output( file
, report_id
, caps
.OutputReportByteLength
, preparsed_data
);
2103 test_write_file( file
, report_id
, caps
.OutputReportByteLength
);
2105 memset( report
, 0xcd, sizeof(report
) );
2106 SetLastError( 0xdeadbeef );
2107 ret
= ReadFile( file
, report
, 0, &value
, NULL
);
2108 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n",
2110 ok( value
== 0, "ReadFile returned %x\n", value
);
2111 SetLastError( 0xdeadbeef );
2112 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
- 1, &value
, NULL
);
2113 ok( !ret
&& GetLastError() == ERROR_INVALID_USER_BUFFER
, "ReadFile failed, last error %u\n",
2115 ok( value
== 0, "ReadFile returned %x\n", value
);
2119 struct hid_expect expect
[] =
2122 .code
= IOCTL_HID_READ_REPORT
,
2123 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2124 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0},
2126 .ret_status
= STATUS_SUCCESS
,
2129 .code
= IOCTL_HID_READ_REPORT
,
2130 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2131 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,1},
2133 .ret_status
= STATUS_SUCCESS
,
2137 send_hid_input( file
, expect
, sizeof(expect
) );
2139 memset( report
, 0xcd, sizeof(report
) );
2140 SetLastError( 0xdeadbeef );
2141 ret
= ReadFile( file
, report
, caps
.InputReportByteLength
, &value
, NULL
);
2142 ok( ret
, "ReadFile failed, last error %u\n", GetLastError() );
2143 ok( value
== (report_id
? 3 : 4), "ReadFile returned %x\n", value
);
2144 ok( report
[0] == report_id
, "unexpected report data\n" );
2146 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2147 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2149 /* drain available input reports */
2150 SetLastError( 0xdeadbeef );
2151 while (ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
))
2152 ResetEvent( overlapped
.hEvent
);
2153 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2154 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2155 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2156 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2157 value
, (report_id
? 3 : 4) );
2158 ResetEvent( overlapped
.hEvent
);
2160 memcpy( buffer
, report
, caps
.InputReportByteLength
);
2161 memcpy( buffer
+ caps
.InputReportByteLength
, report
, caps
.InputReportByteLength
);
2163 SetLastError( 0xdeadbeef );
2164 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2165 ok( !ret
, "ReadFile succeeded\n" );
2166 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2168 SetLastError( 0xdeadbeef );
2169 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2170 ok( !ret
, "ReadFile succeeded\n" );
2171 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2173 /* wait for second report to be ready */
2174 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2175 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2176 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2177 value
, (report_id
? 3 : 4) );
2178 /* first report should be ready and the same */
2179 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2180 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2181 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2182 value
, (report_id
? 3 : 4) );
2183 ok( memcmp( report
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
),
2184 "expected different report\n" );
2185 ok( !memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected identical reports\n" );
2188 SetLastError( 0xdeadbeef );
2189 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &value
, sizeof(ULONG
), NULL
, NULL
, INFINITE
);
2190 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2194 SetLastError( 0xdeadbeef );
2195 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2196 ok( !ret
, "ReadFile succeeded\n" );
2197 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2199 SetLastError( 0xdeadbeef );
2200 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2201 ok( !ret
, "ReadFile succeeded\n" );
2202 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2204 /* wait for second report to be ready */
2205 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2206 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2207 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2208 value
, (report_id
? 3 : 4) );
2209 /* first report should be ready and the same */
2210 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2211 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2212 ok( value
== (report_id
? 3 : 4), "GetOverlappedResult returned length %u, expected %u\n",
2213 value
, (report_id
? 3 : 4) );
2214 ok( !memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected identical reports\n" );
2216 CloseHandle( overlapped
.hEvent
);
2217 CloseHandle( overlapped2
.hEvent
);
2221 struct hid_expect expect
[] =
2224 .code
= IOCTL_HID_READ_REPORT
,
2225 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2226 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
2228 .ret_status
= STATUS_SUCCESS
,
2231 .code
= IOCTL_HID_READ_REPORT
,
2232 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2233 .report_buf
= {report_id
? report_id
: 0xa5,0xa5,0xa5,0xa5,0xa5},
2234 .ret_length
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2235 .ret_status
= STATUS_SUCCESS
,
2239 overlapped
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2240 overlapped2
.hEvent
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
2242 SetLastError( 0xdeadbeef );
2243 memset( report
, 0, sizeof(report
) );
2244 ret
= ReadFile( async_file
, report
, caps
.InputReportByteLength
, NULL
, &overlapped
);
2245 ok( !ret
, "ReadFile succeeded\n" );
2246 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2248 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, FALSE
);
2249 ok( !ret
, "GetOverlappedResult succeeded\n" );
2250 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2252 SetLastError( 0xdeadbeef );
2253 memset( buffer
, 0, sizeof(buffer
) );
2254 ret
= ReadFile( async_file
, buffer
, caps
.InputReportByteLength
, NULL
, &overlapped2
);
2255 ok( !ret
, "ReadFile succeeded\n" );
2256 ok( GetLastError() == ERROR_IO_PENDING
, "ReadFile returned error %u\n", GetLastError() );
2258 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2259 ok( !ret
, "GetOverlappedResult succeeded\n" );
2260 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2262 memset( report
+ caps
.InputReportByteLength
, 0xa5, 5 );
2263 if (report_id
) report
[caps
.InputReportByteLength
] = report_id
;
2265 send_hid_input( file
, expect
, sizeof(expect
) );
2267 /* first read should be completed */
2268 ret
= GetOverlappedResult( async_file
, &overlapped
, &value
, TRUE
);
2269 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2270 ok( value
== caps
.InputReportByteLength
, "got length %u, expected %u\n", value
, caps
.InputReportByteLength
);
2271 /* second read should still be pending */
2273 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, FALSE
);
2274 ok( !ret
, "GetOverlappedResult succeeded\n" );
2275 ok( GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult returned error %u\n", GetLastError() );
2277 memset( buffer
+ caps
.InputReportByteLength
, 0x3b, 5 );
2278 if (report_id
) buffer
[caps
.InputReportByteLength
] = report_id
;
2279 memset( expect
[1].report_buf
, 0x3b, 5 );
2280 if (report_id
) expect
[1].report_buf
[0] = report_id
;
2282 send_hid_input( file
, expect
, sizeof(expect
) );
2284 ret
= GetOverlappedResult( async_file
, &overlapped2
, &value
, TRUE
);
2285 ok( ret
, "GetOverlappedResult failed, last error %u\n", GetLastError() );
2286 ok( value
== caps
.InputReportByteLength
, "got length %u, expected %u\n", value
, caps
.InputReportByteLength
);
2288 off
= report_id
? 0 : 1;
2289 ok( memcmp( report
, buffer
, caps
.InputReportByteLength
), "expected different report\n" );
2290 ok( !memcmp( report
+ off
, report
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2291 "expected identical reports\n" );
2292 ok( !memcmp( buffer
+ off
, buffer
+ caps
.InputReportByteLength
, caps
.InputReportByteLength
- off
),
2293 "expected identical reports\n" );
2295 CloseHandle( overlapped
.hEvent
);
2296 CloseHandle( overlapped2
.hEvent
);
2299 HidD_FreePreparsedData( preparsed_data
);
2302 static void test_hid_device( DWORD report_id
, DWORD polled
, const HIDP_CAPS
*expect_caps
)
2304 char buffer
[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W
, DevicePath
[MAX_PATH
] )];
2305 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(SP_DEVICE_INTERFACE_DATA
)};
2306 SP_DEVICE_INTERFACE_DETAIL_DATA_W
*iface_detail
= (void *)buffer
;
2307 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
2308 ULONG count
, poll_freq
, out_len
;
2309 HANDLE file
, async_file
;
2310 BOOL ret
, found
= FALSE
;
2311 OBJECT_ATTRIBUTES attr
;
2312 UNICODE_STRING string
;
2318 winetest_push_context( "id %d%s", report_id
, polled
? " poll" : "" );
2320 set
= SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
2321 ok( set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError() );
2323 for (i
= 0; SetupDiEnumDeviceInfo( set
, i
, &device
); ++i
)
2325 ret
= SetupDiEnumDeviceInterfaces( set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
2326 ok( ret
, "failed to get interface, error %#x\n", GetLastError() );
2327 ok( IsEqualGUID( &iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
), "wrong class %s\n",
2328 debugstr_guid( &iface
.InterfaceClassGuid
) );
2329 ok( iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
2331 iface_detail
->cbSize
= sizeof(*iface_detail
);
2332 ret
= SetupDiGetDeviceInterfaceDetailW( set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
2333 ok( ret
, "failed to get interface path, error %#x\n", GetLastError() );
2335 if (wcsstr( iface_detail
->DevicePath
, L
"\\\\?\\hid#winetest#1" ))
2342 SetupDiDestroyDeviceInfoList( set
);
2345 ok( found
, "didn't find device\n" );
2347 file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2348 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
2349 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
2352 SetLastError( 0xdeadbeef );
2353 ret
= HidD_GetNumInputBuffers( file
, &count
);
2354 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2355 ok( count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2357 SetLastError( 0xdeadbeef );
2358 ret
= HidD_SetNumInputBuffers( file
, 1 );
2359 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2360 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n",
2362 SetLastError( 0xdeadbeef );
2363 ret
= HidD_SetNumInputBuffers( file
, 513 );
2364 ok( !ret
, "HidD_SetNumInputBuffers succeeded\n" );
2365 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "HidD_SetNumInputBuffers returned error %u\n",
2368 SetLastError( 0xdeadbeef );
2369 ret
= HidD_SetNumInputBuffers( file
, 16 );
2370 ok( ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError() );
2373 SetLastError( 0xdeadbeef );
2374 ret
= HidD_GetNumInputBuffers( file
, &count
);
2375 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2376 ok( count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2378 async_file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
2379 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
2380 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
2381 ok( async_file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
2384 SetLastError( 0xdeadbeef );
2385 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2386 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2387 ok( count
== 32, "HidD_GetNumInputBuffers returned %u\n", count
);
2389 SetLastError( 0xdeadbeef );
2390 ret
= HidD_SetNumInputBuffers( async_file
, 2 );
2391 ok( ret
, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError() );
2394 SetLastError( 0xdeadbeef );
2395 ret
= HidD_GetNumInputBuffers( async_file
, &count
);
2396 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2397 ok( count
== 2, "HidD_GetNumInputBuffers returned %u\n", count
);
2399 SetLastError( 0xdeadbeef );
2400 ret
= HidD_GetNumInputBuffers( file
, &count
);
2401 ok( ret
, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError() );
2402 ok( count
== 16, "HidD_GetNumInputBuffers returned %u\n", count
);
2406 out_len
= sizeof(ULONG
);
2407 SetLastError( 0xdeadbeef );
2408 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, INFINITE
);
2409 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2410 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2412 ok( poll_freq
== 5, "got poll_freq %u, expected 5\n", poll_freq
);
2416 SetLastError( 0xdeadbeef );
2417 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2418 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2419 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2423 SetLastError( 0xdeadbeef );
2424 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2425 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2426 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2430 SetLastError( 0xdeadbeef );
2431 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2432 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2433 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2435 out_len
= sizeof(ULONG
);
2436 SetLastError( 0xdeadbeef );
2437 ret
= sync_ioctl( file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, INFINITE
);
2438 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2439 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2440 ok( poll_freq
== 10000, "got poll_freq %u, expected 10000\n", poll_freq
);
2444 SetLastError( 0xdeadbeef );
2445 ret
= sync_ioctl( file
, IOCTL_HID_SET_POLL_FREQUENCY_MSEC
, &poll_freq
, sizeof(ULONG
), NULL
, &out_len
, INFINITE
);
2446 ok( ret
, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2447 ok( out_len
== 0, "got out_len %u, expected 0\n", out_len
);
2449 out_len
= sizeof(ULONG
);
2450 SetLastError( 0xdeadbeef );
2451 ret
= sync_ioctl( async_file
, IOCTL_HID_GET_POLL_FREQUENCY_MSEC
, NULL
, 0, &poll_freq
, &out_len
, INFINITE
);
2452 ok( ret
, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError() );
2453 ok( out_len
== sizeof(ULONG
), "got out_len %u, expected sizeof(ULONG)\n", out_len
);
2454 ok( poll_freq
== 500, "got poll_freq %u, expected 500\n", poll_freq
);
2457 test_hidp( file
, async_file
, report_id
, polled
, expect_caps
);
2459 CloseHandle( async_file
);
2460 CloseHandle( file
);
2462 RtlInitUnicodeString( &string
, L
"\\??\\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}" );
2463 InitializeObjectAttributes( &attr
, &string
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
2464 status
= NtOpenFile( &file
, SYNCHRONIZE
, &attr
, &io
, 0, FILE_SYNCHRONOUS_IO_NONALERT
);
2466 ok( status
== STATUS_UNSUCCESSFUL
, "got %#x\n", status
);
2468 winetest_pop_context();
2471 static void test_hid_driver( DWORD report_id
, DWORD polled
)
2473 #include "psh_hid_macros.h"
2474 /* Replace REPORT_ID with USAGE_PAGE when id is 0 */
2475 #define REPORT_ID_OR_USAGE_PAGE(size, id, off) SHORT_ITEM_1((id ? 8 : 0), 1, (id + off))
2476 const unsigned char report_desc
[] =
2478 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2479 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2480 COLLECTION(1, Application
),
2481 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2482 COLLECTION(1, Logical
),
2483 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2484 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2485 USAGE(1, HID_USAGE_GENERIC_X
),
2486 USAGE(1, HID_USAGE_GENERIC_Y
),
2487 LOGICAL_MINIMUM(1, -128),
2488 LOGICAL_MAXIMUM(1, 127),
2491 INPUT(1, Data
|Var
|Abs
),
2493 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2494 USAGE_MINIMUM(1, 1),
2495 USAGE_MAXIMUM(1, 8),
2496 LOGICAL_MINIMUM(1, 0),
2497 LOGICAL_MAXIMUM(1, 1),
2500 INPUT(1, Data
|Var
|Abs
),
2502 USAGE_MINIMUM(1, 0x18),
2503 USAGE_MAXIMUM(1, 0x1f),
2504 LOGICAL_MINIMUM(1, 0),
2505 LOGICAL_MAXIMUM(1, 1),
2508 INPUT(1, Cnst
|Var
|Abs
),
2510 INPUT(1, Cnst
|Var
|Abs
),
2511 /* needs to be 8 bit aligned as next has Buff */
2513 USAGE_MINIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8),
2514 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0xf),
2515 LOGICAL_MINIMUM(1, 0),
2516 LOGICAL_MAXIMUM(1, 8),
2519 INPUT(2, Data
|Ary
|Rel
|Wrap
|Lin
|Pref
|Null
|Vol
|Buff
),
2521 /* needs to be 8 bit aligned as previous has Buff */
2523 LOGICAL_MINIMUM(1, 0),
2524 LOGICAL_MAXIMUM(1, 1),
2527 INPUT(1, Data
|Var
|Abs
),
2528 USAGE_MINIMUM(1, 0x21),
2529 USAGE_MAXIMUM(1, 0x22),
2532 INPUT(1, Data
|Var
|Abs
),
2536 INPUT(1, Data
|Var
|Abs
),
2538 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2539 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
2540 LOGICAL_MINIMUM(1, 1),
2541 LOGICAL_MAXIMUM(1, 8),
2544 INPUT(1, Data
|Var
|Abs
),
2546 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2547 USAGE(1, HID_USAGE_GENERIC_Z
),
2548 LOGICAL_MINIMUM(4, 0x00000000),
2549 LOGICAL_MAXIMUM(4, 0x3fffffff),
2550 PHYSICAL_MINIMUM(4, 0x80000000),
2551 PHYSICAL_MAXIMUM(4, 0x7fffffff),
2554 INPUT(1, Data
|Var
|Abs
),
2556 /* reset physical range to its default interpretation */
2557 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2558 USAGE(1, HID_USAGE_GENERIC_RX
),
2559 PHYSICAL_MINIMUM(4, 0),
2560 PHYSICAL_MAXIMUM(4, 0),
2563 INPUT(1, Data
|Var
|Abs
),
2565 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2566 USAGE(1, HID_USAGE_GENERIC_RY
),
2567 LOGICAL_MINIMUM(4, 0x7fff),
2568 LOGICAL_MAXIMUM(4, 0x0000),
2569 PHYSICAL_MINIMUM(4, 0x0000),
2570 PHYSICAL_MAXIMUM(4, 0x7fff),
2573 INPUT(1, Data
|Var
|Abs
),
2576 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2577 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2578 COLLECTION(1, Report
),
2579 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2580 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2581 USAGE_MINIMUM(1, 9),
2582 USAGE_MAXIMUM(1, 10),
2583 LOGICAL_MINIMUM(1, 0),
2584 LOGICAL_MAXIMUM(1, 1),
2587 INPUT(1, Data
|Var
|Abs
),
2590 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2591 USAGE(1, HID_USAGE_LED_GREEN
),
2592 COLLECTION(1, Report
),
2593 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2594 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2603 LOGICAL_MINIMUM(1, 0),
2604 LOGICAL_MAXIMUM(1, 1),
2605 PHYSICAL_MINIMUM(1, 0),
2606 PHYSICAL_MAXIMUM(1, 1),
2609 INPUT(1, Data
|Var
|Abs
),
2611 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8c),
2612 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8d),
2613 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8e),
2614 USAGE(4, (HID_USAGE_PAGE_KEYBOARD
<<16)|0x8f),
2615 LOGICAL_MINIMUM(1, 1),
2616 LOGICAL_MAXIMUM(1, 16),
2619 INPUT(1, Data
|Ary
|Abs
),
2622 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2623 USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER
),
2624 COLLECTION(1, Logical
),
2625 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2626 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2628 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST
),
2629 COLLECTION(1, NamedArray
),
2630 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2631 USAGE(1, 3), /* HID_USAGE_HAPTICS_WAVEFORM_RUMBLE */
2632 USAGE(1, 4), /* HID_USAGE_HAPTICS_WAVEFORM_BUZZ */
2633 LOGICAL_MINIMUM(2, 0x0000),
2634 LOGICAL_MAXIMUM(2, 0xffff),
2637 FEATURE(1, Data
|Var
|Abs
|Null
),
2640 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2641 USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST
),
2642 COLLECTION(1, NamedArray
),
2643 USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL
),
2644 USAGE(1, 3), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) */
2645 USAGE(1, 4), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_BUZZ) */
2646 LOGICAL_MINIMUM(2, 0x0000),
2647 LOGICAL_MAXIMUM(2, 0xffff),
2650 FEATURE(1, Data
|Var
|Abs
|Null
),
2653 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
2654 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
),
2655 UNIT(2, 0x1001), /* seconds */
2656 UNIT_EXPONENT(1, -3), /* 10^-3 */
2657 LOGICAL_MINIMUM(2, 0x8000),
2658 LOGICAL_MAXIMUM(2, 0x7fff),
2659 PHYSICAL_MINIMUM(4, 0x00000000),
2660 PHYSICAL_MAXIMUM(4, 0xffffffff),
2663 FEATURE(1, Data
|Var
|Abs
),
2664 /* reset global items */
2665 UNIT(1, 0), /* None */
2666 UNIT_EXPONENT(1, 0),
2668 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2669 USAGE(1, HID_USAGE_GENERIC_Z
),
2670 LOGICAL_MINIMUM(4, 0x0000),
2671 LOGICAL_MAXIMUM(4, 0x7fff),
2672 PHYSICAL_MINIMUM(4, 0xfff90000),
2673 PHYSICAL_MAXIMUM(4, 0x0003ffff),
2676 FEATURE(1, Data
|Var
|Abs
),
2679 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2680 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2681 COLLECTION(1, Report
),
2682 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2683 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
2684 USAGE_MINIMUM(1, 9),
2685 USAGE_MAXIMUM(1, 10),
2686 LOGICAL_MINIMUM(1, 0),
2687 LOGICAL_MAXIMUM(1, 1),
2688 PHYSICAL_MINIMUM(1, 0),
2689 PHYSICAL_MAXIMUM(1, 1),
2692 FEATURE(1, Data
|Var
|Abs
),
2695 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2696 USAGE(1, HID_USAGE_LED_GREEN
),
2697 COLLECTION(1, Report
),
2698 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 0),
2699 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2702 OUTPUT(1, Cnst
|Var
|Abs
),
2705 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2706 USAGE(1, HID_USAGE_LED_RED
),
2707 COLLECTION(1, Report
),
2708 REPORT_ID_OR_USAGE_PAGE(1, report_id
, 1),
2709 USAGE_PAGE(1, HID_USAGE_PAGE_LED
),
2712 OUTPUT(1, Cnst
|Var
|Abs
),
2716 #undef REPORT_ID_OR_USAGE_PAGE
2717 #include "pop_hid_macros.h"
2719 static const HID_DEVICE_ATTRIBUTES attributes
=
2721 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
2723 .ProductID
= 0x0001,
2724 .VersionNumber
= 0x0100,
2726 const HIDP_CAPS caps
=
2728 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
2729 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
2730 .InputReportByteLength
= report_id
? 32 : 33,
2731 .OutputReportByteLength
= report_id
? 2 : 3,
2732 .FeatureReportByteLength
= report_id
? 21 : 22,
2733 .NumberLinkCollectionNodes
= 10,
2734 .NumberInputButtonCaps
= 17,
2735 .NumberInputValueCaps
= 7,
2736 .NumberInputDataIndices
= 47,
2737 .NumberFeatureButtonCaps
= 1,
2738 .NumberFeatureValueCaps
= 6,
2739 .NumberFeatureDataIndices
= 8,
2741 const struct hid_expect expect_in
=
2743 .code
= IOCTL_HID_READ_REPORT
,
2744 .report_len
= caps
.InputReportByteLength
- (report_id
? 0 : 1),
2745 .report_buf
= {report_id
? report_id
: 0x5a,0x5a,0x5a},
2747 .ret_status
= STATUS_SUCCESS
,
2750 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
2755 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
2756 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
2757 SetCurrentDirectoryW( tempdir
);
2759 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
2760 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
2761 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
2763 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
2764 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2766 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
2767 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2769 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)report_desc
, sizeof(report_desc
) );
2770 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2772 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
2773 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2775 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)&caps
, sizeof(caps
) );
2776 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2778 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, NULL
, 0 );
2779 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2781 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, (void *)&expect_in
, polled
? sizeof(expect_in
) : 0 );
2782 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2784 fill_context( __LINE__
, context
, ARRAY_SIZE(context
) );
2785 status
= RegSetValueExW( hkey
, L
"Context", 0, REG_BINARY
, (void *)context
, sizeof(context
) );
2786 ok( !status
, "RegSetValueExW returned %#x\n", status
);
2788 if (pnp_driver_start( L
"driver_hid.dll" )) test_hid_device( report_id
, polled
, &caps
);
2791 SetCurrentDirectoryW( cwd
);
2794 /* undocumented HID internal preparsed data structure */
2796 struct hidp_kdr_caps
2802 USHORT report_count
;
2807 USHORT link_collection
;
2808 USAGE link_usage_page
;
2816 USHORT designator_min
;
2817 USHORT designator_max
;
2818 USHORT data_index_min
;
2819 USHORT data_index_max
;
2830 /* named array continues on next caps */
2831 #define HIDP_KDR_CAPS_ARRAY_HAS_MORE 0x01
2832 #define HIDP_KDR_CAPS_IS_CONSTANT 0x02
2833 #define HIDP_KDR_CAPS_IS_BUTTON 0x04
2834 #define HIDP_KDR_CAPS_IS_ABSOLUTE 0x08
2835 #define HIDP_KDR_CAPS_IS_RANGE 0x10
2836 #define HIDP_KDR_CAPS_IS_STRING_RANGE 0x40
2837 #define HIDP_KDR_CAPS_IS_DESIGNATOR_RANGE 0x80
2839 struct hidp_kdr_node
2844 USHORT number_of_children
;
2845 USHORT next_sibling
;
2847 ULONG collection_type
;
2856 USHORT input_caps_start
;
2857 USHORT input_caps_count
;
2858 USHORT input_caps_end
;
2859 USHORT input_report_byte_length
;
2860 USHORT output_caps_start
;
2861 USHORT output_caps_count
;
2862 USHORT output_caps_end
;
2863 USHORT output_report_byte_length
;
2864 USHORT feature_caps_start
;
2865 USHORT feature_caps_count
;
2866 USHORT feature_caps_end
;
2867 USHORT feature_report_byte_length
;
2869 USHORT number_link_collection_nodes
;
2870 struct hidp_kdr_caps caps
[1];
2871 /* struct hidp_kdr_node nodes[1] */
2874 static void test_hidp_kdr(void)
2876 #include "psh_hid_macros.h"
2877 const unsigned char report_desc
[] =
2879 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2880 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
2881 COLLECTION(1, Application
),
2882 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
2883 LOGICAL_MINIMUM(1, 1),
2884 LOGICAL_MAXIMUM(1, 127),
2885 PHYSICAL_MINIMUM(1, -128),
2886 PHYSICAL_MAXIMUM(1, 127),
2888 USAGE(1, HID_USAGE_GENERIC_RZ
),
2891 FEATURE(1, Data
|Var
|Abs
),
2892 USAGE(1, HID_USAGE_GENERIC_SLIDER
),
2895 FEATURE(1, Data
|Var
|Abs
),
2897 USAGE(1, HID_USAGE_GENERIC_X
),
2901 UNIT_EXPONENT(1, -3),
2902 INPUT(1, Data
|Var
|Abs
),
2903 UNIT_EXPONENT(1, 0),
2905 USAGE(1, HID_USAGE_GENERIC_Y
),
2906 DESIGNATOR_MINIMUM(1, 1),
2907 DESIGNATOR_MAXIMUM(1, 4),
2910 INPUT(1, Cnst
|Var
|Abs
),
2911 USAGE(1, HID_USAGE_GENERIC_Z
),
2914 INPUT(1, Data
|Var
|Rel
),
2915 USAGE(1, HID_USAGE_GENERIC_RX
),
2916 USAGE(1, HID_USAGE_GENERIC_RY
),
2919 LOGICAL_MINIMUM(1, 7),
2920 INPUT(1, Data
|Var
|Abs
|Null
),
2922 COLLECTION(1, Application
),
2923 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|1),
2924 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|2),
2927 LOGICAL_MINIMUM(1, 0),
2928 LOGICAL_MAXIMUM(1, 1),
2929 INPUT(1, Data
|Var
|Abs
),
2931 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|3),
2932 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|8),
2935 LOGICAL_MINIMUM(1, 3),
2936 LOGICAL_MAXIMUM(1, 8),
2937 INPUT(1, Data
|Ary
|Abs
),
2939 USAGE_MINIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|9),
2940 USAGE_MAXIMUM(4, (HID_USAGE_PAGE_BUTTON
<< 16)|12),
2943 LOGICAL_MINIMUM(1, 9),
2944 LOGICAL_MAXIMUM(1, 12),
2945 INPUT(2, Data
|Ary
|Abs
|Buff
),
2947 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|13),
2948 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|14),
2949 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|15),
2950 USAGE(4, (HID_USAGE_PAGE_BUTTON
<< 16)|16),
2953 LOGICAL_MINIMUM(1, 13),
2954 LOGICAL_MAXIMUM(1, 16),
2955 INPUT(1, Data
|Ary
|Abs
),
2959 #include "pop_hid_macros.h"
2961 static const HIDP_CAPS expect_hidp_caps
=
2963 .Usage
= HID_USAGE_GENERIC_JOYSTICK
,
2964 .UsagePage
= HID_USAGE_PAGE_GENERIC
,
2965 .InputReportByteLength
= 15,
2967 static const HID_DEVICE_ATTRIBUTES attributes
=
2969 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
2971 .ProductID
= 0x0001,
2972 .VersionNumber
= 0x0100,
2974 static const struct hidp_kdr expect_kdr
=
2976 .magic
= "HidP KDR",
2979 .input_caps_count
= 13,
2980 .input_caps_end
= 13,
2981 .input_report_byte_length
= 15,
2982 .output_caps_start
= 13,
2983 .output_caps_end
= 13,
2984 .feature_caps_start
= 13,
2985 .feature_caps_count
= 2,
2986 .feature_caps_end
= 14,
2987 .feature_report_byte_length
= 3,
2989 .number_link_collection_nodes
= 2,
2991 static const struct hidp_kdr_caps expect_caps
[] =
2994 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x08,
2995 .bit_field
= 0x002, .end_byte
= 0x2, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
2996 .usage_min
= 0x30, .usage_max
= 0x30, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
2997 .physical_max
= 127, .units
= 0xe, .units_exp
= -3
3000 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x2, .total_bits
= 0x08,
3001 .bit_field
= 0x003, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x8a,
3002 .usage_min
= 0x31, .usage_max
= 0x31, .designator_min
= 1, .designator_max
= 4, .data_index_min
= 0x01,
3003 .data_index_max
= 0x01, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3006 .usage_page
= 0x01, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x3, .total_bits
= 0x08,
3007 .bit_field
= 0x006, .end_byte
= 0x4, .link_usage_page
= 0x01, .link_usage
= 0x04, .usage_min
= 0x32,
3008 .usage_max
= 0x32, .data_index_min
= 0x02, .data_index_max
= 0x02, .logical_min
= 1, .logical_max
= 127,
3009 .physical_min
= -128, .physical_max
= 127
3012 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x6, .total_bits
= 0x10,
3013 .bit_field
= 0x042, .end_byte
= 0x8, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3014 .usage_min
= 0x34, .usage_max
= 0x34, .data_index_min
= 0x03, .data_index_max
= 0x03, .null_value
= 1,
3015 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3018 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x4, .total_bits
= 0x10,
3019 .bit_field
= 0x042, .end_byte
= 0x6, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3020 .usage_min
= 0x33, .usage_max
= 0x33, .data_index_min
= 0x04, .data_index_max
= 0x04, .null_value
= 1,
3021 .logical_min
= 7, .logical_max
= 127, .physical_min
= -128, .physical_max
= 127
3024 .usage_page
= 0x09, .start_bit
= 1, .bit_size
= 0x01, .report_count
= 0x7, .start_byte
= 0x8, .total_bits
= 0x07,
3025 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3026 .usage_min
= 0x02, .usage_max
= 0x02, .data_index_min
= 0x05, .data_index_max
= 0x05,
3029 .usage_page
= 0x09, .bit_size
= 0x01, .report_count
= 0x1, .start_byte
= 0x8, .total_bits
= 0x01,
3030 .bit_field
= 0x002, .end_byte
= 0x9, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3031 .usage_min
= 0x01, .usage_max
= 0x01, .data_index_min
= 0x06, .data_index_max
= 0x06,
3034 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0x9, .total_bits
= 0x08,
3035 .bit_field
= 0x000, .end_byte
= 0xa, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
3036 .usage_min
= 0x03, .usage_max
= 0x08, .data_index_min
= 0x07, .data_index_max
= 0x0c, .null_value
= 3,
3040 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x4, .start_byte
= 0xa, .total_bits
= 0x20,
3041 .bit_field
= 0x100, .end_byte
= 0xe, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x1c,
3042 .usage_min
= 0x09, .usage_max
= 0x0c, .data_index_min
= 0x0d, .data_index_max
= 0x10, .null_value
= 9,
3046 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3047 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3048 .usage_min
= 0x10, .usage_max
= 0x10, .data_index_min
= 0x14, .data_index_max
= 0x14, .null_value
= 13,
3052 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3053 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3054 .usage_min
= 0x0f, .usage_max
= 0x0f, .data_index_min
= 0x13, .data_index_max
= 0x13, .null_value
= 13,
3058 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3059 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0d,
3060 .usage_min
= 0x0e, .usage_max
= 0x0e, .data_index_min
= 0x12, .data_index_max
= 0x12, .null_value
= 13,
3064 .usage_page
= 0x09, .bit_size
= 0x08, .report_count
= 0x1, .start_byte
= 0xe, .total_bits
= 0x08,
3065 .bit_field
= 0x000, .end_byte
= 0xf, .link_collection
= 1, .link_usage_page
= 0x01, .flags
= 0x0c,
3066 .usage_min
= 0x0d, .usage_max
= 0x0d, .data_index_min
= 0x11, .data_index_max
= 0x11, .null_value
= 13,
3070 .usage_page
= 0x01, .bit_size
= 0x10, .report_count
= 0x1, .start_byte
= 0x1, .total_bits
= 0x10,
3071 .bit_field
= 0x002, .end_byte
= 0x3, .link_usage_page
= 0x01, .link_usage
= 0x04, .flags
= 0x08,
3072 .usage_min
= 0x36, .usage_max
= 0x36, .logical_min
= 1, .logical_max
= 127, .physical_min
= -128,
3078 static const struct hidp_kdr_node expect_nodes
[] =
3084 .number_of_children
= 0x1,
3087 .collection_type
= 0x1,
3093 .number_of_children
= 0,
3096 .collection_type
= 0x1,
3100 char buffer
[FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W
, DevicePath
[MAX_PATH
] )];
3101 SP_DEVICE_INTERFACE_DATA iface
= {sizeof(SP_DEVICE_INTERFACE_DATA
)};
3102 SP_DEVICE_INTERFACE_DETAIL_DATA_W
*iface_detail
= (void *)buffer
;
3103 SP_DEVINFO_DATA device
= {sizeof(SP_DEVINFO_DATA
)};
3104 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
3105 PHIDP_PREPARSED_DATA preparsed_data
;
3106 DWORD i
, report_id
= 0, polled
= 0;
3107 struct hidp_kdr
*kdr
;
3115 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
3116 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
3117 SetCurrentDirectoryW( tempdir
);
3119 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
3120 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
3121 ok( !status
, "RegCreateKeyExW returned %#x\n", status
);
3123 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
3124 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3126 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
3127 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3129 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)report_desc
, sizeof(report_desc
) );
3130 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3132 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
3133 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3135 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)&expect_hidp_caps
, sizeof(expect_hidp_caps
) );
3136 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3138 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, NULL
, 0 );
3139 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3141 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, NULL
, 0 );
3142 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3144 fill_context( __LINE__
, context
, ARRAY_SIZE(context
) );
3145 status
= RegSetValueExW( hkey
, L
"Context", 0, REG_BINARY
, (void *)context
, sizeof(context
) );
3146 ok( !status
, "RegSetValueExW returned %#x\n", status
);
3148 if (!pnp_driver_start( L
"driver_hid.dll" )) goto done
;
3150 set
= SetupDiGetClassDevsW( &GUID_DEVINTERFACE_HID
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
3151 ok( set
!= INVALID_HANDLE_VALUE
, "failed to get device list, error %#x\n", GetLastError() );
3152 for (i
= 0; SetupDiEnumDeviceInfo( set
, i
, &device
); ++i
)
3154 ret
= SetupDiEnumDeviceInterfaces( set
, &device
, &GUID_DEVINTERFACE_HID
, 0, &iface
);
3155 ok( ret
, "failed to get interface, error %#x\n", GetLastError() );
3156 ok( IsEqualGUID( &iface
.InterfaceClassGuid
, &GUID_DEVINTERFACE_HID
), "wrong class %s\n",
3157 debugstr_guid( &iface
.InterfaceClassGuid
) );
3158 ok( iface
.Flags
== SPINT_ACTIVE
, "got flags %#x\n", iface
.Flags
);
3160 iface_detail
->cbSize
= sizeof(*iface_detail
);
3161 ret
= SetupDiGetDeviceInterfaceDetailW( set
, &iface
, iface_detail
, sizeof(buffer
), NULL
, NULL
);
3162 ok( ret
, "failed to get interface path, error %#x\n", GetLastError() );
3164 if (wcsstr( iface_detail
->DevicePath
, L
"\\\\?\\hid#winetest#1" )) break;
3166 SetupDiDestroyDeviceInfoList( set
);
3168 file
= CreateFileW( iface_detail
->DevicePath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
3169 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
3170 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
3172 ret
= HidD_GetPreparsedData( file
, &preparsed_data
);
3173 ok( ret
, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
3175 kdr
= (struct hidp_kdr
*)preparsed_data
;
3176 ok( !strncmp( kdr
->magic
, expect_kdr
.magic
, 8 ), "got %s expected %s\n",
3177 debugstr_an(kdr
->magic
, 8), debugstr_an(expect_kdr
.magic
, 8) );
3179 if (!strncmp( kdr
->magic
, expect_kdr
.magic
, 8 ))
3181 check_member( *kdr
, expect_kdr
, "%04x", usage
);
3182 check_member( *kdr
, expect_kdr
, "%04x", usage_page
);
3183 check_member( *kdr
, expect_kdr
, "%#x", unknown
[0] );
3184 check_member( *kdr
, expect_kdr
, "%#x", unknown
[1] );
3185 check_member( *kdr
, expect_kdr
, "%d", input_caps_start
);
3186 check_member( *kdr
, expect_kdr
, "%d", input_caps_count
);
3187 check_member( *kdr
, expect_kdr
, "%d", input_caps_end
);
3188 check_member( *kdr
, expect_kdr
, "%d", input_report_byte_length
);
3189 check_member( *kdr
, expect_kdr
, "%d", output_caps_start
);
3190 check_member( *kdr
, expect_kdr
, "%d", output_caps_count
);
3191 check_member( *kdr
, expect_kdr
, "%d", output_caps_end
);
3192 check_member( *kdr
, expect_kdr
, "%d", output_report_byte_length
);
3193 check_member( *kdr
, expect_kdr
, "%d", feature_caps_start
);
3195 check_member( *kdr
, expect_kdr
, "%d", feature_caps_count
);
3196 check_member( *kdr
, expect_kdr
, "%d", feature_caps_end
);
3197 check_member( *kdr
, expect_kdr
, "%d", feature_report_byte_length
);
3199 check_member( *kdr
, expect_kdr
, "%d", caps_size
);
3200 check_member( *kdr
, expect_kdr
, "%d", number_link_collection_nodes
);
3202 for (i
= 0; i
< min( ARRAY_SIZE(expect_caps
), kdr
->caps_size
/ sizeof(struct hidp_kdr_caps
) ); ++i
)
3204 winetest_push_context( "caps[%d]", i
);
3205 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_page
);
3206 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_id
);
3207 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_bit
);
3208 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", bit_size
);
3209 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", report_count
);
3210 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", start_byte
);
3211 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", total_bits
);
3212 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", bit_field
);
3213 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", end_byte
);
3214 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", link_collection
);
3215 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage_page
);
3216 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", link_usage
);
3217 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", flags
);
3218 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[0] );
3219 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[1] );
3220 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[2] );
3221 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[3] );
3222 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[4] );
3223 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[5] );
3224 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[6] );
3225 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", padding
[7] );
3226 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_min
);
3227 check_member( kdr
->caps
[i
], expect_caps
[i
], "%04x", usage_max
);
3228 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_min
);
3229 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", string_max
);
3230 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_min
);
3231 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", designator_max
);
3232 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_min
);
3233 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", data_index_max
);
3234 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", null_value
);
3235 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", unknown
);
3236 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", logical_min
);
3237 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", logical_max
);
3238 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", physical_min
);
3239 check_member( kdr
->caps
[i
], expect_caps
[i
], "%d", physical_max
);
3240 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", units
);
3241 check_member( kdr
->caps
[i
], expect_caps
[i
], "%#x", units_exp
);
3242 winetest_pop_context();
3245 for (i
= 0; i
< ARRAY_SIZE(expect_nodes
); ++i
)
3247 struct hidp_kdr_node
*nodes
= (struct hidp_kdr_node
*)((char *)kdr
->caps
+ kdr
->caps_size
);
3248 winetest_push_context( "nodes[%d]", i
);
3249 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage
);
3250 check_member( nodes
[i
], expect_nodes
[i
], "%04x", usage_page
);
3251 check_member( nodes
[i
], expect_nodes
[i
], "%d", parent
);
3252 check_member( nodes
[i
], expect_nodes
[i
], "%d", number_of_children
);
3253 check_member( nodes
[i
], expect_nodes
[i
], "%d", next_sibling
);
3254 check_member( nodes
[i
], expect_nodes
[i
], "%d", first_child
);
3255 check_member( nodes
[i
], expect_nodes
[i
], "%#x", collection_type
);
3256 winetest_pop_context();
3260 HidD_FreePreparsedData( preparsed_data
);
3262 CloseHandle( file
);
3266 SetCurrentDirectoryW( cwd
);
3269 static void cleanup_registry_keys(void)
3271 static const WCHAR joystick_oem_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3272 "PrivateProperties\\Joystick\\OEM";
3273 static const WCHAR dinput_path
[] = L
"System\\CurrentControlSet\\Control\\MediaProperties\\"
3274 "PrivateProperties\\DirectInput";
3277 /* These keys are automatically created by DInput and they store the
3278 list of supported force-feedback effects. OEM drivers are supposed
3279 to provide a list in HKLM for the vendor-specific force-feedback
3282 We need to clean them up, or DInput will not refresh the list of
3283 effects from the PID report changes.
3285 RegCreateKeyExW( HKEY_CURRENT_USER
, 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_CURRENT_USER
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3290 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3291 RegCloseKey( root_key
);
3293 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, joystick_oem_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3294 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3295 RegCloseKey( root_key
);
3297 RegCreateKeyExW( HKEY_LOCAL_MACHINE
, dinput_path
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &root_key
, NULL
);
3298 RegDeleteTreeW( root_key
, expect_vidpid_str
);
3299 RegCloseKey( root_key
);
3302 #define dinput_driver_start( a, b, c, d, e ) dinput_driver_start_( __LINE__, a, b, c, d, e )
3303 static BOOL
dinput_driver_start_( int line
, const BYTE
*desc_buf
, ULONG desc_len
, const HIDP_CAPS
*caps
,
3304 struct hid_expect
*expect
, ULONG expect_size
)
3306 static const HID_DEVICE_ATTRIBUTES attributes
=
3308 .Size
= sizeof(HID_DEVICE_ATTRIBUTES
),
3309 .VendorID
= LOWORD( EXPECT_VIDPID
),
3310 .ProductID
= HIWORD( EXPECT_VIDPID
),
3311 .VersionNumber
= 0x0100,
3313 DWORD report_id
= 1;
3319 status
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, L
"System\\CurrentControlSet\\Services\\winetest",
3320 0, NULL
, REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
3321 ok_(__FILE__
, line
)( !status
, "RegCreateKeyExW returned %#x\n", status
);
3322 status
= RegSetValueExW( hkey
, L
"ReportID", 0, REG_DWORD
, (void *)&report_id
, sizeof(report_id
) );
3323 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3324 status
= RegSetValueExW( hkey
, L
"PolledMode", 0, REG_DWORD
, (void *)&polled
, sizeof(polled
) );
3325 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3326 status
= RegSetValueExW( hkey
, L
"Descriptor", 0, REG_BINARY
, (void *)desc_buf
, desc_len
);
3327 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3328 status
= RegSetValueExW( hkey
, L
"Attributes", 0, REG_BINARY
, (void *)&attributes
, sizeof(attributes
) );
3329 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3330 status
= RegSetValueExW( hkey
, L
"Caps", 0, REG_BINARY
, (void *)caps
, sizeof(*caps
) );
3331 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3332 status
= RegSetValueExW( hkey
, L
"Expect", 0, REG_BINARY
, (void *)expect
, expect_size
);
3333 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3334 status
= RegSetValueExW( hkey
, L
"Input", 0, REG_BINARY
, NULL
, 0 );
3335 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3336 fill_context( line
, context
, ARRAY_SIZE(context
) );
3337 status
= RegSetValueExW( hkey
, L
"Context", 0, REG_BINARY
, (void *)context
, sizeof(context
) );
3338 ok_(__FILE__
, line
)( !status
, "RegSetValueExW returned %#x\n", status
);
3340 return pnp_driver_start( L
"driver_hid.dll" );
3343 static BOOL CALLBACK
find_test_device( const DIDEVICEINSTANCEW
*devinst
, void *context
)
3345 if (IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3346 *(DIDEVICEINSTANCEW
*)context
= *devinst
;
3347 return DIENUM_CONTINUE
;
3350 struct check_objects_todos
3358 struct check_objects_params
3363 const DIDEVICEOBJECTINSTANCEW
*expect_objs
;
3364 const struct check_objects_todos
*todo_objs
;
3368 static BOOL CALLBACK
check_objects( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
3370 static const DIDEVICEOBJECTINSTANCEW unexpected_obj
= {0};
3371 static const struct check_objects_todos todo_none
= {0};
3372 struct check_objects_params
*params
= args
;
3373 const DIDEVICEOBJECTINSTANCEW
*exp
= params
->expect_objs
+ params
->index
;
3374 const struct check_objects_todos
*todo
;
3376 if (!params
->todo_objs
) todo
= &todo_none
;
3377 else todo
= params
->todo_objs
+ params
->index
;
3379 todo_wine_if( params
->todo_extra
&& params
->index
>= params
->expect_count
)
3380 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
3381 if (params
->index
>= params
->expect_count
) return DIENUM_STOP
;
3383 winetest_push_context( "obj[%d]", params
->index
);
3385 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
3386 if (params
->index
>= params
->expect_count
) exp
= &unexpected_obj
;
3388 check_member( *obj
, *exp
, "%u", dwSize
);
3389 todo_wine_if( todo
->guid
)
3390 check_member_guid( *obj
, *exp
, guidType
);
3391 todo_wine_if( params
->version
< 0x700 && (obj
->dwType
& DIDFT_BUTTON
) )
3392 check_member( *obj
, *exp
, "%#x", dwOfs
);
3393 todo_wine_if( todo
->type
)
3394 check_member( *obj
, *exp
, "%#x", dwType
);
3395 check_member( *obj
, *exp
, "%#x", dwFlags
);
3396 if (!localized
) todo_wine_if( todo
->name
)check_member_wstr( *obj
, *exp
, tszName
);
3397 check_member( *obj
, *exp
, "%u", dwFFMaxForce
);
3398 check_member( *obj
, *exp
, "%u", dwFFForceResolution
);
3399 check_member( *obj
, *exp
, "%u", wCollectionNumber
);
3400 check_member( *obj
, *exp
, "%u", wDesignatorIndex
);
3401 check_member( *obj
, *exp
, "%#04x", wUsagePage
);
3402 todo_wine_if( todo
->usage
)
3403 check_member( *obj
, *exp
, "%#04x", wUsage
);
3404 check_member( *obj
, *exp
, "%#04x", dwDimension
);
3405 check_member( *obj
, *exp
, "%#04x", wExponent
);
3406 check_member( *obj
, *exp
, "%u", wReportId
);
3408 winetest_pop_context();
3411 return DIENUM_CONTINUE
;
3414 static BOOL CALLBACK
check_object_count( const DIDEVICEOBJECTINSTANCEW
*obj
, void *args
)
3416 DWORD
*count
= args
;
3417 *count
= *count
+ 1;
3418 return DIENUM_CONTINUE
;
3421 struct check_effects_params
3425 const DIEFFECTINFOW
*expect_effects
;
3428 static BOOL CALLBACK
check_effects( const DIEFFECTINFOW
*effect
, void *args
)
3430 static const DIEFFECTINFOW unexpected_effect
= {0};
3431 struct check_effects_params
*params
= args
;
3432 const DIEFFECTINFOW
*exp
= params
->expect_effects
+ params
->index
;
3434 winetest_push_context( "effect[%d]", params
->index
);
3436 ok( params
->index
< params
->expect_count
, "unexpected extra object\n" );
3437 if (params
->index
>= params
->expect_count
) exp
= &unexpected_effect
;
3439 check_member( *effect
, *exp
, "%u", dwSize
);
3440 check_member_guid( *effect
, *exp
, guid
);
3441 check_member( *effect
, *exp
, "%#x", dwEffType
);
3442 check_member( *effect
, *exp
, "%#x", dwStaticParams
);
3443 check_member( *effect
, *exp
, "%#x", dwDynamicParams
);
3444 check_member_wstr( *effect
, *exp
, tszName
);
3446 winetest_pop_context();
3449 return DIENUM_CONTINUE
;
3452 static BOOL CALLBACK
check_effect_count( const DIEFFECTINFOW
*effect
, void *args
)
3454 DWORD
*count
= args
;
3455 *count
= *count
+ 1;
3456 return DIENUM_CONTINUE
;
3459 static BOOL CALLBACK
check_no_created_effect_objects( IDirectInputEffect
*effect
, void *context
)
3461 ok( 0, "unexpected effect %p\n", effect
);
3462 return DIENUM_CONTINUE
;
3465 struct check_created_effect_params
3467 IDirectInputEffect
*expect_effect
;
3471 static BOOL CALLBACK
check_created_effect_objects( IDirectInputEffect
*effect
, void *context
)
3473 struct check_created_effect_params
*params
= context
;
3476 ok( effect
== params
->expect_effect
, "got effect %p, expected %p\n", effect
, params
->expect_effect
);
3479 IDirectInputEffect_AddRef( effect
);
3480 ref
= IDirectInputEffect_Release( effect
);
3481 ok( ref
== 1, "got ref %u, expected 1\n", ref
);
3482 return DIENUM_CONTINUE
;
3485 static BOOL CALLBACK
enum_device_count( const DIDEVICEINSTANCEW
*devinst
, void *context
)
3487 DWORD
*count
= context
;
3488 *count
= *count
+ 1;
3489 return DIENUM_CONTINUE
;
3492 static HRESULT
create_dinput_device( DWORD version
, DIDEVICEINSTANCEW
*devinst
, IDirectInputDevice8W
**device
)
3494 DIPROPDWORD prop_dword
=
3498 .dwSize
= sizeof(DIPROPDWORD
),
3499 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3500 .dwHow
= DIPH_DEVICE
,
3503 IDirectInput8W
*di8
;
3508 if (version
>= 0x800)
3510 hr
= DirectInput8Create( instance
, version
, &IID_IDirectInput8W
, (void **)&di8
, NULL
);
3513 win_skip( "DirectInput8Create returned %#x\n", hr
);
3517 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, find_test_device
, devinst
, DIEDFL_ALLDEVICES
);
3518 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3519 if (!IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3521 win_skip( "device not found, skipping tests\n" );
3522 ref
= IDirectInput8_Release( di8
);
3523 ok( ref
== 0, "Release returned %d\n", ref
);
3524 return DIERR_DEVICENOTREG
;
3527 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, NULL
, NULL
, DIEDFL_ALLDEVICES
);
3528 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3529 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, 0xdeadbeef );
3530 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3531 hr
= IDirectInput8_EnumDevices( di8
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3532 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3535 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_ALL
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3536 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3537 ok( count
== 3, "got count %u, expected 0\n", count
);
3539 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3540 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3541 ok( count
== 0, "got count %u, expected 0\n", count
);
3543 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_POINTER
, enum_device_count
, &count
,
3544 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
3545 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3547 ok( count
== 3, "got count %u, expected 3\n", count
);
3549 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_KEYBOARD
, enum_device_count
, &count
,
3550 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
3551 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3553 ok( count
== 3, "got count %u, expected 3\n", count
);
3555 hr
= IDirectInput8_EnumDevices( di8
, DI8DEVCLASS_GAMECTRL
, enum_device_count
, &count
,
3556 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
| DIEDFL_INCLUDEHIDDEN
);
3557 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3558 ok( count
== 1, "got count %u, expected 1\n", count
);
3561 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3562 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3563 ok( count
== 1, "got count %u, expected 1\n", count
);
3566 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
3567 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3568 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %u, expected 0\n", count
);
3569 else ok( count
== 1, "got count %u, expected 1\n", count
);
3572 hr
= IDirectInput8_EnumDevices( di8
, (devinst
->dwDevType
& 0xff) + 1, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3573 if ((devinst
->dwDevType
& 0xff) != DI8DEVTYPE_SUPPLEMENTAL
) ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3574 else ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3575 ok( count
== 0, "got count %u, expected 0\n", count
);
3577 hr
= IDirectInput8_CreateDevice( di8
, &devinst
->guidInstance
, NULL
, NULL
);
3578 ok( hr
== E_POINTER
, "CreateDevice returned %#x\n", hr
);
3579 hr
= IDirectInput8_CreateDevice( di8
, NULL
, device
, NULL
);
3580 ok( hr
== E_POINTER
, "CreateDevice returned %#x\n", hr
);
3581 hr
= IDirectInput8_CreateDevice( di8
, &GUID_NULL
, device
, NULL
);
3582 ok( hr
== DIERR_DEVICENOTREG
, "CreateDevice returned %#x\n", hr
);
3583 hr
= IDirectInput8_CreateDevice( di8
, &devinst
->guidInstance
, device
, NULL
);
3584 ok( hr
== DI_OK
, "CreateDevice returned %#x\n", hr
);
3586 prop_dword
.dwData
= 0xdeadbeef;
3587 hr
= IDirectInputDevice8_GetProperty( *device
, DIPROP_VIDPID
, &prop_dword
.diph
);
3588 ok( hr
== DI_OK
, "GetProperty DIPROP_VIDPID returned %#x\n", hr
);
3589 /* Wine may get the wrong device here, because the test driver creates another instance of
3590 hidclass.sys, and gets duplicate rawinput handles, which we use in the guidInstance */
3591 todo_wine_if( prop_dword
.dwData
!= EXPECT_VIDPID
)
3592 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#x expected %#x\n", prop_dword
.dwData
, EXPECT_VIDPID
);
3594 ref
= IDirectInputDevice8_Release( *device
);
3595 ok( ref
== 0, "Release returned %d\n", ref
);
3597 hr
= IDirectInput8_CreateDevice( di8
, &expect_guid_product
, device
, NULL
);
3598 ok( hr
== DI_OK
, "CreateDevice returned %#x\n", hr
);
3600 ref
= IDirectInput8_Release( di8
);
3602 ok( ref
== 0, "Release returned %d\n", ref
);
3606 hr
= DirectInputCreateEx( instance
, version
, &IID_IDirectInput2W
, (void **)&di
, NULL
);
3609 win_skip( "DirectInputCreateEx returned %#x\n", hr
);
3613 hr
= IDirectInput_EnumDevices( di
, 0, find_test_device
, devinst
, DIEDFL_ALLDEVICES
);
3614 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3615 if (!IsEqualGUID( &devinst
->guidProduct
, &expect_guid_product
))
3617 win_skip( "device not found, skipping tests\n" );
3619 ref
= IDirectInput_Release( di
);
3620 ok( ref
== 0, "Release returned %d\n", ref
);
3621 return DIERR_DEVICENOTREG
;
3624 hr
= IDirectInput_EnumDevices( di
, 0, NULL
, NULL
, DIEDFL_ALLDEVICES
);
3625 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3626 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, 0xdeadbeef );
3627 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3628 hr
= IDirectInput_EnumDevices( di
, 0xdeadbeef, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3629 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3630 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_INCLUDEHIDDEN
);
3631 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3634 hr
= IDirectInput_EnumDevices( di
, 0, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3635 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3636 ok( count
== 3, "got count %u, expected 0\n", count
);
3638 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_DEVICE
, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3639 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3640 ok( count
== 0, "got count %u, expected 0\n", count
);
3642 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_MOUSE
, enum_device_count
, &count
,
3643 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
3644 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3646 ok( count
== 3, "got count %u, expected 3\n", count
);
3648 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_KEYBOARD
, enum_device_count
, &count
,
3649 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
3650 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3652 ok( count
== 3, "got count %u, expected 3\n", count
);
3654 hr
= IDirectInput_EnumDevices( di
, DIDEVTYPE_JOYSTICK
, enum_device_count
, &count
,
3655 DIEDFL_INCLUDEALIASES
| DIEDFL_INCLUDEPHANTOMS
);
3656 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3657 ok( count
== 1, "got count %u, expected 1\n", count
);
3660 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3661 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3662 ok( count
== 1, "got count %u, expected 1\n", count
);
3665 hr
= IDirectInput_EnumDevices( di
, (devinst
->dwDevType
& 0xff), enum_device_count
, &count
, DIEDFL_FORCEFEEDBACK
);
3666 ok( hr
== DI_OK
, "EnumDevices returned: %#x\n", hr
);
3667 if (IsEqualGUID( &devinst
->guidFFDriver
, &GUID_NULL
)) ok( count
== 0, "got count %u, expected 0\n", count
);
3668 else ok( count
== 1, "got count %u, expected 1\n", count
);
3670 hr
= IDirectInput_EnumDevices( di
, 0x14, enum_device_count
, &count
, DIEDFL_ALLDEVICES
);
3671 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned: %#x\n", hr
);
3673 hr
= IDirectInput_CreateDevice( di
, &expect_guid_product
, (IDirectInputDeviceW
**)device
, NULL
);
3674 ok( hr
== DI_OK
, "CreateDevice returned %#x\n", hr
);
3676 ref
= IDirectInput_Release( di
);
3678 ok( ref
== 0, "Release returned %d\n", ref
);
3684 static void test_simple_joystick(void)
3686 #include "psh_hid_macros.h"
3687 static const unsigned char report_desc
[] =
3689 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
3690 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3691 COLLECTION(1, Application
),
3692 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
3693 COLLECTION(1, Report
),
3696 USAGE(1, HID_USAGE_GENERIC_WHEEL
),
3697 USAGE(4, (0xff01u
<<16)|(0x1234)),
3698 USAGE(1, HID_USAGE_GENERIC_X
),
3699 USAGE(1, HID_USAGE_GENERIC_Y
),
3700 USAGE(4, (HID_USAGE_PAGE_SIMULATION
<<16)|HID_USAGE_SIMULATION_RUDDER
),
3701 USAGE(4, (HID_USAGE_PAGE_DIGITIZER
<<16)|HID_USAGE_DIGITIZER_TIP_PRESSURE
),
3702 USAGE(4, (HID_USAGE_PAGE_CONSUMER
<<16)|HID_USAGE_CONSUMER_VOLUME
),
3703 LOGICAL_MINIMUM(1, 0xe7),
3704 LOGICAL_MAXIMUM(1, 0x38),
3705 PHYSICAL_MINIMUM(1, 0xe7),
3706 PHYSICAL_MAXIMUM(1, 0x38),
3709 INPUT(1, Data
|Var
|Abs
),
3711 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
3712 LOGICAL_MINIMUM(1, 1),
3713 LOGICAL_MAXIMUM(1, 8),
3714 PHYSICAL_MINIMUM(1, 0),
3715 PHYSICAL_MAXIMUM(1, 8),
3718 INPUT(1, Data
|Var
|Abs
|Null
),
3720 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
3721 USAGE_MINIMUM(1, 1),
3722 USAGE_MAXIMUM(1, 2),
3723 LOGICAL_MINIMUM(1, 0),
3724 LOGICAL_MAXIMUM(1, 1),
3725 PHYSICAL_MINIMUM(1, 0),
3726 PHYSICAL_MAXIMUM(1, 1),
3729 INPUT(1, Data
|Var
|Abs
),
3733 #undef REPORT_ID_OR_USAGE_PAGE
3734 #include "pop_hid_macros.h"
3736 static const HIDP_CAPS hid_caps
=
3738 .InputReportByteLength
= 9,
3740 static const DIDEVCAPS expect_caps
=
3742 .dwSize
= sizeof(DIDEVCAPS
),
3743 .dwFlags
= DIDC_ATTACHED
| DIDC_EMULATED
,
3744 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
,
3749 struct hid_expect injected_input
[] =
3752 .code
= IOCTL_HID_READ_REPORT
,
3753 .report_buf
= {1,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0},
3756 .code
= IOCTL_HID_READ_REPORT
,
3757 .report_buf
= {1,0x10,0x10,0x38,0x38,0x10,0x10,0x10,0xf8},
3760 .code
= IOCTL_HID_READ_REPORT
,
3761 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
3764 .code
= IOCTL_HID_READ_REPORT
,
3765 .report_buf
= {1,0x10,0x10,0x01,0x01,0x10,0x10,0x10,0x00},
3768 .code
= IOCTL_HID_READ_REPORT
,
3769 .report_buf
= {1,0x10,0x10,0x80,0x80,0x10,0x10,0x10,0xff},
3772 .code
= IOCTL_HID_READ_REPORT
,
3773 .report_buf
= {1,0x10,0x10,0x10,0xee,0x10,0x10,0x10,0x54},
3776 static const struct DIJOYSTATE2 expect_state
[] =
3778 {.lX
= 32767, .lY
= 32767, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3779 {.lX
= 32767, .lY
= 32767, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3780 {.lX
= 65535, .lY
= 65535, .lZ
= 32767, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3781 {.lX
= 20779, .lY
= 20779, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3782 {.lX
= 20779, .lY
= 20779, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3783 {.lX
= 0, .lY
= 0, .lZ
= 32767, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3784 {.lX
= 32767, .lY
= 5594, .lZ
= 32767, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3786 static const struct DIJOYSTATE2 expect_state_abs
[] =
3788 {.lX
= -9000, .lY
= 26000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3789 {.lX
= -9000, .lY
= 26000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3790 {.lX
= -4000, .lY
= 51000, .lZ
= 26000, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3791 {.lX
= -10667, .lY
= 12905, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3792 {.lX
= -10667, .lY
= 12905, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3793 {.lX
= -14000, .lY
= 1000, .lZ
= 26000, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3794 {.lX
= -9000, .lY
= 1000, .lZ
= 26000, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3796 static const struct DIJOYSTATE2 expect_state_rel
[] =
3798 {.lX
= 0, .lY
= 0, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80, 0}},
3799 {.lX
= 9016, .lY
= -984, .lZ
= -25984, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3800 {.lX
= 40, .lY
= 40, .rgdwPOV
= {31500, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3801 {.lX
= -55, .lY
= -55, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3802 {.lX
= 0, .lY
= 0, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0, 0}},
3803 {.lX
= -129, .lY
= -129, .rgdwPOV
= {-1, -1, -1, -1}, .rgbButtons
= {0x80, 0x80}},
3804 {.lX
= 144, .lY
= 110, .rgdwPOV
= {13500, -1, -1, -1}, .rgbButtons
= {0x80}},
3806 static const DIDEVICEOBJECTDATA expect_objdata
[] =
3808 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
3809 {.dwOfs
= 0x4, .dwData
= 0xffff, .dwSequence
= 0xa},
3810 {.dwOfs
= 0, .dwData
= 0xffff, .dwSequence
= 0xa},
3811 {.dwOfs
= 0x20, .dwData
= 31500, .dwSequence
= 0xa},
3812 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xa},
3813 {.dwOfs
= 0x4, .dwData
= 0x512b, .dwSequence
= 0xd},
3814 {.dwOfs
= 0, .dwData
= 0x512b, .dwSequence
= 0xd},
3815 {.dwOfs
= 0x20, .dwData
= -1, .dwSequence
= 0xd},
3816 {.dwOfs
= 0x30, .dwData
= 0, .dwSequence
= 0xd},
3817 {.dwOfs
= 0x31, .dwData
= 0, .dwSequence
= 0xd},
3818 {.dwOfs
= 0x4, .dwData
= 0, .dwSequence
= 0xf},
3819 {.dwOfs
= 0, .dwData
= 0, .dwSequence
= 0xf},
3820 {.dwOfs
= 0x30, .dwData
= 0x80, .dwSequence
= 0xf},
3821 {.dwOfs
= 0x31, .dwData
= 0x80, .dwSequence
= 0xf},
3824 const DIDEVICEINSTANCEW expect_devinst
=
3826 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
3827 .guidInstance
= expect_guid_product
,
3828 .guidProduct
= expect_guid_product
,
3829 .dwDevType
= DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
,
3830 .tszInstanceName
= L
"Wine test root driver",
3831 .tszProductName
= L
"Wine test root driver",
3832 .guidFFDriver
= GUID_NULL
,
3833 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3834 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3836 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
3839 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3840 .guidType
= GUID_Unknown
,
3841 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(6),
3842 .tszName
= L
"Volume",
3843 .wCollectionNumber
= 1,
3844 .wUsagePage
= HID_USAGE_PAGE_CONSUMER
,
3845 .wUsage
= HID_USAGE_CONSUMER_VOLUME
,
3849 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3850 .guidType
= GUID_Unknown
,
3852 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(7),
3853 .tszName
= L
"Tip Pressure",
3854 .wCollectionNumber
= 1,
3855 .wUsagePage
= HID_USAGE_PAGE_DIGITIZER
,
3856 .wUsage
= HID_USAGE_DIGITIZER_TIP_PRESSURE
,
3860 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3861 .guidType
= GUID_RzAxis
,
3863 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(5),
3864 .dwFlags
= DIDOI_ASPECTPOSITION
,
3865 .tszName
= L
"Rudder",
3866 .wCollectionNumber
= 1,
3867 .wUsagePage
= HID_USAGE_PAGE_SIMULATION
,
3868 .wUsage
= HID_USAGE_SIMULATION_RUDDER
,
3872 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3873 .guidType
= GUID_YAxis
,
3875 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1),
3876 .dwFlags
= DIDOI_ASPECTPOSITION
,
3877 .tszName
= L
"Y Axis",
3878 .wCollectionNumber
= 1,
3879 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3880 .wUsage
= HID_USAGE_GENERIC_Y
,
3884 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3885 .guidType
= GUID_XAxis
,
3887 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0),
3888 .dwFlags
= DIDOI_ASPECTPOSITION
,
3889 .tszName
= L
"X Axis",
3890 .wCollectionNumber
= 1,
3891 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3892 .wUsage
= HID_USAGE_GENERIC_X
,
3896 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3897 .guidType
= GUID_ZAxis
,
3899 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2),
3900 .dwFlags
= DIDOI_ASPECTPOSITION
,
3901 .tszName
= L
"Wheel",
3902 .wCollectionNumber
= 1,
3903 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3904 .wUsage
= HID_USAGE_GENERIC_WHEEL
,
3908 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3909 .guidType
= GUID_POV
,
3911 .dwType
= DIDFT_POV
|DIDFT_MAKEINSTANCE(0),
3912 .tszName
= L
"Hat Switch",
3913 .wCollectionNumber
= 1,
3914 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3915 .wUsage
= HID_USAGE_GENERIC_HATSWITCH
,
3919 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3920 .guidType
= GUID_Button
,
3922 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0),
3923 .tszName
= L
"Button 0",
3924 .wCollectionNumber
= 1,
3925 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
3930 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3931 .guidType
= GUID_Button
,
3933 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1),
3934 .tszName
= L
"Button 1",
3935 .wCollectionNumber
= 1,
3936 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
3941 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3942 .guidType
= GUID_Unknown
,
3943 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
3944 .tszName
= L
"Collection 0 - Joystick",
3945 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3946 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3949 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
3950 .guidType
= GUID_Unknown
,
3951 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
3952 .tszName
= L
"Collection 1 - Joystick",
3953 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
3954 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
3957 const DIEFFECTINFOW expect_effects
[] = {};
3959 struct check_objects_params check_objects_params
=
3961 .version
= DIRECTINPUT_VERSION
,
3962 .expect_count
= ARRAY_SIZE(expect_objects
),
3963 .expect_objs
= expect_objects
,
3965 struct check_effects_params check_effects_params
=
3967 .expect_count
= ARRAY_SIZE(expect_effects
),
3968 .expect_effects
= expect_effects
,
3970 DIPROPGUIDANDPATH prop_guid_path
=
3974 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
3975 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3976 .dwHow
= DIPH_DEVICE
,
3979 DIPROPSTRING prop_string
=
3983 .dwSize
= sizeof(DIPROPSTRING
),
3984 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3985 .dwHow
= DIPH_DEVICE
,
3988 DIPROPDWORD prop_dword
=
3992 .dwSize
= sizeof(DIPROPDWORD
),
3993 .dwHeaderSize
= sizeof(DIPROPHEADER
),
3994 .dwHow
= DIPH_DEVICE
,
3997 DIPROPRANGE prop_range
=
4001 .dwSize
= sizeof(DIPROPRANGE
),
4002 .dwHeaderSize
= sizeof(DIPROPHEADER
),
4003 .dwHow
= DIPH_DEVICE
,
4006 DIPROPPOINTER prop_pointer
=
4010 .dwSize
= sizeof(DIPROPPOINTER
),
4011 .dwHeaderSize
= sizeof(DIPROPHEADER
),
4014 DIOBJECTDATAFORMAT objdataformat
[32] = {{0}};
4015 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
4016 DIDEVICEOBJECTDATA objdata
[32] = {{0}};
4017 DIDEVICEOBJECTINSTANCEW objinst
= {0};
4018 DIDEVICEINSTANCEW devinst
= {0};
4019 DIEFFECTINFOW effectinfo
= {0};
4020 DIDATAFORMAT dataformat
= {0};
4021 IDirectInputDevice8W
*device
;
4022 IDirectInputEffect
*effect
;
4023 DIEFFESCAPE escape
= {0};
4024 DIDEVCAPS caps
= {0};
4034 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
4035 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
4036 SetCurrentDirectoryW( tempdir
);
4038 cleanup_registry_keys();
4039 if (!dinput_driver_start( report_desc
, sizeof(report_desc
), &hid_caps
, NULL
, 0 )) goto done
;
4040 if (FAILED(hr
= create_dinput_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
4042 hr
= IDirectInputDevice8_Initialize( device
, instance
, 0x0700, &GUID_NULL
);
4044 ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#x\n", hr
);
4045 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, NULL
);
4047 ok( hr
== E_POINTER
, "Initialize returned %#x\n", hr
);
4048 hr
= IDirectInputDevice8_Initialize( device
, NULL
, DIRECTINPUT_VERSION
, &GUID_NULL
);
4050 ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#x\n", hr
);
4051 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, &GUID_NULL
);
4053 ok( hr
== REGDB_E_CLASSNOTREG
, "Initialize returned %#x\n", hr
);
4055 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, &devinst
.guidInstance
);
4056 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
4057 guid
= devinst
.guidInstance
;
4058 memset( &devinst
, 0, sizeof(devinst
) );
4059 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
4060 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4061 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
4062 ok( IsEqualGUID( &guid
, &devinst
.guidInstance
), "got %s expected %s\n", debugstr_guid( &guid
),
4063 debugstr_guid( &devinst
.guidInstance
) );
4064 hr
= IDirectInputDevice8_Initialize( device
, instance
, DIRECTINPUT_VERSION
, &devinst
.guidProduct
);
4065 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
4067 hr
= IDirectInputDevice8_GetDeviceInfo( device
, NULL
);
4068 ok( hr
== E_POINTER
, "GetDeviceInfo returned %#x\n", hr
);
4069 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
) + 1;
4070 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4071 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceInfo returned %#x\n", hr
);
4073 devinst
.dwSize
= sizeof(DIDEVICEINSTANCE_DX3W
);
4074 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4075 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
4077 check_member_guid( devinst
, expect_devinst
, guidInstance
);
4078 check_member_guid( devinst
, expect_devinst
, guidProduct
);
4079 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
4081 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
4083 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
4085 memset( &devinst
, 0, sizeof(devinst
) );
4086 devinst
.dwSize
= sizeof(DIDEVICEINSTANCEW
);
4087 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
4088 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
4089 check_member( devinst
, expect_devinst
, "%d", dwSize
);
4091 check_member_guid( devinst
, expect_devinst
, guidInstance
);
4092 check_member_guid( devinst
, expect_devinst
, guidProduct
);
4093 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
4095 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
4097 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
4098 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
4099 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
4100 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
4102 hr
= IDirectInputDevice8_GetCapabilities( device
, NULL
);
4103 ok( hr
== E_POINTER
, "GetCapabilities returned %#x\n", hr
);
4104 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4105 ok( hr
== DIERR_INVALIDPARAM
, "GetCapabilities returned %#x\n", hr
);
4106 caps
.dwSize
= sizeof(DIDEVCAPS
);
4107 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
4108 ok( hr
== DI_OK
, "GetCapabilities returned %#x\n", hr
);
4109 check_member( caps
, expect_caps
, "%d", dwSize
);
4110 check_member( caps
, expect_caps
, "%#x", dwFlags
);
4111 check_member( caps
, expect_caps
, "%#x", dwDevType
);
4112 check_member( caps
, expect_caps
, "%d", dwAxes
);
4113 check_member( caps
, expect_caps
, "%d", dwButtons
);
4114 check_member( caps
, expect_caps
, "%d", dwPOVs
);
4115 check_member( caps
, expect_caps
, "%d", dwFFSamplePeriod
);
4116 check_member( caps
, expect_caps
, "%d", dwFFMinTimeResolution
);
4117 check_member( caps
, expect_caps
, "%d", dwFirmwareRevision
);
4118 check_member( caps
, expect_caps
, "%d", dwHardwareRevision
);
4119 check_member( caps
, expect_caps
, "%d", dwFFDriverVersion
);
4121 hr
= IDirectInputDevice8_GetProperty( device
, NULL
, NULL
);
4122 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4123 hr
= IDirectInputDevice8_GetProperty( device
, &GUID_NULL
, NULL
);
4124 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4125 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, NULL
);
4126 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4127 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
4128 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4129 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
) - 1;
4130 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
4131 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty returned %#x\n", hr
);
4132 prop_dword
.diph
.dwHeaderSize
= sizeof(DIPROPHEADER
);
4134 prop_dword
.dwData
= 0xdeadbeef;
4135 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
4136 ok( hr
== DI_OK
, "GetProperty DIPROP_VIDPID returned %#x\n", hr
);
4137 ok( prop_dword
.dwData
== EXPECT_VIDPID
, "got %#x expected %#x\n", prop_dword
.dwData
, EXPECT_VIDPID
);
4139 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
4140 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
4142 ok( IsEqualGUID( &prop_guid_path
.guidClass
, &GUID_DEVCLASS_HIDCLASS
), "got guid %s\n",
4143 debugstr_guid( &prop_guid_path
.guidClass
) );
4145 ok( !wcsncmp( prop_guid_path
.wszPath
, expect_path
, wcslen( expect_path
) ), "got path %s\n",
4146 debugstr_w(prop_guid_path
.wszPath
) );
4147 if (!(tmp
= wcsrchr( prop_guid_path
.wszPath
, '&' )))
4148 todo_wine
ok( 0, "got path %s\n", debugstr_w(prop_guid_path
.wszPath
) );
4151 ok( !wcscmp( wcsrchr( prop_guid_path
.wszPath
, '&' ), expect_path_end
), "got path %s\n",
4152 debugstr_w(prop_guid_path
.wszPath
) );
4155 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
4156 ok( hr
== DI_OK
, "GetProperty DIPROP_INSTANCENAME returned %#x\n", hr
);
4158 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszInstanceName
), "got instance %s\n",
4159 debugstr_w(prop_string
.wsz
) );
4160 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4161 ok( hr
== DI_OK
, "GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4163 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
4164 debugstr_w(prop_string
.wsz
) );
4165 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
4167 ok( hr
== DI_OK
, "GetProperty DIPROP_TYPENAME returned %#x\n", hr
);
4169 ok( !wcscmp( prop_string
.wsz
, expect_vidpid_str
), "got type %s\n", debugstr_w(prop_string
.wsz
) );
4170 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
4171 ok( hr
== S_FALSE
, "GetProperty DIPROP_USERNAME returned %#x\n", hr
);
4173 ok( !wcscmp( prop_string
.wsz
, L
"" ), "got user %s\n", debugstr_w(prop_string
.wsz
) );
4175 prop_dword
.dwData
= 0xdeadbeef;
4176 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
4177 ok( hr
== DI_OK
, "GetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
4179 ok( prop_dword
.dwData
== 0, "got %#x expected %#x\n", prop_dword
.dwData
, 0 );
4181 prop_dword
.dwData
= 0xdeadbeef;
4182 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4184 ok( hr
== DI_OK
, "GetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4186 ok( prop_dword
.dwData
== DIPROPAXISMODE_ABS
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_ABS
);
4187 prop_dword
.dwData
= 0xdeadbeef;
4188 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4189 ok( hr
== DI_OK
, "GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4190 ok( prop_dword
.dwData
== 0, "got %#x expected %#x\n", prop_dword
.dwData
, 0 );
4191 prop_dword
.dwData
= 0xdeadbeef;
4192 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
4193 ok( hr
== DI_OK
, "GetProperty DIPROP_FFGAIN returned %#x\n", hr
);
4194 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
4196 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
4197 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty DIPROP_CALIBRATION returned %#x\n", hr
);
4198 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
4199 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
4200 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4201 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4202 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4203 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
4204 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
4205 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
4206 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4207 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4208 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4209 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4210 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4211 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4212 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4213 ok( hr
== DIERR_INVALIDPARAM
, "GetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4214 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4215 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4216 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4217 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4219 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4220 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4221 prop_dword
.dwData
= 0xdeadbeef;
4222 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4223 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4224 ok( prop_dword
.dwData
== 0, "got %u expected %u\n", prop_dword
.dwData
, 0 );
4225 prop_dword
.dwData
= 0xdeadbeef;
4226 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
4227 ok( hr
== DI_OK
, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
4228 ok( prop_dword
.dwData
== 1, "got %u expected %u\n", prop_dword
.dwData
, 1 );
4229 prop_dword
.dwData
= 0xdeadbeef;
4230 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4231 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4232 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
4233 prop_dword
.dwData
= 0xdeadbeef;
4234 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4235 ok( hr
== DI_OK
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4236 ok( prop_dword
.dwData
== DIPROPCALIBRATIONMODE_COOKED
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPCALIBRATIONMODE_COOKED
);
4238 prop_string
.diph
.dwHow
= DIPH_BYUSAGE
;
4239 prop_string
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4240 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4241 ok( hr
== DI_OK
, "GetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4242 ok( !wcscmp( prop_string
.wsz
, expect_objects
[4].tszName
), "got DIPROP_KEYNAME %s\n",
4243 debugstr_w( prop_string
.wsz
) );
4244 prop_string
.diph
.dwObj
= MAKELONG( 0x1, HID_USAGE_PAGE_BUTTON
);
4245 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4247 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4248 prop_string
.diph
.dwHow
= DIPH_BYUSAGE
;
4249 prop_string
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4250 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_KEYNAME
, &prop_string
.diph
);
4251 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_KEYNAME returned %#x\n", hr
);
4253 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4254 prop_range
.diph
.dwObj
= MAKELONG( 0, 0 );
4255 prop_range
.lMin
= 0xdeadbeef;
4256 prop_range
.lMax
= 0xdeadbeef;
4257 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4258 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4259 prop_range
.diph
.dwObj
= MAKELONG( 0, HID_USAGE_PAGE_GENERIC
);
4260 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4261 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4262 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_PAGE_GENERIC
, HID_USAGE_GENERIC_X
);
4263 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4264 ok( hr
== DIERR_NOTFOUND
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4265 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4266 prop_range
.lMin
= 0xdeadbeef;
4267 prop_range
.lMax
= 0xdeadbeef;
4268 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4269 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4270 ok( prop_range
.lMin
== 0, "got %d expected %d\n", prop_range
.lMin
, 0 );
4271 ok( prop_range
.lMax
== 65535, "got %d expected %d\n", prop_range
.lMax
, 65535 );
4272 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4273 ok( hr
== DI_OK
, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4274 ok( prop_range
.lMin
== -25, "got %d expected %d\n", prop_range
.lMin
, -25 );
4275 ok( prop_range
.lMax
== 56, "got %d expected %d\n", prop_range
.lMax
, 56 );
4276 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4277 ok( hr
== DI_OK
, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4278 ok( prop_range
.lMin
== -25, "got %d expected %d\n", prop_range
.lMin
, -25 );
4279 ok( prop_range
.lMax
== 56, "got %d expected %d\n", prop_range
.lMax
, 56 );
4281 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
4282 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4283 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
4285 ok( hr
== DIERR_NOTINITIALIZED
, "GetProperty DIPROP_APPDATA returned %#x\n", hr
);
4287 hr
= IDirectInputDevice8_EnumObjects( device
, NULL
, NULL
, DIDFT_ALL
);
4288 ok( hr
== DIERR_INVALIDPARAM
, "EnumObjects returned %#x\n", hr
);
4289 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, 0x20 );
4290 ok( hr
== DIERR_INVALIDPARAM
, "EnumObjects returned %#x\n", hr
);
4292 hr
= IDirectInputDevice8_EnumObjects( device
, check_object_count
, &res
, DIDFT_AXIS
| DIDFT_PSHBUTTON
);
4293 ok( hr
== DI_OK
, "EnumObjects returned %#x\n", hr
);
4294 ok( res
== 8, "got %u expected %u\n", res
, 8 );
4295 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
4296 ok( hr
== DI_OK
, "EnumObjects returned %#x\n", hr
);
4297 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
4298 check_objects_params
.expect_count
- check_objects_params
.index
);
4300 hr
= IDirectInputDevice8_GetObjectInfo( device
, NULL
, 0, DIPH_DEVICE
);
4301 ok( hr
== E_POINTER
, "GetObjectInfo returned: %#x\n", hr
);
4302 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_DEVICE
);
4303 ok( hr
== DIERR_INVALIDPARAM
, "GetObjectInfo returned: %#x\n", hr
);
4304 objinst
.dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
);
4305 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_DEVICE
);
4306 ok( hr
== DIERR_INVALIDPARAM
, "GetObjectInfo returned: %#x\n", hr
);
4308 res
= MAKELONG( HID_USAGE_GENERIC_Z
, HID_USAGE_PAGE_GENERIC
);
4309 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYUSAGE
);
4310 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4311 res
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4312 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYUSAGE
);
4313 ok( hr
== DI_OK
, "GetObjectInfo returned: %#x\n", hr
);
4315 check_member( objinst
, expect_objects
[4], "%u", dwSize
);
4316 check_member_guid( objinst
, expect_objects
[4], guidType
);
4317 check_member( objinst
, expect_objects
[4], "%#x", dwOfs
);
4318 check_member( objinst
, expect_objects
[4], "%#x", dwType
);
4319 check_member( objinst
, expect_objects
[4], "%#x", dwFlags
);
4320 if (!localized
) check_member_wstr( objinst
, expect_objects
[4], tszName
);
4321 check_member( objinst
, expect_objects
[4], "%u", dwFFMaxForce
);
4322 check_member( objinst
, expect_objects
[4], "%u", dwFFForceResolution
);
4323 check_member( objinst
, expect_objects
[4], "%u", wCollectionNumber
);
4324 check_member( objinst
, expect_objects
[4], "%u", wDesignatorIndex
);
4325 check_member( objinst
, expect_objects
[4], "%#04x", wUsagePage
);
4326 check_member( objinst
, expect_objects
[4], "%#04x", wUsage
);
4327 check_member( objinst
, expect_objects
[4], "%#04x", dwDimension
);
4328 check_member( objinst
, expect_objects
[4], "%#04x", wExponent
);
4329 check_member( objinst
, expect_objects
[4], "%u", wReportId
);
4331 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0x14, DIPH_BYOFFSET
);
4332 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4333 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, 0, DIPH_BYOFFSET
);
4334 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4335 res
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 3 );
4336 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYID
);
4337 ok( hr
== DIERR_NOTFOUND
, "GetObjectInfo returned: %#x\n", hr
);
4338 res
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 1 );
4339 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, res
, DIPH_BYID
);
4340 ok( hr
== DI_OK
, "GetObjectInfo returned: %#x\n", hr
);
4342 check_member( objinst
, expect_objects
[8], "%u", dwSize
);
4343 check_member_guid( objinst
, expect_objects
[8], guidType
);
4344 check_member( objinst
, expect_objects
[8], "%#x", dwOfs
);
4345 check_member( objinst
, expect_objects
[8], "%#x", dwType
);
4346 check_member( objinst
, expect_objects
[8], "%#x", dwFlags
);
4347 if (!localized
) check_member_wstr( objinst
, expect_objects
[8], tszName
);
4348 check_member( objinst
, expect_objects
[8], "%u", dwFFMaxForce
);
4349 check_member( objinst
, expect_objects
[8], "%u", dwFFForceResolution
);
4350 check_member( objinst
, expect_objects
[8], "%u", wCollectionNumber
);
4351 check_member( objinst
, expect_objects
[8], "%u", wDesignatorIndex
);
4352 check_member( objinst
, expect_objects
[8], "%#04x", wUsagePage
);
4353 check_member( objinst
, expect_objects
[8], "%#04x", wUsage
);
4354 check_member( objinst
, expect_objects
[8], "%#04x", dwDimension
);
4355 check_member( objinst
, expect_objects
[8], "%#04x", wExponent
);
4356 check_member( objinst
, expect_objects
[8], "%u", wReportId
);
4358 hr
= IDirectInputDevice8_EnumEffects( device
, NULL
, NULL
, DIEFT_ALL
);
4359 ok( hr
== DIERR_INVALIDPARAM
, "EnumEffects returned %#x\n", hr
);
4361 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, 0xfe );
4362 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
4363 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4365 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, DIEFT_PERIODIC
);
4366 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
4367 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4368 hr
= IDirectInputDevice8_EnumEffects( device
, check_effects
, &check_effects_params
, DIEFT_ALL
);
4369 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
4370 ok( check_effects_params
.index
>= check_effects_params
.expect_count
, "missing %u effects\n",
4371 check_effects_params
.expect_count
- check_effects_params
.index
);
4373 hr
= IDirectInputDevice8_GetEffectInfo( device
, NULL
, &GUID_Sine
);
4374 ok( hr
== E_POINTER
, "GetEffectInfo returned %#x\n", hr
);
4375 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
) + 1;
4376 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
4377 ok( hr
== DIERR_INVALIDPARAM
, "GetEffectInfo returned %#x\n", hr
);
4378 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
);
4379 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_NULL
);
4380 ok( hr
== DIERR_DEVICENOTREG
, "GetEffectInfo returned %#x\n", hr
);
4381 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
4382 ok( hr
== DIERR_DEVICENOTREG
, "GetEffectInfo returned %#x\n", hr
);
4384 hr
= IDirectInputDevice8_SetDataFormat( device
, NULL
);
4385 ok( hr
== E_POINTER
, "SetDataFormat returned: %#x\n", hr
);
4386 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4387 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4388 dataformat
.dwSize
= sizeof(DIDATAFORMAT
);
4389 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4390 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4391 dataformat
.dwObjSize
= sizeof(DIOBJECTDATAFORMAT
);
4392 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4393 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4394 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
4395 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4397 hr
= IDirectInputDevice8_GetObjectInfo( device
, &objinst
, DIJOFS_Y
, DIPH_BYOFFSET
);
4398 ok( hr
== DI_OK
, "GetObjectInfo returned: %#x\n", hr
);
4400 check_member( objinst
, expect_objects
[3], "%u", dwSize
);
4401 check_member_guid( objinst
, expect_objects
[3], guidType
);
4402 check_member( objinst
, expect_objects
[3], "%#x", dwOfs
);
4403 check_member( objinst
, expect_objects
[3], "%#x", dwType
);
4404 check_member( objinst
, expect_objects
[3], "%#x", dwFlags
);
4405 if (!localized
) check_member_wstr( objinst
, expect_objects
[3], tszName
);
4406 check_member( objinst
, expect_objects
[3], "%u", dwFFMaxForce
);
4407 check_member( objinst
, expect_objects
[3], "%u", dwFFForceResolution
);
4408 check_member( objinst
, expect_objects
[3], "%u", wCollectionNumber
);
4409 check_member( objinst
, expect_objects
[3], "%u", wDesignatorIndex
);
4410 check_member( objinst
, expect_objects
[3], "%#04x", wUsagePage
);
4411 check_member( objinst
, expect_objects
[3], "%#04x", wUsage
);
4412 check_member( objinst
, expect_objects
[3], "%#04x", dwDimension
);
4413 check_member( objinst
, expect_objects
[3], "%#04x", wExponent
);
4414 check_member( objinst
, expect_objects
[3], "%u", wReportId
);
4416 hr
= IDirectInputDevice8_SetEventNotification( device
, (HANDLE
)0xdeadbeef );
4418 ok( hr
== E_HANDLE
, "SetEventNotification returned: %#x\n", hr
);
4419 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
4420 ok( event
!= NULL
, "CreateEventW failed, last error %u\n", GetLastError() );
4421 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
4422 ok( hr
== DI_OK
, "SetEventNotification returned: %#x\n", hr
);
4424 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
4425 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
4426 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
4427 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
4429 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, 0 );
4430 ok( hr
== DIERR_INVALIDPARAM
, "SetCooperativeLevel returned: %#x\n", hr
);
4431 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
);
4432 ok( hr
== DIERR_INVALIDPARAM
, "SetCooperativeLevel returned: %#x\n", hr
);
4433 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
4434 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#x\n", hr
);
4435 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
4436 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#x\n", hr
);
4437 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
4438 ok( hr
== E_HANDLE
, "SetCooperativeLevel returned: %#x\n", hr
);
4440 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
4441 NULL
, NULL
, NULL
, NULL
);
4442 SetForegroundWindow( hwnd
);
4444 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_NONEXCLUSIVE
);
4445 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4446 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
4447 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4448 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
4449 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4451 hr
= IDirectInputDevice8_Unacquire( device
);
4452 ok( hr
== DI_NOEFFECT
, "Unacquire returned: %#x\n", hr
);
4453 hr
= IDirectInputDevice8_Acquire( device
);
4454 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
4455 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_FOREGROUND
| DISCL_EXCLUSIVE
);
4456 ok( hr
== DIERR_ACQUIRED
, "SetCooperativeLevel returned: %#x\n", hr
);
4457 hr
= IDirectInputDevice8_Unacquire( device
);
4458 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4460 DestroyWindow( hwnd
);
4462 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, NULL
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
4463 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
4465 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4466 ok( hr
== DIERR_NOTACQUIRED
, "GetDeviceState returned: %#x\n", hr
);
4468 hr
= IDirectInputDevice8_Poll( device
);
4469 ok( hr
== DIERR_NOTACQUIRED
, "Poll returned: %#x\n", hr
);
4471 hr
= IDirectInputDevice8_Acquire( device
);
4472 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
4474 hr
= IDirectInputDevice8_Poll( device
);
4475 ok( hr
== DI_NOEFFECT
, "Poll returned: %#x\n", hr
);
4477 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
) + 1, &state
);
4478 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceState returned: %#x\n", hr
);
4480 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
4482 winetest_push_context( "state[%d]", i
);
4483 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4484 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4485 check_member( state
, expect_state
[i
], "%d", lX
);
4486 check_member( state
, expect_state
[i
], "%d", lY
);
4487 check_member( state
, expect_state
[i
], "%d", lZ
);
4488 check_member( state
, expect_state
[i
], "%d", lRx
);
4489 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[0] );
4490 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[1] );
4491 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
4492 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
4493 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
4495 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
4497 res
= WaitForSingleObject( event
, 100 );
4498 if (i
== 0 || i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
4499 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4500 ResetEvent( event
);
4501 winetest_pop_context();
4504 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4505 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4506 winetest_push_context( "state[%d]", i
);
4507 check_member( state
, expect_state
[i
], "%d", lX
);
4508 check_member( state
, expect_state
[i
], "%d", lY
);
4509 check_member( state
, expect_state
[i
], "%d", lZ
);
4510 check_member( state
, expect_state
[i
], "%d", lRx
);
4511 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[0] );
4512 check_member( state
, expect_state
[i
], "%#x", rgdwPOV
[1] );
4513 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[0] );
4514 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[1] );
4515 check_member( state
, expect_state
[i
], "%#x", rgbButtons
[2] );
4516 winetest_pop_context();
4519 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
) - 1, objdata
, &res
, DIGDD_PEEK
);
4521 ok( hr
== DIERR_INVALIDPARAM
, "GetDeviceData returned %#x\n", hr
);
4523 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4524 ok( hr
== DIERR_NOTBUFFERED
, "GetDeviceData returned %#x\n", hr
);
4526 hr
= IDirectInputDevice8_Unacquire( device
);
4527 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4528 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4529 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4530 prop_dword
.dwData
= 1;
4531 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4532 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4533 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4534 prop_dword
.diph
.dwObj
= 0;
4535 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4536 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4537 hr
= IDirectInputDevice8_Acquire( device
);
4538 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4541 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4542 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4543 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4545 send_hid_input( file
, &injected_input
[0], sizeof(*injected_input
) );
4546 res
= WaitForSingleObject( event
, 100 );
4547 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4548 ResetEvent( event
);
4551 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4552 ok( hr
== DI_BUFFEROVERFLOW
, "GetDeviceData returned %#x\n", hr
);
4553 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4555 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4557 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4558 ok( res
== 0, "got %u expected %u\n", res
, 0 );
4560 hr
= IDirectInputDevice8_Unacquire( device
);
4561 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4562 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4563 prop_dword
.diph
.dwObj
= 0;
4564 prop_dword
.dwData
= 10;
4565 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4566 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4567 hr
= IDirectInputDevice8_Acquire( device
);
4568 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4570 send_hid_input( file
, &injected_input
[1], sizeof(*injected_input
) );
4571 res
= WaitForSingleObject( event
, 100 );
4572 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4573 ResetEvent( event
);
4576 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, DIGDD_PEEK
);
4577 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4578 ok( res
== 1, "got %u expected %u\n", res
, 1 );
4579 check_member( objdata
[0], expect_objdata
[0], "%#x", dwOfs
);
4580 check_member( objdata
[0], expect_objdata
[0], "%#x", dwData
);
4581 ok( objdata
[0].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[0].uAppData
, (void *)-1 );
4583 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4584 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4585 ok( res
== 4, "got %u expected %u\n", res
, 4 );
4586 for (i
= 0; i
< 4; ++i
)
4588 winetest_push_context( "objdata[%d]", i
);
4589 check_member( objdata
[i
], expect_objdata
[1 + i
], "%#x", dwOfs
);
4590 check_member( objdata
[i
], expect_objdata
[1 + i
], "%#x", dwData
);
4591 ok( objdata
[i
].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[i
].uAppData
, (void *)-1 );
4592 winetest_pop_context();
4595 send_hid_input( file
, &injected_input
[2], sizeof(*injected_input
) );
4596 res
= WaitForSingleObject( event
, 100 );
4597 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4598 ResetEvent( event
);
4599 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4600 res
= WaitForSingleObject( event
, 100 );
4601 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4602 ResetEvent( event
);
4605 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4606 ok( hr
== DI_BUFFEROVERFLOW
, "GetDeviceData returned %#x\n", hr
);
4607 ok( res
== 1, "got %u expected %u\n", res
, 1 );
4609 check_member( objdata
[0], expect_objdata
[5], "%#x", dwOfs
);
4611 check_member( objdata
[0], expect_objdata
[5], "%#x", dwData
);
4612 ok( objdata
[0].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[0].uAppData
, (void *)-1 );
4613 res
= ARRAY_SIZE(objdata
);
4614 hr
= IDirectInputDevice8_GetDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
4615 ok( hr
== DI_OK
, "GetDeviceData returned %#x\n", hr
);
4616 ok( res
== 8, "got %u expected %u\n", res
, 8 );
4617 for (i
= 0; i
< 8; ++i
)
4619 winetest_push_context( "objdata[%d]", i
);
4621 check_member( objdata
[i
], expect_objdata
[6 + i
], "%#x", dwOfs
);
4622 todo_wine_if( i
== 1 || i
== 2 || i
== 6 )
4623 check_member( objdata
[i
], expect_objdata
[6 + i
], "%#x", dwData
);
4624 ok( objdata
[i
].uAppData
== -1, "got %p, expected %p\n", (void *)objdata
[i
].uAppData
, (void *)-1 );
4625 winetest_pop_context();
4628 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
4629 res
= WaitForSingleObject( event
, 100 );
4630 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4631 ResetEvent( event
);
4633 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4634 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4635 check_member( state
, expect_state
[3], "%d", lX
);
4636 check_member( state
, expect_state
[3], "%d", lY
);
4637 check_member( state
, expect_state
[3], "%d", lZ
);
4638 check_member( state
, expect_state
[3], "%d", lRx
);
4639 check_member( state
, expect_state
[3], "%d", rgdwPOV
[0] );
4640 check_member( state
, expect_state
[3], "%d", rgdwPOV
[1] );
4641 check_member( state
, expect_state
[3], "%#x", rgbButtons
[0] );
4642 check_member( state
, expect_state
[3], "%#x", rgbButtons
[1] );
4643 check_member( state
, expect_state
[3], "%#x", rgbButtons
[2] );
4645 hr
= IDirectInputDevice8_Unacquire( device
);
4646 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4648 dataformat
.dwSize
= sizeof(DIDATAFORMAT
);
4649 dataformat
.dwObjSize
= sizeof(DIOBJECTDATAFORMAT
);
4650 dataformat
.dwFlags
= DIDF_ABSAXIS
;
4651 dataformat
.dwDataSize
= sizeof(buffer
);
4652 dataformat
.dwNumObjs
= 0;
4653 dataformat
.rgodf
= objdataformat
;
4654 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4655 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4657 dataformat
.dwNumObjs
= 1;
4658 dataformat
.dwDataSize
= 8;
4659 objdataformat
[0].pguid
= NULL
;
4660 objdataformat
[0].dwOfs
= 2;
4661 objdataformat
[0].dwType
= DIDFT_AXIS
|DIDFT_ANYINSTANCE
;
4662 objdataformat
[0].dwFlags
= 0;
4663 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4665 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4666 objdataformat
[0].dwOfs
= 4;
4667 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4668 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4669 dataformat
.dwDataSize
= 10;
4670 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4672 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4673 dataformat
.dwDataSize
= 8;
4674 objdataformat
[0].dwOfs
= 2;
4675 objdataformat
[0].dwType
= DIDFT_OPTIONAL
|0xff|DIDFT_ANYINSTANCE
;
4676 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4678 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4680 dataformat
.dwNumObjs
= 2;
4681 dataformat
.dwDataSize
= 5;
4682 objdataformat
[0].pguid
= NULL
;
4683 objdataformat
[0].dwOfs
= 4;
4684 objdataformat
[0].dwType
= DIDFT_BUTTON
|DIDFT_ANYINSTANCE
;
4685 objdataformat
[0].dwFlags
= 0;
4686 objdataformat
[1].pguid
= NULL
;
4687 objdataformat
[1].dwOfs
= 0;
4688 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4689 objdataformat
[1].dwFlags
= 0;
4690 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4692 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4693 dataformat
.dwDataSize
= 8;
4694 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4695 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4697 dataformat
.dwNumObjs
= 4;
4698 dataformat
.dwDataSize
= 12;
4699 objdataformat
[0].pguid
= NULL
;
4700 objdataformat
[0].dwOfs
= 0;
4701 objdataformat
[0].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4702 objdataformat
[0].dwFlags
= 0;
4703 objdataformat
[1].pguid
= NULL
;
4704 objdataformat
[1].dwOfs
= 0;
4705 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4706 objdataformat
[1].dwFlags
= 0;
4707 objdataformat
[2].pguid
= &GUID_ZAxis
;
4708 objdataformat
[2].dwOfs
= 8;
4709 objdataformat
[2].dwType
= 0xff|DIDFT_ANYINSTANCE
;
4710 objdataformat
[2].dwFlags
= 0;
4711 objdataformat
[3].pguid
= &GUID_POV
;
4712 objdataformat
[3].dwOfs
= 0;
4713 objdataformat
[3].dwType
= 0xff|DIDFT_ANYINSTANCE
;
4714 objdataformat
[3].dwFlags
= 0;
4715 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4716 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4717 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 12 );
4718 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4719 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4720 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0xff );
4721 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4722 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4723 objdataformat
[1].dwType
= DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 1 );
4724 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4725 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4726 objdataformat
[1].pguid
= &GUID_RzAxis
;
4727 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4728 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4729 objdataformat
[1].pguid
= &GUID_Unknown
;
4730 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4731 ok( hr
== DIERR_INVALIDPARAM
, "SetDataFormat returned: %#x\n", hr
);
4732 objdataformat
[1].pguid
= &GUID_YAxis
;
4733 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4734 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4735 objdataformat
[1].pguid
= NULL
;
4736 objdataformat
[1].dwType
= DIDFT_OPTIONAL
|DIDFT_AXIS
|DIDFT_MAKEINSTANCE( 0 );
4737 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4738 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4740 dataformat
.dwNumObjs
= 0;
4741 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4742 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4743 hr
= IDirectInputDevice8_Acquire( device
);
4744 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4746 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4747 res
= WaitForSingleObject( event
, 100 );
4749 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject failed\n" );
4750 ResetEvent( event
);
4752 hr
= IDirectInputDevice8_GetDeviceState( device
, dataformat
.dwDataSize
, buffer
);
4753 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4754 hr
= IDirectInputDevice8_Unacquire( device
);
4755 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4757 dataformat
.dwNumObjs
= 4;
4758 hr
= IDirectInputDevice8_SetDataFormat( device
, &dataformat
);
4759 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4760 hr
= IDirectInputDevice8_Acquire( device
);
4761 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4763 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4764 res
= WaitForSingleObject( event
, 100 );
4766 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4767 ResetEvent( event
);
4768 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
4769 res
= WaitForSingleObject( event
, 100 );
4770 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4771 ResetEvent( event
);
4773 hr
= IDirectInputDevice8_GetDeviceState( device
, dataformat
.dwDataSize
, buffer
);
4774 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4775 ok( ((ULONG
*)buffer
)[0] == 0x512b, "got %#x, expected %#x\n", ((ULONG
*)buffer
)[0], 0x512b );
4776 ok( ((ULONG
*)buffer
)[1] == 0, "got %#x, expected %#x\n", ((ULONG
*)buffer
)[1], 0 );
4777 ok( ((ULONG
*)buffer
)[2] == 0x7fff, "got %#x, expected %#x\n", ((ULONG
*)buffer
)[2], 0x7fff );
4778 hr
= IDirectInputDevice8_Unacquire( device
);
4779 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4781 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
4782 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
4783 hr
= IDirectInputDevice8_Acquire( device
);
4784 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4786 send_hid_input( file
, &injected_input
[4], sizeof(*injected_input
) );
4787 res
= WaitForSingleObject( event
, 100 );
4788 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4789 ResetEvent( event
);
4790 send_hid_input( file
, &injected_input
[3], sizeof(*injected_input
) );
4791 res
= WaitForSingleObject( event
, 100 );
4792 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
4793 ResetEvent( event
);
4795 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4796 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4797 check_member( state
, expect_state
[3], "%d", lX
);
4798 check_member( state
, expect_state
[3], "%d", lY
);
4799 check_member( state
, expect_state
[3], "%d", lZ
);
4800 check_member( state
, expect_state
[3], "%d", lRx
);
4801 check_member( state
, expect_state
[3], "%d", rgdwPOV
[0] );
4802 check_member( state
, expect_state
[3], "%d", rgdwPOV
[1] );
4803 check_member( state
, expect_state
[3], "%#x", rgbButtons
[0] );
4804 check_member( state
, expect_state
[3], "%#x", rgbButtons
[1] );
4805 check_member( state
, expect_state
[3], "%#x", rgbButtons
[2] );
4807 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
4808 prop_range
.diph
.dwObj
= 0;
4809 prop_range
.lMin
= 1000;
4810 prop_range
.lMax
= 51000;
4811 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4812 ok( hr
== DI_OK
, "SetProperty DIPROP_RANGE returned %#x\n", hr
);
4813 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4814 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4815 prop_range
.lMin
= -4000;
4816 prop_range
.lMax
= -14000;
4817 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4818 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_RANGE returned %#x\n", hr
);
4819 prop_range
.lMin
= -14000;
4820 prop_range
.lMax
= -4000;
4821 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4822 ok( hr
== DI_OK
, "SetProperty DIPROP_RANGE returned %#x\n", hr
);
4823 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4824 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4825 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4826 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4828 hr
= IDirectInputDevice8_Unacquire( device
);
4829 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4830 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_LOGICALRANGE
, &prop_range
.diph
);
4831 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_LOGICALRANGE returned %#x\n", hr
);
4832 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PHYSICALRANGE
, &prop_range
.diph
);
4833 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr
);
4834 hr
= IDirectInputDevice8_Acquire( device
);
4835 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
4837 prop_range
.diph
.dwHow
= DIPH_DEVICE
;
4838 prop_range
.diph
.dwObj
= 0;
4839 prop_range
.lMin
= 0xdeadbeef;
4840 prop_range
.lMax
= 0xdeadbeef;
4841 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4842 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4843 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4844 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4845 prop_range
.lMin
= 0xdeadbeef;
4846 prop_range
.lMax
= 0xdeadbeef;
4847 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4848 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4849 ok( prop_range
.lMin
== -14000, "got %d expected %d\n", prop_range
.lMin
, -14000 );
4850 ok( prop_range
.lMax
== -4000, "got %d expected %d\n", prop_range
.lMax
, -4000 );
4851 prop_range
.diph
.dwHow
= DIPH_BYUSAGE
;
4852 prop_range
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
4853 prop_range
.lMin
= 0xdeadbeef;
4854 prop_range
.lMax
= 0xdeadbeef;
4855 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_RANGE
, &prop_range
.diph
);
4856 ok( hr
== DI_OK
, "GetProperty DIPROP_RANGE returned %#x\n", hr
);
4857 ok( prop_range
.lMin
== 1000, "got %d expected %d\n", prop_range
.lMin
, 1000 );
4858 ok( prop_range
.lMax
== 51000, "got %d expected %d\n", prop_range
.lMax
, 51000 );
4860 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4861 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4862 check_member( state
, expect_state_abs
[1], "%d", lX
);
4863 check_member( state
, expect_state_abs
[1], "%d", lY
);
4864 check_member( state
, expect_state_abs
[1], "%d", lZ
);
4865 check_member( state
, expect_state_abs
[1], "%d", lRx
);
4866 check_member( state
, expect_state_abs
[1], "%d", rgdwPOV
[0] );
4867 check_member( state
, expect_state_abs
[1], "%d", rgdwPOV
[1] );
4868 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[0] );
4869 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[1] );
4870 check_member( state
, expect_state_abs
[1], "%#x", rgbButtons
[2] );
4872 hr
= IDirectInputDevice8_SetProperty( device
, NULL
, NULL
);
4873 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4874 hr
= IDirectInputDevice8_SetProperty( device
, &GUID_NULL
, NULL
);
4875 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4876 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, NULL
);
4877 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4878 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_string
.diph
);
4879 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty returned %#x\n", hr
);
4881 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4882 prop_dword
.diph
.dwObj
= 0;
4883 prop_dword
.dwData
= 0xdeadbeef;
4884 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_VIDPID
, &prop_dword
.diph
);
4885 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_VIDPID returned %#x\n", hr
);
4886 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
4887 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
4889 prop_string
.diph
.dwHow
= DIPH_DEVICE
;
4890 prop_string
.diph
.dwObj
= 0;
4891 wcscpy( prop_string
.wsz
, L
"instance name" );
4892 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_INSTANCENAME
, &prop_string
.diph
);
4893 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_INSTANCENAME returned %#x\n", hr
);
4895 wcscpy( prop_string
.wsz
, L
"product name" );
4896 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4898 ok( hr
== DI_OK
, "SetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4899 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_PRODUCTNAME
, &prop_string
.diph
);
4900 ok( hr
== DI_OK
, "GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr
);
4902 ok( !wcscmp( prop_string
.wsz
, expect_devinst
.tszProductName
), "got product %s\n",
4903 debugstr_w(prop_string
.wsz
) );
4905 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_TYPENAME
, &prop_string
.diph
);
4906 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_TYPENAME returned %#x\n", hr
);
4907 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_USERNAME
, &prop_string
.diph
);
4908 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_USERNAME returned %#x\n", hr
);
4909 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
4910 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_FFLOAD returned %#x\n", hr
);
4911 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_GRANULARITY
, &prop_dword
.diph
);
4912 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_GRANULARITY returned %#x\n", hr
);
4914 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
4916 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
4917 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
4918 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
4919 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
4920 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
4921 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
4922 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
4923 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
4924 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4925 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
4927 ok( hr
== DIERR_ACQUIRED
, "SetProperty DIPROP_APPDATA returned %#x\n", hr
);
4929 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
4930 prop_dword
.diph
.dwObj
= 0;
4931 prop_dword
.dwData
= 10001;
4932 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4933 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4934 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4935 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4936 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4937 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4938 prop_dword
.dwData
= 1000;
4939 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4940 ok( hr
== DI_OK
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4941 prop_dword
.dwData
= 6000;
4942 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4943 ok( hr
== DI_OK
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4944 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_COOKED
;
4945 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4946 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4948 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4949 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4950 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4951 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4952 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
4953 ok( hr
== DIERR_UNSUPPORTED
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
4955 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4956 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4957 prop_dword
.dwData
= 2000;
4958 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4959 ok( hr
== DI_OK
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4960 ok( prop_dword
.dwData
== 2000, "got %u expected %u\n", prop_dword
.dwData
, 2000 );
4961 prop_dword
.dwData
= 7000;
4962 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4963 ok( hr
== DI_OK
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
4965 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4966 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
4967 prop_dword
.dwData
= 0xdeadbeef;
4968 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4969 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4970 ok( prop_dword
.dwData
== 2000, "got %u expected %u\n", prop_dword
.dwData
, 2000 );
4971 prop_dword
.dwData
= 0xdeadbeef;
4972 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4973 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4974 ok( prop_dword
.dwData
== 7000, "got %u expected %u\n", prop_dword
.dwData
, 7000 );
4976 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
4977 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_Y
, HID_USAGE_PAGE_GENERIC
);
4978 prop_dword
.dwData
= 0xdeadbeef;
4979 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
4980 ok( hr
== DI_OK
, "GetProperty DIPROP_DEADZONE returned %#x\n", hr
);
4981 ok( prop_dword
.dwData
== 1000, "got %u expected %u\n", prop_dword
.dwData
, 1000 );
4982 prop_dword
.dwData
= 0xdeadbeef;
4983 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
4984 ok( hr
== DI_OK
, "GetProperty DIPROP_SATURATION returned %#x\n", hr
);
4985 ok( prop_dword
.dwData
== 6000, "got %u expected %u\n", prop_dword
.dwData
, 6000 );
4987 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
4989 winetest_push_context( "state[%d]", i
);
4990 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
4991 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
4992 if (broken( state
.lX
== -10750 )) win_skip( "Ignoring 32-bit rounding\n" );
4995 check_member( state
, expect_state_abs
[i
], "%d", lX
);
4996 check_member( state
, expect_state_abs
[i
], "%d", lY
);
4998 check_member( state
, expect_state_abs
[i
], "%d", lZ
);
4999 check_member( state
, expect_state_abs
[i
], "%d", lRx
);
5000 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[0] );
5001 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[1] );
5002 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
5003 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
5004 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
5006 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
5008 res
= WaitForSingleObject( event
, 100 );
5009 if (i
== 0 || i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
5010 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
5011 ResetEvent( event
);
5012 winetest_pop_context();
5015 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5016 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5017 winetest_push_context( "state[%d]", i
);
5018 check_member( state
, expect_state_abs
[i
], "%d", lX
);
5019 check_member( state
, expect_state_abs
[i
], "%d", lY
);
5020 check_member( state
, expect_state_abs
[i
], "%d", lZ
);
5021 check_member( state
, expect_state_abs
[i
], "%d", lRx
);
5022 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[0] );
5023 check_member( state
, expect_state_abs
[i
], "%d", rgdwPOV
[1] );
5024 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[0] );
5025 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[1] );
5026 check_member( state
, expect_state_abs
[i
], "%#x", rgbButtons
[2] );
5027 winetest_pop_context();
5029 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
5030 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
5031 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_RAW
;
5032 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
5033 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
5034 prop_dword
.dwData
= 0xdeadbeef;
5035 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
5036 ok( hr
== DI_OK
, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
5037 ok( prop_dword
.dwData
== DIPROPCALIBRATIONMODE_RAW
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPCALIBRATIONMODE_RAW
);
5039 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5040 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5041 winetest_push_context( "state[%d]", i
);
5043 ok( state
.lX
== 15, "got lX %d, expected %d\n" , state
.lX
, 15 );
5044 check_member( state
, expect_state_abs
[0], "%d", lY
);
5045 check_member( state
, expect_state_abs
[0], "%d", lZ
);
5046 check_member( state
, expect_state_abs
[0], "%d", lRx
);
5047 check_member( state
, expect_state_abs
[0], "%d", rgdwPOV
[0] );
5048 check_member( state
, expect_state_abs
[0], "%d", rgdwPOV
[1] );
5049 winetest_pop_context();
5051 prop_dword
.dwData
= DIPROPCALIBRATIONMODE_COOKED
;
5052 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATIONMODE
, &prop_dword
.diph
);
5053 ok( hr
== DI_OK
, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr
);
5055 send_hid_input( file
, &injected_input
[ARRAY_SIZE(injected_input
) - 1], sizeof(*injected_input
) );
5056 res
= WaitForSingleObject( event
, 100 );
5057 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
5059 hr
= IDirectInputDevice8_Unacquire( device
);
5060 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5062 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
5063 prop_dword
.diph
.dwObj
= 0;
5064 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_JOYSTICKID
, &prop_dword
.diph
);
5065 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_JOYSTICKID returned %#x\n", hr
);
5066 prop_dword
.dwData
= 0x1000;
5067 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
5068 ok( hr
== DI_OK
, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
5069 prop_dword
.dwData
= 0xdeadbeef;
5070 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
5071 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
5072 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
5073 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
5074 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
5075 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
5076 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
5077 prop_pointer
.uData
= 0xfeedcafe;
5078 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
5079 ok( hr
== DI_OK
, "SetProperty DIPROP_APPDATA returned %#x\n", hr
);
5081 prop_dword
.dwData
= 0xdeadbeef;
5082 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
5083 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
5084 prop_dword
.dwData
= DIPROPAXISMODE_REL
;
5085 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
5086 ok( hr
== DI_OK
, "SetProperty DIPROP_AXISMODE returned %#x\n", hr
);
5088 hr
= IDirectInputDevice8_Acquire( device
);
5089 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5091 prop_dword
.dwData
= 0xdeadbeef;
5092 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_AXISMODE
, &prop_dword
.diph
);
5094 ok( hr
== DI_OK
, "GetProperty DIPROP_AXISMODE returned %#x\n", hr
);
5096 ok( prop_dword
.dwData
== DIPROPAXISMODE_REL
, "got %u expected %u\n", prop_dword
.dwData
, DIPROPAXISMODE_REL
);
5098 prop_dword
.dwData
= 0xdeadbeef;
5099 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_BUFFERSIZE
, &prop_dword
.diph
);
5100 ok( hr
== DI_OK
, "GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr
);
5101 ok( prop_dword
.dwData
== 0x1000, "got %#x expected %#x\n", prop_dword
.dwData
, 0x1000 );
5103 prop_pointer
.diph
.dwHow
= DIPH_BYUSAGE
;
5104 prop_pointer
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
5105 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_APPDATA
, &prop_pointer
.diph
);
5107 ok( hr
== DI_OK
, "GetProperty DIPROP_APPDATA returned %#x\n", hr
);
5108 ok( prop_pointer
.uData
== 0xfeedcafe, "got %p expected %p\n", (void *)prop_pointer
.uData
, (void *)0xfeedcafe );
5110 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
5111 prop_dword
.diph
.dwObj
= 0;
5112 prop_dword
.dwData
= 0xdeadbeef;
5113 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
5114 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
5115 prop_dword
.dwData
= 1000;
5116 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
5117 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
5119 prop_dword
.dwData
= 0xdeadbeef;
5120 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_CALIBRATION
, &prop_dword
.diph
);
5122 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_CALIBRATION returned %#x\n", hr
);
5123 prop_dword
.dwData
= 0xdeadbeef;
5124 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_DEADZONE
, &prop_dword
.diph
);
5125 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_DEADZONE returned %#x\n", hr
);
5126 prop_dword
.dwData
= 0xdeadbeef;
5127 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_SATURATION
, &prop_dword
.diph
);
5128 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_SATURATION returned %#x\n", hr
);
5130 for (i
= 0; i
< ARRAY_SIZE(injected_input
); ++i
)
5132 winetest_push_context( "state[%d]", i
);
5133 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5134 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5136 check_member( state
, expect_state_rel
[i
], "%d", lX
);
5138 check_member( state
, expect_state_rel
[i
], "%d", lY
);
5140 check_member( state
, expect_state_rel
[i
], "%d", lZ
);
5141 check_member( state
, expect_state_rel
[i
], "%d", lRx
);
5142 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[0] );
5143 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[1] );
5144 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
5145 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
5146 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
5148 send_hid_input( file
, &injected_input
[i
], sizeof(*injected_input
) );
5150 res
= WaitForSingleObject( event
, 100 );
5151 if (i
== 3) ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject succeeded\n" );
5152 else ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n" );
5153 ResetEvent( event
);
5154 winetest_pop_context();
5157 hr
= IDirectInputDevice8_GetDeviceState( device
, sizeof(DIJOYSTATE2
), &state
);
5158 ok( hr
== DI_OK
, "GetDeviceState returned: %#x\n", hr
);
5159 winetest_push_context( "state[%d]", i
);
5161 check_member( state
, expect_state_rel
[i
], "%d", lX
);
5163 check_member( state
, expect_state_rel
[i
], "%d", lY
);
5165 check_member( state
, expect_state_rel
[i
], "%d", lZ
);
5166 check_member( state
, expect_state_rel
[i
], "%d", lRx
);
5167 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[0] );
5168 check_member( state
, expect_state_rel
[i
], "%d", rgdwPOV
[1] );
5169 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[0] );
5170 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[1] );
5171 check_member( state
, expect_state_rel
[i
], "%#x", rgbButtons
[2] );
5172 winetest_pop_context();
5174 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, NULL
);
5175 ok( hr
== E_POINTER
, "GetForceFeedbackState returned %#x\n", hr
);
5177 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
5178 ok( hr
== DIERR_UNSUPPORTED
, "GetForceFeedbackState returned %#x\n", hr
);
5180 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, 0xdeadbeef );
5181 ok( hr
== DIERR_INVALIDPARAM
, "SendForceFeedbackCommand returned %#x\n", hr
);
5182 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
5183 ok( hr
== DIERR_UNSUPPORTED
, "SendForceFeedbackCommand returned %#x\n", hr
);
5185 objdata
[0].dwOfs
= 0xd;
5186 objdata
[0].dwData
= 0x80;
5188 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0xdeadbeef );
5190 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
5192 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 1 /*DISDD_CONTINUE*/ );
5194 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
5196 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), objdata
, &res
, 0 );
5198 ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
5200 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, NULL
, NULL
);
5201 ok( hr
== E_POINTER
, "CreateEffect returned %#x\n", hr
);
5202 hr
= IDirectInputDevice8_CreateEffect( device
, NULL
, NULL
, &effect
, NULL
);
5203 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5204 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_NULL
, NULL
, &effect
, NULL
);
5205 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5206 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
5207 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5209 hr
= IDirectInputDevice8_Unacquire( device
);
5210 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5212 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
5213 ok( hr
== DIERR_UNSUPPORTED
, "CreateEffect returned %#x\n", hr
);
5215 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, NULL
, effect
, 0 );
5216 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5217 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, effect
, 0xdeadbeef );
5218 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5219 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, (void *)0xdeadbeef, 0 );
5220 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5222 hr
= IDirectInputDevice8_Escape( device
, NULL
);
5224 ok( hr
== E_POINTER
, "Escape returned: %#x\n", hr
);
5225 hr
= IDirectInputDevice8_Escape( device
, &escape
);
5227 ok( hr
== DIERR_INVALIDPARAM
, "Escape returned: %#x\n", hr
);
5228 escape
.dwSize
= sizeof(DIEFFESCAPE
) + 1;
5229 hr
= IDirectInputDevice8_Escape( device
, &escape
);
5231 ok( hr
== DIERR_INVALIDPARAM
, "Escape returned: %#x\n", hr
);
5232 escape
.dwSize
= sizeof(DIEFFESCAPE
);
5233 escape
.dwCommand
= 0;
5234 escape
.lpvInBuffer
= buffer
;
5235 escape
.cbInBuffer
= 10;
5236 escape
.lpvOutBuffer
= buffer
+ 10;
5237 escape
.cbOutBuffer
= 10;
5238 hr
= IDirectInputDevice8_Escape( device
, &escape
);
5240 ok( hr
== DIERR_UNSUPPORTED
, "Escape returned: %#x\n", hr
);
5242 ref
= IDirectInputDevice8_Release( device
);
5243 ok( ref
== 0, "Release returned %d\n", ref
);
5245 CloseHandle( event
);
5246 CloseHandle( file
);
5250 cleanup_registry_keys();
5251 SetCurrentDirectoryW( cwd
);
5256 const BYTE
*report_desc_buf
;
5257 ULONG report_desc_len
;
5261 static BOOL
test_device_types( DWORD version
)
5263 #include "psh_hid_macros.h"
5264 static const unsigned char unknown_desc
[] =
5266 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5267 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5268 COLLECTION(1, Application
),
5269 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5270 COLLECTION(1, Physical
),
5271 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5272 USAGE_MINIMUM(1, 1),
5273 USAGE_MAXIMUM(1, 6),
5274 LOGICAL_MINIMUM(1, 0),
5275 LOGICAL_MAXIMUM(1, 1),
5276 PHYSICAL_MINIMUM(1, 0),
5277 PHYSICAL_MAXIMUM(1, 1),
5280 INPUT(1, Data
|Var
|Abs
),
5284 static const unsigned char limited_desc
[] =
5286 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5287 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5288 COLLECTION(1, Application
),
5289 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5290 COLLECTION(1, Physical
),
5291 USAGE(1, HID_USAGE_GENERIC_X
),
5292 USAGE(1, HID_USAGE_GENERIC_Y
),
5293 LOGICAL_MINIMUM(1, 0),
5294 LOGICAL_MAXIMUM(1, 127),
5295 PHYSICAL_MINIMUM(1, 0),
5296 PHYSICAL_MAXIMUM(1, 127),
5299 INPUT(1, Data
|Var
|Abs
),
5301 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5302 USAGE_MINIMUM(1, 1),
5303 USAGE_MAXIMUM(1, 6),
5304 LOGICAL_MINIMUM(1, 0),
5305 LOGICAL_MAXIMUM(1, 1),
5306 PHYSICAL_MINIMUM(1, 0),
5307 PHYSICAL_MAXIMUM(1, 1),
5310 INPUT(1, Data
|Var
|Abs
),
5314 static const unsigned char gamepad_desc
[] =
5316 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5317 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
5318 COLLECTION(1, Application
),
5319 USAGE(1, HID_USAGE_GENERIC_GAMEPAD
),
5320 COLLECTION(1, Physical
),
5321 USAGE(1, HID_USAGE_GENERIC_X
),
5322 USAGE(1, HID_USAGE_GENERIC_Y
),
5323 LOGICAL_MINIMUM(1, 0),
5324 LOGICAL_MAXIMUM(1, 127),
5325 PHYSICAL_MINIMUM(1, 0),
5326 PHYSICAL_MAXIMUM(1, 127),
5329 INPUT(1, Data
|Var
|Abs
),
5331 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5332 USAGE_MINIMUM(1, 1),
5333 USAGE_MAXIMUM(1, 6),
5334 LOGICAL_MINIMUM(1, 0),
5335 LOGICAL_MAXIMUM(1, 1),
5336 PHYSICAL_MINIMUM(1, 0),
5337 PHYSICAL_MAXIMUM(1, 1),
5340 INPUT(1, Data
|Var
|Abs
),
5344 static const unsigned char joystick_desc
[] =
5346 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
5347 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5348 COLLECTION(1, Application
),
5349 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
5350 COLLECTION(1, Physical
),
5351 USAGE(1, HID_USAGE_GENERIC_X
),
5352 USAGE(1, HID_USAGE_GENERIC_Y
),
5353 USAGE(1, HID_USAGE_GENERIC_Z
),
5354 LOGICAL_MINIMUM(1, 0),
5355 LOGICAL_MAXIMUM(1, 127),
5356 PHYSICAL_MINIMUM(1, 0),
5357 PHYSICAL_MAXIMUM(1, 127),
5360 INPUT(1, Data
|Var
|Abs
),
5362 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
5363 LOGICAL_MINIMUM(1, 1),
5364 LOGICAL_MAXIMUM(1, 8),
5365 PHYSICAL_MINIMUM(1, 0),
5366 PHYSICAL_MAXIMUM(1, 8),
5369 INPUT(1, Data
|Var
|Abs
|Null
),
5371 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
5372 USAGE_MINIMUM(1, 1),
5373 USAGE_MAXIMUM(1, 5),
5374 LOGICAL_MINIMUM(1, 0),
5375 LOGICAL_MAXIMUM(1, 1),
5376 PHYSICAL_MINIMUM(1, 0),
5377 PHYSICAL_MAXIMUM(1, 1),
5380 INPUT(1, Data
|Var
|Abs
),
5384 #include "pop_hid_macros.h"
5386 static struct device_desc device_desc
[] =
5389 .report_desc_buf
= unknown_desc
,
5390 .report_desc_len
= sizeof(unknown_desc
),
5393 .InputReportByteLength
= 1,
5397 .report_desc_buf
= limited_desc
,
5398 .report_desc_len
= sizeof(limited_desc
),
5401 .InputReportByteLength
= 3,
5405 .report_desc_buf
= gamepad_desc
,
5406 .report_desc_len
= sizeof(gamepad_desc
),
5409 .InputReportByteLength
= 3,
5413 .report_desc_buf
= joystick_desc
,
5414 .report_desc_len
= sizeof(joystick_desc
),
5417 .InputReportByteLength
= 5,
5421 const DIDEVCAPS expect_caps
[] =
5424 .dwSize
= sizeof(DIDEVCAPS
),
5425 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5426 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPESUPPLEMENTAL_UNKNOWN
<< 8)|DI8DEVTYPE_SUPPLEMENTAL
5427 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5431 .dwSize
= sizeof(DIDEVCAPS
),
5432 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5433 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_LIMITED
<< 8)|DI8DEVTYPE_JOYSTICK
5434 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5439 .dwSize
= sizeof(DIDEVCAPS
),
5440 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5441 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEGAMEPAD_STANDARD
<< 8)|DI8DEVTYPE_GAMEPAD
5442 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_GAMEPAD
<< 8)|DIDEVTYPE_JOYSTICK
,
5447 .dwSize
= sizeof(DIDEVCAPS
),
5448 .dwFlags
= DIDC_ATTACHED
|DIDC_EMULATED
,
5449 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_STANDARD
<< 8)|DI8DEVTYPE_JOYSTICK
5450 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5457 const DIDEVICEINSTANCEW expect_devinst
[] =
5460 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5461 .guidInstance
= expect_guid_product
,
5462 .guidProduct
= expect_guid_product
,
5463 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPESUPPLEMENTAL_UNKNOWN
<< 8)|DI8DEVTYPE_SUPPLEMENTAL
5464 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5465 .tszInstanceName
= L
"Wine test root driver",
5466 .tszProductName
= L
"Wine test root driver",
5467 .guidFFDriver
= GUID_NULL
,
5468 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5469 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
5472 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5473 .guidInstance
= expect_guid_product
,
5474 .guidProduct
= expect_guid_product
,
5475 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_LIMITED
<< 8)|DI8DEVTYPE_JOYSTICK
5476 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5477 .tszInstanceName
= L
"Wine test root driver",
5478 .tszProductName
= L
"Wine test root driver",
5479 .guidFFDriver
= GUID_NULL
,
5480 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5481 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
5484 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5485 .guidInstance
= expect_guid_product
,
5486 .guidProduct
= expect_guid_product
,
5487 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEGAMEPAD_STANDARD
<< 8)|DI8DEVTYPE_GAMEPAD
5488 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_GAMEPAD
<< 8)|DIDEVTYPE_JOYSTICK
,
5489 .tszInstanceName
= L
"Wine test root driver",
5490 .tszProductName
= L
"Wine test root driver",
5491 .guidFFDriver
= GUID_NULL
,
5492 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5493 .wUsage
= HID_USAGE_GENERIC_GAMEPAD
,
5496 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
5497 .guidInstance
= expect_guid_product
,
5498 .guidProduct
= expect_guid_product
,
5499 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
|(DI8DEVTYPEJOYSTICK_STANDARD
<< 8)|DI8DEVTYPE_JOYSTICK
5500 : DIDEVTYPE_HID
|(DIDEVTYPEJOYSTICK_UNKNOWN
<< 8)|DIDEVTYPE_JOYSTICK
,
5501 .tszInstanceName
= L
"Wine test root driver",
5502 .tszProductName
= L
"Wine test root driver",
5503 .guidFFDriver
= GUID_NULL
,
5504 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
5505 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
5509 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
5510 DIDEVCAPS caps
= {.dwSize
= sizeof(DIDEVCAPS
)};
5511 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
5512 IDirectInputDevice8W
*device
;
5513 BOOL success
= TRUE
;
5517 winetest_push_context( "version %#x", version
);
5519 for (i
= 0; i
< ARRAY_SIZE(device_desc
) && success
; ++i
)
5521 winetest_push_context( "desc[%d]", i
);
5522 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
5523 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
5524 SetCurrentDirectoryW( tempdir
);
5526 cleanup_registry_keys();
5527 if (!dinput_driver_start( device_desc
[i
].report_desc_buf
, device_desc
[i
].report_desc_len
,
5528 &device_desc
[i
].hid_caps
, NULL
, 0 ))
5534 if (FAILED(hr
= create_dinput_device( version
, &devinst
, &device
)))
5540 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
5541 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
5542 check_member( devinst
, expect_devinst
[i
], "%d", dwSize
);
5544 check_member_guid( devinst
, expect_devinst
[i
], guidInstance
);
5545 check_member_guid( devinst
, expect_devinst
[i
], guidProduct
);
5546 todo_wine_if( version
<= 0x700 && i
== 3 )
5547 check_member( devinst
, expect_devinst
[i
], "%#x", dwDevType
);
5549 check_member_wstr( devinst
, expect_devinst
[i
], tszInstanceName
);
5551 check_member_wstr( devinst
, expect_devinst
[i
], tszProductName
);
5552 check_member_guid( devinst
, expect_devinst
[i
], guidFFDriver
);
5553 check_member( devinst
, expect_devinst
[i
], "%04x", wUsagePage
);
5554 check_member( devinst
, expect_devinst
[i
], "%04x", wUsage
);
5556 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
5557 ok( hr
== DI_OK
, "GetCapabilities returned %#x\n", hr
);
5558 check_member( caps
, expect_caps
[i
], "%d", dwSize
);
5559 check_member( caps
, expect_caps
[i
], "%#x", dwFlags
);
5560 todo_wine_if( version
<= 0x700 && i
== 3 )
5561 check_member( caps
, expect_caps
[i
], "%#x", dwDevType
);
5562 check_member( caps
, expect_caps
[i
], "%d", dwAxes
);
5563 check_member( caps
, expect_caps
[i
], "%d", dwButtons
);
5564 check_member( caps
, expect_caps
[i
], "%d", dwPOVs
);
5565 check_member( caps
, expect_caps
[i
], "%d", dwFFSamplePeriod
);
5566 check_member( caps
, expect_caps
[i
], "%d", dwFFMinTimeResolution
);
5567 check_member( caps
, expect_caps
[i
], "%d", dwFirmwareRevision
);
5568 check_member( caps
, expect_caps
[i
], "%d", dwHardwareRevision
);
5569 check_member( caps
, expect_caps
[i
], "%d", dwFFDriverVersion
);
5571 ref
= IDirectInputDevice8_Release( device
);
5572 ok( ref
== 0, "Release returned %d\n", ref
);
5576 cleanup_registry_keys();
5577 SetCurrentDirectoryW( cwd
);
5578 winetest_pop_context();
5581 winetest_pop_context();
5586 static void test_periodic_effect( IDirectInputDevice8W
*device
, HANDLE file
, DWORD version
)
5588 struct hid_expect expect_download
[] =
5592 .code
= IOCTL_HID_WRITE_REPORT
,
5595 .report_buf
= {0x05,0x19},
5599 .code
= IOCTL_HID_WRITE_REPORT
,
5602 .report_buf
= {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
5606 .code
= IOCTL_HID_WRITE_REPORT
,
5609 .report_buf
= {0x03,0x01,0x01,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5611 /* start command when DIEP_START is set */
5613 .code
= IOCTL_HID_WRITE_REPORT
,
5616 .report_buf
= {0x02,0x01,0x01,0x01},
5619 struct hid_expect expect_download_2
[] =
5623 .code
= IOCTL_HID_WRITE_REPORT
,
5626 .report_buf
= {0x05,0x19},
5630 .code
= IOCTL_HID_WRITE_REPORT
,
5633 .report_buf
= {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
5637 .code
= IOCTL_HID_WRITE_REPORT
,
5640 .report_buf
= {0x03,0x01,0x02,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5643 struct hid_expect expect_update
[] =
5647 .code
= IOCTL_HID_WRITE_REPORT
,
5650 .report_buf
= {0x03,0x01,0x02,0x08,0xff,0xff,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5653 struct hid_expect expect_set_envelope
[] =
5657 .code
= IOCTL_HID_WRITE_REPORT
,
5660 .report_buf
= {0x06,0x19,0x4c,0x01,0x00,0x04,0x00},
5663 struct hid_expect expect_start
=
5665 .code
= IOCTL_HID_WRITE_REPORT
,
5668 .report_buf
= {0x02, 0x01, 0x01, 0x01},
5670 struct hid_expect expect_start_solo
=
5672 .code
= IOCTL_HID_WRITE_REPORT
,
5675 .report_buf
= {0x02, 0x01, 0x02, 0x01},
5677 struct hid_expect expect_start_0
=
5679 .code
= IOCTL_HID_WRITE_REPORT
,
5682 .report_buf
= {0x02, 0x01, 0x01, 0x00},
5684 struct hid_expect expect_start_4
=
5686 .code
= IOCTL_HID_WRITE_REPORT
,
5689 .report_buf
= {0x02, 0x01, 0x01, 0x04},
5691 struct hid_expect expect_stop
=
5693 .code
= IOCTL_HID_WRITE_REPORT
,
5696 .report_buf
= {0x02, 0x01, 0x03, 0x00},
5698 struct hid_expect expect_unload
[] =
5701 .code
= IOCTL_HID_WRITE_REPORT
,
5704 .report_buf
= {0x02,0x01,0x03,0x00},
5706 /* device reset, when unloaded from Unacquire */
5708 .code
= IOCTL_HID_WRITE_REPORT
,
5711 .report_buf
= {1,0x01},
5714 struct hid_expect expect_acquire
[] =
5717 .code
= IOCTL_HID_WRITE_REPORT
,
5720 .report_buf
= {1, 0x01},
5723 .code
= IOCTL_HID_WRITE_REPORT
,
5726 .report_buf
= {8, 0x19},
5729 struct hid_expect expect_reset
[] =
5732 .code
= IOCTL_HID_WRITE_REPORT
,
5735 .report_buf
= {1, 0x01},
5738 static const DWORD expect_axes_init
[2] = {0};
5739 const DIEFFECT expect_desc_init
=
5741 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
5742 .dwTriggerButton
= -1,
5743 .rgdwAxes
= (void *)expect_axes_init
,
5745 static const DWORD expect_axes
[3] =
5747 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
5748 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
5749 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
5751 static const LONG expect_directions
[3] =
5757 static const DIENVELOPE expect_envelope
=
5759 .dwSize
= sizeof(DIENVELOPE
),
5760 .dwAttackLevel
= 1000,
5761 .dwAttackTime
= 2000,
5762 .dwFadeLevel
= 3000,
5765 static const DIPERIODIC expect_periodic
=
5767 .dwMagnitude
= 1000,
5772 const DIEFFECT expect_desc
=
5774 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
5775 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
5777 .dwSamplePeriod
= 2000,
5779 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
5780 .dwTriggerRepeatInterval
= 5000,
5782 .rgdwAxes
= (void *)expect_axes
,
5783 .rglDirection
= (void *)expect_directions
,
5784 .lpEnvelope
= (void *)&expect_envelope
,
5785 .cbTypeSpecificParams
= sizeof(DIPERIODIC
),
5786 .lpvTypeSpecificParams
= (void *)&expect_periodic
,
5787 .dwStartDelay
= 6000,
5789 struct check_created_effect_params check_params
= {0};
5790 IDirectInputEffect
*effect
;
5791 DIPERIODIC periodic
= {0};
5792 DIENVELOPE envelope
= {0};
5793 LONG directions
[4] = {0};
5794 DIEFFECT desc
= {0};
5795 DWORD axes
[4] = {0};
5796 ULONG i
, ref
, flags
;
5800 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, NULL
, NULL
);
5801 ok( hr
== E_POINTER
, "CreateEffect returned %#x\n", hr
);
5802 hr
= IDirectInputDevice8_CreateEffect( device
, NULL
, NULL
, &effect
, NULL
);
5803 ok( hr
== E_POINTER
, "CreateEffect returned %#x\n", hr
);
5804 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_NULL
, NULL
, &effect
, NULL
);
5805 ok( hr
== DIERR_DEVICENOTREG
, "CreateEffect returned %#x\n", hr
);
5807 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
5808 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
5809 if (hr
!= DI_OK
) return;
5811 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_no_created_effect_objects
, effect
, 0xdeadbeef );
5812 ok( hr
== DIERR_INVALIDPARAM
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5813 check_params
.expect_effect
= effect
;
5814 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_created_effect_objects
, &check_params
, 0 );
5815 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#x\n", hr
);
5816 ok( check_params
.count
== 1, "got count %u, expected 1\n", check_params
.count
);
5818 hr
= IDirectInputEffect_Initialize( effect
, NULL
, version
, &GUID_Sine
);
5819 ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#x\n", hr
);
5820 hr
= IDirectInputEffect_Initialize( effect
, instance
, 0x800 - (version
- 0x700), &GUID_Sine
);
5821 if (version
== 0x800)
5824 ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#x\n", hr
);
5829 ok( hr
== DIERR_OLDDIRECTINPUTVERSION
, "Initialize returned %#x\n", hr
);
5831 hr
= IDirectInputEffect_Initialize( effect
, instance
, 0, &GUID_Sine
);
5833 ok( hr
== DIERR_NOTINITIALIZED
, "Initialize returned %#x\n", hr
);
5834 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, NULL
);
5835 ok( hr
== E_POINTER
, "Initialize returned %#x\n", hr
);
5837 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_NULL
);
5838 ok( hr
== DIERR_DEVICENOTREG
, "Initialize returned %#x\n", hr
);
5839 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_Sine
);
5840 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
5841 hr
= IDirectInputEffect_Initialize( effect
, instance
, version
, &GUID_Square
);
5842 ok( hr
== DI_OK
, "Initialize returned %#x\n", hr
);
5844 hr
= IDirectInputEffect_GetEffectGuid( effect
, NULL
);
5845 ok( hr
== E_POINTER
, "GetEffectGuid returned %#x\n", hr
);
5846 hr
= IDirectInputEffect_GetEffectGuid( effect
, &guid
);
5847 ok( hr
== DI_OK
, "GetEffectGuid returned %#x\n", hr
);
5848 ok( IsEqualGUID( &guid
, &GUID_Square
), "got guid %s, expected %s\n", debugstr_guid( &guid
),
5849 debugstr_guid( &GUID_Square
) );
5851 hr
= IDirectInputEffect_GetParameters( effect
, NULL
, 0 );
5852 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5853 hr
= IDirectInputEffect_GetParameters( effect
, NULL
, DIEP_DURATION
);
5854 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5855 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5856 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5857 desc
.dwSize
= sizeof(DIEFFECT_DX5
) + 2;
5858 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5859 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5860 desc
.dwSize
= sizeof(DIEFFECT_DX5
);
5861 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5862 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5863 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_STARTDELAY
);
5864 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5865 desc
.dwSize
= sizeof(DIEFFECT_DX6
);
5866 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, 0 );
5867 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5869 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
5870 hr
= IDirectInputDevice8_Unacquire( device
);
5871 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5872 set_hid_expect( file
, NULL
, 0 );
5873 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
5874 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5875 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
5876 hr
= IDirectInputDevice8_Acquire( device
);
5877 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
5878 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
5880 desc
.dwDuration
= 0xdeadbeef;
5881 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
5882 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5883 check_member( desc
, expect_desc_init
, "%u", dwDuration
);
5884 memset( &desc
, 0xcd, sizeof(desc
) );
5885 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
5887 desc
.dwStartDelay
= 0xdeadbeef;
5888 flags
= DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
|
5889 (version
>= 0x700 ? DIEP_STARTDELAY
: 0);
5890 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, flags
);
5891 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5892 check_member( desc
, expect_desc_init
, "%u", dwSamplePeriod
);
5893 check_member( desc
, expect_desc_init
, "%u", dwGain
);
5894 if (version
>= 0x700) check_member( desc
, expect_desc_init
, "%u", dwStartDelay
);
5895 else ok( desc
.dwStartDelay
== 0xdeadbeef, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
5896 check_member( desc
, expect_desc_init
, "%u", dwTriggerRepeatInterval
);
5898 memset( &desc
, 0xcd, sizeof(desc
) );
5899 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
5901 desc
.lpEnvelope
= NULL
;
5902 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
5903 ok( hr
== E_POINTER
, "GetParameters returned %#x\n", hr
);
5904 desc
.lpEnvelope
= &envelope
;
5905 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
5906 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5907 envelope
.dwSize
= sizeof(DIENVELOPE
);
5908 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
5909 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5913 desc
.rgdwAxes
= NULL
;
5914 desc
.rglDirection
= NULL
;
5915 desc
.lpEnvelope
= NULL
;
5916 desc
.cbTypeSpecificParams
= 0;
5917 desc
.lpvTypeSpecificParams
= NULL
;
5918 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
5919 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5920 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
5921 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5922 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
5923 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5924 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
5925 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5926 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5927 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
5928 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5929 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
5930 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
5931 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5932 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5933 desc
.dwFlags
= DIEFF_OBJECTIDS
;
5934 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5935 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5936 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
);
5937 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5938 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
5939 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
);
5940 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5941 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5942 desc
.dwFlags
|= DIEFF_CARTESIAN
;
5943 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5944 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5945 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5946 desc
.dwFlags
|= DIEFF_POLAR
;
5947 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5948 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
5949 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5950 desc
.dwFlags
|= DIEFF_SPHERICAL
;
5951 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
5952 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5953 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5954 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5956 desc
.dwFlags
|= DIEFF_SPHERICAL
;
5958 desc
.rgdwAxes
= axes
;
5959 desc
.rglDirection
= directions
;
5960 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_DIRECTION
);
5961 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5962 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5963 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[0] );
5964 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[1] );
5965 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
5966 ok( desc
.dwFlags
== DIEFF_OBJECTIDS
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_OBJECTIDS
);
5968 desc
.dwFlags
|= DIEFF_SPHERICAL
;
5969 desc
.lpEnvelope
= &envelope
;
5970 desc
.cbTypeSpecificParams
= sizeof(periodic
);
5971 desc
.lpvTypeSpecificParams
= &periodic
;
5972 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
5973 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
5974 check_member( desc
, expect_desc_init
, "%u", dwDuration
);
5975 check_member( desc
, expect_desc_init
, "%u", dwSamplePeriod
);
5976 check_member( desc
, expect_desc_init
, "%u", dwGain
);
5977 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
5978 check_member( desc
, expect_desc_init
, "%u", dwTriggerRepeatInterval
);
5979 check_member( desc
, expect_desc_init
, "%u", cAxes
);
5980 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[0] );
5981 check_member( desc
, expect_desc_init
, "%u", rgdwAxes
[1] );
5982 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
5984 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
5986 check_member( desc
, expect_desc_init
, "%u", cbTypeSpecificParams
);
5987 if (version
>= 0x700) check_member( desc
, expect_desc_init
, "%u", dwStartDelay
);
5988 else ok( desc
.dwStartDelay
== 0xcdcdcdcd, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
5990 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
5991 hr
= IDirectInputDevice8_Unacquire( device
);
5992 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
5993 set_hid_expect( file
, NULL
, 0 );
5994 hr
= IDirectInputEffect_Download( effect
);
5995 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Download returned %#x\n", hr
);
5996 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
5997 hr
= IDirectInputDevice8_Acquire( device
);
5998 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
5999 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
6001 hr
= IDirectInputEffect_Download( effect
);
6002 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6003 hr
= IDirectInputEffect_Unload( effect
);
6004 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6006 hr
= IDirectInputEffect_SetParameters( effect
, NULL
, DIEP_NODOWNLOAD
);
6007 ok( hr
== E_POINTER
, "SetParameters returned %#x\n", hr
);
6008 memset( &desc
, 0, sizeof(desc
) );
6009 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
);
6010 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6011 desc
.dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
);
6012 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
);
6013 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6015 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
6016 hr
= IDirectInputDevice8_Unacquire( device
);
6017 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
6018 set_hid_expect( file
, NULL
, 0 );
6019 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DURATION
);
6020 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6021 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
6022 hr
= IDirectInputDevice8_Acquire( device
);
6023 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6024 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
6026 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DURATION
| DIEP_NODOWNLOAD
);
6027 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6029 desc
.dwTriggerButton
= -1;
6030 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DURATION
);
6031 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6032 check_member( desc
, expect_desc
, "%u", dwDuration
);
6033 check_member( desc
, expect_desc_init
, "%u", dwSamplePeriod
);
6034 check_member( desc
, expect_desc_init
, "%u", dwGain
);
6035 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
6036 check_member( desc
, expect_desc_init
, "%u", dwTriggerRepeatInterval
);
6037 check_member( desc
, expect_desc_init
, "%u", cAxes
);
6038 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
6039 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
6040 check_member( desc
, expect_desc_init
, "%u", cbTypeSpecificParams
);
6041 check_member( desc
, expect_desc_init
, "%u", dwStartDelay
);
6043 hr
= IDirectInputEffect_Download( effect
);
6044 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6045 hr
= IDirectInputEffect_Unload( effect
);
6046 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6048 flags
= DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
| DIEP_NODOWNLOAD
;
6049 if (version
>= 0x700) flags
|= DIEP_STARTDELAY
;
6050 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
);
6051 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6052 desc
.dwDuration
= 0;
6053 flags
= DIEP_DURATION
| DIEP_GAIN
| DIEP_SAMPLEPERIOD
| DIEP_TRIGGERREPEATINTERVAL
;
6054 if (version
>= 0x700) flags
|= DIEP_STARTDELAY
;
6055 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, flags
);
6056 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6057 check_member( desc
, expect_desc
, "%u", dwDuration
);
6058 check_member( desc
, expect_desc
, "%u", dwSamplePeriod
);
6059 check_member( desc
, expect_desc
, "%u", dwGain
);
6060 check_member( desc
, expect_desc_init
, "%#x", dwTriggerButton
);
6061 check_member( desc
, expect_desc
, "%u", dwTriggerRepeatInterval
);
6062 check_member( desc
, expect_desc_init
, "%u", cAxes
);
6063 check_member( desc
, expect_desc_init
, "%p", rglDirection
);
6064 check_member( desc
, expect_desc_init
, "%p", lpEnvelope
);
6065 check_member( desc
, expect_desc_init
, "%u", cbTypeSpecificParams
);
6066 if (version
>= 0x700) check_member( desc
, expect_desc
, "%u", dwStartDelay
);
6067 else ok( desc
.dwStartDelay
== 0, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
6069 hr
= IDirectInputEffect_Download( effect
);
6070 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6071 hr
= IDirectInputEffect_Unload( effect
);
6072 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6074 desc
.lpEnvelope
= NULL
;
6075 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
6076 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6077 desc
.lpEnvelope
= &envelope
;
6078 envelope
.dwSize
= 0;
6079 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
6080 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6082 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_ENVELOPE
| DIEP_NODOWNLOAD
);
6083 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6085 desc
.lpEnvelope
= &envelope
;
6086 envelope
.dwSize
= sizeof(DIENVELOPE
);
6087 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_ENVELOPE
);
6088 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6089 check_member( envelope
, expect_envelope
, "%u", dwAttackLevel
);
6090 check_member( envelope
, expect_envelope
, "%u", dwAttackTime
);
6091 check_member( envelope
, expect_envelope
, "%u", dwFadeLevel
);
6092 check_member( envelope
, expect_envelope
, "%u", dwFadeTime
);
6094 hr
= IDirectInputEffect_Download( effect
);
6095 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6096 hr
= IDirectInputEffect_Unload( effect
);
6097 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6101 desc
.rgdwAxes
= NULL
;
6102 desc
.rglDirection
= NULL
;
6103 desc
.lpEnvelope
= NULL
;
6104 desc
.cbTypeSpecificParams
= 0;
6105 desc
.lpvTypeSpecificParams
= NULL
;
6106 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
6107 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, flags
| DIEP_NODOWNLOAD
);
6108 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6109 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
6110 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6111 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_NODOWNLOAD
);
6112 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6114 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
6116 desc
.rgdwAxes
= axes
;
6117 desc
.rgdwAxes
[0] = DIJOFS_X
;
6118 desc
.dwTriggerButton
= DIJOFS_BUTTON( 1 );
6119 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6120 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6121 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
6122 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6123 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
| DIEP_NODOWNLOAD
);
6124 ok( hr
== DIERR_ALREADYINITIALIZED
, "SetParameters returned %#x\n", hr
);
6127 desc
.dwFlags
= DIEFF_OBJECTIDS
;
6128 desc
.rgdwAxes
= axes
;
6129 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
6130 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6131 check_member( desc
, expect_desc
, "%u", cAxes
);
6132 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
6133 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6134 check_member( desc
, expect_desc
, "%#x", dwTriggerButton
);
6135 check_member( desc
, expect_desc
, "%u", cAxes
);
6136 check_member( desc
, expect_desc
, "%u", rgdwAxes
[0] );
6137 check_member( desc
, expect_desc
, "%u", rgdwAxes
[1] );
6138 check_member( desc
, expect_desc
, "%u", rgdwAxes
[2] );
6140 desc
.dwFlags
= DIEFF_OBJECTOFFSETS
;
6141 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_AXES
| DIEP_TRIGGERBUTTON
);
6142 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6143 ok( desc
.dwTriggerButton
== 0x30, "got %#x expected %#x\n", desc
.dwTriggerButton
, 0x30 );
6144 ok( desc
.rgdwAxes
[0] == 8, "got %#x expected %#x\n", desc
.rgdwAxes
[0], 8 );
6145 ok( desc
.rgdwAxes
[1] == 0, "got %#x expected %#x\n", desc
.rgdwAxes
[1], 0 );
6146 ok( desc
.rgdwAxes
[2] == 4, "got %#x expected %#x\n", desc
.rgdwAxes
[2], 4 );
6148 hr
= IDirectInputEffect_Download( effect
);
6149 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6150 hr
= IDirectInputEffect_Unload( effect
);
6151 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6153 desc
.dwFlags
= DIEFF_CARTESIAN
;
6155 desc
.rglDirection
= directions
;
6156 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6157 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6159 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6160 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6161 desc
.dwFlags
= DIEFF_POLAR
;
6163 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6164 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6166 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6167 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6169 desc
.dwFlags
= DIEFF_SPHERICAL
;
6171 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6172 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6173 ok( desc
.dwFlags
== DIEFF_SPHERICAL
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_SPHERICAL
);
6174 check_member( desc
, expect_desc
, "%u", cAxes
);
6175 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6176 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6177 check_member( desc
, expect_desc
, "%u", cAxes
);
6178 ok( desc
.rglDirection
[0] == 3000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 3000 );
6179 ok( desc
.rglDirection
[1] == 30000, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 30000 );
6180 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6181 desc
.dwFlags
= DIEFF_CARTESIAN
;
6183 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6184 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6185 ok( desc
.dwFlags
== DIEFF_CARTESIAN
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_CARTESIAN
);
6186 check_member( desc
, expect_desc
, "%u", cAxes
);
6187 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6188 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6189 check_member( desc
, expect_desc
, "%u", cAxes
);
6190 ok( desc
.rglDirection
[0] == 4330, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 4330 );
6191 ok( desc
.rglDirection
[1] == 2500, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 2500 );
6192 ok( desc
.rglDirection
[2] == -8660, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], -8660 );
6193 desc
.dwFlags
= DIEFF_POLAR
;
6195 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6196 ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
6198 hr
= IDirectInputEffect_Download( effect
);
6199 ok( hr
== DIERR_INCOMPLETEEFFECT
, "Download returned %#x\n", hr
);
6200 hr
= IDirectInputEffect_Unload( effect
);
6201 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6203 desc
.cbTypeSpecificParams
= 0;
6204 desc
.lpvTypeSpecificParams
= &periodic
;
6205 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
6206 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6207 desc
.cbTypeSpecificParams
= sizeof(DIPERIODIC
);
6208 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
6209 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6210 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_TYPESPECIFICPARAMS
| DIEP_NODOWNLOAD
);
6211 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6213 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_TYPESPECIFICPARAMS
);
6214 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6215 check_member( periodic
, expect_periodic
, "%u", dwMagnitude
);
6216 check_member( periodic
, expect_periodic
, "%d", lOffset
);
6217 check_member( periodic
, expect_periodic
, "%u", dwPhase
);
6218 check_member( periodic
, expect_periodic
, "%u", dwPeriod
);
6220 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
6221 ok( hr
== DIERR_NOTDOWNLOADED
, "Start returned %#x\n", hr
);
6222 hr
= IDirectInputEffect_Stop( effect
);
6223 ok( hr
== DIERR_NOTDOWNLOADED
, "Stop returned %#x\n", hr
);
6225 set_hid_expect( file
, expect_download
, 3 * sizeof(struct hid_expect
) );
6226 hr
= IDirectInputEffect_Download( effect
);
6227 ok( hr
== DI_OK
, "Download returned %#x\n", hr
);
6228 set_hid_expect( file
, NULL
, 0 );
6230 hr
= IDirectInputEffect_Download( effect
);
6231 ok( hr
== DI_NOEFFECT
, "Download returned %#x\n", hr
);
6233 hr
= IDirectInputEffect_Start( effect
, 1, 0xdeadbeef );
6234 ok( hr
== DIERR_INVALIDPARAM
, "Start returned %#x\n", hr
);
6236 set_hid_expect( file
, &expect_start_solo
, sizeof(expect_start_solo
) );
6237 hr
= IDirectInputEffect_Start( effect
, 1, DIES_SOLO
);
6238 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6239 set_hid_expect( file
, NULL
, 0 );
6241 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
6242 hr
= IDirectInputEffect_Stop( effect
);
6243 ok( hr
== DI_OK
, "Stop returned %#x\n", hr
);
6244 set_hid_expect( file
, NULL
, 0 );
6246 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
6247 hr
= IDirectInputEffect_Start( effect
, 1, 0 );
6248 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6249 set_hid_expect( file
, NULL
, 0 );
6251 set_hid_expect( file
, &expect_start_4
, sizeof(expect_start_4
) );
6252 hr
= IDirectInputEffect_Start( effect
, 4, 0 );
6253 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6254 set_hid_expect( file
, NULL
, 0 );
6256 set_hid_expect( file
, &expect_start_0
, sizeof(expect_start_4
) );
6257 hr
= IDirectInputEffect_Start( effect
, 0, 0 );
6258 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
6259 set_hid_expect( file
, NULL
, 0 );
6261 set_hid_expect( file
, expect_unload
, sizeof(struct hid_expect
) );
6262 hr
= IDirectInputEffect_Unload( effect
);
6263 ok( hr
== DI_OK
, "Unload returned %#x\n", hr
);
6264 set_hid_expect( file
, NULL
, 0 );
6266 set_hid_expect( file
, expect_download
, 4 * sizeof(struct hid_expect
) );
6267 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, DIEP_START
);
6268 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6269 set_hid_expect( file
, NULL
, 0 );
6271 set_hid_expect( file
, expect_unload
, sizeof(struct hid_expect
) );
6272 hr
= IDirectInputEffect_Unload( effect
);
6273 ok( hr
== DI_OK
, "Unload returned %#x\n", hr
);
6274 set_hid_expect( file
, NULL
, 0 );
6276 set_hid_expect( file
, expect_download
, 3 * sizeof(struct hid_expect
) );
6277 hr
= IDirectInputEffect_Download( effect
);
6278 ok( hr
== DI_OK
, "Download returned %#x\n", hr
);
6279 set_hid_expect( file
, NULL
, 0 );
6281 set_hid_expect( file
, expect_unload
, 2 * sizeof(struct hid_expect
) );
6282 hr
= IDirectInputDevice8_Unacquire( device
);
6283 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
6284 set_hid_expect( file
, NULL
, 0 );
6286 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
6287 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Start returned %#x\n", hr
);
6288 hr
= IDirectInputEffect_Stop( effect
);
6289 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Stop returned %#x\n", hr
);
6291 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
6292 hr
= IDirectInputDevice8_Acquire( device
);
6293 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6294 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
6296 hr
= IDirectInputEffect_Unload( effect
);
6297 ok( hr
== DI_NOEFFECT
, "Unload returned %#x\n", hr
);
6299 ref
= IDirectInputEffect_Release( effect
);
6300 ok( ref
== 0, "Release returned %d\n", ref
);
6302 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
6303 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6305 desc
.dwFlags
= DIEFF_POLAR
| DIEFF_OBJECTIDS
;
6307 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
6308 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
;
6309 desc
.rglDirection
[0] = 3000;
6310 desc
.rglDirection
[1] = 0;
6311 desc
.rglDirection
[2] = 0;
6312 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6313 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6314 desc
.rglDirection
[0] = 0;
6316 desc
.dwFlags
= DIEFF_SPHERICAL
;
6318 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6319 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6320 ok( desc
.dwFlags
== DIEFF_SPHERICAL
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_SPHERICAL
);
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] == 30000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 30000 );
6326 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 0 );
6327 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6329 desc
.dwFlags
= DIEFF_CARTESIAN
;
6331 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6332 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6333 ok( desc
.dwFlags
== DIEFF_CARTESIAN
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_CARTESIAN
);
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] == 5000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 5000 );
6339 ok( desc
.rglDirection
[1] == -8660, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], -8660 );
6340 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6342 desc
.dwFlags
= DIEFF_POLAR
;
6344 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6345 ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6346 ok( desc
.dwFlags
== DIEFF_POLAR
, "got flags %#x, expected %#x\n", desc
.dwFlags
, DIEFF_POLAR
);
6347 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6348 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6349 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6350 ok( desc
.cAxes
== 2, "got cAxes %u expected 2\n", desc
.cAxes
);
6351 ok( desc
.rglDirection
[0] == 3000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 3000 );
6352 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 0 );
6353 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n", desc
.rglDirection
[2], 0 );
6355 ref
= IDirectInputEffect_Release( effect
);
6356 ok( ref
== 0, "Release returned %d\n", ref
);
6358 for (i
= 1; i
< 4; i
++)
6360 winetest_push_context( "%u axes", i
);
6361 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
6362 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6364 desc
.dwFlags
= DIEFF_OBJECTIDS
;
6366 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
6367 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
;
6368 desc
.rgdwAxes
[2] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
;
6369 desc
.rglDirection
[0] = 0;
6370 desc
.rglDirection
[1] = 0;
6371 desc
.rglDirection
[2] = 0;
6372 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_AXES
| DIEP_NODOWNLOAD
);
6373 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6375 desc
.dwFlags
= DIEFF_CARTESIAN
;
6376 desc
.cAxes
= i
== 3 ? 2 : 3;
6377 desc
.rglDirection
[0] = 1000;
6378 desc
.rglDirection
[1] = 2000;
6379 desc
.rglDirection
[2] = 3000;
6380 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6381 ok( hr
== DIERR_INVALIDPARAM
, "SetParameters returned %#x\n", hr
);
6383 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_DIRECTION
| DIEP_NODOWNLOAD
);
6384 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6386 desc
.dwFlags
= DIEFF_SPHERICAL
;
6388 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6389 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6391 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
6392 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6393 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6394 ok( desc
.cAxes
== i
, "got cAxes %u expected 2\n", desc
.cAxes
);
6397 ok( desc
.rglDirection
[0] == 0, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 0 );
6398 ok( desc
.rglDirection
[1] == 0xcdcdcdcd, "got rglDirection[1] %d expected %d\n",
6399 desc
.rglDirection
[1], 0xcdcdcdcd );
6400 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6401 desc
.rglDirection
[2], 0xcdcdcdcd );
6405 ok( desc
.rglDirection
[0] == 6343, "got rglDirection[0] %d expected %d\n",
6406 desc
.rglDirection
[0], 6343 );
6409 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n",
6410 desc
.rglDirection
[1], 0 );
6411 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6412 desc
.rglDirection
[2], 0xcdcdcdcd );
6416 ok( desc
.rglDirection
[1] == 5330, "got rglDirection[1] %d expected %d\n",
6417 desc
.rglDirection
[1], 5330 );
6418 ok( desc
.rglDirection
[2] == 0, "got rglDirection[2] %d expected %d\n",
6419 desc
.rglDirection
[2], 0 );
6423 desc
.dwFlags
= DIEFF_CARTESIAN
;
6425 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6426 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6428 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
6429 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6430 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6431 ok( desc
.cAxes
== i
, "got cAxes %u expected 2\n", desc
.cAxes
);
6432 ok( desc
.rglDirection
[0] == 1000, "got rglDirection[0] %d expected %d\n", desc
.rglDirection
[0], 1000 );
6434 ok( desc
.rglDirection
[1] == 0xcdcdcdcd, "got rglDirection[1] %d expected %d\n",
6435 desc
.rglDirection
[1], 0xcdcdcdcd );
6437 ok( desc
.rglDirection
[1] == 2000, "got rglDirection[1] %d expected %d\n",
6438 desc
.rglDirection
[1], 2000 );
6440 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6441 desc
.rglDirection
[2], 0xcdcdcdcd );
6443 ok( desc
.rglDirection
[2] == 3000, "got rglDirection[2] %d expected %d\n",
6444 desc
.rglDirection
[2], 3000 );
6446 desc
.dwFlags
= DIEFF_POLAR
;
6448 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6449 if (i
!= 2) ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
6450 else ok( hr
== DIERR_MOREDATA
, "GetParameters returned %#x\n", hr
);
6452 memset( desc
.rglDirection
, 0xcd, 3 * sizeof(LONG
) );
6453 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, DIEP_DIRECTION
);
6454 if (i
!= 2) ok( hr
== DIERR_INVALIDPARAM
, "GetParameters returned %#x\n", hr
);
6457 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6458 ok( desc
.cAxes
== i
, "got cAxes %u expected 2\n", desc
.cAxes
);
6459 ok( desc
.rglDirection
[0] == 15343, "got rglDirection[0] %d expected %d\n",
6460 desc
.rglDirection
[0], 15343 );
6461 ok( desc
.rglDirection
[1] == 0, "got rglDirection[1] %d expected %d\n", desc
.rglDirection
[1], 0 );
6462 ok( desc
.rglDirection
[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6463 desc
.rglDirection
[2], 0xcdcdcdcd );
6466 ref
= IDirectInputEffect_Release( effect
);
6467 ok( ref
== 0, "Release returned %d\n", ref
);
6468 winetest_pop_context();
6471 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, NULL
, &effect
, NULL
);
6472 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6474 set_hid_expect( file
, expect_download_2
, sizeof(expect_download_2
) );
6475 flags
= version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
;
6476 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
);
6477 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6478 set_hid_expect( file
, NULL
, 0 );
6480 desc
.dwDuration
= INFINITE
;
6481 desc
.dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
6482 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
|DIEP_DURATION
|DIEP_TRIGGERBUTTON
);
6483 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6484 set_hid_expect( file
, expect_update
, sizeof(expect_update
) );
6485 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
6486 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6487 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
6489 desc
.dwDuration
= INFINITE
;
6490 desc
.dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
6491 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
|DIEP_DURATION
|DIEP_TRIGGERBUTTON
);
6492 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6493 set_hid_expect( file
, expect_update
, sizeof(expect_update
) );
6494 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
6495 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6496 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
6499 desc
.lpEnvelope
= &envelope
;
6500 desc
.lpEnvelope
->dwAttackTime
= 1000;
6501 hr
= IDirectInputEffect_SetParameters( effect
, &desc
, DIEP_NODOWNLOAD
|DIEP_ENVELOPE
);
6502 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
6503 set_hid_expect( file
, expect_set_envelope
, sizeof(expect_set_envelope
) );
6504 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, 0 );
6505 ok( hr
== DI_OK
, "SetParameters returned %#x\n", hr
);
6506 wait_hid_expect( file
, 100 ); /* these updates are sent asynchronously */
6508 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
6509 ref
= IDirectInputEffect_Release( effect
);
6510 ok( ref
== 0, "Release returned %d\n", ref
);
6511 set_hid_expect( file
, NULL
, 0 );
6513 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
6514 hr
= IDirectInputDevice8_Unacquire( device
);
6515 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6516 set_hid_expect( file
, NULL
, 0 );
6517 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Sine
, &expect_desc
, &effect
, NULL
);
6518 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6519 ref
= IDirectInputEffect_Release( effect
);
6520 ok( ref
== 0, "Release returned %d\n", ref
);
6521 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
6522 hr
= IDirectInputDevice8_Acquire( device
);
6523 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
6524 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
6527 static void test_condition_effect( IDirectInputDevice8W
*device
, HANDLE file
, DWORD version
)
6529 struct hid_expect expect_create
[] =
6533 .code
= IOCTL_HID_WRITE_REPORT
,
6536 .report_buf
= {0x07,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
6540 .code
= IOCTL_HID_WRITE_REPORT
,
6543 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6547 .code
= IOCTL_HID_WRITE_REPORT
,
6550 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
6553 struct hid_expect expect_create_1
[] =
6557 .code
= IOCTL_HID_WRITE_REPORT
,
6560 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6564 .code
= IOCTL_HID_WRITE_REPORT
,
6567 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x3f,0x00},
6570 struct hid_expect expect_create_2
[] =
6574 .code
= IOCTL_HID_WRITE_REPORT
,
6577 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6581 .code
= IOCTL_HID_WRITE_REPORT
,
6584 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xf1},
6587 struct hid_expect expect_create_3
[] =
6591 .code
= IOCTL_HID_WRITE_REPORT
,
6594 .report_buf
= {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6598 .code
= IOCTL_HID_WRITE_REPORT
,
6601 .report_buf
= {0x03,0x01,0x03,0x08,0x01,0x00,version
>= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
6604 struct hid_expect expect_destroy
=
6606 .code
= IOCTL_HID_WRITE_REPORT
,
6609 .report_buf
= {0x02, 0x01, 0x03, 0x00},
6611 static const DWORD expect_axes
[3] =
6613 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
6614 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
6615 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
6617 static const LONG expect_directions
[3] = {
6622 static const DIENVELOPE expect_envelope
=
6624 .dwSize
= sizeof(DIENVELOPE
),
6625 .dwAttackLevel
= 1000,
6626 .dwAttackTime
= 2000,
6627 .dwFadeLevel
= 3000,
6630 static const DICONDITION expect_condition
[3] =
6634 .lPositiveCoefficient
= 2000,
6635 .lNegativeCoefficient
= -3000,
6636 .dwPositiveSaturation
= -4000,
6637 .dwNegativeSaturation
= -5000,
6642 .lPositiveCoefficient
= 5000,
6643 .lNegativeCoefficient
= -4000,
6644 .dwPositiveSaturation
= 3000,
6645 .dwNegativeSaturation
= 2000,
6650 .lPositiveCoefficient
= -8000,
6651 .lNegativeCoefficient
= 9000,
6652 .dwPositiveSaturation
= 10000,
6653 .dwNegativeSaturation
= 11000,
6654 .lDeadBand
= -12000,
6657 const DIEFFECT expect_desc
=
6659 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
6660 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
6662 .dwSamplePeriod
= 2000,
6664 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
6665 .dwTriggerRepeatInterval
= 5000,
6667 .rgdwAxes
= (void *)expect_axes
,
6668 .rglDirection
= (void *)expect_directions
,
6669 .lpEnvelope
= (void *)&expect_envelope
,
6670 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
6671 .lpvTypeSpecificParams
= (void *)expect_condition
,
6672 .dwStartDelay
= 6000,
6674 struct check_created_effect_params check_params
= {0};
6675 DIENVELOPE envelope
=
6676 {.dwSize
= sizeof(DIENVELOPE
)};
6677 DICONDITION condition
[2] = {0};
6678 IDirectInputEffect
*effect
;
6679 LONG directions
[4] = {0};
6680 DWORD axes
[4] = {0};
6683 .dwSize
= version
>= 0x700 ? sizeof(DIEFFECT_DX6
) : sizeof(DIEFFECT_DX5
),
6684 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
6687 .rglDirection
= directions
,
6688 .lpEnvelope
= &envelope
,
6689 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
6690 .lpvTypeSpecificParams
= condition
,
6696 set_hid_expect( file
, expect_create
, sizeof(expect_create
) );
6697 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &expect_desc
, &effect
, NULL
);
6698 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6699 set_hid_expect( file
, NULL
, 0 );
6701 check_params
.expect_effect
= effect
;
6702 hr
= IDirectInputDevice8_EnumCreatedEffectObjects( device
, check_created_effect_objects
, &check_params
, 0 );
6703 ok( hr
== DI_OK
, "EnumCreatedEffectObjects returned %#x\n", hr
);
6704 ok( check_params
.count
== 1, "got count %u, expected 1\n", check_params
.count
);
6706 hr
= IDirectInputEffect_GetEffectGuid( effect
, &guid
);
6707 ok( hr
== DI_OK
, "GetEffectGuid returned %#x\n", hr
);
6708 ok( IsEqualGUID( &guid
, &GUID_Spring
), "got guid %s, expected %s\n", debugstr_guid( &guid
),
6709 debugstr_guid( &GUID_Spring
) );
6711 hr
= IDirectInputEffect_GetParameters( effect
, &desc
, version
>= 0x700 ? DIEP_ALLPARAMS
: DIEP_ALLPARAMS_DX5
);
6712 ok( hr
== DI_OK
, "GetParameters returned %#x\n", hr
);
6713 check_member( desc
, expect_desc
, "%u", dwDuration
);
6714 check_member( desc
, expect_desc
, "%u", dwSamplePeriod
);
6715 check_member( desc
, expect_desc
, "%u", dwGain
);
6716 check_member( desc
, expect_desc
, "%#x", dwTriggerButton
);
6717 check_member( desc
, expect_desc
, "%u", dwTriggerRepeatInterval
);
6718 check_member( desc
, expect_desc
, "%u", cAxes
);
6719 check_member( desc
, expect_desc
, "%#x", rgdwAxes
[0] );
6720 check_member( desc
, expect_desc
, "%#x", rgdwAxes
[1] );
6721 check_member( desc
, expect_desc
, "%d", rglDirection
[0] );
6722 check_member( desc
, expect_desc
, "%d", rglDirection
[1] );
6723 check_member( desc
, expect_desc
, "%u", cbTypeSpecificParams
);
6724 if (version
>= 0x700) check_member( desc
, expect_desc
, "%u", dwStartDelay
);
6725 else ok( desc
.dwStartDelay
== 0, "got dwStartDelay %#x\n", desc
.dwStartDelay
);
6726 check_member( envelope
, expect_envelope
, "%u", dwAttackLevel
);
6727 check_member( envelope
, expect_envelope
, "%u", dwAttackTime
);
6728 check_member( envelope
, expect_envelope
, "%u", dwFadeLevel
);
6729 check_member( envelope
, expect_envelope
, "%u", dwFadeTime
);
6730 check_member( condition
[0], expect_condition
[0], "%d", lOffset
);
6731 check_member( condition
[0], expect_condition
[0], "%d", lPositiveCoefficient
);
6732 check_member( condition
[0], expect_condition
[0], "%d", lNegativeCoefficient
);
6733 check_member( condition
[0], expect_condition
[0], "%u", dwPositiveSaturation
);
6734 check_member( condition
[0], expect_condition
[0], "%u", dwNegativeSaturation
);
6735 check_member( condition
[0], expect_condition
[0], "%d", lDeadBand
);
6736 check_member( condition
[1], expect_condition
[1], "%d", lOffset
);
6737 check_member( condition
[1], expect_condition
[1], "%d", lPositiveCoefficient
);
6738 check_member( condition
[1], expect_condition
[1], "%d", lNegativeCoefficient
);
6739 check_member( condition
[1], expect_condition
[1], "%u", dwPositiveSaturation
);
6740 check_member( condition
[1], expect_condition
[1], "%u", dwNegativeSaturation
);
6741 check_member( condition
[1], expect_condition
[1], "%d", lDeadBand
);
6743 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6744 ref
= IDirectInputEffect_Release( effect
);
6745 ok( ref
== 0, "Release returned %d\n", ref
);
6746 set_hid_expect( file
, NULL
, 0 );
6750 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6751 ok( hr
== DIERR_INVALIDPARAM
, "CreateEffect returned %#x\n", hr
);
6752 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
6753 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
6754 set_hid_expect( file
, expect_create_1
, sizeof(expect_create_1
) );
6755 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6756 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6757 set_hid_expect( file
, NULL
, 0 );
6759 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6760 ref
= IDirectInputEffect_Release( effect
);
6761 ok( ref
== 0, "Release returned %d\n", ref
);
6762 set_hid_expect( file
, NULL
, 0 );
6766 desc
.rglDirection
= directions
;
6767 desc
.rglDirection
[0] = +3000;
6768 desc
.rglDirection
[1] = -2000;
6769 desc
.rglDirection
[2] = +1000;
6770 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
6771 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
6772 set_hid_expect( file
, expect_create_2
, sizeof(expect_create_2
) );
6773 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6774 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6775 set_hid_expect( file
, NULL
, 0 );
6777 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6778 ref
= IDirectInputEffect_Release( effect
);
6779 ok( ref
== 0, "Release returned %d\n", ref
);
6780 set_hid_expect( file
, NULL
, 0 );
6784 desc
.rgdwAxes
= axes
;
6785 desc
.rgdwAxes
[0] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
;
6786 desc
.rgdwAxes
[1] = DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
;
6787 desc
.rglDirection
= directions
;
6788 desc
.rglDirection
[0] = +3000;
6789 desc
.rglDirection
[1] = -2000;
6790 desc
.cbTypeSpecificParams
= 1 * sizeof(DICONDITION
);
6791 desc
.lpvTypeSpecificParams
= (void *)&expect_condition
[1];
6792 set_hid_expect( file
, expect_create_3
, sizeof(expect_create_3
) );
6793 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
6794 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
6795 set_hid_expect( file
, NULL
, 0 );
6797 set_hid_expect( file
, &expect_destroy
, sizeof(expect_destroy
) );
6798 ref
= IDirectInputEffect_Release( effect
);
6799 ok( ref
== 0, "Release returned %d\n", ref
);
6800 set_hid_expect( file
, NULL
, 0 );
6803 static void test_force_feedback_joystick( DWORD version
)
6805 #include "psh_hid_macros.h"
6806 const unsigned char report_descriptor
[] = {
6807 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
6808 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
6809 COLLECTION(1, Application
),
6810 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
6811 COLLECTION(1, Report
),
6814 USAGE(1, HID_USAGE_GENERIC_X
),
6815 USAGE(1, HID_USAGE_GENERIC_Y
),
6816 USAGE(1, HID_USAGE_GENERIC_Z
),
6817 LOGICAL_MINIMUM(1, 0),
6818 LOGICAL_MAXIMUM(1, 0x7f),
6819 PHYSICAL_MINIMUM(1, 0),
6820 PHYSICAL_MAXIMUM(1, 0x7f),
6823 INPUT(1, Data
|Var
|Abs
),
6825 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
6826 USAGE_MINIMUM(1, 1),
6827 USAGE_MAXIMUM(1, 2),
6828 LOGICAL_MINIMUM(1, 0),
6829 LOGICAL_MAXIMUM(1, 1),
6830 PHYSICAL_MINIMUM(1, 0),
6831 PHYSICAL_MAXIMUM(1, 1),
6834 INPUT(1, Data
|Var
|Abs
),
6836 INPUT(1, Cnst
|Var
|Abs
),
6839 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
6840 USAGE(1, PID_USAGE_STATE_REPORT
),
6841 COLLECTION(1, Report
),
6844 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
6845 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
6846 USAGE(1, PID_USAGE_SAFETY_SWITCH
),
6847 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH
),
6848 USAGE(1, PID_USAGE_ACTUATOR_POWER
),
6849 LOGICAL_MINIMUM(1, 0),
6850 LOGICAL_MAXIMUM(1, 1),
6851 PHYSICAL_MINIMUM(1, 0),
6852 PHYSICAL_MAXIMUM(1, 1),
6855 INPUT(1, Data
|Var
|Abs
),
6857 INPUT(1, Cnst
|Var
|Abs
),
6859 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
6860 LOGICAL_MINIMUM(1, 0),
6861 LOGICAL_MAXIMUM(1, 1),
6862 PHYSICAL_MINIMUM(1, 0),
6863 PHYSICAL_MAXIMUM(1, 1),
6866 INPUT(1, Data
|Var
|Abs
),
6868 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
6869 LOGICAL_MAXIMUM(1, 0x7f),
6870 LOGICAL_MINIMUM(1, 0x00),
6873 INPUT(1, Data
|Var
|Abs
),
6876 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
6877 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
6878 COLLECTION(1, Report
),
6881 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
6882 COLLECTION(1, Logical
),
6883 USAGE(1, PID_USAGE_DC_DEVICE_RESET
),
6884 LOGICAL_MINIMUM(1, 1),
6885 LOGICAL_MAXIMUM(1, 2),
6886 PHYSICAL_MINIMUM(1, 1),
6887 PHYSICAL_MAXIMUM(1, 2),
6890 OUTPUT(1, Data
|Ary
|Abs
),
6894 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
6895 COLLECTION(1, Report
),
6898 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
6899 LOGICAL_MINIMUM(1, 0),
6900 LOGICAL_MAXIMUM(1, 0x7f),
6901 PHYSICAL_MINIMUM(1, 0),
6902 PHYSICAL_MAXIMUM(1, 0x7f),
6905 OUTPUT(1, Data
|Var
|Abs
),
6907 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
6908 COLLECTION(1, NamedArray
),
6909 USAGE(1, PID_USAGE_OP_EFFECT_START
),
6910 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO
),
6911 USAGE(1, PID_USAGE_OP_EFFECT_STOP
),
6912 LOGICAL_MINIMUM(1, 1),
6913 LOGICAL_MAXIMUM(1, 3),
6914 PHYSICAL_MINIMUM(1, 1),
6915 PHYSICAL_MAXIMUM(1, 3),
6918 OUTPUT(1, Data
|Ary
|Abs
),
6921 USAGE(1, PID_USAGE_LOOP_COUNT
),
6922 LOGICAL_MINIMUM(1, 0),
6923 LOGICAL_MAXIMUM(1, 0x7f),
6924 PHYSICAL_MINIMUM(1, 0),
6925 PHYSICAL_MAXIMUM(1, 0x7f),
6928 OUTPUT(1, Data
|Var
|Abs
),
6931 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
6932 COLLECTION(1, Report
),
6935 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
6936 LOGICAL_MINIMUM(1, 0),
6937 LOGICAL_MAXIMUM(1, 0x7f),
6938 PHYSICAL_MINIMUM(1, 0),
6939 PHYSICAL_MAXIMUM(1, 0x7f),
6942 OUTPUT(1, Data
|Var
|Abs
),
6944 USAGE(1, PID_USAGE_EFFECT_TYPE
),
6945 COLLECTION(1, NamedArray
),
6946 USAGE(1, PID_USAGE_ET_SQUARE
),
6947 USAGE(1, PID_USAGE_ET_SINE
),
6948 USAGE(1, PID_USAGE_ET_SPRING
),
6949 LOGICAL_MINIMUM(1, 1),
6950 LOGICAL_MAXIMUM(1, 3),
6951 PHYSICAL_MINIMUM(1, 1),
6952 PHYSICAL_MAXIMUM(1, 3),
6955 OUTPUT(1, Data
|Ary
|Abs
),
6958 USAGE(1, PID_USAGE_AXES_ENABLE
),
6959 COLLECTION(1, Logical
),
6960 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_X
),
6961 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Y
),
6962 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Z
),
6963 LOGICAL_MINIMUM(1, 0),
6964 LOGICAL_MAXIMUM(1, 1),
6965 PHYSICAL_MINIMUM(1, 0),
6966 PHYSICAL_MAXIMUM(1, 1),
6969 OUTPUT(1, Data
|Var
|Abs
),
6971 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
6973 OUTPUT(1, Data
|Var
|Abs
),
6975 OUTPUT(1, Cnst
|Var
|Abs
),
6977 USAGE(1, PID_USAGE_DURATION
),
6978 USAGE(1, PID_USAGE_START_DELAY
),
6979 UNIT(2, 0x1003), /* Eng Lin:Time */
6980 UNIT_EXPONENT(1, -3), /* 10^-3 */
6981 LOGICAL_MINIMUM(1, 0),
6982 LOGICAL_MAXIMUM(2, 0x7fff),
6983 PHYSICAL_MINIMUM(1, 0),
6984 PHYSICAL_MAXIMUM(2, 0x7fff),
6987 OUTPUT(1, Data
|Var
|Abs
),
6989 UNIT_EXPONENT(1, 0),
6991 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
6992 LOGICAL_MINIMUM(1, 1),
6993 LOGICAL_MAXIMUM(1, 0x08),
6994 PHYSICAL_MINIMUM(1, 1),
6995 PHYSICAL_MAXIMUM(1, 0x08),
6998 OUTPUT(1, Data
|Var
|Abs
),
7000 USAGE(1, PID_USAGE_DIRECTION
),
7001 COLLECTION(1, Logical
),
7002 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
7003 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
7004 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
7005 UNIT_EXPONENT(1, -2), /* 10^-2 */
7006 LOGICAL_MINIMUM(1, 0),
7007 LOGICAL_MAXIMUM(2, 0x00ff),
7008 PHYSICAL_MINIMUM(1, 0),
7009 PHYSICAL_MAXIMUM(4, 0x00008ca0),
7013 OUTPUT(1, Data
|Var
|Abs
),
7014 UNIT_EXPONENT(1, 0),
7019 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT
),
7020 COLLECTION(1, Logical
),
7023 USAGE(1, PID_USAGE_MAGNITUDE
),
7024 LOGICAL_MINIMUM(1, 0),
7025 LOGICAL_MAXIMUM(2, 0x00ff),
7026 PHYSICAL_MINIMUM(1, 0),
7027 PHYSICAL_MAXIMUM(2, 0x2710),
7030 OUTPUT(1, Data
|Var
|Abs
),
7033 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT
),
7034 COLLECTION(1, Logical
),
7037 USAGE(1, PID_USAGE_ATTACK_LEVEL
),
7038 USAGE(1, PID_USAGE_FADE_LEVEL
),
7039 LOGICAL_MINIMUM(1, 0),
7040 LOGICAL_MAXIMUM(2, 0x00ff),
7041 PHYSICAL_MINIMUM(1, 0),
7042 PHYSICAL_MAXIMUM(2, 0x2710),
7045 OUTPUT(1, Data
|Var
|Abs
),
7047 USAGE(1, PID_USAGE_ATTACK_TIME
),
7048 USAGE(1, PID_USAGE_FADE_TIME
),
7049 UNIT(2, 0x1003), /* Eng Lin:Time */
7050 UNIT_EXPONENT(1, -3), /* 10^-3 */
7051 LOGICAL_MINIMUM(1, 0),
7052 LOGICAL_MAXIMUM(2, 0x7fff),
7053 PHYSICAL_MINIMUM(1, 0),
7054 PHYSICAL_MAXIMUM(2, 0x7fff),
7057 OUTPUT(1, Data
|Var
|Abs
),
7058 PHYSICAL_MAXIMUM(1, 0),
7059 UNIT_EXPONENT(1, 0),
7064 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
7065 COLLECTION(1, Logical
),
7068 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
),
7069 COLLECTION(1, Logical
),
7070 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
7071 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
7072 LOGICAL_MINIMUM(1, 0),
7073 LOGICAL_MAXIMUM(1, 1),
7074 PHYSICAL_MINIMUM(1, 0),
7075 PHYSICAL_MAXIMUM(1, 1),
7078 OUTPUT(1, Data
|Var
|Abs
),
7082 OUTPUT(1, Cnst
|Var
|Abs
),
7084 USAGE(1, PID_USAGE_CP_OFFSET
),
7085 LOGICAL_MINIMUM(1, 0x80),
7086 LOGICAL_MAXIMUM(1, 0x7f),
7087 PHYSICAL_MINIMUM(2, 0xd8f0),
7088 PHYSICAL_MAXIMUM(2, 0x2710),
7091 OUTPUT(1, Data
|Var
|Abs
),
7093 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
7094 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
7095 LOGICAL_MINIMUM(1, 0x80),
7096 LOGICAL_MAXIMUM(1, 0x7f),
7097 PHYSICAL_MINIMUM(2, 0xd8f0),
7098 PHYSICAL_MAXIMUM(2, 0x2710),
7101 OUTPUT(1, Data
|Var
|Abs
),
7103 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
7104 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
7105 LOGICAL_MINIMUM(1, 0),
7106 LOGICAL_MAXIMUM(2, 0x00ff),
7107 PHYSICAL_MINIMUM(1, 0),
7108 PHYSICAL_MAXIMUM(2, 0x2710),
7111 OUTPUT(1, Data
|Var
|Abs
),
7113 USAGE(1, PID_USAGE_DEAD_BAND
),
7114 LOGICAL_MINIMUM(1, 0),
7115 LOGICAL_MAXIMUM(2, 0x00ff),
7116 PHYSICAL_MINIMUM(1, 0),
7117 PHYSICAL_MAXIMUM(2, 0x2710),
7120 OUTPUT(1, Data
|Var
|Abs
),
7124 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT
),
7125 COLLECTION(1, Logical
),
7128 USAGE(1, PID_USAGE_DEVICE_GAIN
),
7129 LOGICAL_MINIMUM(1, 0),
7130 LOGICAL_MAXIMUM(2, 0x00ff),
7131 PHYSICAL_MINIMUM(1, 0),
7132 PHYSICAL_MAXIMUM(2, 0x2710),
7135 OUTPUT(1, Data
|Var
|Abs
),
7139 #undef REPORT_ID_OR_USAGE_PAGE
7140 #include "pop_hid_macros.h"
7142 static const HIDP_CAPS hid_caps
=
7144 .InputReportByteLength
= 5,
7146 const DIDEVCAPS expect_caps
=
7148 .dwSize
= sizeof(DIDEVCAPS
),
7149 .dwFlags
= DIDC_FORCEFEEDBACK
| DIDC_ATTACHED
| DIDC_EMULATED
| DIDC_STARTDELAY
|
7150 DIDC_FFFADE
| DIDC_FFATTACK
| DIDC_DEADBAND
| DIDC_SATURATION
,
7151 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
7152 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_UNKNOWN
<< 8) | DIDEVTYPE_JOYSTICK
,
7155 .dwFFSamplePeriod
= 1000000,
7156 .dwFFMinTimeResolution
= 1000000,
7157 .dwHardwareRevision
= 1,
7158 .dwFFDriverVersion
= 1,
7160 struct hid_expect expect_acquire
[] =
7163 .code
= IOCTL_HID_WRITE_REPORT
,
7166 .report_buf
= {1, 0x01},
7169 .code
= IOCTL_HID_WRITE_REPORT
,
7172 .report_buf
= {8, 0x19},
7175 struct hid_expect expect_reset
[] =
7178 .code
= IOCTL_HID_WRITE_REPORT
,
7181 .report_buf
= {1, 0x01},
7184 struct hid_expect expect_set_device_gain_1
=
7186 .code
= IOCTL_HID_WRITE_REPORT
,
7189 .report_buf
= {8, 0x19},
7191 struct hid_expect expect_set_device_gain_2
=
7193 .code
= IOCTL_HID_WRITE_REPORT
,
7196 .report_buf
= {8, 0x33},
7199 const DIDEVICEINSTANCEW expect_devinst
=
7201 .dwSize
= sizeof(DIDEVICEINSTANCEW
),
7202 .guidInstance
= expect_guid_product
,
7203 .guidProduct
= expect_guid_product
,
7204 .dwDevType
= version
>= 0x800 ? DIDEVTYPE_HID
| (DI8DEVTYPEJOYSTICK_LIMITED
<< 8) | DI8DEVTYPE_JOYSTICK
7205 : DIDEVTYPE_HID
| (DIDEVTYPEJOYSTICK_UNKNOWN
<< 8) | DIDEVTYPE_JOYSTICK
,
7206 .tszInstanceName
= L
"Wine test root driver",
7207 .tszProductName
= L
"Wine test root driver",
7208 .guidFFDriver
= IID_IDirectInputPIDDriver
,
7209 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7210 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
7212 const DIDEVICEOBJECTINSTANCEW expect_objects_5
[] =
7215 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7216 .guidType
= GUID_XAxis
,
7217 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR
,
7218 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7219 .tszName
= L
"X Axis",
7220 .wCollectionNumber
= 1,
7221 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7222 .wUsage
= HID_USAGE_GENERIC_X
,
7226 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7227 .guidType
= GUID_YAxis
,
7229 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR
,
7230 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7231 .tszName
= L
"Y Axis",
7232 .wCollectionNumber
= 1,
7233 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7234 .wUsage
= HID_USAGE_GENERIC_Y
,
7238 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7239 .guidType
= GUID_ZAxis
,
7241 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR
,
7242 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7243 .tszName
= L
"Z Axis",
7244 .wCollectionNumber
= 1,
7245 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7246 .wUsage
= HID_USAGE_GENERIC_Z
,
7250 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7251 .guidType
= GUID_Button
,
7253 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER
,
7254 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7255 .tszName
= L
"Button 0",
7256 .wCollectionNumber
= 1,
7257 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7262 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7263 .guidType
= GUID_Button
,
7265 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER
,
7266 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7267 .tszName
= L
"Button 1",
7268 .wCollectionNumber
= 1,
7269 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7274 const DIDEVICEOBJECTINSTANCEW expect_objects
[] =
7277 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7278 .guidType
= GUID_ZAxis
,
7279 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR
,
7280 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7281 .tszName
= L
"Z Axis",
7282 .wCollectionNumber
= 1,
7283 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7284 .wUsage
= HID_USAGE_GENERIC_Z
,
7288 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7289 .guidType
= GUID_YAxis
,
7291 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR
,
7292 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7293 .tszName
= L
"Y Axis",
7294 .wCollectionNumber
= 1,
7295 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7296 .wUsage
= HID_USAGE_GENERIC_Y
,
7300 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7301 .guidType
= GUID_XAxis
,
7303 .dwType
= DIDFT_ABSAXIS
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR
,
7304 .dwFlags
= DIDOI_ASPECTPOSITION
|DIDOI_FFACTUATOR
,
7305 .tszName
= L
"X Axis",
7306 .wCollectionNumber
= 1,
7307 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7308 .wUsage
= HID_USAGE_GENERIC_X
,
7312 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7313 .guidType
= GUID_Button
,
7314 .dwOfs
= version
>= 0x800 ? 0x68 : 0x10,
7315 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER
,
7316 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7317 .tszName
= L
"Button 0",
7318 .wCollectionNumber
= 1,
7319 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7324 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7325 .guidType
= GUID_Button
,
7326 .dwOfs
= version
>= 0x800 ? 0x69 : 0x11,
7327 .dwType
= DIDFT_PSHBUTTON
|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER
,
7328 .dwFlags
= DIDOI_FFEFFECTTRIGGER
,
7329 .tszName
= L
"Button 1",
7330 .wCollectionNumber
= 1,
7331 .wUsagePage
= HID_USAGE_PAGE_BUTTON
,
7336 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7337 .guidType
= GUID_Unknown
,
7338 .dwOfs
= version
>= 0x800 ? 0x70 : 0,
7339 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(12)|DIDFT_OUTPUT
,
7340 .dwFlags
= 0x80008000,
7341 .tszName
= L
"DC Device Reset",
7342 .wCollectionNumber
= 4,
7343 .wUsagePage
= HID_USAGE_PAGE_PID
,
7344 .wUsage
= PID_USAGE_DC_DEVICE_RESET
,
7348 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7349 .guidType
= GUID_Unknown
,
7350 .dwOfs
= version
>= 0x800 ? 0x10 : 0,
7351 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(13)|DIDFT_OUTPUT
,
7352 .dwFlags
= 0x80008000,
7353 .tszName
= L
"Effect Block Index",
7354 .wCollectionNumber
= 5,
7355 .wUsagePage
= HID_USAGE_PAGE_PID
,
7356 .wUsage
= PID_USAGE_EFFECT_BLOCK_INDEX
,
7360 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7361 .guidType
= GUID_Unknown
,
7362 .dwOfs
= version
>= 0x800 ? 0x71 : 0,
7363 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(14)|DIDFT_OUTPUT
,
7364 .dwFlags
= 0x80008000,
7365 .tszName
= L
"Op Effect Start",
7366 .wCollectionNumber
= 6,
7367 .wUsagePage
= HID_USAGE_PAGE_PID
,
7368 .wUsage
= PID_USAGE_OP_EFFECT_START
,
7372 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7373 .guidType
= GUID_Unknown
,
7374 .dwOfs
= version
>= 0x800 ? 0x72 : 0,
7375 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(15)|DIDFT_OUTPUT
,
7376 .dwFlags
= 0x80008000,
7377 .tszName
= L
"Op Effect Start Solo",
7378 .wCollectionNumber
= 6,
7379 .wUsagePage
= HID_USAGE_PAGE_PID
,
7380 .wUsage
= PID_USAGE_OP_EFFECT_START_SOLO
,
7384 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7385 .guidType
= GUID_Unknown
,
7386 .dwOfs
= version
>= 0x800 ? 0x73 : 0,
7387 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(16)|DIDFT_OUTPUT
,
7388 .dwFlags
= 0x80008000,
7389 .tszName
= L
"Op Effect Stop",
7390 .wCollectionNumber
= 6,
7391 .wUsagePage
= HID_USAGE_PAGE_PID
,
7392 .wUsage
= PID_USAGE_OP_EFFECT_STOP
,
7396 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7397 .guidType
= GUID_Unknown
,
7398 .dwOfs
= version
>= 0x800 ? 0x14 : 0,
7399 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(17)|DIDFT_OUTPUT
,
7400 .dwFlags
= 0x80008000,
7401 .tszName
= L
"Loop Count",
7402 .wCollectionNumber
= 5,
7403 .wUsagePage
= HID_USAGE_PAGE_PID
,
7404 .wUsage
= PID_USAGE_LOOP_COUNT
,
7408 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7409 .guidType
= GUID_Unknown
,
7410 .dwOfs
= version
>= 0x800 ? 0x18 : 0,
7411 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(18)|DIDFT_OUTPUT
,
7412 .dwFlags
= 0x80008000,
7413 .tszName
= L
"Effect Block Index",
7414 .wCollectionNumber
= 7,
7415 .wUsagePage
= HID_USAGE_PAGE_PID
,
7416 .wUsage
= PID_USAGE_EFFECT_BLOCK_INDEX
,
7420 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7421 .guidType
= GUID_Unknown
,
7422 .dwOfs
= version
>= 0x800 ? 0x74 : 0,
7423 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(19)|DIDFT_OUTPUT
,
7424 .dwFlags
= 0x80008000,
7425 .tszName
= L
"ET Square",
7426 .wCollectionNumber
= 8,
7427 .wUsagePage
= HID_USAGE_PAGE_PID
,
7428 .wUsage
= PID_USAGE_ET_SQUARE
,
7432 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7433 .guidType
= GUID_Unknown
,
7434 .dwOfs
= version
>= 0x800 ? 0x75 : 0,
7435 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(20)|DIDFT_OUTPUT
,
7436 .dwFlags
= 0x80008000,
7437 .tszName
= L
"ET Sine",
7438 .wCollectionNumber
= 8,
7439 .wUsagePage
= HID_USAGE_PAGE_PID
,
7440 .wUsage
= PID_USAGE_ET_SINE
,
7444 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7445 .guidType
= GUID_Unknown
,
7446 .dwOfs
= version
>= 0x800 ? 0x76 : 0,
7447 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(21)|DIDFT_OUTPUT
,
7448 .dwFlags
= 0x80008000,
7449 .tszName
= L
"ET Spring",
7450 .wCollectionNumber
= 8,
7451 .wUsagePage
= HID_USAGE_PAGE_PID
,
7452 .wUsage
= PID_USAGE_ET_SPRING
,
7456 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7457 .guidType
= GUID_Unknown
,
7458 .dwOfs
= version
>= 0x800 ? 0x77 : 0,
7459 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(22)|DIDFT_OUTPUT
,
7460 .dwFlags
= 0x80008000,
7461 .tszName
= L
"Z Axis",
7462 .wCollectionNumber
= 9,
7463 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7464 .wUsage
= HID_USAGE_GENERIC_Z
,
7468 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7469 .guidType
= GUID_Unknown
,
7470 .dwOfs
= version
>= 0x800 ? 0x78 : 0,
7471 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(23)|DIDFT_OUTPUT
,
7472 .dwFlags
= 0x80008000,
7473 .tszName
= L
"Y Axis",
7474 .wCollectionNumber
= 9,
7475 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7476 .wUsage
= HID_USAGE_GENERIC_Y
,
7480 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7481 .guidType
= GUID_Unknown
,
7482 .dwOfs
= version
>= 0x800 ? 0x79 : 0,
7483 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(24)|DIDFT_OUTPUT
,
7484 .dwFlags
= 0x80008000,
7485 .tszName
= L
"X Axis",
7486 .wCollectionNumber
= 9,
7487 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7488 .wUsage
= HID_USAGE_GENERIC_X
,
7492 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7493 .guidType
= GUID_Unknown
,
7494 .dwOfs
= version
>= 0x800 ? 0x7a : 0,
7495 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(25)|DIDFT_OUTPUT
,
7496 .dwFlags
= 0x80008000,
7497 .tszName
= L
"Direction Enable",
7498 .wCollectionNumber
= 7,
7499 .wUsagePage
= HID_USAGE_PAGE_PID
,
7500 .wUsage
= PID_USAGE_DIRECTION_ENABLE
,
7504 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7505 .guidType
= GUID_Unknown
,
7506 .dwOfs
= version
>= 0x800 ? 0x1c : 0,
7507 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(26)|DIDFT_OUTPUT
,
7508 .dwFlags
= 0x80008000,
7509 .tszName
= L
"Start Delay",
7510 .wCollectionNumber
= 7,
7511 .wUsagePage
= HID_USAGE_PAGE_PID
,
7512 .wUsage
= PID_USAGE_START_DELAY
,
7514 .dwDimension
= 0x1003,
7518 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7519 .guidType
= GUID_Unknown
,
7520 .dwOfs
= version
>= 0x800 ? 0x20 : 0,
7521 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(27)|DIDFT_OUTPUT
,
7522 .dwFlags
= 0x80008000,
7523 .tszName
= L
"Duration",
7524 .wCollectionNumber
= 7,
7525 .wUsagePage
= HID_USAGE_PAGE_PID
,
7526 .wUsage
= PID_USAGE_DURATION
,
7528 .dwDimension
= 0x1003,
7532 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7533 .guidType
= GUID_Unknown
,
7534 .dwOfs
= version
>= 0x800 ? 0x24 : 0,
7535 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(28)|DIDFT_OUTPUT
,
7536 .dwFlags
= 0x80008000,
7537 .tszName
= L
"Trigger Button",
7538 .wCollectionNumber
= 7,
7539 .wUsagePage
= HID_USAGE_PAGE_PID
,
7540 .wUsage
= PID_USAGE_TRIGGER_BUTTON
,
7544 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7545 .guidType
= GUID_Unknown
,
7546 .dwOfs
= version
>= 0x800 ? 0x28 : 0,
7547 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(29)|DIDFT_OUTPUT
,
7548 .dwFlags
= 0x80008000,
7549 .tszName
= L
"Unknown 29",
7550 .wCollectionNumber
= 10,
7551 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7557 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7558 .guidType
= GUID_Unknown
,
7559 .dwOfs
= version
>= 0x800 ? 0x2c : 0,
7560 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(30)|DIDFT_OUTPUT
,
7561 .dwFlags
= 0x80008000,
7562 .tszName
= L
"Unknown 30",
7563 .wCollectionNumber
= 10,
7564 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7570 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7571 .guidType
= GUID_Unknown
,
7572 .dwOfs
= version
>= 0x800 ? 0x30 : 0,
7573 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(31)|DIDFT_OUTPUT
,
7574 .dwFlags
= 0x80008000,
7575 .tszName
= L
"Magnitude",
7576 .wCollectionNumber
= 11,
7577 .wUsagePage
= HID_USAGE_PAGE_PID
,
7578 .wUsage
= PID_USAGE_MAGNITUDE
,
7582 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7583 .guidType
= GUID_Unknown
,
7584 .dwOfs
= version
>= 0x800 ? 0x34 : 0,
7585 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(32)|DIDFT_OUTPUT
,
7586 .dwFlags
= 0x80008000,
7587 .tszName
= L
"Fade Level",
7588 .wCollectionNumber
= 12,
7589 .wUsagePage
= HID_USAGE_PAGE_PID
,
7590 .wUsage
= PID_USAGE_FADE_LEVEL
,
7594 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7595 .guidType
= GUID_Unknown
,
7596 .dwOfs
= version
>= 0x800 ? 0x38 : 0,
7597 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(33)|DIDFT_OUTPUT
,
7598 .dwFlags
= 0x80008000,
7599 .tszName
= L
"Attack Level",
7600 .wCollectionNumber
= 12,
7601 .wUsagePage
= HID_USAGE_PAGE_PID
,
7602 .wUsage
= PID_USAGE_ATTACK_LEVEL
,
7606 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7607 .guidType
= GUID_Unknown
,
7608 .dwOfs
= version
>= 0x800 ? 0x3c : 0,
7609 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(34)|DIDFT_OUTPUT
,
7610 .dwFlags
= 0x80008000,
7611 .tszName
= L
"Fade Time",
7612 .wCollectionNumber
= 12,
7613 .wUsagePage
= HID_USAGE_PAGE_PID
,
7614 .wUsage
= PID_USAGE_FADE_TIME
,
7616 .dwDimension
= 0x1003,
7620 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7621 .guidType
= GUID_Unknown
,
7622 .dwOfs
= version
>= 0x800 ? 0x40 : 0,
7623 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(35)|DIDFT_OUTPUT
,
7624 .dwFlags
= 0x80008000,
7625 .tszName
= L
"Attack Time",
7626 .wCollectionNumber
= 12,
7627 .wUsagePage
= HID_USAGE_PAGE_PID
,
7628 .wUsage
= PID_USAGE_ATTACK_TIME
,
7630 .dwDimension
= 0x1003,
7634 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7635 .guidType
= GUID_Unknown
,
7636 .dwOfs
= version
>= 0x800 ? 0x44 : 0,
7637 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(36)|DIDFT_OUTPUT
,
7638 .dwFlags
= 0x80008000,
7639 .tszName
= L
"Unknown 36",
7640 .wCollectionNumber
= 14,
7641 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7646 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7647 .guidType
= GUID_Unknown
,
7648 .dwOfs
= version
>= 0x800 ? 0x48 : 0,
7649 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(37)|DIDFT_OUTPUT
,
7650 .dwFlags
= 0x80008000,
7651 .tszName
= L
"Unknown 37",
7652 .wCollectionNumber
= 14,
7653 .wUsagePage
= HID_USAGE_PAGE_ORDINAL
,
7658 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7659 .guidType
= GUID_Unknown
,
7660 .dwOfs
= version
>= 0x800 ? 0x4c : 0,
7661 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(38)|DIDFT_OUTPUT
,
7662 .dwFlags
= 0x80008000,
7663 .tszName
= L
"CP Offset",
7664 .wCollectionNumber
= 13,
7665 .wUsagePage
= HID_USAGE_PAGE_PID
,
7666 .wUsage
= PID_USAGE_CP_OFFSET
,
7670 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7671 .guidType
= GUID_Unknown
,
7672 .dwOfs
= version
>= 0x800 ? 0x50 : 0,
7673 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(39)|DIDFT_OUTPUT
,
7674 .dwFlags
= 0x80008000,
7675 .tszName
= L
"Negative Coefficient",
7676 .wCollectionNumber
= 13,
7677 .wUsagePage
= HID_USAGE_PAGE_PID
,
7678 .wUsage
= PID_USAGE_NEGATIVE_COEFFICIENT
,
7682 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7683 .guidType
= GUID_Unknown
,
7684 .dwOfs
= version
>= 0x800 ? 0x54 : 0,
7685 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(40)|DIDFT_OUTPUT
,
7686 .dwFlags
= 0x80008000,
7687 .tszName
= L
"Positive Coefficient",
7688 .wCollectionNumber
= 13,
7689 .wUsagePage
= HID_USAGE_PAGE_PID
,
7690 .wUsage
= PID_USAGE_POSITIVE_COEFFICIENT
,
7694 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7695 .guidType
= GUID_Unknown
,
7696 .dwOfs
= version
>= 0x800 ? 0x58 : 0,
7697 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(41)|DIDFT_OUTPUT
,
7698 .dwFlags
= 0x80008000,
7699 .tszName
= L
"Negative Saturation",
7700 .wCollectionNumber
= 13,
7701 .wUsagePage
= HID_USAGE_PAGE_PID
,
7702 .wUsage
= PID_USAGE_NEGATIVE_SATURATION
,
7706 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7707 .guidType
= GUID_Unknown
,
7708 .dwOfs
= version
>= 0x800 ? 0x5c : 0,
7709 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(42)|DIDFT_OUTPUT
,
7710 .dwFlags
= 0x80008000,
7711 .tszName
= L
"Positive Saturation",
7712 .wCollectionNumber
= 13,
7713 .wUsagePage
= HID_USAGE_PAGE_PID
,
7714 .wUsage
= PID_USAGE_POSITIVE_SATURATION
,
7718 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7719 .guidType
= GUID_Unknown
,
7720 .dwOfs
= version
>= 0x800 ? 0x60 : 0,
7721 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(43)|DIDFT_OUTPUT
,
7722 .dwFlags
= 0x80008000,
7723 .tszName
= L
"Dead Band",
7724 .wCollectionNumber
= 13,
7725 .wUsagePage
= HID_USAGE_PAGE_PID
,
7726 .wUsage
= PID_USAGE_DEAD_BAND
,
7730 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7731 .guidType
= GUID_Unknown
,
7732 .dwOfs
= version
>= 0x800 ? 0x64 : 0,
7733 .dwType
= DIDFT_NODATA
|DIDFT_MAKEINSTANCE(44)|DIDFT_OUTPUT
,
7734 .dwFlags
= 0x80008000,
7735 .tszName
= L
"Device Gain",
7736 .wCollectionNumber
= 15,
7737 .wUsagePage
= HID_USAGE_PAGE_PID
,
7738 .wUsage
= PID_USAGE_DEVICE_GAIN
,
7742 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7743 .guidType
= GUID_Unknown
,
7744 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(0),
7745 .tszName
= L
"Collection 0 - Joystick",
7746 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7747 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
7750 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7751 .guidType
= GUID_Unknown
,
7752 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(1),
7753 .tszName
= L
"Collection 1 - Joystick",
7754 .wUsagePage
= HID_USAGE_PAGE_GENERIC
,
7755 .wUsage
= HID_USAGE_GENERIC_JOYSTICK
,
7758 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7759 .guidType
= GUID_Unknown
,
7760 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(2),
7761 .tszName
= L
"Collection 2 - PID State Report",
7762 .wUsagePage
= HID_USAGE_PAGE_PID
,
7763 .wUsage
= PID_USAGE_STATE_REPORT
,
7766 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7767 .guidType
= GUID_Unknown
,
7768 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(3),
7769 .tszName
= L
"Collection 3 - PID Device Control Report",
7770 .wUsagePage
= HID_USAGE_PAGE_PID
,
7771 .wUsage
= PID_USAGE_DEVICE_CONTROL_REPORT
,
7774 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7775 .guidType
= GUID_Unknown
,
7776 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(4),
7777 .tszName
= L
"Collection 4 - PID Device Control",
7778 .wCollectionNumber
= 3,
7779 .wUsagePage
= HID_USAGE_PAGE_PID
,
7780 .wUsage
= PID_USAGE_DEVICE_CONTROL
,
7783 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7784 .guidType
= GUID_Unknown
,
7785 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(5),
7786 .tszName
= L
"Collection 5 - Effect Operation Report",
7787 .wUsagePage
= HID_USAGE_PAGE_PID
,
7788 .wUsage
= PID_USAGE_EFFECT_OPERATION_REPORT
,
7791 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7792 .guidType
= GUID_Unknown
,
7793 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(6),
7794 .tszName
= L
"Collection 6 - Effect Operation",
7795 .wCollectionNumber
= 5,
7796 .wUsagePage
= HID_USAGE_PAGE_PID
,
7797 .wUsage
= PID_USAGE_EFFECT_OPERATION
,
7800 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7801 .guidType
= GUID_Unknown
,
7802 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(7),
7803 .tszName
= L
"Collection 7 - Set Effect Report",
7804 .wUsagePage
= HID_USAGE_PAGE_PID
,
7805 .wUsage
= PID_USAGE_SET_EFFECT_REPORT
,
7808 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7809 .guidType
= GUID_Unknown
,
7810 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(8),
7811 .tszName
= L
"Collection 8 - Effect Type",
7812 .wCollectionNumber
= 7,
7813 .wUsagePage
= HID_USAGE_PAGE_PID
,
7814 .wUsage
= PID_USAGE_EFFECT_TYPE
,
7817 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7818 .guidType
= GUID_Unknown
,
7819 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(9),
7820 .tszName
= L
"Collection 9 - Axes Enable",
7821 .wCollectionNumber
= 7,
7822 .wUsagePage
= HID_USAGE_PAGE_PID
,
7823 .wUsage
= PID_USAGE_AXES_ENABLE
,
7826 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7827 .guidType
= GUID_Unknown
,
7828 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(10),
7829 .tszName
= L
"Collection 10 - Direction",
7830 .wCollectionNumber
= 7,
7831 .wUsagePage
= HID_USAGE_PAGE_PID
,
7832 .wUsage
= PID_USAGE_DIRECTION
,
7835 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7836 .guidType
= GUID_Unknown
,
7837 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(11),
7838 .tszName
= L
"Collection 11 - Set Periodic Report",
7839 .wUsagePage
= HID_USAGE_PAGE_PID
,
7840 .wUsage
= PID_USAGE_SET_PERIODIC_REPORT
,
7843 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7844 .guidType
= GUID_Unknown
,
7845 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(12),
7846 .tszName
= L
"Collection 12 - Set Envelope Report",
7847 .wUsagePage
= HID_USAGE_PAGE_PID
,
7848 .wUsage
= PID_USAGE_SET_ENVELOPE_REPORT
,
7851 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7852 .guidType
= GUID_Unknown
,
7853 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(13),
7854 .tszName
= L
"Collection 13 - Set Condition Report",
7855 .wUsagePage
= HID_USAGE_PAGE_PID
,
7856 .wUsage
= PID_USAGE_SET_CONDITION_REPORT
,
7859 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7860 .guidType
= GUID_Unknown
,
7861 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(14),
7862 .tszName
= L
"Collection 14 - Type Specific Block Offset",
7863 .wCollectionNumber
= 13,
7864 .wUsagePage
= HID_USAGE_PAGE_PID
,
7865 .wUsage
= PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
,
7868 .dwSize
= sizeof(DIDEVICEOBJECTINSTANCEW
),
7869 .guidType
= GUID_Unknown
,
7870 .dwType
= DIDFT_COLLECTION
|DIDFT_NODATA
|DIDFT_MAKEINSTANCE(15),
7871 .tszName
= L
"Collection 15 - Device Gain Report",
7872 .wUsagePage
= HID_USAGE_PAGE_PID
,
7873 .wUsage
= PID_USAGE_DEVICE_GAIN_REPORT
,
7876 const DIEFFECTINFOW expect_effects
[] =
7879 .dwSize
= sizeof(DIEFFECTINFOW
),
7880 .guid
= GUID_Square
,
7881 .dwEffType
= DIEFT_PERIODIC
| DIEFT_STARTDELAY
| DIEFT_FFFADE
| DIEFT_FFATTACK
,
7882 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7883 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7884 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7885 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7886 .tszName
= L
"GUID_Square",
7889 .dwSize
= sizeof(DIEFFECTINFOW
),
7891 .dwEffType
= DIEFT_PERIODIC
| DIEFT_STARTDELAY
| DIEFT_FFFADE
| DIEFT_FFATTACK
,
7892 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7893 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7894 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7895 DIEP_DURATION
| DIEP_TRIGGERBUTTON
| DIEP_ENVELOPE
,
7896 .tszName
= L
"GUID_Sine",
7899 .dwSize
= sizeof(DIEFFECTINFOW
),
7900 .guid
= GUID_Spring
,
7901 .dwEffType
= DIEFT_CONDITION
| DIEFT_STARTDELAY
| DIEFT_DEADBAND
| DIEFT_SATURATION
,
7902 .dwStaticParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7904 .dwDynamicParams
= DIEP_AXES
| DIEP_DIRECTION
| DIEP_TYPESPECIFICPARAMS
| DIEP_STARTDELAY
|
7906 .tszName
= L
"GUID_Spring",
7910 struct check_objects_todos todo_objects_5
[ARRAY_SIZE(expect_objects_5
)] =
7912 {.guid
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .name
= TRUE
},
7914 {.guid
= TRUE
, .type
= TRUE
, .usage
= TRUE
, .name
= TRUE
},
7916 struct check_objects_params check_objects_params
=
7919 .expect_count
= version
< 0x700 ? ARRAY_SIZE(expect_objects_5
) : ARRAY_SIZE(expect_objects
),
7920 .expect_objs
= version
< 0x700 ? expect_objects_5
: expect_objects
,
7921 .todo_objs
= version
< 0x700 ? todo_objects_5
: NULL
,
7922 .todo_extra
= version
< 0x700 ? TRUE
: FALSE
,
7924 struct check_effects_params check_effects_params
=
7926 .expect_count
= ARRAY_SIZE(expect_effects
),
7927 .expect_effects
= expect_effects
,
7929 DIPROPDWORD prop_dword
=
7933 .dwSize
= sizeof(DIPROPDWORD
),
7934 .dwHeaderSize
= sizeof(DIPROPHEADER
),
7935 .dwHow
= DIPH_DEVICE
,
7938 DIPROPGUIDANDPATH prop_guid_path
=
7942 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
7943 .dwHeaderSize
= sizeof(DIPROPHEADER
),
7944 .dwHow
= DIPH_DEVICE
,
7947 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
7948 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
7949 DIDEVICEOBJECTDATA objdata
= {0};
7950 DIEFFECTINFOW effectinfo
= {0};
7951 IDirectInputDevice8W
*device
;
7952 DIEFFESCAPE escape
= {0};
7953 DIDEVCAPS caps
= {0};
7960 winetest_push_context( "version %#x", version
);
7962 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
7963 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
7964 SetCurrentDirectoryW( tempdir
);
7966 cleanup_registry_keys();
7967 if (!dinput_driver_start( report_descriptor
, sizeof(report_descriptor
), &hid_caps
, NULL
, 0 )) goto done
;
7968 if (FAILED(hr
= create_dinput_device( version
, &devinst
, &device
))) goto done
;
7970 hr
= IDirectInputDevice8_GetDeviceInfo( device
, &devinst
);
7971 ok( hr
== DI_OK
, "GetDeviceInfo returned %#x\n", hr
);
7972 check_member( devinst
, expect_devinst
, "%d", dwSize
);
7974 check_member_guid( devinst
, expect_devinst
, guidInstance
);
7975 check_member_guid( devinst
, expect_devinst
, guidProduct
);
7976 check_member( devinst
, expect_devinst
, "%#x", dwDevType
);
7978 check_member_wstr( devinst
, expect_devinst
, tszInstanceName
);
7980 check_member_wstr( devinst
, expect_devinst
, tszProductName
);
7981 check_member_guid( devinst
, expect_devinst
, guidFFDriver
);
7982 check_member( devinst
, expect_devinst
, "%04x", wUsagePage
);
7983 check_member( devinst
, expect_devinst
, "%04x", wUsage
);
7985 caps
.dwSize
= sizeof(DIDEVCAPS
);
7986 hr
= IDirectInputDevice8_GetCapabilities( device
, &caps
);
7987 ok( hr
== DI_OK
, "GetCapabilities returned %#x\n", hr
);
7988 check_member( caps
, expect_caps
, "%d", dwSize
);
7989 check_member( caps
, expect_caps
, "%#x", dwFlags
);
7990 check_member( caps
, expect_caps
, "%#x", dwDevType
);
7991 check_member( caps
, expect_caps
, "%d", dwAxes
);
7992 check_member( caps
, expect_caps
, "%d", dwButtons
);
7993 check_member( caps
, expect_caps
, "%d", dwPOVs
);
7994 check_member( caps
, expect_caps
, "%d", dwFFSamplePeriod
);
7995 check_member( caps
, expect_caps
, "%d", dwFFMinTimeResolution
);
7996 check_member( caps
, expect_caps
, "%d", dwFirmwareRevision
);
7997 check_member( caps
, expect_caps
, "%d", dwHardwareRevision
);
7998 check_member( caps
, expect_caps
, "%d", dwFFDriverVersion
);
8000 prop_dword
.dwData
= 0xdeadbeef;
8001 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8002 ok( hr
== DI_OK
, "GetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8003 ok( prop_dword
.dwData
== 10000, "got %u expected %u\n", prop_dword
.dwData
, 10000 );
8005 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8006 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8008 hr
= IDirectInputDevice8_EnumObjects( device
, check_objects
, &check_objects_params
, DIDFT_ALL
);
8009 ok( hr
== DI_OK
, "EnumObjects returned %#x\n", hr
);
8010 ok( check_objects_params
.index
>= check_objects_params
.expect_count
, "missing %u objects\n",
8011 check_objects_params
.expect_count
- check_objects_params
.index
);
8014 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, 0xfe );
8015 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
8016 ok( res
== 0, "got %u expected %u\n", res
, 0 );
8018 hr
= IDirectInputDevice8_EnumEffects( device
, check_effect_count
, &res
, DIEFT_PERIODIC
);
8019 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
8020 ok( res
== 2, "got %u expected %u\n", res
, 2 );
8021 hr
= IDirectInputDevice8_EnumEffects( device
, check_effects
, &check_effects_params
, DIEFT_ALL
);
8022 ok( hr
== DI_OK
, "EnumEffects returned %#x\n", hr
);
8023 ok( check_effects_params
.index
>= check_effects_params
.expect_count
, "missing %u effects\n",
8024 check_effects_params
.expect_count
- check_effects_params
.index
);
8026 effectinfo
.dwSize
= sizeof(DIEFFECTINFOW
);
8027 hr
= IDirectInputDevice8_GetEffectInfo( device
, &effectinfo
, &GUID_Sine
);
8028 ok( hr
== DI_OK
, "GetEffectInfo returned %#x\n", hr
);
8029 check_member_guid( effectinfo
, expect_effects
[1], guid
);
8030 check_member( effectinfo
, expect_effects
[1], "%#x", dwEffType
);
8031 check_member( effectinfo
, expect_effects
[1], "%#x", dwStaticParams
);
8032 check_member( effectinfo
, expect_effects
[1], "%#x", dwDynamicParams
);
8033 check_member_wstr( effectinfo
, expect_effects
[1], tszName
);
8035 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
8036 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
8038 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
8039 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
8041 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
8042 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
8043 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
8044 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
8046 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
8047 NULL
, NULL
, NULL
, NULL
);
8049 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_NONEXCLUSIVE
);
8050 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
8052 prop_dword
.diph
.dwHow
= DIPH_BYUSAGE
;
8053 prop_dword
.diph
.dwObj
= MAKELONG( HID_USAGE_GENERIC_X
, HID_USAGE_PAGE_GENERIC
);
8054 prop_dword
.dwData
= DIPROPAUTOCENTER_ON
;
8055 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
8056 ok( hr
== DIERR_UNSUPPORTED
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
8057 prop_dword
.diph
.dwHow
= DIPH_DEVICE
;
8058 prop_dword
.diph
.dwObj
= 0;
8059 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_AUTOCENTER
, &prop_dword
.diph
);
8060 ok( hr
== DI_OK
, "SetProperty DIPROP_AUTOCENTER returned %#x\n", hr
);
8062 hr
= IDirectInputDevice8_Acquire( device
);
8063 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
8065 prop_dword
.dwData
= 0xdeadbeef;
8066 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8067 ok( hr
== DIERR_INVALIDPARAM
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8068 prop_dword
.dwData
= 1000;
8069 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8070 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8072 prop_dword
.dwData
= 0xdeadbeef;
8073 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8074 ok( hr
== DIERR_READONLY
, "SetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8075 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8076 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8077 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8078 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetForceFeedbackState returned %#x\n", hr
);
8079 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
8080 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "SendForceFeedbackCommand returned %#x\n", hr
);
8082 escape
.dwSize
= sizeof(DIEFFESCAPE
);
8083 escape
.dwCommand
= 0;
8084 escape
.lpvInBuffer
= buffer
;
8085 escape
.cbInBuffer
= 10;
8086 escape
.lpvOutBuffer
= buffer
+ 10;
8087 escape
.cbOutBuffer
= 10;
8088 hr
= IDirectInputDevice8_Escape( device
, &escape
);
8090 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "Escape returned: %#x\n", hr
);
8092 hr
= IDirectInputDevice8_Unacquire( device
);
8093 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
8094 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
8095 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
8097 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
8098 hr
= IDirectInputDevice8_Acquire( device
);
8099 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
8100 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8102 set_hid_expect( file
, &expect_set_device_gain_2
, sizeof(expect_set_device_gain_2
) );
8103 prop_dword
.dwData
= 2000;
8104 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8105 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8106 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8108 set_hid_expect( file
, &expect_set_device_gain_1
, sizeof(expect_set_device_gain_1
) );
8109 prop_dword
.dwData
= 1000;
8110 hr
= IDirectInputDevice8_SetProperty( device
, DIPROP_FFGAIN
, &prop_dword
.diph
);
8111 ok( hr
== DI_OK
, "SetProperty DIPROP_FFGAIN returned %#x\n", hr
);
8112 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8114 hr
= IDirectInputDevice8_Escape( device
, &escape
);
8116 ok( hr
== DIERR_UNSUPPORTED
, "Escape returned: %#x\n", hr
);
8118 prop_dword
.dwData
= 0xdeadbeef;
8119 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
8121 ok( hr
== 0x80040301, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
8123 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
8125 ok( hr
== 0x80040301, "GetForceFeedbackState returned %#x\n", hr
);
8127 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, 0xdeadbeef );
8128 ok( hr
== DIERR_INVALIDPARAM
, "SendForceFeedbackCommand returned %#x\n", hr
);
8130 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
8131 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
8132 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#x\n", hr
);
8133 wait_hid_expect( file
, 100 ); /* device gain reports are written asynchronously */
8135 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_STOPALL
);
8136 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8137 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_PAUSE
);
8138 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8139 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_CONTINUE
);
8140 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8141 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSON
);
8142 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8143 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSOFF
);
8144 ok( hr
== HIDP_STATUS_USAGE_NOT_FOUND
, "SendForceFeedbackCommand returned %#x\n", hr
);
8146 objdata
.dwOfs
= 0x1e;
8147 objdata
.dwData
= 0x80;
8149 hr
= IDirectInputDevice8_SendDeviceData( device
, sizeof(DIDEVICEOBJECTDATA
), &objdata
, &res
, 0 );
8150 if (version
< 0x800) ok( hr
== DI_OK
, "SendDeviceData returned %#x\n", hr
);
8151 else todo_wine
ok( hr
== DIERR_INVALIDPARAM
, "SendDeviceData returned %#x\n", hr
);
8153 test_periodic_effect( device
, file
, version
);
8154 test_condition_effect( device
, file
, version
);
8156 set_hid_expect( file
, expect_reset
, sizeof(expect_reset
) );
8157 hr
= IDirectInputDevice8_Unacquire( device
);
8158 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
8159 set_hid_expect( file
, NULL
, 0 );
8161 ref
= IDirectInputDevice8_Release( device
);
8162 ok( ref
== 0, "Release returned %d\n", ref
);
8164 DestroyWindow( hwnd
);
8165 CloseHandle( file
);
8169 cleanup_registry_keys();
8170 SetCurrentDirectoryW( cwd
);
8171 winetest_pop_context();
8174 static void test_device_managed_effect(void)
8176 #include "psh_hid_macros.h"
8177 const unsigned char report_descriptor
[] = {
8178 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
8179 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
8180 COLLECTION(1, Application
),
8181 USAGE(1, HID_USAGE_GENERIC_JOYSTICK
),
8182 COLLECTION(1, Report
),
8185 USAGE(1, HID_USAGE_GENERIC_X
),
8186 USAGE(1, HID_USAGE_GENERIC_Y
),
8187 USAGE(1, HID_USAGE_GENERIC_Z
),
8188 LOGICAL_MINIMUM(1, 0),
8189 LOGICAL_MAXIMUM(1, 0x7f),
8190 PHYSICAL_MINIMUM(1, 0),
8191 PHYSICAL_MAXIMUM(1, 0x7f),
8194 INPUT(1, Data
|Var
|Abs
),
8196 USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON
),
8197 USAGE_MINIMUM(1, 1),
8198 USAGE_MAXIMUM(1, 2),
8199 LOGICAL_MINIMUM(1, 0),
8200 LOGICAL_MAXIMUM(1, 1),
8201 PHYSICAL_MINIMUM(1, 0),
8202 PHYSICAL_MAXIMUM(1, 1),
8205 INPUT(1, Data
|Var
|Abs
),
8207 INPUT(1, Cnst
|Var
|Abs
),
8210 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
8211 USAGE(1, PID_USAGE_STATE_REPORT
),
8212 COLLECTION(1, Report
),
8215 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
8216 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
8217 USAGE(1, PID_USAGE_SAFETY_SWITCH
),
8218 USAGE(1, PID_USAGE_ACTUATOR_OVERRIDE_SWITCH
),
8219 USAGE(1, PID_USAGE_ACTUATOR_POWER
),
8220 LOGICAL_MINIMUM(1, 0),
8221 LOGICAL_MAXIMUM(1, 1),
8222 PHYSICAL_MINIMUM(1, 0),
8223 PHYSICAL_MAXIMUM(1, 1),
8226 INPUT(1, Data
|Var
|Abs
),
8228 INPUT(1, Cnst
|Var
|Abs
),
8230 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
8231 LOGICAL_MINIMUM(1, 0),
8232 LOGICAL_MAXIMUM(1, 1),
8233 PHYSICAL_MINIMUM(1, 0),
8234 PHYSICAL_MAXIMUM(1, 1),
8237 INPUT(1, Data
|Var
|Abs
),
8239 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8240 LOGICAL_MINIMUM(1, 1),
8241 LOGICAL_MAXIMUM(1, 0x7f),
8242 PHYSICAL_MINIMUM(1, 1),
8243 PHYSICAL_MAXIMUM(1, 0x7f),
8246 INPUT(1, Data
|Var
|Abs
),
8249 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
8250 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
8251 COLLECTION(1, Report
),
8254 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
8255 COLLECTION(1, Logical
),
8256 USAGE(1, PID_USAGE_DC_DEVICE_RESET
),
8257 USAGE(1, PID_USAGE_DC_DEVICE_PAUSE
),
8258 USAGE(1, PID_USAGE_DC_DEVICE_CONTINUE
),
8259 USAGE(1, PID_USAGE_DC_ENABLE_ACTUATORS
),
8260 USAGE(1, PID_USAGE_DC_DISABLE_ACTUATORS
),
8261 USAGE(1, PID_USAGE_DC_STOP_ALL_EFFECTS
),
8262 LOGICAL_MINIMUM(1, 1),
8263 LOGICAL_MAXIMUM(1, 6),
8264 PHYSICAL_MINIMUM(1, 1),
8265 PHYSICAL_MAXIMUM(1, 6),
8268 OUTPUT(1, Data
|Ary
|Abs
),
8272 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
8273 COLLECTION(1, Report
),
8276 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8277 LOGICAL_MINIMUM(1, 1),
8278 LOGICAL_MAXIMUM(1, 0x7f),
8279 PHYSICAL_MINIMUM(1, 1),
8280 PHYSICAL_MAXIMUM(1, 0x7f),
8283 OUTPUT(1, Data
|Var
|Abs
),
8285 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
8286 COLLECTION(1, NamedArray
),
8287 USAGE(1, PID_USAGE_OP_EFFECT_START
),
8288 USAGE(1, PID_USAGE_OP_EFFECT_START_SOLO
),
8289 USAGE(1, PID_USAGE_OP_EFFECT_STOP
),
8290 LOGICAL_MINIMUM(1, 1),
8291 LOGICAL_MAXIMUM(1, 3),
8292 PHYSICAL_MINIMUM(1, 1),
8293 PHYSICAL_MAXIMUM(1, 3),
8296 OUTPUT(1, Data
|Ary
|Abs
),
8299 USAGE(1, PID_USAGE_LOOP_COUNT
),
8300 LOGICAL_MINIMUM(1, 0),
8301 LOGICAL_MAXIMUM(1, 0x7f),
8302 PHYSICAL_MINIMUM(1, 0),
8303 PHYSICAL_MAXIMUM(1, 0x7f),
8306 OUTPUT(1, Data
|Var
|Abs
),
8309 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
8310 COLLECTION(1, Report
),
8313 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8314 LOGICAL_MINIMUM(1, 1),
8315 LOGICAL_MAXIMUM(1, 0x7f),
8316 PHYSICAL_MINIMUM(1, 1),
8317 PHYSICAL_MAXIMUM(1, 0x7f),
8320 OUTPUT(1, Data
|Var
|Abs
),
8322 USAGE(1, PID_USAGE_EFFECT_TYPE
),
8323 COLLECTION(1, NamedArray
),
8324 USAGE(1, PID_USAGE_ET_SQUARE
),
8325 USAGE(1, PID_USAGE_ET_SINE
),
8326 USAGE(1, PID_USAGE_ET_SPRING
),
8327 LOGICAL_MINIMUM(1, 1),
8328 LOGICAL_MAXIMUM(1, 3),
8329 PHYSICAL_MINIMUM(1, 1),
8330 PHYSICAL_MAXIMUM(1, 3),
8333 OUTPUT(1, Data
|Ary
|Abs
),
8336 USAGE(1, PID_USAGE_AXES_ENABLE
),
8337 COLLECTION(1, Logical
),
8338 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_X
),
8339 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Y
),
8340 USAGE(4, (HID_USAGE_PAGE_GENERIC
<< 16)|HID_USAGE_GENERIC_Z
),
8341 LOGICAL_MINIMUM(1, 0),
8342 LOGICAL_MAXIMUM(1, 1),
8343 PHYSICAL_MINIMUM(1, 0),
8344 PHYSICAL_MAXIMUM(1, 1),
8347 OUTPUT(1, Data
|Var
|Abs
),
8349 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
8351 OUTPUT(1, Data
|Var
|Abs
),
8353 OUTPUT(1, Cnst
|Var
|Abs
),
8355 USAGE(1, PID_USAGE_DURATION
),
8356 USAGE(1, PID_USAGE_START_DELAY
),
8357 UNIT(2, 0x1003), /* Eng Lin:Time */
8358 UNIT_EXPONENT(1, -3), /* 10^-3 */
8359 LOGICAL_MINIMUM(1, 0),
8360 LOGICAL_MAXIMUM(2, 0x7fff),
8361 PHYSICAL_MINIMUM(1, 0),
8362 PHYSICAL_MAXIMUM(2, 0x7fff),
8365 OUTPUT(1, Data
|Var
|Abs
),
8367 UNIT_EXPONENT(1, 0),
8369 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
8370 LOGICAL_MINIMUM(1, 1),
8371 LOGICAL_MAXIMUM(1, 0x08),
8372 PHYSICAL_MINIMUM(1, 1),
8373 PHYSICAL_MAXIMUM(1, 0x08),
8376 OUTPUT(1, Data
|Var
|Abs
),
8378 USAGE(1, PID_USAGE_DIRECTION
),
8379 COLLECTION(1, Logical
),
8380 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
8381 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
8382 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
8383 UNIT_EXPONENT(1, -2), /* 10^-2 */
8384 LOGICAL_MINIMUM(1, 0),
8385 LOGICAL_MAXIMUM(2, 0x00ff),
8386 PHYSICAL_MINIMUM(1, 0),
8387 PHYSICAL_MAXIMUM(4, 0x00008ca0),
8391 OUTPUT(1, Data
|Var
|Abs
),
8392 UNIT_EXPONENT(1, 0),
8397 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
8398 COLLECTION(1, Logical
),
8401 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8402 LOGICAL_MINIMUM(1, 1),
8403 LOGICAL_MAXIMUM(1, 0x7f),
8404 PHYSICAL_MINIMUM(1, 1),
8405 PHYSICAL_MAXIMUM(1, 0x7f),
8408 OUTPUT(1, Data
|Var
|Abs
),
8410 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET
),
8411 LOGICAL_MINIMUM(1, 0),
8412 LOGICAL_MAXIMUM(1, 1),
8413 PHYSICAL_MINIMUM(1, 0),
8414 PHYSICAL_MAXIMUM(1, 1),
8417 OUTPUT(1, Data
|Var
|Abs
),
8419 USAGE(1, PID_USAGE_TYPE_SPECIFIC_BLOCK_OFFSET
),
8420 COLLECTION(1, Logical
),
8421 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|1),
8422 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<< 16)|2),
8423 LOGICAL_MINIMUM(1, 0),
8424 LOGICAL_MAXIMUM(1, 1),
8425 PHYSICAL_MINIMUM(1, 0),
8426 PHYSICAL_MAXIMUM(1, 1),
8429 OUTPUT(1, Data
|Var
|Abs
),
8432 USAGE(1, PID_USAGE_CP_OFFSET
),
8433 LOGICAL_MINIMUM(1, 0x80),
8434 LOGICAL_MAXIMUM(1, 0x7f),
8435 PHYSICAL_MINIMUM(2, 0xd8f0),
8436 PHYSICAL_MAXIMUM(2, 0x2710),
8439 OUTPUT(1, Data
|Var
|Abs
),
8441 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
8442 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
8443 LOGICAL_MINIMUM(1, 0x80),
8444 LOGICAL_MAXIMUM(1, 0x7f),
8445 PHYSICAL_MINIMUM(2, 0xd8f0),
8446 PHYSICAL_MAXIMUM(2, 0x2710),
8449 OUTPUT(1, Data
|Var
|Abs
),
8451 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
8452 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
8453 LOGICAL_MINIMUM(1, 0),
8454 LOGICAL_MAXIMUM(2, 0x00ff),
8455 PHYSICAL_MINIMUM(1, 0),
8456 PHYSICAL_MAXIMUM(2, 0x2710),
8459 OUTPUT(1, Data
|Var
|Abs
),
8461 USAGE(1, PID_USAGE_DEAD_BAND
),
8462 LOGICAL_MINIMUM(1, 0),
8463 LOGICAL_MAXIMUM(2, 0x00ff),
8464 PHYSICAL_MINIMUM(1, 0),
8465 PHYSICAL_MAXIMUM(2, 0x2710),
8468 OUTPUT(1, Data
|Var
|Abs
),
8471 USAGE(1, PID_USAGE_BLOCK_FREE_REPORT
),
8472 COLLECTION(1, Logical
),
8475 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8476 LOGICAL_MINIMUM(1, 1),
8477 LOGICAL_MAXIMUM(1, 0x7f),
8478 PHYSICAL_MINIMUM(1, 1),
8479 PHYSICAL_MAXIMUM(1, 0x7f),
8482 OUTPUT(1, Data
|Var
|Abs
),
8485 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT
),
8486 COLLECTION(1, Logical
),
8489 USAGE(1, PID_USAGE_DEVICE_GAIN
),
8490 LOGICAL_MINIMUM(1, 0),
8491 LOGICAL_MAXIMUM(2, 0x00ff),
8492 PHYSICAL_MINIMUM(1, 0),
8493 PHYSICAL_MAXIMUM(2, 0x2710),
8496 OUTPUT(1, Data
|Var
|Abs
),
8499 USAGE(1, PID_USAGE_POOL_REPORT
),
8500 COLLECTION(1, Logical
),
8503 USAGE(1, PID_USAGE_RAM_POOL_SIZE
),
8504 LOGICAL_MINIMUM(1, 0),
8505 LOGICAL_MAXIMUM(4, 0xffff),
8506 PHYSICAL_MINIMUM(1, 0),
8507 PHYSICAL_MAXIMUM(4, 0xffff),
8510 FEATURE(1, Data
|Var
|Abs
),
8512 USAGE(1, PID_USAGE_SIMULTANEOUS_EFFECTS_MAX
),
8513 LOGICAL_MINIMUM(1, 0),
8514 LOGICAL_MAXIMUM(1, 0x7f),
8515 PHYSICAL_MINIMUM(1, 0),
8516 PHYSICAL_MAXIMUM(1, 0x7f),
8519 FEATURE(1, Data
|Var
|Abs
),
8521 USAGE(1, PID_USAGE_DEVICE_MANAGED_POOL
),
8522 USAGE(1, PID_USAGE_SHARED_PARAMETER_BLOCKS
),
8523 LOGICAL_MINIMUM(1, 0),
8524 LOGICAL_MAXIMUM(1, 1),
8525 PHYSICAL_MINIMUM(1, 0),
8526 PHYSICAL_MAXIMUM(1, 1),
8529 FEATURE(1, Data
|Var
|Abs
),
8532 USAGE(1, PID_USAGE_CREATE_NEW_EFFECT_REPORT
),
8533 COLLECTION(1, Logical
),
8536 USAGE(1, PID_USAGE_EFFECT_TYPE
),
8537 COLLECTION(1, NamedArray
),
8538 USAGE(1, PID_USAGE_ET_SQUARE
),
8539 USAGE(1, PID_USAGE_ET_SINE
),
8540 USAGE(1, PID_USAGE_ET_SPRING
),
8541 LOGICAL_MINIMUM(1, 1),
8542 LOGICAL_MAXIMUM(1, 3),
8543 PHYSICAL_MINIMUM(1, 1),
8544 PHYSICAL_MAXIMUM(1, 3),
8547 FEATURE(1, Data
|Ary
|Abs
),
8551 USAGE(1, PID_USAGE_BLOCK_LOAD_REPORT
),
8552 COLLECTION(1, Logical
),
8555 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
8556 LOGICAL_MINIMUM(1, 1),
8557 LOGICAL_MAXIMUM(1, 0x7f),
8558 PHYSICAL_MINIMUM(1, 1),
8559 PHYSICAL_MAXIMUM(1, 0x7f),
8562 FEATURE(1, Data
|Var
|Abs
),
8564 USAGE(1, PID_USAGE_BLOCK_LOAD_STATUS
),
8565 COLLECTION(1, NamedArray
),
8566 USAGE(1, PID_USAGE_BLOCK_LOAD_SUCCESS
),
8567 USAGE(1, PID_USAGE_BLOCK_LOAD_FULL
),
8568 USAGE(1, PID_USAGE_BLOCK_LOAD_ERROR
),
8569 LOGICAL_MINIMUM(1, 1),
8570 LOGICAL_MAXIMUM(1, 3),
8571 PHYSICAL_MINIMUM(1, 1),
8572 PHYSICAL_MAXIMUM(1, 3),
8575 FEATURE(1, Data
|Ary
|Abs
),
8578 USAGE(1, PID_USAGE_RAM_POOL_AVAILABLE
),
8579 LOGICAL_MINIMUM(1, 0),
8580 LOGICAL_MAXIMUM(4, 0xffff),
8581 PHYSICAL_MINIMUM(1, 0),
8582 PHYSICAL_MAXIMUM(4, 0xffff),
8585 FEATURE(1, Data
|Var
|Abs
),
8589 #include "pop_hid_macros.h"
8591 static const HIDP_CAPS hid_caps
=
8593 .InputReportByteLength
= 5,
8595 struct hid_expect expect_acquire
[] =
8597 /* device control */
8599 .code
= IOCTL_HID_WRITE_REPORT
,
8602 .report_buf
= {1, 0x01},
8606 .code
= IOCTL_HID_WRITE_REPORT
,
8609 .report_buf
= {6, 0xff},
8612 struct hid_expect expect_reset
[] =
8614 /* device control */
8616 .code
= IOCTL_HID_WRITE_REPORT
,
8619 .report_buf
= {1, 0x01},
8622 struct hid_expect expect_enable_actuators
[] =
8624 /* device control */
8626 .code
= IOCTL_HID_WRITE_REPORT
,
8629 .report_buf
= {1, 0x04},
8632 struct hid_expect expect_disable_actuators
[] =
8634 /* device control */
8636 .code
= IOCTL_HID_WRITE_REPORT
,
8639 .report_buf
= {1, 0x05},
8642 struct hid_expect expect_stop_all
[] =
8644 /* device control */
8646 .code
= IOCTL_HID_WRITE_REPORT
,
8649 .report_buf
= {1, 0x06},
8652 struct hid_expect expect_device_pause
[] =
8654 /* device control */
8656 .code
= IOCTL_HID_WRITE_REPORT
,
8659 .report_buf
= {1, 0x02},
8662 struct hid_expect expect_device_continue
[] =
8664 /* device control */
8666 .code
= IOCTL_HID_WRITE_REPORT
,
8669 .report_buf
= {1, 0x03},
8672 struct hid_expect expect_create
[] =
8674 /* create new effect */
8676 .code
= IOCTL_HID_SET_FEATURE
,
8679 .report_buf
= {2,0x03},
8683 .code
= IOCTL_HID_GET_FEATURE
,
8686 .report_buf
= {3,0x01,0x01,0x00,0x00},
8690 .code
= IOCTL_HID_WRITE_REPORT
,
8693 .report_buf
= {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8697 .code
= IOCTL_HID_WRITE_REPORT
,
8700 .report_buf
= {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8704 .code
= IOCTL_HID_WRITE_REPORT
,
8707 .report_buf
= {3,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
8710 struct hid_expect expect_create_2
[] =
8712 /* create new effect */
8714 .code
= IOCTL_HID_SET_FEATURE
,
8717 .report_buf
= {2,0x03},
8721 .code
= IOCTL_HID_GET_FEATURE
,
8724 .report_buf
= {3,0x02,0x01,0x00,0x00},
8728 .code
= IOCTL_HID_WRITE_REPORT
,
8731 .report_buf
= {4,0x02,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8735 .code
= IOCTL_HID_WRITE_REPORT
,
8738 .report_buf
= {4,0x02,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8742 .code
= IOCTL_HID_WRITE_REPORT
,
8745 .report_buf
= {3,0x02,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
8748 struct hid_expect expect_create_delay
[] =
8750 /* create new effect */
8752 .code
= IOCTL_HID_SET_FEATURE
,
8755 .report_buf
= {2,0x03},
8759 .code
= IOCTL_HID_GET_FEATURE
,
8762 .report_buf
= {3,0x01,0x01,0x00,0x00},
8766 .code
= IOCTL_HID_WRITE_REPORT
,
8769 .report_buf
= {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8773 .code
= IOCTL_HID_WRITE_REPORT
,
8776 .report_buf
= {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8780 .code
= IOCTL_HID_WRITE_REPORT
,
8783 .report_buf
= {3,0x01,0x03,0x08,0x01,0x00,0xff,0x7f,0x01,0x55,0x00},
8786 struct hid_expect expect_create_duration
[] =
8788 /* create new effect */
8790 .code
= IOCTL_HID_SET_FEATURE
,
8793 .report_buf
= {2,0x03},
8797 .code
= IOCTL_HID_GET_FEATURE
,
8800 .report_buf
= {3,0x01,0x01,0x00,0x00},
8804 .code
= IOCTL_HID_WRITE_REPORT
,
8807 .report_buf
= {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8811 .code
= IOCTL_HID_WRITE_REPORT
,
8814 .report_buf
= {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8818 .code
= IOCTL_HID_WRITE_REPORT
,
8821 .report_buf
= {3,0x01,0x03,0x08,0x00,0x00,0x00,0x00,0x01,0x55,0x00},
8824 struct hid_expect expect_start
=
8826 /* effect control */
8827 .code
= IOCTL_HID_WRITE_REPORT
,
8830 .report_buf
= {2,0x01,0x01,0x01},
8832 struct hid_expect expect_start_2
=
8834 /* effect control */
8835 .code
= IOCTL_HID_WRITE_REPORT
,
8838 .report_buf
= {2,0x02,0x02,0x01},
8840 struct hid_expect expect_stop
=
8842 /* effect control */
8843 .code
= IOCTL_HID_WRITE_REPORT
,
8846 .report_buf
= {2,0x01,0x03,0x00},
8848 struct hid_expect expect_stop_2
=
8850 /* effect control */
8851 .code
= IOCTL_HID_WRITE_REPORT
,
8854 .report_buf
= {2,0x02,0x03,0x00},
8856 struct hid_expect expect_destroy
[] =
8858 /* effect operation */
8860 .code
= IOCTL_HID_WRITE_REPORT
,
8863 .report_buf
= {2,0x01,0x03,0x00},
8867 .code
= IOCTL_HID_WRITE_REPORT
,
8870 .report_buf
= {5,0x01},
8873 struct hid_expect expect_destroy_2
[] =
8875 /* effect operation */
8877 .code
= IOCTL_HID_WRITE_REPORT
,
8880 .report_buf
= {2,0x02,0x03,0x00},
8884 .code
= IOCTL_HID_WRITE_REPORT
,
8887 .report_buf
= {5,0x02},
8890 struct hid_expect device_state_input
[] =
8894 .code
= IOCTL_HID_READ_REPORT
,
8897 .report_buf
= {2,0xff,0x00,0xff},
8901 .code
= IOCTL_HID_READ_REPORT
,
8904 .report_buf
= {1,0x12,0x34,0x56,0xff},
8907 struct hid_expect device_state_input_0
[] =
8911 .code
= IOCTL_HID_READ_REPORT
,
8914 .report_buf
= {2,0xff,0x00,0xff},
8918 .code
= IOCTL_HID_READ_REPORT
,
8921 .report_buf
= {1,0x56,0x12,0x34,0xff},
8924 struct hid_expect device_state_input_1
[] =
8928 .code
= IOCTL_HID_READ_REPORT
,
8931 .report_buf
= {2,0x00,0x01,0x01},
8935 .code
= IOCTL_HID_READ_REPORT
,
8938 .report_buf
= {1,0x65,0x43,0x21,0x00},
8941 struct hid_expect device_state_input_2
[] =
8945 .code
= IOCTL_HID_READ_REPORT
,
8948 .report_buf
= {2,0x03,0x00,0x01},
8952 .code
= IOCTL_HID_READ_REPORT
,
8955 .report_buf
= {1,0x12,0x34,0x56,0xff},
8958 struct hid_expect expect_pool
[] =
8962 .code
= IOCTL_HID_GET_FEATURE
,
8965 .report_buf
= {1,0x10,0x00,0x04,0x03},
8970 .code
= IOCTL_HID_GET_FEATURE
,
8973 .report_buf
= {1,0x10,0x00,0x04,0x03},
8977 static const DWORD expect_axes
[3] =
8979 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFACTUATOR
,
8980 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 2 ) | DIDFT_FFACTUATOR
,
8981 DIDFT_ABSAXIS
| DIDFT_MAKEINSTANCE( 1 ) | DIDFT_FFACTUATOR
,
8983 static const LONG expect_directions
[3] = {
8988 static const DIENVELOPE expect_envelope
=
8990 .dwSize
= sizeof(DIENVELOPE
),
8991 .dwAttackLevel
= 1000,
8992 .dwAttackTime
= 2000,
8993 .dwFadeLevel
= 3000,
8996 static const DICONDITION expect_condition
[3] =
9000 .lPositiveCoefficient
= 2000,
9001 .lNegativeCoefficient
= -3000,
9002 .dwPositiveSaturation
= -4000,
9003 .dwNegativeSaturation
= -5000,
9008 .lPositiveCoefficient
= 5000,
9009 .lNegativeCoefficient
= -4000,
9010 .dwPositiveSaturation
= 3000,
9011 .dwNegativeSaturation
= 2000,
9016 .lPositiveCoefficient
= -8000,
9017 .lNegativeCoefficient
= 9000,
9018 .dwPositiveSaturation
= 10000,
9019 .dwNegativeSaturation
= 11000,
9020 .lDeadBand
= -12000,
9023 const DIEFFECT expect_desc
=
9025 .dwSize
= sizeof(DIEFFECT_DX6
),
9026 .dwFlags
= DIEFF_SPHERICAL
| DIEFF_OBJECTIDS
,
9028 .dwSamplePeriod
= 2000,
9030 .dwTriggerButton
= DIDFT_PSHBUTTON
| DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER
,
9031 .dwTriggerRepeatInterval
= 5000,
9033 .rgdwAxes
= (void *)expect_axes
,
9034 .rglDirection
= (void *)expect_directions
,
9035 .lpEnvelope
= (void *)&expect_envelope
,
9036 .cbTypeSpecificParams
= 2 * sizeof(DICONDITION
),
9037 .lpvTypeSpecificParams
= (void *)expect_condition
,
9038 .dwStartDelay
= 6000,
9040 DIPROPGUIDANDPATH prop_guid_path
=
9044 .dwSize
= sizeof(DIPROPGUIDANDPATH
),
9045 .dwHeaderSize
= sizeof(DIPROPHEADER
),
9046 .dwHow
= DIPH_DEVICE
,
9049 DIPROPDWORD prop_dword
=
9053 .dwSize
= sizeof(DIPROPDWORD
),
9054 .dwHeaderSize
= sizeof(DIPROPHEADER
),
9055 .dwHow
= DIPH_DEVICE
,
9058 DIDEVICEINSTANCEW devinst
= {.dwSize
= sizeof(DIDEVICEINSTANCEW
)};
9059 WCHAR cwd
[MAX_PATH
], tempdir
[MAX_PATH
];
9060 IDirectInputDevice8W
*device
;
9061 IDirectInputEffect
*effect
, *effect2
;
9069 GetCurrentDirectoryW( ARRAY_SIZE(cwd
), cwd
);
9070 GetTempPathW( ARRAY_SIZE(tempdir
), tempdir
);
9071 SetCurrentDirectoryW( tempdir
);
9073 cleanup_registry_keys();
9074 if (!dinput_driver_start( report_descriptor
, sizeof(report_descriptor
), &hid_caps
,
9075 expect_pool
, sizeof(expect_pool
) )) goto done
;
9076 if (FAILED(hr
= create_dinput_device( DIRECTINPUT_VERSION
, &devinst
, &device
))) goto done
;
9078 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_GUIDANDPATH
, &prop_guid_path
.diph
);
9079 ok( hr
== DI_OK
, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr
);
9080 file
= CreateFileW( prop_guid_path
.wszPath
, FILE_READ_ACCESS
| FILE_WRITE_ACCESS
,
9081 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
9082 FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
, NULL
);
9083 ok( file
!= INVALID_HANDLE_VALUE
, "got error %u\n", GetLastError() );
9085 hwnd
= CreateWindowW( L
"static", L
"dinput", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 10, 10, 200, 200,
9086 NULL
, NULL
, NULL
, NULL
);
9088 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
9089 ok( event
!= NULL
, "CreateEventW failed, last error %u\n", GetLastError() );
9090 hr
= IDirectInputDevice8_SetEventNotification( device
, event
);
9091 ok( hr
== DI_OK
, "SetEventNotification returned: %#x\n", hr
);
9092 hr
= IDirectInputDevice8_SetCooperativeLevel( device
, hwnd
, DISCL_BACKGROUND
| DISCL_EXCLUSIVE
);
9093 ok( hr
== DI_OK
, "SetCooperativeLevel returned: %#x\n", hr
);
9094 hr
= IDirectInputDevice8_SetDataFormat( device
, &c_dfDIJoystick2
);
9095 ok( hr
== DI_OK
, "SetDataFormat returned: %#x\n", hr
);
9097 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
9098 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
9099 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9100 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetForceFeedbackState returned %#x\n", hr
);
9101 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_RESET
);
9102 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "SendForceFeedbackCommand returned %#x\n", hr
);
9104 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
9105 hr
= IDirectInputDevice8_Acquire( device
);
9106 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
9107 wait_hid_expect( file
, 100 );
9109 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9110 prop_dword
.dwData
= 0xdeadbeef;
9111 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
9112 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
9113 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#x\n", prop_dword
.dwData
);
9114 set_hid_expect( file
, NULL
, 0 );
9116 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9118 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9119 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9120 flags
= DIGFFS_STOPPED
|DIGFFS_EMPTY
;
9121 ok( res
== flags
, "got state %#x\n", res
);
9122 set_hid_expect( file
, NULL
, 0 );
9124 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9125 prop_dword
.dwData
= 0xdeadbeef;
9126 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
9127 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
9128 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#x\n", prop_dword
.dwData
);
9129 set_hid_expect( file
, NULL
, 0 );
9131 send_hid_input( file
, device_state_input
, sizeof(struct hid_expect
) );
9132 res
= WaitForSingleObject( event
, 100 );
9133 ok( res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %#x\n", res
);
9134 send_hid_input( file
, device_state_input
, sizeof(device_state_input
) );
9135 res
= WaitForSingleObject( event
, 100 );
9136 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
9138 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9140 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9141 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9142 flags
= DIGFFS_PAUSED
|DIGFFS_EMPTY
|DIGFFS_ACTUATORSON
|DIGFFS_POWERON
|DIGFFS_SAFETYSWITCHON
|DIGFFS_USERFFSWITCHON
;
9144 ok( res
== flags
, "got state %#x\n", res
);
9145 set_hid_expect( file
, NULL
, 0 );
9147 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, NULL
, &effect
, NULL
);
9148 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
9150 hr
= IDirectInputEffect_GetEffectStatus( effect
, NULL
);
9151 ok( hr
== E_POINTER
, "GetEffectStatus returned %#x\n", hr
);
9153 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9154 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#x\n", hr
);
9155 ok( res
== 0, "got status %#x\n", res
);
9157 flags
= DIEP_ALLPARAMS
;
9158 hr
= IDirectInputEffect_SetParameters( effect
, &expect_desc
, flags
| DIEP_NODOWNLOAD
);
9159 ok( hr
== DI_DOWNLOADSKIPPED
, "SetParameters returned %#x\n", hr
);
9161 set_hid_expect( file
, expect_reset
, sizeof(struct hid_expect
) );
9162 hr
= IDirectInputDevice8_Unacquire( device
);
9163 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
9164 set_hid_expect( file
, NULL
, 0 );
9166 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9167 ok( hr
== DIERR_NOTEXCLUSIVEACQUIRED
, "GetEffectStatus returned %#x\n", hr
);
9169 set_hid_expect( file
, expect_acquire
, sizeof(expect_acquire
) );
9170 hr
= IDirectInputDevice8_Acquire( device
);
9171 ok( hr
== DI_OK
, "Acquire returned: %#x\n", hr
);
9172 wait_hid_expect( file
, 100 );
9175 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9176 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#x\n", hr
);
9177 ok( res
== 0, "got status %#x\n", res
);
9179 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9181 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9182 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9183 flags
= DIGFFS_STOPPED
|DIGFFS_EMPTY
;
9184 ok( res
== flags
, "got state %#x\n", res
);
9185 set_hid_expect( file
, NULL
, 0 );
9187 set_hid_expect( file
, expect_create
, sizeof(expect_create
) );
9188 hr
= IDirectInputEffect_Download( effect
);
9189 ok( hr
== DI_OK
, "Download returned %#x\n", hr
);
9190 set_hid_expect( file
, NULL
, 0 );
9193 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9194 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9195 ok( res
== 0, "got status %#x\n", res
);
9196 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9198 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9199 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9200 flags
= DIGFFS_STOPPED
;
9201 ok( res
== flags
, "got state %#x\n", res
);
9202 set_hid_expect( file
, NULL
, 0 );
9204 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9205 prop_dword
.dwData
= 0xdeadbeef;
9206 hr
= IDirectInputDevice8_GetProperty( device
, DIPROP_FFLOAD
, &prop_dword
.diph
);
9207 ok( hr
== DI_OK
, "GetProperty DIPROP_FFLOAD returned %#x\n", hr
);
9208 ok( prop_dword
.dwData
== 0, "got DIPROP_FFLOAD %#x\n", prop_dword
.dwData
);
9209 set_hid_expect( file
, NULL
, 0 );
9211 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
9212 hr
= IDirectInputEffect_Start( effect
, 1, DIES_NODOWNLOAD
);
9213 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
9214 set_hid_expect( file
, NULL
, 0 );
9216 set_hid_expect( file
, expect_create_2
, sizeof(expect_create_2
) );
9217 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &expect_desc
, &effect2
, NULL
);
9218 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
9219 set_hid_expect( file
, NULL
, 0 );
9220 set_hid_expect( file
, &expect_start_2
, sizeof(expect_start_2
) );
9221 hr
= IDirectInputEffect_Start( effect2
, 1, DIES_SOLO
);
9222 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
9223 set_hid_expect( file
, NULL
, 0 );
9225 hr
= IDirectInputEffect_GetEffectStatus( effect2
, &res
);
9226 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9227 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9229 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9230 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9231 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9232 set_hid_expect( file
, &expect_stop_2
, sizeof(expect_stop_2
) );
9233 hr
= IDirectInputEffect_Stop( effect2
);
9234 ok( hr
== DI_OK
, "Stop returned %#x\n", hr
);
9235 set_hid_expect( file
, NULL
, 0 );
9237 hr
= IDirectInputEffect_GetEffectStatus( effect2
, &res
);
9238 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9239 ok( res
== 0, "got status %#x\n", res
);
9240 set_hid_expect( file
, expect_destroy_2
, sizeof(expect_destroy_2
) );
9241 ref
= IDirectInputEffect_Release( effect2
);
9242 ok( ref
== 0, "Release returned %d\n", ref
);
9243 set_hid_expect( file
, NULL
, 0 );
9245 /* sending commands has no direct effect on status */
9246 set_hid_expect( file
, expect_stop_all
, sizeof(expect_stop_all
) );
9247 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_STOPALL
);
9248 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#x\n", hr
);
9249 set_hid_expect( file
, NULL
, 0 );
9251 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9252 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9253 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9254 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9256 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9257 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9258 flags
= DIGFFS_STOPPED
;
9259 ok( res
== flags
, "got state %#x\n", res
);
9260 set_hid_expect( file
, NULL
, 0 );
9262 set_hid_expect( file
, expect_device_pause
, sizeof(expect_device_pause
) );
9263 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_PAUSE
);
9264 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#x\n", hr
);
9265 set_hid_expect( file
, NULL
, 0 );
9267 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9268 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9269 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9270 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9272 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9273 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9274 flags
= DIGFFS_STOPPED
;
9275 ok( res
== flags
, "got state %#x\n", res
);
9276 set_hid_expect( file
, NULL
, 0 );
9278 set_hid_expect( file
, expect_device_continue
, sizeof(expect_device_continue
) );
9279 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_CONTINUE
);
9280 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#x\n", hr
);
9281 set_hid_expect( file
, NULL
, 0 );
9283 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9284 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9285 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9286 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9288 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9289 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9290 flags
= DIGFFS_STOPPED
;
9291 ok( res
== flags
, "got state %#x\n", res
);
9292 set_hid_expect( file
, NULL
, 0 );
9294 set_hid_expect( file
, expect_disable_actuators
, sizeof(expect_disable_actuators
) );
9295 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSOFF
);
9296 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#x\n", hr
);
9297 set_hid_expect( file
, NULL
, 0 );
9299 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9300 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9301 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9302 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9304 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9305 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9306 flags
= DIGFFS_STOPPED
;
9307 ok( res
== flags
, "got state %#x\n", res
);
9308 set_hid_expect( file
, NULL
, 0 );
9310 set_hid_expect( file
, expect_enable_actuators
, sizeof(expect_enable_actuators
) );
9311 hr
= IDirectInputDevice8_SendForceFeedbackCommand( device
, DISFFC_SETACTUATORSON
);
9312 ok( hr
== DI_OK
, "SendForceFeedbackCommand returned %#x\n", hr
);
9313 set_hid_expect( file
, NULL
, 0 );
9315 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9316 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9317 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9318 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9320 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9321 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9322 flags
= DIGFFS_STOPPED
;
9323 ok( res
== flags
, "got state %#x\n", res
);
9324 set_hid_expect( file
, NULL
, 0 );
9326 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
9327 hr
= IDirectInputEffect_Stop( effect
);
9328 ok( hr
== DI_OK
, "Stop returned %#x\n", hr
);
9329 set_hid_expect( file
, NULL
, 0 );
9331 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9332 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9333 ok( res
== 0, "got status %#x\n", res
);
9334 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9336 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9337 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9338 flags
= DIGFFS_STOPPED
;
9339 ok( res
== flags
, "got state %#x\n", res
);
9340 set_hid_expect( file
, NULL
, 0 );
9342 send_hid_input( file
, device_state_input_0
, sizeof(device_state_input_0
) );
9343 res
= WaitForSingleObject( event
, 100 );
9344 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
9345 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9347 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9348 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9349 flags
= DIGFFS_PAUSED
|DIGFFS_ACTUATORSON
|DIGFFS_POWERON
|DIGFFS_SAFETYSWITCHON
|DIGFFS_USERFFSWITCHON
;
9351 ok( res
== flags
, "got state %#x\n", res
);
9352 set_hid_expect( file
, NULL
, 0 );
9354 send_hid_input( file
, device_state_input_1
, sizeof(device_state_input_1
) );
9355 res
= WaitForSingleObject( event
, 100 );
9356 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
9358 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9359 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9361 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9362 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9364 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9365 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9366 flags
= DIGFFS_ACTUATORSOFF
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
9368 ok( res
== flags
, "got state %#x\n", res
);
9369 set_hid_expect( file
, NULL
, 0 );
9371 send_hid_input( file
, device_state_input_2
, sizeof(device_state_input_2
) );
9372 res
= WaitForSingleObject( event
, 100 );
9373 ok( res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %#x\n", res
);
9375 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9376 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9377 ok( res
== 0, "got status %#x\n", res
);
9378 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9380 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9381 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9382 flags
= DIGFFS_PAUSED
|DIGFFS_ACTUATORSON
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
9384 ok( res
== flags
, "got state %#x\n", res
);
9385 set_hid_expect( file
, NULL
, 0 );
9387 set_hid_expect( file
, &expect_stop
, sizeof(expect_stop
) );
9388 hr
= IDirectInputEffect_Stop( effect
);
9389 ok( hr
== DI_OK
, "Stop returned %#x\n", hr
);
9390 set_hid_expect( file
, NULL
, 0 );
9393 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9394 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9395 ok( res
== 0, "got status %#x\n", res
);
9396 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9398 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9399 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9400 flags
= DIGFFS_PAUSED
|DIGFFS_ACTUATORSON
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
9402 ok( res
== flags
, "got state %#x\n", res
);
9403 set_hid_expect( file
, NULL
, 0 );
9405 set_hid_expect( file
, expect_destroy
, sizeof(expect_destroy
) );
9406 hr
= IDirectInputEffect_Unload( effect
);
9407 ok( hr
== DI_OK
, "Unload returned %#x\n", hr
);
9408 set_hid_expect( file
, NULL
, 0 );
9411 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9412 ok( hr
== DIERR_NOTDOWNLOADED
, "GetEffectStatus returned %#x\n", hr
);
9413 ok( res
== 0, "got status %#x\n", res
);
9414 set_hid_expect( file
, expect_pool
, sizeof(struct hid_expect
) );
9416 hr
= IDirectInputDevice8_GetForceFeedbackState( device
, &res
);
9417 ok( hr
== DI_OK
, "GetForceFeedbackState returned %#x\n", hr
);
9418 flags
= DIGFFS_EMPTY
|DIGFFS_PAUSED
|DIGFFS_ACTUATORSON
|DIGFFS_POWEROFF
|DIGFFS_SAFETYSWITCHOFF
|DIGFFS_USERFFSWITCHOFF
;
9420 ok( res
== flags
, "got state %#x\n", res
);
9421 set_hid_expect( file
, NULL
, 0 );
9423 ref
= IDirectInputEffect_Release( effect
);
9424 ok( ref
== 0, "Release returned %d\n", ref
);
9426 /* start delay has no direct effect on effect status */
9428 desc
.dwStartDelay
= 32767000;
9429 set_hid_expect( file
, expect_create_delay
, sizeof(expect_create_delay
) );
9430 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
9431 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
9432 set_hid_expect( file
, NULL
, 0 );
9434 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9435 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9436 ok( res
== 0, "got status %#x\n", res
);
9437 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
9438 hr
= IDirectInputEffect_Start( effect
, 1, 0 );
9439 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
9440 set_hid_expect( file
, NULL
, 0 );
9442 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9443 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9444 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9445 set_hid_expect( file
, expect_destroy
, sizeof(expect_destroy
) );
9446 ref
= IDirectInputEffect_Release( effect
);
9447 ok( ref
== 0, "Release returned %d\n", ref
);
9448 set_hid_expect( file
, NULL
, 0 );
9450 /* duration has no direct effect on effect status */
9452 desc
.dwDuration
= 100;
9453 desc
.dwStartDelay
= 0;
9454 set_hid_expect( file
, expect_create_duration
, sizeof(expect_create_duration
) );
9455 hr
= IDirectInputDevice8_CreateEffect( device
, &GUID_Spring
, &desc
, &effect
, NULL
);
9456 ok( hr
== DI_OK
, "CreateEffect returned %#x\n", hr
);
9457 set_hid_expect( file
, NULL
, 0 );
9459 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9460 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9461 ok( res
== 0, "got status %#x\n", res
);
9462 set_hid_expect( file
, &expect_start
, sizeof(expect_start
) );
9463 hr
= IDirectInputEffect_Start( effect
, 1, 0 );
9464 ok( hr
== DI_OK
, "Start returned %#x\n", hr
);
9465 set_hid_expect( file
, NULL
, 0 );
9468 hr
= IDirectInputEffect_GetEffectStatus( effect
, &res
);
9469 ok( hr
== DI_OK
, "GetEffectStatus returned %#x\n", hr
);
9470 ok( res
== DIEGES_PLAYING
, "got status %#x\n", res
);
9471 set_hid_expect( file
, expect_destroy
, sizeof(expect_destroy
) );
9472 ref
= IDirectInputEffect_Release( effect
);
9473 ok( ref
== 0, "Release returned %d\n", ref
);
9474 set_hid_expect( file
, NULL
, 0 );
9476 set_hid_expect( file
, expect_reset
, sizeof(struct hid_expect
) );
9477 hr
= IDirectInputDevice8_Unacquire( device
);
9478 ok( hr
== DI_OK
, "Unacquire returned: %#x\n", hr
);
9479 set_hid_expect( file
, NULL
, 0 );
9481 ref
= IDirectInputDevice8_Release( device
);
9482 ok( ref
== 0, "Release returned %d\n", ref
);
9484 DestroyWindow( hwnd
);
9485 CloseHandle( event
);
9486 CloseHandle( file
);
9490 cleanup_registry_keys();
9491 SetCurrentDirectoryW( cwd
);
9492 winetest_pop_context();
9500 instance
= GetModuleHandleW( NULL
);
9501 localized
= GetUserDefaultLCID() != MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
);
9502 pSignerSign
= (void *)GetProcAddress( LoadLibraryW( L
"mssign32" ), "SignerSign" );
9504 if (IsWow64Process( GetCurrentProcess(), &is_wow64
) && is_wow64
)
9506 skip( "Running in WoW64.\n" );
9510 mapping
= CreateFileMappingW( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, sizeof(*test_data
),
9511 L
"Global\\winetest_dinput_section" );
9512 if (!mapping
&& GetLastError() == ERROR_ACCESS_DENIED
)
9514 win_skip( "Failed to create test data mapping.\n" );
9517 ok( !!mapping
, "got error %u\n", GetLastError() );
9518 test_data
= MapViewOfFile( mapping
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 1024 );
9519 test_data
->running_under_wine
= !strcmp( winetest_platform
, "wine" );
9520 test_data
->winetest_report_success
= winetest_report_success
;
9521 test_data
->winetest_debug
= winetest_debug
;
9523 okfile
= CreateFileW( L
"C:\\windows\\winetest_dinput_okfile", GENERIC_READ
| GENERIC_WRITE
,
9524 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
9525 ok( okfile
!= INVALID_HANDLE_VALUE
, "failed to create file, error %u\n", GetLastError() );
9527 subtest( "driver_hid" );
9529 test_hid_driver( 0, FALSE
);
9530 test_hid_driver( 1, FALSE
);
9531 test_hid_driver( 0, TRUE
);
9532 test_hid_driver( 1, TRUE
);
9534 CoInitialize( NULL
);
9535 if (test_device_types( 0x800 ))
9537 test_device_types( 0x500 );
9538 test_device_types( 0x700 );
9540 test_simple_joystick();
9541 test_force_feedback_joystick( 0x500 );
9542 test_force_feedback_joystick( 0x700 );
9543 test_force_feedback_joystick( 0x800 );
9545 test_device_managed_effect();
9549 UnmapViewOfFile( test_data
);
9550 CloseHandle( mapping
);
9551 CloseHandle( okfile
);
9552 DeleteFileW( L
"C:\\windows\\winetest_dinput_okfile" );