dinput: Open the WINEXINPUT interface when the override key is set.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-09-24 10:10:35 +02:00 committed by Alexandre Julliard
parent 4ba54cb448
commit 6217705391
5 changed files with 46 additions and 15 deletions

View File

@ -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;
}
}

View File

@ -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) );

View File

@ -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;
}

View File

@ -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)

View File

@ -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);