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