Andrew Eikum : mmdevapi: Fix refcounts in IAudioClient::GetService.

Alexandre Julliard julliard at winehq.org
Mon Jun 20 14:24:07 CDT 2011


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

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon Jun 20 09:31:22 2011 -0500

mmdevapi: Fix refcounts in IAudioClient::GetService.

---

 dlls/winealsa.drv/mmdevdrv.c      |   16 ++++++++++++----
 dlls/winecoreaudio.drv/mmdevdrv.c |   26 ++++++++++++++++++--------
 dlls/wineoss.drv/mmdevdrv.c       |   16 ++++++++++++----
 3 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index b96e5f5..23f76e3 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -1666,16 +1666,20 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
             LeaveCriticalSection(&This->lock);
             return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
         }
+        IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface);
         *ppv = &This->IAudioRenderClient_iface;
     }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){
         if(This->dataflow != eCapture){
             LeaveCriticalSection(&This->lock);
             return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
         }
+        IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface);
         *ppv = &This->IAudioCaptureClient_iface;
     }else if(IsEqualIID(riid, &IID_IAudioClock)){
+        IAudioClock_AddRef(&This->IAudioClock_iface);
         *ppv = &This->IAudioClock_iface;
     }else if(IsEqualIID(riid, &IID_IAudioStreamVolume)){
+        IAudioStreamVolume_AddRef(&This->IAudioStreamVolume_iface);
         *ppv = &This->IAudioStreamVolume_iface;
     }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){
         if(!This->session_wrapper){
@@ -1684,7 +1688,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 LeaveCriticalSection(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface);
 
         *ppv = &This->session_wrapper->IAudioSessionControl2_iface;
     }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){
@@ -1694,7 +1699,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 LeaveCriticalSection(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface);
 
         *ppv = &This->session_wrapper->IChannelAudioVolume_iface;
     }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){
@@ -1704,13 +1710,13 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 LeaveCriticalSection(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface);
 
         *ppv = &This->session_wrapper->ISimpleAudioVolume_iface;
     }
 
     if(*ppv){
-        IUnknown_AddRef((IUnknown*)*ppv);
         LeaveCriticalSection(&This->lock);
         return S_OK;
     }
@@ -2245,6 +2251,8 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
     ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl;
     ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl;
 
+    ret->ref = 1;
+
     ret->client = client;
     if(client){
         ret->session = client->session;
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index fd5e5ad..fd3ed1b 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -1459,16 +1459,20 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
             OSSpinLockUnlock(&This->lock);
             return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
         }
+        IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface);
         *ppv = &This->IAudioRenderClient_iface;
     }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){
         if(This->dataflow != eCapture){
             OSSpinLockUnlock(&This->lock);
             return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
         }
+        IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface);
         *ppv = &This->IAudioCaptureClient_iface;
     }else if(IsEqualIID(riid, &IID_IAudioClock)){
+        IAudioClock_AddRef(&This->IAudioClock_iface);
         *ppv = &This->IAudioClock_iface;
     }else if(IsEqualIID(riid, &IID_IAudioStreamVolume)){
+        IAudioStreamVolume_AddRef(&This->IAudioStreamVolume_iface);
         *ppv = &This->IAudioStreamVolume_iface;
     }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){
         if(!This->session_wrapper){
@@ -1477,7 +1481,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 OSSpinLockUnlock(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface);
 
         *ppv = &This->session_wrapper->IAudioSessionControl2_iface;
     }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){
@@ -1487,7 +1492,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 OSSpinLockUnlock(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface);
 
         *ppv = &This->session_wrapper->IChannelAudioVolume_iface;
     }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){
@@ -1497,13 +1503,13 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 OSSpinLockUnlock(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface);
 
         *ppv = &This->session_wrapper->ISimpleAudioVolume_iface;
     }
 
     if(*ppv){
-        IUnknown_AddRef((IUnknown*)*ppv);
         OSSpinLockUnlock(&This->lock);
         return S_OK;
     }
@@ -2035,6 +2041,8 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
     ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl;
     ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl;
 
+    ret->ref = 1;
+
     ret->client = client;
     if(client){
         ret->session = client->session;
@@ -2082,10 +2090,12 @@ static ULONG WINAPI AudioSessionControl_Release(IAudioSessionControl2 *iface)
     ref = InterlockedDecrement(&This->ref);
     TRACE("(%p) Refcount now %u\n", This, ref);
     if(!ref){
-        OSSpinLockLock(&This->client->lock);
-        This->client->session_wrapper = NULL;
-        OSSpinLockUnlock(&This->client->lock);
-        AudioClient_Release(&This->client->IAudioClient_iface);
+        if(This->client){
+            OSSpinLockLock(&This->client->lock);
+            This->client->session_wrapper = NULL;
+            OSSpinLockUnlock(&This->client->lock);
+            AudioClient_Release(&This->client->IAudioClient_iface);
+        }
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c
index c6f561e..c8359a9 100644
--- a/dlls/wineoss.drv/mmdevdrv.c
+++ b/dlls/wineoss.drv/mmdevdrv.c
@@ -1381,16 +1381,20 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
             LeaveCriticalSection(&This->lock);
             return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
         }
+        IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface);
         *ppv = &This->IAudioRenderClient_iface;
     }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){
         if(This->dataflow != eCapture){
             LeaveCriticalSection(&This->lock);
             return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
         }
+        IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface);
         *ppv = &This->IAudioCaptureClient_iface;
     }else if(IsEqualIID(riid, &IID_IAudioClock)){
+        IAudioClock_AddRef(&This->IAudioClock_iface);
         *ppv = &This->IAudioClock_iface;
     }else if(IsEqualIID(riid, &IID_IAudioStreamVolume)){
+        IAudioStreamVolume_AddRef(&This->IAudioStreamVolume_iface);
         *ppv = &This->IAudioStreamVolume_iface;
     }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){
         if(!This->session_wrapper){
@@ -1399,7 +1403,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 LeaveCriticalSection(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface);
 
         *ppv = &This->session_wrapper->IAudioSessionControl2_iface;
     }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){
@@ -1409,7 +1414,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 LeaveCriticalSection(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface);
 
         *ppv = &This->session_wrapper->IChannelAudioVolume_iface;
     }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){
@@ -1419,13 +1425,13 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
                 LeaveCriticalSection(&This->lock);
                 return E_OUTOFMEMORY;
             }
-        }
+        }else
+            ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface);
 
         *ppv = &This->session_wrapper->ISimpleAudioVolume_iface;
     }
 
     if(*ppv){
-        IUnknown_AddRef((IUnknown*)*ppv);
         LeaveCriticalSection(&This->lock);
         return S_OK;
     }
@@ -1951,6 +1957,8 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
     ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl;
     ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl;
 
+    ret->ref = 1;
+
     ret->client = client;
     if(client){
         ret->session = client->session;




More information about the wine-cvs mailing list