[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-patches
Subject:    more DirectSound COM fixes
From:       Robert Reif <reif () earthlink ! net>
Date:       2003-08-30 17:19:41
[Download RAW message or body]

Fixes more COM issues.

Added SecondaryBuffer and DirectSoundCaptureNotify
COM objects to get reference counting right.

Added more tests and restructured tests for easier debugging.

This still needs at least one more refactoring pass to get
all the interfaces right but it works well as is.

["tests.diff" (application/x-unknown-content-type-diff_auto_file)]

diff -u wine.cvs/dlls/dsound/tests/dsound.c wine/dlls/dsound/tests/dsound.c
--- wine.cvs/dlls/dsound/tests/dsound.c	2003-08-16 15:35:50.000000000 -0400
+++ wine/dlls/dsound/tests/dsound.c	2003-08-30 12:52:54.000000000 -0400
@@ -396,6 +396,14 @@
 	    ref=IDirectSoundBuffer_Release(temp_buffer);
 	    ok(ref==1,"IDirectSoundBuffer_Release has %d references, should have 1\n",ref);
 
+#if 0	    /* FIXME: this works on windows */
+	    ref=IDirectSoundBuffer_Release(dsbo);
+	    ok(ref==0,"IDirectSoundBuffer_Release has %d references, should have 0\n",ref);
+
+	    rc=IDirectSound3DBuffer_QueryInterface(buffer, &IID_IDirectSoundBuffer,(LPVOID \
*)&dsbo); +	    ok(rc==DS_OK&&dsbo!=NULL,"IDirectSound3DBuffer_QueryInterface failed: \
0x%lx\n",rc); +#endif
+
 	    /* DSOUND: Error: Invalid buffer */
 	    rc=IDirectSound3DBuffer_GetAllParameters(buffer,0);
 	    ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters failed: \
0x%lx\n",rc); @@ -441,7 +449,6 @@
 	ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING),
 	   "GetStatus: bad status: %lx",status);
 
-	/* FIXME: set position here someday */
 	if (listener) {
 	    ZeroMemory(&listener_param,sizeof(listener_param));
 	    listener_param.dwSize=sizeof(listener_param);
@@ -469,7 +476,6 @@
 
 	while (buffer_service(&state)) {
 	    WaitForSingleObject(GetCurrentProcess(),TIME_SLICE/2);
-	    /* FIXME: move positions here someday */
 	    if (listener&&move_listener) {
 		listener_param.vPosition.u1.x += 0.5;
 		rc=IDirectSound3DListener_SetPosition(listener,listener_param.vPosition.u1.x,listener_param.vPosition.u2.y,listener_param.vPosition.u3.z,DS3D_IMMEDIATE);
 @@ -501,23 +507,48 @@
     }
 }
 
-static void test_secondary(LPDIRECTSOUND dso, 
-			   int play, int has_3dbuffer, 
-			   int has_listener, int has_duplicate, 
-			   int move_listener, int move_sound)
+static HRESULT test_secondary(LPGUID lpGuid, int play, 
+			      int has_3d, int has_3dbuffer, 
+			      int has_listener, int has_duplicate, 
+			      int move_listener, int move_sound)
 {
     HRESULT rc;
+    LPDIRECTSOUND dso=NULL;
     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
     LPDIRECTSOUND3DLISTENER listener=NULL;
     DSBUFFERDESC bufdesc;
+    DSCAPS dscaps;
     WAVEFORMATEX wfx;
     int f,ref;
 
+    /* Create the DirectSound object */
+    rc=DirectSoundCreate(lpGuid,&dso,NULL);
+    ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+	return rc;
+
+    /* Get the device capabilities */
+    ZeroMemory(&dscaps, sizeof(dscaps));
+    dscaps.dwSize=sizeof(dscaps);
+    rc=IDirectSound_GetCaps(dso,&dscaps);
+    ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+        goto EXIT;
+
+	/* We must call SetCooperativeLevel before creating primary buffer */
+	/* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
+	rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
+	ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
+	if(rc!=DS_OK)
+	    goto EXIT;
+
     ZeroMemory(&bufdesc, sizeof(bufdesc));
     bufdesc.dwSize=sizeof(bufdesc);
     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
+    if (has_3d)
+    	bufdesc.dwFlags|=DSBCAPS_CTRL3D;
     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
-    ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary \
buffer 0x%lx\n",rc); +    ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to \
create a %sprimary buffer 0x%lx\n",has_3d?"3D ":"", rc);  if \
(rc==DS_OK&&primary!=NULL) {  if (has_listener) {
 	    rc=IDirectSoundBuffer_QueryInterface(primary,&IID_IDirectSound3DListener,(void \
**)&listener); @@ -539,7 +570,7 @@
 		rc=IDirectSound3DListener_GetAllParameters(listener,&listener_param);
 		ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters failed 0x%lx\n",rc);
 	    } else
-		return;
+		goto EXIT;
 	} 
 
 	for (f=0;f<NB_FORMATS;f++) {
@@ -548,6 +579,8 @@
 	    ZeroMemory(&bufdesc, sizeof(bufdesc));
 	    bufdesc.dwSize=sizeof(bufdesc);
 	    bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRL3D;
+	    if (has_3d)
+	        bufdesc.dwFlags|=DSBCAPS_CTRL3D;
 	    bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
 	    bufdesc.lpwfxFormat=&wfx;
 	    trace("  Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d\n",
@@ -602,29 +635,37 @@
 	    ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have \
0\n",ref);  }
     }
+	/* Set the CooperativeLevel back to normal */
+	/* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
+	rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
+	ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
+
+EXIT:
+    ref=IDirectSound_Release(dso);
+    ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+    if (ref!=0)
+	return DSERR_GENERIC;
+
+    return rc;
 }
 
-static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
-				   LPCSTR lpcstrModule, LPVOID lpContext)
+static HRESULT test_dsound(LPGUID lpGuid)
 {
     HRESULT rc;
     LPDIRECTSOUND dso=NULL;
-    LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL,duplicated=NULL;
-    DSBUFFERDESC bufdesc;
-    WAVEFORMATEX wfx;
     DSCAPS dscaps;
-    int f,ref;
-
-    trace("Testing %s - %s\n",lpcstrDescription,lpcstrModule);
+    DWORD speaker_config, new_speaker_config;
+    int ref;
 
     /* DSOUND: Error: Invalid interface buffer */
     rc=DirectSoundCreate(lpGuid,0,NULL);
     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate should have failed: 0x%lx\n",rc);
 
+    /* Create the DirectSound object */
     rc=DirectSoundCreate(lpGuid,&dso,NULL);
     ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
     if (rc!=DS_OK)
-	goto EXIT;
+	return rc;
 
     /* DSOUND: Error: Invalid caps buffer */
     rc=IDirectSound_GetCaps(dso,0);
@@ -647,6 +688,84 @@
 	      dscaps.dwMaxSecondarySampleRate);
     }
 
+    rc=IDirectSound_GetSpeakerConfig(dso,0);
+    ok(rc==DSERR_INVALIDPARAM,"GetSpeakerConfig should have failed: 0x%lx\n",rc);
+
+    rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config);
+    ok(rc==DS_OK,"GetSpeakerConfig failed: 0x%lx\n",rc);
+    if (rc==DS_OK) {
+	trace("  DirectSound SpeakerConfig: 0x%08lx\n", speaker_config);
+    }
+ 
+    speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,DSSPEAKER_GEOMETRY_WIDE);
+    rc=IDirectSound_SetSpeakerConfig(dso,speaker_config);
+    ok(rc==DS_OK,"SetSpeakerConfig failed: 0x%lx\n",rc);
+    if (rc==DS_OK) {
+	rc=IDirectSound_GetSpeakerConfig(dso,&new_speaker_config);
+	ok(rc==DS_OK,"GetSpeakerConfig failed: 0x%lx\n",rc);
+	if (rc==DS_OK)
+	    ok(speaker_config==new_speaker_config,"SetSpeakerConfig failed to set speaker \
config: expected 0x%08lx, got 0x%08lx\n", +		speaker_config,new_speaker_config);
+    }
+
+    /* Release the DirectSound object */
+    ref=IDirectSound_Release(dso);
+    ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+    if (ref!=0)
+	return DSERR_GENERIC; 
+
+#if 0	/* FIXME: this works on windows */ 
+    /* Create a DirectSound object */
+    rc=DirectSoundCreate(lpGuid,&dso,NULL);
+    ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+    if (rc==DS_OK) {
+	LPDIRECTSOUND dso1=NULL;
+
+	/* Create a second DirectSound object */
+	rc=DirectSoundCreate(lpGuid,&dso1,NULL);
+	ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+	if (rc==DS_OK) {
+	    /* Release the second DirectSound object */
+	    ref=IDirectSound_Release(dso1);
+	    ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+	    ok(dso!=dso1,"DirectSound objects should be unique: \
dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1); +	}
+
+	/* Release the first DirectSound object */
+	ref=IDirectSound_Release(dso);
+	ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+	if (ref!=0)
+	    return DSERR_GENERIC; 
+    } else
+	return rc;
+#endif
+
+    return DS_OK;
+}
+
+static HRESULT test_primary(LPGUID lpGuid)
+{
+    HRESULT rc;
+    LPDIRECTSOUND dso=NULL;
+    LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
+    DSBUFFERDESC bufdesc;
+    DSCAPS dscaps;
+    int ref;
+
+    /* Create the DirectSound object */
+    rc=DirectSoundCreate(lpGuid,&dso,NULL);
+    ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+	return rc;
+
+    /* Get the device capabilities */
+    ZeroMemory(&dscaps, sizeof(dscaps));
+    dscaps.dwSize=sizeof(dscaps);
+    rc=IDirectSound_GetCaps(dso,&dscaps);
+    ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+        goto EXIT;
+
     /* DSOUND: Error: Invalid buffer description pointer */
     rc=IDirectSound_CreateSoundBuffer(dso,0,0,NULL);
     ok(rc==DSERR_INVALIDPARAM,"CreateSoundBuffer should have failed: 0x%lx\n",rc);
@@ -678,23 +797,73 @@
     ZeroMemory(&bufdesc, sizeof(bufdesc));
     bufdesc.dwSize=sizeof(bufdesc);
     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
-    trace("  Testing the primary buffer\n");
     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
     ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a primary \
buffer: 0x%lx\n",rc);  if (rc==DS_OK&&primary!=NULL) {
+	/* Try to create a second primary buffer */
+	/* DSOUND: Error: The primary buffer already exists.  Any changes made to the \
buffer description will be ignored. */ \
+	rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&second,NULL); \
+	ok(rc==DS_OK&&second==primary,"CreateSoundBuffer should have returned original \
primary buffer: 0x%lx\n",rc); +	ref=IDirectSoundBuffer_Release(second);
+	ok(ref==1,"IDirectSoundBuffer_Release primary has %d references, should have \
1\n",ref);  +	/* Try to duplicate a primary buffer */
+	/* DSOUND: Error: Can't duplicate primary buffers */
+	rc=IDirectSound_DuplicateSoundBuffer(dso,primary,&third);
+	/* rc=0x88780032 */
+	ok(rc!=DS_OK,"IDirectSound_DuplicateSoundBuffer primary buffer should have failed \
0x%lx\n",rc);  test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & \
DSCAPS_EMULDRIVER),0,0,0,0);  ref=IDirectSoundBuffer_Release(primary);
 	ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have \
0\n",ref);   }
+    /* Set the CooperativeLevel back to normal */
+    /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
+    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
+    ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
 
-    /* Testing 3D primary buffer */
+EXIT:
+    ref=IDirectSound_Release(dso);
+    ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+    if (ref!=0)
+	return DSERR_GENERIC;
+
+    return rc;
+}
+
+static HRESULT test_primary_3d(LPGUID lpGuid)
+{
+    HRESULT rc;
+    LPDIRECTSOUND dso=NULL;
+    LPDIRECTSOUNDBUFFER primary=NULL;
+    DSBUFFERDESC bufdesc;
+    DSCAPS dscaps;
+    int ref;
+
+    /* Create the DirectSound object */
+    rc=DirectSoundCreate(lpGuid,&dso,NULL);
+    ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+	return rc;
+
+    /* Get the device capabilities */
+    ZeroMemory(&dscaps, sizeof(dscaps));
+    dscaps.dwSize=sizeof(dscaps);
+    rc=IDirectSound_GetCaps(dso,&dscaps);
+    ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+        goto EXIT;
+
+    /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
+    /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
+    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
+    ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+	goto EXIT;
     primary=NULL;
     ZeroMemory(&bufdesc, sizeof(bufdesc));
     bufdesc.dwSize=sizeof(bufdesc);
     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
-    trace("  Testing 3D primary buffer\n");
     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
-    ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary \
buffer: 0x%lx\n",rc); +    ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to \
create a primary buffer: 0x%lx\n",rc);  if (rc==DS_OK&&primary!=NULL) {
 	ref=IDirectSoundBuffer_Release(primary);
 	ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have \
0\n",ref);  @@ -710,44 +879,53 @@
 	    ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have \
0\n",ref);   }
     }
+    /* Set the CooperativeLevel back to normal */
+    /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
+    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
+    ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
 
-    /* Testing the primary buffer with listener */
-    primary=NULL;
-    ZeroMemory(&bufdesc, sizeof(bufdesc));
-    bufdesc.dwSize=sizeof(bufdesc);
-    bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
-    trace("  Testing 3D primary buffer\n");
-    rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
-    ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary \
                buffer: 0x%lx\n",rc);
-    if (rc==DS_OK&&primary!=NULL) {
-	ref=IDirectSoundBuffer_Release(primary);
-	ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have \
                0\n",ref); 
-        primary=NULL;
-        ZeroMemory(&bufdesc, sizeof(bufdesc));
-        bufdesc.dwSize=sizeof(bufdesc);
-        bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
-        rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
-        ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary \
                buffer: 0x%lx\n",rc);
-        if (rc==DS_OK&&primary!=NULL) {
-	    LPDIRECTSOUND3DLISTENER listener=NULL;
-	    rc=IDirectSoundBuffer_QueryInterface(primary,&IID_IDirectSound3DListener,(void \
                **)&listener);
-	    ok(rc==DS_OK&&listener!=NULL,"IDirectSoundBuffer_QueryInterface failed to get a \
                3D listener 0x%lx\n",rc);
-	    if (rc==DS_OK&&listener) {
-	        test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & \
                DSCAPS_EMULDRIVER),0,listener,0,0);
-	        ref=IDirectSound3DListener_Release(listener);
-	        ok(ref==0,"IDirectSound3DListener_Release listener has %d references, \
                should have 0\n",ref);
-	    }
-	    ref=IDirectSoundBuffer_Release(primary);
-	    ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have \
                0\n",ref); 
-	}
-    }
+EXIT:
+    ref=IDirectSound_Release(dso);
+    ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+    if (ref!=0)
+	return DSERR_GENERIC;
+
+    return rc;
+}
+
+static HRESULT test_primary_3d_with_listener(LPGUID lpGuid)
+{
+    HRESULT rc;
+    LPDIRECTSOUND dso=NULL;
+    LPDIRECTSOUNDBUFFER primary=NULL;
+    DSBUFFERDESC bufdesc;
+    DSCAPS dscaps;
+    int ref;
+
+    /* Create the DirectSound object */
+    rc=DirectSoundCreate(lpGuid,&dso,NULL);
+    ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+	return rc;
+
+    /* Get the device capabilities */
+    ZeroMemory(&dscaps, sizeof(dscaps));
+    dscaps.dwSize=sizeof(dscaps);
+    rc=IDirectSound_GetCaps(dso,&dscaps);
+    ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+        goto EXIT;
 
-    /* Testing 3D primary buffer with listener */
+    /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
+    /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
+    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
+    ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
+    if (rc!=DS_OK)
+	goto EXIT;
     primary=NULL;
     ZeroMemory(&bufdesc, sizeof(bufdesc));
     bufdesc.dwSize=sizeof(bufdesc);
     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
-    trace("  Testing 3D primary buffer with listener\n");
     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
     ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary \
buffer 0x%lx\n",rc);  if (rc==DS_OK&&primary!=NULL) {
@@ -786,92 +964,52 @@
 	ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have \
0\n",ref);   }
 
-    /* Set the CooperativeLevel back to normal */
-    /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
-    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
-    ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
-    if (rc!=DS_OK)
-	goto EXIT;
+EXIT:
+    ref=IDirectSound_Release(dso);
+    ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+    if (ref!=0)
+	return DSERR_GENERIC;
 
-    /* Testing secondary buffers */
-    for (f=0;f<NB_FORMATS;f++) {
-	init_format(&wfx,formats[f][0],formats[f][1],formats[f][2]);
-	secondary=NULL;
-	ZeroMemory(&bufdesc, sizeof(bufdesc));
-	bufdesc.dwSize=sizeof(bufdesc);
-	bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
-	bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
-	bufdesc.lpwfxFormat=&wfx;
-	trace("  Testing a secondary buffer at %ldx%dx%d\n",
-	    wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
-	rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
-	ok(rc==DS_OK&&secondary!=NULL,"CreateSoundBuffer failed to create a secondary \
                buffer 0x%lx\n",rc);
-	if (rc==DS_OK&&secondary!=NULL) {
-	    test_buffer(dso,secondary,0,winetest_interactive,0,0,0,0);
-	    ref=IDirectSoundBuffer_Release(secondary);
-	    ok(ref==0,"IDirectSoundBuffer_Release secondary has %d references, should have \
                0\n",ref); 
-	}
-    }
+    return rc;
+}
 
-    /* Testing duplicated secondary buffers */
-    for (f=0;f<NB_FORMATS;f++) {
-	init_format(&wfx,formats[f][0],formats[f][1],formats[f][2]);
-	secondary=NULL;
-	ZeroMemory(&bufdesc, sizeof(bufdesc));
-	bufdesc.dwSize=sizeof(bufdesc);
-	bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
-	bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
-	bufdesc.lpwfxFormat=&wfx;
-	trace("  Testing a duplicated secondary buffer at %ldx%dx%d\n",
-	    wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
-	rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
-	ok(rc==DS_OK&&secondary!=NULL,"CreateSoundBuffer failed to create a secondary \
                buffer 0x%lx\n",rc);
-	if(rc==DS_OK&&secondary!=NULL) {
-	    /* DSOUND: Error: Invalid source buffer */
-	    rc=IDirectSound_DuplicateSoundBuffer(dso,0,0);
-	    ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed \
                0x%lx\n",rc);
-
-	    /* DSOUND: Error: Invalid dest buffer */
-	    rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,0);
-	    ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed \
                0x%lx\n",rc);
-
-	    /* DSOUND: Error: Invalid source buffer */
-	    rc=IDirectSound_DuplicateSoundBuffer(dso,0,&duplicated);
-	    ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed \
                0x%lx\n",rc);
-
-	    duplicated=NULL;
-	    rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,&duplicated);
-	    ok(rc==DS_OK&&duplicated!=NULL,"IDirectSound_DuplicateSoundBuffer failed to \
duplicate a secondary buffer 0x%lx\n",rc); +static BOOL WINAPI dsenum_callback(LPGUID \
lpGuid, LPCSTR lpcstrDescription, +				   LPCSTR lpcstrModule, LPVOID lpContext)
+{
+    HRESULT rc;
 
-	    ref=IDirectSoundBuffer_Release(secondary);
-	    ok(ref==0,"IDirectSoundBuffer_Release secondary has %d references, should have \
0\n",ref);  +    trace("Testing %s - %s\n",lpcstrDescription,lpcstrModule);
+    rc=test_dsound(lpGuid);
+    ok(rc==DS_OK,"DirectSound test failed\n");
+   
+    trace("  Testing the primary buffer\n");
+    rc=test_primary(lpGuid);
+    ok(rc==DS_OK,"Primary Buffer test failed\n");
 
-	    if (rc==DS_OK&&duplicated!=NULL) {
-		test_buffer(dso,duplicated,0,winetest_interactive,0,0,0,0);
+    trace("  Testing 3D primary buffer\n");
+    rc=test_primary_3d(lpGuid);
+    ok(rc==DS_OK,"3D Primary Buffer test failed\n");
 
-		ref=IDirectSoundBuffer_Release(duplicated);
-		ok(ref==0,"IDirectSoundBuffer_Release duplicated has %d references, should have \
                0\n",ref); 
-	    }
-	}
-    }
+    trace("  Testing 3D primary buffer with listener\n");
+    rc=test_primary_3d_with_listener(lpGuid);
+    ok(rc==DS_OK,"3D Primary Buffer with listener test failed\n");
+
+    /* Testing secondary buffers */
+    test_secondary(lpGuid,winetest_interactive,0,0,0,0,0,0);
+    test_secondary(lpGuid,winetest_interactive,0,0,0,1,0,0);
 
     /* Testing 3D secondary buffers */
-    test_secondary(dso,winetest_interactive,0,0,0,0,0);
-    test_secondary(dso,winetest_interactive,1,0,0,0,0);
-    test_secondary(dso,winetest_interactive,1,0,1,0,0);
-    test_secondary(dso,winetest_interactive,0,1,0,0,0);
-    test_secondary(dso,winetest_interactive,0,1,1,0,0);
-    test_secondary(dso,winetest_interactive,1,1,0,0,0);
-    test_secondary(dso,winetest_interactive,1,1,1,0,0);
-    test_secondary(dso,winetest_interactive,1,1,0,1,0);
-    test_secondary(dso,winetest_interactive,1,1,0,0,1);
-    test_secondary(dso,winetest_interactive,1,1,0,1,1);
+    test_secondary(lpGuid,winetest_interactive,1,0,0,0,0,0);
+    test_secondary(lpGuid,winetest_interactive,1,1,0,0,0,0);
+    test_secondary(lpGuid,winetest_interactive,1,1,0,1,0,0);
+    test_secondary(lpGuid,winetest_interactive,1,0,1,0,0,0);
+    test_secondary(lpGuid,winetest_interactive,1,0,1,1,0,0);
+    test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,0);
+    test_secondary(lpGuid,winetest_interactive,1,1,1,1,0,0);
+    test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,0);
+    test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,1);
+    test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,1);
 
