[PATCH v2 08/10] winmm: Guard accesses to joystick array with a critical section.

Andrew Eikum aeikum at codeweavers.com
Thu Dec 9 09:32:45 CST 2021


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Fri, Dec 03, 2021 at 12:19:08PM +0100, Rémi Bernon wrote:
> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> ---
>  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;
>  
> +    EnterCriticalSection( &joystick_cs );
> +
>      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;
> +        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;
> +    }
>  
> -    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;
>  }
> -- 
> 2.34.0
> 
> 



More information about the wine-devel mailing list