From b22ce2b5a811abe2bc7bd4119da5d3a4f36a87d0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 17 Mar 2022 17:10:40 -0700 Subject: [PATCH] Workaround for bug in Microsoft WGI support Fixes https://github.com/libsdl-org/SDL/issues/5270 --- src/core/windows/SDL_windows.c | 46 ++++++++++++++++++- src/joystick/windows/SDL_dinputjoystick.c | 3 +- src/joystick/windows/SDL_rawinputjoystick.c | 3 +- .../windows/SDL_windows_gaming_input.c | 46 +------------------ src/joystick/windows/SDL_windowsjoystick.c | 3 +- 5 files changed, 49 insertions(+), 52 deletions(-) diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index 2bdf878dd..fcbf8e847 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -104,7 +104,51 @@ void WIN_CoUninitialize(void) { #ifndef __WINRT__ - CoUninitialize(); + /* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting. + * + * If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize() + * with this stack trace: + + Windows.Gaming.Input.dll!GameController::~GameController(void) Unknown + Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid,class Microsoft::WRL::FtmBase>::Release(void) Unknown + Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass,struct Microsoft::WRL::CloakedIid,struct Microsoft::WRL::CloakedIid,struct Microsoft::WRL::CloakedIid,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>() Unknown + Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *)) Unknown + Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection::~GameControllerCollection(void) Unknown + Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection::`vector deleting destructor'(unsigned int) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl,1,1,0,struct Windows::Foundation::Collections::IIterable,struct Windows::Foundation::Collections::IVectorView,class Microsoft::WRL::FtmBase>::Release(void) Unknown + Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase::~CustomGameControllerFactoryBase(void) Unknown + Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase::`vector deleting destructor'(unsigned int) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>() Unknown + Windows.Gaming.Input.dll!NtList::~NtList(void) Unknown + Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid,0>::Release(void) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void) Unknown + Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int) Unknown + Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage,0,int>::instance_''() Unknown + Windows.Gaming.Input.dll!__CRT_INIT@12() Unknown + Windows.Gaming.Input.dll!__DllMainCRTStartup() Unknown + ntdll.dll!_LdrxCallInitRoutine@16() Unknown + ntdll.dll!LdrpCallInitRoutine() Unknown + ntdll.dll!LdrpProcessDetachNode() Unknown + ntdll.dll!LdrpUnloadNode() Unknown + ntdll.dll!LdrpDecrementModuleLoadCountEx() Unknown + ntdll.dll!LdrUnloadDll() Unknown + KernelBase.dll!FreeLibrary() Unknown + combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193 C++ + combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311 C++ + combase.dll!CClassCache::CFinishComposite::Finish() Line 3421 C++ + combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009 C++ + [Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773 C++ + combase.dll!ProcessUninitialize() Line 2243 C++ + combase.dll!DecrementProcessInitializeCount() Line 993 C++ + combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126 C++ + combase.dll!CoUninitialize() Line 3945 C++ + */ + /*CoUninitialize();*/ #endif } diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index caf627a6c..c2f53a93f 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -1147,8 +1147,7 @@ SDL_DINPUT_JoystickQuit(void) } if (coinitialized) { - /* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */ - /*WIN_CoUninitialize();*/ + WIN_CoUninitialize(); coinitialized = SDL_FALSE; } } diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index e0fcc28a9..1fe99a4bf 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -657,8 +657,7 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics); wgi_state.gamepad_statics = NULL; } - /* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */ - /*WIN_CoUninitialize();*/ + WIN_CoUninitialize(); wgi_state.initialized = SDL_FALSE; } } diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index 2cb5f2cb7..e9ff1daaf 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -865,51 +865,7 @@ WGI_JoystickQuit(void) } SDL_zero(wgi); - /* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting. - * - * If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize() - * with this stack trace: - - Windows.Gaming.Input.dll!GameController::~GameController(void) Unknown - Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid,class Microsoft::WRL::FtmBase>::Release(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass,struct Microsoft::WRL::CloakedIid,struct Microsoft::WRL::CloakedIid,struct Microsoft::WRL::CloakedIid,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>() Unknown - Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *)) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection::~GameControllerCollection(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl,1,1,0,struct Windows::Foundation::Collections::IIterable,struct Windows::Foundation::Collections::IVectorView,class Microsoft::WRL::FtmBase>::Release(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase::~CustomGameControllerFactoryBase(void) Unknown - Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion,Windows::Foundation::IAsyncOperationWithProgress>'::`2'::FTMEventDelegate>() Unknown - Windows.Gaming.Input.dll!NtList::~NtList(void) Unknown - Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid,0>::Release(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void) Unknown - Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int) Unknown - Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage,0,int>::instance_''() Unknown - Windows.Gaming.Input.dll!__CRT_INIT@12() Unknown - Windows.Gaming.Input.dll!__DllMainCRTStartup() Unknown - ntdll.dll!_LdrxCallInitRoutine@16() Unknown - ntdll.dll!LdrpCallInitRoutine() Unknown - ntdll.dll!LdrpProcessDetachNode() Unknown - ntdll.dll!LdrpUnloadNode() Unknown - ntdll.dll!LdrpDecrementModuleLoadCountEx() Unknown - ntdll.dll!LdrUnloadDll() Unknown - KernelBase.dll!FreeLibrary() Unknown - combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193 C++ - combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311 C++ - combase.dll!CClassCache::CFinishComposite::Finish() Line 3421 C++ - combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009 C++ - [Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773 C++ - combase.dll!ProcessUninitialize() Line 2243 C++ - combase.dll!DecrementProcessInitializeCount() Line 993 C++ - combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126 C++ - combase.dll!CoUninitialize() Line 3945 C++ - */ - /* WIN_CoUninitialize(); */ + WIN_CoUninitialize(); } static SDL_bool diff --git a/src/joystick/windows/SDL_windowsjoystick.c b/src/joystick/windows/SDL_windowsjoystick.c index 35a4e9c6d..7dae16d9f 100644 --- a/src/joystick/windows/SDL_windowsjoystick.c +++ b/src/joystick/windows/SDL_windowsjoystick.c @@ -256,8 +256,7 @@ SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data) UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance); if (data->coinitialized == S_OK) { - /* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */ - /*WIN_CoUninitialize();*/ + WIN_CoUninitialize(); } }