-EXIT:
-    if (dso!=NULL) {
-	ref=IDirectSound_Release(dso);
-	ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
-    }
     return 1;
 }
 


["dsound.diff" (application/x-unknown-content-type-diff_auto_file)]

diff -u wine.cvs/dlls/dsound/buffer.c wine/dlls/dsound/buffer.c
--- wine.cvs/dlls/dsound/buffer.c	2003-08-21 08:00:35.000000000 -0400
+++ wine/dlls/dsound/buffer.c	2003-08-30 12:07:05.000000000 -0400
@@ -58,23 +58,12 @@
 	ICOM_THIS(IDirectSoundNotifyImpl,iface);
 	TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
 
-	if (ppobj == NULL) {
+	if (This->dsb == NULL) {
 		WARN("invalid parameter\n");
 		return E_INVALIDARG;
 	}
 
-	*ppobj = NULL;	/* assume error */
-
-	if ( IsEqualGUID(riid, &IID_IUnknown) || 
-	     IsEqualGUID(riid, &IID_IDirectSoundNotify) ||
-	     IsEqualGUID(riid, &IID_IDirectSoundNotify8) ) {
-		IDirectSoundNotify_AddRef(iface);
-		*ppobj = This;
-		return DS_OK;
-	}
-
-	FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
-	return E_NOINTERFACE;
+	return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER)This->dsb, riid, \
ppobj);;  }
 
 static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface) {
@@ -94,14 +83,11 @@
 	TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
 
 	ref = InterlockedDecrement(&(This->ref));
-	/* FIXME: A notification should be a part of a buffer rather than pointed 
-	 * to from a buffer. Hence the -1 ref count */
-	if (ref == -1) {
-		if (This->notifies != NULL)
-			HeapFree(GetProcessHeap(), 0, This->notifies);
-
+	if (ref == 0) {
+		IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER)This->dsb);
+		This->dsb->notify = NULL;
 		HeapFree(GetProcessHeap(),0,This);
-		return 0;
+		TRACE("(%p) released\n",This);
 	}
 	return ref;
 }
@@ -124,23 +110,23 @@
 		    notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
 	}
 
-	if (This->hwnotify) {
+	if (This->dsb->hwnotify) {
 	    HRESULT hres;
-	    hres = IDsDriverNotify_SetNotificationPositions(This->hwnotify, howmuch, \
notify); +	    hres = IDsDriverNotify_SetNotificationPositions(This->dsb->hwnotify, \
howmuch, notify);  if (hres != DS_OK)
 		    WARN("IDsDriverNotify_SetNotificationPositions failed\n");
 	    return hres;
 	} else {
 	    /* Make an internal copy of the caller-supplied array.
 	     * Replace the existing copy if one is already present. */
-	    This->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
-	        This->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
-	    if (This->notifies == NULL) {
+	    This->dsb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
+	        This->dsb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
+	    if (This->dsb->notifies == NULL) {
 		    WARN("out of memory\n");
 		    return DSERR_OUTOFMEMORY;
 	    }
-	    memcpy(This->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
-	    This->nrofnotifies = howmuch;
+	    memcpy(This->dsb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
+	    This->dsb->nrofnotifies = howmuch;
 	}
 
 	return S_OK;
@@ -148,13 +134,37 @@
 
 ICOM_VTABLE(IDirectSoundNotify) dsnvt =
 {
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IDirectSoundNotifyImpl_QueryInterface,
-	IDirectSoundNotifyImpl_AddRef,
-	IDirectSoundNotifyImpl_Release,
-	IDirectSoundNotifyImpl_SetNotificationPositions,
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirectSoundNotifyImpl_QueryInterface,
+    IDirectSoundNotifyImpl_AddRef,
+    IDirectSoundNotifyImpl_Release,
+    IDirectSoundNotifyImpl_SetNotificationPositions,
 };
 
+HRESULT WINAPI IDirectSoundNotifyImpl_Create(
+    IDirectSoundBufferImpl * dsb,
+    IDirectSoundNotifyImpl **pdsn)
+{
+    IDirectSoundNotifyImpl * dsn;
+    TRACE("(%p,%p)\n",dsb,pdsn);
+                                                                                     \
 +    dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, \
sizeof(dsn)); +                                                                       \
 +    if (dsn == NULL) {
+        WARN("out of memory\n");
+        return DSERR_OUTOFMEMORY;
+    }
+
+    dsn->ref = 0;
+    dsn->lpVtbl = &dsnvt;
+    dsn->dsb = dsb;
+    dsb->notify = dsn;
+    IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
+                                                                                     \
 +    *pdsn = dsn;
+    return DS_OK;
+}
+                                                                                     \
  /*******************************************************************************
  *		IDirectSoundBuffer
  */
@@ -361,7 +371,6 @@
 	for (i=0;i<This->dsound->nrofbuffers;i++)
 		if (This->dsound->buffers[i] == This)
 			break;
-
 	if (i < This->dsound->nrofbuffers) {
 		/* Put the last buffer of the list in the (now empty) position */
 		This->dsound->buffers[i] = This->dsound->buffers[This->dsound->nrofbuffers - 1];
@@ -401,8 +410,12 @@
 	if (This->iks)
 		IKsPropertySet_Release((LPKSPROPERTYSET)This->iks);
 
+	if (This->notifies != NULL)
+		HeapFree(GetProcessHeap(), 0, This->notifies);
+
 	HeapFree(GetProcessHeap(),0,This);
 
+	TRACE("(%p) released\n",This);
 	return 0;
 }
 
@@ -920,24 +933,24 @@
 	if ( IsEqualGUID(riid, &IID_IUnknown) || 
 	     IsEqualGUID(riid, &IID_IDirectSoundBuffer) || 
 	     IsEqualGUID(riid, &IID_IDirectSoundBuffer8) ) {
-		IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This);
-		*ppobj = This;
-		return S_OK;
+		if (!This->dsb)
+			SecondaryBufferImpl_Create(This, &(This->dsb));
+		if (This->dsb) {
+			IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This->dsb);
+			*ppobj = This->dsb;
+			return S_OK;
+		}
+		WARN("IID_IDirectSoundBuffer\n");
+		return E_NOINTERFACE;;
 	}
 
 	if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ||
 	     IsEqualGUID( &IID_IDirectSoundNotify8, riid ) ) {
-		if (!This->notify) {
-			This->notify = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),
-				HEAP_ZERO_MEMORY,sizeof(*This->notify));
-			if (This->notify) {
-				This->notify->ref = 0;	/* release when ref == -1 */
-				This->notify->lpVtbl = &dsnvt;
-			}
-		}
+		if (!This->notify)
+			IDirectSoundNotifyImpl_Create(This, &(This->notify));
 		if (This->notify) {
 			IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify);
-			*ppobj = (LPVOID)This->notify;
+			*ppobj = This->notify;
 			return S_OK;
 		}
 		WARN("IID_IDirectSoundNotify\n");
@@ -946,10 +959,10 @@
 
 	if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
 		if (!This->ds3db)
-			IDirectSound3DBufferImpl_Create(This, &This->ds3db);
-		*ppobj = This->ds3db;
-		if (*ppobj) {
-			IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)*ppobj);
+			IDirectSound3DBufferImpl_Create(This, &(This->ds3db));
+		if (This->ds3db) {
+			IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)This->ds3db);
+			*ppobj = This->ds3db;
 			return S_OK;
 		}
 		WARN("IID_IDirectSound3DBuffer\n");
@@ -965,13 +978,12 @@
 		/* only supported on hardware 3D secondary buffers */
 		if (!(This->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) && 
 		     (This->dsbd.dwFlags & DSBCAPS_CTRL3D) && 
-		     (This->dsbd.dwFlags & DSBCAPS_LOCHARDWARE) &&
 		     (This->hwbuf != NULL) ) {
 			if (!This->iks)
-				IKsBufferPropertySetImpl_Create(This, &This->iks);
-		    	*ppobj = This->iks;
-			if (*ppobj) {
+				IKsBufferPropertySetImpl_Create(This, &(This->iks));
+			if (This->iks) {
 				IKsPropertySet_AddRef((LPKSPROPERTYSET)*ppobj);
+		    		*ppobj = This->iks;
 				return S_OK;
 			}
 		}
@@ -1013,8 +1025,8 @@
 	IDirectSoundBufferImpl_GetObjectInPath
 };
 
