Rémi Bernon : dinput: Factor all type specific parameter handling together.
Alexandre Julliard
julliard at winehq.org
Fri Dec 3 15:18:59 CST 2021
Module: wine
Branch: master
Commit: d0fc7c96f34247c5ac301d152e675168e963a419
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d0fc7c96f34247c5ac301d152e675168e963a419
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Fri Dec 3 14:08:49 2021 +0100
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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 2411053390f..7759a8d05f1 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[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 )
More information about the wine-cvs
mailing list