From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/force_feedback.c | 125 ++++++++++------------------- 1 file changed, 43 insertions(+), 82 deletions(-)
diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index 4e6f8dfc8d4..6c7d4791c84 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -4723,6 +4723,23 @@ static IAsyncOperationCompletedHandler_booleanVtbl bool_async_handler_vtbl =
static struct bool_async_handler default_bool_async_handler = {{&bool_async_handler_vtbl}};
+#define await_bool( a ) await_bool_( __LINE__, a ) +static void await_bool_( int line, IAsyncOperation_boolean *async ) +{ + struct bool_async_handler handler = default_bool_async_handler; + HRESULT hr; + DWORD ret; + + handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); + ok_(__FILE__, line)( !!handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); + hr = IAsyncOperation_boolean_put_Completed( async, &handler.IAsyncOperationCompletedHandler_boolean_iface ); + ok_(__FILE__, line)( hr == S_OK, "put_Completed returned %#lx\n", hr ); + ret = WaitForSingleObject( handler.event, 5000 ); + ok_(__FILE__, line)( !ret, "WaitForSingleObject returned %#lx\n", ret ); + ret = CloseHandle( handler.event ); + ok_(__FILE__, line)( ret, "CloseHandle failed, error %lu\n", GetLastError() ); +} + struct result_async_handler { IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface; @@ -4791,6 +4808,23 @@ static IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResultVtbl result_
static struct result_async_handler default_result_async_handler = {{&result_async_handler_vtbl}};
+#define await_result( a ) await_result_( __LINE__, a ) +static void await_result_( int line, IAsyncOperation_ForceFeedbackLoadEffectResult *async ) +{ + struct result_async_handler handler = default_result_async_handler; + HRESULT hr; + DWORD ret; + + handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); + ok_(__FILE__, line)( !!handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); + hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( async, &handler.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface ); + ok_(__FILE__, line)( hr == S_OK, "put_Completed returned %#lx\n", hr ); + ret = WaitForSingleObject( handler.event, 5000 ); + ok_(__FILE__, line)( !ret, "WaitForSingleObject returned %#lx\n", ret ); + ret = CloseHandle( handler.event ); + ok_(__FILE__, line)( ret, "CloseHandle failed, error %lu\n", GetLastError() ); +} + static void test_windows_gaming_input(void) { #include "psh_hid_macros.h" @@ -5727,7 +5761,6 @@ static void test_windows_gaming_input(void) DIDEVICEINSTANCEW devinst = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; IAsyncOperation_ForceFeedbackLoadEffectResult *result_async; IAsyncOperationCompletedHandler_boolean *tmp_handler; - struct result_async_handler result_async_handler; IVectorView_RawGameController *controllers_view; IConditionForceEffectFactory *condition_factory; IRawGameControllerStatics *controller_statics; @@ -6121,15 +6154,7 @@ static void test_windows_gaming_input(void)
hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async ); ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr ); - result_async_handler = default_result_async_handler; - result_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!result_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async, &result_async_handler.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( result_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( result_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_result( result_async ); check_result_async( result_async, 1, Error, 0x86854008, ForceFeedbackLoadEffectResult_EffectNotSupported ); IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
@@ -6180,15 +6205,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_create_periodic, sizeof(expect_create_periodic) ); hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async ); ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr ); - result_async_handler = default_result_async_handler; - result_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!result_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async, &result_async_handler.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( result_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( result_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_result( result_async ); check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded ); IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async ); set_hid_expect( file, NULL, 0 ); @@ -6210,15 +6227,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_unload, sizeof(expect_unload) ); hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async ); ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr ); - bool_async_handler = default_bool_async_handler; - bool_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!bool_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler.IAsyncOperationCompletedHandler_boolean_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( bool_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( bool_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_bool( bool_async ); check_bool_async( bool_async, 1, Completed, S_OK, TRUE ); IAsyncOperation_boolean_Release( bool_async ); set_hid_expect( file, NULL, 0 ); @@ -6272,15 +6281,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_create_condition, sizeof(expect_create_condition) ); hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async ); ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr ); - result_async_handler = default_result_async_handler; - result_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!result_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async, &result_async_handler.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( result_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( result_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_result( result_async ); check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded ); IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async ); set_hid_expect( file, NULL, 0 ); @@ -6302,15 +6303,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_unload, sizeof(expect_unload) ); hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async ); ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr ); - bool_async_handler = default_bool_async_handler; - bool_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!bool_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler.IAsyncOperationCompletedHandler_boolean_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( bool_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( bool_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_bool( bool_async ); check_bool_async( bool_async, 1, Completed, S_OK, TRUE ); IAsyncOperation_boolean_Release( bool_async ); set_hid_expect( file, NULL, 0 ); @@ -6364,15 +6357,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_create_constant, sizeof(expect_create_constant) ); hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async ); ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr ); - result_async_handler = default_result_async_handler; - result_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!result_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async, &result_async_handler.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( result_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( result_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_result( result_async ); check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded ); IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async ); set_hid_expect( file, NULL, 0 ); @@ -6394,15 +6379,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_unload, sizeof(expect_unload) ); hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async ); ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr ); - bool_async_handler = default_bool_async_handler; - bool_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!bool_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler.IAsyncOperationCompletedHandler_boolean_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( bool_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( bool_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_bool( bool_async ); check_bool_async( bool_async, 1, Completed, S_OK, TRUE ); IAsyncOperation_boolean_Release( bool_async ); set_hid_expect( file, NULL, 0 ); @@ -6437,15 +6414,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_create_ramp, sizeof(expect_create_ramp) ); hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async ); ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr ); - result_async_handler = default_result_async_handler; - result_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!result_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async, &result_async_handler.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( result_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( result_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_result( result_async ); check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded ); IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async ); set_hid_expect( file, NULL, 0 ); @@ -6467,15 +6436,7 @@ static void test_windows_gaming_input(void) set_hid_expect( file, expect_unload, sizeof(expect_unload) ); hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async ); ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr ); - bool_async_handler = default_bool_async_handler; - bool_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL ); - ok( !!bool_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() ); - hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler.IAsyncOperationCompletedHandler_boolean_iface ); - ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); - ret = WaitForSingleObject( bool_async_handler.event, 5000 ); - ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); - ret = CloseHandle( bool_async_handler.event ); - ok( ret, "CloseHandle failed, error %lu\n", GetLastError() ); + await_bool( bool_async ); check_bool_async( bool_async, 1, Completed, S_OK, TRUE ); IAsyncOperation_boolean_Release( bool_async ); set_hid_expect( file, NULL, 0 );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/force_feedback.c | 77 +++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index 6c7d4791c84..353a8968f89 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -20,6 +20,7 @@
#include <stdarg.h> #include <stddef.h> +#include <stdint.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -5024,7 +5025,7 @@ static void test_windows_gaming_input(void) LOGICAL_MINIMUM(1, 0), LOGICAL_MAXIMUM(2, 0x7fff), PHYSICAL_MINIMUM(1, 0), - PHYSICAL_MAXIMUM(2, 0x7fff), + PHYSICAL_MAXIMUM(1, 0), REPORT_SIZE(1, 16), REPORT_COUNT(1, 4), OUTPUT(1, Data|Var|Abs), @@ -5709,6 +5710,54 @@ static void test_windows_gaming_input(void) .report_buf = {3,0x01,0x05,0x04,0x5a,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0xff,0xff,0x4e,0x01,0x00,0x00}, }, }; + struct hid_expect expect_create_ramp_inf[] = + { + /* create new effect */ + { + .code = IOCTL_HID_SET_FEATURE, + .report_id = 2, + .report_len = 3, + .report_buf = {2,0x05,0x00}, + }, + /* block load */ + { + .code = IOCTL_HID_GET_FEATURE, + .report_id = 3, + .report_len = 5, + .report_buf = {3,0x01,0x01,0x00,0x00}, + }, + /* set ramp */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 10, + .report_len = 6, + .report_buf = {10,0x01,0xe8,0x03,0xa0,0x0f}, + }, + /* set envelope (wine) */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 8, + .report_len = 8, + .report_buf = {8,0x01,0x00,0x00,0x00,0x00,0x00,0x00}, + .todo = TRUE, .wine_only = TRUE, + }, + /* update effect (wine) */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 18, + .report_buf = {3,0x01,0x05,0x04,0x8f,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x01,0x00,0x00}, + .todo = TRUE, .wine_only = TRUE, + }, + /* update effect */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 18, + .report_buf = {3,0x01,0x05,0x04,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x01,0x00,0x00}, + .todo = TRUE, + }, + }; struct hid_expect expect_effect_start = { .code = IOCTL_HID_WRITE_REPORT, @@ -5756,7 +5805,7 @@ static void test_windows_gaming_input(void) .dwHow = DIPH_DEVICE, }, }; - TimeSpan delay = {100000}, attack_duration = {200000}, release_duration = {300000}, duration = {400000}; + TimeSpan delay = {100000}, attack_duration = {200000}, release_duration = {300000}, duration = {400000}, infinite_duration = {INT64_MAX}; Vector3 direction = {0.1, 0.2, 0.3}, end_direction = {0.4, 0.5, 0.6}; DIDEVICEINSTANCEW devinst = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; IAsyncOperation_ForceFeedbackLoadEffectResult *result_async; @@ -6441,6 +6490,30 @@ static void test_windows_gaming_input(void) IAsyncOperation_boolean_Release( bool_async ); set_hid_expect( file, NULL, 0 );
+ + hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IRampForceEffect, (void **)&ramp_effect ); + ok( hr == S_OK, "QueryInterface returned %#lx\n", hr ); + hr = IRampForceEffect_SetParameters( ramp_effect, direction, end_direction, infinite_duration ); + ok( hr == S_OK, "SetParameters returned %#lx\n", hr ); + IRampForceEffect_Release( ramp_effect ); + + set_hid_expect( file, expect_create_ramp_inf, sizeof(expect_create_ramp_inf) ); + hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async ); + ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr ); + await_result( result_async ); + check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded ); + IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async ); + set_hid_expect( file, NULL, 0 ); + + set_hid_expect( file, expect_unload, sizeof(expect_unload) ); + hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async ); + ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr ); + await_bool( bool_async ); + check_bool_async( bool_async, 1, Completed, S_OK, TRUE ); + IAsyncOperation_boolean_Release( bool_async ); + set_hid_expect( file, NULL, 0 ); + + IForceFeedbackEffect_Release( effect );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/tests/force_feedback.c | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index 353a8968f89..145f6108ab6 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -425,6 +425,55 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO .report_buf = {0x03,0x01,0x02,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5}, }, }; + struct hid_expect expect_download_3[] = + { + /* set periodic */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 5, + .report_len = 2, + .report_buf = {0x05,0x19}, + }, + /* set envelope */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 6, + .report_len = 7, + .report_buf = {0x06,0x19,0x4c,0x01,0x00,0x04,0x00}, + }, + /* update effect */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 11, + .report_buf = {0x03,0x01,0x02,0x08,0xff,0xff,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5}, + }, + }; + struct hid_expect expect_download_4[] = + { + /* set periodic */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 5, + .report_len = 2, + .report_buf = {0x05,0x19}, + }, + /* set envelope (wine) */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 6, + .report_len = 7, + .report_buf = {0x06,0x19,0x4c,0x01,0x00,0x04,0x00}, + .todo = TRUE, .wine_only = TRUE, + }, + /* update effect */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 11, + .report_buf = {0x03,0x01,0x02,0x08,0xff,0xff,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5}, + }, + }; struct hid_expect expect_update[] = { /* update effect */ @@ -1441,6 +1490,32 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO ok( hr == DI_OK, "SetParameters returned %#lx\n", hr ); wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */
+ set_hid_expect( file, &expect_stop, sizeof(expect_stop) ); + hr = IDirectInputEffect_Unload( effect ); + ok( hr == DI_OK, "Unload returned %#lx\n", hr ); + set_hid_expect( file, NULL, 0 ); + + hr = IDirectInputEffect_SetParameters( effect, &expect_desc, DIEP_NODOWNLOAD ); + ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr ); + set_hid_expect( file, expect_download_3, sizeof(expect_download_3) ); + hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 ); + ok( hr == DI_OK, "SetParameters returned %#lx\n", hr ); + wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */ + + set_hid_expect( file, &expect_stop, sizeof(expect_stop) ); + hr = IDirectInputEffect_Unload( effect ); + ok( hr == DI_OK, "Unload returned %#lx\n", hr ); + set_hid_expect( file, NULL, 0 ); + + desc = expect_desc; + desc.lpEnvelope = NULL; + hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD | DIEP_ENVELOPE ); + ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#lx\n", hr ); + set_hid_expect( file, expect_download_4, sizeof(expect_download_4) ); + hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 ); + ok( hr == DI_OK, "SetParameters returned %#lx\n", hr ); + wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */ + set_hid_expect( file, &expect_stop, sizeof(expect_stop) ); ref = IDirectInputEffect_Release( effect ); ok( ref == 0, "Release returned %ld\n", ref );