-HRESULT WINAPI SecondaryBuffer_Create(
-	IDirectSoundImpl *This,
+HRESULT WINAPI IDirectSoundBufferImpl_Create(
+	IDirectSoundImpl *ds,
 	IDirectSoundBufferImpl **pdsb,
 	LPDSBUFFERDESC dsbd)
 {
@@ -1023,6 +1035,7 @@
 	HRESULT err = DS_OK;
 	DWORD capf = 0;
 	int use_hw;
+	TRACE("(%p,%p,%p)\n",ds,pdsb,dsbd);
 
 	if (dsbd->dwBufferBytes < DSBSIZE_MIN || dsbd->dwBufferBytes > DSBSIZE_MAX) {
 		WARN("invalid parameter: dsbd->dwBufferBytes = %ld\n", dsbd->dwBufferBytes);
@@ -1038,7 +1051,8 @@
 		return DSERR_OUTOFMEMORY;
 	}
 	dsb->ref = 0;
-	dsb->dsound = This;
+	dsb->dsb = 0;
+	dsb->dsound = ds;
 	dsb->lpVtbl = &dsbvt;
 
 	memcpy(&dsb->dsbd, dsbd, sizeof(*dsbd));
@@ -1050,12 +1064,17 @@
 	dsb->buflen = dsbd->dwBufferBytes;
 	dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec;
 
+	dsb->notify = NULL;
+	dsb->notifies = NULL;
+	dsb->nrofnotifies = 0;
+	dsb->hwnotify = 0;
+
 	/* Check necessary hardware mixing capabilities */
 	if (wfex->nChannels==2) capf |= DSCAPS_SECONDARYSTEREO;
 	else capf |= DSCAPS_SECONDARYMONO;
 	if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT;
 	else capf |= DSCAPS_SECONDARY8BIT;
-	use_hw = (This->drvcaps.dwFlags & capf) == capf;
+	use_hw = (ds->drvcaps.dwFlags & capf) == capf;
 
 	/* FIXME: check hardware sample rate mixing capabilities */
 	/* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) \
*/ @@ -1063,7 +1082,7 @@
 	/* FIXME: handle DSDHEAP_CREATEHEAP for hardware buffers */
 
 	/* Allocate system memory if applicable */
-	if ((This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) {
+	if ((ds->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) {
 		dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
 		if (dsb->buffer == NULL) {
 			WARN("out of memory\n");
@@ -1084,7 +1103,7 @@
 
 	/* Allocate the hardware buffer */
 	if (use_hw) {
-		err = IDsDriver_CreateSoundBuffer(This->driver,wfex,dsbd->dwFlags,0,
+		err = IDsDriver_CreateSoundBuffer(ds->driver,wfex,dsbd->dwFlags,0,
 						  &(dsb->buflen),&(dsb->buffer->memory),
 						  (LPVOID*)&(dsb->hwbuf));
 		if (err != DS_OK) {
@@ -1109,7 +1128,7 @@
 	dsb->state = STATE_STOPPED;
 
 	dsb->freqAdjust = (dsb->freq << DSOUND_FREQSHIFT) /
-		This->wfx.nSamplesPerSec;
+		ds->wfx.nSamplesPerSec;
 	dsb->nAvgBytesPerSec = dsb->freq *
 		dsbd->lpwfxFormat->nBlockAlign;
 
@@ -1139,29 +1158,312 @@
 	InitializeCriticalSection(&(dsb->lock));
 
 	/* register buffer */
-	RtlAcquireResourceExclusive(&(This->lock), TRUE);
+	RtlAcquireResourceExclusive(&(ds->lock), TRUE);
 	if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
-		IDirectSoundBufferImpl **newbuffers = \
(IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl*)*(This->nrofbuffers+1));
 +		IDirectSoundBufferImpl **newbuffers = \
(IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,ds->buffers,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
  if (newbuffers) {
-			This->buffers = newbuffers;
-			This->buffers[This->nrofbuffers] = dsb;
-			This->nrofbuffers++;
-			TRACE("buffer count is now %d\n", This->nrofbuffers);
+			ds->buffers = newbuffers;
+			ds->buffers[ds->nrofbuffers] = dsb;
+			ds->nrofbuffers++;
+			TRACE("buffer count is now %d\n", ds->nrofbuffers);
 		} else {
-			ERR("out of memory for buffer list! Current buffer count is %d\n", \
This->nrofbuffers); +			ERR("out of memory for buffer list! Current buffer count is \
%d\n", ds->nrofbuffers);  if (dsb->buffer->memory)
 				HeapFree(GetProcessHeap(),0,dsb->buffer->memory);
 			if (dsb->buffer)
 				HeapFree(GetProcessHeap(),0,dsb->buffer);
 			DeleteCriticalSection(&(dsb->lock));
-			RtlReleaseResource(&(This->lock));
+			RtlReleaseResource(&(ds->lock));
 			HeapFree(GetProcessHeap(),0,dsb);
 			*pdsb = NULL;
 			return DSERR_OUTOFMEMORY;
 		}
 	}
-	RtlReleaseResource(&(This->lock));
-	IDirectSound8_AddRef((LPDIRECTSOUND8)This);
+	RtlReleaseResource(&(ds->lock));
+	IDirectSound8_AddRef((LPDIRECTSOUND8)ds);
 	*pdsb = dsb;
 	return S_OK;
 }
+
+/*******************************************************************************
+ *		SecondaryBuffer
+ */
+
+static HRESULT WINAPI SecondaryBufferImpl_QueryInterface(
+	LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj) 
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+
+	return IDirectSoundBufferImpl_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb,riid,ppobj);
 +}
+
+static DWORD WINAPI SecondaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface)
+{
+	ICOM_THIS(IDirectSoundBufferImpl,iface);
+	DWORD ref;
+	TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
+
+	ref = InterlockedIncrement(&(This->ref));
+	if (!ref) {
+		FIXME("thread-safety alert! AddRef-ing with a zero refcount!\n");
+	}
+	return ref;
+}
+
+static DWORD WINAPI SecondaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface)
+{
+	ICOM_THIS(IDirectSoundBufferImpl,iface);
+	DWORD ref;
+	TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
+
+	ref = InterlockedDecrement(&(This->ref));
+	if (!ref) {
+		This->dsb->dsb = NULL;
+		IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
+		HeapFree(GetProcessHeap(),0,This);
+		TRACE("(%p) released\n",This);
+	}
+	return ref;
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetCaps(
+	LPDIRECTSOUNDBUFFER8 iface,LPDSBCAPS caps)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+  	TRACE("(%p)->(%p)\n",This,caps);
+
+	return IDirectSoundBufferImpl_GetCaps((LPDIRECTSOUNDBUFFER8)This->dsb,caps);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetCurrentPosition(
+	LPDIRECTSOUNDBUFFER8 iface,LPDWORD playpos,LPDWORD writepos)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p,%p)\n",This,playpos,writepos);
+
+	return IDirectSoundBufferImpl_GetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,playpos,writepos);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetFormat(
+	LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
+
+	return IDirectSoundBufferImpl_GetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,lpwf,wfsize,wfwritten);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetVolume(
+	LPDIRECTSOUNDBUFFER8 iface,LPLONG vol)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p)\n",This,vol);
+
+	return IDirectSoundBufferImpl_GetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetPan(
+	LPDIRECTSOUNDBUFFER8 iface,LPLONG pan)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p)\n",This,pan);
+
+	return IDirectSoundBufferImpl_GetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetFrequency(
+	LPDIRECTSOUNDBUFFER8 iface,LPDWORD freq)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p)\n",This,freq);
+
+	return IDirectSoundBufferImpl_GetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetStatus(
+	LPDIRECTSOUNDBUFFER8 iface,LPDWORD status)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p)\n",This,status);
+
+	return IDirectSoundBufferImpl_GetStatus((LPDIRECTSOUNDBUFFER8)This->dsb,status);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_Initialize(
+	LPDIRECTSOUNDBUFFER8 iface,LPDIRECTSOUND8 dsound,LPDSBUFFERDESC dbsd)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p,%p)\n",This,dsound,dbsd);
+
+	return IDirectSoundBufferImpl_Initialize((LPDIRECTSOUNDBUFFER8)This->dsb,dsound,dbsd);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_Lock(
+	LPDIRECTSOUNDBUFFER8 iface,DWORD writecursor,DWORD writebytes,LPVOID \
lplpaudioptr1,LPDWORD audiobytes1,LPVOID lplpaudioptr2,LPDWORD audiobytes2,DWORD \
flags) +{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%ld,%ld,%p,%p,%p,%p,0x%08lx)\n",
+		This,writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,flags);
 +
+	return IDirectSoundBufferImpl_Lock((LPDIRECTSOUNDBUFFER8)This->dsb,writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,flags);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_Play(
+	LPDIRECTSOUNDBUFFER8 iface,DWORD reserved1,DWORD reserved2,DWORD flags)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%08lx,%08lx,%08lx)\n",This,reserved1,reserved2,flags);
+
+	return IDirectSoundBufferImpl_Play((LPDIRECTSOUNDBUFFER8)This->dsb,reserved1,reserved2,flags);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_SetCurrentPosition(
+	LPDIRECTSOUNDBUFFER8 iface,DWORD newpos)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%ld)\n",This,newpos);
+
+	return IDirectSoundBufferImpl_SetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,newpos);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_SetFormat(
+	LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX wfex)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p)\n",This,wfex);
+
+	return IDirectSoundBufferImpl_SetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,wfex);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_SetVolume(
+	LPDIRECTSOUNDBUFFER8 iface,LONG vol)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%ld)\n",This,vol);
+
+	return IDirectSoundBufferImpl_SetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_SetPan(
+	LPDIRECTSOUNDBUFFER8 iface,LONG pan)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%ld)\n",This,pan);
+
+	return IDirectSoundBufferImpl_SetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_SetFrequency(
+	LPDIRECTSOUNDBUFFER8 iface,DWORD freq)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%ld)\n",This,freq);
+
+	return IDirectSoundBufferImpl_SetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p)\n",This);
+
+	return IDirectSoundBufferImpl_Stop((LPDIRECTSOUNDBUFFER8)This->dsb);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_Unlock(
+	LPDIRECTSOUNDBUFFER8 iface,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2);
+
+	return IDirectSoundBufferImpl_Unlock((LPDIRECTSOUNDBUFFER8)This->dsb,p1,x1,p2,x2);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_Restore(
+	LPDIRECTSOUNDBUFFER8 iface)
+{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p)\n",This);
+
+	return IDirectSoundBufferImpl_Restore((LPDIRECTSOUNDBUFFER8)This->dsb);
+}
+
+static HRESULT WINAPI SecondaryBufferImpl_SetFX(
+	LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD \
pdwResultCodes) +{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%lu,%p,%p)\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes);
+
+	return IDirectSoundBufferImpl_SetFX((LPDIRECTSOUNDBUFFER8)This->dsb,dwEffectsCount,pDSFXDesc,pdwResultCodes);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_AcquireResources(
+	LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD \
pdwResultCodes) +{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%08lu,%lu,%p)\n",This,dwFlags,dwEffectsCount,pdwResultCodes);
+
+	return IDirectSoundBufferImpl_AcquireResources((LPDIRECTSOUNDBUFFER8)This->dsb,dwFlags,dwEffectsCount,pdwResultCodes);
 +}
+
+static HRESULT WINAPI SecondaryBufferImpl_GetObjectInPath(
+	LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID \
rguidInterface,LPVOID* ppObject) +{
+	ICOM_THIS(SecondaryBufferImpl,iface);
+	TRACE("(%p,%s,%lu,%s,%p)\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject);
 +
+	return IDirectSoundBufferImpl_GetObjectInPath((LPDIRECTSOUNDBUFFER8)This->dsb,rguidObject,dwIndex,rguidInterface,ppObject);
 +}
+
+static ICOM_VTABLE(IDirectSoundBuffer8) sbvt =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	SecondaryBufferImpl_QueryInterface,
+	SecondaryBufferImpl_AddRef,
+	SecondaryBufferImpl_Release,
+	SecondaryBufferImpl_GetCaps,
+	SecondaryBufferImpl_GetCurrentPosition,
+	SecondaryBufferImpl_GetFormat,
+	SecondaryBufferImpl_GetVolume,
+	SecondaryBufferImpl_GetPan,
+	SecondaryBufferImpl_GetFrequency,
+	SecondaryBufferImpl_GetStatus,
+	SecondaryBufferImpl_Initialize,
+	SecondaryBufferImpl_Lock,
+	SecondaryBufferImpl_Play,
+	SecondaryBufferImpl_SetCurrentPosition,
+	SecondaryBufferImpl_SetFormat,
+	SecondaryBufferImpl_SetVolume,
+	SecondaryBufferImpl_SetPan,
+	SecondaryBufferImpl_SetFrequency,
+	SecondaryBufferImpl_Stop,
+	SecondaryBufferImpl_Unlock,
+	SecondaryBufferImpl_Restore,
+	SecondaryBufferImpl_SetFX,
+	SecondaryBufferImpl_AcquireResources,
+	SecondaryBufferImpl_GetObjectInPath
+};
+
+HRESULT WINAPI SecondaryBufferImpl_Create(
+	IDirectSoundBufferImpl *dsb,
+	SecondaryBufferImpl **psb)
+{
+	SecondaryBufferImpl *sb;
+	TRACE("(%p,%p)\n",dsb,psb);
+
+	sb = (SecondaryBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*sb));
 +
+	if (sb == 0) {
+		WARN("out of memory\n");
+		*psb = NULL;
+		return DSERR_OUTOFMEMORY;
+	}
+	sb->ref = 0;
+	sb->dsb = dsb;
+	sb->lpVtbl = &sbvt;
+
+	IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)dsb);
+	*psb = sb;
+	return S_OK;
+}
diff -u wine.cvs/dlls/dsound/capture.c wine/dlls/dsound/capture.c
--- wine.cvs/dlls/dsound/capture.c	2003-08-16 15:35:49.000000000 -0400
+++ wine/dlls/dsound/capture.c	2003-08-30 12:09:14.000000000 -0400
@@ -325,8 +325,8 @@
 	    }
 	    This->index = (This->index + 1) % This->nrofpwaves;
 	    waveInUnprepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR));
-	    if (This->capture_buffer->notify && This->capture_buffer->notify->nrofnotifies)
-		SetEvent(This->capture_buffer->notify->notifies[This->index].hEventNotify);
+	    if (This->capture_buffer->nrofnotifies)
+		SetEvent(This->capture_buffer->notifies[This->index].hEventNotify);
 	    if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) \
{  TRACE("end of buffer\n");
 		This->state = STATE_STOPPED;
@@ -377,10 +377,9 @@
 {
     ULONG uRef;
     ICOM_THIS(IDirectSoundCaptureImpl,iface);
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId());  
     EnterCriticalSection( &(This->lock) );
-
-    TRACE( "(%p) was 0x%08lx\n", This, This->ref );
     uRef = ++(This->ref);
 
     if (This->driver) 
@@ -396,10 +395,10 @@
 {
     ULONG uRef;
     ICOM_THIS(IDirectSoundCaptureImpl,iface);
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId());  
     EnterCriticalSection( &(This->lock) );
 
-    TRACE( "(%p) was 0x%08lx\n", This, This->ref );
     uRef = --(This->ref);
 
     LeaveCriticalSection( &(This->lock) );
@@ -418,9 +417,9 @@
         DeleteCriticalSection( &(This->lock) );
         HeapFree( GetProcessHeap(), 0, This );
 	dsound_capture = NULL;
+	TRACE("(%p) released\n",This);
     }
 
-    TRACE( "returning 0x%08lx\n", uRef );
     return uRef;
 }
 
@@ -704,6 +703,9 @@
         This->ref = 1;
         This->dsound = ipDSC;
         This->dsound->capture_buffer = This;
+	This->notify = NULL;
+	This->nrofnotifies = 0;
+	This->hwnotify = NULL;
 
         This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
             lpcDSCBufferDesc->dwSize);
@@ -765,6 +767,131 @@
     return DS_OK;
 }
 
+/*******************************************************************************
+ *		IDirectSoundCaptureNotify
+ */
+static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_QueryInterface(
+    LPDIRECTSOUNDNOTIFY iface,
+    REFIID riid,
+    LPVOID *ppobj)
+{
+    ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface);
+    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+
+    if (This->dscb == NULL) {
+	WARN("invalid parameter\n");
+	return E_INVALIDARG;
+    }
+
+    return IDirectSoundCaptureBuffer_QueryInterface((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb, \
riid, ppobj); +}
+
+static ULONG WINAPI IDirectSoundCaptureNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface)
+{
+    ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface);
+    DWORD ref;
+
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId()); +
+    ref = InterlockedIncrement(&(This->ref));
+    return ref;
+}
+
+static ULONG WINAPI IDirectSoundCaptureNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface)
+{
+    ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface);
+    DWORD ref;
+
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId()); +
+    ref = InterlockedDecrement(&(This->ref));
+    if (ref == 0) {
+	This->dscb->notify=NULL;
+	IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb);
+	HeapFree(GetProcessHeap(),0,This);
+	TRACE("(%p) released\n",This);
+    }
+    return ref;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_SetNotificationPositions(
+    LPDIRECTSOUNDNOTIFY iface,
+    DWORD howmuch,
+    LPCDSBPOSITIONNOTIFY notify)
+{
+    ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface);
+    TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);
+
+    if (notify == NULL) {
+	WARN("invalid parameter: notify == NULL\n");
+	return DSERR_INVALIDPARAM;
+    }
+
+    if (TRACE_ON(dsound)) {
+	int	i;
+	for (i=0;i<howmuch;i++)
+	    TRACE("notify at %ld to 0x%08lx\n",
+	    notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
+    }
+
+    if (This->dscb->hwnotify) {
+	HRESULT hres;
+	hres = IDsDriverNotify_SetNotificationPositions(This->dscb->hwnotify, howmuch, \
notify); +	if (hres != DS_OK)
+	    WARN("IDsDriverNotify_SetNotificationPositions failed\n");
+	return hres;
+    } else {
+	/* Make an internal copy of the caller-supplied array.
+	 * Replace the existing copy if one is already present. */
+	This->dscb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
+	    This->dscb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
+	if (This->dscb->notifies == NULL) {
+	    WARN("out of memory\n");
+	    return DSERR_OUTOFMEMORY;
+	}
+	memcpy(This->dscb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
+	This->dscb->nrofnotifies = howmuch;
+    }
+
+    return S_OK;
+}
+
+ICOM_VTABLE(IDirectSoundNotify) dscnvt =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirectSoundCaptureNotifyImpl_QueryInterface,
+    IDirectSoundCaptureNotifyImpl_AddRef,
+    IDirectSoundCaptureNotifyImpl_Release,
+    IDirectSoundCaptureNotifyImpl_SetNotificationPositions,
+};
+
+HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create(
+    IDirectSoundCaptureBufferImpl *dscb,
+    IDirectSoundCaptureNotifyImpl **pdscn)
+{
+    IDirectSoundCaptureNotifyImpl * dscn;
+    TRACE("(%p,%p)\n",dscb,pdscn);
+
+    dscn = (IDirectSoundCaptureNotifyImpl*)HeapAlloc(GetProcessHeap(), \
HEAP_ZERO_MEMORY, sizeof(dscn)); +
+    if (dscn == NULL) {
+	WARN("out of memory\n");
+	return DSERR_OUTOFMEMORY;
+    }
+
+    dscn->ref = 0;
+    dscn->lpVtbl = &dscnvt;
+    dscn->dscb = dscb;
+    dscb->notify = dscn;
+    IDirectSoundCaptureBuffer_AddRef((LPDIRECTSOUNDCAPTUREBUFFER)dscb);
+
+    *pdscn = dscn;
+    return DS_OK;
+}
+
+/*******************************************************************************
+ *		IDirectSoundCaptureBuffer
+ */
 static HRESULT WINAPI
 IDirectSoundCaptureBufferImpl_QueryInterface(
     LPDIRECTSOUNDCAPTUREBUFFER8 iface,
@@ -772,6 +899,7 @@
     LPVOID* ppobj )
 {
     ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
+    HRESULT hres;
     TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
 
     if (ppobj == NULL) {
@@ -783,24 +911,16 @@
 
     if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ||
          IsEqualGUID( &IID_IDirectSoundNotify8, riid ) ) {
-	if (!This->notify) {
-	    This->notify = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),
-		HEAP_ZERO_MEMORY, sizeof(*This->notify));
-	    if (This->notify) {
-		This->notify->ref = 0;	/* release when ref = -1 */
-		This->notify->lpVtbl = &dsnvt;
-	    }
-	}
+	if (!This->notify)
+	    hres = IDirectSoundCaptureNotifyImpl_Create(This, &This->notify);
 	if (This->notify) {
 	    if (This->dsound->hwbuf) {
-		HRESULT err;
-		
-		err = IDsCaptureDriverBuffer_QueryInterface(This->dsound->hwbuf, 
-		    &IID_IDsDriverNotify, (LPVOID*)&(This->notify->hwnotify));
-		if (err != DS_OK) {
+		hres = IDsCaptureDriverBuffer_QueryInterface(This->dsound->hwbuf, 
+		    &IID_IDsDriverNotify, (LPVOID*)&(This->hwnotify));
+		if (hres != DS_OK) {
 		    WARN("IDsCaptureDriverBuffer_QueryInterface failed\n");
 		    *ppobj = 0;
-		    return err;
+		    return hres;
 	        }
 	    }
 
@@ -809,7 +929,6 @@
 	    return DS_OK;
 	}
 
-	*ppobj = 0;
 	WARN("IID_IDirectSoundNotify\n");
 	return E_FAIL;
     }
@@ -822,9 +941,6 @@
     }
 
     FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
-
-    *ppobj = 0;
-
     return E_NOINTERFACE;
 }
 
@@ -833,13 +949,12 @@
 {
     ULONG uRef;
     ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
-    TRACE( "(%p)\n", This );
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId());  
     assert(This->dsound);
 
     EnterCriticalSection( &(This->dsound->lock) );
 
-    TRACE( "(%p) was 0x%08lx\n", This, This->ref );
     uRef = ++(This->ref);
 
     LeaveCriticalSection( &(This->dsound->lock) );
@@ -852,13 +967,12 @@
 {
     ULONG uRef;
     ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
-    TRACE( "(%p)\n", This );
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId());  
     assert(This->dsound);
 
     EnterCriticalSection( &(This->dsound->lock) );
 
-    TRACE( "(%p) was 0x%08lx\n", This, This->ref );
     uRef = --(This->ref);
 
     LeaveCriticalSection( &(This->dsound->lock) );
@@ -890,10 +1004,13 @@
         if (This->notify)
 	    IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify);
         
+	if (This->notifies != NULL)
+		HeapFree(GetProcessHeap(), 0, This->notifies);
+
         HeapFree( GetProcessHeap(), 0, This );
+	TRACE("(%p) released\n",This);
     }
 
-    TRACE( "returning 0x%08lx\n", uRef );
     return uRef;
 }
 
@@ -1205,10 +1322,10 @@
         IDirectSoundCaptureImpl* ipDSC = This->dsound;
 
         if (ipDSC->buffer) {
-            if (This->notify && This->notify->nrofnotifies) {
+            if (This->nrofnotifies) {
             	unsigned c;
 
-		ipDSC->nrofpwaves = This->notify->nrofnotifies;
+		ipDSC->nrofpwaves = This->nrofnotifies;
 
                 /* prepare headers */
                 ipDSC->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->pwave,
@@ -1218,13 +1335,13 @@
                     if (c == 0) {
                         ipDSC->pwave[0].lpData = ipDSC->buffer;
                         ipDSC->pwave[0].dwBufferLength = 
-                            This->notify->notifies[0].dwOffset + 1;
+                            This->notifies[0].dwOffset + 1;
                     } else {
                         ipDSC->pwave[c].lpData = ipDSC->buffer + 
-                            This->notify->notifies[c-1].dwOffset + 1;
+                            This->notifies[c-1].dwOffset + 1;
                         ipDSC->pwave[c].dwBufferLength = 
-                            This->notify->notifies[c].dwOffset - 
-                            This->notify->notifies[c-1].dwOffset;
+                            This->notifies[c].dwOffset - 
+                            This->notifies[c-1].dwOffset;
                     }
                     ipDSC->pwave[c].dwUser = (DWORD)ipDSC;
                     ipDSC->pwave[c].dwFlags = 0;
@@ -1604,10 +1721,10 @@
 {
     ULONG uRef;
     ICOM_THIS(IDirectSoundFullDuplexImpl,iface);
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId());  
     EnterCriticalSection( &(This->lock) );
 
-    TRACE( "(%p) was 0x%08lx\n", This, This->ref );
     uRef = ++(This->ref);
 
     LeaveCriticalSection( &(This->lock) );
@@ -1620,18 +1737,18 @@
 {
     ULONG uRef;
     ICOM_THIS(IDirectSoundFullDuplexImpl,iface);
+    TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, \
GetCurrentThreadId());  
     EnterCriticalSection( &(This->lock) );
 
-    TRACE( "(%p) was 0x%08lx\n", This, This->ref );
     uRef = --(This->ref);
 
     LeaveCriticalSection( &(This->lock) );
 
     if ( uRef == 0 ) {
-        TRACE("deleting object\n");
         DeleteCriticalSection( &(This->lock) );
         HeapFree( GetProcessHeap(), 0, This );
+	TRACE("(%p) released\n",This);
     }
 
     return uRef;
diff -u wine.cvs/dlls/dsound/dsound_main.c wine/dlls/dsound/dsound_main.c
--- wine.cvs/dlls/dsound/dsound_main.c	2003-08-21 08:00:35.000000000 -0400
+++ wine/dlls/dsound/dsound_main.c	2003-08-30 12:26:49.000000000 -0400
@@ -529,39 +529,52 @@
 		   wfex->wBitsPerSample, wfex->cbSize);
 
 	if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
-		*ppdsb=(LPDIRECTSOUNDBUFFER8)This->primary;
-		if (*ppdsb==NULL)
-			WARN("PrimaryBuffer_Create failed\n");
-		else {
+		if (This->primary) {
+			WARN("Primary Buffer already created\n");
+			IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+			*ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
+		} else {
 			This->dsbd = *dsbd;
-			IDirectSoundBuffer_AddRef(*ppdsb);
+			hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), \
&(This->dsbd)); +			if (This->primary) {
+				IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+				*ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
+			} else 
+				WARN("PrimaryBufferImpl_Create failed\n");
 		}
 	} else {
-		hres = SecondaryBuffer_Create(This, (IDirectSoundBufferImpl**)ppdsb, dsbd);
-		if (hres != DS_OK)
-			WARN("SecondaryBuffer_Create failed\n");
-		else 
-			IDirectSoundBuffer_AddRef(*ppdsb);
+		IDirectSoundBufferImpl * dsb;
+		hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd);
+		if (dsb) {
+			hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
+			if (*ppdsb) {
+				dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
+				IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
+			} else
+				WARN("SecondaryBufferImpl_Create failed\n");
+		} else 
+			WARN("IDirectSoundBufferImpl_Create failed\n");
 	}
 
 	return hres;
 }
 
 static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
-	LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 pdsb,LPLPDIRECTSOUNDBUFFER8 ppdsb
+	LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 psb,LPLPDIRECTSOUNDBUFFER8 ppdsb
 ) {
 	ICOM_THIS(IDirectSoundImpl,iface);
-	IDirectSoundBufferImpl* ipdsb=(IDirectSoundBufferImpl*)pdsb;
+	IDirectSoundBufferImpl* pdsb;
 	IDirectSoundBufferImpl* dsb;
-	TRACE("(%p,%p,%p)\n",This,pdsb,ppdsb);
+	HRESULT hres = DS_OK;
+	TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
 
 	if (This == NULL) {
 		WARN("invalid parameter: This == NULL\n");
 		return DSERR_INVALIDPARAM;
 	}
 
-	if (pdsb == NULL) {
-		WARN("invalid parameter: pdsb == NULL\n");
+	if (psb == NULL) {
+		WARN("invalid parameter: psb == NULL\n");
 		return DSERR_INVALIDPARAM;
 	}
 
@@ -570,13 +583,16 @@
 		return DSERR_INVALIDPARAM;
 	}
 
-	if (ipdsb->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) {
+	/* FIXME: hack to make sure we have a secondary buffer */
+	if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
 		ERR("trying to duplicate primary buffer\n");
 		*ppdsb = NULL;
 		return DSERR_INVALIDCALL;
 	}
 
-	if (ipdsb->hwbuf) {
+	pdsb = ((SecondaryBufferImpl *)psb)->dsb;
+
+	if (pdsb->hwbuf) {
 		FIXME("need to duplicate hardware buffer\n");
 		*ppdsb = NULL;
 		return DSERR_INVALIDCALL;
@@ -590,8 +606,8 @@
 		return DSERR_OUTOFMEMORY;
 	}
 
-	memcpy(dsb, ipdsb, sizeof(IDirectSoundBufferImpl));
-	dsb->ref = 1;
+	memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
+	dsb->ref = 0;
 	dsb->state = STATE_STOPPED;
 	dsb->playpos = 0;
 	dsb->buf_mixpos = 0;
@@ -600,7 +616,8 @@
 	dsb->hwbuf = NULL;
 	dsb->ds3db = NULL;
 	dsb->iks = NULL; /* FIXME? */
-	memcpy(&(dsb->wfx), &(ipdsb->wfx), sizeof(dsb->wfx));
+	dsb->dsb = NULL;
+	memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
 	InitializeCriticalSection(&(dsb->lock));
 	/* register buffer */
 	RtlAcquireResourceExclusive(&(This->lock), TRUE);
@@ -613,7 +630,7 @@
 			TRACE("buffer count is now %d\n", This->nrofbuffers);
 		} else {
 			ERR("out of memory for buffer list! Current buffer count is %d\n", \
                This->nrofbuffers);
-			IDirectSoundBuffer8_Release(pdsb);
+			IDirectSoundBuffer8_Release(psb);
 			DeleteCriticalSection(&(dsb->lock));
 			RtlReleaseResource(&(This->lock));
 			HeapFree(GetProcessHeap(),0,dsb);
@@ -623,10 +640,15 @@
 	}
 	RtlReleaseResource(&(This->lock));
 	IDirectSound_AddRef(iface);
-	*ppdsb = (LPDIRECTSOUNDBUFFER8)dsb;
-	return DS_OK;
-}
+	hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
+	if (*ppdsb) {
+		dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
+		IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
+	} else
+		WARN("SecondaryBufferImpl_Create failed\n");
 
+	return hres;
+}
 
 static HRESULT WINAPI IDirectSoundImpl_GetCaps(LPDIRECTSOUND8 iface,LPDSCAPS \
lpDSCaps) {  ICOM_THIS(IDirectSoundImpl,iface);
@@ -699,7 +721,6 @@
 
 	TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, \
GetCurrentThreadId());  ulReturn = InterlockedDecrement(&This->ref);
-
 	if (ulReturn == 0) {
 		HRESULT hres;
 		UINT i;
@@ -718,8 +739,10 @@
 
 		RtlReleaseResource(&(This->lock));
 
-		if (This->primary)
+		if (This->primary) {
+			WARN("primary buffer not released\n");
 			IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
+		}
 
 		hres = DSOUND_PrimaryDestroy(This);
 		if (hres != DS_OK)
@@ -739,8 +762,9 @@
 		DeleteCriticalSection(&This->ds3dl_lock);
 		HeapFree(GetProcessHeap(),0,This);
 		dsound = NULL;
-		return 0;
+		TRACE("(%p) released\n",This);
 	}
+
 	return ulReturn;
 }
 
@@ -748,7 +772,11 @@
 	LPDIRECTSOUND8 iface,DWORD config
 ) {
 	ICOM_THIS(IDirectSoundImpl,iface);
-	FIXME("(%p,0x%08lx):stub\n",This,config);
+	TRACE("(%p,0x%08lx)\n",This,config);
+
+	This->speaker_config = config;
+
+	WARN("not fully functional\n");
 	return DS_OK;
 }
 
@@ -796,7 +824,16 @@
 {
 	ICOM_THIS(IDirectSoundImpl,iface);
 	TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
-	*lpdwSpeakerConfig = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
+
+	if (lpdwSpeakerConfig == NULL) {
+		WARN("invalid parameter\n");
+		return DSERR_INVALIDPARAM;
+	}
+
+	WARN("not fully functional\n");
+
+	*lpdwSpeakerConfig = This->speaker_config;
+
 	return DS_OK;
 }
 
