[SHELL32]

- Don't hardcode the path in the shell namespace in any folder appart for CDesktopFolder and CDrivesFolder.
- Make SHELL32_CoCreateInitSF slightly more generic and use it when we need to create and initialise a shell folder.
- Now SHELL32_BindToFS is used only by CFSFolder but SHELL32_CoCreateInitSF still uses the generic _ILSimpleGetTextW (it accesses the pidl).

svn path=/trunk/; revision=72167
This commit is contained in:
Giannis Adamopoulos 2016-08-09 18:05:50 +00:00
parent b346062c73
commit ecf30d78ed
16 changed files with 163 additions and 230 deletions

View file

@ -25,37 +25,13 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell);
CAdminToolsFolder::CAdminToolsFolder()
{
m_pisfInner = NULL;
m_pidlInner = NULL;
}
CAdminToolsFolder::~CAdminToolsFolder()
{
m_pisfInner.Release();
}
HRESULT WINAPI CAdminToolsFolder::FinalConstruct()
{
HRESULT hr;
CComPtr<IPersistFolder3> ppf3;
hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder2, &m_pisfInner));
if (FAILED(hr))
return hr;
hr = m_pisfInner->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
if (FAILED(hr))
return hr;
LPITEMIDLIST pidlRoot = _ILCreateAdminTools();
PERSIST_FOLDER_TARGET_INFO info;
ZeroMemory(&info, sizeof(PERSIST_FOLDER_TARGET_INFO));
info.csidl = CSIDL_COMMON_ADMINTOOLS;
hr = ppf3->InitializeEx(NULL, pidlRoot, &info);
SHFree(pidlRoot);
return hr;
if(m_pidlInner)
SHFree(m_pidlInner);
}
HRESULT WINAPI CAdminToolsFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
@ -194,13 +170,22 @@ HRESULT WINAPI CAdminToolsFolder::GetClassID(CLSID *lpClassId)
HRESULT WINAPI CAdminToolsFolder::Initialize(LPCITEMIDLIST pidl)
{
return S_OK;
m_pidlInner = ILClone(pidl);
if (!m_pidlInner)
return E_OUTOFMEMORY;
return SHELL32_CoCreateInitSF(m_pidlInner,
NULL,
NULL,
&CLSID_ShellFSFolder,
CSIDL_COMMON_ADMINTOOLS,
IID_PPV_ARG(IShellFolder2, &m_pisfInner));
}
HRESULT WINAPI CAdminToolsFolder::GetCurFolder(LPITEMIDLIST *pidl)
{
if (!pidl)
return E_POINTER;
*pidl = _ILCreateAdminTools();
*pidl = ILClone(m_pidlInner);
return S_OK;
}

View file

@ -30,10 +30,10 @@ class CAdminToolsFolder :
{
private:
CComPtr<IShellFolder2> m_pisfInner;
public:
LPITEMIDLIST m_pidlInner;
public:
CAdminToolsFolder();
~CAdminToolsFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes);

View file

@ -293,14 +293,6 @@ CControlPanelFolder::~CControlPanelFolder()
SHFree(pidlRoot);
}
HRESULT WINAPI CControlPanelFolder::FinalConstruct()
{
pidlRoot = _ILCreateControlPanel(); /* my qualified pidl */
if (pidlRoot == NULL)
return E_OUTOFMEMORY;
return S_OK;
}
/**************************************************************************
* CControlPanelFolder::ParseDisplayName
*/

View file

@ -38,7 +38,6 @@ class CControlPanelFolder :
public:
CControlPanelFolder();
~CControlPanelFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes);

View file

