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