From: Connor McAdams <cmcadams@codeweavers.com> --- dlls/dinput/joystick_hid.c | 54 ++++++++++++++++++++++++----------- dlls/dinput/tests/joystick8.c | 4 +-- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 2d75194117e..5d21e993d10 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -51,9 +51,41 @@ 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_GUID( device_path_guid, 0x00000000, 0x0000, 0x0000, 0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf8 ); +/* + * Version 1 UUID timestamps are a count of the number of 100 nanosecond + * intervals since 00:00:00.00, 15 October 1582 (the date of Gregorian + * reform to the Christian calendar). FILETIME is a count of the number of 100 + * nanosecond intervals since 00:00:00.00, 1 January 1601. In order to convert + * a FILETIME value to a UUID timestamp, we need to add: + * - 17 days in October 1582. + * - 30 days in November 1582. + * - 31 days in December 1582. + * - 18 years between January 1583 and January 1601. + * - 5 leap days in those 18 years. + */ +#define UUID_TIME_TO_SYSTEM_TIME_DAYS ((ULONG64)((365 * 18) + 5 + 17 + 30 + 31)) +#define UUID_TIME_TO_SYSTEM_TIME_NS_DIFFERENCE ((UUID_TIME_TO_SYSTEM_TIME_DAYS) * 24 * 60 * 60 * 10000000) +DEFINE_GUID( dinput_joystick_uuid_init, 0x00000000, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x00, 'D', 'E', 'S', 'T' ); +static void create_v1_uuid( GUID *guid ) +{ + GUID tmp = dinput_joystick_uuid_init; + static LONG clock_seq; + ULARGE_INTEGER time; + ULONG cur_seq; + + GetSystemTimeAsFileTime( (FILETIME *)&time ); + time.QuadPart += UUID_TIME_TO_SYSTEM_TIME_NS_DIFFERENCE; + tmp.Data1 = (time.QuadPart & 0xffffffff); + tmp.Data2 = ((time.QuadPart >> 32) & 0xffff); + tmp.Data3 |= ((time.QuadPart >> 48) & 0x0fff); + cur_seq = InterlockedIncrement( &clock_seq ); + tmp.Data4[1] |= (cur_seq & 0xff); + tmp.Data4[0] |= ((cur_seq & 0x3f00) >> 8); + *guid = tmp; +} + static CRITICAL_SECTION joystick_cache_cs; static CRITICAL_SECTION_DEBUG joystick_cache_cs_debug = { @@ -1793,7 +1825,7 @@ static HRESULT hid_joystick_get_class_dev_iface_list( const GUID *class, const D return DI_OK; } -static BOOL hid_device_is_valid_joystick( const WCHAR *path, WORD *vid, WORD *pid, BOOL *override, GUID *guid_instance ) +static BOOL hid_device_is_valid_joystick( const WCHAR *path, WORD *vid, WORD *pid, BOOL *override ) { PHIDP_PREPARSED_DATA preparsed = NULL; HIDD_ATTRIBUTES attrs = { 0 }; @@ -1801,8 +1833,6 @@ static BOOL hid_device_is_valid_joystick( const WCHAR *path, WORD *vid, WORD *pi WCHAR product[MAX_PATH]; BOOL ret_val = FALSE; HIDP_CAPS caps; - UINT32 handle; - DWORD size; device_file = CreateFileW( path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, 0 ); @@ -1823,13 +1853,6 @@ static BOOL hid_device_is_valid_joystick( const WCHAR *path, WORD *vid, WORD *pi if (!HidD_GetProductString( device_file, product, sizeof(product) )) goto exit; if (device_instance_is_disabled( product, override )) goto exit; - if (!DeviceIoControl( device_file, IOCTL_HID_GET_WINE_RAWINPUT_HANDLE, NULL, 0, &handle, sizeof(handle), &size, NULL )) - { - ERR( "failed to get raw input handle, error %lu\n", GetLastError() ); - goto exit; - } - *guid_instance = hid_joystick_guid; - guid_instance->Data1 ^= handle; *vid = attrs.VendorID; *pid = attrs.ProductID; ret_val = TRUE; @@ -1844,6 +1867,7 @@ static HRESULT get_joystick_instance_id_for_joystick( WORD vid, WORD pid, struct struct list *new_ids, struct joystick_instance_id **out_id ) { struct joystick_instance_id *instance_id_prev, *tmp; + GUID uuid; /* First, try to find an unassigned ID from the existing registry entries. */ instance_id_prev = tmp = NULL; @@ -1874,8 +1898,9 @@ static HRESULT get_joystick_instance_id_for_joystick( WORD vid, WORD pid, struct } } + create_v1_uuid( &uuid ); return add_joystick_instance_id_to_list( vid, pid, instance_id_prev ? instance_id_prev->idx + 1 : 0, - &GUID_NULL, new_ids, out_id ); + &uuid, new_ids, out_id ); } HRESULT hid_joystick_refresh_devices( void ) @@ -1907,9 +1932,8 @@ HRESULT hid_joystick_refresh_devices( void ) struct joystick_instance *instance = NULL; BOOL override; WORD vid, pid; - GUID guid; - if (!hid_device_is_valid_joystick( tmp, &vid, &pid, &override, &guid )) continue; + if (!hid_device_is_valid_joystick( tmp, &vid, &pid, &override )) continue; if (!(instance = malloc( sizeof(*instance) ))) { hr = E_OUTOFMEMORY; @@ -1918,7 +1942,6 @@ HRESULT hid_joystick_refresh_devices( void ) instance->vid = vid; instance->pid = pid; instance->override = override; - instance->guid = guid; wcscpy( instance->dev_path, tmp ); /* * SetupAPI returns paths in lowercase, cfgmgr32 does not. joy.cpl @@ -1956,7 +1979,6 @@ HRESULT hid_joystick_refresh_devices( void ) } id->assigned = TRUE; - if (IsEqualGUID( &id->guid, &GUID_NULL )) id->guid = cur->guid; cur->guid = id->guid; } diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 2c395cb4462..f2b9c490054 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -6191,12 +6191,12 @@ static void test_joystick_instance_guid( DWORD version ) { winetest_push_context( "device %d", i ); - todo_wine ok( !IsEqualGUID( &expect_instances[i], &instances[i] ), + ok( !IsEqualGUID( &expect_instances[i], &instances[i] ), "Unexpected instance %s.\n", debugstr_guid( &instances[i] ) ); /* Old guidInstance no longer works. */ hr = dinput_create_device( &di, &expect_instances[i], &device ); - todo_wine ok( hr == DIERR_DEVICENOTREG, "Unexpected hr %#lx.\n", hr ); + ok( hr == DIERR_DEVICENOTREG, "Unexpected hr %#lx.\n", hr ); if (SUCCEEDED(hr)) IDirectInputDevice8_Release( device ); expect_instances[i] = instances[i]; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10364