@ -258,43 +258,42 @@ CDesktopFolder::~CDesktopFolder()
HRESULT WINAPI CDesktopFolder::FinalConstruct()
{
WCHAR szMyPath[MAX_PATH];
HRESULT hr;
CComPtr<IPersistFolder3> ppf3;
WCHAR szMyPath[MAX_PATH]; HRESULT hr;
/* Create the root pidl */
pidlRoot = _ILCreateDesktop();
if (!pidlRoot)
return E_OUTOFMEMORY;
/* Create the inner fs folder */
hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
if (FAILED(hr))
hr = SHELL32_CoCreateInitSF(pidlRoot,
NULL,
NULL,
&CLSID_ShellFSFolder,
CSIDL_DESKTOPDIRECTORY,
IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
if (FAILED(hr))
/* 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));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
PERSIST_FOLDER_TARGET_INFO info;
ZeroMemory(&info, sizeof(PERSIST_FOLDER_TARGET_INFO));
info.csidl = CSIDL_DESKTOPDIRECTORY;
hr = ppf3->InitializeEx(NULL, pidlRoot, &info);
/* Create the inner shared fs folder */
hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder2, &m_SharedDesktopFSFolder));
if (FAILED(hr))
return hr;
hr = m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
if (FAILED(hr))
return hr;
info.csidl = CSIDL_COMMON_DESKTOPDIRECTORY;
hr = ppf3->InitializeEx(NULL, pidlRoot, &info);
/* Cache the path to the user desktop directory */
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
return E_UNEXPECTED;
sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
if (!sPathTarget)
return E_OUTOFMEMORY;
wcscpy(sPathTarget, szMyPath);
return S_OK;
}

View file