@@ -883,6 +920,7 @@
 
 	if (dsound) {
 		if (IsEqualGUID(&devGuid, &dsound->guid) ) {
+			/* FIXME: this is wrong, need to create a new instance */
 			ERR("dsound already opened\n");
 			IDirectSound_AddRef((LPDIRECTSOUND)dsound);
 			*ippDS = dsound;
@@ -957,6 +995,7 @@
 	(*ippDS)->nrofbuffers	= 0;
 	(*ippDS)->buffers	= NULL;
 	(*ippDS)->primary	= NULL;
+	(*ippDS)->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
 	
 	/* 3D listener initial parameters */
 	(*ippDS)->listener	= NULL;
@@ -1115,15 +1154,7 @@
 					       (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
 	}
 
-	/* create a user accessable primary buffer */
-	(*ippDS)->dsbd.dwSize = sizeof((*ippDS)->dsbd);
-	err = PrimaryBuffer_Create((*ippDS), (PrimaryBufferImpl**)&((*ippDS)->primary), \
                &((*ippDS)->dsbd));
-	if ((*ippDS)->primary)
-		IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(*ippDS)->primary);
-	else 
-		WARN("PrimaryBuffer_Create failed\n");
-
-	return err;
+	return DS_OK;
 }
 
 
diff -u wine.cvs/dlls/dsound/dsound_private.h wine/dlls/dsound/dsound_private.h
--- wine.cvs/dlls/dsound/dsound_private.h	2003-08-21 08:00:35.000000000 -0400
+++ wine/dlls/dsound/dsound_private.h	2003-08-29 15:02:45.000000000 -0400
@@ -50,11 +50,13 @@
 typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
 typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
 typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
+typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
 typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
 typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
 typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
 typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
 typedef struct PrimaryBufferImpl PrimaryBufferImpl;
+typedef struct SecondaryBufferImpl SecondaryBufferImpl;
 typedef struct IClassFactoryImpl IClassFactoryImpl;
 
 /*****************************************************************************
@@ -87,6 +89,7 @@
     DSVOLUMEPAN                 volpan;
     PrimaryBufferImpl*          primary;
     DSBUFFERDESC                dsbd;
+    DWORD                       speaker_config;
 
     /* DirectSound3DListener fields */
     IDirectSound3DListenerImpl*	listener;
@@ -112,9 +115,8 @@
     ICOM_VFIELD(IDirectSoundBuffer8);
     DWORD                       ref;
     /* IDirectSoundBufferImpl fields */
+    SecondaryBufferImpl*        dsb;
     IDirectSoundImpl*           dsound;
-    IDirectSound3DBufferImpl*   ds3db;
-    IKsBufferPropertySetImpl*   iks;
     CRITICAL_SECTION            lock;
     PIDSDRIVERBUFFER            hwbuf;
     WAVEFORMATEX                wfx;
@@ -131,30 +133,56 @@
     DWORD                       probably_valid_to, last_playpos;
     DWORD                       primary_mixpos, buf_mixpos;
     BOOL                        need_remix;
+
     /* IDirectSoundNotifyImpl fields */
     IDirectSoundNotifyImpl*     notify;
+    LPDSBPOSITIONNOTIFY         notifies;
+    int                         nrofnotifies;
+    PIDSDRIVERNOTIFY            hwnotify;
 
     /* DirectSound3DBuffer fields */
+    IDirectSound3DBufferImpl*   ds3db;
     DS3DBUFFER                  ds3db_ds3db;
     LONG                        ds3db_lVolume;
     BOOL                        ds3db_need_recalc;
+
+    /* IKsPropertySet fields */
+    IKsBufferPropertySetImpl*   iks;
 };
 
-HRESULT WINAPI SecondaryBuffer_Create(
-	IDirectSoundImpl *This,
-	IDirectSoundBufferImpl **pdsb,
-	LPDSBUFFERDESC dsbd);
+HRESULT WINAPI IDirectSoundBufferImpl_Create(
+    IDirectSoundImpl *ds,
+    IDirectSoundBufferImpl **pdsb,
+    LPDSBUFFERDESC dsbd);
 
-struct PrimaryBufferImpl {
+/*****************************************************************************
+ * SecondaryBuffer implementation structure
+ */
+struct SecondaryBufferImpl
+{
+    ICOM_VFIELD(IDirectSoundBuffer8);
+    DWORD                       ref;
+    IDirectSoundBufferImpl*     dsb;
+};
+
+HRESULT WINAPI SecondaryBufferImpl_Create(
+    IDirectSoundBufferImpl *dsb,
+    SecondaryBufferImpl **pdsb);
+
+/*****************************************************************************
+ * PrimaryBuffer implementation structure
+ */
+struct PrimaryBufferImpl
+{
     ICOM_VFIELD(IDirectSoundBuffer8);
     DWORD                       ref;
     IDirectSoundImpl*           dsound;
 };
 
-HRESULT WINAPI PrimaryBuffer_Create(
-	IDirectSoundImpl *This,
-	PrimaryBufferImpl **pdsb,
-	LPDSBUFFERDESC dsbd);
+HRESULT WINAPI PrimaryBufferImpl_Create(
+    IDirectSoundImpl *ds,
+    PrimaryBufferImpl **pdsb,
+    LPDSBUFFERDESC dsbd);
 
 /*****************************************************************************
  * IDirectSoundCapture implementation structure
@@ -208,8 +236,12 @@
     /* FIXME: don't need this */
     LPDSCBUFFERDESC                     pdscbd;
     DWORD                               flags;
-    /* IDirectSoundNotifyImpl fields */
-    IDirectSoundNotifyImpl*             notify;
+
+    /* IDirectSoundCaptureNotifyImpl fields */
+    IDirectSoundCaptureNotifyImpl*      notify;
+    LPDSBPOSITIONNOTIFY                 notifies;
+    int                                 nrofnotifies;
+    PIDSDRIVERNOTIFY                    hwnotify;
 };
 
 /*****************************************************************************
@@ -233,13 +265,28 @@
     /* IUnknown fields */
     ICOM_VFIELD(IDirectSoundNotify);
     DWORD                       ref;
-    /* IDirectSoundNotifyImpl fields */
-    LPDSBPOSITIONNOTIFY         notifies;
-    int                         nrofnotifies;
+    IDirectSoundBufferImpl*     dsb;
+};
 
-    PIDSDRIVERNOTIFY            hwnotify;
+HRESULT WINAPI IDirectSoundNotifyImpl_Create(
+    IDirectSoundBufferImpl *dsb,
+    IDirectSoundNotifyImpl **pdsn);
+
+/*****************************************************************************
+ * IDirectSoundCaptureNotify implementation structure
+ */
+struct IDirectSoundCaptureNotifyImpl
+{
+    /* IUnknown fields */
+    ICOM_VFIELD(IDirectSoundNotify);
+    DWORD                               ref;
+    IDirectSoundCaptureBufferImpl*      dscb;
 };
 
+HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create(
+    IDirectSoundCaptureBufferImpl *dscb,
+    IDirectSoundCaptureNotifyImpl ** pdscn);
+
 /*****************************************************************************
  *  IDirectSound3DListener implementation structure
  */
@@ -253,8 +300,8 @@
 };
 
 HRESULT WINAPI IDirectSound3DListenerImpl_Create(
-	PrimaryBufferImpl *This,
-	IDirectSound3DListenerImpl **pdsl);
+    PrimaryBufferImpl *pb,
+    IDirectSound3DListenerImpl **pdsl);
 
 /*****************************************************************************
  *  IKsBufferPropertySet implementation structure
@@ -269,8 +316,8 @@
 };
 
 HRESULT WINAPI IKsBufferPropertySetImpl_Create(
-	IDirectSoundBufferImpl *This,
-	IKsBufferPropertySetImpl **piks);
+    IDirectSoundBufferImpl *dsb,
+    IKsBufferPropertySetImpl **piks);
 
 /*****************************************************************************
  *  IKsPrivatePropertySet implementation structure
@@ -283,7 +330,7 @@
 };
 
 HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
-	IKsPrivatePropertySetImpl **piks);
+    IKsPrivatePropertySetImpl **piks);
 
 /*****************************************************************************
  * IDirectSound3DBuffer implementation structure
@@ -299,8 +346,8 @@
 };
 
 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
-	IDirectSoundBufferImpl *This,
-	IDirectSound3DBufferImpl **pds3db);
+    IDirectSoundBufferImpl *dsb,
+    IDirectSound3DBufferImpl **pds3db);
 
 /*******************************************************************************
  * DirectSound ClassFactory implementation structure
@@ -356,6 +403,5 @@
 extern IDirectSoundImpl* dsound;
 extern IDirectSoundCaptureImpl* dsound_capture;
 
-extern ICOM_VTABLE(IDirectSoundNotify) dsnvt;
 extern HRESULT mmErr(UINT err);
 extern void setup_dsound_options(void);
diff -u wine.cvs/dlls/dsound/mixer.c wine/dlls/dsound/mixer.c
--- wine.cvs/dlls/dsound/mixer.c	2003-08-16 15:35:49.000000000 -0400
+++ wine/dlls/dsound/mixer.c	2003-08-28 20:09:03.000000000 -0400
@@ -68,6 +68,7 @@
 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
 {
 	DWORD sw;
+	TRACE("(%p)\n",dsb);
 
 	sw = dsb->wfx.nChannels * (dsb->wfx.wBitsPerSample / 8);
 	/* calculate the 10ms write lead */
@@ -79,14 +80,15 @@
 	int			i;
 	DWORD			offset;
 	LPDSBPOSITIONNOTIFY	event;
+	TRACE("(%p,%d)\n",dsb,len);
 
-	if (!dsb->notify || dsb->notify->nrofnotifies == 0)
+	if (dsb->nrofnotifies == 0)
 		return;
 
 	TRACE("(%p) buflen = %ld, playpos = %ld, len = %d\n",
 		dsb, dsb->buflen, dsb->playpos, len);
