diff --git a/src/core/windows/SDL_gameinput.cpp b/src/core/windows/SDL_gameinput.cpp index 1d5113671e..7606b29c3c 100644 --- a/src/core/windows/SDL_gameinput.cpp +++ b/src/core/windows/SDL_gameinput.cpp @@ -40,6 +40,10 @@ static int g_nGameInputRefCount; bool SDL_InitGameInput(IGameInput **ppGameInput) { if (g_nGameInputRefCount == 0) { + if (WIN_HasBrokenEZFRD64DLL()) { + return SDL_SetError("GameInput disabled to prevent application crashing"); + } + // This is recommended, as Microsoft's GameInputCreate() is robust // and better handles various GameInput installations HRESULT hr = GameInputCreate(&g_pGameInput); diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index 084113e9fa..6c39b5c7d7 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -773,4 +773,35 @@ char *WIN_GetModulePath(HMODULE handle) return retval; } +bool WIN_HasBrokenEZFRD64DLL(void) +{ + static bool checked = false; + static bool has_broken_EZFRD64_DLL = false; + +#ifdef _WIN64 + if (!checked) { + if (SDL_GetHintBoolean("SDL_CHECK_BROKEN_EZFRD64", true)) { + // The 64-bit version of EZFRD64.DLL crashes after being loaded, + // which happens implicitly when querying the device capabilities, + // so make sure we don't do that if there's a possibility of crashing + static const char *directories[] = { + "C:/Windows/USB_Vibration", + "C:/Windows/USB Vibration" + }; + for (int i = 0; i < SDL_arraysize(directories) && !has_broken_EZFRD64_DLL; ++i) { + int count = 0; + char **files = SDL_GlobDirectory(directories[i], "*/EZFRD64.DLL", SDL_GLOB_CASEINSENSITIVE, &count); + if (count > 0) { + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Broken EZFRD64.DLL detected, disabling GameInput and DirectInput force feedback"); + has_broken_EZFRD64_DLL = true; + } + SDL_free(files); + } + } + checked = true; + } +#endif + return has_broken_EZFRD64_DLL; +} + #endif // defined(SDL_PLATFORM_WINDOWS) diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index 2c18c5cd1b..f5006393a8 100644 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -231,6 +231,9 @@ extern const char *WIN_CheckDefaultArgcArgv(int *pargc, char ***pargv, void **pa // Does all the win32 tapdancing to make GetModuleFileName work. Returns a SDL_malloc'd UTF-8 string, or NULL on failure. extern char *WIN_GetModulePath(HMODULE handle); +// Return true if this system has a broken EZFRD64.DLL installed +extern bool WIN_HasBrokenEZFRD64DLL(void); + // Ends C function definitions when using C++ #ifdef __cplusplus } diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 54d06a138e..1c6134c909 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -46,7 +46,6 @@ extern HWND SDL_HelperWindow; // local variables static bool coinitialized = false; static LPDIRECTINPUT8 dinput = NULL; -static bool has_broken_EZFRD64DLL = false; // Taken from Wine - Thanks! static DIOBJECTDATAFORMAT dfDIJoystick2[] = { @@ -440,29 +439,6 @@ bool SDL_DINPUT_JoystickInit(void) dinput = NULL; return SetDIerror("IDirectInput::Initialize", result); } - -#ifdef _WIN64 - if (SDL_GetHintBoolean("SDL_JOYSTICK_CHECK_EZFRD64", true)) { - // The 64-bit version of EZFRD64.DLL crashes after being loaded, - // which happens implicitly when querying the device capabilities, - // so make sure we don't do that if there's a possibility of crashing - static const char *directories[] = { - "C:/Windows/USB_Vibration", - "C:/Windows/USB Vibration" - }; - for (int i = 0; i < SDL_arraysize(directories) && !has_broken_EZFRD64DLL; ++i) { - int count = 0; - char **files = SDL_GlobDirectory(directories[i], "*/EZFRD64.DLL", SDL_GLOB_CASEINSENSITIVE, &count); - if (count > 0) { - has_broken_EZFRD64DLL = true; - } - SDL_free(files); - } - if (has_broken_EZFRD64DLL) { - SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Broken EZFRD64.DLL detected, disabling DirectInput force feedback"); - } - } -#endif return true; } @@ -808,7 +784,7 @@ bool SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joysti return SetDIerror("IDirectInputDevice8::SetDataFormat", result); } - if (!has_broken_EZFRD64DLL) { + if (!WIN_HasBrokenEZFRD64DLL()) { // Get device capabilities to see if we are force feedback capable result = IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice,