https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d7313273c50358922b7d2e253c186d0081ec0e0
commit 9d7313273c50358922b7d2e253c186d0081ec0e0 Author: Giannis Adamopoulos <[email protected]> AuthorDate: Tue Feb 20 16:31:28 2018 +0200 Commit: Giannis Adamopoulos <[email protected]> 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);
