Commit a85da703 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

Properly implement DllCanUnloadNow ref counting.

parent 54df9ada
......@@ -68,6 +68,8 @@ ULONG WINAPI IDirectMusicWaveImpl_IUnknown_AddRef (LPUNKNOWN iface) {
TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1);
DSWAVE_LockModule();
return refCount;
}
......@@ -80,6 +82,9 @@ ULONG WINAPI IDirectMusicWaveImpl_IUnknown_Release (LPUNKNOWN iface) {
if (!refCount) {
HeapFree(GetProcessHeap(), 0, This);
}
DSWAVE_UnlockModule();
return refCount;
}
......
......@@ -23,41 +23,49 @@
WINE_DEFAULT_DEBUG_CHANNEL(dswave);
LONG DSWAVE_refCount = 0;
typedef struct {
/* IUnknown fields */
IClassFactoryVtbl *lpVtbl;
DWORD ref;
} IClassFactoryImpl;
/******************************************************************
* DirectMusicWave ClassFactory
*/
static HRESULT WINAPI WaveCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("(%p, %s, %p): stub\n", This, debugstr_dmguid(riid), ppobj);
FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
if (ppobj == NULL) return E_POINTER;
return E_NOINTERFACE;
}
static ULONG WINAPI WaveCF_AddRef(LPCLASSFACTORY iface) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
return InterlockedIncrement(&This->ref);
DSWAVE_LockModule();
return 2; /* non-heap based object */
}
static ULONG WINAPI WaveCF_Release(LPCLASSFACTORY iface) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
/* static class, won't be freed */
return InterlockedDecrement(&This->ref);
DSWAVE_UnlockModule();
return 1; /* non-heap based object */
}
static HRESULT WINAPI WaveCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
TRACE ("(%p, %p, %s, %p)\n", This, pOuter, debugstr_dmguid(riid), ppobj);
TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
return DMUSIC_CreateDirectMusicWaveImpl (riid, ppobj, pOuter);
}
static HRESULT WINAPI WaveCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("(%p, %d): stub\n", This, dolock);
TRACE("(%d)\n", dolock);
if (dolock)
DSWAVE_LockModule();
else
DSWAVE_UnlockModule();
return S_OK;
}
......@@ -69,7 +77,7 @@ static IClassFactoryVtbl WaveCF_Vtbl = {
WaveCF_LockServer
};
static IClassFactoryImpl Wave_CF = {&WaveCF_Vtbl, 1 };
static IClassFactoryImpl Wave_CF = {&WaveCF_Vtbl};
/******************************************************************
* DllMain
......@@ -94,8 +102,7 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
*
*/
HRESULT WINAPI DSWAVE_DllCanUnloadNow(void) {
FIXME("(void): stub\n");
return S_FALSE;
return DSWAVE_refCount != 0 ? S_FALSE : S_OK;
}
......
......@@ -130,6 +130,12 @@ extern HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_Load (LPPERSISTSTREAM
extern HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty);
extern HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize);
/**********************************************************************
* Dll lifetime tracking declaration for dswave.dll
*/
extern LONG DSWAVE_refCount;
static inline void DSWAVE_LockModule() { InterlockedIncrement( &DSWAVE_refCount ); }
static inline void DSWAVE_UnlockModule() { InterlockedDecrement( &DSWAVE_refCount ); }
/*****************************************************************************
* Misc.
......
......@@ -48,6 +48,8 @@ ULONG WINAPI IDxDiagContainerImpl_AddRef(PDXDIAGCONTAINER iface) {
TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1);
DXDIAGN_LockModule();
return refCount;
}
......@@ -60,6 +62,9 @@ ULONG WINAPI IDxDiagContainerImpl_Release(PDXDIAGCONTAINER iface) {
if (!refCount) {
HeapFree(GetProcessHeap(), 0, This);
}
DXDIAGN_UnlockModule();
return refCount;
}
......
......@@ -25,6 +25,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
LONG DXDIAGN_refCount = 0;
/* At process attach */
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
......@@ -39,41 +41,46 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
* DXDiag ClassFactory
*/
typedef struct {
/* IUnknown fields */
IClassFactoryVtbl *lpVtbl;
DWORD ref;
REFCLSID rclsid;
HRESULT (*pfnCreateInstanceFactory)(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
} IClassFactoryImpl;
static HRESULT WINAPI DXDiagCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
if (ppobj == NULL) return E_POINTER;
FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
return E_NOINTERFACE;
}
static ULONG WINAPI DXDiagCF_AddRef(LPCLASSFACTORY iface) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
return InterlockedIncrement(&This->ref);
DXDIAGN_LockModule();
return 2; /* non-heap based object */
}
static ULONG WINAPI DXDiagCF_Release(LPCLASSFACTORY iface) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
/* static class, won't be freed */
return InterlockedDecrement(&This->ref);
DXDIAGN_UnlockModule();
return 1; /* non-heap based object */
}
static HRESULT WINAPI DXDiagCF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
return This->pfnCreateInstanceFactory(iface, pOuter, riid, ppobj);
}
static HRESULT WINAPI DXDiagCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("(%p)->(%d),stub!\n",This,dolock);
TRACE("(%d)\n", dolock);
if (dolock)
DXDIAGN_LockModule();
else
DXDIAGN_UnlockModule();
return S_OK;
}
......@@ -86,8 +93,8 @@ static IClassFactoryVtbl DXDiagCF_Vtbl = {
};
static IClassFactoryImpl DXDiag_CFS[] = {
{ &DXDiagCF_Vtbl, 1, &CLSID_DxDiagProvider, DXDiag_CreateDXDiagProvider },
{ NULL, 0, NULL, NULL }
{ &DXDiagCF_Vtbl, &CLSID_DxDiagProvider, DXDiag_CreateDXDiagProvider },
{ NULL, NULL, NULL }
};
/***********************************************************************
......@@ -95,7 +102,7 @@ static IClassFactoryImpl DXDiag_CFS[] = {
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
return S_FALSE;
return DXDIAGN_refCount != 0 ? S_FALSE : S_OK;
}
/***********************************************************************
......
......@@ -129,6 +129,11 @@ extern HRESULT DXDiag_CreateDXDiagProvider(LPCLASSFACTORY iface, LPUNKNOWN punkO
extern HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, LPVOID *ppobj);
extern HRESULT DXDiag_InitRootDXDiagContainer(IDxDiagContainer* pRootCont);
/**********************************************************************
* Dll lifetime tracking declaration for dxdiagn.dll
*/
extern LONG DXDIAGN_refCount;
static inline void DXDIAGN_LockModule() { InterlockedIncrement( &DXDIAGN_refCount ); }
static inline void DXDIAGN_UnlockModule() { InterlockedDecrement( &DXDIAGN_refCount ); }
#endif
......@@ -47,6 +47,8 @@ ULONG WINAPI IDxDiagProviderImpl_AddRef(PDXDIAGPROVIDER iface) {
TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1);
DXDIAGN_LockModule();
return refCount;
}
......@@ -59,6 +61,9 @@ ULONG WINAPI IDxDiagProviderImpl_Release(PDXDIAGPROVIDER iface) {
if (!refCount) {
HeapFree(GetProcessHeap(), 0, This);
}
DXDIAGN_UnlockModule();
return refCount;
}
......
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