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