From eb28ee17c8268a60e03ffb97a711cc975e18d7de Mon Sep 17 00:00:00 2001 From: David Quintana Date: Thu, 10 Jul 2014 17:17:36 +0000 Subject: [PATCH] [RSHELL] * Use the IAugmentedShellFolder methods instead of the old constructor. [SHELL32] * Fix gcc compilation. svn path=/branches/shell-experiments/; revision=63708 --- base/shell/rshell/CMergedFolder.cpp | 116 ++++++++++++++++++++------- base/shell/rshell/CMergedFolder.h | 2 + base/shell/rshell/CStartMenu.cpp | 17 ++-- base/shell/rshell/precomp.h | 2 +- dll/win32/shell32/defcontextmenu.cpp | 2 +- 5 files changed, 96 insertions(+), 43 deletions(-) diff --git a/base/shell/rshell/CMergedFolder.cpp b/base/shell/rshell/CMergedFolder.cpp index 40f3f342ddb..544f1a07f12 100644 --- a/base/shell/rshell/CMergedFolder.cpp +++ b/base/shell/rshell/CMergedFolder.cpp @@ -30,7 +30,6 @@ struct LocalPidlInfo BOOL shared; IShellFolder * parent; LPITEMIDLIST pidl; - LPITEMIDLIST pidlCommon; }; class CEnumMergedFolder : @@ -41,8 +40,6 @@ class CEnumMergedFolder : private: CComPtr m_UserLocalFolder; CComPtr m_AllUSersFolder; - CComPtr m_UserLocal; - CComPtr m_AllUSers; HWND m_HwndOwner; SHCONTF m_Flags; @@ -83,8 +80,6 @@ public: CEnumMergedFolder::CEnumMergedFolder() : m_UserLocalFolder(NULL), m_AllUSersFolder(NULL), - m_UserLocal(NULL), - m_AllUSers(NULL), m_HwndOwner(NULL), m_Flags(0), m_hDsa(NULL), @@ -115,6 +110,8 @@ HRESULT CEnumMergedFolder::SetSources(IShellFolder * userLocal, IShellFolder * a { m_UserLocalFolder = userLocal; m_AllUSersFolder = allUSers; + + TRACE("SetSources %p %p\n", m_UserLocalFolder, m_AllUSersFolder); return S_OK; } @@ -129,13 +126,15 @@ HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags) TRACE("Search conditions changed, recreating list...\n"); - hr = m_UserLocalFolder->EnumObjects(hwndOwner, flags, &m_UserLocal); + CComPtr userLocal; + CComPtr allUSers; + hr = m_UserLocalFolder->EnumObjects(hwndOwner, flags, &userLocal); if (FAILED_UNEXPECTEDLY(hr)) return hr; - hr = m_AllUSersFolder->EnumObjects(hwndOwner, flags, &m_AllUSers); + hr = m_AllUSersFolder->EnumObjects(hwndOwner, flags, &allUSers); if (FAILED_UNEXPECTEDLY(hr)) { - m_UserLocal = NULL; + userLocal = NULL; return hr; } @@ -159,7 +158,7 @@ HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags) { if (hr1 == S_OK) { - hr1 = m_UserLocal->Next(1, &pidl1, NULL); + hr1 = userLocal->Next(1, &pidl1, NULL); if (FAILED_UNEXPECTEDLY(hr1)) return hr1; } @@ -172,7 +171,7 @@ HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags) { if (hr2 == S_OK) { - hr2 = m_AllUSers->Next(1, &pidl2, NULL); + hr2 = allUSers->Next(1, &pidl2, NULL); if (FAILED_UNEXPECTEDLY(hr2)) return hr2; } @@ -197,19 +196,27 @@ HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags) StrRetToStrW(&str1, pidl1, &name1); StrRetToStrW(&str2, pidl2, &name2); order = StrCmpW(name1, name2); + + TRACE("Both sources are S_OK, comparison between %S and %S returns %d\n", name1, name2, order); + CoTaskMemFree(name1); CoTaskMemFree(name2); } else if (hr1 == S_OK) { order = -1; + + TRACE("Both sources are S_OK, forcing %d\n", order); } else if (hr2 == S_OK) { order = 1; + + TRACE("Both sources are S_OK, forcing %d\n", order); } else { + TRACE("None of the sources\n"); break; } @@ -347,7 +354,7 @@ HRESULT STDMETHODCALLTYPE CEnumMergedFolder::Clone( // CMergedFolder extern "C" -HRESULT WINAPI CMergedFolder_Constructor(IShellFolder* userLocal, IShellFolder* allUsers, REFIID riid, LPVOID *ppv) +HRESULT WINAPI CMergedFolder_Constructor(REFIID riid, LPVOID *ppv) { *ppv = NULL; @@ -358,8 +365,6 @@ HRESULT WINAPI CMergedFolder_Constructor(IShellFolder* userLocal, IShellFolder* HRESULT hr; - hr = fld->_SetSources(userLocal, allUsers); - hr = fld->QueryInterface(riid, ppv); if (FAILED_UNEXPECTEDLY(hr)) delete fld; @@ -371,27 +376,46 @@ CMergedFolder::CMergedFolder() : m_UserLocal(NULL), m_AllUSers(NULL), m_EnumSource(NULL), + m_UserLocalPidl(NULL), + m_AllUsersPidl(NULL), m_shellPidl(NULL) { } CMergedFolder::~CMergedFolder() { -} - -HRESULT CMergedFolder::_SetSources(IShellFolder* userLocal, IShellFolder* allUsers) -{ - m_UserLocal = userLocal; - m_AllUSers = allUsers; - m_EnumSource = new CComObject(); - return m_EnumSource->SetSources(m_UserLocal, m_AllUSers); + if (m_UserLocalPidl) ILFree(m_UserLocalPidl); + if (m_AllUsersPidl) ILFree(m_AllUsersPidl); } // IAugmentedShellFolder2 HRESULT STDMETHODCALLTYPE CMergedFolder::AddNameSpace(LPGUID lpGuid, IShellFolder * psf, LPCITEMIDLIST pcidl, ULONG dwUnknown) { - UNIMPLEMENTED; - return E_NOTIMPL; + if (lpGuid) + { + TRACE("FIXME: No idea how to handle the GUID\n"); + return E_NOTIMPL; + } + + TRACE("AddNameSpace %p %p\n", m_UserLocal, m_AllUSers); + + // FIXME: Use a DSA to store the list of merged namespaces, together with their related info (psf, pidl, ...) + // For now, assume only 2 will ever be used, and ignore all the other data. + if (!m_UserLocal) + { + m_UserLocal = psf; + m_UserLocalPidl = ILClone(pcidl); + return S_OK; + } + + if (m_AllUSers) + return E_FAIL; + + m_AllUSers = psf; + m_AllUsersPidl = ILClone(pcidl); + + m_EnumSource = new CComObject(); + return m_EnumSource->SetSources(m_UserLocal, m_AllUSers); } HRESULT STDMETHODCALLTYPE CMergedFolder::GetNameSpaceID(LPCITEMIDLIST pcidl, LPGUID lpGuid) @@ -429,26 +453,39 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::ParseDisplayName( { HRESULT hr; LocalPidlInfo info; + LPITEMIDLIST pidl; if (!ppidl) return E_FAIL; if (pchEaten) *pchEaten = 0; if (pdwAttributes) *pdwAttributes = 0; - hr = m_UserLocal->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten, ppidl, pdwAttributes); + TRACE("ParseDisplayName name=%S\n", lpszDisplayName); + + hr = m_UserLocal->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten, &pidl, pdwAttributes); if (SUCCEEDED(hr)) { - hr = m_EnumSource->FindPidlInList(hwndOwner, *ppidl, &info); + TRACE("ParseDisplayName result local\n"); + hr = m_EnumSource->FindPidlInList(hwndOwner, pidl, &info); if (SUCCEEDED(hr)) + { + ILFree(pidl); + *ppidl = ILClone(info.pidl); return hr; + } } - hr = m_AllUSers->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten, ppidl, pdwAttributes); + hr = m_AllUSers->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten, &pidl, pdwAttributes); if (SUCCEEDED(hr)) { - hr = m_EnumSource->FindPidlInList(hwndOwner, *ppidl, &info); + TRACE("ParseDisplayName result common\n"); + hr = m_EnumSource->FindPidlInList(hwndOwner, pidl, &info); if (SUCCEEDED(hr)) + { + ILFree(pidl); + *ppidl = ILClone(info.pidl); return hr; + } } if (ppidl) *ppidl = NULL; @@ -477,13 +514,13 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::BindToObject( { LocalPidlInfo info; HRESULT hr; - - TRACE("BindToObject\n"); - + hr = m_EnumSource->FindPidlInList(NULL, pidl, &info); if (FAILED_UNEXPECTEDLY(hr)) return hr; + TRACE("BindToObject shared = %d\n", info.shared); + if (!info.shared) return info.parent->BindToObject(info.pidl, pbcReserved, riid, ppvOut); @@ -501,7 +538,24 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::BindToObject( if (FAILED_UNEXPECTEDLY(hr)) return hr; - return CMergedFolder_Constructor(fld1, fld2, riid, ppvOut); + CComPtr pasf; + hr = CMergedFolder_Constructor(IID_PPV_ARG(IAugmentedShellFolder, &pasf)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = pasf->QueryInterface(riid, ppvOut); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = pasf->AddNameSpace(NULL, fld1, info.pidl, 0xFF00); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = pasf->AddNameSpace(NULL, fld2, info.pidl, 0x0000); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + return hr; } HRESULT STDMETHODCALLTYPE CMergedFolder::BindToStorage( diff --git a/base/shell/rshell/CMergedFolder.h b/base/shell/rshell/CMergedFolder.h index 5b397a67959..8b8f359459e 100644 --- a/base/shell/rshell/CMergedFolder.h +++ b/base/shell/rshell/CMergedFolder.h @@ -65,6 +65,8 @@ private: CComPtr m_AllUSers; CComPtr m_EnumSource; + LPITEMIDLIST m_UserLocalPidl; + LPITEMIDLIST m_AllUsersPidl; LPITEMIDLIST m_shellPidl; public: diff --git a/base/shell/rshell/CStartMenu.cpp b/base/shell/rshell/CStartMenu.cpp index 53070504796..13361e6373c 100644 --- a/base/shell/rshell/CStartMenu.cpp +++ b/base/shell/rshell/CStartMenu.cpp @@ -310,6 +310,9 @@ HRESULT GetStartMenuFolder(IShellFolder ** ppsfStartMenu) HRESULT hr; LPITEMIDLIST pidlUserStartMenu; LPITEMIDLIST pidlCommonStartMenu; + CComPtr psfUserStartMenu; + CComPtr psfCommonStartMenu; + CComPtr pasf; *ppsfStartMenu = NULL; @@ -324,27 +327,22 @@ HRESULT GetStartMenuFolder(IShellFolder ** ppsfStartMenu) return hr; } - CComPtr psfUserStartMenu; hr = BindToDesktop(pidlUserStartMenu, &psfUserStartMenu); if (FAILED_UNEXPECTEDLY(hr)) return hr; - CComPtr psfCommonStartMenu; hr = BindToDesktop(pidlCommonStartMenu, &psfCommonStartMenu); if (FAILED_UNEXPECTEDLY(hr)) return hr; -#if CUSTOM_MERGE_FOLDERS - IShellFolder * psfMerged; - hr = CMergedFolder_Constructor(psfUserStartMenu, psfCommonStartMenu, IID_PPV_ARG(IShellFolder, &psfMerged)); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; +#if 1 + hr = CMergedFolder_Constructor(IID_PPV_ARG(IAugmentedShellFolder, &pasf)); #else - CComPtr pasf; hr = CoCreateInstance(CLSID_MergedFolder, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IAugmentedShellFolder, &pasf)); +#endif if (FAILED_UNEXPECTEDLY(hr)) { - hr = BindToDesktop(pidlUserStartMenu, ppsfStartMenu); + *ppsfStartMenu = psfUserStartMenu.Detach(); ILFree(pidlCommonStartMenu); ILFree(pidlUserStartMenu); return hr; @@ -360,7 +358,6 @@ HRESULT GetStartMenuFolder(IShellFolder ** ppsfStartMenu) hr = pasf->QueryInterface(IID_PPV_ARG(IShellFolder, ppsfStartMenu)); pasf.Release(); -#endif ILFree(pidlCommonStartMenu); ILFree(pidlUserStartMenu); diff --git a/base/shell/rshell/precomp.h b/base/shell/rshell/precomp.h index 17ffaaff057..ce2f0a41f34 100644 --- a/base/shell/rshell/precomp.h +++ b/base/shell/rshell/precomp.h @@ -71,7 +71,7 @@ extern "C" HRESULT WINAPI CMenuBand_Constructor(REFIID riid, LPVOID *ppv); extern "C" HRESULT WINAPI CMenuDeskBar_Wrapper(IDeskBar * db, REFIID riid, LPVOID *ppv); extern "C" HRESULT WINAPI CMenuSite_Wrapper(IBandSite * bs, REFIID riid, LPVOID *ppv); extern "C" HRESULT WINAPI CMenuBand_Wrapper(IShellMenu * sm, REFIID riid, LPVOID *ppv); -extern "C" HRESULT WINAPI CMergedFolder_Constructor(IShellFolder* userLocal, IShellFolder* allUsers, REFIID riid, LPVOID *ppv); +extern "C" HRESULT WINAPI CMergedFolder_Constructor(REFIID riid, LPVOID *ppv); extern "C" HRESULT WINAPI CStartMenuSite_Wrapper(ITrayPriv * trayPriv, REFIID riid, LPVOID *ppv); static __inline ULONG diff --git a/dll/win32/shell32/defcontextmenu.cpp b/dll/win32/shell32/defcontextmenu.cpp index 839f1191d4b..f7717a1fedd 100644 --- a/dll/win32/shell32/defcontextmenu.cpp +++ b/dll/win32/shell32/defcontextmenu.cpp @@ -1675,7 +1675,7 @@ CDefFolderMenu_Create2( // FIXME: This needs to be freed somewhere (like in the destructor of the context menu) LPCITEMIDLIST *apidl2 = (LPCITEMIDLIST *) SHAlloc(sizeof(LPCITEMIDLIST) * cidl); - for (int i = 0; i < cidl; i++) + for (int i = 0; i < (int)cidl; i++) { apidl2[i] = apidl[i]; } -- 2.17.1