@@ -54,6 +54,7 @@ struct rdpsnd_winmm_plugin
5454UINT32 latency ;
5555HANDLE hThread ;
5656DWORD threadId ;
57+ CRITICAL_SECTION cs ;
5758};
5859
5960static BOOL rdpsnd_winmm_convert_format (const AUDIO_FORMAT * in , WAVEFORMATEX * out )
@@ -96,6 +97,7 @@ static BOOL rdpsnd_winmm_set_format(rdpsndDevicePlugin* device, const AUDIO_FORM
9697static DWORD WINAPI waveOutProc (LPVOID lpParameter )
9798{
9899MSG msg ;
100+ rdpsndWinmmPlugin * winmm = (rdpsndWinmmPlugin * )lpParameter ;
99101while (GetMessage (& msg , NULL , 0 , 0 ))
100102{
101103if (msg .message == MM_WOM_CLOSE )
@@ -107,7 +109,9 @@ static DWORD WINAPI waveOutProc(LPVOID lpParameter)
107109{
108110/* free buffer */
109111LPWAVEHDR waveHdr = (LPWAVEHDR )msg .lParam ;
112+ EnterCriticalSection (& winmm -> cs );
110113waveOutUnprepareHeader ((HWAVEOUT )msg .wParam , waveHdr , sizeof (WAVEHDR ));
114+ LeaveCriticalSection (& winmm -> cs );
111115free (waveHdr -> lpData );
112116free (waveHdr );
113117}
@@ -128,7 +132,7 @@ static BOOL rdpsnd_winmm_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* fo
128132if (!rdpsnd_winmm_set_format (device , format , latency ))
129133return FALSE;
130134
131- winmm -> hThread = CreateThread (NULL , 0 , waveOutProc , NULL , 0 , & winmm -> threadId );
135+ winmm -> hThread = CreateThread (NULL , 0 , waveOutProc , winmm , 0 , & winmm -> threadId );
132136if (!winmm -> hThread )
133137{
134138WLog_Print (winmm -> log , WLOG_ERROR , "CreateThread failed: %" PRIu32 "" , GetLastError ());
@@ -162,6 +166,8 @@ static void rdpsnd_winmm_close(rdpsndDevicePlugin* device)
162166
163167if (winmm -> hWaveOut )
164168{
169+ EnterCriticalSection (& winmm -> cs );
170+
165171mmResult = waveOutReset (winmm -> hWaveOut );
166172if (mmResult != MMSYSERR_NOERROR )
167173WLog_Print (winmm -> log , WLOG_ERROR , "waveOutReset failure: %" PRIu32 "" , mmResult );
@@ -170,6 +176,8 @@ static void rdpsnd_winmm_close(rdpsndDevicePlugin* device)
170176if (mmResult != MMSYSERR_NOERROR )
171177WLog_Print (winmm -> log , WLOG_ERROR , "waveOutClose failure: %" PRIu32 "" , mmResult );
172178
179+ LeaveCriticalSection (& winmm -> cs );
180+
173181winmm -> hWaveOut = NULL ;
174182}
175183
@@ -188,6 +196,7 @@ static void rdpsnd_winmm_free(rdpsndDevicePlugin* device)
188196if (winmm )
189197{
190198rdpsnd_winmm_close (device );
199+ DeleteCriticalSection (& winmm -> cs );
191200free (winmm );
192201}
193202}
@@ -269,22 +278,27 @@ static UINT rdpsnd_winmm_play(rdpsndDevicePlugin* device, const BYTE* data, size
269278memcpy (lpWaveHdr -> lpData , data , size );
270279lpWaveHdr -> dwBufferLength = (DWORD )size ;
271280
281+ EnterCriticalSection (& winmm -> cs );
282+
272283mmResult = waveOutPrepareHeader (winmm -> hWaveOut , lpWaveHdr , sizeof (WAVEHDR ));
273284if (mmResult != MMSYSERR_NOERROR )
274285{
275286WLog_Print (winmm -> log , WLOG_ERROR , "waveOutPrepareHeader failure: %" PRIu32 "" , mmResult );
276- goto fail ;
287+ goto failCS ;
277288}
278289
279290mmResult = waveOutWrite (winmm -> hWaveOut , lpWaveHdr , sizeof (WAVEHDR ));
280291if (mmResult != MMSYSERR_NOERROR )
281292{
282293WLog_Print (winmm -> log , WLOG_ERROR , "waveOutWrite failure: %" PRIu32 "" , mmResult );
283294waveOutUnprepareHeader (winmm -> hWaveOut , lpWaveHdr , sizeof (WAVEHDR ));
284- goto fail ;
295+ goto failCS ;
285296}
286297
298+ LeaveCriticalSection (& winmm -> cs );
287299return winmm -> latency ;
300+ failCS :
301+ LeaveCriticalSection (& winmm -> cs );
288302fail :
289303if (lpWaveHdr )
290304free (lpWaveHdr -> lpData );
@@ -332,6 +346,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p
332346winmm -> device .Close = rdpsnd_winmm_close ;
333347winmm -> device .Free = rdpsnd_winmm_free ;
334348winmm -> log = WLog_Get (TAG );
349+ InitializeCriticalSection (& winmm -> cs );
335350
336351args = pEntryPoints -> args ;
337352rdpsnd_winmm_parse_addin_args ((rdpsndDevicePlugin * )winmm , args );
0 commit comments