-	for (i = 0; i < dsb->notify->nrofnotifies ; i++) {
-		event = dsb->notify->notifies + i;
+	for (i = 0; i < dsb->nrofnotifies ; i++) {
+		event = dsb->notifies + i;
 		offset = event->dwOffset;
 		TRACE("checking %d, position %ld, event = %p\n",
 			i, offset, event->hEventNotify);
@@ -354,7 +356,7 @@
 	BYTE	*buf, *ibuf, *obuf;
 	INT16	*ibufs, *obufs;
 
-	TRACE("%p,%ld,%ld)\n",dsb,writepos,fraglen);
+	TRACE("(%p,%ld,%ld)\n",dsb,writepos,fraglen);
 
 	len = fraglen;
 	if (!(dsb->playflags & DSBPLAY_LOOPING)) {
@@ -440,6 +442,7 @@
 	INT     advance = dsb->dsound->wfx.wBitsPerSample >> 3;
 	BYTE	*buf, *ibuf, *obuf;
 	INT16	*ibufs, *obufs;
+	TRACE("(%p,%ld,%ld)\n",dsb,writepos,len);
 
 	nBlockAlign = dsb->dsound->wfx.nBlockAlign;
 	len = len / nBlockAlign * nBlockAlign;  /* data alignment */
@@ -552,6 +555,7 @@
 
 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb)
 {
+	TRACE("(%p)\n",dsb);
 	EnterCriticalSection(&dsb->lock);
 	if (dsb->state == STATE_PLAYING) {
 #if 0 /* this may not be quite reliable yet */
@@ -585,6 +589,7 @@
 	DWORD buf_left = dsb->buflen - buf_writepos;
 	int still_behind;
 
+	TRACE("(%p,%ld,%ld,%ld)\n",dsb,playpos,writepos,mixlen);
 	TRACE("buf_writepos=%ld, primary_writepos=%ld\n", buf_writepos, writepos);
 	TRACE("buf_done=%ld, primary_done=%ld\n", buf_done, primary_done);
 	TRACE("buf_mixpos=%ld, primary_mixpos=%ld, mixlen=%ld\n", dsb->buf_mixpos, \
dsb->primary_mixpos, @@ -724,7 +729,7 @@
 	INT			i, len, maxlen = 0;
 	IDirectSoundBufferImpl	*dsb;
 
-	TRACE("(%ld,%ld,%ld)\n", playpos, writepos, mixlen);
+	TRACE("(%ld,%ld,%ld,%d)\n", playpos, writepos, mixlen, recover);
 	for (i = dsound->nrofbuffers - 1; i >= 0; i--) {
 		dsb = dsound->buffers[i];
 
@@ -808,6 +813,7 @@
 
 static void DSOUND_CheckReset(IDirectSoundImpl *dsound, DWORD writepos)
 {
+	TRACE("(%p,%ld)\n",dsound,writepos);
 	if (dsound->need_remix) {
 		DSOUND_MixReset(writepos);
 		dsound->need_remix = FALSE;
@@ -827,6 +833,7 @@
 
 void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq)
 {
+	TRACE("(%p,%ld)\n",dsound,mixq);
 	if (mixq + dsound->pwqueue > ds_hel_queue) mixq = ds_hel_queue - dsound->pwqueue;
 	TRACE("queueing %ld buffers, starting at %d\n", mixq, dsound->pwwrite);
 	for (; mixq; mixq--) {
@@ -1034,6 +1041,7 @@
 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD \
dw2)  {
         IDirectSoundImpl* This = (IDirectSoundImpl*)dwUser;
+	TRACE("(%p,%x,%lx,%lx,%lx)\n",hwo,msg,dwUser,dw1,dw2);
 	TRACE("entering at %ld, msg=%08x(%s)\n", GetTickCount(), msg, 
 		msg==MM_WOM_DONE ? "MM_WOM_DONE" : msg==MM_WOM_CLOSE ? "MM_WOM_CLOSE" : 
 		msg==MM_WOM_OPEN ? "MM_WOM_OPEN" : "UNKNOWN");
diff -u wine.cvs/dlls/dsound/primary.c wine/dlls/dsound/primary.c
--- wine.cvs/dlls/dsound/primary.c	2003-08-16 15:35:49.000000000 -0400
+++ wine/dlls/dsound/primary.c	2003-08-30 12:11:10.000000000 -0400
@@ -303,7 +303,7 @@
 
 
 /*******************************************************************************
- *		IDirectSoundBuffer
+ *		PrimaryBuffer
  */
 /* This sets this format for the <em>Primary Buffer Only</em> */
 /* See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120 */
@@ -573,9 +573,11 @@
 	TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
 	ref = InterlockedDecrement(&(This->ref));
 
-	if (ref == -1) {
+	if (ref == 0) {
 		This->dsound->primary = NULL;
+		IDirectSound_Release((LPDIRECTSOUND)This->dsound);
 		HeapFree(GetProcessHeap(),0,This);
+		TRACE("(%p) released\n",This);
 	}
 
 	return ref;
@@ -942,16 +944,12 @@
 	}
 
         if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
-		if (This->dsound->dsbd.dwFlags & DSBCAPS_CTRL3D) {
-			if (!This->dsound->listener)
-				IDirectSound3DListenerImpl_Create(This, &This->dsound->listener);
-	
+		if (!This->dsound->listener)
+			IDirectSound3DListenerImpl_Create(This, &This->dsound->listener);
+		if (This->dsound->listener) {
 			*ppobj = This->dsound->listener;
-	
-			if (This->dsound->listener) {
-				IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj);
-				return S_OK;
-			}
+			IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj);
+			return S_OK;
 		}
 
 		WARN("IID_IDirectSound3DListener failed\n");
@@ -996,14 +994,14 @@
 	PrimaryBufferImpl_GetObjectInPath
 };
 
-HRESULT WINAPI PrimaryBuffer_Create(
-	IDirectSoundImpl *This,
+HRESULT WINAPI PrimaryBufferImpl_Create(
+	IDirectSoundImpl *ds,
 	PrimaryBufferImpl **pdsb,
 	LPDSBUFFERDESC dsbd)
 {
 	PrimaryBufferImpl *dsb;
 
-	TRACE("%p,%p,%p)\n",This,pdsb,dsbd);
+	TRACE("%p,%p,%p)\n",ds,pdsb,dsbd);
 
 	if (dsbd->lpwfxFormat) {
 		WARN("invalid parameter: dsbd->lpwfxFormat != NULL\n");
@@ -1019,19 +1017,20 @@
 		return DSERR_OUTOFMEMORY;
 	}
 
-	dsb->ref = -1;
-	dsb->dsound = This;
+	dsb->ref = 0;
+	dsb->dsound = ds;
 	dsb->lpVtbl = &dspbvt;
 
-	memcpy(&This->dsbd, dsbd, sizeof(*dsbd));
+	memcpy(&ds->dsbd, dsbd, sizeof(*dsbd));
 
 	TRACE("Created primary buffer at %p\n", dsb);
 	TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
 		"bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
-		This->wfx.wFormatTag, This->wfx.nChannels, This->wfx.nSamplesPerSec,
-		This->wfx.nAvgBytesPerSec, This->wfx.nBlockAlign,
-		This->wfx.wBitsPerSample, This->wfx.cbSize);
+		ds->wfx.wFormatTag, ds->wfx.nChannels, ds->wfx.nSamplesPerSec,
+		ds->wfx.nAvgBytesPerSec, ds->wfx.nBlockAlign,
+		ds->wfx.wBitsPerSample, ds->wfx.cbSize);
 
+	IDirectSound_AddRef((LPDIRECTSOUND)ds);
 	*pdsb = dsb;
 	return S_OK;
 }
diff -u wine.cvs/dlls/dsound/propset.c wine/dlls/dsound/propset.c
--- wine.cvs/dlls/dsound/propset.c	2003-08-21 08:00:35.000000000 -0400
+++ wine/dlls/dsound/propset.c	2003-08-30 12:11:29.000000000 -0400
@@ -72,9 +72,7 @@
     ULONG ulReturn;
 
     TRACE("(%p) ref was %ld\n", This, This->ref);
-    ulReturn = InterlockedIncrement(&This->ref);
-    if (ulReturn == 1)
-	IDirectSoundBuffer_AddRef((LPDIRECTSOUND3DBUFFER)This->dsb);
+    ulReturn = InterlockedIncrement(&(This->ref));
     return ulReturn;
 }
 
@@ -85,10 +83,13 @@
 
     TRACE("(%p) ref was %ld\n", This, This->ref);
     ulReturn = InterlockedDecrement(&This->ref);
-    if (ulReturn)
-	return ulReturn;
-    IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
-    return 0;
+    if (!ulReturn) {
+	This->dsb->iks = 0;
+	IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
+	HeapFree(GetProcessHeap(),0,This);
+	TRACE("(%p) released\n",This);
+    }
+    return ulReturn;
 }
 
 static HRESULT WINAPI IKsBufferPropertySetImpl_Get(
@@ -146,16 +147,19 @@
 };
 
 HRESULT WINAPI IKsBufferPropertySetImpl_Create(
-    IDirectSoundBufferImpl *This,
+    IDirectSoundBufferImpl *dsb,
     IKsBufferPropertySetImpl **piks)
 {
     IKsBufferPropertySetImpl *iks;
 
     iks = (IKsBufferPropertySetImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
     iks->ref = 0;
-    iks->dsb = This;
+    iks->dsb = dsb;
+    dsb->iks = iks;
     iks->lpVtbl = &iksbvt;
 
+    IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
+
     *piks = iks;
     return S_OK;
 }
diff -u wine.cvs/dlls/dsound/sound3d.c wine/dlls/dsound/sound3d.c
--- wine.cvs/dlls/dsound/sound3d.c	2003-08-16 15:35:50.000000000 -0400
+++ wine/dlls/dsound/sound3d.c	2003-08-30 12:23:56.000000000 -0400
@@ -395,10 +395,11 @@
 	TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
 	ulReturn = InterlockedDecrement(&This->ref);
 	if (!ulReturn) {
-		IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This);
 		This->dsb->ds3db = NULL;
+		IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
 		DeleteCriticalSection(&(This->lock));
 		HeapFree(GetProcessHeap(),0,This);
+		TRACE("(%p) released\n",This);
 	}
 
 	return ulReturn;
@@ -766,11 +767,11 @@
 };
 
 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
-	IDirectSoundBufferImpl *This,
+	IDirectSoundBufferImpl *dsb,
 	IDirectSound3DBufferImpl **pds3db)
 {
 	IDirectSound3DBufferImpl *ds3db;
-	TRACE("(%p,%p)\n",This,pds3db);
+	TRACE("(%p,%p)\n",dsb,pds3db);
 
 	ds3db = (IDirectSound3DBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
  
@@ -781,7 +782,7 @@
 	}
 
 	ds3db->ref = 0;
-	ds3db->dsb = This;
+	ds3db->dsb = dsb;
 	ds3db->lpVtbl = &ds3dbvt;
 
 	ds3db->dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER);
@@ -805,6 +806,8 @@
 
 	InitializeCriticalSection(&(ds3db->lock));
 
+	IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)dsb);
+
 	*pds3db = ds3db;
 	return S_OK;
 }
@@ -836,9 +839,13 @@
 	}
 
 	if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
-		*ppobj = This->dsound->primary;
-		IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj);
-		return S_OK;
+		if (!This->dsound->primary)
+			PrimaryBufferImpl_Create(This->dsound, &(This->dsound->primary), \
&(This->dsound->dsbd)); +		if (This->dsound->primary) {
+			*ppobj = This->dsound->primary;
+			IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj);
+			return S_OK;
+		}
 	}
 
         FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
@@ -873,6 +880,7 @@
 		IDirectSound8_Release((LPDIRECTSOUND8)This->dsound);
 		This->dsound->listener = 0;
 		HeapFree(GetProcessHeap(),0,This);
+		TRACE("(%p) released\n",This);
 	}
 
 	return ulReturn;



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic