From 2c118e18904ba705a8cd2d0d9c01867161d80fbe Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Tue, 8 Nov 2016 23:38:42 +0000 Subject: [PATCH] [BROWSEUI] - CAddressBand: Call the SetOwner method with NULL parameter to CAddressEditBox to let it know that it should deinitialize. - CAddressEditBox: Release the connection with the browse window and release the pointer to the site during deinitialization. - CInternetToolbar: Destroy the toolbar and release pointers when CloseDW method gets called. - CBaseBar: Destroy the window when SetClient is called with NULL parameter. - CToolbarProxy: Add a Destroy method to release resources because we hold a pointer to the CInternetToolbar. - CShellBrowser: When storing the pointer to the new basebar add a new reference because we directly change the pointer in the smart pointer and not the smart pointer itself. Destroy the toolbar proxy and properly release all references to containted objects. Also expect the reference count of the shell view to reach zero after the internet toolbar gets freed because it also keeps a reference. This should fix all the leaking objects and windows when closing the shell browser. It should also fix CORE-12066. svn path=/trunk/; revision=73175 --- reactos/dll/win32/browseui/addressband.cpp | 5 +++- reactos/dll/win32/browseui/addresseditbox.cpp | 10 +++++++- reactos/dll/win32/browseui/basebar.cpp | 4 ++++ .../dll/win32/browseui/internettoolbar.cpp | 2 ++ reactos/dll/win32/browseui/shellbrowser.cpp | 24 ++++++++++++------- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/reactos/dll/win32/browseui/addressband.cpp b/reactos/dll/win32/browseui/addressband.cpp index 97d672f2589..3cc67e02d1c 100644 --- a/reactos/dll/win32/browseui/addressband.cpp +++ b/reactos/dll/win32/browseui/addressband.cpp @@ -197,7 +197,10 @@ HRESULT STDMETHODCALLTYPE CAddressBand::CloseDW(DWORD dwReserved) m_hWnd = NULL; - IUnknown_SetSite(fAddressEditBox, NULL); + CComPtr pservice; + HRESULT hres = fAddressEditBox->QueryInterface(IID_PPV_ARG(IShellService, &pservice)); + if (SUCCEEDED(hres )) + pservice->SetOwner(NULL); if (fAddressEditBox) fAddressEditBox.Release(); if (fSite) fSite.Release(); diff --git a/reactos/dll/win32/browseui/addresseditbox.cpp b/reactos/dll/win32/browseui/addresseditbox.cpp index 9d0380354b7..9633d881507 100644 --- a/reactos/dll/win32/browseui/addresseditbox.cpp +++ b/reactos/dll/win32/browseui/addresseditbox.cpp @@ -43,8 +43,16 @@ CAddressEditBox::~CAddressEditBox() { } -HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *) +HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *pOwner) { + if (!pOwner) + { + CComPtr browserService; + HRESULT hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); + if (SUCCEEDED(hResult)) + AtlUnadvise(browserService, DIID_DWebBrowserEvents, fAdviseCookie); + fSite = NULL; + } // connect to browser connection point return 0; } diff --git a/reactos/dll/win32/browseui/basebar.cpp b/reactos/dll/win32/browseui/basebar.cpp index 6a30462e0b4..bd84b4a7985 100644 --- a/reactos/dll/win32/browseui/basebar.cpp +++ b/reactos/dll/win32/browseui/basebar.cpp @@ -328,6 +328,10 @@ HRESULT STDMETHODCALLTYPE CBaseBar::SetClient(IUnknown *punkClient) WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW); ReserveBorderSpace(); } + else + { + DestroyWindow(); + } return S_OK; } diff --git a/reactos/dll/win32/browseui/internettoolbar.cpp b/reactos/dll/win32/browseui/internettoolbar.cpp index 64393afea46..8b5717b21c2 100644 --- a/reactos/dll/win32/browseui/internettoolbar.cpp +++ b/reactos/dll/win32/browseui/internettoolbar.cpp @@ -934,6 +934,8 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved) return hResult; ReleaseCComPtrExpectZero(fLogoBar); } + + SetSite(NULL); return S_OK; } diff --git a/reactos/dll/win32/browseui/shellbrowser.cpp b/reactos/dll/win32/browseui/shellbrowser.cpp index 63c58694caa..db050150bcc 100644 --- a/reactos/dll/win32/browseui/shellbrowser.cpp +++ b/reactos/dll/win32/browseui/shellbrowser.cpp @@ -179,7 +179,7 @@ private: CComPtr fExplorerToolbar; public: void Initialize(HWND parent, IUnknown *explorerToolbar); - + void Destroy(); private: // message handlers @@ -207,6 +207,12 @@ void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar) } } +void CToolbarProxy::Destroy() +{ + DestroyWindow(); + fExplorerToolbar = NULL; +} + LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { long int result; @@ -1116,6 +1122,7 @@ HRESULT CShellBrowser::GetBaseBar(bool vertical, REFIID riid, void **theBaseBar) // we have to store our basebar into cache now *cache = newBaseBar; + newBaseBar->AddRef(); // tell the new base bar about the shell browser hResult = IUnknown_SetSite(newBaseBar, static_cast(this)); @@ -3362,9 +3369,10 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & // TODO: rip down everything { + fToolbarProxy.Destroy(); + fCurrentShellView->DestroyViewWindow(); fCurrentShellView->UIActivate(SVUIA_DEACTIVATE); - ReleaseCComPtrExpectZero(fCurrentShellView); for (int i = 0; i < 3; i++) { @@ -3393,16 +3401,14 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & } } pdw->CloseDW(0); + + pClient = NULL; + pBarSite = NULL; pdw = NULL; - /* For some reasons, it's like we miss some AddRef in ATL when QueryInterface on - * same interface or inherited one, so we are removing already removed (!) object. - * TODO: check with MSVC's ATL to see if this behaviour happens too - */ - bar.Detach(); - pClient.Detach(); - pBarSite.Detach(); + bar = NULL; ReleaseCComPtrExpectZero(fClientBars[i].clientBar); } + ReleaseCComPtrExpectZero(fCurrentShellView); ReleaseCComPtrExpectZero(fTravelLog); fCurrentShellFolder.Release();