Rémi Bernon : winmm: Guard accesses to joystick array with a critical section.

Alexandre Julliard julliard at winehq.org
Fri Dec 10 15:07:50 CST 2021


Module: wine
Branch: master
Commit: 591dcfda0112476083e2567530c6d3d1fed29ea6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=591dcfda0112476083e2567530c6d3d1fed29ea6

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Fri Dec  3 12:19:08 2021 +0100

winmm: Guard accesses to joystick array with a critical section.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winmm/joystick.c | 46 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c
index 842b521a586..20a69e8119d 100644
--- a/dlls/winmm/joystick.c
+++ b/dlls/winmm/joystick.c
@@ -40,6 +40,15 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
 
+static CRITICAL_SECTION joystick_cs;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &joystick_cs,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": joystick_cs") }
+};
+static CRITICAL_SECTION joystick_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
+
 #define JOY_PERIOD_MIN	(10)	/* min Capture time period */
 #define JOY_PERIOD_MAX	(1000)	/* max Capture time period */
 
@@ -91,6 +100,8 @@ static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD
     LONG pos;
     int i;
 
+    EnterCriticalSection( &joystick_cs );
+
     for (i = 0; i < ARRAY_SIZE(joysticks); i++)
     {
         if (joysticks[i].capture != hwnd) continue;
@@ -125,6 +136,8 @@ static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD
             joysticks[i].info.wButtons = info.wButtons;
         }
     }
+
+    LeaveCriticalSection( &joystick_cs );
 }
 
 /**************************************************************************
@@ -285,7 +298,10 @@ MMRESULT WINAPI joyGetThreshold( UINT id, UINT *threshold )
 
     if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
 
+    EnterCriticalSection( &joystick_cs );
     *threshold = joysticks[id].threshold;
+    LeaveCriticalSection( &joystick_cs );
+
     return JOYERR_NOERROR;
 }
 
@@ -299,6 +315,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id )
     if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
     if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
 
+    EnterCriticalSection( &joystick_cs );
+
     if (!joysticks[id].capture)
         TRACE("Joystick is not captured, ignoring request.\n");
     else
@@ -308,6 +326,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id )
         joysticks[id].timer = 0;
     }
 
+    LeaveCriticalSection( &joystick_cs );
+
     return JOYERR_NOERROR;
 }
 
@@ -316,6 +336,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id )
  */
 MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed )
 {
+    MMRESULT res = JOYERR_NOERROR;
+
     TRACE( "hwnd %p, id %u, period %u, changed %u.\n", hwnd, id, period, changed );
 
     if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS;
@@ -323,16 +345,22 @@ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed )
     else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX;
     if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
 
-    if (joysticks[id].capture || !IsWindow( hwnd ))
-        return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
-    if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED;
-    if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0)
-        return JOYERR_NOCANDO;
+    EnterCriticalSection( &joystick_cs );
 
-    joysticks[id].capture = hwnd;
-    joysticks[id].changed = changed;
+    if (joysticks[id].capture || !IsWindow( hwnd ))
+        res = JOYERR_NOCANDO; /* FIXME: what should be returned ? */
+    else if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR)
+        res = JOYERR_UNPLUGGED;
+    else if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0)
+        res = JOYERR_NOCANDO;
+    else
+    {
+        joysticks[id].capture = hwnd;
+        joysticks[id].changed = changed;
+    }
 
-    return JOYERR_NOERROR;
+    LeaveCriticalSection( &joystick_cs );
+    return res;
 }
 
 /**************************************************************************
@@ -344,7 +372,9 @@ MMRESULT WINAPI joySetThreshold( UINT id, UINT threshold )
 
     if (id >= ARRAY_SIZE(joysticks) || threshold > 65535) return MMSYSERR_INVALPARAM;
 
+    EnterCriticalSection( &joystick_cs );
     joysticks[id].threshold = threshold;
+    LeaveCriticalSection( &joystick_cs );
 
     return JOYERR_NOERROR;
 }




More information about the wine-cvs mailing list