Properly implement DllCanUnloadNow ref counting.
authorJames Hawkins <truiken@gmail.com>
Tue, 1 Feb 2005 14:21:37 +0000 (14:21 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 1 Feb 2005 14:21:37 +0000 (14:21 +0000)
dlls/dswave/dswave.c
dlls/dswave/dswave_main.c
dlls/dswave/dswave_private.h
dlls/dxdiagn/container.c
dlls/dxdiagn/dxdiag_main.c
dlls/dxdiagn/dxdiag_private.h
dlls/dxdiagn/provider.c

index de9a8bb20c8e5eb9c6c836e876aba15e949d12d6..08c076df51cf06b72d9258091ed96c22f5f59e8a 100644 (file)
@@ -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;
 }
 
index 3c7c1a2f5e44f62ce59c3e22d3cc2e391d6cd952..3a5a36a3ad04694abde84d0fcc51658cc8d0cf92 100644 (file)
 
 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;
 }
 
 
index 6697c650320772d09ff58644e7272c5ecbd22da1..940e4010a4fac99e5954a1149d54bfbd03a52327 100644 (file)
@@ -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.
index eca1f0c418a5700b80769032feb81eea4aba3026..5b861f06176ea8250a693b017a664457481a026a 100644 (file)
@@ -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;
 }
 
index 71dadc70b51c050855768bd65fea692417646f13..6938ae0f1e34dc5beb1d9a3a4822cd963af72469 100644 (file)
@@ -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;
 }
 
 /***********************************************************************
index 0d526e62a44db0c6fc8e6751252ac8b03eff14cc..d32f75370329950e3a3f1235c5c2acab3902208d 100644 (file)
@@ -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
index eafd124da3cf1e7c185c2b8c2df7ae229a103808..9f586e7bd436deae318153c69d0824f8a2ff401f 100644 (file)
@@ -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;
 }