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/C... ============================================================================== --- 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/C... ============================================================================== --- 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/C... ============================================================================== --- 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/shlfolder... ============================================================================== --- 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))