https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5d54b65ceb2c0ae0afd9b…
commit 5d54b65ceb2c0ae0afd9b9ca442559d72cdbc2ad
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sun Aug 4 02:42:09 2019 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sat Oct 19 18:42:15 2019 +0200
[SHELL32] Add support for custom View objects defined with UICLSID
CORE-16271
---
dll/win32/shell32/folders/CFSFolder.cpp | 98 ++++++++++++++++++++++++---------
1 file changed, 71 insertions(+), 27 deletions(-)
diff --git a/dll/win32/shell32/folders/CFSFolder.cpp
b/dll/win32/shell32/folders/CFSFolder.cpp
index 0cd33490c92..f3c758d93fc 100644
--- a/dll/win32/shell32/folders/CFSFolder.cpp
+++ b/dll/win32/shell32/folders/CFSFolder.cpp
@@ -490,22 +490,23 @@ LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR
path)
return pidl;
}
-void SHELL32_GetCLSIDForDirectory(LPCWSTR pwszDir, CLSID* pclsidFolder)
+static HRESULT SHELL32_GetCLSIDForDirectory(LPCWSTR pwszDir, LPCWSTR KeyName, CLSID*
pclsidFolder)
{
WCHAR wszCLSIDValue[CHARS_IN_GUID];
WCHAR wszDesktopIni[MAX_PATH];
StringCchCopyW(wszDesktopIni, MAX_PATH, pwszDir);
StringCchCatW(wszDesktopIni, MAX_PATH, L"\\desktop.ini");
- if (GetPrivateProfileStringW(L".ShellClassInfo",
- L"CLSID",
+ if (GetPrivateProfileStringW(L".ShellClassInfo",
+ KeyName,
L"",
- wszCLSIDValue,
- CHARS_IN_GUID,
+ wszCLSIDValue,
+ CHARS_IN_GUID,
wszDesktopIni))
{
- CLSIDFromString (wszCLSIDValue, pclsidFolder);
+ return CLSIDFromString(wszCLSIDValue, pclsidFolder);
}
+ return E_FAIL;
}
HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD
pdwAttributes)
@@ -742,7 +743,7 @@ HRESULT WINAPI CFSFolder::BindToObject(
clsidFolder = CLSID_ShellFSFolder;
if ((pData->uFileAttribs & (FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_READONLY)) != 0)
- SHELL32_GetCLSIDForDirectory(pfti.szTargetParsingName, &clsidFolder);
+ SHELL32_GetCLSIDForDirectory(pfti.szTargetParsingName, L"CLSID",
&clsidFolder);
}
else
{
@@ -857,30 +858,73 @@ HRESULT WINAPI CFSFolder::CreateViewObject(HWND hwndOwner,
{
*ppvOut = NULL;
- if (IsEqualIID (riid, IID_IDropTarget))
- hr = CFSDropTarget_CreateInstance(sPathTarget, riid, ppvOut);
- else if (IsEqualIID (riid, IID_IContextMenu))
+ BOOL bIsDropTarget = IsEqualIID (riid, IID_IDropTarget);
+ BOOL bIsShellView = !bIsDropTarget && IsEqualIID (riid, IID_IShellView);
+
+ if (bIsDropTarget || bIsShellView)
{
- HKEY hKeys[16];
- UINT cKeys = 0;
- AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
+ DWORD dwDirAttributes = _ILGetFileAttributes(ILFindLastID(pidlRoot), NULL,
0);
- DEFCONTEXTMENU dcm;
- dcm.hwnd = hwndOwner;
- dcm.pcmcb = this;
- dcm.pidlFolder = pidlRoot;
- dcm.psf = this;
- dcm.cidl = 0;
- dcm.apidl = NULL;
- dcm.cKeys = cKeys;
- dcm.aKeys = hKeys;
- dcm.punkAssociationInfo = NULL;
- hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
+ if ((dwDirAttributes & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY))
!= 0)
+ {
+ CLSID clsidFolder;
+ hr = SHELL32_GetCLSIDForDirectory(sPathTarget, L"UICLSID",
&clsidFolder);
+ if (SUCCEEDED(hr))
+ {
+ CComPtr<IPersistFolder> spFolder;
+ hr = SHCoCreateInstance(NULL, &clsidFolder, NULL,
IID_PPV_ARG(IPersistFolder, &spFolder));
+ if (!FAILED_UNEXPECTEDLY(hr))
+ {
+ hr = spFolder->Initialize(pidlRoot);
+
+ if (!FAILED_UNEXPECTEDLY(hr))
+ {
+ hr = spFolder->QueryInterface(riid, ppvOut);
+ }
+ }
+ }
+ else
+ {
+ // No desktop.ini, or no UICLSID present, continue as if nothing
happened
+ hr = E_INVALIDARG;
+ }
+ }
}
- else if (IsEqualIID (riid, IID_IShellView))
+
+ if (!SUCCEEDED(hr))
{
- SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this, NULL, this};
- hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
+ // No UICLSID handler found, continue to the default handlers
+ if (bIsDropTarget)
+ {
+ hr = CFSDropTarget_CreateInstance(sPathTarget, riid, ppvOut);
+ }
+ else if (IsEqualIID (riid, IID_IContextMenu))
+ {
+ HKEY hKeys[16];
+ UINT cKeys = 0;
+ AddClassKeyToArray(L"Directory\\Background", hKeys,
&cKeys);
+
+ DEFCONTEXTMENU dcm;
+ dcm.hwnd = hwndOwner;
+ dcm.pcmcb = this;
+ dcm.pidlFolder = pidlRoot;
+ dcm.psf = this;
+ dcm.cidl = 0;
+ dcm.apidl = NULL;
+ dcm.cKeys = cKeys;
+ dcm.aKeys = hKeys;
+ dcm.punkAssociationInfo = NULL;
+ hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
+ }
+ else if (bIsShellView)
+ {
+ SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this, NULL, this};
+ hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
+ }
+ else
+ {
+ hr = E_INVALIDARG;
+ }
}
}
TRACE("-- (%p)->(interface=%p)\n", this, ppvOut);