From bdbadd9e10f869368ec913f2d30f0d72e7d2f8ee Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Thu, 27 Jan 2005 10:43:53 +0000 Subject: [PATCH] Properly implement DllCanUnloadNow ref counting. Make sure the mozilla control is ready to unload as well. --- dlls/shdocvw/classinfo.c | 44 ++++++++++---------------- dlls/shdocvw/events.c | 44 ++++++++++---------------- dlls/shdocvw/factory.c | 40 ++++++++++-------------- dlls/shdocvw/misc.c | 22 +++++-------- dlls/shdocvw/oleobject.c | 61 +++++++++++++------------------------ dlls/shdocvw/persist.c | 44 ++++++++++---------------- dlls/shdocvw/shdocvw.h | 7 +++++ dlls/shdocvw/shdocvw_main.c | 27 +++++++++++++++- dlls/shdocvw/webbrowser.c | 22 +++++-------- 9 files changed, 134 insertions(+), 177 deletions(-) diff --git a/dlls/shdocvw/classinfo.c b/dlls/shdocvw/classinfo.c index 3207726d122..13c954e1617 100644 --- a/dlls/shdocvw/classinfo.c +++ b/dlls/shdocvw/classinfo.c @@ -38,31 +38,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); 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)); + + if (ppobj == NULL) return E_POINTER; - FIXME("(%p)->(%s,%p),stub!\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE; } static ULONG WINAPI WBPCI_AddRef(LPPROVIDECLASSINFO iface) { - IProvideClassInfoImpl *This = (IProvideClassInfoImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBPCI_Release(LPPROVIDECLASSINFO iface) { - IProvideClassInfoImpl *This = (IProvideClassInfoImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } /* Return an ITypeInfo interface to retrieve type library info about @@ -86,7 +80,7 @@ static IProvideClassInfoVtbl WBPCI_Vtbl = WBPCI_GetClassInfo }; -IProvideClassInfoImpl SHDOCVW_ProvideClassInfo = { &WBPCI_Vtbl, 1 }; +IProvideClassInfoImpl SHDOCVW_ProvideClassInfo = { &WBPCI_Vtbl}; /********************************************************************** @@ -97,31 +91,25 @@ IProvideClassInfoImpl SHDOCVW_ProvideClassInfo = { &WBPCI_Vtbl, 1 }; 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBPCI2_Release(LPPROVIDECLASSINFO2 iface) { - IProvideClassInfo2Impl *This = (IProvideClassInfo2Impl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } /* Return an ITypeInfo interface to retrieve type library info about @@ -175,4 +163,4 @@ static IProvideClassInfo2Vtbl WBPCI2_Vtbl = WBPCI2_GetGUID }; -IProvideClassInfo2Impl SHDOCVW_ProvideClassInfo2 = { &WBPCI2_Vtbl, 1 }; +IProvideClassInfo2Impl SHDOCVW_ProvideClassInfo2 = { &WBPCI2_Vtbl}; diff --git a/dlls/shdocvw/events.c b/dlls/shdocvw/events.c index d1b1e25afa6..96ef64bb34d 100644 --- a/dlls/shdocvw/events.c +++ b/dlls/shdocvw/events.c @@ -38,31 +38,25 @@ static const GUID IID_INotifyDBEvents = 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBCPC_Release(LPCONNECTIONPOINTCONTAINER iface) { - IConnectionPointContainerImpl *This = (IConnectionPointContainerImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } /* Get a list of connection points inside this container. */ @@ -116,7 +110,7 @@ static IConnectionPointContainerVtbl WBCPC_Vtbl = WBCPC_FindConnectionPoint }; -IConnectionPointContainerImpl SHDOCVW_ConnectionPointContainer = { &WBCPC_Vtbl, 1 }; +IConnectionPointContainerImpl SHDOCVW_ConnectionPointContainer = {&WBCPC_Vtbl}; /********************************************************************** @@ -126,31 +120,25 @@ IConnectionPointContainerImpl SHDOCVW_ConnectionPointContainer = { &WBCPC_Vtbl, 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBCP_Release(LPCONNECTIONPOINT iface) { - IConnectionPointImpl *This = (IConnectionPointImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } static HRESULT WINAPI WBCP_GetConnectionInterface(LPCONNECTIONPOINT iface, IID* pIId) @@ -217,4 +205,4 @@ static IConnectionPointVtbl WBCP_Vtbl = WBCP_EnumConnections }; -IConnectionPointImpl SHDOCVW_ConnectionPoint = { &WBCP_Vtbl, 1 }; +IConnectionPointImpl SHDOCVW_ConnectionPoint = {&WBCP_Vtbl}; diff --git a/dlls/shdocvw/factory.c b/dlls/shdocvw/factory.c index 9697a82d785..afdf63f665f 100644 --- a/dlls/shdocvw/factory.c +++ b/dlls/shdocvw/factory.c @@ -36,16 +36,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); 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,12 +48,9 @@ static HRESULT WINAPI WBCF_QueryInterface(LPCLASSFACTORY iface, */ static ULONG WINAPI WBCF_AddRef(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } /************************************************************************ @@ -67,13 +58,9 @@ static ULONG WINAPI WBCF_AddRef(LPCLASSFACTORY iface) */ static ULONG WINAPI WBCF_Release(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } /************************************************************************ @@ -108,8 +95,13 @@ static HRESULT WINAPI WBCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter */ 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; } @@ -122,4 +114,4 @@ static IClassFactoryVtbl WBCF_Vtbl = WBCF_LockServer }; -IClassFactoryImpl SHDOCVW_ClassFactory = { &WBCF_Vtbl, 1 }; +IClassFactoryImpl SHDOCVW_ClassFactory = {&WBCF_Vtbl}; diff --git a/dlls/shdocvw/misc.c b/dlls/shdocvw/misc.c index 00fe7fa4dbe..398a466c7de 100644 --- a/dlls/shdocvw/misc.c +++ b/dlls/shdocvw/misc.c @@ -32,31 +32,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBQA_Release(LPQUICKACTIVATE iface) { - IQuickActivateImpl *This = (IQuickActivateImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } /* Alternative interface for quicker, easier activation of a control. */ @@ -94,7 +88,7 @@ static IQuickActivateVtbl WBQA_Vtbl = WBQA_GetContentExtent }; -IQuickActivateImpl SHDOCVW_QuickActivate = { &WBQA_Vtbl, 1 }; +IQuickActivateImpl SHDOCVW_QuickActivate = {&WBQA_Vtbl}; /********************************************************************** * OpenURL (SHDOCVW.@) diff --git a/dlls/shdocvw/oleobject.c b/dlls/shdocvw/oleobject.c index da594c7dd40..8845b5ce277 100644 --- a/dlls/shdocvw/oleobject.c +++ b/dlls/shdocvw/oleobject.c @@ -143,12 +143,9 @@ static HRESULT WINAPI WBOOBJ_QueryInterface(LPOLEOBJECT iface, */ static ULONG WINAPI WBOOBJ_AddRef(LPOLEOBJECT iface) { - IOleObjectImpl *This = (IOleObjectImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } /************************************************************************ @@ -156,13 +153,9 @@ static ULONG WINAPI WBOOBJ_AddRef(LPOLEOBJECT iface) */ static ULONG WINAPI WBOOBJ_Release(LPOLEOBJECT iface) { - IOleObjectImpl *This = (IOleObjectImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } /************************************************************************ @@ -442,7 +435,7 @@ static IOleObjectVtbl WBOOBJ_Vtbl = WBOOBJ_SetColorScheme }; -IOleObjectImpl SHDOCVW_OleObject = { &WBOOBJ_Vtbl, 1 }; +IOleObjectImpl SHDOCVW_OleObject = {&WBOOBJ_Vtbl}; /********************************************************************** @@ -452,31 +445,25 @@ IOleObjectImpl SHDOCVW_OleObject = { &WBOOBJ_Vtbl, 1 }; 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBOIPO_Release(LPOLEINPLACEOBJECT iface) { - IOleInPlaceObjectImpl *This = (IOleInPlaceObjectImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } static HRESULT WINAPI WBOIPO_GetWindow(LPOLEINPLACEOBJECT iface, HWND* phwnd) @@ -548,7 +535,7 @@ static IOleInPlaceObjectVtbl WBOIPO_Vtbl = WBOIPO_ReactivateAndUndo }; -IOleInPlaceObjectImpl SHDOCVW_OleInPlaceObject = { &WBOIPO_Vtbl, 1 }; +IOleInPlaceObjectImpl SHDOCVW_OleInPlaceObject = {&WBOIPO_Vtbl}; /********************************************************************** @@ -558,31 +545,25 @@ IOleInPlaceObjectImpl SHDOCVW_OleInPlaceObject = { &WBOIPO_Vtbl, 1 }; 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBOC_Release(LPOLECONTROL iface) { - IOleControlImpl *This = (IOleControlImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } static HRESULT WINAPI WBOC_GetControlInfo(LPOLECONTROL iface, LPCONTROLINFO pCI) @@ -624,4 +605,4 @@ static IOleControlVtbl WBOC_Vtbl = WBOC_FreezeEvents }; -IOleControlImpl SHDOCVW_OleControl = { &WBOC_Vtbl, 1 }; +IOleControlImpl SHDOCVW_OleControl = {&WBOC_Vtbl}; diff --git a/dlls/shdocvw/persist.c b/dlls/shdocvw/persist.c index a5c2965a547..c07a914aed0 100644 --- a/dlls/shdocvw/persist.c +++ b/dlls/shdocvw/persist.c @@ -30,31 +30,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBPS_Release(LPPERSISTSTORAGE iface) { - IPersistStorageImpl *This = (IPersistStorageImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } static HRESULT WINAPI WBPS_GetClassID(LPPERSISTSTORAGE iface, CLSID *pClassID) @@ -111,7 +105,7 @@ static IPersistStorageVtbl WBPS_Vtbl = WBPS_SaveCompleted }; -IPersistStorageImpl SHDOCVW_PersistStorage = { &WBPS_Vtbl, 1 }; +IPersistStorageImpl SHDOCVW_PersistStorage = {&WBPS_Vtbl}; /********************************************************************** @@ -121,31 +115,25 @@ IPersistStorageImpl SHDOCVW_PersistStorage = { &WBPS_Vtbl, 1 }; 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WBPSI_Release(LPPERSISTSTREAMINIT iface) { - IPersistStreamInitImpl *This = (IPersistStreamInitImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } static HRESULT WINAPI WBPSI_GetClassID(LPPERSISTSTREAMINIT iface, CLSID *pClassID) @@ -203,4 +191,4 @@ static IPersistStreamInitVtbl WBPSI_Vtbl = WBPSI_InitNew }; -IPersistStreamInitImpl SHDOCVW_PersistStreamInit = { &WBPSI_Vtbl, 1 }; +IPersistStreamInitImpl SHDOCVW_PersistStreamInit = {&WBPSI_Vtbl}; diff --git a/dlls/shdocvw/shdocvw.h b/dlls/shdocvw/shdocvw.h index 9139f49dabf..0c8ff470d43 100644 --- a/dlls/shdocvw/shdocvw.h +++ b/dlls/shdocvw/shdocvw.h @@ -190,4 +190,11 @@ typedef struct 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 */ diff --git a/dlls/shdocvw/shdocvw_main.c b/dlls/shdocvw/shdocvw_main.c index 5bd2a697d7a..458ad9d67ff 100644 --- a/dlls/shdocvw/shdocvw_main.c +++ b/dlls/shdocvw/shdocvw_main.c @@ -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 @@ static const WCHAR szMozDlPath[] = { 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,7 +130,20 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad) */ 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 @@ typedef struct _IBindStatusCallbackImpl { 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 @@ dlQueryInterface( IBindStatusCallback* This, REFIID riid, void** ppvObject ) static ULONG WINAPI dlAddRef( IBindStatusCallback* iface ) { IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface; + + SHDOCVW_LockModule(); + return InterlockedIncrement( &This->ref ); } @@ -165,11 +186,15 @@ static ULONG WINAPI dlRelease( IBindStatusCallback* iface ) { IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface; DWORD ref = InterlockedDecrement( &This->ref ); + if( !ref ) { DestroyWindow( This->hDialog ); HeapFree( GetProcessHeap(), 0, This ); } + + SHDOCVW_UnlockModule(); + return ref; } diff --git a/dlls/shdocvw/webbrowser.c b/dlls/shdocvw/webbrowser.c index e242781db6c..bcc8d84efd4 100644 --- a/dlls/shdocvw/webbrowser.c +++ b/dlls/shdocvw/webbrowser.c @@ -29,31 +29,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); 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; - ULONG refCount = InterlockedIncrement(&This->ref); + SHDOCVW_LockModule(); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); - - return refCount; + return 2; /* non-heap based object */ } static ULONG WINAPI WB_Release(IWebBrowser *iface) { - IWebBrowserImpl *This = (IWebBrowserImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); + SHDOCVW_UnlockModule(); - /* static class, won't be freed */ - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); - - return refCount; + return 1; /* non-heap based object */ } /* IDispatch methods */ @@ -281,4 +275,4 @@ static IWebBrowserVtbl WB_Vtbl = WB_get_Busy }; -IWebBrowserImpl SHDOCVW_WebBrowser = { &WB_Vtbl, 1 }; +IWebBrowserImpl SHDOCVW_WebBrowser = {&WB_Vtbl};