diff --git a/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp b/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp index a2ce99e4a28..0c944612f45 100644 --- a/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CAdminToolsFolder.cpp @@ -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 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; } diff --git a/reactos/dll/win32/shell32/folders/CAdminToolsFolder.h b/reactos/dll/win32/shell32/folders/CAdminToolsFolder.h index 1719d90df6c..f6cd79a2fe4 100644 --- a/reactos/dll/win32/shell32/folders/CAdminToolsFolder.h +++ b/reactos/dll/win32/shell32/folders/CAdminToolsFolder.h @@ -30,10 +30,10 @@ class CAdminToolsFolder : { private: CComPtr 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); diff --git a/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp b/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp index 6943f28b04d..664184569d8 100644 --- a/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp @@ -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 */ diff --git a/reactos/dll/win32/shell32/folders/CControlPanelFolder.h b/reactos/dll/win32/shell32/folders/CControlPanelFolder.h index 2e2ec0ec3db..ff31db51e6a 100644 --- a/reactos/dll/win32/shell32/folders/CControlPanelFolder.h +++ b/reactos/dll/win32/shell32/folders/CControlPanelFolder.h @@ -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); diff --git a/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp b/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp index b8da039d902..02dd05e32ac 100644 --- a/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp @@ -258,43 +258,42 @@ CDesktopFolder::~CDesktopFolder() HRESULT WINAPI CDesktopFolder::FinalConstruct() { - WCHAR szMyPath[MAX_PATH]; - HRESULT hr; - CComPtr 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; } diff --git a/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp b/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp index aa79ea8408e..5622a2fff7f 100644 --- a/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -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 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); + } } /************************************************************************** diff --git a/reactos/dll/win32/shell32/folders/CFontsFolder.cpp b/reactos/dll/win32/shell32/folders/CFontsFolder.cpp index 5728343dc0a..d504ec9b21e 100644 --- a/reactos/dll/win32/shell32/folders/CFontsFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CFontsFolder.cpp @@ -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 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; } diff --git a/reactos/dll/win32/shell32/folders/CFontsFolder.h b/reactos/dll/win32/shell32/folders/CFontsFolder.h index 3a397839108..e3b9205187c 100644 --- a/reactos/dll/win32/shell32/folders/CFontsFolder.h +++ b/reactos/dll/win32/shell32/folders/CFontsFolder.h @@ -30,10 +30,10 @@ class CFontsFolder : { private: CComPtr 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); diff --git a/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp b/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp index 93896daf48b..e2e557810ee 100644 --- a/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CMyDocsFolder.cpp @@ -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 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; } diff --git a/reactos/dll/win32/shell32/folders/CMyDocsFolder.h b/reactos/dll/win32/shell32/folders/CMyDocsFolder.h index 05e13b9cf3c..b689a6719f2 100644 --- a/reactos/dll/win32/shell32/folders/CMyDocsFolder.h +++ b/reactos/dll/win32/shell32/folders/CMyDocsFolder.h @@ -30,10 +30,10 @@ class CMyDocsFolder : { private: CComPtr 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); diff --git a/reactos/dll/win32/shell32/folders/CNetFolder.cpp b/reactos/dll/win32/shell32/folders/CNetFolder.cpp index 266bc54d7fc..774d506d4c2 100644 --- a/reactos/dll/win32/shell32/folders/CNetFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CNetFolder.cpp @@ -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 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 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 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; } diff --git a/reactos/dll/win32/shell32/folders/CNetFolder.h b/reactos/dll/win32/shell32/folders/CNetFolder.h index 618f3da976c..33f65bf3191 100644 --- a/reactos/dll/win32/shell32/folders/CNetFolder.h +++ b/reactos/dll/win32/shell32/folders/CNetFolder.h @@ -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); diff --git a/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp b/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp index 14b483390d0..b63ab772ac9 100644 --- a/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CPrinterFolder.cpp @@ -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 * diff --git a/reactos/dll/win32/shell32/folders/CPrinterFolder.h b/reactos/dll/win32/shell32/folders/CPrinterFolder.h index b3f30a4421d..699338079ef 100644 --- a/reactos/dll/win32/shell32/folders/CPrinterFolder.h +++ b/reactos/dll/win32/shell32/folders/CPrinterFolder.h @@ -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); diff --git a/reactos/dll/win32/shell32/shfldr.h b/reactos/dll/win32/shell32/shfldr.h index 5aaa88cb48c..61759c6e016 100644 --- a/reactos/dll/win32/shell32/shfldr.h +++ b/reactos/dll/win32/shell32/shfldr.h @@ -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); diff --git a/reactos/dll/win32/shell32/shlfolder.cpp b/reactos/dll/win32/shell32/shlfolder.cpp index 138632a9c77..77cdbb5fc1f 100644 --- a/reactos/dll/win32/shell32/shlfolder.cpp +++ b/reactos/dll/win32/shell32/shlfolder.cpp @@ -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 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 ppf; + CComPtr ppf3; + + if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3)))) { - LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild); - CComPtr ppf; - CComPtr 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 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 psf; - hr = pFolder->QueryInterface(IID_PPV_ARG(IShellFolder, &psf)); - if (FAILED(hr)) - return hr; - return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut); } }