Properly implement DllCanUnloadNow ref counting.
This commit is contained in:
parent
54df9adabc
commit
a85da70304
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue