Author: gadamopoulos
Date: Mon Aug 31 23:44:02 2015
New Revision: 68885
URL:
http://svn.reactos.org/svn/reactos?rev=68885&view=rev
Log:
[SHELL32]
- Rename SHELL32_BindToChild to SHELL32_BindToFS. Do not let it be used for guid items any
more. Split SHELL32_GetCLSIDForDirectoryout of it and call it only when needed.
- Fix callers to use SHELL32_BindToGuidItem for guid items.
- Fix a bug in CFSFolder which marked folder items as files when a binding context was
used.
Modified:
trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp
trunk/reactos/dll/win32/shell32/shfldr.h
trunk/reactos/dll/win32/shell32/shlfolder.cpp
Modified: trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] Mon Aug 31
23:44:02 2015
@@ -446,7 +446,10 @@
TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
- return SHELL32_BindToChild( pidlRoot, sPathTarget, pidl, riid, ppvOut );
+ if (_ILIsSpecialFolder(pidl))
+ return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
+
+ return SHELL32_BindToFS( pidlRoot, sPathTarget, pidl, riid, ppvOut );
}
/**************************************************************************
Modified: trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] Mon Aug 31
23:44:02 2015
@@ -272,7 +272,7 @@
if (_ILIsSpecialFolder(pidl))
return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
- return SHELL32_BindToChild(pidlRoot, NULL, pidl, riid, ppvOut);
+ return SHELL32_BindToFS(pidlRoot, NULL, pidl, riid, ppvOut);
}
/**************************************************************************
Modified: trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] Mon Aug 31 23:44:02
2015
@@ -207,6 +207,13 @@
pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, szElement);
if (pidlTemp != NULL)
{
+ /* We are creating an id list without ensuring that the items exist.
+ If we have a remaining path, this must be a folder.
+ We have to do it now because it is set as a file by default */
+ if (szNext)
+ {
+ pidlTemp->mkid.abID[0] = PT_FOLDER;
+ }
hr = S_OK;
}
else
@@ -280,7 +287,7 @@
TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this, pidl, pbc,
shdebugstr_guid(&riid), ppvOut);
- return SHELL32_BindToChild(pidlRoot, sPathTarget, pidl, riid, ppvOut);
+ return SHELL32_BindToFS(pidlRoot, sPathTarget, pidl, riid, ppvOut);
}
/**************************************************************************
Modified: trunk/reactos/dll/win32/shell32/shfldr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr.h…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] Mon Aug 31 23:44:02 2015
@@ -41,7 +41,7 @@
LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD
dwFlags, LPSTRRET strRet);
-HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
+HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID *
ppvOut);
HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2);
Modified: trunk/reactos/dll/win32/shell32/shlfolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfolde…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] Mon Aug 31 23:44:02 2015
@@ -149,7 +149,7 @@
* In this case the absolute path is built from pidlChild (eg. C:)
*/
static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
- LPCITEMIDLIST pidlChild, REFCLSID clsid, LPVOID * ppvOut)
+ LPCITEMIDLIST pidlChild, REFCLSID clsid, IShellFolder** ppsfOut)
{
HRESULT hr;
CComPtr<IShellFolder> pShellFolder;
@@ -163,8 +163,7 @@
CComPtr<IPersistFolder> ppf;
CComPtr<IPersistFolder3> ppf3;
- if ((_ILIsFolder(pidlChild) || _ILIsDrive(pidlChild)) &&
- SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3,
&ppf3))))
+ if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3,
&ppf3))))
{
PERSIST_FOLDER_TARGET_INFO ppfti;
@@ -198,15 +197,35 @@
ILFree (pidlAbsolute);
}
- *ppvOut = pShellFolder.Detach();
-
- TRACE ("-- (%p) ret=0x%08x\n", *ppvOut, hr);
+ *ppsfOut = pShellFolder.Detach();
+
+ TRACE ("-- (%p) ret=0x%08x\n", *ppsfOut, hr);
return hr;
}
+void SHELL32_GetCLSIDForDirectory(LPCWSTR pathRoot, LPCITEMIDLIST pidl, CLSID*
pclsidFolder)
+{
+ static const WCHAR wszDotShellClassInfo[] = {
+
'.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0
};
+ static const WCHAR wszCLSID[] =
{'C','L','S','I','D',0};
+ WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail =
wszFolderPath;
+
+ /* see if folder CLSID should be overridden by desktop.ini file */
+ if (pathRoot) {
+ lstrcpynW(wszFolderPath, pathRoot, MAX_PATH);
+ pwszPathTail = PathAddBackslashW(wszFolderPath);
+ }
+
+ _ILSimpleGetTextW(pidl,pwszPathTail,MAX_PATH - (int)(pwszPathTail - wszFolderPath));
+
+ if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath,
+ wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID))
+ CLSIDFromString (wszCLSIDValue, pclsidFolder);
+}
+
/***********************************************************************
- * SHELL32_BindToChild [Internal]
+ * SHELL32_BindToFS [Internal]
*
* Common code for IShellFolder_BindToObject.
*
@@ -222,49 +241,40 @@
* This function makes special assumptions on the shell namespace, which
* means you probably can't use it for your IShellFolder implementation.
*/
-HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
+HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid,
LPVOID * ppvOut)
{
- static const WCHAR wszDotShellClassInfo[] = {
-
'.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0
};
-
- GUID const *clsid;
CComPtr<IShellFolder> pSF;
HRESULT hr;
- LPITEMIDLIST pidlChild;
+ LPCITEMIDLIST pidlChild;
if (!pidlRoot || !ppvOut || !pidlComplete || !pidlComplete->mkid.cb)
return E_INVALIDARG;
+ if (_ILIsValue(pidlComplete))
+ {
+ ERR("Binding to file is unimplemented\n");
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+ if (!_ILIsFolder(pidlComplete) && !_ILIsDrive(pidlComplete))
+ {
+ ERR("Got an unknown type of pidl!\n");
+ return E_FAIL;
+ }
+
*ppvOut = NULL;
- pidlChild = ILCloneFirst (pidlComplete);
-
- if ((clsid = _ILGetGUIDPointer (pidlChild))) {
- /* virtual folder */
- hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, *clsid, (LPVOID
*)&pSF);
- } else {
- /* file system folder */
- CLSID clsidFolder = CLSID_ShellFSFolder;
- static const WCHAR wszCLSID[] =
{'C','L','S','I','D',0};
- WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail =
wszFolderPath;
-
- /* see if folder CLSID should be overridden by desktop.ini file */
- if (pathRoot) {
- lstrcpynW(wszFolderPath, pathRoot, MAX_PATH);
- pwszPathTail = PathAddBackslashW(wszFolderPath);
- }
-
- _ILSimpleGetTextW(pidlChild,pwszPathTail,MAX_PATH - (int)(pwszPathTail -
wszFolderPath));
-
- if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath,
- wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID))
- CLSIDFromString (wszCLSIDValue, &clsidFolder);
-
- hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild,
- clsidFolder, (LPVOID *)&pSF);
- }
- ILFree (pidlChild);
+ pidlChild = (_ILIsPidlSimple (pidlComplete)) ? pidlComplete : ILCloneFirst
(pidlComplete);
+
+ CLSID clsidFolder = CLSID_ShellFSFolder;
+ DWORD attributes = _ILGetFileAttributes(ILFindLastID(pidlChild), NULL, 0);
+ if ((attributes & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) != 0)
+ SHELL32_GetCLSIDForDirectory(pathRoot, pidlChild, &clsidFolder);
+
+ hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsidFolder, &pSF);
+
+ if (pidlChild != pidlComplete)
+ ILFree ((LPITEMIDLIST)pidlChild);
if (SUCCEEDED (hr)) {
if (_ILIsPidlSimple (pidlComplete)) {
@@ -290,27 +300,41 @@
CComPtr<IPersistFolder> pFolder;
HRESULT hr;
+ if (!pidlRoot || !ppvOut || !pidl || !pidl->mkid.cb)
+ return E_INVALIDARG;
+
+ *ppvOut = NULL;
+
GUID *pGUID = _ILGetGUIDPointer(pidl);
if (!pGUID)
{
ERR("SHELL32_BindToGuidItem called for non guid item!\n");
- return E_FAIL;
+ return E_INVALIDARG;
}
hr = SHCoCreateInstance(NULL, pGUID, NULL, IID_PPV_ARG(IPersistFolder,
&pFolder));
if (FAILED(hr))
return hr;
- hr = pFolder->Initialize(ILCombine(pidlRoot, pidl));
- if (FAILED(hr))
- return hr;
-
if (_ILIsPidlSimple (pidl))
{
+ hr = pFolder->Initialize(ILCombine(pidlRoot, pidl));
+ if (FAILED(hr))
+ return hr;
+
return pFolder->QueryInterface(riid, ppvOut);
}
else
{
+ LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
+ if (!pidlChild)
+ return E_OUTOFMEMORY;
+
+ hr = pFolder->Initialize(ILCombine(pidlRoot, pidlChild));
+ ILFree(pidlChild);
+ if (FAILED(hr))
+ return hr;
+
CComPtr<IShellFolder> psf;
hr = pFolder->QueryInterface(IID_PPV_ARG(IShellFolder, &psf));
if (FAILED(hr))