dsound: IDirectSoundCapture / IUnknown use separate refcounts.
This commit is contained in:
parent
b8ffb4930f
commit
9383affe87
|
@ -995,67 +995,124 @@ static HRESULT DirectSoundCaptureDevice_Initialize(
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* IDirectSoundCapture implementation structure
|
* IDirectSoundCapture implementation structure
|
||||||
*/
|
*/
|
||||||
struct IDirectSoundCaptureImpl
|
typedef struct IDirectSoundCaptureImpl
|
||||||
{
|
{
|
||||||
|
IUnknown IUnknown_iface; /* Separate refcount */
|
||||||
IDirectSoundCapture IDirectSoundCapture_iface;
|
IDirectSoundCapture IDirectSoundCapture_iface;
|
||||||
LONG ref;
|
LONG ref, refdsc, numIfaces;
|
||||||
DirectSoundCaptureDevice *device;
|
DirectSoundCaptureDevice *device;
|
||||||
BOOL has_dsc8;
|
BOOL has_dsc8;
|
||||||
|
} IDirectSoundCaptureImpl;
|
||||||
|
|
||||||
|
static void capture_destroy(IDirectSoundCaptureImpl *This)
|
||||||
|
{
|
||||||
|
if (This->device)
|
||||||
|
DirectSoundCaptureDevice_Release(This->device);
|
||||||
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
TRACE("(%p) released\n", This);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* IUnknown Implementation for DirectSoundCapture
|
||||||
|
*/
|
||||||
|
static inline IDirectSoundCaptureImpl *impl_from_IUnknown(IUnknown *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, IDirectSoundCaptureImpl, IUnknown_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
|
||||||
|
|
||||||
|
TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
|
||||||
|
|
||||||
|
if (!ppv) {
|
||||||
|
WARN("invalid parameter\n");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
*ppv = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown))
|
||||||
|
*ppv = &This->IUnknown_iface;
|
||||||
|
else if (IsEqualIID(riid, &IID_IDirectSoundCapture))
|
||||||
|
*ppv = &This->IDirectSoundCapture_iface;
|
||||||
|
else {
|
||||||
|
WARN("unknown IID %s\n", debugstr_guid(riid));
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IUnknown_AddRef((IUnknown*)*ppv);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
|
||||||
|
{
|
||||||
|
IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
|
||||||
|
ULONG ref = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%d\n", This, ref);
|
||||||
|
|
||||||
|
if(ref == 1)
|
||||||
|
InterlockedIncrement(&This->numIfaces);
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
|
||||||
|
{
|
||||||
|
IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
|
||||||
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%d\n", This, ref);
|
||||||
|
|
||||||
|
if (!ref && !InterlockedDecrement(&This->numIfaces))
|
||||||
|
capture_destroy(This);
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IUnknownVtbl unk_vtbl =
|
||||||
|
{
|
||||||
|
IUnknownImpl_QueryInterface,
|
||||||
|
IUnknownImpl_AddRef,
|
||||||
|
IUnknownImpl_Release
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* IDirectSoundCaptureImpl
|
||||||
|
*/
|
||||||
static inline struct IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
|
static inline struct IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, struct IDirectSoundCaptureImpl, IDirectSoundCapture_iface);
|
return CONTAINING_RECORD(iface, struct IDirectSoundCaptureImpl, IDirectSoundCapture_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* IDirectSoundCaptureImpl
|
|
||||||
*/
|
|
||||||
static HRESULT WINAPI IDirectSoundCaptureImpl_QueryInterface(IDirectSoundCapture *iface,
|
static HRESULT WINAPI IDirectSoundCaptureImpl_QueryInterface(IDirectSoundCapture *iface,
|
||||||
REFIID riid, void **ppobj)
|
REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
TRACE( "(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj );
|
IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
|
||||||
|
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
|
||||||
if (ppobj == NULL) {
|
return IUnknown_QueryInterface(&This->IUnknown_iface, riid, ppv);
|
||||||
WARN("invalid parameter\n");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppobj = NULL;
|
|
||||||
|
|
||||||
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectSoundCapture)) {
|
|
||||||
IDirectSoundCapture_AddRef(iface);
|
|
||||||
*ppobj = iface;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN("unsupported riid: %s\n", debugstr_guid(riid));
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirectSoundCaptureImpl_AddRef(IDirectSoundCapture *iface)
|
static ULONG WINAPI IDirectSoundCaptureImpl_AddRef(IDirectSoundCapture *iface)
|
||||||
{
|
{
|
||||||
IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
|
IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
|
||||||
ULONG ref = InterlockedIncrement(&(This->ref));
|
ULONG ref = InterlockedIncrement(&This->refdsc);
|
||||||
|
|
||||||
TRACE("(%p) ref was %d\n", This, ref - 1);
|
TRACE("(%p) ref=%d\n", This, ref);
|
||||||
|
|
||||||
|
if(ref == 1)
|
||||||
|
InterlockedIncrement(&This->numIfaces);
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirectSoundCaptureImpl_Release(IDirectSoundCapture *iface)
|
static ULONG WINAPI IDirectSoundCaptureImpl_Release(IDirectSoundCapture *iface)
|
||||||
{
|
{
|
||||||
IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
|
IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
|
||||||
ULONG ref = InterlockedDecrement(&(This->ref));
|
ULONG ref = InterlockedDecrement(&This->refdsc);
|
||||||
|
|
||||||
TRACE("(%p) ref was %d\n", This, ref + 1);
|
TRACE("(%p) ref=%d\n", This, ref);
|
||||||
|
|
||||||
if (!ref) {
|
if (!ref && !InterlockedDecrement(&This->numIfaces))
|
||||||
if (This->device)
|
capture_destroy(This);
|
||||||
DirectSoundCaptureDevice_Release(This->device);
|
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, This );
|
|
||||||
TRACE("(%p) released\n", This);
|
|
||||||
}
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1178,13 +1235,16 @@ static HRESULT IDirectSoundCaptureImpl_Create(REFIID riid, void **ppv, BOOL has_
|
||||||
|
|
||||||
setup_dsound_options();
|
setup_dsound_options();
|
||||||
|
|
||||||
|
obj->IUnknown_iface.lpVtbl = &unk_vtbl;
|
||||||
obj->IDirectSoundCapture_iface.lpVtbl = &dscvt;
|
obj->IDirectSoundCapture_iface.lpVtbl = &dscvt;
|
||||||
obj->ref = 1;
|
obj->ref = 1;
|
||||||
|
obj->refdsc = 0;
|
||||||
|
obj->numIfaces = 1;
|
||||||
obj->device = NULL;
|
obj->device = NULL;
|
||||||
obj->has_dsc8 = has_dsc8;
|
obj->has_dsc8 = has_dsc8;
|
||||||
|
|
||||||
hr = IDirectSoundCapture_QueryInterface(&obj->IDirectSoundCapture_iface, riid, ppv);
|
hr = IUnknown_QueryInterface(&obj->IUnknown_iface, riid, ppv);
|
||||||
IDirectSoundCapture_Release(&obj->IDirectSoundCapture_iface);
|
IUnknown_Release(&obj->IUnknown_iface);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ extern int ds_default_bits_per_sample DECLSPEC_HIDDEN;
|
||||||
* Predeclare the interface implementation structures
|
* Predeclare the interface implementation structures
|
||||||
*/
|
*/
|
||||||
typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
|
typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
|
||||||
typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
|
|
||||||
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
|
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
|
||||||
typedef struct DirectSoundDevice DirectSoundDevice;
|
typedef struct DirectSoundDevice DirectSoundDevice;
|
||||||
typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
|
typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
|
||||||
|
|
Loading…
Reference in New Issue