@ -312,7 +312,31 @@ HRESULT WINAPI CDrivesFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcRese
if (_ILIsSpecialFolder(pidl))
return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
return SHELL32_BindToFS(pidlRoot, NULL, pidl, 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))
return hr;
if (_ILIsPidlSimple (pidl))
{
return psf->QueryInterface(riid, ppvOut);
}
else
{
return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
}
}
/**************************************************************************

View file

@ -25,37 +25,13 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell);
CFontsFolder::CFontsFolder()
{
m_pisfInner = NULL;
m_pidlInner = NULL;
}
CFontsFolder::~CFontsFolder()
{
}
HRESULT WINAPI CFontsFolder::FinalConstruct()
{
HRESULT hr;
CComPtr<IPersistFolder3> ppf3;
hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder2, &m_pisfInner));
if (FAILED(hr))
return hr;
hr = m_pisfInner->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
if (FAILED(hr))
return hr;
LPITEMIDLIST pidl = _ILCreateGuid(PT_GUID, CLSID_FontsFolderShortcut);
if (!pidl)
return E_OUTOFMEMORY;
PERSIST_FOLDER_TARGET_INFO info;
ZeroMemory(&info, sizeof(PERSIST_FOLDER_TARGET_INFO));
info.csidl = CSIDL_FONTS;
hr = ppf3->InitializeEx(NULL, pidl, &info);
ILFree(pidl);
return hr;
if(m_pidlInner)
SHFree(m_pidlInner);
}
HRESULT WINAPI CFontsFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
@ -195,15 +171,22 @@ HRESULT WINAPI CFontsFolder::GetClassID(CLSID *lpClassId)
HRESULT WINAPI CFontsFolder::Initialize(LPCITEMIDLIST pidl)
{
return S_OK;
m_pidlInner = ILClone(pidl);
if (!m_pidlInner)
return E_OUTOFMEMORY;
return SHELL32_CoCreateInitSF(m_pidlInner,
NULL,
NULL,
&CLSID_ShellFSFolder,
CSIDL_FONTS,
IID_PPV_ARG(IShellFolder2, &m_pisfInner));
}
HRESULT WINAPI CFontsFolder::GetCurFolder(LPITEMIDLIST *pidl)
{
if (!pidl)
return E_POINTER;
*pidl = _ILCreateGuid(PT_GUID, CLSID_FontsFolderShortcut);
*pidl = ILClone(m_pidlInner);
return S_OK;
}

View file

@ -30,10 +30,10 @@ class CFontsFolder :
{
private:
CComPtr<IShellFolder2> m_pisfInner;
LPITEMIDLIST m_pidlInner;
public:
CFontsFolder();
~CFontsFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes);

View file

@ -25,37 +25,13 @@ WINE_DEFAULT_DEBUG_CHANNEL (mydocs);
CMyDocsFolder::CMyDocsFolder()
{
m_pisfInner = NULL;
m_pidlInner = NULL;
}
CMyDocsFolder::~CMyDocsFolder()
{
m_pisfInner.Release();
}
HRESULT WINAPI CMyDocsFolder::FinalConstruct()
{
HRESULT hr;
CComPtr<IPersistFolder3> ppf3;
hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder2, &m_pisfInner));
if (FAILED(hr))
return hr;
hr = m_pisfInner->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
if (FAILED(hr))
return hr;
LPITEMIDLIST pidlRoot = _ILCreateMyDocuments();
PERSIST_FOLDER_TARGET_INFO info;
ZeroMemory(&info, sizeof(PERSIST_FOLDER_TARGET_INFO));
info.csidl = CSIDL_PERSONAL;
hr = ppf3->InitializeEx(NULL, pidlRoot, &info);
SHFree(pidlRoot);
return hr;
if(m_pidlInner)
SHFree(m_pidlInner);
}
HRESULT WINAPI CMyDocsFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
@ -194,13 +170,22 @@ HRESULT WINAPI CMyDocsFolder::GetClassID(CLSID *lpClassId)
HRESULT WINAPI CMyDocsFolder::Initialize(LPCITEMIDLIST pidl)
{
return S_OK;
m_pidlInner = ILClone(pidl);
if (!m_pidlInner)
return E_OUTOFMEMORY;
return SHELL32_CoCreateInitSF(m_pidlInner,
NULL,
NULL,
&CLSID_ShellFSFolder,
CSIDL_PERSONAL,
IID_PPV_ARG(IShellFolder2, &m_pisfInner));
}
HRESULT WINAPI CMyDocsFolder::GetCurFolder(LPITEMIDLIST *pidl)
{
if (!pidl)
return E_POINTER;
*pidl = _ILCreateMyDocuments();
*pidl = ILClone(m_pidlInner);
return S_OK;
}

View file

@ -30,10 +30,10 @@ class CMyDocsFolder :
{
private:
CComPtr<IShellFolder2> m_pisfInner;
LPITEMIDLIST m_pidlInner;
public:
CMyDocsFolder();
~CMyDocsFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes);

View file

@ -204,16 +204,8 @@ CNetFolder::CNetFolder()
CNetFolder::~CNetFolder()
{
TRACE("-- destroying IShellFolder(%p)\n", this);
SHFree(pidlRoot);
}
HRESULT WINAPI CNetFolder::FinalConstruct()
{
pidlRoot = _ILCreateGuid(PT_GUID, CLSID_NetworkPlaces); /* my qualified pidl */
if (pidlRoot == NULL)
return E_OUTOFMEMORY;
return S_OK;
if (pidlRoot)
SHFree(pidlRoot);
}
/**************************************************************************
@ -272,36 +264,31 @@ HRESULT WINAPI CNetFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLI
HRESULT WINAPI CNetFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
#ifdef HACKY_UNC_PATHS
HRESULT hr;
CComPtr<IPersistFolder3> ppf3;
hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IPersistFolder3, &ppf3));
if (FAILED(hr))
return hr;
PITEMID_CHILD pidlChild = ILCloneFirst (pidl);
if (!pidlChild)
return E_FAIL;
PERSIST_FOLDER_TARGET_INFO pfti = {0};
pfti.csidl = -1;
wcscpy(pfti.szTargetParsingName, (WCHAR*)pidl->mkid.abID);
PIDLIST_ABSOLUTE pidlAbsolute = ILCombine(pidlRoot,pidlChild);
if (!pidlAbsolute)
return E_FAIL;
PCUIDLIST_RELATIVE pidlChild = ILCloneFirst (pidl);
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);
hr = ppf3->InitializeEx(NULL, ILCombine(pidlRoot,pidlChild), &pfti);
if (FAILED(hr))
if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (_ILIsPidlSimple (pidl))
{
return ppf3->QueryInterface(riid, ppvOut);
}
return psf->QueryInterface(riid, ppvOut);
else
{
CComPtr<IShellFolder> psf;
hr = ppf3->QueryInterface(IID_PPV_ARG(IShellFolder, &psf));
if (FAILED(hr))
return hr;
return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
}
#else
return E_NOTIMPL;
#endif
@ -584,8 +571,10 @@ HRESULT WINAPI CNetFolder::GetClassID(CLSID *lpClassId)
*/
HRESULT WINAPI CNetFolder::Initialize(LPCITEMIDLIST pidl)
{
TRACE("(%p)->(%p)\n", this, pidl);
if (pidlRoot)
SHFree((LPVOID)pidlRoot);
pidlRoot = ILClone(pidl);
return S_OK;
}

View file

@ -36,7 +36,6 @@ class CNetFolder :
public:
CNetFolder();
~CNetFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes);

View file

@ -192,14 +192,6 @@ CPrinterFolder::~CPrinterFolder()
SHFree(pidlRoot);
}
HRESULT WINAPI CPrinterFolder::FinalConstruct()
{
pidlRoot = _ILCreatePrinters(); /* my qualified pidl */
if (pidlRoot == NULL)
return E_OUTOFMEMORY;
return S_OK;
}
/**************************************************************************
* CPrinterFolder::ParseDisplayName
*

View file

@ -39,7 +39,6 @@ class CPrinterFolder :
public:
CPrinterFolder();
~CPrinterFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes);

View file

@ -77,6 +77,9 @@ HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST
HRESULT SHELL32_CompareGuidItems(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
LPCITEMIDLIST pidlChild, const GUID* clsid, int csidl, REFIID riid, LPVOID *ppvOut);
extern "C"
BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey);

View file

@ -148,60 +148,56 @@ HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
* pathRoot can be NULL for Folders being a drive.
* In this case the absolute path is built from pidlChild (eg. C:)
*/
static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
LPCITEMIDLIST pidlChild, REFCLSID clsid, IShellFolder** ppsfOut)
HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
LPCITEMIDLIST pidlChild, const GUID* clsid, int csidl, 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 (SUCCEEDED (hr))
hr = SHCoCreateInstance(NULL, clsid, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
if (FAILED(hr))
return hr;
LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
CComPtr<IPersistFolder> ppf;
CComPtr<IPersistFolder3> ppf3;
if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3))))
{
LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
CComPtr<IPersistFolder> ppf;
CComPtr<IPersistFolder3> ppf3;
PERSIST_FOLDER_TARGET_INFO ppfti;
if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3))))
ZeroMemory (&ppfti, sizeof (ppfti));
/* fill the PERSIST_FOLDER_TARGET_INFO */
ppfti.dwAttributes = -1;
ppfti.csidl = csidl;
/* build path */
if (pathRoot)
{
PERSIST_FOLDER_TARGET_INFO ppfti;
ZeroMemory (&ppfti, sizeof (ppfti));
/* fill the PERSIST_FOLDER_TARGET_INFO */
ppfti.dwAttributes = -1;
ppfti.csidl = -1;
/* 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);
lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1);
PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */
}
else if (SUCCEEDED((hr = pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &ppf)))))
if (pidlChild)
{
ppf->Initialize(pidlAbsolute);
int len = wcslen(ppfti.szTargetParsingName);
if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH - len))
hr = E_INVALIDARG;
}
ILFree (pidlAbsolute);
ppf3->InitializeEx(NULL, pidlAbsolute, &ppfti);
}
else if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &ppf))))
{
ppf->Initialize(pidlAbsolute);
}
ILFree (pidlAbsolute);
*ppsfOut = pShellFolder.Detach();
TRACE ("-- (%p) ret=0x%08x\n", *ppsfOut, hr);
return hr;
return pShellFolder->QueryInterface(riid, ppvOut);
}
void SHELL32_GetCLSIDForDirectory(LPCWSTR pathRoot, LPCITEMIDLIST pidl, CLSID* pclsidFolder)
@ -271,7 +267,7 @@ HRESULT SHELL32_BindToFS (LPCITEMIDLIST pidlRoot,
if ((attributes & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) != 0)
SHELL32_GetCLSIDForDirectory(pathRoot, pidlChild, &clsidFolder);
hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsidFolder, &pSF);
hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, &clsidFolder, -1, IID_PPV_ARG(IShellFolder, &pSF));
if (pidlChild != pidlComplete)
ILFree ((LPITEMIDLIST)pidlChild);
@ -312,34 +308,22 @@ HRESULT SHELL32_BindToGuidItem(LPCITEMIDLIST pidlRoot,
return E_INVALIDARG;
}
hr = SHCoCreateInstance(NULL, pGUID, NULL, IID_PPV_ARG(IPersistFolder, &pFolder));
LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
if (!pidlChild)
return E_OUTOFMEMORY;
CComPtr<IShellFolder> psf;
hr = SHELL32_CoCreateInitSF(pidlRoot, NULL, pidlChild, pGUID, -1, IID_PPV_ARG(IShellFolder, &psf));
ILFree(pidlChild);
if (FAILED(hr))
return hr;
if (_ILIsPidlSimple (pidl))
{
hr = pFolder->Initialize(ILCombine(pidlRoot, pidl));
if (FAILED(hr))
return hr;
return pFolder->QueryInterface(riid, ppvOut);
return psf->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))
return hr;
return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
}
}