Module: wine Branch: master Commit: 38f9ba0070f9b72d8c94d8124b488921078f8018 URL: http://source.winehq.org/git/wine.git/?a=commit;h=38f9ba0070f9b72d8c94d8124b...
Author: Jörg Höhle hoehle@users.sourceforge.net Date: Thu Dec 15 23:07:41 2011 +0100
mmdevapi: Enforce limits on period and duration.
---
dlls/winealsa.drv/mmdevdrv.c | 31 +++++++++++++++++++++---------- dlls/winecoreaudio.drv/mmdevdrv.c | 32 +++++++++++++++++++++----------- dlls/wineoss.drv/mmdevdrv.c | 30 +++++++++++++++++++++--------- 3 files changed, 63 insertions(+), 30 deletions(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index 359997e..994628e 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -835,14 +835,28 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface, return E_INVALIDARG; }
- if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE && flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){ - FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); - return AUDCLNT_E_DEVICE_IN_USE; + if(mode == AUDCLNT_SHAREMODE_SHARED){ + period = DefaultPeriod; + if( duration < 3 * period) + duration = 3 * period; + }else{ + if(!period) + period = DefaultPeriod; /* not minimum */ + if(period < MinimumPeriod || period > 5000000) + return AUDCLNT_E_INVALID_DEVICE_PERIOD; + if(duration > 20000000) /* the smaller the period, the lower this limit */ + return AUDCLNT_E_BUFFER_SIZE_ERROR; + if(flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){ + if(duration != period) + return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL; + FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); + return AUDCLNT_E_DEVICE_IN_USE; + }else{ + if( duration < 8 * period) + duration = 8 * period; /* may grow above 2s */ + } }
- if(!duration) - duration = 300000; /* 0.03s */ - EnterCriticalSection(&This->lock);
if(This->initted){ @@ -1001,10 +1015,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface, goto exit; }
- if(period) - This->mmdev_period_rt = period; - else - This->mmdev_period_rt = DefaultPeriod; + This->mmdev_period_rt = period;
/* Check if the ALSA buffer is so small that it will run out before * the next MMDevAPI period tick occurs. Allow a little wiggle room diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index a648429..a2c72da 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -961,9 +961,26 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface, return E_INVALIDARG; }
- if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE && flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){ - FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); - return AUDCLNT_E_DEVICE_IN_USE; + if(mode == AUDCLNT_SHAREMODE_SHARED){ + period = DefaultPeriod; + if( duration < 3 * period) + duration = 3 * period; + }else{ + if(!period) + period = DefaultPeriod; /* not minimum */ + if(period < MinimumPeriod || period > 5000000) + return AUDCLNT_E_INVALID_DEVICE_PERIOD; + if(duration > 20000000) /* the smaller the period, the lower this limit */ + return AUDCLNT_E_BUFFER_SIZE_ERROR; + if(flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){ + if(duration != period) + return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL; + FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); + return AUDCLNT_E_DEVICE_IN_USE; + }else{ + if( duration < 8 * period) + duration = 8 * period; /* may grow above 2s */ + } }
OSSpinLockLock(&This->lock); @@ -987,15 +1004,8 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface, return E_OUTOFMEMORY; }
- if(period){ - This->period_ms = period / 10000; - if(This->period_ms == 0) - This->period_ms = 1; - }else - This->period_ms = MinimumPeriod / 10000; + This->period_ms = period / 10000;
- if(!duration) - duration = 300000; /* 0.03s */ This->bufsize_frames = ceil(fmt->nSamplesPerSec * (duration / 10000000.));
if(This->dataflow == eCapture){ diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index 571495d..dbbcd9f 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -906,9 +906,26 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface, return E_INVALIDARG; }
- if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE && flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){ - FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); - return AUDCLNT_E_DEVICE_IN_USE; + if(mode == AUDCLNT_SHAREMODE_SHARED){ + period = DefaultPeriod; + if( duration < 3 * period) + duration = 3 * period; + }else{ + if(!period) + period = DefaultPeriod; /* not minimum */ + if(period < MinimumPeriod || period > 5000000) + return AUDCLNT_E_INVALID_DEVICE_PERIOD; + if(duration > 20000000) /* the smaller the period, the lower this limit */ + return AUDCLNT_E_BUFFER_SIZE_ERROR; + if(flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){ + if(duration != period) + return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL; + FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); + return AUDCLNT_E_DEVICE_IN_USE; + }else{ + if( duration < 8 * period) + duration = 8 * period; /* may grow above 2s */ + } }
EnterCriticalSection(&This->lock); @@ -937,13 +954,8 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface, return E_OUTOFMEMORY; }
- if(period) - This->period_us = period / 10; - else - This->period_us = DefaultPeriod / 10; + This->period_us = period / 10;
- if(!duration) - duration = 300000; /* 0.03s */ This->bufsize_frames = ceil(fmt->nSamplesPerSec * (duration / 10000000.)); This->local_buffer = HeapAlloc(GetProcessHeap(), 0, This->bufsize_frames * fmt->nBlockAlign);