Andrew Eikum : mmdevapi: Children of IAudioClient should hold a reference to their parents.

Alexandre Julliard julliard at winehq.org
Tue Jan 11 10:08:24 CST 2011


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

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon Jan 10 14:10:44 2011 -0600

mmdevapi: Children of IAudioClient should hold a reference to their parents.

---

 dlls/mmdevapi/audio.c        |   10 ++++
 dlls/mmdevapi/tests/render.c |  122 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 121 insertions(+), 11 deletions(-)

diff --git a/dlls/mmdevapi/audio.c b/dlls/mmdevapi/audio.c
index b97dccb..6217cba 100644
--- a/dlls/mmdevapi/audio.c
+++ b/dlls/mmdevapi/audio.c
@@ -1115,12 +1115,14 @@ static HRESULT AudioRenderClient_Create(ACImpl *parent, ACRender **ppv)
     This->lpVtbl = &ACRender_Vtbl;
     This->ref = 0;
     This->parent = parent;
+    AC_AddRef((IAudioClient*)This->parent);
     return S_OK;
 }
 
 static void AudioRenderClient_Destroy(ACRender *This)
 {
     This->parent->render = NULL;
+    AC_Release((IAudioClient*)This->parent);
     HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -1313,12 +1315,14 @@ static HRESULT AudioCaptureClient_Create(ACImpl *parent, ACCapture **ppv)
     This->lpVtbl = &ACCapture_Vtbl;
     This->ref = 0;
     This->parent = parent;
+    AC_AddRef((IAudioClient*)This->parent);
     return S_OK;
 }
 
 static void AudioCaptureClient_Destroy(ACCapture *This)
 {
     This->parent->capture = NULL;
+    AC_Release((IAudioClient*)This->parent);
     HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -1444,12 +1448,14 @@ static HRESULT AudioSessionControl_Create(ACImpl *parent, ACSession **ppv)
     This->lpVtbl = &ACSession_Vtbl;
     This->ref = 0;
     This->parent = parent;
+    AC_AddRef((IAudioClient*)This->parent);
     return S_OK;
 }
 
 static void AudioSessionControl_Destroy(ACSession *This)
 {
     This->parent->session = NULL;
+    AC_Release((IAudioClient*)This->parent);
     HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -1650,12 +1656,14 @@ static HRESULT AudioSimpleVolume_Create(ACImpl *parent, ASVolume **ppv)
     This->lpVtbl = &ASVolume_Vtbl;
     This->ref = 0;
     This->parent = parent;
+    AC_AddRef((IAudioClient*)This->parent);
     return S_OK;
 }
 
 static void AudioSimpleVolume_Destroy(ASVolume *This)
 {
     This->parent->svolume = NULL;
+    AC_Release((IAudioClient*)This->parent);
     HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -1756,12 +1764,14 @@ static HRESULT AudioClock_Create(ACImpl *parent, AClock **ppv)
     This->lp2Vtbl = &AClock2_Vtbl;
     This->ref = 0;
     This->parent = parent;
+    AC_AddRef((IAudioClient*)This->parent);
     return S_OK;
 }
 
 static void AudioClock_Destroy(AClock *This)
 {
     This->parent->clock = NULL;
+    AC_Release((IAudioClient*)This->parent);
     HeapFree(GetProcessHeap(), 0, This);
 }
 
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c
index 9661dbd..22e8c9b 100644
--- a/dlls/mmdevapi/tests/render.c
+++ b/dlls/mmdevapi/tests/render.c
@@ -34,6 +34,8 @@
 #include "mmdeviceapi.h"
 #include "audioclient.h"
 
+static IMMDevice *dev = NULL;
+
 static void test_uninitialized(IAudioClient *ac)
 {
     HRESULT hr;
@@ -70,15 +72,23 @@ static void test_uninitialized(IAudioClient *ac)
     CloseHandle(handle);
 }
 
-static void test_audioclient(IAudioClient *ac)
+static void test_audioclient(void)
 {
+    IAudioClient *ac;
     IUnknown *unk;
     HRESULT hr;
     ULONG ref;
     WAVEFORMATEX *pwfx, *pwfx2;
     REFERENCE_TIME t1, t2;
+    HANDLE handle;
 
-    HANDLE handle = CreateEventW(NULL, FALSE, FALSE, NULL);
+    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+            NULL, (void**)&ac);
+    ok(hr == S_OK, "Activation failed with %08x\n", hr);
+    if(hr != S_OK)
+        return;
+
+    handle = CreateEventW(NULL, FALSE, FALSE, NULL);
 
     hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL);
     ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr);
@@ -224,16 +234,110 @@ static void test_audioclient(IAudioClient *ac)
     hr = IAudioClient_Start(ac);
     ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
 
+    IAudioClient_Release(ac);
+
     CloseHandle(handle);
     CoTaskMemFree(pwfx);
 }
 
+static void test_references(void)
+{
+    IAudioClient *ac;
+    IAudioRenderClient *rc;
+    ISimpleAudioVolume *sav;
+    IAudioClock *acl;
+    WAVEFORMATEX *pwfx;
+    HRESULT hr;
+    ULONG ref;
+
+    /* IAudioRenderClient */
+    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+            NULL, (void**)&ac);
+    ok(hr == S_OK, "Activation failed with %08x\n", hr);
+    if(hr != S_OK)
+        return;
+
+    hr = IAudioClient_GetMixFormat(ac, &pwfx);
+    ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+    if(hr != S_OK)
+        return;
+
+    hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
+            0, pwfx, NULL);
+    ok(hr == S_OK, "Initialize failed: %08x\n", hr);
+
+    hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&rc);
+    ok(hr == S_OK, "GetService failed: %08x\n", hr);
+
+    IAudioRenderClient_AddRef(rc);
+    ref = IAudioRenderClient_Release(rc);
+    ok(ref != 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
+
+    ref = IAudioClient_Release(ac);
+    ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
+
+    ref = IAudioRenderClient_Release(rc);
+    ok(ref == 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
+
+    /* ISimpleAudioVolume */
+    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+            NULL, (void**)&ac);
+    ok(hr == S_OK, "Activation failed with %08x\n", hr);
+    if(hr != S_OK)
+        return;
+
+    hr = IAudioClient_GetMixFormat(ac, &pwfx);
+    ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+
+    hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
+            0, pwfx, NULL);
+    ok(hr == S_OK, "Initialize failed: %08x\n", hr);
+
+    hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
+    ok(hr == S_OK, "GetService failed: %08x\n", hr);
+
+    ISimpleAudioVolume_AddRef(sav);
+    ref = ISimpleAudioVolume_Release(sav);
+    ok(ref != 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
+
+    ref = IAudioClient_Release(ac);
+    ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
+
+    ref = ISimpleAudioVolume_Release(sav);
+    ok(ref == 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
+
+    /* IAudioClock */
+    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+            NULL, (void**)&ac);
+    ok(hr == S_OK, "Activation failed with %08x\n", hr);
+    if(hr != S_OK)
+        return;
+
+    hr = IAudioClient_GetMixFormat(ac, &pwfx);
+    ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+
+    hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
+            0, pwfx, NULL);
+    ok(hr == S_OK, "Initialize failed: %08x\n", hr);
+
+    hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
+    ok(hr == S_OK, "GetService failed: %08x\n", hr);
+
+    IAudioClock_AddRef(acl);
+    ref = IAudioClock_Release(acl);
+    ok(ref != 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
+
+    ref = IAudioClient_Release(ac);
+    ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
+
+    ref = IAudioClock_Release(acl);
+    ok(ref == 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
+}
+
 START_TEST(render)
 {
     HRESULT hr;
     IMMDeviceEnumerator *mme = NULL;
-    IMMDevice *dev = NULL;
-    IAudioClient *ac = NULL;
 
     CoInitializeEx(NULL, COINIT_MULTITHREADED);
     hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
@@ -254,13 +358,9 @@ START_TEST(render)
         goto cleanup;
     }
 
-    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac);
-    ok(hr == S_OK, "Activation failed with %08x\n", hr);
-    if (ac)
-    {
-        test_audioclient(ac);
-        IAudioClient_Release(ac);
-    }
+    test_audioclient();
+    test_references();
+
     IMMDevice_Release(dev);
 
 cleanup:




More information about the wine-cvs mailing list