=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: mmdevapi: Enforce limits on period and duration.

Alexandre Julliard julliard at winehq.org
Mon Dec 19 13:39:22 CST 2011


Module: wine
Branch: master
Commit: 38f9ba0070f9b72d8c94d8124b488921078f8018
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=38f9ba0070f9b72d8c94d8124b488921078f8018

Author: Jörg Höhle <hoehle at 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);




More information about the wine-cvs mailing list