[PATCH 4/5] dinput: Open the WINEXINPUT interface when the override key is set.

Rémi Bernon rbernon at codeweavers.com
Fri Sep 24 01:57:11 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/joystick.c            | 18 +++++++++-------
 dlls/dinput/joystick_hid.c        | 35 ++++++++++++++++++++++++++++---
 dlls/dinput/joystick_linux.c      |  2 +-
 dlls/dinput/joystick_linuxinput.c |  2 +-
 dlls/dinput/joystick_private.h    |  4 ++--
 5 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c
index d4f5b819471..6e573e8741a 100644
--- a/dlls/dinput/joystick.c
+++ b/dlls/dinput/joystick.c
@@ -271,23 +271,25 @@ void dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid, DWORD dwFlags)
     }
 }
 
-BOOL device_disabled_registry(const char* name, BOOL disable)
+BOOL device_disabled_registry(const char* name)
 {
     DIDEVICEINSTANCEW instance;
 
     MultiByteToWideChar( CP_ACP, 0, name, -1, instance.tszInstanceName, MAX_PATH );
-    return device_instance_is_disabled( &instance, disable );
+    return device_instance_is_disabled( &instance, NULL );
 }
 
-BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL disable )
+BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL *override )
 {
     static const WCHAR disabled_str[] = {'d', 'i', 's', 'a', 'b', 'l', 'e', 'd', 0};
-    static const WCHAR enabled_str[] = {'e', 'n', 'a', 'b', 'l', 'e', 'd', 0};
+    static const WCHAR override_str[] = {'o', 'v', 'e', 'r', 'r', 'i', 'd', 'e', 0};
     static const WCHAR joystick_key[] = {'J', 'o', 'y', 's', 't', 'i', 'c', 'k', 's', 0};
     WCHAR buffer[MAX_PATH];
     HKEY hkey, appkey, temp;
+    BOOL disable = FALSE;
 
     get_app_key(&hkey, &appkey);
+    if (override) *override = FALSE;
 
     /* Joystick settings are in the 'joysticks' subkey */
     if (appkey)
@@ -307,15 +309,15 @@ BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL disable )
     /* Look for the "controllername"="disabled" key */
     if (!get_config_key( hkey, appkey, instance->tszInstanceName, buffer, sizeof(buffer) ))
     {
-        if (!disable && !strcmpW( disabled_str, buffer ))
+        if (!strcmpW( disabled_str, buffer ))
         {
             TRACE( "Disabling joystick '%s' based on registry key.\n", debugstr_w(instance->tszInstanceName) );
             disable = TRUE;
         }
-        else if (disable && !strcmpW( enabled_str, buffer ))
+        else if (override && !strcmpW( override_str, buffer ))
         {
-            TRACE( "Enabling joystick '%s' based on registry key.\n", debugstr_w(instance->tszInstanceName) );
-            disable = FALSE;
+            TRACE( "Force enabling joystick '%s' based on registry key.\n", debugstr_w(instance->tszInstanceName) );
+            *override = TRUE;
         }
     }
 
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 81fa3eefe7a..30e63c16cb8 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -45,6 +45,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
 
+DEFINE_GUID( GUID_DEVINTERFACE_WINEXINPUT,0x6c53d5fd,0x6480,0x440f,0xb6,0x18,0x47,0x67,0x50,0xc5,0xe1,0xa6 );
 DEFINE_GUID( hid_joystick_guid, 0x9e573edb, 0x7734, 0x11d2, 0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7 );
 DEFINE_DEVPROPKEY( DEVPROPKEY_HID_HANDLE, 0xbc62e415, 0xf4fe, 0x405c, 0x8e, 0xda, 0x63, 0x6f, 0xb5, 0x9f, 0x08, 0x98, 2 );
 
@@ -1107,13 +1108,17 @@ static HRESULT hid_joystick_device_open( int index, DIDEVICEINSTANCEW *filter, W
                                          HANDLE *device, PHIDP_PREPARSED_DATA *preparsed,
                                          HIDD_ATTRIBUTES *attrs, HIDP_CAPS *caps, DWORD version )
 {
+    static const WCHAR ig_w[] = {'&','I','G','_',0};
+    static const WCHAR xi_w[] = {'&','X','I','_',0};
     char buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR)];
     SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = (void *)buffer;
     SP_DEVICE_INTERFACE_DATA iface = {.cbSize = sizeof(iface)};
     SP_DEVINFO_DATA devinfo = {.cbSize = sizeof(devinfo)};
     DIDEVICEINSTANCEW instance = *filter;
+    WCHAR device_id[MAX_PATH], *tmp;
+    HDEVINFO set, xi_set;
     UINT32 i = 0, handle;
-    HDEVINFO set;
+    BOOL override;
     DWORD type;
     GUID hid;
 
@@ -1124,6 +1129,7 @@ static HRESULT hid_joystick_device_open( int index, DIDEVICEINSTANCEW *filter, W
 
     set = SetupDiGetClassDevsW( &hid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT );
     if (set == INVALID_HANDLE_VALUE) return DIERR_DEVICENOTREG;
+    xi_set = SetupDiGetClassDevsW( &GUID_DEVINTERFACE_WINEXINPUT, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT );
 
     *device = NULL;
     *preparsed = NULL;
@@ -1140,6 +1146,29 @@ static HRESULT hid_joystick_device_open( int index, DIDEVICEINSTANCEW *filter, W
                                            attrs, caps, &instance, version ))
             continue;
 
+        if (device_instance_is_disabled( &instance, &override ))
+            goto next;
+
+        if (override)
+        {
+            if (!SetupDiGetDeviceInstanceIdW( set, &devinfo, device_id, MAX_PATH, NULL ) ||
+                !(tmp = strstrW( device_id, ig_w )))
+                goto next;
+            memcpy( tmp, xi_w, sizeof(xi_w) - sizeof(WCHAR) );
+            if (!SetupDiOpenDeviceInfoW( xi_set, device_id, NULL, 0, &devinfo ))
+                goto next;
+            if (!SetupDiEnumDeviceInterfaces( xi_set, &devinfo, &GUID_DEVINTERFACE_WINEXINPUT, 0, &iface ))
+                goto next;
+            if (!SetupDiGetDeviceInterfaceDetailW( xi_set, &iface, detail, sizeof(buffer), NULL, &devinfo ))
+                goto next;
+
+            CloseHandle( *device );
+            HidD_FreePreparsedData( *preparsed );
+            if (!hid_joystick_device_try_open( handle, detail->DevicePath, device, preparsed,
+                                               attrs, caps, &instance, version ))
+                continue;
+        }
+
         /* enumerate device by GUID */
         if (index < 0 && IsEqualGUID( &filter->guidProduct, &instance.guidProduct )) break;
         if (index < 0 && IsEqualGUID( &filter->guidInstance, &instance.guidInstance )) break;
@@ -1147,12 +1176,14 @@ static HRESULT hid_joystick_device_open( int index, DIDEVICEINSTANCEW *filter, W
         /* enumerate all devices */
         if (index >= 0 && !index--) break;
 
+    next:
         CloseHandle( *device );
         HidD_FreePreparsedData( *preparsed );
         *device = NULL;
         *preparsed = NULL;
     }
 
+    if (xi_set != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList( xi_set );
     SetupDiDestroyDeviceInfoList( set );
     if (!*device || !*preparsed) return DIERR_DEVICENOTREG;
 
@@ -1187,8 +1218,6 @@ static HRESULT hid_joystick_enum_device( DWORD type, DWORD flags, DIDEVICEINSTAN
     if (version >= 0x0800 && type != DI8DEVCLASS_ALL && type != DI8DEVCLASS_GAMECTRL)
         return S_FALSE;
 
-    if (device_instance_is_disabled( instance, FALSE )) return DIERR_DEVICENOTREG;
-
     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/joystick_linux.c b/dlls/dinput/joystick_linux.c
index c439cca81c3..5b54e352c20 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -175,7 +175,7 @@ static INT find_joystick_devices(void)
         /* Append driver name */
         strcat(joydev.name, JOYDEVDRIVER);
 
-        if (device_disabled_registry(joydev.name, FALSE)) {
+        if (device_disabled_registry(joydev.name)) {
             close(fd);
             continue;
         }
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 8279ffbf74a..949fd1da081 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -264,7 +264,7 @@ static void find_joydevs(void)
         else
             joydev.name = joydev.device;
 
-        if (device_disabled_registry(joydev.name, FALSE)) {
+        if (device_disabled_registry(joydev.name)) {
             close(fd);
             HeapFree(GetProcessHeap(), 0, joydev.name);
             if (joydev.name != joydev.device)
diff --git a/dlls/dinput/joystick_private.h b/dlls/dinput/joystick_private.h
index 4fe51d17067..32265edef03 100644
--- a/dlls/dinput/joystick_private.h
+++ b/dlls/dinput/joystick_private.h
@@ -57,8 +57,8 @@ HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_
 
 DWORD joystick_map_pov(const POINTL *p) DECLSPEC_HIDDEN;
 
-BOOL device_disabled_registry(const char* name, BOOL disable) DECLSPEC_HIDDEN;
-BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL disable ) DECLSPEC_HIDDEN;
+BOOL device_disabled_registry(const char* name) DECLSPEC_HIDDEN;
+BOOL device_instance_is_disabled( DIDEVICEINSTANCEW *instance, BOOL *override ) DECLSPEC_HIDDEN;
 
 ULONG WINAPI JoystickWGenericImpl_Release(LPDIRECTINPUTDEVICE8W iface);
 
-- 
2.33.0




More information about the wine-devel mailing list