From: Ivo Ivanov logos128@gmail.com
Signed-off-by: Ivo Ivanov logos128@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 976961c3a9f..a5deedb6ffb 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -2437,7 +2437,7 @@ static HRESULT WINAPI hid_joystick_effect_GetParameters( IDirectInputEffect *ifa case PID_USAGE_ET_RAMP: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) return DIERR_INVALIDPARAM; - memcpy( params->lpvTypeSpecificParams, &impl->constant_force, sizeof(DIRAMPFORCE) ); + memcpy( params->lpvTypeSpecificParams, &impl->ramp_force, sizeof(DIRAMPFORCE) ); break; case PID_USAGE_ET_CUSTOM_FORCE_DATA: FIXME( "DIEP_TYPESPECIFICPARAMS not implemented!\n" ); @@ -2591,9 +2591,9 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa case PID_USAGE_ET_RAMP: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) return DIERR_INVALIDPARAM; - if (memcmp( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) )) + if (memcmp( &impl->ramp_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) )) impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); + memcpy( &impl->ramp_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); impl->params.cbTypeSpecificParams = sizeof(DIRAMPFORCE); break; case PID_USAGE_ET_CUSTOM_FORCE_DATA:
And lpEnvelope in SetParameters.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 37 +++++++++++++++++++++---------------- dlls/dinput8/tests/hid.c | 1 - 2 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index a5deedb6ffb..86bb31737ab 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -2136,6 +2136,7 @@ static HRESULT WINAPI hid_joystick_effect_Initialize( IDirectInputEffect *iface, status = HidP_InitializeReportForID( HidP_Output, joystick->pid_set_periodic.id, joystick->preparsed, impl->type_specific_buf, report_len ); if (status != HIDP_STATUS_SUCCESS) return DIERR_DEVICENOTREG; + impl->params.lpvTypeSpecificParams = &impl->periodic; break; case PID_USAGE_ET_SPRING: case PID_USAGE_ET_DAMPER: @@ -2144,16 +2145,19 @@ static HRESULT WINAPI hid_joystick_effect_Initialize( IDirectInputEffect *iface, status = HidP_InitializeReportForID( HidP_Output, joystick->pid_set_condition.id, joystick->preparsed, impl->type_specific_buf, report_len ); if (status != HIDP_STATUS_SUCCESS) return DIERR_DEVICENOTREG; + impl->params.lpvTypeSpecificParams = &impl->condition; break; case PID_USAGE_ET_CONSTANT_FORCE: status = HidP_InitializeReportForID( HidP_Output, joystick->pid_set_constant_force.id, joystick->preparsed, impl->type_specific_buf, report_len ); if (status != HIDP_STATUS_SUCCESS) return DIERR_DEVICENOTREG; + impl->params.lpvTypeSpecificParams = &impl->constant_force; break; case PID_USAGE_ET_RAMP: status = HidP_InitializeReportForID( HidP_Output, joystick->pid_set_ramp_force.id, joystick->preparsed, impl->type_specific_buf, report_len ); if (status != HIDP_STATUS_SUCCESS) return DIERR_DEVICENOTREG; + impl->params.lpvTypeSpecificParams = &impl->ramp_force; break; case PID_USAGE_ET_CUSTOM_FORCE_DATA: FIXME( "effect type %#x not implemented!\n", type ); @@ -2417,7 +2421,7 @@ static HRESULT WINAPI hid_joystick_effect_GetParameters( IDirectInputEffect *ifa case PID_USAGE_ET_SAWTOOTH_DOWN: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DIPERIODIC)) return DIERR_INVALIDPARAM; - memcpy( params->lpvTypeSpecificParams, &impl->periodic, sizeof(DIPERIODIC) ); + memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DIPERIODIC) ); break; case PID_USAGE_ET_SPRING: case PID_USAGE_ET_DAMPER: @@ -2427,17 +2431,17 @@ static HRESULT WINAPI hid_joystick_effect_GetParameters( IDirectInputEffect *ifa capacity = params->cbTypeSpecificParams; params->cbTypeSpecificParams = count; if (capacity < count) return DIERR_MOREDATA; - memcpy( params->lpvTypeSpecificParams, impl->condition, params->cbTypeSpecificParams ); + memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, params->cbTypeSpecificParams ); break; case PID_USAGE_ET_CONSTANT_FORCE: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) return DIERR_INVALIDPARAM; - memcpy( params->lpvTypeSpecificParams, &impl->constant_force, sizeof(DICONSTANTFORCE) ); + memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) ); break; case PID_USAGE_ET_RAMP: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) return DIERR_INVALIDPARAM; - memcpy( params->lpvTypeSpecificParams, &impl->ramp_force, sizeof(DIRAMPFORCE) ); + memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); break; case PID_USAGE_ET_CUSTOM_FORCE_DATA: FIXME( "DIEP_TYPESPECIFICPARAMS not implemented!\n" ); @@ -2449,7 +2453,8 @@ static HRESULT WINAPI hid_joystick_effect_GetParameters( IDirectInputEffect *ifa { if (!params->lpEnvelope) return E_POINTER; if (params->lpEnvelope->dwSize != sizeof(DIENVELOPE)) return DIERR_INVALIDPARAM; - memcpy( params->lpEnvelope, &impl->envelope, sizeof(DIENVELOPE) ); + if (!impl->params.lpEnvelope) params->lpEnvelope = NULL; + else memcpy( params->lpEnvelope, impl->params.lpEnvelope, sizeof(DIENVELOPE) ); }
if (flags & DIEP_DURATION) params->dwDuration = impl->params.dwDuration; @@ -2559,9 +2564,9 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa case PID_USAGE_ET_SAWTOOTH_DOWN: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DIPERIODIC)) return DIERR_INVALIDPARAM; - if (memcmp( &impl->periodic, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) )) + if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) )) impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( &impl->periodic, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) ); + memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) ); impl->params.cbTypeSpecificParams = sizeof(DIPERIODIC); break; case PID_USAGE_ET_SPRING: @@ -2574,26 +2579,26 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa if (params->cbTypeSpecificParams != count * sizeof(DICONDITION) && params->cbTypeSpecificParams != sizeof(DICONDITION)) return DIERR_INVALIDPARAM; - if (memcmp( impl->condition, params->lpvTypeSpecificParams, params->cbTypeSpecificParams )) + if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, params->cbTypeSpecificParams )) impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( impl->condition, params->lpvTypeSpecificParams, params->cbTypeSpecificParams ); + memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, params->cbTypeSpecificParams ); impl->params.cbTypeSpecificParams = params->cbTypeSpecificParams; } break; case PID_USAGE_ET_CONSTANT_FORCE: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) return DIERR_INVALIDPARAM; - if (memcmp( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) )) + if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) )) impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( &impl->constant_force, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) ); + memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) ); impl->params.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); break; case PID_USAGE_ET_RAMP: if (!params->lpvTypeSpecificParams) return E_POINTER; if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) return DIERR_INVALIDPARAM; - if (memcmp( &impl->ramp_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) )) + if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) )) impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( &impl->ramp_force, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); + memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); impl->params.cbTypeSpecificParams = sizeof(DIRAMPFORCE); break; case PID_USAGE_ET_CUSTOM_FORCE_DATA: @@ -2605,9 +2610,10 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa if ((flags & DIEP_ENVELOPE) && params->lpEnvelope) { if (params->lpEnvelope->dwSize != sizeof(DIENVELOPE)) return DIERR_INVALIDPARAM; - if (memcmp( &impl->envelope, params->lpEnvelope, sizeof(DIENVELOPE) )) + impl->params.lpEnvelope = &impl->envelope; + if (memcmp( impl->params.lpEnvelope, params->lpEnvelope, sizeof(DIENVELOPE) )) impl->modified |= DIEP_ENVELOPE; - memcpy( &impl->envelope, params->lpEnvelope, sizeof(DIENVELOPE) ); + memcpy( impl->params.lpEnvelope, params->lpEnvelope, sizeof(DIENVELOPE) ); }
if (flags & DIEP_DURATION) @@ -3119,7 +3125,6 @@ static HRESULT hid_joystick_create_effect( IDirectInputDevice8W *iface, IDirectI
impl->envelope.dwSize = sizeof(DIENVELOPE); impl->params.dwSize = sizeof(DIEFFECT); - impl->params.lpEnvelope = &impl->envelope; impl->params.rgdwAxes = impl->axes; impl->params.rglDirection = impl->directions; impl->params.dwTriggerButton = -1; diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index c7bf549deb1..1a2c4852737 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -5981,7 +5981,6 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO check_member( desc, expect_desc_init, "%u", rgdwAxes[0] ); check_member( desc, expect_desc_init, "%u", rgdwAxes[1] ); check_member( desc, expect_desc_init, "%p", rglDirection ); - todo_wine check_member( desc, expect_desc_init, "%p", lpEnvelope ); todo_wine check_member( desc, expect_desc_init, "%u", cbTypeSpecificParams );
From: Ivo Ivanov logos128@gmail.com
And return DIERR_MOREDATA the provided buffer is too short.
Fixes the WheelCheck application not showing type specific params for Constant and Periodic effects.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 86bb31737ab..56ef9ef6ce2 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -2419,28 +2419,34 @@ static HRESULT WINAPI hid_joystick_effect_GetParameters( IDirectInputEffect *ifa case PID_USAGE_ET_TRIANGLE: case PID_USAGE_ET_SAWTOOTH_UP: case PID_USAGE_ET_SAWTOOTH_DOWN: + capacity = params->cbTypeSpecificParams; + params->cbTypeSpecificParams = sizeof(DIPERIODIC); + if (capacity < sizeof(DIPERIODIC)) return DIERR_MOREDATA; if (!params->lpvTypeSpecificParams) return E_POINTER; - if (params->cbTypeSpecificParams != sizeof(DIPERIODIC)) return DIERR_INVALIDPARAM; memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DIPERIODIC) ); break; case PID_USAGE_ET_SPRING: case PID_USAGE_ET_DAMPER: case PID_USAGE_ET_INERTIA: case PID_USAGE_ET_FRICTION: - count = impl->params.cbTypeSpecificParams; capacity = params->cbTypeSpecificParams; - params->cbTypeSpecificParams = count; - if (capacity < count) return DIERR_MOREDATA; + params->cbTypeSpecificParams = impl->params.cbTypeSpecificParams; + if (capacity < impl->params.cbTypeSpecificParams) return DIERR_MOREDATA; + if (!params->lpvTypeSpecificParams) return E_POINTER; memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, params->cbTypeSpecificParams ); break; case PID_USAGE_ET_CONSTANT_FORCE: + capacity = params->cbTypeSpecificParams; + params->cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + if (capacity < sizeof(DICONSTANTFORCE)) return DIERR_MOREDATA; if (!params->lpvTypeSpecificParams) return E_POINTER; - if (params->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) return DIERR_INVALIDPARAM; memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) ); break; case PID_USAGE_ET_RAMP: + capacity = params->cbTypeSpecificParams; + params->cbTypeSpecificParams = sizeof(DIRAMPFORCE); + if (capacity < sizeof(DIRAMPFORCE)) return DIERR_MOREDATA; if (!params->lpvTypeSpecificParams) return E_POINTER; - if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) return DIERR_INVALIDPARAM; memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); break; case PID_USAGE_ET_CUSTOM_FORCE_DATA:
The internal params cbTypeSpecificParams is assigned in SetParameters after validation, and contains the expected buffer size.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 92 ++++++++++---------------------------- dlls/dinput8/tests/hid.c | 23 +++++++++- 2 files changed, 46 insertions(+), 69 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 56ef9ef6ce2..682af063ff1 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -2412,46 +2412,14 @@ static HRESULT WINAPI hid_joystick_effect_GetParameters( IDirectInputEffect *ifa
if (flags & DIEP_TYPESPECIFICPARAMS) { - switch (impl->type) + capacity = params->cbTypeSpecificParams; + params->cbTypeSpecificParams = impl->params.cbTypeSpecificParams; + if (capacity < impl->params.cbTypeSpecificParams) return DIERR_MOREDATA; + if (impl->params.lpvTypeSpecificParams) { - case PID_USAGE_ET_SQUARE: - case PID_USAGE_ET_SINE: - case PID_USAGE_ET_TRIANGLE: - case PID_USAGE_ET_SAWTOOTH_UP: - case PID_USAGE_ET_SAWTOOTH_DOWN: - capacity = params->cbTypeSpecificParams; - params->cbTypeSpecificParams = sizeof(DIPERIODIC); - if (capacity < sizeof(DIPERIODIC)) return DIERR_MOREDATA; if (!params->lpvTypeSpecificParams) return E_POINTER; - memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DIPERIODIC) ); - break; - case PID_USAGE_ET_SPRING: - case PID_USAGE_ET_DAMPER: - case PID_USAGE_ET_INERTIA: - case PID_USAGE_ET_FRICTION: - capacity = params->cbTypeSpecificParams; - params->cbTypeSpecificParams = impl->params.cbTypeSpecificParams; - if (capacity < impl->params.cbTypeSpecificParams) return DIERR_MOREDATA; - if (!params->lpvTypeSpecificParams) return E_POINTER; - memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, params->cbTypeSpecificParams ); - break; - case PID_USAGE_ET_CONSTANT_FORCE: - capacity = params->cbTypeSpecificParams; - params->cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - if (capacity < sizeof(DICONSTANTFORCE)) return DIERR_MOREDATA; - if (!params->lpvTypeSpecificParams) return E_POINTER; - memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) ); - break; - case PID_USAGE_ET_RAMP: - capacity = params->cbTypeSpecificParams; - params->cbTypeSpecificParams = sizeof(DIRAMPFORCE); - if (capacity < sizeof(DIRAMPFORCE)) return DIERR_MOREDATA; - if (!params->lpvTypeSpecificParams) return E_POINTER; - memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); - break; - case PID_USAGE_ET_CUSTOM_FORCE_DATA: - FIXME( "DIEP_TYPESPECIFICPARAMS not implemented!\n" ); - return DIERR_UNSUPPORTED; + memcpy( params->lpvTypeSpecificParams, impl->params.lpvTypeSpecificParams, + impl->params.cbTypeSpecificParams ); } }
@@ -2561,6 +2529,7 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa
if (flags & DIEP_TYPESPECIFICPARAMS) { + if (!params->lpvTypeSpecificParams) return E_POINTER; switch (impl->type) { case PID_USAGE_ET_SQUARE: @@ -2568,49 +2537,36 @@ static HRESULT WINAPI hid_joystick_effect_SetParameters( IDirectInputEffect *ifa case PID_USAGE_ET_TRIANGLE: case PID_USAGE_ET_SAWTOOTH_UP: case PID_USAGE_ET_SAWTOOTH_DOWN: - if (!params->lpvTypeSpecificParams) return E_POINTER; - if (params->cbTypeSpecificParams != sizeof(DIPERIODIC)) return DIERR_INVALIDPARAM; - if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) )) - impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIPERIODIC) ); - impl->params.cbTypeSpecificParams = sizeof(DIPERIODIC); + if (params->cbTypeSpecificParams != sizeof(DIPERIODIC)) + return DIERR_INVALIDPARAM; break; case PID_USAGE_ET_SPRING: case PID_USAGE_ET_DAMPER: case PID_USAGE_ET_INERTIA: case PID_USAGE_ET_FRICTION: - if ((count = impl->params.cAxes)) - { - if (!params->lpvTypeSpecificParams) return E_POINTER; - if (params->cbTypeSpecificParams != count * sizeof(DICONDITION) && - params->cbTypeSpecificParams != sizeof(DICONDITION)) - return DIERR_INVALIDPARAM; - if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, params->cbTypeSpecificParams )) - impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, params->cbTypeSpecificParams ); - impl->params.cbTypeSpecificParams = params->cbTypeSpecificParams; - } + if (params->cbTypeSpecificParams != sizeof(DICONDITION) && impl->params.cAxes && + params->cbTypeSpecificParams != impl->params.cAxes * sizeof(DICONDITION)) + return DIERR_INVALIDPARAM; break; case PID_USAGE_ET_CONSTANT_FORCE: - if (!params->lpvTypeSpecificParams) return E_POINTER; - if (params->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) return DIERR_INVALIDPARAM; - if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) )) - impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DICONSTANTFORCE) ); - impl->params.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + if (params->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) + return DIERR_INVALIDPARAM; break; case PID_USAGE_ET_RAMP: - if (!params->lpvTypeSpecificParams) return E_POINTER; - if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) return DIERR_INVALIDPARAM; - if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) )) - impl->modified |= DIEP_TYPESPECIFICPARAMS; - memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, sizeof(DIRAMPFORCE) ); - impl->params.cbTypeSpecificParams = sizeof(DIRAMPFORCE); + if (params->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) + return DIERR_INVALIDPARAM; break; case PID_USAGE_ET_CUSTOM_FORCE_DATA: - FIXME( "DIEP_TYPESPECIFICPARAMS not implemented!\n" ); + FIXME( "custom force data not implemented!\n" ); return DIERR_UNSUPPORTED; } + + if (memcmp( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, + params->cbTypeSpecificParams )) + impl->modified |= DIEP_TYPESPECIFICPARAMS; + memcpy( impl->params.lpvTypeSpecificParams, params->lpvTypeSpecificParams, + params->cbTypeSpecificParams ); + impl->params.cbTypeSpecificParams = params->cbTypeSpecificParams; }
if ((flags & DIEP_ENVELOPE) && params->lpEnvelope) diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 1a2c4852737..35d72409af5 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -5982,7 +5982,6 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO check_member( desc, expect_desc_init, "%u", rgdwAxes[1] ); check_member( desc, expect_desc_init, "%p", rglDirection ); check_member( desc, expect_desc_init, "%p", lpEnvelope ); - todo_wine check_member( desc, expect_desc_init, "%u", cbTypeSpecificParams ); if (version >= 0x700) check_member( desc, expect_desc_init, "%u", dwStartDelay ); else ok( desc.dwStartDelay == 0xcdcdcdcd, "got dwStartDelay %#x\n", desc.dwStartDelay ); @@ -6901,6 +6900,28 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file, DW ref = IDirectInputEffect_Release( effect ); ok( ref == 0, "Release returned %d\n", ref ); set_hid_expect( file, NULL, 0 ); + + hr = IDirectInputDevice8_CreateEffect( device, &GUID_Spring, NULL, &effect, NULL ); + ok( hr == DI_OK, "CreateEffect returned %#x\n", hr ); + desc = expect_desc; + desc.cAxes = 0; + desc.cbTypeSpecificParams = 1 * sizeof(DICONDITION); + desc.lpvTypeSpecificParams = (void *)&expect_condition[0]; + hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS | DIEP_NODOWNLOAD ); + ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#x\n", hr ); + desc.cbTypeSpecificParams = 0 * sizeof(DICONDITION); + hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS ); + ok( hr == DIERR_MOREDATA, "SetParameters returned %#x\n", hr ); + ok( desc.cbTypeSpecificParams == 1 * sizeof(DICONDITION), "got %u\n", desc.cbTypeSpecificParams ); + desc.cbTypeSpecificParams = 0 * sizeof(DICONDITION); + hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS | DIEP_NODOWNLOAD ); + ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#x\n", hr ); + desc.cbTypeSpecificParams = 0 * sizeof(DICONDITION); + hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TYPESPECIFICPARAMS ); + ok( hr == DI_OK, "SetParameters returned %#x\n", hr ); + ok( desc.cbTypeSpecificParams == 0 * sizeof(DICONDITION), "got %u\n", desc.cbTypeSpecificParams ); + ref = IDirectInputEffect_Release( effect ); + ok( ref == 0, "Release returned %d\n", ref ); }
static void test_force_feedback_joystick( DWORD version )