Instead of message notifications only. We have to remove the events from devices that are automatically unacquired whenever a read failed.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 5226a07e500..cd40eabb373 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1311,16 +1311,9 @@ static DWORD WINAPI dinput_thread_proc( void *params ) goto done; }
- events_count = 0; EnterCriticalSection( &dinput_hook_crit ); kbd_cnt = list_count( &acquired_keyboard_list ); mice_cnt = list_count( &acquired_mouse_list ); - LIST_FOR_EACH_ENTRY( impl, &acquired_device_list, struct dinput_device, entry ) - { - if (!impl->read_event || !impl->vtbl->read) continue; - if (events_count >= ARRAY_SIZE(events)) break; - events[events_count++] = impl->read_event; - } LeaveCriticalSection( &dinput_hook_crit );
if (kbd_cnt && !kbd_hook) @@ -1341,8 +1334,20 @@ static DWORD WINAPI dinput_thread_proc( void *params )
SetEvent(finished_event); } + + events_count = 0; + EnterCriticalSection( &dinput_hook_crit ); + LIST_FOR_EACH_ENTRY( impl, &acquired_device_list, struct dinput_device, entry ) + { + if (!impl->read_event || !impl->vtbl->read) continue; + if (events_count >= ARRAY_SIZE(events)) break; + events[events_count++] = impl->read_event; + } + LeaveCriticalSection( &dinput_hook_crit ); }
+ if (ret != events_count) ERR("Unexpected termination, ret %#x\n", ret); + done: DestroyWindow( di_em_win ); di_em_win = NULL;
MSDN states that the function can only return one of DIERR_INVALIDPARAM, DIERR_NOTINITIALIZED, DIERR_OTHERAPPHASPRIO, on error, and DI_OK, or DI_NOEFFECT, on success.
Some games will try to call Acquire again in a tight loop and block the main thread if DIERR_INPUTLOST is returned. There's a small chance for this to happen with Resident Evil 2, whenever a joystick is plugged, then quickly unplugged.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/joystick_hid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 3b02600ce4e..4ba127b1fd2 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -866,7 +866,7 @@ static HRESULT hid_joystick_acquire( IDirectInputDevice8W *iface ) { impl->device = CreateFileW( impl->device_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, 0 ); - if (impl->device == INVALID_HANDLE_VALUE) return DIERR_INPUTLOST; + if (impl->device == INVALID_HANDLE_VALUE) return DIERR_INVALIDPARAM; }
memset( &impl->read_ovl, 0, sizeof(impl->read_ovl) ); @@ -876,7 +876,7 @@ static HRESULT hid_joystick_acquire( IDirectInputDevice8W *iface ) { CloseHandle( impl->device ); impl->device = INVALID_HANDLE_VALUE; - return DIERR_INPUTLOST; + return DIERR_INVALIDPARAM; }
IDirectInputDevice8_SendForceFeedbackCommand( iface, DISFFC_RESET );