Commit 605cc1b0 authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Remove DirectSound reference counts by buffers and add Destroy

functions to buffer components and DirectSound to allow proper destruction even with outstanding references. Remove trailing white space. Add tests for proper release even with active buffers.
parent 4cd38b48
......@@ -121,11 +121,11 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(
} else if (howmuch > 0) {
/* Make an internal copy of the caller-supplied array.
* Replace the existing copy if one is already present. */
if (This->dsb->notifies)
This->dsb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
if (This->dsb->notifies)
This->dsb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
This->dsb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
else
This->dsb->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
This->dsb->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
howmuch * sizeof(DSBPOSITIONNOTIFY));
if (This->dsb->notifies == NULL) {
......@@ -160,9 +160,9 @@ HRESULT WINAPI IDirectSoundNotifyImpl_Create(
{
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;
......@@ -173,11 +173,21 @@ HRESULT WINAPI IDirectSoundNotifyImpl_Create(
dsn->dsb = dsb;
dsb->notify = dsn;
IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
*pdsn = dsn;
return DS_OK;
}
HRESULT WINAPI IDirectSoundNotifyImpl_Destroy(
IDirectSoundNotifyImpl *pdsn)
{
TRACE("(%p)\n",pdsn);
while (IDirectSoundNotifyImpl_Release((LPDIRECTSOUNDNOTIFY)pdsn) > 0);
return DS_OK;
}
/*******************************************************************************
* IDirectSoundBuffer
*/
......@@ -220,7 +230,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume(
} else {
oldVol = This->volpan.lVolume;
This->volpan.lVolume = vol;
if (vol != oldVol)
if (vol != oldVol)
DSOUND_RecalcVolPan(&(This->volpan));
}
......@@ -230,7 +240,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume(
hres = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
if (hres != DS_OK)
WARN("IDsDriverBuffer_SetVolumePan failed\n");
} else
} else
DSOUND_ForceRemix(This);
}
......@@ -291,7 +301,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(
This->freqAdjust = (freq << DSOUND_FREQSHIFT) / This->dsound->wfx.nSamplesPerSec;
This->nAvgBytesPerSec = freq * This->wfx.nBlockAlign;
DSOUND_RecalcFormat(This);
if (!This->hwbuf)
if (!This->hwbuf)
DSOUND_ForceRemix(This);
}
......@@ -393,7 +403,6 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
This->dsound->nrofbuffers--;
This->dsound->buffers = HeapReAlloc(GetProcessHeap(),0,This->dsound->buffers,sizeof(LPDIRECTSOUNDBUFFER8)*This->dsound->nrofbuffers);
TRACE("(%p) buffer count is now %d\n", This, This->dsound->nrofbuffers);
IDirectSound_Release((LPDIRECTSOUND)This->dsound);
}
RtlReleaseResource(&(This->dsound->lock));
......@@ -757,7 +766,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetPan(
hres = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
if (hres != DS_OK)
WARN("IDsDriverBuffer_SetVolumePan failed\n");
} else
} else
DSOUND_ForceRemix(This);
}
......@@ -941,8 +950,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
*ppobj = NULL; /* assume failure */
if ( IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IDirectSoundBuffer) ||
if ( IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IDirectSoundBuffer) ||
IsEqualGUID(riid, &IID_IDirectSoundBuffer8) ) {
if (!This->dsb)
SecondaryBufferImpl_Create(This, &(This->dsb));
......@@ -987,8 +996,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
/* only supported on hardware 3D secondary buffers */
if (!(This->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) &&
(This->dsbd.dwFlags & DSBCAPS_CTRL3D) &&
if (!(This->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) &&
(This->dsbd.dwFlags & DSBCAPS_CTRL3D) &&
(This->hwbuf != NULL) ) {
if (!This->iks)
IKsBufferPropertySetImpl_Create(This, &(This->iks));
......@@ -1214,17 +1223,54 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
}
}
RtlReleaseResource(&(ds->lock));
IDirectSound8_AddRef((LPDIRECTSOUND8)ds);
*pdsb = dsb;
return S_OK;
}
HRESULT WINAPI IDirectSoundBufferImpl_Destroy(
IDirectSoundBufferImpl *pdsb)
{
TRACE("(%p)\n",pdsb);
/* This keeps the *_Destroy functions from possibly deleting
* this object until it is ready to be deleted */
IDirectSoundBufferImpl_AddRef((LPDIRECTSOUNDBUFFER8)pdsb);
if (pdsb->iks) {
WARN("iks not NULL\n");
IKsBufferPropertySetImpl_Destroy(pdsb->iks);
pdsb->iks = NULL;
}
if (pdsb->ds3db) {
WARN("ds3db not NULL\n");
IDirectSound3DBufferImpl_Destroy(pdsb->ds3db);
pdsb->ds3db = NULL;
}
if (pdsb->notify) {
WARN("notify not NULL\n");
IDirectSoundNotifyImpl_Destroy(pdsb->notify);
pdsb->notify = NULL;
}
if (pdsb->dsb) {
WARN("dsb not NULL\n");
SecondaryBufferImpl_Destroy(pdsb->dsb);
pdsb->dsb = NULL;
}
while (IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)pdsb) > 0);
return S_OK;
}
/*******************************************************************************
* SecondaryBuffer
*/
static HRESULT WINAPI SecondaryBufferImpl_QueryInterface(
LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj)
LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj)
{
ICOM_THIS(SecondaryBufferImpl,iface);
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
......@@ -1515,3 +1561,13 @@ HRESULT WINAPI SecondaryBufferImpl_Create(
*psb = sb;
return S_OK;
}
HRESULT WINAPI SecondaryBufferImpl_Destroy(
SecondaryBufferImpl *pdsb)
{
TRACE("(%p)\n",pdsb);
while (SecondaryBufferImpl_Release((LPDIRECTSOUNDBUFFER8)pdsb) > 0);
return S_OK;
}
......@@ -233,7 +233,8 @@ static ULONG WINAPI IDirectSoundImpl_Release(
{
ICOM_THIS(IDirectSoundImpl,iface);
ULONG ref;
TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
TRACE("(%p) ref was %ld, thread is %04lx\n",
This, This->ref, GetCurrentThreadId());
ref = InterlockedDecrement(&This->ref);
if (ref == 0) {
......@@ -245,15 +246,19 @@ static ULONG WINAPI IDirectSoundImpl_Release(
/* wait for timer to expire */
Sleep(DS_TIME_RES+1);
/* The sleep above should have allowed the timer process to expire
* but try to grab the lock just in case. Can't hold lock because
* IDirectSoundBufferImpl_Destroy also grabs the lock */
RtlAcquireResourceShared(&(This->lock), TRUE);
RtlReleaseResource(&(This->lock));
/* It is allowed to release this object even when buffers are playing */
if (This->buffers) {
WARN("%d secondary buffers not released\n", This->nrofbuffers);
for( i=0;i<This->nrofbuffers;i++)
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->buffers[i]);
IDirectSoundBufferImpl_Destroy(This->buffers[i]);
}
RtlReleaseResource(&(This->lock));
if (This->primary) {
WARN("primary buffer not released\n");
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
......@@ -530,7 +535,6 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
}
}
RtlReleaseResource(&(This->lock));
IDirectSound_AddRef(iface);
hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
if (*ppdsb) {
dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
......
......@@ -222,6 +222,8 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
IDirectSoundImpl *ds,
IDirectSoundBufferImpl **pdsb,
LPCDSBUFFERDESC dsbd);
HRESULT WINAPI IDirectSoundBufferImpl_Destroy(
IDirectSoundBufferImpl *pdsb);
/*****************************************************************************
* SecondaryBuffer implementation structure
......@@ -236,6 +238,8 @@ struct SecondaryBufferImpl
HRESULT WINAPI SecondaryBufferImpl_Create(
IDirectSoundBufferImpl *dsb,
SecondaryBufferImpl **pdsb);
HRESULT WINAPI SecondaryBufferImpl_Destroy(
SecondaryBufferImpl *pdsb);
/*****************************************************************************
* PrimaryBuffer implementation structure
......@@ -338,6 +342,8 @@ struct IDirectSoundNotifyImpl
HRESULT WINAPI IDirectSoundNotifyImpl_Create(
IDirectSoundBufferImpl *dsb,
IDirectSoundNotifyImpl **pdsn);
HRESULT WINAPI IDirectSoundNotifyImpl_Destroy(
IDirectSoundNotifyImpl *pdsn);
/*****************************************************************************
* IDirectSoundCaptureNotify implementation structure
......@@ -385,6 +391,8 @@ struct IKsBufferPropertySetImpl
HRESULT WINAPI IKsBufferPropertySetImpl_Create(
IDirectSoundBufferImpl *dsb,
IKsBufferPropertySetImpl **piks);
HRESULT WINAPI IKsBufferPropertySetImpl_Destroy(
IKsBufferPropertySetImpl *piks);
/*****************************************************************************
* IKsPrivatePropertySet implementation structure
......@@ -414,6 +422,8 @@ struct IDirectSound3DBufferImpl
HRESULT WINAPI IDirectSound3DBufferImpl_Create(
IDirectSoundBufferImpl *dsb,
IDirectSound3DBufferImpl **pds3db);
HRESULT WINAPI IDirectSound3DBufferImpl_Destroy(
IDirectSound3DBufferImpl *pds3db);
/*******************************************************************************
* DirectSound ClassFactory implementation structure
......
......@@ -601,7 +601,6 @@ static DWORD WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
if (ref == 0) {
This->dsound->primary = NULL;
IDirectSound_Release((LPDIRECTSOUND)This->dsound);
HeapFree(GetProcessHeap(),0,This);
TRACE("(%p) released\n",This);
}
......@@ -1098,7 +1097,6 @@ HRESULT WINAPI PrimaryBufferImpl_Create(
ds->wfx.nAvgBytesPerSec, ds->wfx.nBlockAlign,
ds->wfx.wBitsPerSample, ds->wfx.cbSize);
IDirectSound_AddRef((LPDIRECTSOUND)ds);
*pdsb = dsb;
return S_OK;
}
......@@ -219,6 +219,16 @@ HRESULT WINAPI IKsBufferPropertySetImpl_Create(
return S_OK;
}
HRESULT WINAPI IKsBufferPropertySetImpl_Destroy(
IKsBufferPropertySetImpl *piks)
{
TRACE("(%p)\n",piks);
while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0);
return S_OK;
}
/*******************************************************************************
* IKsPrivatePropertySet
*/
......@@ -258,7 +268,7 @@ static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
REFGUID guidPropSet,
LPVOID pPropData,
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
......@@ -282,7 +292,7 @@ static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
ppd->DeviceId = GUID_NULL;
if (pcbReturned) {
*pcbReturned = cbPropData;
*pcbReturned = cbPropData;
FIXME("*pcbReturned=%ld\n", *pcbReturned);
}
......@@ -291,7 +301,7 @@ static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingW(
REFGUID guidPropSet,
LPVOID pPropData,
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
......@@ -315,7 +325,7 @@ static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingW(
ppd->DeviceId = GUID_NULL;
if (pcbReturned) {
*pcbReturned = cbPropData;
*pcbReturned = cbPropData;
FIXME("*pcbReturned=%ld\n", *pcbReturned);
}
......@@ -359,7 +369,7 @@ static HRESULT WINAPI DSPROPERTY_Description1(
ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
GetDeviceID(&ppd->DeviceId, &dev_guid);
if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) {
ULONG wod;
int wodn;
......@@ -475,7 +485,7 @@ static HRESULT WINAPI DSPROPERTY_Description1(
}
if (pcbReturned) {
*pcbReturned = cbPropData;
*pcbReturned = cbPropData;
TRACE("*pcbReturned=%ld\n", *pcbReturned);
}
......@@ -686,7 +696,7 @@ static HRESULT WINAPI DSPROPERTY_DescriptionW(
ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
GetDeviceID(&ppd->DeviceId, &dev_guid);
if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
ULONG wod;
int wodn;
......@@ -823,7 +833,7 @@ static HRESULT WINAPI DSPROPERTY_DescriptionW(
}
if (pcbReturned) {
*pcbReturned = cbPropData;
*pcbReturned = cbPropData;
TRACE("*pcbReturned=%ld\n", *pcbReturned);
}
......@@ -906,10 +916,10 @@ static HRESULT WINAPI DSPROPERTY_EnumerateA(
}
if (pcbReturned) {
*pcbReturned = 0;
*pcbReturned = 0;
FIXME("*pcbReturned=%ld\n", *pcbReturned);
}
return E_PROP_ID_UNSUPPORTED;
}
......@@ -942,7 +952,7 @@ static HRESULT WINAPI DSPROPERTY_EnumerateW(
WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
memset(&data, 0, sizeof(data));
data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
data.WaveDeviceId = wod;
......@@ -971,7 +981,7 @@ static HRESULT WINAPI DSPROPERTY_EnumerateW(
WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
memset(&data, 0, sizeof(data));
data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
data.WaveDeviceId = wid;
......@@ -998,10 +1008,10 @@ static HRESULT WINAPI DSPROPERTY_EnumerateW(
}
if (pcbReturned) {
*pcbReturned = 0;
*pcbReturned = 0;
FIXME("*pcbReturned=%ld\n", *pcbReturned);
}
return E_PROP_ID_UNSUPPORTED;
}
......@@ -1046,7 +1056,7 @@ static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
}
if (pcbReturned) {
*pcbReturned = 0;
*pcbReturned = 0;
FIXME("*pcbReturned=%ld\n", *pcbReturned);
}
......
......@@ -207,7 +207,7 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
TRACE("(%p)\n",dsb);
/* initial buffer volume */
lVolume = dsb->ds3db_lVolume;
lVolume = dsb->ds3db_lVolume;
switch (dsb->ds3db_ds3db.dwMode)
{
......@@ -448,8 +448,8 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation(
{
ICOM_THIS(IDirectSound3DBufferImpl,iface);
TRACE("returning: Cone Orientation vector = (%f,%f,%f)\n",
This->dsb->ds3db_ds3db.vConeOrientation.x,
This->dsb->ds3db_ds3db.vConeOrientation.y,
This->dsb->ds3db_ds3db.vConeOrientation.x,
This->dsb->ds3db_ds3db.vConeOrientation.y,
This->dsb->ds3db_ds3db.vConeOrientation.z);
*lpvConeOrientation = This->dsb->ds3db_ds3db.vConeOrientation;
return DS_OK;
......@@ -770,6 +770,16 @@ HRESULT WINAPI IDirectSound3DBufferImpl_Create(
return S_OK;
}
HRESULT WINAPI IDirectSound3DBufferImpl_Destroy(
IDirectSound3DBufferImpl *pds3db)
{
TRACE("(%p)\n",pds3db);
while (IDirectSound3DBufferImpl_Release((LPDIRECTSOUND3DBUFFER)pds3db) > 0);
return S_OK;
}
/*******************************************************************************
* IDirectSound3DListener
*/
......@@ -835,7 +845,6 @@ static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER i
/* Free all resources */
if( ulReturn == 0 ) {
IDirectSound8_Release((LPDIRECTSOUND8)This->dsound);
This->dsound->listener = 0;
HeapFree(GetProcessHeap(),0,This);
TRACE("(%p) released\n",This);
......@@ -1134,8 +1143,6 @@ HRESULT WINAPI IDirectSound3DListenerImpl_Create(
dsl->dsound->ds3dl_need_recalc = TRUE;
IDirectSound8_AddRef((LPDIRECTSOUND8)This->dsound);
*pdsl = dsl;
return S_OK;
}
......@@ -325,6 +325,39 @@ static HRESULT test_dsound(LPGUID lpGuid)
} else
return rc;
/* Create a DirectSound object */
rc=DirectSoundCreate(lpGuid,&dso,NULL);
ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
LPDIRECTSOUNDBUFFER secondary;
DSBUFFERDESC bufdesc;
WAVEFORMATEX wfx;
init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
ZeroMemory(&bufdesc, sizeof(bufdesc));
bufdesc.dwSize=sizeof(bufdesc);
bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
bufdesc.lpwfxFormat=&wfx;
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) {
LPDIRECTSOUND3DBUFFER buffer3d;
rc=IDirectSound_QueryInterface(secondary, &IID_IDirectSound3DBuffer, (void **)&buffer3d);
ok(rc==DS_OK && buffer3d!=NULL,"QueryInterface failed: %s\n",DXGetErrorString9(rc));
/* add some more refs */
IDirectSound3DBuffer_AddRef(buffer3d);
IDirectSoundBuffer_AddRef(secondary);
}
/* release with buffer */
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;
return DS_OK;
}
......@@ -415,6 +448,39 @@ static HRESULT test_dsound8(LPGUID lpGuid)
} else
return rc;
/* Create a DirectSound8 object */
rc=DirectSoundCreate8(lpGuid,&dso,NULL);
ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
LPDIRECTSOUNDBUFFER secondary;
DSBUFFERDESC bufdesc;
WAVEFORMATEX wfx;
init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
ZeroMemory(&bufdesc, sizeof(bufdesc));
bufdesc.dwSize=sizeof(bufdesc);
bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
bufdesc.lpwfxFormat=&wfx;
rc=IDirectSound8_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) {
LPDIRECTSOUND3DBUFFER buffer3d;
rc=IDirectSound8_QueryInterface(secondary, &IID_IDirectSound3DBuffer, (void **)&buffer3d);
ok(rc==DS_OK && buffer3d!=NULL,"QueryInterface failed: %s\n",DXGetErrorString9(rc));
/* add some more refs */
IDirectSound3DBuffer_AddRef(buffer3d);
IDirectSoundBuffer8_AddRef(secondary);
}
/* release with buffer */
ref=IDirectSound8_Release(dso);
ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
if (ref!=0)
return DSERR_GENERIC;
} else
return rc;
return DS_OK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment