James Hawkins wrote:
On Mon, 07 Feb 2005 12:37:15 -0500, Robert Reif reif@earthlink.net wrote:
James Hawkins wrote:
Hi,
Changelog
- Properly implement DllCanUnloadNow ref counting.
dsound.dll is a strange dll that doesn't really follow proper COM reference counting rules for buffers. This is intentional by Microsoft (don't know why) and was made common by the example code from "Inside Direct X" .
You may want to add a test to the dsound.dll regression tests to verify what Microsoft does.
I've been reading a lot about COM and trying to catch up, but I don't know exactly what I need to test. My guess for what you're looking for is to create some buffers and release them all the while keeping track of the ref count and when the dll can unload. Is this close to what is needed? Could you point me in the right direction concerning documentation (should I get "Inside Direct X") or examples for the tests. Thanks a lot.
Something like this is a start:
Only tested on wine but fails because of improper reference counting. The interesting thing will be what happens when a direct sound object is released while buffers are still active. The reference count goes to zero but can the DLL be unloaded? This needs to be tested on Windows to determine the correct behavior.
Index: dlls/dsound/tests/dsound8.c =================================================================== RCS file: /home/wine/wine/dlls/dsound/tests/dsound8.c,v retrieving revision 1.14 diff -u -r1.14 dsound8.c --- dlls/dsound/tests/dsound8.c 10 Jan 2005 12:25:56 -0000 1.14 +++ dlls/dsound/tests/dsound8.c 8 Feb 2005 00:51:43 -0000 @@ -37,6 +37,7 @@ #include "dsound_test.h"
static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL; +static HRESULT (WINAPI *pDllCanUnloadNow)(void)=NULL;
static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized, LPCGUID lpGuid) @@ -265,9 +266,17 @@ if (rc!=DS_OK) return rc;
+ /* Check if DLL can be unloaded now */ + rc=pDllCanUnloadNow(); + ok(rc==S_FALSE, "DllCanUnloadNow() returned %ld, should have returned %ld\n", rc, S_FALSE); + /* Try the enumerated device */ IDirectSound8_test(dso, TRUE, lpGuid);
+ /* Check if DLL can be unloaded now */ + rc=pDllCanUnloadNow(); + ok(rc==S_OK, "DllCanUnloadNow() returned %ld, should have returned %ld\n", rc, S_OK); + /* Try the COM class factory method of creation with enumerated device */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); @@ -356,6 +365,10 @@ } else return rc;
+ /* Check if DLL can be unloaded now */ + rc=pDllCanUnloadNow(); + ok(rc==S_OK, "DllCanUnloadNow() returned %ld, should have returned %ld\n", rc, S_OK); + return DS_OK; }
@@ -769,6 +782,7 @@ START_TEST(dsound8) { HMODULE hDsound; + HRESULT rc;
CoInitialize(NULL);
@@ -778,6 +792,14 @@ return; }
+ pDllCanUnloadNow = (void*)GetProcAddress(hDsound, "DllCanUnloadNow"); + ok(pDllCanUnloadNow!=NULL, "GetProcAddress(DllCanUnloadNow) failed\n"); + if (!pDllCanUnloadNow) + return; + + rc=pDllCanUnloadNow(); + ok(rc==S_OK, "DllCanUnloadNow() returned %ld, should have returned %ld\n", rc, S_OK); + pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8"); if (!pDirectSoundCreate8) { trace("dsound8 test skipped\n"); @@ -786,6 +808,9 @@
IDirectSound8_tests(); dsound8_tests(); + + rc=pDllCanUnloadNow(); + ok(rc==S_OK, "DllCanUnloadNow() returned %ld, should have returned %ld\n", rc, S_OK);
CoUninitialize(); }