Sync to Wine-20050211
James Hawkins <truiken@gmail.com>
- Properly implement DllCanUnloadNow ref counting. Make sure the mozilla
  control is ready to unload as well.
- Use Interlocked* instead of ++/-- in AddRef/Release.
- Use only stored result of Interlocked* in AddRef/Release.
- Expand TRACEs to display the ref count.
Mike McCormack <mike@codeweavers.com>
- Stub definition for OpenUrl.
Modified: trunk/reactos/lib/shdocvw/classinfo.c
Modified: trunk/reactos/lib/shdocvw/events.c
Modified: trunk/reactos/lib/shdocvw/factory.c
Modified: trunk/reactos/lib/shdocvw/misc.c
Modified: trunk/reactos/lib/shdocvw/oleobject.c
Modified: trunk/reactos/lib/shdocvw/persist.c
Modified: trunk/reactos/lib/shdocvw/shdocvw.h
Modified: trunk/reactos/lib/shdocvw/shdocvw.spec
Modified: trunk/reactos/lib/shdocvw/shdocvw_main.c
Modified: trunk/reactos/lib/shdocvw/webbrowser.c

Modified: trunk/reactos/lib/shdocvw/classinfo.c
--- trunk/reactos/lib/shdocvw/classinfo.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/classinfo.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -38,27 +38,25 @@
 static HRESULT WINAPI WBPCI_QueryInterface(LPPROVIDECLASSINFO iface,
                                            REFIID riid, LPVOID *ppobj)
 {
-    IProvideClassInfoImpl *This = (IProvideClassInfoImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBPCI_AddRef(LPPROVIDECLASSINFO iface)
 {
-    IProvideClassInfoImpl *This = (IProvideClassInfoImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBPCI_Release(LPPROVIDECLASSINFO iface)
 {
-    IProvideClassInfoImpl *This = (IProvideClassInfoImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 /* Return an ITypeInfo interface to retrieve type library info about
@@ -82,7 +80,7 @@
     WBPCI_GetClassInfo
 };
 
-IProvideClassInfoImpl SHDOCVW_ProvideClassInfo = { &WBPCI_Vtbl, 1 };
+IProvideClassInfoImpl SHDOCVW_ProvideClassInfo = { &WBPCI_Vtbl};
 
 
 /**********************************************************************
@@ -93,27 +91,25 @@
 static HRESULT WINAPI WBPCI2_QueryInterface(LPPROVIDECLASSINFO2 iface,
                                             REFIID riid, LPVOID *ppobj)
 {
-    IProvideClassInfo2Impl *This = (IProvideClassInfo2Impl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBPCI2_AddRef(LPPROVIDECLASSINFO2 iface)
 {
-    IProvideClassInfo2Impl *This = (IProvideClassInfo2Impl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBPCI2_Release(LPPROVIDECLASSINFO2 iface)
 {
-    IProvideClassInfo2Impl *This = (IProvideClassInfo2Impl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 /* Return an ITypeInfo interface to retrieve type library info about
@@ -167,4 +163,4 @@
     WBPCI2_GetGUID
 };
 
-IProvideClassInfo2Impl SHDOCVW_ProvideClassInfo2 = { &WBPCI2_Vtbl, 1 };
+IProvideClassInfo2Impl SHDOCVW_ProvideClassInfo2 = { &WBPCI2_Vtbl};

Modified: trunk/reactos/lib/shdocvw/events.c
--- trunk/reactos/lib/shdocvw/events.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/events.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -38,27 +38,25 @@
 static HRESULT WINAPI WBCPC_QueryInterface(LPCONNECTIONPOINTCONTAINER iface,
                                            REFIID riid, LPVOID *ppobj)
 {
-    IConnectionPointContainerImpl *This = (IConnectionPointContainerImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBCPC_AddRef(LPCONNECTIONPOINTCONTAINER iface)
 {
-    IConnectionPointContainerImpl *This = (IConnectionPointContainerImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBCPC_Release(LPCONNECTIONPOINTCONTAINER iface)
 {
-    IConnectionPointContainerImpl *This = (IConnectionPointContainerImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 /* Get a list of connection points inside this container. */
@@ -112,7 +110,7 @@
     WBCPC_FindConnectionPoint
 };
 
-IConnectionPointContainerImpl SHDOCVW_ConnectionPointContainer = { &WBCPC_Vtbl, 1 };
+IConnectionPointContainerImpl SHDOCVW_ConnectionPointContainer = {&WBCPC_Vtbl};
 
 
 /**********************************************************************
@@ -122,27 +120,25 @@
 static HRESULT WINAPI WBCP_QueryInterface(LPCONNECTIONPOINT iface,
                                           REFIID riid, LPVOID *ppobj)
 {
-    IConnectionPointImpl *This = (IConnectionPointImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBCP_AddRef(LPCONNECTIONPOINT iface)
 {
-    IConnectionPointImpl *This = (IConnectionPointImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBCP_Release(LPCONNECTIONPOINT iface)
 {
-    IConnectionPointImpl *This = (IConnectionPointImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 static HRESULT WINAPI WBCP_GetConnectionInterface(LPCONNECTIONPOINT iface, IID* pIId)
@@ -209,4 +205,4 @@
     WBCP_EnumConnections
 };
 
-IConnectionPointImpl SHDOCVW_ConnectionPoint = { &WBCP_Vtbl, 1 };
+IConnectionPointImpl SHDOCVW_ConnectionPoint = {&WBCP_Vtbl};

Modified: trunk/reactos/lib/shdocvw/factory.c
--- trunk/reactos/lib/shdocvw/factory.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/factory.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -36,16 +36,10 @@
 static HRESULT WINAPI WBCF_QueryInterface(LPCLASSFACTORY iface,
                                           REFIID riid, LPVOID *ppobj)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
-
-    TRACE ("\n");
-
-    /*
-     * Perform a sanity check on the parameters.
-     */
-    if ((This == NULL) || (ppobj == NULL) )
-        return E_INVALIDARG;
-
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
+    
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
@@ -54,10 +48,9 @@
  */
 static ULONG WINAPI WBCF_AddRef(LPCLASSFACTORY iface)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 /************************************************************************
@@ -65,11 +58,9 @@
  */
 static ULONG WINAPI WBCF_Release(LPCLASSFACTORY iface)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 /************************************************************************
@@ -104,8 +95,13 @@
  */
 static HRESULT WINAPI WBCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
 {
-    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
-    FIXME("(%p)->(%d),stub!\n", This, dolock);
+    TRACE("(%d)\n", dolock);
+
+    if (dolock)
+	    SHDOCVW_LockModule();
+    else
+	    SHDOCVW_UnlockModule();
+    
     return S_OK;
 }
 
@@ -118,4 +114,4 @@
     WBCF_LockServer
 };
 
-IClassFactoryImpl SHDOCVW_ClassFactory = { &WBCF_Vtbl, 1 };
+IClassFactoryImpl SHDOCVW_ClassFactory = {&WBCF_Vtbl};

Modified: trunk/reactos/lib/shdocvw/misc.c
--- trunk/reactos/lib/shdocvw/misc.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/misc.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -32,27 +32,25 @@
 static HRESULT WINAPI WBQA_QueryInterface(LPQUICKACTIVATE iface,
                                           REFIID riid, LPVOID *ppobj)
 {
-    IQuickActivateImpl *This = (IQuickActivateImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBQA_AddRef(LPQUICKACTIVATE iface)
 {
-    IQuickActivateImpl *This = (IQuickActivateImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBQA_Release(LPQUICKACTIVATE iface)
 {
-    IQuickActivateImpl *This = (IQuickActivateImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 /* Alternative interface for quicker, easier activation of a control. */
@@ -90,4 +88,12 @@
     WBQA_GetContentExtent
 };
 
-IQuickActivateImpl SHDOCVW_QuickActivate = { &WBQA_Vtbl, 1 };
+IQuickActivateImpl SHDOCVW_QuickActivate = {&WBQA_Vtbl};
+
+/**********************************************************************
+ * OpenURL  (SHDOCVW.@)
+ */
+void WINAPI OpenURL(HWND hWnd, HINSTANCE hInst, LPCSTR lpcstrUrl, int nShowCmd)
+{
+    FIXME("%p %p %s %d\n", hWnd, hInst, debugstr_a(lpcstrUrl), nShowCmd);
+}

Modified: trunk/reactos/lib/shdocvw/oleobject.c
--- trunk/reactos/lib/shdocvw/oleobject.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/oleobject.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -143,10 +143,9 @@
  */
 static ULONG WINAPI WBOOBJ_AddRef(LPOLEOBJECT iface)
 {
-    IOleObjectImpl *This = (IOleObjectImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 /************************************************************************
@@ -154,11 +153,9 @@
  */
 static ULONG WINAPI WBOOBJ_Release(LPOLEOBJECT iface)
 {
-    IOleObjectImpl *This = (IOleObjectImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 /************************************************************************
@@ -438,7 +435,7 @@
     WBOOBJ_SetColorScheme
 };
 
-IOleObjectImpl SHDOCVW_OleObject = { &WBOOBJ_Vtbl, 1 };
+IOleObjectImpl SHDOCVW_OleObject = {&WBOOBJ_Vtbl};
 
 
 /**********************************************************************
@@ -448,27 +445,25 @@
 static HRESULT WINAPI WBOIPO_QueryInterface(LPOLEINPLACEOBJECT iface,
                                             REFIID riid, LPVOID *ppobj)
 {
-    IOleInPlaceObjectImpl *This = (IOleInPlaceObjectImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBOIPO_AddRef(LPOLEINPLACEOBJECT iface)
 {
-    IOleInPlaceObjectImpl *This = (IOleInPlaceObjectImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBOIPO_Release(LPOLEINPLACEOBJECT iface)
 {
-    IOleInPlaceObjectImpl *This = (IOleInPlaceObjectImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 static HRESULT WINAPI WBOIPO_GetWindow(LPOLEINPLACEOBJECT iface, HWND* phwnd)
@@ -540,7 +535,7 @@
     WBOIPO_ReactivateAndUndo
 };
 
-IOleInPlaceObjectImpl SHDOCVW_OleInPlaceObject = { &WBOIPO_Vtbl, 1 };
+IOleInPlaceObjectImpl SHDOCVW_OleInPlaceObject = {&WBOIPO_Vtbl};
 
 
 /**********************************************************************
@@ -550,27 +545,25 @@
 static HRESULT WINAPI WBOC_QueryInterface(LPOLECONTROL iface,
                                           REFIID riid, LPVOID *ppobj)
 {
-    IOleControlImpl *This = (IOleControlImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBOC_AddRef(LPOLECONTROL iface)
 {
-    IOleControlImpl *This = (IOleControlImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBOC_Release(LPOLECONTROL iface)
 {
-    IOleControlImpl *This = (IOleControlImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 static HRESULT WINAPI WBOC_GetControlInfo(LPOLECONTROL iface, LPCONTROLINFO pCI)
@@ -612,4 +605,4 @@
     WBOC_FreezeEvents
 };
 
-IOleControlImpl SHDOCVW_OleControl = { &WBOC_Vtbl, 1 };
+IOleControlImpl SHDOCVW_OleControl = {&WBOC_Vtbl};

Modified: trunk/reactos/lib/shdocvw/persist.c
--- trunk/reactos/lib/shdocvw/persist.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/persist.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -30,27 +30,25 @@
 static HRESULT WINAPI WBPS_QueryInterface(LPPERSISTSTORAGE iface,
                                           REFIID riid, LPVOID *ppobj)
 {
-    IPersistStorageImpl *This = (IPersistStorageImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBPS_AddRef(LPPERSISTSTORAGE iface)
 {
-    IPersistStorageImpl *This = (IPersistStorageImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBPS_Release(LPPERSISTSTORAGE iface)
 {
-    IPersistStorageImpl *This = (IPersistStorageImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 static HRESULT WINAPI WBPS_GetClassID(LPPERSISTSTORAGE iface, CLSID *pClassID)
@@ -107,7 +105,7 @@
     WBPS_SaveCompleted
 };
 
-IPersistStorageImpl SHDOCVW_PersistStorage = { &WBPS_Vtbl, 1 };
+IPersistStorageImpl SHDOCVW_PersistStorage = {&WBPS_Vtbl};
 
 
 /**********************************************************************
@@ -117,27 +115,25 @@
 static HRESULT WINAPI WBPSI_QueryInterface(LPPERSISTSTREAMINIT iface,
                                            REFIID riid, LPVOID *ppobj)
 {
-    IPersistStreamInitImpl *This = (IPersistStreamInitImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WBPSI_AddRef(LPPERSISTSTREAMINIT iface)
 {
-    IPersistStreamInitImpl *This = (IPersistStreamInitImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WBPSI_Release(LPPERSISTSTREAMINIT iface)
 {
-    IPersistStreamInitImpl *This = (IPersistStreamInitImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 static HRESULT WINAPI WBPSI_GetClassID(LPPERSISTSTREAMINIT iface, CLSID *pClassID)
@@ -195,4 +191,4 @@
     WBPSI_InitNew
 };
 
-IPersistStreamInitImpl SHDOCVW_PersistStreamInit = { &WBPSI_Vtbl, 1 };
+IPersistStreamInitImpl SHDOCVW_PersistStreamInit = {&WBPSI_Vtbl};

Modified: trunk/reactos/lib/shdocvw/shdocvw.h
--- trunk/reactos/lib/shdocvw/shdocvw.h	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/shdocvw.h	2005-02-13 23:10:36 UTC (rev 13551)
@@ -190,4 +190,11 @@
 
 extern IConnectionPointImpl SHDOCVW_ConnectionPoint;
 
+/**********************************************************************
+ * Dll lifetime tracking declaration for shdocvw.dll
+ */
+extern LONG SHDOCVW_refCount;
+static inline void SHDOCVW_LockModule() { InterlockedIncrement( &SHDOCVW_refCount ); }
+static inline void SHDOCVW_UnlockModule() { InterlockedDecrement( &SHDOCVW_refCount ); }
+
 #endif /* __WINE_SHDOCVW_H */

Modified: trunk/reactos/lib/shdocvw/shdocvw.spec
--- trunk/reactos/lib/shdocvw/shdocvw.spec	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/shdocvw.spec	2005-02-13 23:10:36 UTC (rev 13551)
@@ -121,7 +121,7 @@
 @ stub ImportPrivacySettings
 @ stub InstallReg_RunDLL
 @ stub IEWriteErrorLog
-@ stub OpenURL
+@ stdcall OpenURL(long long str long)
 @ stub SHGetIDispatchForFolder
 @ stdcall SetQueryNetSessionCount(long)
 @ stub SoftwareUpdateMessageBox

Modified: trunk/reactos/lib/shdocvw/shdocvw_main.c
--- trunk/reactos/lib/shdocvw/shdocvw_main.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/shdocvw_main.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -47,6 +47,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
 
+LONG SHDOCVW_refCount = 0;
+
 static const WCHAR szMozDlPath[] = {
     'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
     's','h','d','o','c','v','w',0
@@ -55,6 +57,7 @@
 DEFINE_GUID( CLSID_MozillaBrowser, 0x1339B54C,0x3453,0x11D2,0x93,0xB9,0x00,0x00,0x00,0x00,0x00,0x00);
 
 typedef HRESULT (WINAPI *fnGetClassObject)(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
+typedef HRESULT (WINAPI *fnCanUnloadNow)(void);
 
 HINSTANCE shdocvw_hinstance = 0;
 static HMODULE SHDOCVW_hshell32 = 0;
@@ -127,8 +130,21 @@
  */
 HRESULT WINAPI SHDOCVW_DllCanUnloadNow(void)
 {
-    FIXME("(void): stub\n");
+    HRESULT moz_can_unload = S_FALSE;
+    fnCanUnloadNow pCanUnloadNow;
 
+    if (hMozCtl)
+    {
+        pCanUnloadNow = (fnCanUnloadNow)
+            GetProcAddress(hMozCtl, "DllCanUnloadNow");
+        moz_can_unload = pCanUnloadNow();
+    }
+    else
+        moz_can_unload = S_OK;
+
+    if (moz_can_unload == S_OK && SHDOCVW_refCount == 0)
+        return S_OK;
+
     return S_FALSE;
 }
 
@@ -145,6 +161,8 @@
 static HRESULT WINAPI
 dlQueryInterface( IBindStatusCallback* This, REFIID riid, void** ppvObject )
 {
+    if (ppvObject == NULL) return E_POINTER;
+    
     if( IsEqualIID(riid, &IID_IUnknown) ||
         IsEqualIID(riid, &IID_IBindStatusCallback))
     {
@@ -158,6 +176,9 @@
 static ULONG WINAPI dlAddRef( IBindStatusCallback* iface )
 {
     IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
+
+    SHDOCVW_LockModule();
+    
     return InterlockedIncrement( &This->ref );
 }
 
@@ -165,11 +186,15 @@
 {
     IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
     DWORD ref = InterlockedDecrement( &This->ref );
+    
     if( !ref )
     {
         DestroyWindow( This->hDialog );
         HeapFree( GetProcessHeap(), 0, This );
     }
+
+    SHDOCVW_UnlockModule();
+    
     return ref;
 }
 

Modified: trunk/reactos/lib/shdocvw/webbrowser.c
--- trunk/reactos/lib/shdocvw/webbrowser.c	2005-02-13 23:03:17 UTC (rev 13550)
+++ trunk/reactos/lib/shdocvw/webbrowser.c	2005-02-13 23:10:36 UTC (rev 13551)
@@ -29,27 +29,25 @@
 
 static HRESULT WINAPI WB_QueryInterface(IWebBrowser *iface, REFIID riid, LPVOID *ppobj)
 {
-    IWebBrowserImpl *This = (IWebBrowserImpl *)iface;
+    FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
 
-    FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj);
+    if (ppobj == NULL) return E_POINTER;
+    
     return E_NOINTERFACE;
 }
 
 static ULONG WINAPI WB_AddRef(IWebBrowser *iface)
 {
-    IWebBrowserImpl *This = (IWebBrowserImpl *)iface;
+    SHDOCVW_LockModule();
 
-    TRACE("\n");
-    return ++(This->ref);
+    return 2; /* non-heap based object */
 }
 
 static ULONG WINAPI WB_Release(IWebBrowser *iface)
 {
-    IWebBrowserImpl *This = (IWebBrowserImpl *)iface;
+    SHDOCVW_UnlockModule();
 
-    /* static class, won't be freed */
-    TRACE("\n");
-    return --(This->ref);
+    return 1; /* non-heap based object */
 }
 
 /* IDispatch methods */
@@ -277,4 +275,4 @@
     WB_get_Busy
 };
 
-IWebBrowserImpl SHDOCVW_WebBrowser = { &WB_Vtbl, 1 };
+IWebBrowserImpl SHDOCVW_WebBrowser = {&WB_Vtbl};