[PATCH 8/8] dinput: Handle device types and flags directly in EnumDevices.

Rémi Bernon rbernon at codeweavers.com
Tue Nov 16 01:23:42 CST 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/dinput_main.c    | 43 +++++++++++++++++++++++++++---------
 dlls/dinput/dinput_private.h |  4 ++--
 dlls/dinput/joystick_hid.c   |  7 ------
 dlls/dinput/keyboard.c       | 16 +++-----------
 dlls/dinput/mouse.c          | 16 +++-----------
 dlls/dinput8/tests/hid.c     |  5 ++---
 6 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 4a6bca7d77f..55d566afa4a 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -637,11 +637,21 @@ static HRESULT WINAPI IDirectInput8WImpl_CreateDevice(LPDIRECTINPUT8W iface, REF
     return IDirectInput7_CreateDeviceEx( &This->IDirectInput7W_iface, rguid, &IID_IDirectInputDevice8W, (LPVOID *)pdev, punk );
 }
 
+static BOOL try_enum_device( DWORD type, LPDIENUMDEVICESCALLBACKW callback,
+                             DIDEVICEINSTANCEW *instance, void *context, DWORD flags )
+{
+    if (type && (instance->dwDevType & 0xff) != type) return DIENUM_CONTINUE;
+    if ((flags & DIEDFL_FORCEFEEDBACK) && IsEqualGUID( &instance->guidFFDriver, &GUID_NULL ))
+        return DIENUM_CONTINUE;
+    return enum_callback_wrapper( callback, instance, context );
+}
+
 static HRESULT WINAPI IDirectInput8WImpl_EnumDevices( IDirectInput8W *iface, DWORD type, LPDIENUMDEVICESCALLBACKW callback,
                                                       void *context, DWORD flags )
 {
     DIDEVICEINSTANCEW instance = {.dwSize = sizeof(DIDEVICEINSTANCEW)};
     IDirectInputImpl *impl = impl_from_IDirectInput8W( iface );
+    DWORD device_class = 0, device_type = 0;
     unsigned int i = 0;
     HRESULT hr;
 
@@ -657,19 +667,32 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevices( IDirectInput8W *iface, DWO
 
     if (!impl->initialized) return DIERR_NOTINITIALIZED;
 
-    hr = mouse_enum_device( type, flags, &instance, impl->dwVersion, 0 );
-    if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP)
-        return DI_OK;
-    hr = keyboard_enum_device( type, flags, &instance, impl->dwVersion, 0 );
-    if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP)
-        return DI_OK;
+    if (type <= DI8DEVCLASS_GAMECTRL) device_class = type;
+    else device_type = type;
 
-    do
+    if (device_class == DI8DEVCLASS_ALL || device_class == DI8DEVCLASS_POINTER)
     {
-        hr = hid_joystick_enum_device( type, flags, &instance, impl->dwVersion, i++ );
-        if (hr == DI_OK && enum_callback_wrapper( callback, &instance, context ) == DIENUM_STOP)
+        hr = mouse_enum_device( type, flags, &instance, impl->dwVersion );
+        if (hr == DI_OK && try_enum_device( device_type, callback, &instance, context, flags ) == DIENUM_STOP)
             return DI_OK;
-    } while (SUCCEEDED(hr));
+    }
+
+    if (device_class == DI8DEVCLASS_ALL || device_class == DI8DEVCLASS_KEYBOARD)
+    {
+        hr = keyboard_enum_device( type, flags, &instance, impl->dwVersion );
+        if (hr == DI_OK && try_enum_device( device_type, callback, &instance, context, flags ) == DIENUM_STOP)
+            return DI_OK;
+    }
+
+    if (device_class == DI8DEVCLASS_ALL || device_class == DI8DEVCLASS_GAMECTRL)
+    {
+        do
+        {
+            hr = hid_joystick_enum_device( type, flags, &instance, impl->dwVersion, i++ );
+            if (hr == DI_OK && try_enum_device( device_type, callback, &instance, context, flags ) == DIENUM_STOP)
+                return DI_OK;
+        } while (SUCCEEDED(hr));
+    }
 
     return DI_OK;
 }
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index a9777dc8dbb..c25fe6320ca 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -52,9 +52,9 @@ struct IDirectInputImpl
 extern const IDirectInput7AVtbl dinput7_a_vtbl DECLSPEC_HIDDEN;
 extern const IDirectInput8AVtbl dinput8_a_vtbl DECLSPEC_HIDDEN;
 
-extern HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index );
+extern HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version );
 extern HRESULT mouse_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out );
-extern HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index );
+extern HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version );
 extern HRESULT keyboard_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out );
 extern HRESULT hid_joystick_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index );
 extern HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out );
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 17b79a0f716..4af7da6654d 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -1510,13 +1510,6 @@ HRESULT hid_joystick_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *in
     HidD_FreePreparsedData( preparsed );
     CloseHandle( device );
 
-    if (instance->dwSize != sizeof(DIDEVICEINSTANCEW))
-        return S_FALSE;
-    if (version < 0x0800 && type != 0 && type != DIDEVTYPE_JOYSTICK)
-        return S_FALSE;
-    if (version >= 0x0800 && type != DI8DEVCLASS_ALL && type != DI8DEVCLASS_GAMECTRL)
-        return S_FALSE;
-
     TRACE( "found device %s, usage %04x:%04x, product %s, instance %s, name %s\n", debugstr_w(device_path),
            instance->wUsagePage, instance->wUsage, debugstr_guid( &instance->guidProduct ),
            debugstr_guid( &instance->guidInstance ), debugstr_w(instance->tszInstanceName) );
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index ef125176ecb..f906e32a59d 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -144,22 +144,12 @@ static DWORD get_keyboard_subtype(void)
     return dev_subtype;
 }
 
-HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index )
+HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version )
 {
     BYTE subtype = get_keyboard_subtype();
     DWORD size;
 
-    TRACE( "type %#x, flags %#x, instance %p, version %#04x, index %d\n", type, flags, instance, version, index );
-
-    if (index != 0) return DIERR_GENERIC;
-    if (flags & DIEDFL_FORCEFEEDBACK) return DI_NOEFFECT;
-    if (version < 0x0800 && type != 0 && type != DIDEVTYPE_KEYBOARD) return DI_NOEFFECT;
-    if (version >= 0x0800 && type != DI8DEVCLASS_ALL && type != DI8DEVCLASS_KEYBOARD && type != DI8DEVTYPE_KEYBOARD)
-        return DI_NOEFFECT;
-
-    if (instance->dwSize != sizeof(DIDEVICEINSTANCEW) &&
-        instance->dwSize != sizeof(DIDEVICEINSTANCE_DX3W))
-        return DIERR_INVALIDPARAM;
+    TRACE( "type %#x, flags %#x, instance %p, version %#04x\n", type, flags, instance, version );
 
     size = instance->dwSize;
     memset( instance, 0, size );
@@ -188,7 +178,7 @@ HRESULT keyboard_create_device( IDirectInputImpl *dinput, const GUID *guid, IDir
         return hr;
     impl->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": struct keyboard*->base.crit");
 
-    keyboard_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion, 0 );
+    keyboard_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion );
     impl->base.caps.dwDevType = impl->base.instance.dwDevType;
     impl->base.caps.dwFirmwareRevision = 100;
     impl->base.caps.dwHardwareRevision = 100;
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 628011c13e1..1b45c8d5fd4 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -72,21 +72,11 @@ static inline struct mouse *impl_from_IDirectInputDevice8W( IDirectInputDevice8W
     return CONTAINING_RECORD( CONTAINING_RECORD( iface, struct dinput_device, IDirectInputDevice8W_iface ), struct mouse, base );
 }
 
-HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version, int index )
+HRESULT mouse_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instance, DWORD version )
 {
     DWORD size;
 
-    TRACE( "type %#x, flags %#x, instance %p, version %#04x, index %d\n", type, flags, instance, version, index );
-
-    if (index != 0) return DIERR_GENERIC;
-    if (flags & DIEDFL_FORCEFEEDBACK) return DI_NOEFFECT;
-    if (version < 0x0800 && type != 0 && type != DIDEVTYPE_MOUSE) return DI_NOEFFECT;
-    if (version >= 0x0800 && type != DI8DEVCLASS_ALL && type != DI8DEVCLASS_POINTER && type != DI8DEVTYPE_MOUSE)
-        return DI_NOEFFECT;
-
-    if (instance->dwSize != sizeof(DIDEVICEINSTANCEW) &&
-        instance->dwSize != sizeof(DIDEVICEINSTANCE_DX3W))
-        return DIERR_INVALIDPARAM;
+    TRACE( "type %#x, flags %#x, instance %p, version %#04x\n", type, flags, instance, version );
 
     size = instance->dwSize;
     memset( instance, 0, size );
@@ -117,7 +107,7 @@ HRESULT mouse_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirect
         return hr;
     impl->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": struct mouse*->base.crit");
 
-    mouse_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion, 0 );
+    mouse_enum_device( 0, 0, &impl->base.instance, dinput->dwVersion );
     impl->base.caps.dwDevType = impl->base.instance.dwDevType;
     impl->base.caps.dwFirmwareRevision = 100;
     impl->base.caps.dwHardwareRevision = 100;
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index 73f8ea33650..38bdfb7455e 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -3531,14 +3531,13 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst,
         count = 0;
         hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_ALLDEVICES );
         ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr );
-        todo_wine
         ok( count == 1, "got count %u, expected 1\n", count );
 
         count = 0;
         hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK );
         ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr );
         if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) ok( count == 0, "got count %u, expected 0\n", count );
-        else todo_wine ok( count == 1, "got count %u, expected 1\n", count );
+        else ok( count == 1, "got count %u, expected 1\n", count );
 
         count = 0;
         hr = IDirectInput8_EnumDevices( di8, (devinst->dwDevType & 0xff) + 1, enum_device_count, &count, DIEDFL_ALLDEVICES );
@@ -3636,7 +3635,7 @@ static HRESULT create_dinput_device( DWORD version, DIDEVICEINSTANCEW *devinst,
         count = 0;
         hr = IDirectInput_EnumDevices( di, (devinst->dwDevType & 0xff), enum_device_count, &count, DIEDFL_FORCEFEEDBACK );
         ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr );
-        if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) todo_wine ok( count == 0, "got count %u, expected 0\n", count );
+        if (IsEqualGUID( &devinst->guidFFDriver, &GUID_NULL )) ok( count == 0, "got count %u, expected 0\n", count );
         else ok( count == 1, "got count %u, expected 1\n", count );
 
         hr = IDirectInput_EnumDevices( di, 0x14, enum_device_count, &count, DIEDFL_ALLDEVICES );
-- 
2.33.1




More information about the wine-devel mailing list