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