dinput: Factor all type specific parameter handling together.

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>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-12-03 14:08:49 +01:00 committed by Alexandre Julliard
parent 5ce61fc04f
commit d0fc7c96f3
2 changed files with 46 additions and 69 deletions

View file

@ -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)

View file

@ -5981,7 +5981,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 );
@ -6900,6 +6899,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 )