dinput: Improve GetForceFeedbackState / GetEffectStatus stubs.
[wine.git] / dlls / dinput8 / tests / hid.c
blobd9ecf4a5dd54853a8fcb31f1c918948262543892
1 /*
2 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define DIRECTINPUT_VERSION 0x0800
21 #include <stdarg.h>
22 #include <stddef.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winioctl.h"
29 #include "winternl.h"
30 #include "wincrypt.h"
31 #include "winreg.h"
32 #include "winsvc.h"
33 #include "winuser.h"
34 #include "winnls.h"
36 #include "mscat.h"
37 #include "mssip.h"
38 #include "ntsecapi.h"
39 #include "setupapi.h"
40 #include "cfgmgr32.h"
41 #include "newdev.h"
43 #include "objbase.h"
45 #define COBJMACROS
46 #include "wingdi.h"
47 #include "dinput.h"
48 #include "dinputd.h"
50 #include "initguid.h"
51 #include "ddk/wdm.h"
52 #include "ddk/hidclass.h"
53 #include "ddk/hidsdi.h"
54 #include "ddk/hidpi.h"
55 #include "ddk/hidport.h"
56 #include "hidusage.h"
57 #include "devguid.h"
59 #include "wine/test.h"
60 #include "wine/mssign.h"
61 #include "wine/hid.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;
75 static HANDLE okfile;
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;
103 HCRYPTPROV provider;
104 HCRYPTKEY key;
105 HRESULT hr;
106 BOOL ret;
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() );
198 return NULL;
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() );
209 return NULL;
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 );
237 todo_wine
238 ok( hr == S_OK || broken( hr == NTE_BAD_ALGID ) /* < 7 */, "Failed to sign, hr %#x\n", hr );
240 return cert;
243 static void testsign_cleanup( const CERT_CONTEXT *cert )
245 HCERTSTORE root_store, pub_store;
246 const CERT_CONTEXT *store_cert;
247 HCRYPTPROV provider;
248 BOOL ret;
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];
279 DWORD written;
280 HANDLE file;
281 HRSRC res;
282 void *ptr;
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" );
295 CloseHandle( file );
298 #ifdef __i386__
299 #define EXT "x86"
300 #elif defined(__x86_64__)
301 #define EXT "amd64"
302 #elif defined(__arm__)
303 #define EXT "arm"
304 #elif defined(__aarch64__)
305 #define EXT "arm64"
306 #else
307 #define EXT
308 #endif
310 static const char inf_text[] =
311 "[Version]\n"
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"
317 "[Manufacturer]\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"
329 "[file_section]\n"
330 "winetest.sys\n"
332 "[SourceDisksFiles]\n"
333 "winetest.sys=1\n"
335 "[SourceDisksNames]\n"
336 "1=,winetest.sys\n"
338 "[DestinationDirs]\n"
339 "DefaultDestDir=12\n"
341 "[svc_section]\n"
342 "ServiceBinary=%12%\\winetest.sys\n"
343 "ServiceType=1\n"
344 "StartType=3\n"
345 "ErrorControl=1\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];
357 GUID subject_guid;
358 unsigned int i;
359 DWORD size;
360 BOOL ret;
362 ret = CryptSIPRetrieveSubjectGuidForCatalogFile( file, NULL, &subject_guid );
363 todo_wine
364 ok( ret, "Failed to get subject guid, error %u\n", GetLastError() );
366 size = 0;
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 );
373 todo_wine
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 );
378 todo_wine
379 ok( ret, "Failed to get indirect data, error %u\n", GetLastError() );
380 if (ret)
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)
411 BOOL ret;
412 Sleep( 100 );
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;
427 char buffer[512];
428 HDEVINFO set;
429 HANDLE file;
430 DWORD size;
431 BOOL ret;
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() );
441 return;
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;
504 HANDLE catalog;
505 HDEVINFO set;
506 FILE *f;
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 );
518 fclose( 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 );
529 todo_wine
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;
544 return FALSE;
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};
751 BOOL ret;
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;
765 return ret;
768 #define fill_context( line, a, b ) \
769 do { \
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 ); \
776 } while (0)
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 )
781 char context[64];
782 BOOL ret;
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 )
803 char context[64];
804 BOOL ret;
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},
822 .ret_length = 3,
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},
830 .ret_length = 3,
831 .ret_status = STATUS_SUCCESS,
835 char buffer[200], report[200];
836 NTSTATUS status;
837 ULONG length;
838 BOOL ret;
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() );
855 if (!report_id)
857 struct hid_expect broken_expect =
859 .code = IOCTL_HID_GET_INPUT_REPORT,
860 .broken = TRUE,
861 .report_len = report_len - 1,
862 .report_buf =
864 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
865 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
866 0x5a,0x5a,0x5a,0x5a,0x5a,
868 .ret_length = 3,
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() );
884 else
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},
916 .ret_length = 3,
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},
924 .ret_length = 3,
925 .ret_status = STATUS_SUCCESS,
929 char buffer[200], report[200];
930 NTSTATUS status;
931 ULONG length;
932 BOOL ret;
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() );
949 if (!report_id)
951 struct hid_expect broken_expect =
953 .code = IOCTL_HID_GET_FEATURE,
954 .broken = TRUE,
955 .report_len = report_len - 1,
956 .report_buf =
958 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
959 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
960 0x5a,0x5a,0x5a,0x5a,0x5a,
962 .ret_length = 3,
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() );
978 else
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},
1010 .ret_length = 3,
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),
1017 .report_buf =
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,
1023 .ret_length = 3,
1024 .ret_status = STATUS_SUCCESS,
1027 char buffer[200], report[200];
1028 NTSTATUS status;
1029 ULONG length;
1030 BOOL ret;
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() );
1047 if (!report_id)
1049 struct hid_expect broken_expect =
1051 .code = IOCTL_HID_SET_FEATURE,
1052 .broken = TRUE,
1053 .report_len = report_len - 1,
1054 .report_buf =
1056 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1057 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
1058 0x5a,0x5a,0x5a,0x5a,0x5a,
1060 .ret_length = 3,
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() );
1076 else
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",
1092 GetLastError() );
1093 length = 0;
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},
1111 .ret_length = 3,
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},
1119 .ret_length = 3,
1120 .ret_status = STATUS_SUCCESS,
1124 char buffer[200], report[200];
1125 NTSTATUS status;
1126 ULONG length;
1127 BOOL ret;
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",
1139 GetLastError() );
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() );
1147 if (!report_id)
1149 struct hid_expect broken_expect =
1151 .code = IOCTL_HID_SET_OUTPUT_REPORT,
1152 .broken = TRUE,
1153 .report_len = report_len - 1,
1154 .report_buf = {0x5a,0x5a},
1155 .ret_length = 3,
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() );
1171 else
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() );
1188 length = 0;
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},
1205 .ret_length = 3,
1206 .ret_status = STATUS_SUCCESS,
1209 char report[200];
1210 ULONG length;
1211 BOOL ret;
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) );
1228 report[0] = 0xa5;
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 );
1241 if (report_id)
1243 ok( ret, "WriteFile failed, last error %u\n", GetLastError() );
1244 ok( length == 2, "WriteFile wrote %u\n", length );
1246 else
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,
1262 .BitField = 2,
1263 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1264 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1265 .LinkCollection = 1,
1266 .IsRange = TRUE,
1267 .IsAbsolute = TRUE,
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,
1276 .BitField = 3,
1277 .LinkCollection = 1,
1278 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1279 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1280 .IsRange = TRUE,
1281 .IsAbsolute = TRUE,
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,
1290 .BitField = 0x1fc,
1291 .LinkCollection = 1,
1292 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1293 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1294 .IsRange = TRUE,
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,
1304 .BitField = 2,
1305 .LinkCollection = 1,
1306 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1307 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1308 .IsRange = FALSE,
1309 .IsAbsolute = TRUE,
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,
1321 .BitField = 2,
1322 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1323 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1324 .LinkCollection = 1,
1325 .IsAbsolute = TRUE,
1326 .BitSize = 8,
1327 .ReportCount = 1,
1328 .LogicalMin = -128,
1329 .LogicalMax = 127,
1330 .NotRange.Usage = HID_USAGE_GENERIC_Y,
1331 .NotRange.Reserved1 = HID_USAGE_GENERIC_Y,
1334 .UsagePage = HID_USAGE_PAGE_GENERIC,
1335 .ReportID = report_id,
1336 .BitField = 2,
1337 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1338 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1339 .LinkCollection = 1,
1340 .IsAbsolute = TRUE,
1341 .BitSize = 8,
1342 .ReportCount = 1,
1343 .LogicalMin = -128,
1344 .LogicalMax = 127,
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,
1353 .BitField = 2,
1354 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1355 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1356 .LinkCollection = 1,
1357 .IsAbsolute = TRUE,
1358 .ReportCount = 1,
1359 .LogicalMax = 1,
1360 .IsRange = TRUE,
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,
1369 .BitField = 2,
1370 .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
1371 .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
1372 .LinkCollection = 1,
1373 .IsAbsolute = TRUE,
1374 .BitSize = 4,
1375 .ReportCount = 2,
1376 .LogicalMin = 1,
1377 .LogicalMax = 8,
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,
1391 .FirstChild = 9,
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;
1423 HIDP_DATA data[64];
1424 USAGE usages[16];
1425 ULONG off, value;
1426 NTSTATUS status;
1427 HIDP_CAPS caps;
1428 unsigned int i;
1429 USHORT count;
1430 BOOL ret;
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 );
1467 count = 0;
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 );
1493 count = 0;
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] );
1514 count = 0xbeef;
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 );
1518 count = 0xbeef;
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 );
1522 count = 0xbeef;
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 );
1532 count = 0;
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 );
1557 count = 0;
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] );
1575 count = 1;
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] );
1582 count = 0xdead;
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 );
1586 count = 0xdead;
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 );
1590 count = 0xdead;
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 );
1625 todo_wine
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 );
1637 todo_wine
1638 ok( status == HIDP_STATUS_NOT_IMPLEMENTED, "HidP_GetUsageValueArray returned %#x\n", status );
1640 value = -128;
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 );
1644 value = 0xdeadbeef;
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 );
1649 value = 0xdeadbeef;
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 );
1655 value = 127;
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 );
1659 value = 0xdeadbeef;
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 );
1665 value = 0;
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 );
1669 value = 0xdeadbeef;
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 );
1675 value = 0x7fffffff;
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 );
1679 value = 0xdeadbeef;
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 );
1684 value = 0xdeadbeef;
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 );
1690 value = 0x3fffffff;
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 );
1694 value = 0xdeadbeef;
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 );
1700 value = 0;
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 );
1704 value = 0xdeadbeef;
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 );
1710 value = 0;
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 );
1714 value = 0xdeadbeef;
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 );
1720 value = 0xfeedcafe;
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 );
1724 value = 0xdeadbeef;
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",
1740 value, 32 );
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",
1743 value, 8 );
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",
1746 value, 8 );
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",
1749 value, 0 );
1751 usages[0] = 0xff;
1752 value = 1;
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 );
1756 usages[1] = 2;
1757 usages[2] = 0xff;
1758 value = 3;
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 );
1762 usages[0] = 4;
1763 usages[1] = 6;
1764 value = 2;
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 );
1768 usages[0] = 4;
1769 usages[1] = 6;
1770 value = 2;
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 );
1781 usages[0] = 0x9;
1782 usages[1] = 0xb;
1783 usages[2] = 0xa;
1784 value = 3;
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 );
1791 buffer[13] = 2;
1792 buffer[14] = 4;
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 );
1799 value = 0xdeadbeef;
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 );
1805 value = 1;
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 );
1868 value = 1;
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 );
1888 value = 2;
1889 usages[0] = 0x8e;
1890 usages[1] = 0x8f;
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 );
1908 value = 1;
1909 usages[0] = 0x8c;
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" );
1937 waveform_list = i;
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 );
1957 report[0] = 2;
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 );
1993 report[0] = 2;
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 );
2002 value = 0xdeadbeef;
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" );
2032 value = 0x7fffffff;
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 );
2036 value = 0xdeadbeef;
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 );
2041 value = 0xdeadbeef;
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 );
2047 value = 0x7fff;
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 );
2051 value = 0xdeadbeef;
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 );
2057 value = 0;
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 );
2061 value = 0xdeadbeef;
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 );
2069 value = 0;
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 );
2077 value = 0;
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 );
2085 value = 0;
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 );
2093 value = 0;
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",
2109 GetLastError() );
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",
2114 GetLastError() );
2115 ok( value == 0, "ReadFile returned %x\n", value );
2117 if (polled)
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},
2125 .ret_length = 3,
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},
2132 .ret_length = 3,
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" );
2187 value = 10;
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() );
2192 Sleep( 600 );
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 );
2219 else
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},
2227 .ret_length = 3,
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() );
2247 Sleep( 50 );
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() );
2257 Sleep( 50 );
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 */
2272 Sleep( 50 );
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;
2313 IO_STATUS_BLOCK io;
2314 NTSTATUS status;
2315 unsigned int i;
2316 HDEVINFO set;
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" ))
2337 found = TRUE;
2338 break;
2342 SetupDiDestroyDeviceInfoList( set );
2344 todo_wine
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() );
2351 count = 0xdeadbeef;
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",
2361 GetLastError() );
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",
2366 GetLastError() );
2368 SetLastError( 0xdeadbeef );
2369 ret = HidD_SetNumInputBuffers( file, 16 );
2370 ok( ret, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError() );
2372 count = 0xdeadbeef;
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() );
2383 count = 0xdeadbeef;
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() );
2393 count = 0xdeadbeef;
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 );
2398 count = 0xdeadbeef;
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 );
2404 if (polled)
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 );
2411 todo_wine
2412 ok( poll_freq == 5, "got poll_freq %u, expected 5\n", poll_freq );
2414 out_len = 0;
2415 poll_freq = 500;
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 );
2421 out_len = 0;
2422 poll_freq = 10001;
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 );
2428 out_len = 0;
2429 poll_freq = 0;
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 );
2442 out_len = 0;
2443 poll_freq = 500;
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 );
2465 todo_wine
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),
2489 REPORT_SIZE(1, 8),
2490 REPORT_COUNT(1, 2),
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),
2498 REPORT_COUNT(1, 8),
2499 REPORT_SIZE(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),
2506 REPORT_COUNT(1, 8),
2507 REPORT_SIZE(1, 1),
2508 INPUT(1, Cnst|Var|Abs),
2509 REPORT_SIZE(1, 8),
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),
2517 REPORT_COUNT(1, 2),
2518 REPORT_SIZE(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 */
2522 USAGE(1, 0x20),
2523 LOGICAL_MINIMUM(1, 0),
2524 LOGICAL_MAXIMUM(1, 1),
2525 REPORT_COUNT(1, 8),
2526 REPORT_SIZE(1, 1),
2527 INPUT(1, Data|Var|Abs),
2528 USAGE_MINIMUM(1, 0x21),
2529 USAGE_MAXIMUM(1, 0x22),
2530 REPORT_COUNT(1, 2),
2531 REPORT_SIZE(1, 0),
2532 INPUT(1, Data|Var|Abs),
2533 USAGE(1, 0x23),
2534 REPORT_COUNT(1, 0),
2535 REPORT_SIZE(1, 1),
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),
2542 REPORT_SIZE(1, 4),
2543 REPORT_COUNT(1, 2),
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),
2552 REPORT_SIZE(1, 32),
2553 REPORT_COUNT(1, 1),
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),
2561 REPORT_SIZE(1, 32),
2562 REPORT_COUNT(1, 1),
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),
2571 REPORT_SIZE(1, 32),
2572 REPORT_COUNT(1, 1),
2573 INPUT(1, Data|Var|Abs),
2574 END_COLLECTION,
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),
2585 REPORT_COUNT(1, 8),
2586 REPORT_SIZE(1, 1),
2587 INPUT(1, Data|Var|Abs),
2588 END_COLLECTION,
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),
2595 USAGE(1, 1),
2596 USAGE(1, 2),
2597 USAGE(1, 3),
2598 USAGE(1, 4),
2599 USAGE(1, 5),
2600 USAGE(1, 6),
2601 USAGE(1, 7),
2602 USAGE(1, 8),
2603 LOGICAL_MINIMUM(1, 0),
2604 LOGICAL_MAXIMUM(1, 1),
2605 PHYSICAL_MINIMUM(1, 0),
2606 PHYSICAL_MAXIMUM(1, 1),
2607 REPORT_COUNT(1, 8),
2608 REPORT_SIZE(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),
2617 REPORT_COUNT(1, 2),
2618 REPORT_SIZE(1, 8),
2619 INPUT(1, Data|Ary|Abs),
2620 END_COLLECTION,
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),
2635 REPORT_COUNT(1, 2),
2636 REPORT_SIZE(1, 16),
2637 FEATURE(1, Data|Var|Abs|Null),
2638 END_COLLECTION,
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),
2648 REPORT_COUNT(1, 2),
2649 REPORT_SIZE(1, 16),
2650 FEATURE(1, Data|Var|Abs|Null),
2651 END_COLLECTION,
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),
2661 REPORT_SIZE(1, 32),
2662 REPORT_COUNT(1, 2),
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),
2674 REPORT_SIZE(1, 32),
2675 REPORT_COUNT(1, 1),
2676 FEATURE(1, Data|Var|Abs),
2677 END_COLLECTION,
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),
2690 REPORT_COUNT(1, 8),
2691 REPORT_SIZE(1, 1),
2692 FEATURE(1, Data|Var|Abs),
2693 END_COLLECTION,
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),
2700 REPORT_COUNT(1, 8),
2701 REPORT_SIZE(1, 1),
2702 OUTPUT(1, Cnst|Var|Abs),
2703 END_COLLECTION,
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),
2710 REPORT_COUNT(1, 8),
2711 REPORT_SIZE(1, 1),
2712 OUTPUT(1, Cnst|Var|Abs),
2713 END_COLLECTION,
2714 END_COLLECTION,
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),
2722 .VendorID = 0x1209,
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},
2746 .ret_length = 3,
2747 .ret_status = STATUS_SUCCESS,
2750 WCHAR cwd[MAX_PATH], tempdir[MAX_PATH];
2751 char context[64];
2752 LSTATUS status;
2753 HKEY hkey;
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 );
2790 pnp_driver_stop();
2791 SetCurrentDirectoryW( cwd );
2794 /* undocumented HID internal preparsed data structure */
2796 struct hidp_kdr_caps
2798 USHORT usage_page;
2799 UCHAR report_id;
2800 UCHAR start_bit;
2801 USHORT bit_size;
2802 USHORT report_count;
2803 USHORT start_byte;
2804 USHORT total_bits;
2805 ULONG bit_field;
2806 USHORT end_byte;
2807 USHORT link_collection;
2808 USAGE link_usage_page;
2809 USAGE link_usage;
2810 ULONG flags;
2811 ULONG padding[8];
2812 USAGE usage_min;
2813 USAGE usage_max;
2814 USHORT string_min;
2815 USHORT string_max;
2816 USHORT designator_min;
2817 USHORT designator_max;
2818 USHORT data_index_min;
2819 USHORT data_index_max;
2820 USHORT null_value;
2821 USHORT unknown;
2822 LONG logical_min;
2823 LONG logical_max;
2824 LONG physical_min;
2825 LONG physical_max;
2826 LONG units;
2827 LONG units_exp;
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
2841 USAGE usage;
2842 USAGE usage_page;
2843 USHORT parent;
2844 USHORT number_of_children;
2845 USHORT next_sibling;
2846 USHORT first_child;
2847 ULONG collection_type;
2850 struct hidp_kdr
2852 char magic[8];
2853 USAGE usage;
2854 USAGE usage_page;
2855 USHORT unknown[2];
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;
2868 USHORT caps_size;
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),
2889 REPORT_SIZE(1, 16),
2890 REPORT_COUNT(1, 0),
2891 FEATURE(1, Data|Var|Abs),
2892 USAGE(1, HID_USAGE_GENERIC_SLIDER),
2893 REPORT_SIZE(1, 16),
2894 REPORT_COUNT(1, 1),
2895 FEATURE(1, Data|Var|Abs),
2897 USAGE(1, HID_USAGE_GENERIC_X),
2898 REPORT_SIZE(1, 8),
2899 REPORT_COUNT(1, 1),
2900 UNIT(1, 0x100e),
2901 UNIT_EXPONENT(1, -3),
2902 INPUT(1, Data|Var|Abs),
2903 UNIT_EXPONENT(1, 0),
2904 UNIT(1, 0),
2905 USAGE(1, HID_USAGE_GENERIC_Y),
2906 DESIGNATOR_MINIMUM(1, 1),
2907 DESIGNATOR_MAXIMUM(1, 4),
2908 REPORT_SIZE(1, 8),
2909 REPORT_COUNT(1, 1),
2910 INPUT(1, Cnst|Var|Abs),
2911 USAGE(1, HID_USAGE_GENERIC_Z),
2912 REPORT_SIZE(1, 8),
2913 REPORT_COUNT(1, 1),
2914 INPUT(1, Data|Var|Rel),
2915 USAGE(1, HID_USAGE_GENERIC_RX),
2916 USAGE(1, HID_USAGE_GENERIC_RY),
2917 REPORT_SIZE(1, 16),
2918 REPORT_COUNT(1, 2),
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),
2925 REPORT_SIZE(1, 1),
2926 REPORT_COUNT(1, 8),
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),
2933 REPORT_SIZE(1, 8),
2934 REPORT_COUNT(1, 1),
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),
2941 REPORT_SIZE(1, 8),
2942 REPORT_COUNT(1, 4),
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),
2951 REPORT_SIZE(1, 8),
2952 REPORT_COUNT(1, 1),
2953 LOGICAL_MINIMUM(1, 13),
2954 LOGICAL_MAXIMUM(1, 16),
2955 INPUT(1, Data|Ary|Abs),
2956 END_COLLECTION,
2957 END_COLLECTION,
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),
2970 .VendorID = 0x1209,
2971 .ProductID = 0x0001,
2972 .VersionNumber = 0x0100,
2974 static const struct hidp_kdr expect_kdr =
2976 .magic = "HidP KDR",
2977 .usage = 0x04,
2978 .usage_page = 0x01,
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,
2988 .caps_size = 1560,
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,
3037 .logical_min = 8
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,
3043 .logical_min = 12
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,
3049 .logical_min = 16
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,
3055 .logical_min = 16
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,
3061 .logical_min = 16
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,
3067 .logical_min = 16
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,
3073 .physical_max = 127
3078 static const struct hidp_kdr_node expect_nodes[] =
3081 .usage = 0x04,
3082 .usage_page = 0x01,
3083 .parent = 0,
3084 .number_of_children = 0x1,
3085 .next_sibling = 0,
3086 .first_child = 0x1,
3087 .collection_type = 0x1,
3090 .usage = 0x00,
3091 .usage_page = 0x01,
3092 .parent = 0,
3093 .number_of_children = 0,
3094 .next_sibling = 0,
3095 .first_child = 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;
3108 char context[64];
3109 LSTATUS status;
3110 HDEVINFO set;
3111 HANDLE file;
3112 HKEY hkey;
3113 BOOL ret;
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 );
3194 todo_wine
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 );
3198 todo_wine
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 );
3264 done:
3265 pnp_driver_stop();
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";
3275 HKEY root_key;
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
3280 support.
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;
3314 DWORD polled = 0;
3315 char context[64];
3316 LSTATUS status;
3317 HKEY hkey;
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
3352 BOOL type;
3353 BOOL guid;
3354 BOOL usage;
3355 BOOL name;
3358 struct check_objects_params
3360 DWORD version;
3361 UINT index;
3362 UINT expect_count;
3363 const DIDEVICEOBJECTINSTANCEW *expect_objs;
3364 const struct check_objects_todos *todo_objs;
3365 BOOL todo_extra;
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();
3410 params->index++;
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
3423 UINT index;
3424 UINT expect_count;
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();
3447 params->index++;
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;
3468 DWORD count;
3471 static BOOL CALLBACK check_created_effect_objects( IDirectInputEffect *effect, void *context )
3473 struct check_created_effect_params *params = context;
3474 ULONG ref;
3476 ok( effect == params->expect_effect, "got effect %p, expected %p\n", effect, params->expect_effect );
3477 params->count++;
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 =
3496 .diph =
3498 .dwSize = sizeof(DIPROPDWORD),
3499 .dwHeaderSize = sizeof(DIPROPHEADER),
3500 .dwHow = DIPH_DEVICE,
3503 IDirectInput8W *di8;
3504 IDirectInputW *di;
3505 ULONG ref, count;
3506 HRESULT hr;
3508 if (version >= 0x800)
3510 hr = DirectInput8Create( instance, version, &IID_IDirectInput8W, (void **)&di8, NULL );
3511 if (FAILED(hr))
3513 win_skip( "DirectInput8Create returned %#x\n", hr );
3514 return 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 );
3534 count = 0;
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 );
3538 count = 0;
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 );
3542 count = 0;
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 );
3546 todo_wine
3547 ok( count == 3, "got count %u, expected 3\n", count );
3548 count = 0;
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 );
3552 todo_wine
3553 ok( count == 3, "got count %u, expected 3\n", count );
3554 count = 0;
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 );
3560 count = 0;
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 );
3565 count = 0;
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 );
3571 count = 0;
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 );
3601 todo_wine
3602 ok( ref == 0, "Release returned %d\n", ref );
3604 else
3606 hr = DirectInputCreateEx( instance, version, &IID_IDirectInput2W, (void **)&di, NULL );
3607 if (FAILED(hr))
3609 win_skip( "DirectInputCreateEx returned %#x\n", hr );
3610 return 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 );
3633 count = 0;
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 );
3637 count = 0;
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 );
3641 count = 0;
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 );
3645 todo_wine
3646 ok( count == 3, "got count %u, expected 3\n", count );
3647 count = 0;
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 );
3651 todo_wine
3652 ok( count == 3, "got count %u, expected 3\n", count );
3653 count = 0;
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 );
3659 count = 0;
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 );
3664 count = 0;
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 );
3677 todo_wine
3678 ok( ref == 0, "Release returned %d\n", ref );
3681 return DI_OK;
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),
3694 REPORT_ID(1, 1),
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),
3707 REPORT_SIZE(1, 8),
3708 REPORT_COUNT(1, 7),
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),
3716 REPORT_SIZE(1, 4),
3717 REPORT_COUNT(1, 1),
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),
3727 REPORT_SIZE(1, 1),
3728 REPORT_COUNT(1, 4),
3729 INPUT(1, Data|Var|Abs),
3730 END_COLLECTION,
3731 END_COLLECTION,
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,
3745 .dwAxes = 6,
3746 .dwPOVs = 1,
3747 .dwButtons = 2,
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,
3846 .wReportId = 1,
3849 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3850 .guidType = GUID_Unknown,
3851 .dwOfs = 0x4,
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,
3857 .wReportId = 1,
3860 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3861 .guidType = GUID_RzAxis,
3862 .dwOfs = 0x8,
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,
3869 .wReportId = 1,
3872 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3873 .guidType = GUID_YAxis,
3874 .dwOfs = 0xc,
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,
3881 .wReportId = 1,
3884 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3885 .guidType = GUID_XAxis,
3886 .dwOfs = 0x10,
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,
3893 .wReportId = 1,
3896 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3897 .guidType = GUID_ZAxis,
3898 .dwOfs = 0x18,
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,
3905 .wReportId = 1,
3908 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3909 .guidType = GUID_POV,
3910 .dwOfs = 0x1c,
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,
3916 .wReportId = 1,
3919 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3920 .guidType = GUID_Button,
3921 .dwOfs = 0x20,
3922 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(0),
3923 .tszName = L"Button 0",
3924 .wCollectionNumber = 1,
3925 .wUsagePage = HID_USAGE_PAGE_BUTTON,
3926 .wUsage = 0x1,
3927 .wReportId = 1,
3930 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
3931 .guidType = GUID_Button,
3932 .dwOfs = 0x21,
3933 .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(1),
3934 .tszName = L"Button 1",
3935 .wCollectionNumber = 1,
3936 .wUsagePage = HID_USAGE_PAGE_BUTTON,
3937 .wUsage = 0x2,
3938 .wReportId = 1,
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 =
3972 .diph =
3974 .dwSize = sizeof(DIPROPGUIDANDPATH),
3975 .dwHeaderSize = sizeof(DIPROPHEADER),
3976 .dwHow = DIPH_DEVICE,
3979 DIPROPSTRING prop_string =
3981 .diph =
3983 .dwSize = sizeof(DIPROPSTRING),
3984 .dwHeaderSize = sizeof(DIPROPHEADER),
3985 .dwHow = DIPH_DEVICE,
3988 DIPROPDWORD prop_dword =
3990 .diph =
3992 .dwSize = sizeof(DIPROPDWORD),
3993 .dwHeaderSize = sizeof(DIPROPHEADER),
3994 .dwHow = DIPH_DEVICE,
3997 DIPROPRANGE prop_range =
3999 .diph =
4001 .dwSize = sizeof(DIPROPRANGE),
4002 .dwHeaderSize = sizeof(DIPROPHEADER),
4003 .dwHow = DIPH_DEVICE,
4006 DIPROPPOINTER prop_pointer =
4008 .diph =
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};
4025 HANDLE event, file;
4026 char buffer[1024];
4027 DIJOYSTATE2 state;
4028 ULONG i, res, ref;
4029 HRESULT hr;
4030 WCHAR *tmp;
4031 GUID guid;
4032 HWND hwnd;
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 );
4043 todo_wine
4044 ok( hr == DIERR_BETADIRECTINPUTVERSION, "Initialize returned %#x\n", hr );
4045 hr = IDirectInputDevice8_Initialize( device, instance, DIRECTINPUT_VERSION, NULL );
4046 todo_wine
4047 ok( hr == E_POINTER, "Initialize returned %#x\n", hr );
4048 hr = IDirectInputDevice8_Initialize( device, NULL, DIRECTINPUT_VERSION, &GUID_NULL );
4049 todo_wine
4050 ok( hr == DIERR_INVALIDPARAM, "Initialize returned %#x\n", hr );
4051 hr = IDirectInputDevice8_Initialize( device, instance, DIRECTINPUT_VERSION, &GUID_NULL );
4052 todo_wine
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 );
4076 todo_wine
4077 check_member_guid( devinst, expect_devinst, guidInstance );
4078 check_member_guid( devinst, expect_devinst, guidProduct );
4079 check_member( devinst, expect_devinst, "%#x", dwDevType );
4080 todo_wine
4081 check_member_wstr( devinst, expect_devinst, tszInstanceName );
4082 todo_wine
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 );
4090 todo_wine
4091 check_member_guid( devinst, expect_devinst, guidInstance );
4092 check_member_guid( devinst, expect_devinst, guidProduct );
4093 check_member( devinst, expect_devinst, "%#x", dwDevType );
4094 todo_wine
4095 check_member_wstr( devinst, expect_devinst, tszInstanceName );
4096 todo_wine
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 );
4141 todo_wine
4142 ok( IsEqualGUID( &prop_guid_path.guidClass, &GUID_DEVCLASS_HIDCLASS ), "got guid %s\n",
4143 debugstr_guid( &prop_guid_path.guidClass ) );
4144 todo_wine
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) );
4149 else
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 );
4157 todo_wine
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 );
4162 todo_wine
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 );
4166 todo_wine
4167 ok( hr == DI_OK, "GetProperty DIPROP_TYPENAME returned %#x\n", hr );
4168 todo_wine
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 );
4172 todo_wine
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 );
4178 todo_wine
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 );
4183 todo_wine
4184 ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#x\n", hr );
4185 todo_wine
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 );
4246 todo_wine
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 );
4284 todo_wine
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 );
4291 res = 0;
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 );
4360 res = 0;
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 );
4364 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 );
4417 todo_wine
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();
4518 res = 1;
4519 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA) - 1, objdata, &res, DIGDD_PEEK );
4520 todo_wine
4521 ok( hr == DIERR_INVALIDPARAM, "GetDeviceData returned %#x\n", hr );
4522 res = 1;
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 );
4540 res = 1;
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 );
4550 res = 1;
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 );
4554 res = 1;
4555 hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 0 );
4556 todo_wine
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 );
4575 res = 1;
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 );
4582 res = 4;
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 );
4604 res = 1;
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 );
4608 todo_wine
4609 check_member( objdata[0], expect_objdata[5], "%#x", dwOfs );
4610 todo_wine
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 );
4620 todo_wine
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 );
4664 todo_wine
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 );
4671 todo_wine
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 );
4677 todo_wine
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 );
4691 todo_wine
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 );
4748 todo_wine
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 );
4765 todo_wine
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 );
4897 todo_wine
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 );
4901 todo_wine
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 );
4915 todo_wine
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 );
4926 todo_wine
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" );
4993 else
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 );
5042 todo_wine
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 );
5093 todo_wine
5094 ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#x\n", hr );
5095 todo_wine
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 );
5106 todo_wine
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 );
5121 todo_wine
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 );
5135 todo_wine
5136 check_member( state, expect_state_rel[i], "%d", lX );
5137 todo_wine
5138 check_member( state, expect_state_rel[i], "%d", lY );
5139 todo_wine
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 );
5160 todo_wine
5161 check_member( state, expect_state_rel[i], "%d", lX );
5162 todo_wine
5163 check_member( state, expect_state_rel[i], "%d", lY );
5164 todo_wine
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 );
5176 res = 0xdeadbeef;
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;
5187 res = 1;
5188 hr = IDirectInputDevice8_SendDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 0xdeadbeef );
5189 todo_wine
5190 ok( hr == DIERR_INVALIDPARAM, "SendDeviceData returned %#x\n", hr );
5191 res = 1;
5192 hr = IDirectInputDevice8_SendDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 1 /*DISDD_CONTINUE*/ );
5193 todo_wine
5194 ok( hr == DIERR_INVALIDPARAM, "SendDeviceData returned %#x\n", hr );
5195 res = 1;
5196 hr = IDirectInputDevice8_SendDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 0 );
5197 todo_wine
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 );
5223 todo_wine
5224 ok( hr == E_POINTER, "Escape returned: %#x\n", hr );
5225 hr = IDirectInputDevice8_Escape( device, &escape );
5226 todo_wine
5227 ok( hr == DIERR_INVALIDPARAM, "Escape returned: %#x\n", hr );
5228 escape.dwSize = sizeof(DIEFFESCAPE) + 1;
5229 hr = IDirectInputDevice8_Escape( device, &escape );
5230 todo_wine
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 );
5239 todo_wine
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 );
5248 done:
5249 pnp_driver_stop();
5250 cleanup_registry_keys();
5251 SetCurrentDirectoryW( cwd );
5254 struct device_desc
5256 const BYTE *report_desc_buf;
5257 ULONG report_desc_len;
5258 HIDP_CAPS hid_caps;
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),
5278 REPORT_SIZE(1, 1),
5279 REPORT_COUNT(1, 8),
5280 INPUT(1, Data|Var|Abs),
5281 END_COLLECTION,
5282 END_COLLECTION,
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),
5297 REPORT_SIZE(1, 8),
5298 REPORT_COUNT(1, 2),
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),
5308 REPORT_SIZE(1, 1),
5309 REPORT_COUNT(1, 8),
5310 INPUT(1, Data|Var|Abs),
5311 END_COLLECTION,
5312 END_COLLECTION,
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),
5327 REPORT_SIZE(1, 8),
5328 REPORT_COUNT(1, 2),
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),
5338 REPORT_SIZE(1, 1),
5339 REPORT_COUNT(1, 8),
5340 INPUT(1, Data|Var|Abs),
5341 END_COLLECTION,
5342 END_COLLECTION,
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),
5358 REPORT_SIZE(1, 8),
5359 REPORT_COUNT(1, 3),
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),
5367 REPORT_SIZE(1, 8),
5368 REPORT_COUNT(1, 1),
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),
5378 REPORT_SIZE(1, 1),
5379 REPORT_COUNT(1, 8),
5380 INPUT(1, Data|Var|Abs),
5381 END_COLLECTION,
5382 END_COLLECTION,
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),
5391 .hid_caps =
5393 .InputReportByteLength = 1,
5397 .report_desc_buf = limited_desc,
5398 .report_desc_len = sizeof(limited_desc),
5399 .hid_caps =
5401 .InputReportByteLength = 3,
5405 .report_desc_buf = gamepad_desc,
5406 .report_desc_len = sizeof(gamepad_desc),
5407 .hid_caps =
5409 .InputReportByteLength = 3,
5413 .report_desc_buf = joystick_desc,
5414 .report_desc_len = sizeof(joystick_desc),
5415 .hid_caps =
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,
5428 .dwButtons = 6,
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,
5435 .dwAxes = 2,
5436 .dwButtons = 6,
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,
5443 .dwAxes = 2,
5444 .dwButtons = 6,
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,
5451 .dwAxes = 3,
5452 .dwPOVs = 1,
5453 .dwButtons = 5,
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;
5514 ULONG i, ref;
5515 HRESULT hr;
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 ))
5530 success = FALSE;
5531 goto done;
5534 if (FAILED(hr = create_dinput_device( version, &devinst, &device )))
5536 success = FALSE;
5537 goto done;
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 );
5543 todo_wine
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 );
5548 todo_wine
5549 check_member_wstr( devinst, expect_devinst[i], tszInstanceName );
5550 todo_wine
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 );
5574 done:
5575 pnp_driver_stop();
5576 cleanup_registry_keys();
5577 SetCurrentDirectoryW( cwd );
5578 winetest_pop_context();
5581 winetest_pop_context();
5583 return success;
5586 static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWORD version )
5588 struct hid_expect expect_download[] =
5590 /* set periodic */
5592 .code = IOCTL_HID_WRITE_REPORT,
5593 .report_id = 5,
5594 .report_len = 2,
5595 .report_buf = {0x05,0x19},
5597 /* set envelope */
5599 .code = IOCTL_HID_WRITE_REPORT,
5600 .report_id = 6,
5601 .report_len = 7,
5602 .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
5604 /* update effect */
5606 .code = IOCTL_HID_WRITE_REPORT,
5607 .report_id = 3,
5608 .report_len = 11,
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,
5614 .report_id = 2,
5615 .report_len = 4,
5616 .report_buf = {0x02,0x01,0x01,0x01},
5619 struct hid_expect expect_download_2[] =
5621 /* set periodic */
5623 .code = IOCTL_HID_WRITE_REPORT,
5624 .report_id = 5,
5625 .report_len = 2,
5626 .report_buf = {0x05,0x19},
5628 /* set envelope */
5630 .code = IOCTL_HID_WRITE_REPORT,
5631 .report_id = 6,
5632 .report_len = 7,
5633 .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00},
5635 /* update effect */
5637 .code = IOCTL_HID_WRITE_REPORT,
5638 .report_id = 3,
5639 .report_len = 11,
5640 .report_buf = {0x03,0x01,0x02,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5643 struct hid_expect expect_update[] =
5645 /* update effect */
5647 .code = IOCTL_HID_WRITE_REPORT,
5648 .report_id = 3,
5649 .report_len = 11,
5650 .report_buf = {0x03,0x01,0x02,0x08,0xff,0xff,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
5653 struct hid_expect expect_set_envelope[] =
5655 /* set envelope */
5657 .code = IOCTL_HID_WRITE_REPORT,
5658 .report_id = 6,
5659 .report_len = 7,
5660 .report_buf = {0x06,0x19,0x4c,0x01,0x00,0x04,0x00},
5663 struct hid_expect expect_start =
5665 .code = IOCTL_HID_WRITE_REPORT,
5666 .report_id = 2,
5667 .report_len = 4,
5668 .report_buf = {0x02, 0x01, 0x01, 0x01},
5670 struct hid_expect expect_start_solo =
5672 .code = IOCTL_HID_WRITE_REPORT,
5673 .report_id = 2,
5674 .report_len = 4,
5675 .report_buf = {0x02, 0x01, 0x02, 0x01},
5677 struct hid_expect expect_start_0 =
5679 .code = IOCTL_HID_WRITE_REPORT,
5680 .report_id = 2,
5681 .report_len = 4,
5682 .report_buf = {0x02, 0x01, 0x01, 0x00},
5684 struct hid_expect expect_start_4 =
5686 .code = IOCTL_HID_WRITE_REPORT,
5687 .report_id = 2,
5688 .report_len = 4,
5689 .report_buf = {0x02, 0x01, 0x01, 0x04},
5691 struct hid_expect expect_stop =
5693 .code = IOCTL_HID_WRITE_REPORT,
5694 .report_id = 2,
5695 .report_len = 4,
5696 .report_buf = {0x02, 0x01, 0x03, 0x00},
5698 struct hid_expect expect_unload[] =
5701 .code = IOCTL_HID_WRITE_REPORT,
5702 .report_id = 2,
5703 .report_len = 4,
5704 .report_buf = {0x02,0x01,0x03,0x00},
5706 /* device reset, when unloaded from Unacquire */
5708 .code = IOCTL_HID_WRITE_REPORT,
5709 .report_id = 1,
5710 .report_len = 2,
5711 .report_buf = {1,0x01},
5714 struct hid_expect expect_acquire[] =
5717 .code = IOCTL_HID_WRITE_REPORT,
5718 .report_id = 1,
5719 .report_len = 2,
5720 .report_buf = {1, 0x01},
5723 .code = IOCTL_HID_WRITE_REPORT,
5724 .report_id = 8,
5725 .report_len = 2,
5726 .report_buf = {8, 0x19},
5729 struct hid_expect expect_reset[] =
5732 .code = IOCTL_HID_WRITE_REPORT,
5733 .report_id = 1,
5734 .report_len = 2,
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] =
5753 +3000,
5754 -6000,
5757 static const DIENVELOPE expect_envelope =
5759 .dwSize = sizeof(DIENVELOPE),
5760 .dwAttackLevel = 1000,
5761 .dwAttackTime = 2000,
5762 .dwFadeLevel = 3000,
5763 .dwFadeTime = 4000,
5765 static const DIPERIODIC expect_periodic =
5767 .dwMagnitude = 1000,
5768 .lOffset = 2000,
5769 .dwPhase = 3000,
5770 .dwPeriod = 4000,
5772 const DIEFFECT expect_desc =
5774 .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
5775 .dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
5776 .dwDuration = 1000,
5777 .dwSamplePeriod = 2000,
5778 .dwGain = 3000,
5779 .dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER,
5780 .dwTriggerRepeatInterval = 5000,
5781 .cAxes = 3,
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;
5797 HRESULT hr;
5798 GUID guid;
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)
5823 todo_wine
5824 ok( hr == DIERR_BETADIRECTINPUTVERSION, "Initialize returned %#x\n", hr );
5826 else
5828 todo_wine
5829 ok( hr == DIERR_OLDDIRECTINPUTVERSION, "Initialize returned %#x\n", hr );
5831 hr = IDirectInputEffect_Initialize( effect, instance, 0, &GUID_Sine );
5832 todo_wine
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);
5886 desc.dwFlags = 0;
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);
5900 desc.dwFlags = 0;
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 );
5911 desc.dwFlags = 0;
5912 desc.cAxes = 0;
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;
5957 desc.cAxes = 2;
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 );
5983 todo_wine
5984 check_member( desc, expect_desc_init, "%p", lpEnvelope );
5985 todo_wine
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 );
6099 desc.dwFlags = 0;
6100 desc.cAxes = 0;
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;
6115 desc.cAxes = 1;
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 );
6126 desc.cAxes = 0;
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;
6154 desc.cAxes = 0;
6155 desc.rglDirection = directions;
6156 hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_DIRECTION | DIEP_NODOWNLOAD );
6157 ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#x\n", hr );
6158 desc.cAxes = 3;
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;
6162 desc.cAxes = 3;
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;
6170 desc.cAxes = 1;
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;
6182 desc.cAxes = 2;
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;
6194 desc.cAxes = 3;
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;
6306 desc.cAxes = 2;
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;
6317 desc.cAxes = 1;
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;
6330 desc.cAxes = 1;
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;
6343 desc.cAxes = 1;
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;
6365 desc.cAxes = i;
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 );
6382 desc.cAxes = i;
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;
6387 desc.cAxes = i;
6388 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
6389 ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
6390 desc.cAxes = 3;
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 );
6395 if (i == 1)
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 );
6403 else
6405 ok( desc.rglDirection[0] == 6343, "got rglDirection[0] %d expected %d\n",
6406 desc.rglDirection[0], 6343 );
6407 if (i == 2)
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 );
6414 else
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;
6424 desc.cAxes = i;
6425 hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_DIRECTION );
6426 ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
6427 desc.cAxes = 3;
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 );
6433 if (i == 1)
6434 ok( desc.rglDirection[1] == 0xcdcdcdcd, "got rglDirection[1] %d expected %d\n",
6435 desc.rglDirection[1], 0xcdcdcdcd );
6436 else
6437 ok( desc.rglDirection[1] == 2000, "got rglDirection[1] %d expected %d\n",
6438 desc.rglDirection[1], 2000 );
6439 if (i <= 2)
6440 ok( desc.rglDirection[2] == 0xcdcdcdcd, "got rglDirection[2] %d expected %d\n",
6441 desc.rglDirection[2], 0xcdcdcdcd );
6442 else
6443 ok( desc.rglDirection[2] == 3000, "got rglDirection[2] %d expected %d\n",
6444 desc.rglDirection[2], 3000 );
6446 desc.dwFlags = DIEFF_POLAR;
6447 desc.cAxes = 1;
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 );
6451 desc.cAxes = 3;
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 );
6455 else
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 );
6479 desc = expect_desc;
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 */
6488 desc = expect_desc;
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 */
6498 desc = expect_desc;
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[] =
6531 /* set condition */
6533 .code = IOCTL_HID_WRITE_REPORT,
6534 .report_id = 7,
6535 .report_len = 8,
6536 .report_buf = {0x07,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
6538 /* set condition */
6540 .code = IOCTL_HID_WRITE_REPORT,
6541 .report_id = 7,
6542 .report_len = 8,
6543 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6545 /* update effect */
6547 .code = IOCTL_HID_WRITE_REPORT,
6548 .report_id = 3,
6549 .report_len = 11,
6550 .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
6553 struct hid_expect expect_create_1[] =
6555 /* set condition */
6557 .code = IOCTL_HID_WRITE_REPORT,
6558 .report_id = 7,
6559 .report_len = 8,
6560 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6562 /* update effect */
6564 .code = IOCTL_HID_WRITE_REPORT,
6565 .report_id = 3,
6566 .report_len = 11,
6567 .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x3f,0x00},
6570 struct hid_expect expect_create_2[] =
6572 /* set condition */
6574 .code = IOCTL_HID_WRITE_REPORT,
6575 .report_id = 7,
6576 .report_len = 8,
6577 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6579 /* update effect */
6581 .code = IOCTL_HID_WRITE_REPORT,
6582 .report_id = 3,
6583 .report_len = 11,
6584 .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xf1},
6587 struct hid_expect expect_create_3[] =
6589 /* set condition */
6591 .code = IOCTL_HID_WRITE_REPORT,
6592 .report_id = 7,
6593 .report_len = 8,
6594 .report_buf = {0x07,0x00,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
6596 /* update effect */
6598 .code = IOCTL_HID_WRITE_REPORT,
6599 .report_id = 3,
6600 .report_len = 11,
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,
6607 .report_id = 2,
6608 .report_len = 4,
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] = {
6618 +3000,
6622 static const DIENVELOPE expect_envelope =
6624 .dwSize = sizeof(DIENVELOPE),
6625 .dwAttackLevel = 1000,
6626 .dwAttackTime = 2000,
6627 .dwFadeLevel = 3000,
6628 .dwFadeTime = 4000,
6630 static const DICONDITION expect_condition[3] =
6633 .lOffset = -500,
6634 .lPositiveCoefficient = 2000,
6635 .lNegativeCoefficient = -3000,
6636 .dwPositiveSaturation = -4000,
6637 .dwNegativeSaturation = -5000,
6638 .lDeadBand = 6000,
6641 .lOffset = 6000,
6642 .lPositiveCoefficient = 5000,
6643 .lNegativeCoefficient = -4000,
6644 .dwPositiveSaturation = 3000,
6645 .dwNegativeSaturation = 2000,
6646 .lDeadBand = 1000,
6649 .lOffset = -7000,
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,
6661 .dwDuration = 1000,
6662 .dwSamplePeriod = 2000,
6663 .dwGain = 3000,
6664 .dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER,
6665 .dwTriggerRepeatInterval = 5000,
6666 .cAxes = 2,
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};
6681 DIEFFECT desc =
6683 .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
6684 .dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
6685 .cAxes = 4,
6686 .rgdwAxes = axes,
6687 .rglDirection = directions,
6688 .lpEnvelope = &envelope,
6689 .cbTypeSpecificParams = 2 * sizeof(DICONDITION),
6690 .lpvTypeSpecificParams = condition,
6692 HRESULT hr;
6693 ULONG ref;
6694 GUID guid;
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 );
6748 desc = expect_desc;
6749 desc.cAxes = 1;
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 );
6764 desc = expect_desc;
6765 desc.cAxes = 3;
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 );
6782 desc = expect_desc;
6783 desc.cAxes = 2;
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),
6812 REPORT_ID(1, 1),
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),
6821 REPORT_SIZE(1, 8),
6822 REPORT_COUNT(1, 3),
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),
6832 REPORT_SIZE(1, 1),
6833 REPORT_COUNT(1, 2),
6834 INPUT(1, Data|Var|Abs),
6835 REPORT_COUNT(1, 6),
6836 INPUT(1, Cnst|Var|Abs),
6837 END_COLLECTION,
6839 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
6840 USAGE(1, PID_USAGE_STATE_REPORT),
6841 COLLECTION(1, Report),
6842 REPORT_ID(1, 2),
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),
6853 REPORT_SIZE(1, 1),
6854 REPORT_COUNT(1, 5),
6855 INPUT(1, Data|Var|Abs),
6856 REPORT_COUNT(1, 3),
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),
6864 REPORT_SIZE(1, 1),
6865 REPORT_COUNT(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),
6871 REPORT_SIZE(1, 7),
6872 REPORT_COUNT(1, 1),
6873 INPUT(1, Data|Var|Abs),
6874 END_COLLECTION,
6876 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
6877 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT),
6878 COLLECTION(1, Report),
6879 REPORT_ID(1, 1),
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),
6888 REPORT_SIZE(1, 8),
6889 REPORT_COUNT(1, 1),
6890 OUTPUT(1, Data|Ary|Abs),
6891 END_COLLECTION,
6892 END_COLLECTION,
6894 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
6895 COLLECTION(1, Report),
6896 REPORT_ID(1, 2),
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),
6903 REPORT_SIZE(1, 8),
6904 REPORT_COUNT(1, 1),
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),
6916 REPORT_SIZE(1, 8),
6917 REPORT_COUNT(1, 1),
6918 OUTPUT(1, Data|Ary|Abs),
6919 END_COLLECTION,
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),
6926 REPORT_SIZE(1, 8),
6927 REPORT_COUNT(1, 1),
6928 OUTPUT(1, Data|Var|Abs),
6929 END_COLLECTION,
6931 USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
6932 COLLECTION(1, Report),
6933 REPORT_ID(1, 3),
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),
6940 REPORT_SIZE(1, 8),
6941 REPORT_COUNT(1, 1),
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),
6953 REPORT_SIZE(1, 8),
6954 REPORT_COUNT(1, 1),
6955 OUTPUT(1, Data|Ary|Abs),
6956 END_COLLECTION,
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),
6967 REPORT_SIZE(1, 1),
6968 REPORT_COUNT(1, 3),
6969 OUTPUT(1, Data|Var|Abs),
6970 END_COLLECTION,
6971 USAGE(1, PID_USAGE_DIRECTION_ENABLE),
6972 REPORT_COUNT(1, 1),
6973 OUTPUT(1, Data|Var|Abs),
6974 REPORT_COUNT(1, 4),
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),
6985 REPORT_SIZE(1, 16),
6986 REPORT_COUNT(1, 2),
6987 OUTPUT(1, Data|Var|Abs),
6988 UNIT(1, 0),
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),
6996 REPORT_SIZE(1, 8),
6997 REPORT_COUNT(1, 1),
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),
7010 UNIT(1, 0),
7011 REPORT_SIZE(1, 8),
7012 REPORT_COUNT(1, 2),
7013 OUTPUT(1, Data|Var|Abs),
7014 UNIT_EXPONENT(1, 0),
7015 UNIT(1, 0),
7016 END_COLLECTION,
7017 END_COLLECTION,
7019 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT),
7020 COLLECTION(1, Logical),
7021 REPORT_ID(1, 5),
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),
7028 REPORT_SIZE(1, 8),
7029 REPORT_COUNT(1, 1),
7030 OUTPUT(1, Data|Var|Abs),
7031 END_COLLECTION,
7033 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT),
7034 COLLECTION(1, Logical),
7035 REPORT_ID(1, 6),
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),
7043 REPORT_SIZE(1, 8),
7044 REPORT_COUNT(1, 2),
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),
7055 REPORT_SIZE(1, 16),
7056 REPORT_COUNT(1, 2),
7057 OUTPUT(1, Data|Var|Abs),
7058 PHYSICAL_MAXIMUM(1, 0),
7059 UNIT_EXPONENT(1, 0),
7060 UNIT(1, 0),
7061 END_COLLECTION,
7064 USAGE(1, PID_USAGE_SET_CONDITION_REPORT),
7065 COLLECTION(1, Logical),
7066 REPORT_ID(1, 7),
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),
7076 REPORT_SIZE(1, 2),
7077 REPORT_COUNT(1, 2),
7078 OUTPUT(1, Data|Var|Abs),
7079 END_COLLECTION,
7080 REPORT_SIZE(1, 4),
7081 REPORT_COUNT(1, 1),
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),
7089 REPORT_SIZE(1, 8),
7090 REPORT_COUNT(1, 1),
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),
7099 REPORT_SIZE(1, 8),
7100 REPORT_COUNT(1, 2),
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),
7109 REPORT_SIZE(1, 8),
7110 REPORT_COUNT(1, 2),
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),
7118 REPORT_SIZE(1, 8),
7119 REPORT_COUNT(1, 1),
7120 OUTPUT(1, Data|Var|Abs),
7121 END_COLLECTION,
7124 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT),
7125 COLLECTION(1, Logical),
7126 REPORT_ID(1, 8),
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),
7133 REPORT_SIZE(1, 8),
7134 REPORT_COUNT(1, 1),
7135 OUTPUT(1, Data|Var|Abs),
7136 END_COLLECTION,
7137 END_COLLECTION,
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,
7153 .dwAxes = 3,
7154 .dwButtons = 2,
7155 .dwFFSamplePeriod = 1000000,
7156 .dwFFMinTimeResolution = 1000000,
7157 .dwHardwareRevision = 1,
7158 .dwFFDriverVersion = 1,
7160 struct hid_expect expect_acquire[] =
7163 .code = IOCTL_HID_WRITE_REPORT,
7164 .report_id = 1,
7165 .report_len = 2,
7166 .report_buf = {1, 0x01},
7169 .code = IOCTL_HID_WRITE_REPORT,
7170 .report_id = 8,
7171 .report_len = 2,
7172 .report_buf = {8, 0x19},
7175 struct hid_expect expect_reset[] =
7178 .code = IOCTL_HID_WRITE_REPORT,
7179 .report_id = 1,
7180 .report_len = 2,
7181 .report_buf = {1, 0x01},
7184 struct hid_expect expect_set_device_gain_1 =
7186 .code = IOCTL_HID_WRITE_REPORT,
7187 .report_id = 8,
7188 .report_len = 2,
7189 .report_buf = {8, 0x19},
7191 struct hid_expect expect_set_device_gain_2 =
7193 .code = IOCTL_HID_WRITE_REPORT,
7194 .report_id = 8,
7195 .report_len = 2,
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,
7223 .wReportId = 1,
7226 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
7227 .guidType = GUID_YAxis,
7228 .dwOfs = 0x4,
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,
7235 .wReportId = 1,
7238 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
7239 .guidType = GUID_ZAxis,
7240 .dwOfs = 0x8,
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,
7247 .wReportId = 1,
7250 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
7251 .guidType = GUID_Button,
7252 .dwOfs = 0x30,
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,
7258 .wUsage = 0x1,
7259 .wReportId = 1,
7262 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
7263 .guidType = GUID_Button,
7264 .dwOfs = 0x31,
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,
7270 .wUsage = 0x2,
7271 .wReportId = 1,
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,
7285 .wReportId = 1,
7288 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
7289 .guidType = GUID_YAxis,
7290 .dwOfs = 0x4,
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,
7297 .wReportId = 1,
7300 .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
7301 .guidType = GUID_XAxis,
7302 .dwOfs = 0x8,
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,
7309 .wReportId = 1,
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,
7320 .wUsage = 0x1,
7321 .wReportId = 1,
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,
7332 .wUsage = 0x2,
7333 .wReportId = 1,
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,
7345 .wReportId = 1,
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,
7357 .wReportId = 2,
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,
7369 .wReportId = 2,
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,
7381 .wReportId = 2,
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,
7393 .wReportId = 2,
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,
7405 .wReportId = 2,
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,
7417 .wReportId = 3,
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,
7429 .wReportId = 3,
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,
7441 .wReportId = 3,
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,
7453 .wReportId = 3,
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,
7465 .wReportId = 3,
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,
7477 .wReportId = 3,
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,
7489 .wReportId = 3,
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,
7501 .wReportId = 3,
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,
7513 .wReportId = 3,
7514 .dwDimension = 0x1003,
7515 .wExponent = -3,
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,
7527 .wReportId = 3,
7528 .dwDimension = 0x1003,
7529 .wExponent = -3,
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,
7541 .wReportId = 3,
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,
7552 .wUsage = 2,
7553 .wReportId = 3,
7554 .wExponent = -2,
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,
7565 .wUsage = 1,
7566 .wReportId = 3,
7567 .wExponent = -2,
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,
7579 .wReportId = 5,
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,
7591 .wReportId = 6,
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,
7603 .wReportId = 6,
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,
7615 .wReportId = 6,
7616 .dwDimension = 0x1003,
7617 .wExponent = -3,
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,
7629 .wReportId = 6,
7630 .dwDimension = 0x1003,
7631 .wExponent = -3,
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,
7642 .wUsage = 2,
7643 .wReportId = 7,
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,
7654 .wUsage = 1,
7655 .wReportId = 7,
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,
7667 .wReportId = 7,
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,
7679 .wReportId = 7,
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,
7691 .wReportId = 7,
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,
7703 .wReportId = 7,
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,
7715 .wReportId = 7,
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,
7727 .wReportId = 7,
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,
7739 .wReportId = 8,
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),
7890 .guid = GUID_Sine,
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 |
7903 DIEP_DURATION,
7904 .dwDynamicParams = DIEP_AXES | DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_STARTDELAY |
7905 DIEP_DURATION,
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},
7913 {0},
7914 {.guid = TRUE, .type = TRUE, .usage = TRUE, .name = TRUE},
7916 struct check_objects_params check_objects_params =
7918 .version = version,
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 =
7931 .diph =
7933 .dwSize = sizeof(DIPROPDWORD),
7934 .dwHeaderSize = sizeof(DIPROPHEADER),
7935 .dwHow = DIPH_DEVICE,
7938 DIPROPGUIDANDPATH prop_guid_path =
7940 .diph =
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};
7954 char buffer[1024];
7955 ULONG res, ref;
7956 HANDLE file;
7957 HRESULT hr;
7958 HWND hwnd;
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 );
7973 todo_wine
7974 check_member_guid( devinst, expect_devinst, guidInstance );
7975 check_member_guid( devinst, expect_devinst, guidProduct );
7976 check_member( devinst, expect_devinst, "%#x", dwDevType );
7977 todo_wine
7978 check_member_wstr( devinst, expect_devinst, tszInstanceName );
7979 todo_wine
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 );
8013 res = 0;
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 );
8017 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 );
8089 todo_wine
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 );
8115 todo_wine
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 );
8120 todo_wine
8121 ok( hr == 0x80040301, "GetProperty DIPROP_FFLOAD returned %#x\n", hr );
8122 res = 0xdeadbeef;
8123 hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
8124 todo_wine
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;
8148 res = 1;
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 );
8167 done:
8168 pnp_driver_stop();
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),
8183 REPORT_ID(1, 1),
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),
8192 REPORT_SIZE(1, 8),
8193 REPORT_COUNT(1, 3),
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),
8203 REPORT_SIZE(1, 1),
8204 REPORT_COUNT(1, 2),
8205 INPUT(1, Data|Var|Abs),
8206 REPORT_COUNT(1, 6),
8207 INPUT(1, Cnst|Var|Abs),
8208 END_COLLECTION,
8210 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
8211 USAGE(1, PID_USAGE_STATE_REPORT),
8212 COLLECTION(1, Report),
8213 REPORT_ID(1, 2),
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),
8224 REPORT_SIZE(1, 1),
8225 REPORT_COUNT(1, 5),
8226 INPUT(1, Data|Var|Abs),
8227 REPORT_COUNT(1, 3),
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),
8235 REPORT_SIZE(1, 1),
8236 REPORT_COUNT(1, 8),
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),
8244 REPORT_SIZE(1, 8),
8245 REPORT_COUNT(1, 1),
8246 INPUT(1, Data|Var|Abs),
8247 END_COLLECTION,
8249 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
8250 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT),
8251 COLLECTION(1, Report),
8252 REPORT_ID(1, 1),
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),
8266 REPORT_SIZE(1, 8),
8267 REPORT_COUNT(1, 1),
8268 OUTPUT(1, Data|Ary|Abs),
8269 END_COLLECTION,
8270 END_COLLECTION,
8272 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
8273 COLLECTION(1, Report),
8274 REPORT_ID(1, 2),
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),
8281 REPORT_SIZE(1, 8),
8282 REPORT_COUNT(1, 1),
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),
8294 REPORT_SIZE(1, 8),
8295 REPORT_COUNT(1, 1),
8296 OUTPUT(1, Data|Ary|Abs),
8297 END_COLLECTION,
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),
8304 REPORT_SIZE(1, 8),
8305 REPORT_COUNT(1, 1),
8306 OUTPUT(1, Data|Var|Abs),
8307 END_COLLECTION,
8309 USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
8310 COLLECTION(1, Report),
8311 REPORT_ID(1, 3),
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),
8318 REPORT_SIZE(1, 8),
8319 REPORT_COUNT(1, 1),
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),
8331 REPORT_SIZE(1, 8),
8332 REPORT_COUNT(1, 1),
8333 OUTPUT(1, Data|Ary|Abs),
8334 END_COLLECTION,
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),
8345 REPORT_SIZE(1, 1),
8346 REPORT_COUNT(1, 3),
8347 OUTPUT(1, Data|Var|Abs),
8348 END_COLLECTION,
8349 USAGE(1, PID_USAGE_DIRECTION_ENABLE),
8350 REPORT_COUNT(1, 1),
8351 OUTPUT(1, Data|Var|Abs),
8352 REPORT_COUNT(1, 4),
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),
8363 REPORT_SIZE(1, 16),
8364 REPORT_COUNT(1, 2),
8365 OUTPUT(1, Data|Var|Abs),
8366 UNIT(1, 0),
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),
8374 REPORT_SIZE(1, 8),
8375 REPORT_COUNT(1, 1),
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),
8388 UNIT(1, 0),
8389 REPORT_SIZE(1, 8),
8390 REPORT_COUNT(1, 2),
8391 OUTPUT(1, Data|Var|Abs),
8392 UNIT_EXPONENT(1, 0),
8393 UNIT(1, 0),
8394 END_COLLECTION,
8395 END_COLLECTION,
8397 USAGE(1, PID_USAGE_SET_CONDITION_REPORT),
8398 COLLECTION(1, Logical),
8399 REPORT_ID(1, 4),
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),
8406 REPORT_SIZE(1, 8),
8407 REPORT_COUNT(1, 1),
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),
8415 REPORT_SIZE(1, 4),
8416 REPORT_COUNT(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),
8427 REPORT_SIZE(1, 2),
8428 REPORT_COUNT(1, 2),
8429 OUTPUT(1, Data|Var|Abs),
8430 END_COLLECTION,
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),
8437 REPORT_SIZE(1, 8),
8438 REPORT_COUNT(1, 1),
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),
8447 REPORT_SIZE(1, 8),
8448 REPORT_COUNT(1, 2),
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),
8457 REPORT_SIZE(1, 8),
8458 REPORT_COUNT(1, 2),
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),
8466 REPORT_SIZE(1, 8),
8467 REPORT_COUNT(1, 1),
8468 OUTPUT(1, Data|Var|Abs),
8469 END_COLLECTION,
8471 USAGE(1, PID_USAGE_BLOCK_FREE_REPORT),
8472 COLLECTION(1, Logical),
8473 REPORT_ID(1, 5),
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),
8480 REPORT_SIZE(1, 8),
8481 REPORT_COUNT(1, 1),
8482 OUTPUT(1, Data|Var|Abs),
8483 END_COLLECTION,
8485 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT),
8486 COLLECTION(1, Logical),
8487 REPORT_ID(1, 6),
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),
8494 REPORT_SIZE(1, 8),
8495 REPORT_COUNT(1, 1),
8496 OUTPUT(1, Data|Var|Abs),
8497 END_COLLECTION,
8499 USAGE(1, PID_USAGE_POOL_REPORT),
8500 COLLECTION(1, Logical),
8501 REPORT_ID(1, 1),
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),
8508 REPORT_SIZE(1, 16),
8509 REPORT_COUNT(1, 1),
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),
8517 REPORT_SIZE(1, 8),
8518 REPORT_COUNT(1, 1),
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),
8527 REPORT_SIZE(1, 1),
8528 REPORT_COUNT(1, 8),
8529 FEATURE(1, Data|Var|Abs),
8530 END_COLLECTION,
8532 USAGE(1, PID_USAGE_CREATE_NEW_EFFECT_REPORT),
8533 COLLECTION(1, Logical),
8534 REPORT_ID(1, 2),
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),
8545 REPORT_SIZE(1, 8),
8546 REPORT_COUNT(1, 1),
8547 FEATURE(1, Data|Ary|Abs),
8548 END_COLLECTION,
8549 END_COLLECTION,
8551 USAGE(1, PID_USAGE_BLOCK_LOAD_REPORT),
8552 COLLECTION(1, Logical),
8553 REPORT_ID(1, 3),
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),
8560 REPORT_SIZE(1, 8),
8561 REPORT_COUNT(1, 1),
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),
8573 REPORT_SIZE(1, 8),
8574 REPORT_COUNT(1, 1),
8575 FEATURE(1, Data|Ary|Abs),
8576 END_COLLECTION,
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),
8583 REPORT_SIZE(1, 16),
8584 REPORT_COUNT(1, 1),
8585 FEATURE(1, Data|Var|Abs),
8586 END_COLLECTION,
8587 END_COLLECTION,
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,
8600 .report_id = 1,
8601 .report_len = 2,
8602 .report_buf = {1, 0x01},
8604 /* device gain */
8606 .code = IOCTL_HID_WRITE_REPORT,
8607 .report_id = 6,
8608 .report_len = 2,
8609 .report_buf = {6, 0xff},
8612 struct hid_expect expect_reset[] =
8614 /* device control */
8616 .code = IOCTL_HID_WRITE_REPORT,
8617 .report_id = 1,
8618 .report_len = 2,
8619 .report_buf = {1, 0x01},
8622 struct hid_expect expect_enable_actuators[] =
8624 /* device control */
8626 .code = IOCTL_HID_WRITE_REPORT,
8627 .report_id = 1,
8628 .report_len = 2,
8629 .report_buf = {1, 0x04},
8632 struct hid_expect expect_disable_actuators[] =
8634 /* device control */
8636 .code = IOCTL_HID_WRITE_REPORT,
8637 .report_id = 1,
8638 .report_len = 2,
8639 .report_buf = {1, 0x05},
8642 struct hid_expect expect_stop_all[] =
8644 /* device control */
8646 .code = IOCTL_HID_WRITE_REPORT,
8647 .report_id = 1,
8648 .report_len = 2,
8649 .report_buf = {1, 0x06},
8652 struct hid_expect expect_device_pause[] =
8654 /* device control */
8656 .code = IOCTL_HID_WRITE_REPORT,
8657 .report_id = 1,
8658 .report_len = 2,
8659 .report_buf = {1, 0x02},
8662 struct hid_expect expect_device_continue[] =
8664 /* device control */
8666 .code = IOCTL_HID_WRITE_REPORT,
8667 .report_id = 1,
8668 .report_len = 2,
8669 .report_buf = {1, 0x03},
8672 struct hid_expect expect_create[] =
8674 /* create new effect */
8676 .code = IOCTL_HID_SET_FEATURE,
8677 .report_id = 2,
8678 .report_len = 2,
8679 .report_buf = {2,0x03},
8681 /* block load */
8683 .code = IOCTL_HID_GET_FEATURE,
8684 .report_id = 3,
8685 .report_len = 5,
8686 .report_buf = {3,0x01,0x01,0x00,0x00},
8688 /* set condition */
8690 .code = IOCTL_HID_WRITE_REPORT,
8691 .report_id = 4,
8692 .report_len = 9,
8693 .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8695 /* set condition */
8697 .code = IOCTL_HID_WRITE_REPORT,
8698 .report_id = 4,
8699 .report_len = 9,
8700 .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8702 /* update effect */
8704 .code = IOCTL_HID_WRITE_REPORT,
8705 .report_id = 3,
8706 .report_len = 11,
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,
8715 .report_id = 2,
8716 .report_len = 2,
8717 .report_buf = {2,0x03},
8719 /* block load */
8721 .code = IOCTL_HID_GET_FEATURE,
8722 .report_id = 3,
8723 .report_len = 5,
8724 .report_buf = {3,0x02,0x01,0x00,0x00},
8726 /* set condition */
8728 .code = IOCTL_HID_WRITE_REPORT,
8729 .report_id = 4,
8730 .report_len = 9,
8731 .report_buf = {4,0x02,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8733 /* set condition */
8735 .code = IOCTL_HID_WRITE_REPORT,
8736 .report_id = 4,
8737 .report_len = 9,
8738 .report_buf = {4,0x02,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8740 /* update effect */
8742 .code = IOCTL_HID_WRITE_REPORT,
8743 .report_id = 3,
8744 .report_len = 11,
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,
8753 .report_id = 2,
8754 .report_len = 2,
8755 .report_buf = {2,0x03},
8757 /* block load */
8759 .code = IOCTL_HID_GET_FEATURE,
8760 .report_id = 3,
8761 .report_len = 5,
8762 .report_buf = {3,0x01,0x01,0x00,0x00},
8764 /* set condition */
8766 .code = IOCTL_HID_WRITE_REPORT,
8767 .report_id = 4,
8768 .report_len = 9,
8769 .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8771 /* set condition */
8773 .code = IOCTL_HID_WRITE_REPORT,
8774 .report_id = 4,
8775 .report_len = 9,
8776 .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8778 /* update effect */
8780 .code = IOCTL_HID_WRITE_REPORT,
8781 .report_id = 3,
8782 .report_len = 11,
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,
8791 .report_id = 2,
8792 .report_len = 2,
8793 .report_buf = {2,0x03},
8795 /* block load */
8797 .code = IOCTL_HID_GET_FEATURE,
8798 .report_id = 3,
8799 .report_len = 5,
8800 .report_buf = {3,0x01,0x01,0x00,0x00},
8802 /* set condition */
8804 .code = IOCTL_HID_WRITE_REPORT,
8805 .report_id = 4,
8806 .report_len = 9,
8807 .report_buf = {4,0x01,0x00,0xf9,0x19,0xd9,0xff,0xff,0x99},
8809 /* set condition */
8811 .code = IOCTL_HID_WRITE_REPORT,
8812 .report_id = 4,
8813 .report_len = 9,
8814 .report_buf = {4,0x01,0x01,0x4c,0x3f,0xcc,0x4c,0x33,0x19},
8816 /* update effect */
8818 .code = IOCTL_HID_WRITE_REPORT,
8819 .report_id = 3,
8820 .report_len = 11,
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,
8828 .report_id = 2,
8829 .report_len = 4,
8830 .report_buf = {2,0x01,0x01,0x01},
8832 struct hid_expect expect_start_2 =
8834 /* effect control */
8835 .code = IOCTL_HID_WRITE_REPORT,
8836 .report_id = 2,
8837 .report_len = 4,
8838 .report_buf = {2,0x02,0x02,0x01},
8840 struct hid_expect expect_stop =
8842 /* effect control */
8843 .code = IOCTL_HID_WRITE_REPORT,
8844 .report_id = 2,
8845 .report_len = 4,
8846 .report_buf = {2,0x01,0x03,0x00},
8848 struct hid_expect expect_stop_2 =
8850 /* effect control */
8851 .code = IOCTL_HID_WRITE_REPORT,
8852 .report_id = 2,
8853 .report_len = 4,
8854 .report_buf = {2,0x02,0x03,0x00},
8856 struct hid_expect expect_destroy[] =
8858 /* effect operation */
8860 .code = IOCTL_HID_WRITE_REPORT,
8861 .report_id = 2,
8862 .report_len = 4,
8863 .report_buf = {2,0x01,0x03,0x00},
8865 /* block free */
8867 .code = IOCTL_HID_WRITE_REPORT,
8868 .report_id = 5,
8869 .report_len = 2,
8870 .report_buf = {5,0x01},
8873 struct hid_expect expect_destroy_2[] =
8875 /* effect operation */
8877 .code = IOCTL_HID_WRITE_REPORT,
8878 .report_id = 2,
8879 .report_len = 4,
8880 .report_buf = {2,0x02,0x03,0x00},
8882 /* block free */
8884 .code = IOCTL_HID_WRITE_REPORT,
8885 .report_id = 5,
8886 .report_len = 2,
8887 .report_buf = {5,0x02},
8890 struct hid_expect device_state_input[] =
8892 /* effect state */
8894 .code = IOCTL_HID_READ_REPORT,
8895 .report_id = 2,
8896 .report_len = 4,
8897 .report_buf = {2,0xff,0x00,0xff},
8899 /* device state */
8901 .code = IOCTL_HID_READ_REPORT,
8902 .report_id = 1,
8903 .report_len = 5,
8904 .report_buf = {1,0x12,0x34,0x56,0xff},
8907 struct hid_expect device_state_input_0[] =
8909 /* effect state */
8911 .code = IOCTL_HID_READ_REPORT,
8912 .report_id = 2,
8913 .report_len = 4,
8914 .report_buf = {2,0xff,0x00,0xff},
8916 /* device state */
8918 .code = IOCTL_HID_READ_REPORT,
8919 .report_id = 1,
8920 .report_len = 5,
8921 .report_buf = {1,0x56,0x12,0x34,0xff},
8924 struct hid_expect device_state_input_1[] =
8926 /* effect state */
8928 .code = IOCTL_HID_READ_REPORT,
8929 .report_id = 2,
8930 .report_len = 4,
8931 .report_buf = {2,0x00,0x01,0x01},
8933 /* device state */
8935 .code = IOCTL_HID_READ_REPORT,
8936 .report_id = 1,
8937 .report_len = 5,
8938 .report_buf = {1,0x65,0x43,0x21,0x00},
8941 struct hid_expect device_state_input_2[] =
8943 /* effect state */
8945 .code = IOCTL_HID_READ_REPORT,
8946 .report_id = 2,
8947 .report_len = 4,
8948 .report_buf = {2,0x03,0x00,0x01},
8950 /* device state */
8952 .code = IOCTL_HID_READ_REPORT,
8953 .report_id = 1,
8954 .report_len = 5,
8955 .report_buf = {1,0x12,0x34,0x56,0xff},
8958 struct hid_expect expect_pool[] =
8960 /* device pool */
8962 .code = IOCTL_HID_GET_FEATURE,
8963 .report_id = 1,
8964 .report_len = 5,
8965 .report_buf = {1,0x10,0x00,0x04,0x03},
8966 .todo = TRUE,
8968 /* device pool */
8970 .code = IOCTL_HID_GET_FEATURE,
8971 .report_id = 1,
8972 .report_len = 5,
8973 .report_buf = {1,0x10,0x00,0x04,0x03},
8974 .todo = TRUE,
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] = {
8984 +3000,
8988 static const DIENVELOPE expect_envelope =
8990 .dwSize = sizeof(DIENVELOPE),
8991 .dwAttackLevel = 1000,
8992 .dwAttackTime = 2000,
8993 .dwFadeLevel = 3000,
8994 .dwFadeTime = 4000,
8996 static const DICONDITION expect_condition[3] =
8999 .lOffset = -500,
9000 .lPositiveCoefficient = 2000,
9001 .lNegativeCoefficient = -3000,
9002 .dwPositiveSaturation = -4000,
9003 .dwNegativeSaturation = -5000,
9004 .lDeadBand = 6000,
9007 .lOffset = 6000,
9008 .lPositiveCoefficient = 5000,
9009 .lNegativeCoefficient = -4000,
9010 .dwPositiveSaturation = 3000,
9011 .dwNegativeSaturation = 2000,
9012 .lDeadBand = 1000,
9015 .lOffset = -7000,
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,
9027 .dwDuration = 1000,
9028 .dwSamplePeriod = 2000,
9029 .dwGain = 3000,
9030 .dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER,
9031 .dwTriggerRepeatInterval = 5000,
9032 .cAxes = 2,
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 =
9042 .diph =
9044 .dwSize = sizeof(DIPROPGUIDANDPATH),
9045 .dwHeaderSize = sizeof(DIPROPHEADER),
9046 .dwHow = DIPH_DEVICE,
9049 DIPROPDWORD prop_dword =
9051 .diph =
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;
9062 HANDLE file, event;
9063 ULONG res, ref;
9064 DIEFFECT desc;
9065 DWORD flags;
9066 HRESULT hr;
9067 HWND hwnd;
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) );
9117 res = 0xdeadbeef;
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) );
9139 res = 0xdeadbeef;
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;
9143 todo_wine
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 );
9152 res = 0xdeadbeef;
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 );
9174 res = 0xdeadbeef;
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) );
9180 res = 0xdeadbeef;
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 );
9192 res = 0xdeadbeef;
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) );
9197 res = 0xdeadbeef;
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 );
9224 res = 0xdeadbeef;
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 );
9228 res = 0xdeadbeef;
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 );
9236 res = 0xdeadbeef;
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 );
9250 res = 0xdeadbeef;
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) );
9255 res = 0xdeadbeef;
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 );
9266 res = 0xdeadbeef;
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) );
9271 res = 0xdeadbeef;
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 );
9282 res = 0xdeadbeef;
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) );
9287 res = 0xdeadbeef;
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 );
9298 res = 0xdeadbeef;
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) );
9303 res = 0xdeadbeef;
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 );
9314 res = 0xdeadbeef;
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) );
9319 res = 0xdeadbeef;
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 );
9330 res = 0xdeadbeef;
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) );
9335 res = 0xdeadbeef;
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) );
9346 res = 0xdeadbeef;
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;
9350 todo_wine
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 );
9357 res = 0xdeadbeef;
9358 hr = IDirectInputEffect_GetEffectStatus( effect, &res );
9359 ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
9360 todo_wine
9361 ok( res == DIEGES_PLAYING, "got status %#x\n", res );
9362 set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
9363 res = 0xdeadbeef;
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;
9367 todo_wine
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 );
9374 res = 0xdeadbeef;
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) );
9379 res = 0xdeadbeef;
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;
9383 todo_wine
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 );
9392 res = 0xdeadbeef;
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) );
9397 res = 0xdeadbeef;
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;
9401 todo_wine
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 );
9410 res = 0xdeadbeef;
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) );
9415 res = 0xdeadbeef;
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;
9419 todo_wine
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 */
9427 desc = expect_desc;
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 );
9433 res = 0xdeadbeef;
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 );
9441 res = 0xdeadbeef;
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 */
9451 desc = expect_desc;
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 );
9458 res = 0xdeadbeef;
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 );
9466 Sleep( 100 );
9467 res = 0xdeadbeef;
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 );
9488 done:
9489 pnp_driver_stop();
9490 cleanup_registry_keys();
9491 SetCurrentDirectoryW( cwd );
9492 winetest_pop_context();
9495 START_TEST( hid )
9497 HANDLE mapping;
9498 BOOL is_wow64;
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" );
9507 return;
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" );
9515 return;
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" );
9528 test_hidp_kdr();
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();
9547 CoUninitialize();
9549 UnmapViewOfFile( test_data );
9550 CloseHandle( mapping );
9551 CloseHandle( okfile );
9552 DeleteFileW( L"C:\\windows\\winetest_dinput_okfile" );