https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d7313273c50358922b7d2...
commit 9d7313273c50358922b7d2e253c186d0081ec0e0 Author: Giannis Adamopoulos gadamopoulos@reactos.org AuthorDate: Tue Feb 20 16:31:28 2018 +0200 Commit: Giannis Adamopoulos gadamopoulos@reactos.org CommitDate: Tue Feb 20 16:33:30 2018 +0200
[SHELL32] CShellItem: Implement BindToHandler and improve GetAttributes based on wine Fixes lots of tests. --- dll/win32/shell32/CShellItem.cpp | 82 +++++++++++++++++++++++++++++++++++----- dll/win32/shell32/CShellItem.h | 1 + 2 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/dll/win32/shell32/CShellItem.cpp b/dll/win32/shell32/CShellItem.cpp index 5ef965de47..f0a6ee650a 100644 --- a/dll/win32/shell32/CShellItem.cpp +++ b/dll/win32/shell32/CShellItem.cpp @@ -76,13 +76,68 @@ HRESULT CShellItem::get_parent_shellfolder(IShellFolder **ppsf) return hr; }
+HRESULT CShellItem::get_shellfolder(IBindCtx *pbc, REFIID riid, void **ppvOut) +{ + CComPtr<IShellFolder> psf; + CComPtr<IShellFolder> psfDesktop; + HRESULT ret; + + ret = SHGetDesktopFolder(&psfDesktop); + if (FAILED_UNEXPECTEDLY(ret)) + return ret; + + if (_ILIsDesktop(m_pidl)) + psf = psfDesktop; + else + { + ret = psfDesktop->BindToObject(m_pidl, pbc, IID_PPV_ARG(IShellFolder, &psf)); + if (FAILED_UNEXPECTEDLY(ret)) + return ret; + } + + return psf->QueryInterface(riid, ppvOut); +} + HRESULT WINAPI CShellItem::BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut) { - FIXME("(%p,%p,%s,%p,%p)\n", this, pbc, shdebugstr_guid(&rbhid), riid, ppvOut); + HRESULT ret; + TRACE("(%p, %p,%s,%p,%p)\n", this, pbc, shdebugstr_guid(&rbhid), riid, ppvOut);
*ppvOut = NULL; + if (IsEqualGUID(rbhid, BHID_SFObject)) + { + return get_shellfolder(pbc, riid, ppvOut); + } + else if (IsEqualGUID(rbhid, BHID_SFUIObject)) + { + CComPtr<IShellFolder> psf_parent; + if (_ILIsDesktop(m_pidl)) + ret = SHGetDesktopFolder(&psf_parent); + else + ret = get_parent_shellfolder(&psf_parent); + if (FAILED_UNEXPECTEDLY(ret)) + return ret;
- return E_NOTIMPL; + LPCITEMIDLIST pidl = ILFindLastID(m_pidl); + return psf_parent->GetUIObjectOf(NULL, 1, &pidl, riid, NULL, ppvOut); + } + else if (IsEqualGUID(rbhid, BHID_DataObject)) + { + return BindToHandler(pbc, BHID_SFUIObject, IID_IDataObject, ppvOut); + } + else if (IsEqualGUID(rbhid, BHID_SFViewObject)) + { + CComPtr<IShellFolder> psf; + ret = get_shellfolder(NULL, IID_PPV_ARG(IShellFolder, &psf)); + if (FAILED_UNEXPECTEDLY(ret)) + return ret; + + return psf->CreateViewObject(NULL, riid, ppvOut); + } + + FIXME("Unsupported BHID %s.\n", debugstr_guid(&rbhid)); + + return MK_E_NOOBJECT; }
HRESULT WINAPI CShellItem::GetParent(IShellItem **ppsi) @@ -160,15 +215,22 @@ HRESULT WINAPI CShellItem::GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs
TRACE("(%p,%x,%p)\n", this, sfgaoMask, psfgaoAttribs);
- hr = get_parent_shellfolder(&parent_folder); - if (SUCCEEDED(hr)) - { - child_pidl = ILFindLastID(m_pidl); - *psfgaoAttribs = sfgaoMask; - hr = parent_folder->GetAttributesOf(1, &child_pidl, psfgaoAttribs); - } + if (_ILIsDesktop(m_pidl)) + hr = SHGetDesktopFolder(&parent_folder); + else + hr = get_parent_shellfolder(&parent_folder); + if (FAILED_UNEXPECTEDLY(hr)) + return hr;
- return hr; + child_pidl = ILFindLastID(m_pidl); + *psfgaoAttribs = sfgaoMask; + hr = parent_folder->GetAttributesOf(1, &child_pidl, psfgaoAttribs); + *psfgaoAttribs &= sfgaoMask; + + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + return (sfgaoMask == *psfgaoAttribs) ? S_OK : S_FALSE; }
HRESULT WINAPI CShellItem::Compare(IShellItem *oth, SICHINTF hint, int *piOrder) diff --git a/dll/win32/shell32/CShellItem.h b/dll/win32/shell32/CShellItem.h index a75698edfa..57c318523d 100644 --- a/dll/win32/shell32/CShellItem.h +++ b/dll/win32/shell32/CShellItem.h @@ -36,6 +36,7 @@ public: ~CShellItem(); HRESULT get_parent_pidl(LPITEMIDLIST *parent_pidl); HRESULT get_parent_shellfolder(IShellFolder **ppsf); + HRESULT get_shellfolder(IBindCtx *pbc, REFIID riid, void **ppvOut);
// IShellItem virtual HRESULT WINAPI BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut);