Author: gadamopoulos
Date: Fri Jul 7 20:34:27 2017
New Revision: 75301
URL:
http://svn.reactos.org/svn/reactos?rev=75301&view=rev
Log:
[SHELL32]
- Simplify SHELL32_CoCreateInitSF by letting the callers fill the
PERSIST_FOLDER_TARGET_INFO. This lets us stop using _ILSimpleGetTextW in it which breaks
the logic that pidls should be read only by their shell folder. Also add an overload for
SHELL32_CoCreateInitSF that makes it simpler to create a shell folder with a csidl.
- Add a SHELL32_BindToSF helper to share some logic that was duplicated in several shell
folders.
- Move SHELL32_GetCustomFolderAttributeFromPath, SHELL32_GetCLSIDForDirectory and
SHELL32_GetFSItemAttributes, SHELL32_BindToFS to CFSFolder.cpp as these were fs specific.
- These changes give finer control to shell folders for how the bind will be done and
shares more logic that can be shared.
Modified:
trunk/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp
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/folders/CFontsFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp
trunk/reactos/dll/win32/shell32/shfldr.h
trunk/reactos/dll/win32/shell32/shlfolder.cpp
Modified: trunk/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp [iso-8859-1] Fri Jul 7
20:34:27 2017
@@ -175,8 +175,6 @@
return E_OUTOFMEMORY;
return SHELL32_CoCreateInitSF(m_pidlInner,
- NULL,
- NULL,
&CLSID_ShellFSFolder,
CSIDL_COMMON_ADMINTOOLS,
IID_PPV_ARG(IShellFolder2, &m_pisfInner));
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] Fri Jul 7
20:34:27 2017
@@ -270,8 +270,6 @@
/* Create the inner fs folder */
hr = SHELL32_CoCreateInitSF(pidlRoot,
- NULL,
- NULL,
&CLSID_ShellFSFolder,
CSIDL_DESKTOPDIRECTORY,
IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
@@ -280,8 +278,6 @@
/* Create the inner shared fs folder. Dont fail on failure. */
hr = SHELL32_CoCreateInitSF(pidlRoot,
- NULL,
- NULL,
&CLSID_ShellFSFolder,
CSIDL_COMMON_DESKTOPDIRECTORY,
IID_PPV_ARG(IShellFolder2,
&m_SharedDesktopFSFolder));
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] Fri Jul 7
20:34:27 2017
@@ -390,31 +390,25 @@
if (_ILIsSpecialFolder(pidl))
return m_regFolder->BindToObject(pidl, pbcReserved, riid, ppvOut);
- LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
- if (!pidlChild)
- return E_OUTOFMEMORY;
-
- CComPtr<IShellFolder> psf;
- HRESULT hr = SHELL32_CoCreateInitSF(pidlRoot,
- NULL,
- pidlChild,
- &CLSID_ShellFSFolder,
- -1,
- IID_PPV_ARG(IShellFolder, &psf));
-
- ILFree(pidlChild);
-
- if (FAILED(hr))
+ CHAR* pchDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName;
+
+ PERSIST_FOLDER_TARGET_INFO pfti = {0};
+ pfti.dwAttributes = -1;
+ pfti.csidl = -1;
+ pfti.szTargetParsingName[0] = *pchDrive;
+ pfti.szTargetParsingName[1] = L':';
+ pfti.szTargetParsingName[2] = L'\\';
+
+ HRESULT hr = SHELL32_BindToSF(pidlRoot,
+ &pfti,
+ pidl,
+ &CLSID_ShellFSFolder,
+ riid,
+ ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- if (_ILIsPidlSimple (pidl))
- {
- return psf->QueryInterface(riid, ppvOut);
- }
- else
- {
- return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
- }
+ return S_OK;
}
/**************************************************************************
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] Fri Jul 7 20:34:27
2017
@@ -128,6 +128,110 @@
}
return pidl;
+}
+
+void SHELL32_GetCLSIDForDirectory(LPCWSTR pwszDir, 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",
+ L"",
+ wszCLSIDValue,
+ CHARS_IN_GUID,
+ wszDesktopIni))
+ {
+ CLSIDFromString (wszCLSIDValue, pclsidFolder);
+ }
+}
+
+
+static const DWORD dwSupportedAttr=
+ SFGAO_CANCOPY | /*0x00000001 */
+ SFGAO_CANMOVE | /*0x00000002 */
+ SFGAO_CANLINK | /*0x00000004 */
+ SFGAO_CANRENAME | /*0x00000010 */
+ SFGAO_CANDELETE | /*0x00000020 */
+ SFGAO_HASPROPSHEET | /*0x00000040 */
+ SFGAO_DROPTARGET | /*0x00000100 */
+ SFGAO_LINK | /*0x00010000 */
+ SFGAO_READONLY | /*0x00040000 */
+ SFGAO_HIDDEN | /*0x00080000 */
+ SFGAO_FILESYSANCESTOR | /*0x10000000 */
+ SFGAO_FOLDER | /*0x20000000 */
+ SFGAO_FILESYSTEM | /*0x40000000 */
+ SFGAO_HASSUBFOLDER; /*0x80000000 */
+
+HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD
pdwAttributes)
+{
+ DWORD dwFileAttributes, dwShellAttributes;
+
+ if (!_ILIsFolder(pidl) && !_ILIsValue(pidl))
+ {
+ ERR("Got wrong type of pidl!\n");
+ *pdwAttributes &= SFGAO_CANLINK;
+ return S_OK;
+ }
+
+ if (*pdwAttributes & ~dwSupportedAttr)
+ {
+ WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes &
~dwSupportedAttr));
+ *pdwAttributes &= dwSupportedAttr;
+ }
+
+ dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
+
+ /* Set common attributes */
+ dwShellAttributes = *pdwAttributes;
+ dwShellAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET |
SFGAO_CANDELETE |
+ SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE |
SFGAO_CANCOPY;
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ dwShellAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER |
SFGAO_FILESYSANCESTOR);
+ }
+ else
+ dwShellAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER |
SFGAO_FILESYSANCESTOR);
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+ dwShellAttributes |= SFGAO_HIDDEN;
+ else
+ dwShellAttributes &= ~SFGAO_HIDDEN;
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ dwShellAttributes |= SFGAO_READONLY;
+ else
+ dwShellAttributes &= ~SFGAO_READONLY;
+
+ if (SFGAO_LINK & *pdwAttributes)
+ {
+ char ext[MAX_PATH];
+
+ if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk"))
+ dwShellAttributes &= ~SFGAO_LINK;
+ }
+
+ if (SFGAO_HASSUBFOLDER & *pdwAttributes)
+ {
+ CComPtr<IShellFolder> psf2;
+ if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder,
&psf2))))
+ {
+ CComPtr<IEnumIDList> pEnumIL;
+ if (SUCCEEDED(psf2->EnumObjects(0, SHCONTF_FOLDERS, &pEnumIL)))
+ {
+ if (pEnumIL->Skip(1) != S_OK)
+ dwShellAttributes &= ~SFGAO_HASSUBFOLDER;
+ }
+ }
+ }
+
+ *pdwAttributes &= dwShellAttributes;
+
+ TRACE ("-- 0x%08x\n", *pdwAttributes);
+ return S_OK;
}
/**************************************************************************
@@ -274,7 +378,48 @@
TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this, pidl, pbc,
shdebugstr_guid(&riid), ppvOut);
- return SHELL32_BindToFS(pidlRoot, sPathTarget, pidl, riid, ppvOut);
+ CComPtr<IShellFolder> pSF;
+ HRESULT hr;
+
+ if (!pidlRoot || !ppvOut || !pidl || !pidl->mkid.cb)
+ return E_INVALIDARG;
+
+ if (_ILIsValue(pidl))
+ {
+ ERR("Binding to file is unimplemented\n");
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+ if (!_ILIsFolder(pidl))
+ {
+ ERR("Got an unknown type of pidl!\n");
+ return E_FAIL;
+ }
+
+ *ppvOut = NULL;
+
+ /* Get the pidl data */
+ FileStruct* pData = &_ILGetDataPointer(pidl)->u.file;
+ FileStructW* pDataW = _ILGetFileStructW(pidl);
+
+ /* Create the target folder info */
+ PERSIST_FOLDER_TARGET_INFO pfti = {0};
+ pfti.dwAttributes = -1;
+ pfti.csidl = -1;
+ PathCombineW(pfti.szTargetParsingName, sPathTarget, pDataW->wszName);
+
+ /* Get the CLSID to bind to */
+ CLSID clsidFolder = CLSID_ShellFSFolder;
+ if ((pData->uFileAttribs & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY))
!= 0)
+ SHELL32_GetCLSIDForDirectory(pfti.szTargetParsingName, &clsidFolder);
+
+ hr = SHELL32_BindToSF(pidlRoot, &pfti, pidl, &clsidFolder, riid, ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ TRACE ("-- returning (%p) %08x\n", *ppvOut, hr);
+
+ return S_OK;
+
}
/**************************************************************************
Modified: trunk/reactos/dll/win32/shell32/folders/CFontsFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CFontsFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CFontsFolder.cpp [iso-8859-1] Fri Jul 7
20:34:27 2017
@@ -175,9 +175,7 @@
if (!m_pidlInner)
return E_OUTOFMEMORY;
- return SHELL32_CoCreateInitSF(m_pidlInner,
- NULL,
- NULL,
+ return SHELL32_CoCreateInitSF(m_pidlInner,
&CLSID_ShellFSFolder,
CSIDL_FONTS,
IID_PPV_ARG(IShellFolder2, &m_pisfInner));
Modified: trunk/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp [iso-8859-1] Fri Jul 7
20:34:27 2017
@@ -175,8 +175,6 @@
return E_OUTOFMEMORY;
return SHELL32_CoCreateInitSF(m_pidlInner,
- NULL,
- NULL,
&CLSID_ShellFSFolder,
CSIDL_PERSONAL,
IID_PPV_ARG(IShellFolder2, &m_pisfInner));
Modified: trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp [iso-8859-1] Fri Jul 7
20:34:27 2017
@@ -283,31 +283,13 @@
HRESULT WINAPI CNetFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID
riid, LPVOID *ppvOut)
{
#ifdef HACKY_UNC_PATHS
- PITEMID_CHILD pidlChild = ILCloneFirst (pidl);
- if (!pidlChild)
- return E_FAIL;
-
- PIDLIST_ABSOLUTE pidlAbsolute = ILCombine(pidlRoot,pidlChild);
- if (!pidlAbsolute)
- return E_FAIL;
-
- CComPtr<IShellFolder> psf;
- HRESULT hr = SHELL32_CoCreateInitSF(pidlAbsolute,
- (WCHAR*)pidl->mkid.abID,
- NULL,
- &CLSID_ShellFSFolder,
- -1,
- IID_PPV_ARG(IShellFolder, &psf));
- ILFree(pidlChild);
- ILFree(pidlAbsolute);
-
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (_ILIsPidlSimple (pidl))
- return psf->QueryInterface(riid, ppvOut);
- else
- return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
+ /* Create the target folder info */
+ PERSIST_FOLDER_TARGET_INFO pfti = {0};
+ pfti.dwAttributes = -1;
+ pfti.csidl = -1;
+ StringCchCopyW(pfti.szTargetParsingName, MAX_PATH, (WCHAR*)pidl->mkid.abID);
+
+ return SHELL32_BindToSF(pidlRoot, &pfti, pidl, &CLSID_ShellFSFolder, riid,
ppvOut);
#else
return E_NOTIMPL;
#endif
Modified: trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] Fri Jul 7
20:34:27 2017
@@ -339,24 +339,11 @@
return E_INVALIDARG;
}
- LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
- if (!pidlChild)
- return E_OUTOFMEMORY;
-
- CComPtr<IShellFolder> psf;
- hr = SHELL32_CoCreateInitSF(m_pidlRoot, NULL, pidlChild, pGUID, -1,
IID_PPV_ARG(IShellFolder, &psf));
- ILFree(pidlChild);
- if (FAILED(hr))
+ hr = SHELL32_BindToSF(m_pidlRoot, NULL, pidl, pGUID, riid, ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- if (_ILIsPidlSimple (pidl))
- {
- return psf->QueryInterface(riid, ppvOut);
- }
- else
- {
- return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
- }
+ return S_OK;
}
HRESULT WINAPI CRegFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved,
REFIID riid, LPVOID *ppvOut)
@@ -485,7 +472,14 @@
}
else
{
- return HCR_GetClassName(m_guid, strRet);
+ BOOL bRet;
+ WCHAR wstrName[MAX_PATH+1];
+ bRet = HCR_GetClassNameW(m_guid, wstrName, MAX_PATH);
+ if (!bRet)
+ return E_FAIL;
+
+ return SHSetStrRet(strRet, wstrName);
+
}
}
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] Fri Jul 7 20:34:27 2017
@@ -40,12 +40,7 @@
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
LPITEMIDLIST * pidlInOut,
LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
-HRESULT HCR_GetClassName(REFIID riid, LPSTRRET strRet);
-
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD
dwFlags, LPSTRRET strRet);
-
-HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
- LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID *
ppvOut);
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
@@ -55,8 +50,16 @@
HRESULT SHELL32_CompareChildren(IShellFolder2* psf, LPARAM lParam, LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2);
-HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
- LPCITEMIDLIST pidlChild, const GUID* clsid, int csidl, REFIID riid,
LPVOID *ppvOut);
+#ifdef __cplusplus
+HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO*
ppfti,
+ LPCITEMIDLIST pidlChild, const GUID* clsid, REFIID riid, LPVOID
*ppvOut);
+
+HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, const GUID* clsid,
+ int csidl, REFIID riid, LPVOID *ppvOut);
+#endif
+
+HRESULT SHELL32_BindToSF (LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO* ppfti,
+ LPCITEMIDLIST pidl, const GUID* clsid, REFIID riid, LPVOID *ppvOut);
extern "C"
BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey);
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] Fri Jul 7 20:34:27 2017
@@ -24,37 +24,6 @@
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-
-/***************************************************************************
- * SHELL32_GetCustomFolderAttributeFromPath (internal function)
- *
- * Gets a value from the folder's desktop.ini file, if one exists.
- *
- * PARAMETERS
- * pwszFolderPath[I] Folder containing the desktop.ini file.
- * pwszHeading [I] Heading in .ini file.
- * pwszAttribute [I] Attribute in .ini file.
- * pwszValue [O] Buffer to store value into.
- * cchValue [I] Size in characters including NULL of buffer pointed to
- * by pwszValue.
- *
- * RETURNS
- * TRUE if returned non-NULL value.
- * FALSE otherwise.
- */
-static BOOL __inline SHELL32_GetCustomFolderAttributeFromPath(
- LPWSTR pwszFolderPath, LPCWSTR pwszHeading, LPCWSTR pwszAttribute,
- LPWSTR pwszValue, DWORD cchValue)
-{
- static const WCHAR wszDesktopIni[] =
-
{'d','e','s','k','t','o','p','.','i','n','i',0};
- static const WCHAR wszDefault[] = {0};
-
- PathAddBackslashW(pwszFolderPath);
- PathAppendW(pwszFolderPath, wszDesktopIni);
- return GetPrivateProfileStringW(pwszHeading, pwszAttribute, wszDefault,
- pwszValue, cchValue, pwszFolderPath);
-}
/***************************************************************************
* GetNextElement (internal function)
@@ -148,13 +117,11 @@
* pathRoot can be NULL for Folders being a drive.
* In this case the absolute path is built from pidlChild (eg. C:)
*/
-HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
- LPCITEMIDLIST pidlChild, const GUID* clsid, int csidl, REFIID riid,
LPVOID *ppvOut)
+HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO*
ppfti,
+ LPCITEMIDLIST pidlChild, const GUID* clsid, REFIID riid, LPVOID *ppvOut)
{
HRESULT hr;
CComPtr<IShellFolder> pShellFolder;
-
- TRACE ("%p %s %p\n", pidlRoot, debugstr_w(pathRoot), pidlChild);
hr = SHCoCreateInstance(NULL, clsid, NULL, IID_PPV_ARG(IShellFolder,
&pShellFolder));
if (FAILED(hr))
@@ -164,32 +131,9 @@
CComPtr<IPersistFolder> ppf;
CComPtr<IPersistFolder3> ppf3;
- if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3,
&ppf3))))
- {
- PERSIST_FOLDER_TARGET_INFO ppfti;
-
- ZeroMemory (&ppfti, sizeof (ppfti));
-
- /* fill the PERSIST_FOLDER_TARGET_INFO */
- ppfti.dwAttributes = -1;
- ppfti.csidl = csidl;
-
- /* build path */
- if (pathRoot)
- {
- lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1);
- PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a
backslash here ? */
- }
-
- if (pidlChild)
- {
- int len = wcslen(ppfti.szTargetParsingName);
-
- if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH -
len))
- hr = E_INVALIDARG;
- }
-
- ppf3->InitializeEx(NULL, pidlAbsolute, &ppfti);
+ if (ppfti &&
SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3))))
+ {
+ ppf3->InitializeEx(NULL, pidlAbsolute, ppfti);
}
else if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder,
&ppf))))
{
@@ -200,91 +144,39 @@
return pShellFolder->QueryInterface(riid, ppvOut);
}
-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_BindToFS [Internal]
- *
- * Common code for IShellFolder_BindToObject.
- *
- * PARAMS
- * pidlRoot [I] The parent shell folder's absolute pidl.
- * pathRoot [I] Absolute dos path of the parent shell folder.
- * pidlComplete [I] PIDL of the child. Relative to pidlRoot.
- * riid [I] GUID of the interface, which ppvOut shall be bound to.
- * ppvOut [O] A reference to the child's interface (riid).
- *
- * NOTES
- * pidlComplete has to contain at least one non empty SHITEMID.
- * This function makes special assumptions on the shell namespace, which
- * means you probably can't use it for your IShellFolder implementation.
- */
-HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
- LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid,
LPVOID * ppvOut)
-{
- CComPtr<IShellFolder> pSF;
- HRESULT hr;
- 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))
- {
- ERR("Got an unknown type of pidl!\n");
+HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, const GUID* clsid,
+ int csidl, REFIID riid, LPVOID *ppvOut)
+{
+ /* fill the PERSIST_FOLDER_TARGET_INFO */
+ PERSIST_FOLDER_TARGET_INFO pfti = {0};
+ pfti.dwAttributes = -1;
+ pfti.csidl = csidl;
+
+ return SHELL32_CoCreateInitSF(pidlRoot, &pfti, NULL, clsid, riid, ppvOut);
+}
+
+HRESULT SHELL32_BindToSF (LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO* ppfti,
+ LPCITEMIDLIST pidl, const GUID* clsid, REFIID riid, LPVOID *ppvOut)
+{
+ PITEMID_CHILD pidlChild = ILCloneFirst (pidl);
+ if (!pidlChild)
return E_FAIL;
- }
-
- *ppvOut = NULL;
-
- 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, -1,
IID_PPV_ARG(IShellFolder, &pSF));
-
- if (pidlChild != pidlComplete)
- ILFree ((LPITEMIDLIST)pidlChild);
-
- if (SUCCEEDED (hr)) {
- if (_ILIsPidlSimple (pidlComplete)) {
- /* no sub folders */
- hr = pSF->QueryInterface(riid, ppvOut);
- } else {
- /* go deeper */
- hr = pSF->BindToObject(ILGetNext (pidlComplete), NULL, riid, ppvOut);
- }
- }
-
- TRACE ("-- returning (%p) %08x\n", *ppvOut, hr);
-
- return hr;
+
+ CComPtr<IShellFolder> psf;
+ HRESULT hr = SHELL32_CoCreateInitSF(pidlRoot,
+ ppfti,
+ pidlChild,
+ clsid,
+ IID_PPV_ARG(IShellFolder, &psf));
+ ILFree(pidlChild);
+
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (_ILIsPidlSimple (pidl))
+ return psf->QueryInterface(riid, ppvOut);
+ else
+ return psf->BindToObject(ILGetNext (pidl), NULL, riid, ppvOut);
}
/***********************************************************************
@@ -317,122 +209,6 @@
ILFree (pidlFirst);
return hr;
-}
-
-HRESULT HCR_GetClassName(REFIID riid, LPSTRRET strRet)
-{
- BOOL bRet;
- WCHAR wstrName[MAX_PATH+1];
- bRet = HCR_GetClassNameW(riid, wstrName, MAX_PATH);
- if (!bRet)
- return E_FAIL;
-
- return SHSetStrRet(strRet, wstrName);
-}
-
-/***********************************************************************
- * SHELL32_GetItemAttributes
- *
- * NOTES
- * Observed values:
- * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
- * file: 0x40000177 FILESYSTEM
- * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
- * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
- * (seems to be default for shell extensions if no registry entry exists)
- *
- * win2k:
- * folder: 0xF0400177 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR |
CANMONIKER
- * file: 0x40400177 FILESYSTEM | CANMONIKER
- * drive 0xF0400154 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR |
CANMONIKER | CANRENAME (LABEL)
- *
- * According to the MSDN documentation this function should not set flags. It claims only
to reset flags when necessary.
- * However it turns out the native shell32.dll _sets_ flags in several cases - so do we.
- */
-
-static const DWORD dwSupportedAttr=
- SFGAO_CANCOPY | /*0x00000001 */
- SFGAO_CANMOVE | /*0x00000002 */
- SFGAO_CANLINK | /*0x00000004 */
- SFGAO_CANRENAME | /*0x00000010 */
- SFGAO_CANDELETE | /*0x00000020 */
- SFGAO_HASPROPSHEET | /*0x00000040 */
- SFGAO_DROPTARGET | /*0x00000100 */
- SFGAO_LINK | /*0x00010000 */
- SFGAO_READONLY | /*0x00040000 */
- SFGAO_HIDDEN | /*0x00080000 */
- SFGAO_FILESYSANCESTOR | /*0x10000000 */
- SFGAO_FOLDER | /*0x20000000 */
- SFGAO_FILESYSTEM | /*0x40000000 */
- SFGAO_HASSUBFOLDER; /*0x80000000 */
-
-HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD
pdwAttributes)
-{
- DWORD dwFileAttributes, dwShellAttributes;
-
- if (!_ILIsFolder(pidl) && !_ILIsValue(pidl))
- {
- ERR("Got wrong type of pidl!\n");
- *pdwAttributes &= SFGAO_CANLINK;
- return S_OK;
- }
-
- if (*pdwAttributes & ~dwSupportedAttr)
- {
- WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes &
~dwSupportedAttr));
- *pdwAttributes &= dwSupportedAttr;
- }
-
- dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
-
- /* Set common attributes */
- dwShellAttributes = *pdwAttributes;
- dwShellAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET |
SFGAO_CANDELETE |
- SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE |
SFGAO_CANCOPY;
-
- if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- dwShellAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER |
SFGAO_FILESYSANCESTOR);
- }
- else
- dwShellAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER |
SFGAO_FILESYSANCESTOR);
-
- if (dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
- dwShellAttributes |= SFGAO_HIDDEN;
- else
- dwShellAttributes &= ~SFGAO_HIDDEN;
-
- if (dwFileAttributes & FILE_ATTRIBUTE_READONLY)
- dwShellAttributes |= SFGAO_READONLY;
- else
- dwShellAttributes &= ~SFGAO_READONLY;
-
- if (SFGAO_LINK & *pdwAttributes)
- {
- char ext[MAX_PATH];
-
- if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk"))
- dwShellAttributes &= ~SFGAO_LINK;
- }
-
- if (SFGAO_HASSUBFOLDER & *pdwAttributes)
- {
- CComPtr<IShellFolder> psf2;
- if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder,
&psf2))))
- {
- CComPtr<IEnumIDList> pEnumIL;
- if (SUCCEEDED(psf2->EnumObjects(0, SHCONTF_FOLDERS, &pEnumIL)))
- {
- if (pEnumIL->Skip(1) != S_OK)
- dwShellAttributes &= ~SFGAO_HASSUBFOLDER;
- }
- }
- }
-
- *pdwAttributes &= dwShellAttributes;
-
- TRACE ("-- 0x%08x\n", *pdwAttributes);
- return S_OK;
}
HRESULT SHELL32_CompareChildren(IShellFolder2* psf, LPARAM lParam, LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2)