dsound: Merge IUnknown into the main DirectSound object.
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c
index b8c3d8b..6ce01b2 100644
--- a/dlls/dsound/dsound.c
+++ b/dlls/dsound/dsound.c
@@ -44,14 +44,6 @@
/*****************************************************************************
* IDirectSound COM components
*/
-struct IDirectSound_IUnknown {
- const IUnknownVtbl *lpVtbl;
- LONG ref;
- LPDIRECTSOUND8 pds;
-};
-
-static HRESULT IDirectSound_IUnknown_Create(LPDIRECTSOUND8 pds, LPUNKNOWN * ppunk);
-
struct IDirectSound_IDirectSound {
const IDirectSoundVtbl *lpVtbl;
LONG ref;
@@ -72,20 +64,15 @@
static HRESULT IDirectSound8_IDirectSound8_Create(LPDIRECTSOUND8 pds, LPDIRECTSOUND8 * ppds);
static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(LPDIRECTSOUND8 iface);
-/*****************************************************************************
- * IDirectSound implementation structure
- */
-struct IDirectSoundImpl
-{
- LONG numIfaces;
+typedef struct IDirectSoundImpl {
+ IUnknown IUnknown_iface; /* Separate refcount, not for COM aggregation */
+ LONG ref, numIfaces;
DirectSoundDevice *device;
BOOL has_ds8;
- LPUNKNOWN pUnknown;
LPDIRECTSOUND pDS;
LPDIRECTSOUND8 pDS8;
-};
+} IDirectSoundImpl;
-static ULONG WINAPI IDirectSound_IUnknown_AddRef(LPUNKNOWN iface);
static ULONG WINAPI IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface);
const char * dumpCooperativeLevel(DWORD level)
@@ -172,16 +159,8 @@
}
if (IsEqualIID(riid, &IID_IUnknown)) {
- if (!This->pUnknown) {
- IDirectSound_IUnknown_Create(iface, &This->pUnknown);
- if (!This->pUnknown) {
- WARN("IDirectSound_IUnknown_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSound_IUnknown_AddRef(This->pUnknown);
- *ppobj = This->pUnknown;
+ IUnknown_AddRef(&This->IUnknown_iface);
+ *ppobj = &This->IUnknown_iface;
return S_OK;
} else if (IsEqualIID(riid, &IID_IDirectSound)) {
if (!This->pDS) {
@@ -223,84 +202,53 @@
}
/*******************************************************************************
- * IDirectSound_IUnknown
+ * IUnknown Implementation for DirectSound
*/
-static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
- LPUNKNOWN iface,
- REFIID riid,
- LPVOID * ppobj)
+static inline IDirectSoundImpl *impl_from_IUnknown(IUnknown *iface)
{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return DSOUND_QueryInterface(This->pds, riid, ppobj);
+ return CONTAINING_RECORD(iface, IDirectSoundImpl, IUnknown_iface);
}
-static ULONG WINAPI IDirectSound_IUnknown_AddRef(
- LPUNKNOWN iface)
+static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
+ IDirectSoundImpl *This = impl_from_IUnknown(iface);
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
+ return DSOUND_QueryInterface((IDirectSound8 *)This, riid, ppv);
+}
+
+static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
+{
+ IDirectSoundImpl *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 IDirectSound_IUnknown_Release(
- LPUNKNOWN iface)
+static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref && !InterlockedDecrement(&((IDirectSoundImpl *)This->pds)->numIfaces)) {
- ((IDirectSoundImpl*)This->pds)->pUnknown = NULL;
- directsound_destroy((IDirectSoundImpl*)This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
+ IDirectSoundImpl *This = impl_from_IUnknown(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ directsound_destroy(This);
+
return ref;
}
-static const IUnknownVtbl DirectSound_Unknown_Vtbl =
+static const IUnknownVtbl unk_vtbl =
{
- IDirectSound_IUnknown_QueryInterface,
- IDirectSound_IUnknown_AddRef,
- IDirectSound_IUnknown_Release
+ IUnknownImpl_QueryInterface,
+ IUnknownImpl_AddRef,
+ IUnknownImpl_Release
};
-static HRESULT IDirectSound_IUnknown_Create(
- LPDIRECTSOUND8 pds,
- LPUNKNOWN * ppunk)
-{
- IDirectSound_IUnknown * pdsunk;
- TRACE("(%p,%p)\n",pds,ppunk);
-
- if (ppunk == NULL) {
- ERR("invalid parameter: ppunk == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppunk = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
- if (pdsunk == NULL) {
- WARN("out of memory\n");
- *ppunk = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsunk->lpVtbl = &DirectSound_Unknown_Vtbl;
- pdsunk->ref = 0;
- pdsunk->pds = pds;
-
- InterlockedIncrement(&((IDirectSoundImpl *)pds)->numIfaces);
- *ppunk = (LPUNKNOWN)pdsunk;
-
- return DS_OK;
-}
-
/*******************************************************************************
* IDirectSound_IDirectSound
*/
@@ -646,6 +594,8 @@
return DSERR_OUTOFMEMORY;
}
+ obj->IUnknown_iface.lpVtbl = &unk_vtbl;
+ obj->ref = 0;
obj->numIfaces = 0;
obj->device = NULL;
obj->has_ds8 = has_ds8;
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index c2449b3..8d361bc 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -39,8 +39,6 @@
/*****************************************************************************
* Predeclare the interface implementation structures
*/
-typedef struct IDirectSoundImpl IDirectSoundImpl;
-typedef struct IDirectSound_IUnknown IDirectSound_IUnknown;
typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound;
typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8;
typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;