From a85da70304d8c18b79c74c8a646c4f770db68cea Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Tue, 1 Feb 2005 14:21:37 +0000 Subject: [PATCH] Properly implement DllCanUnloadNow ref counting. --- dlls/dswave/dswave.c | 5 +++++ dlls/dswave/dswave_main.c | 39 +++++++++++++++++++++++---------------- dlls/dswave/dswave_private.h | 6 ++++++ dlls/dxdiagn/container.c | 5 +++++ dlls/dxdiagn/dxdiag_main.c | 37 ++++++++++++++++++++++--------------- dlls/dxdiagn/dxdiag_private.h | 7 ++++++- dlls/dxdiagn/provider.c | 5 +++++ 7 files changed, 72 insertions(+), 32 deletions(-) diff --git a/dlls/dswave/dswave.c b/dlls/dswave/dswave.c index de9a8bb20c8..08c076df51c 100644 --- a/dlls/dswave/dswave.c +++ b/dlls/dswave/dswave.c @@ -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; } diff --git a/dlls/dswave/dswave_main.c b/dlls/dswave/dswave_main.c index 3c7c1a2f5e4..3a5a36a3ad0 100644 --- a/dlls/dswave/dswave_main.c +++ b/dlls/dswave/dswave_main.c @@ -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; } diff --git a/dlls/dswave/dswave_private.h b/dlls/dswave/dswave_private.h index 6697c650320..940e4010a4f 100644 --- a/dlls/dswave/dswave_private.h +++ b/dlls/dswave/dswave_private.h @@ -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. diff --git a/dlls/dxdiagn/container.c b/dlls/dxdiagn/container.c index eca1f0c418a..5b861f06176 100644 --- a/dlls/dxdiagn/container.c +++ b/dlls/dxdiagn/container.c @@ -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; } diff --git a/dlls/dxdiagn/dxdiag_main.c b/dlls/dxdiagn/dxdiag_main.c index 71dadc70b51..6938ae0f1e3 100644 --- a/dlls/dxdiagn/dxdiag_main.c +++ b/dlls/dxdiagn/dxdiag_main.c @@ -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; } /*********************************************************************** diff --git a/dlls/dxdiagn/dxdiag_private.h b/dlls/dxdiagn/dxdiag_private.h index 0d526e62a44..d32f7537032 100644 --- a/dlls/dxdiagn/dxdiag_private.h +++ b/dlls/dxdiagn/dxdiag_private.h @@ -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 diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c index eafd124da3c..9f586e7bd43 100644 --- a/dlls/dxdiagn/provider.c +++ b/dlls/dxdiagn/provider.c @@ -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; } -- 2.11.4.GIT