Commit 3160c7d66fd0bc48951d75d9e687d144c3af3fb0

Sam Lantinga 2020-11-11T19:43:02

Fixed bug 5327 - When direct input fails to load, but a controlller is plugged in through another api, an access violation happens. Bart van der Werf When directinput fails to load, but a controlller is plugged in, an access violation happens. This is due to IEventHandler_CRawGameControllerVtbl_InvokeAdded calling SDL_DINPUT_JoystickPresent which does not check if dinput is assigned signalling initialization of directinput.

diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c
index 5900a96..f025c53 100644
--- a/src/joystick/windows/SDL_dinputjoystick.c
+++ b/src/joystick/windows/SDL_dinputjoystick.c
@@ -514,11 +514,15 @@ SDL_DINPUT_JoystickInit(void)
     /* Because we used CoCreateInstance, we need to Initialize it, first. */
     instance = GetModuleHandle(NULL);
     if (instance == NULL) {
+        IDirectInput8_Release(dinput);
+        dinput = NULL;
         return SDL_SetError("GetModuleHandle() failed with error code %lu.", GetLastError());
     }
     result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
 
     if (FAILED(result)) {
+        IDirectInput8_Release(dinput);
+        dinput = NULL;
         return SetDIerror("IDirectInput::Initialize", result);
     }
     return 0;
@@ -724,6 +728,11 @@ EnumJoystickPresentCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pConte
 SDL_bool
 SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version)
 {
+    if (dinput == NULL)
+    {
+            return SDL_FALSE;
+    }
+
     EnumJoystickPresentData data;
 
     data.vendor = vendor;