[PATCH 06/10] dinput: Factor (Get|Set)Property checks together.

Rémi Bernon rbernon at codeweavers.com
Thu Nov 18 01:52:11 CST 2021


From: Ivo Ivanov <logos128 at gmail.com>

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/device.c     | 186 +++++++++++++++++++++++++--------------
 dlls/dinput8/tests/hid.c |   3 -
 2 files changed, 122 insertions(+), 67 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 9bf52cad2ec..045b0666798 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -905,6 +905,126 @@ static HRESULT enum_object_filter_init( struct dinput_device *impl, DIPROPHEADER
     return DI_OK;
 }
 
+static HRESULT check_property( struct dinput_device *impl, const GUID *guid, const DIPROPHEADER *header, BOOL set )
+{
+    switch (LOWORD( guid ))
+    {
+    case (DWORD_PTR)DIPROP_INSTANCENAME:
+    case (DWORD_PTR)DIPROP_KEYNAME:
+    case (DWORD_PTR)DIPROP_PRODUCTNAME:
+    case (DWORD_PTR)DIPROP_TYPENAME:
+    case (DWORD_PTR)DIPROP_USERNAME:
+        if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
+        break;
+
+    case (DWORD_PTR)DIPROP_AUTOCENTER:
+    case (DWORD_PTR)DIPROP_AXISMODE:
+    case (DWORD_PTR)DIPROP_BUFFERSIZE:
+    case (DWORD_PTR)DIPROP_DEADZONE:
+    case (DWORD_PTR)DIPROP_FFGAIN:
+    case (DWORD_PTR)DIPROP_FFLOAD:
+    case (DWORD_PTR)DIPROP_GRANULARITY:
+    case (DWORD_PTR)DIPROP_JOYSTICKID:
+    case (DWORD_PTR)DIPROP_SATURATION:
+    case (DWORD_PTR)DIPROP_SCANCODE:
+    case (DWORD_PTR)DIPROP_VIDPID:
+        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
+        break;
+
+    case (DWORD_PTR)DIPROP_APPDATA:
+        if (header->dwSize != sizeof(DIPROPPOINTER)) return DIERR_INVALIDPARAM;
+        break;
+
+    case (DWORD_PTR)DIPROP_RANGE:
+        if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM;
+        break;
+
+    case (DWORD_PTR)DIPROP_GUIDANDPATH:
+        if (header->dwSize != sizeof(DIPROPGUIDANDPATH)) return DIERR_INVALIDPARAM;
+        break;
+    }
+
+    switch (LOWORD( guid ))
+    {
+    case (DWORD_PTR)DIPROP_PRODUCTNAME:
+    case (DWORD_PTR)DIPROP_INSTANCENAME:
+    case (DWORD_PTR)DIPROP_VIDPID:
+    case (DWORD_PTR)DIPROP_JOYSTICKID:
+    case (DWORD_PTR)DIPROP_GUIDANDPATH:
+    case (DWORD_PTR)DIPROP_BUFFERSIZE:
+    case (DWORD_PTR)DIPROP_FFGAIN:
+    case (DWORD_PTR)DIPROP_TYPENAME:
+    case (DWORD_PTR)DIPROP_USERNAME:
+    case (DWORD_PTR)DIPROP_AUTOCENTER:
+    case (DWORD_PTR)DIPROP_AXISMODE:
+    case (DWORD_PTR)DIPROP_FFLOAD:
+        if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
+        break;
+
+    case (DWORD_PTR)DIPROP_RANGE:
+    case (DWORD_PTR)DIPROP_DEADZONE:
+    case (DWORD_PTR)DIPROP_SATURATION:
+    case (DWORD_PTR)DIPROP_GRANULARITY:
+        if (header->dwHow == DIPH_DEVICE && !set) return DIERR_UNSUPPORTED;
+        break;
+
+    case (DWORD_PTR)DIPROP_KEYNAME:
+        if (header->dwHow == DIPH_DEVICE) return DIERR_INVALIDPARAM;
+        break;
+
+    case (DWORD_PTR)DIPROP_SCANCODE:
+    case (DWORD_PTR)DIPROP_APPDATA:
+        if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED;
+        break;
+    }
+
+    if (set)
+    {
+        switch (LOWORD( guid ))
+        {
+        case (DWORD_PTR)DIPROP_AUTOCENTER:
+        case (DWORD_PTR)DIPROP_AXISMODE:
+        case (DWORD_PTR)DIPROP_BUFFERSIZE:
+            if (impl->acquired) return DIERR_ACQUIRED;
+            break;
+        case (DWORD_PTR)DIPROP_FFLOAD:
+        case (DWORD_PTR)DIPROP_GRANULARITY:
+        case (DWORD_PTR)DIPROP_VIDPID:
+        case (DWORD_PTR)DIPROP_TYPENAME:
+        case (DWORD_PTR)DIPROP_USERNAME:
+        case (DWORD_PTR)DIPROP_GUIDANDPATH:
+            return DIERR_READONLY;
+        }
+
+        switch (LOWORD( guid ))
+        {
+        case (DWORD_PTR)DIPROP_RANGE:
+        {
+            const DIPROPRANGE *value = (const DIPROPRANGE *)header;
+            if (value->lMin > value->lMax) return DIERR_INVALIDPARAM;
+            break;
+        }
+        case (DWORD_PTR)DIPROP_DEADZONE:
+        case (DWORD_PTR)DIPROP_SATURATION:
+        case (DWORD_PTR)DIPROP_FFGAIN:
+        {
+            const DIPROPDWORD *value = (const DIPROPDWORD *)header;
+            if (value->dwData > 10000) return DIERR_INVALIDPARAM;
+            break;
+        }
+        case (DWORD_PTR)DIPROP_AUTOCENTER:
+        case (DWORD_PTR)DIPROP_AXISMODE:
+        {
+            const DIPROPDWORD *value = (const DIPROPDWORD *)header;
+            if (value->dwData > 1) return DIERR_INVALIDPARAM;
+            break;
+        }
+        }
+    }
+
+    return DI_OK;
+}
+
 static BOOL CALLBACK find_object( const DIDEVICEOBJECTINSTANCEW *instance, void *context )
 {
     *(DIDEVICEOBJECTINSTANCEW *)context = *instance;
@@ -921,40 +1041,21 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU
 
     filter = *header;
     if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr;
+    if (FAILED(hr = check_property( impl, guid, header, FALSE ))) return hr;
 
     switch (LOWORD( guid ))
     {
     case (DWORD_PTR)DIPROP_PRODUCTNAME:
     case (DWORD_PTR)DIPROP_INSTANCENAME:
-        if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
-        if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
-        return impl->vtbl->get_property( iface, LOWORD( guid ), header, NULL );
-
     case (DWORD_PTR)DIPROP_VIDPID:
     case (DWORD_PTR)DIPROP_JOYSTICKID:
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
-        if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
-        return impl->vtbl->get_property( iface, LOWORD( guid ), header, NULL );
-
     case (DWORD_PTR)DIPROP_GUIDANDPATH:
-        if (header->dwSize != sizeof(DIPROPGUIDANDPATH)) return DIERR_INVALIDPARAM;
-        if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
         return impl->vtbl->get_property( iface, LOWORD( guid ), header, NULL );
 
     case (DWORD_PTR)DIPROP_RANGE:
-        if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM;
-        if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED;
-        hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance );
-        if (FAILED(hr)) return hr;
-        if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND;
-        if (!(instance.dwType & DIDFT_AXIS)) return DIERR_UNSUPPORTED;
-        return impl->vtbl->get_property( iface, LOWORD( guid ), header, &instance );
-
     case (DWORD_PTR)DIPROP_DEADZONE:
     case (DWORD_PTR)DIPROP_SATURATION:
     case (DWORD_PTR)DIPROP_GRANULARITY:
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
-        if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED;
         hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance );
         if (FAILED(hr)) return hr;
         if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND;
@@ -962,7 +1063,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU
         return impl->vtbl->get_property( iface, LOWORD( guid ), header, &instance );
 
     case (DWORD_PTR)DIPROP_KEYNAME:
-        if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
         hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance );
         if (FAILED(hr)) return hr;
         if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND;
@@ -972,7 +1072,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU
     case (DWORD_PTR)DIPROP_AUTOCENTER:
     {
         DIPROPDWORD *value = (DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
         if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED;
         value->dwData = impl->autocenter;
         return DI_OK;
@@ -980,7 +1079,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU
     case (DWORD_PTR)DIPROP_BUFFERSIZE:
     {
         DIPROPDWORD *value = (DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
         value->dwData = impl->buffersize;
         return DI_OK;
     }
@@ -988,7 +1086,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU
     {
         DIPROPSTRING *value = (DIPROPSTRING *)header;
         struct DevicePlayer *device_player;
-        if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
         LIST_FOR_EACH_ENTRY( device_player, &impl->dinput->device_players, struct DevicePlayer, entry )
         {
             if (IsEqualGUID( &device_player->instance_guid, &impl->guid ))
@@ -1003,7 +1100,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU
     case (DWORD_PTR)DIPROP_FFGAIN:
     {
         DIPROPDWORD *value = (DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
         value->dwData = impl->device_gain;
         return DI_OK;
     }
@@ -1095,25 +1191,14 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c
 
     filter = *header;
     if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr;
+    if (FAILED(hr = check_property( impl, guid, header, TRUE ))) return hr;
 
     switch (LOWORD( guid ))
     {
     case (DWORD_PTR)DIPROP_RANGE:
-    {
-        const DIPROPRANGE *value = (const DIPROPRANGE *)header;
-        if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM;
-        if (value->lMin > value->lMax) return DIERR_INVALIDPARAM;
-        hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, &params );
-        if (FAILED(hr)) return hr;
-        reset_device_state( iface );
-        return DI_OK;
-    }
     case (DWORD_PTR)DIPROP_DEADZONE:
     case (DWORD_PTR)DIPROP_SATURATION:
     {
-        const DIPROPDWORD *value = (const DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
-        if (value->dwData > 10000) return DIERR_INVALIDPARAM;
         hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, &params );
         if (FAILED(hr)) return hr;
         reset_device_state( iface );
@@ -1122,10 +1207,6 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c
     case (DWORD_PTR)DIPROP_AUTOCENTER:
     {
         const DIPROPDWORD *value = (const DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
-        if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
-        if (impl->acquired) return DIERR_ACQUIRED;
-        if (value->dwData > DIPROPAUTOCENTER_ON) return DIERR_INVALIDPARAM;
         if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED;
 
         FIXME( "DIPROP_AUTOCENTER stub!\n" );
@@ -1135,33 +1216,14 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c
     case (DWORD_PTR)DIPROP_FFGAIN:
     {
         const DIPROPDWORD *value = (const DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
         if (!impl->vtbl->send_device_gain) return DIERR_UNSUPPORTED;
-        if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
-        if (value->dwData > 10000) return DIERR_INVALIDPARAM;
         impl->device_gain = value->dwData;
         if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) return DI_OK;
         return impl->vtbl->send_device_gain( iface, impl->device_gain );
     }
-    case (DWORD_PTR)DIPROP_FFLOAD:
-    case (DWORD_PTR)DIPROP_GRANULARITY:
-    case (DWORD_PTR)DIPROP_VIDPID:
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
-        return DIERR_READONLY;
-    case (DWORD_PTR)DIPROP_TYPENAME:
-    case (DWORD_PTR)DIPROP_USERNAME:
-        if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
-        return DIERR_READONLY;
-    case (DWORD_PTR)DIPROP_GUIDANDPATH:
-        if (header->dwSize != sizeof(DIPROPGUIDANDPATH)) return DIERR_INVALIDPARAM;
-        return DIERR_READONLY;
     case (DWORD_PTR)DIPROP_AXISMODE:
     {
         const DIPROPDWORD *value = (const DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
-        if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
-        if (header->dwHow == DIPH_DEVICE && header->dwObj) return DIERR_INVALIDPARAM;
-        if (impl->acquired) return DIERR_ACQUIRED;
 
         TRACE( "Axis mode: %s\n", value->dwData == DIPROPAXISMODE_ABS ? "absolute" : "relative" );
         if (impl->user_format)
@@ -1174,8 +1236,6 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c
     case (DWORD_PTR)DIPROP_BUFFERSIZE:
     {
         const DIPROPDWORD *value = (const DIPROPDWORD *)header;
-        if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
-        if (impl->acquired) return DIERR_ACQUIRED;
 
         TRACE( "buffersize = %d\n", value->dwData );
 
@@ -1191,8 +1251,6 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c
     {
         const DIPROPPOINTER *value = (const DIPROPPOINTER *)header;
         int user_offset;
-        if (header->dwSize != sizeof(DIPROPPOINTER)) return DIERR_INVALIDPARAM;
-        if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED;
         hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance );
         if (FAILED(hr)) return hr;
         if (hr == DIENUM_CONTINUE) return DIERR_OBJECTNOTFOUND;
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index 355dc8ff855..8c347dc009a 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -4193,7 +4193,6 @@ static void test_simple_joystick(void)
     hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph );
     ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_RANGE returned %#x\n", hr );
     hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph );
-    todo_wine
     ok( hr == DIERR_INVALIDPARAM, "GetProperty DIPROP_KEYNAME returned %#x\n", hr );
     hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph );
     ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr );
@@ -4523,7 +4522,6 @@ static void test_simple_joystick(void)
     prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC );
     prop_dword.dwData = 1;
     hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph );
-    todo_wine
     ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr );
     prop_dword.diph.dwHow = DIPH_DEVICE;
     prop_dword.diph.dwObj = 0;
@@ -5086,7 +5084,6 @@ static void test_simple_joystick(void)
 
     prop_dword.dwData = 0xdeadbeef;
     hr = IDirectInputDevice8_SetProperty( device, DIPROP_AXISMODE, &prop_dword.diph );
-    todo_wine
     ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_AXISMODE returned %#x\n", hr );
     prop_dword.dwData = DIPROPAXISMODE_REL;
     hr = IDirectInputDevice8_SetProperty( device, DIPROP_AXISMODE, &prop_dword.diph );
-- 
2.33.1




More information about the wine-devel mailing list