[PATCH 1/6] shell32: Partial implementation of IShellItem::BindToHandler. (resend)

David Hedberg david.hedberg at gmail.com
Mon Aug 16 02:17:30 CDT 2010


Rebased against current git.

---
 dlls/shell32/shellitem.c       |   43 +++++++++++-
 dlls/shell32/tests/shlfolder.c |  152 ++++++++++++++++++++++++++++++++++++++++
 include/shlguid.h              |   17 +++++
 3 files changed, 210 insertions(+), 2 deletions(-)

diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c
index dbf9b4d..3284020 100644
--- a/dlls/shell32/shellitem.c
+++ b/dlls/shell32/shellitem.c
@@ -147,14 +147,53 @@ static HRESULT ShellItem_get_parent_shellfolder(ShellItem *This, IShellFolder **
     return ret;
 }
 
+static HRESULT ShellItem_get_shellfolder(ShellItem *This, IBindCtx *pbc, IShellFolder **ppsf)
+{
+    IShellFolder *desktop;
+    HRESULT ret;
+
+    ret = SHGetDesktopFolder(&desktop);
+    if (SUCCEEDED(ret))
+    {
+        if (_ILIsDesktop(This->pidl))
+        {
+            *ppsf = desktop;
+            IShellFolder_AddRef(*ppsf);
+        }
+        else
+        {
+            ret = IShellFolder_BindToObject(desktop, This->pidl, pbc, &IID_IShellFolder, (void**)ppsf);
+        }
+
+        IShellFolder_Release(desktop);
+    }
+
+    return ret;
+}
+
 static HRESULT WINAPI ShellItem_BindToHandler(IShellItem *iface, IBindCtx *pbc,
     REFGUID rbhid, REFIID riid, void **ppvOut)
 {
-    FIXME("(%p,%p,%s,%p,%p)\n", iface, pbc, shdebugstr_guid(rbhid), riid, ppvOut);
+    ShellItem *This = (ShellItem*)iface;
+    HRESULT ret;
+    TRACE("(%p,%p,%s,%p,%p)\n", iface, pbc, shdebugstr_guid(rbhid), riid, ppvOut);
 
     *ppvOut = NULL;
+    if (IsEqualGUID(rbhid, &BHID_SFObject))
+    {
+        IShellFolder *psf;
+        ret = ShellItem_get_shellfolder(This, pbc, &psf);
+        if (SUCCEEDED(ret))
+        {
+            ret = IShellFolder_QueryInterface(psf, riid, ppvOut);
+            IShellFolder_Release(psf);
+        }
+        return ret;
+    }
 
-    return E_NOTIMPL;
+    FIXME("Unsupported BHID %s.\n", debugstr_guid(rbhid));
+
+    return MK_E_NOOBJECT;
 }
 
 static HRESULT WINAPI ShellItem_GetParent(IShellItem *iface, IShellItem **ppsi)
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 6c0b6f2..e731f07 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -3218,6 +3218,157 @@ static void test_SHCreateShellItemArray(void)
     Cleanup();
 }
 
+static void test_ShellItemBindToHandler(void)
+{
+    IShellItem *psi;
+    LPITEMIDLIST pidl_desktop;
+    HRESULT hr;
+
+    if(!pSHCreateShellItem)
+    {
+        skip("SHCreateShellItem missing.\n");
+        return;
+    }
+
+    hr = pSHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl_desktop);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+    if(SUCCEEDED(hr))
+    {
+        hr = pSHCreateShellItem(NULL, NULL, pidl_desktop, &psi);
+        ok(hr == S_OK, "Got 0x%08x\n", hr);
+    }
+    if(SUCCEEDED(hr))
+    {
+        IPersistFolder2 *ppf2;
+        IUnknown *punk;
+
+        if(0)
+        {
+            /* Crashes under Windows 7 */
+            hr = IShellItem_BindToHandler(psi, NULL, NULL, NULL, NULL);
+            hr = IShellItem_BindToHandler(psi, NULL, &IID_IUnknown, &IID_IUnknown, NULL);
+        }
+        hr = IShellItem_BindToHandler(psi, NULL, &IID_IUnknown, &IID_IUnknown, (void**)&punk);
+        ok(hr == MK_E_NOOBJECT, "Got 0x%08x\n", hr);
+
+        /* BHID_SFObject */
+        hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&punk);
+        ok(hr == S_OK, "Got 0x%08x\n", hr);
+        if(SUCCEEDED(hr)) IUnknown_Release(punk);
+        hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IPersistFolder2, (void**)&ppf2);
+        ok(hr == S_OK, "Got 0x%08x\n", hr);
+        if(SUCCEEDED(hr))
+        {
+            LPITEMIDLIST pidl_tmp;
+            hr = IPersistFolder2_GetCurFolder(ppf2, &pidl_tmp);
+            ok(hr == S_OK, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr))
+            {
+                ok(ILIsEqual(pidl_desktop, pidl_tmp), "Pidl not equal (%p, %p)\n", pidl_desktop, pidl_tmp);
+                pILFree(pidl_tmp);
+            }
+            IPersistFolder2_Release(ppf2);
+        }
+
+        todo_wine
+        {
+            /* BHID_SFUIObject */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFUIObject, &IID_IDataObject, (void**)&punk);
+            ok(hr == S_OK || broken(hr == E_NOINTERFACE /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFUIObject, &IID_IContextMenu, (void**)&punk);
+            ok(hr == S_OK || broken(hr == E_NOINTERFACE /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_SFViewObject */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFViewObject, &IID_IShellView, (void**)&punk);
+            ok(hr == S_OK, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFViewObject, &IID_IShellFolderView, (void**)&punk);
+            ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_Storage */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_Storage, &IID_IStream, (void**)&punk);
+            ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_Storage, &IID_IUnknown, (void**)&punk);
+            ok(hr == S_OK, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_Stream */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_Stream, &IID_IStream, (void**)&punk);
+            ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_Stream, &IID_IUnknown, (void**)&punk);
+            ok(hr == S_OK, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_StorageEnum */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_StorageEnum, &IID_IEnumShellItems, (void**)&punk);
+            ok(hr == S_OK, "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_Transfer */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_Transfer, &IID_IUnknown, (void**)&punk);
+            ok(hr == E_NOINTERFACE || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_EnumItems */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_EnumItems, &IID_IEnumShellItems, (void**)&punk);
+            ok(hr == S_OK || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_DataObject */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_DataObject, &IID_IDataObject, (void**)&punk);
+            ok(hr == S_OK || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_Filter */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_Filter, &IID_IUnknown, (void**)&punk);
+            ok(hr == S_OK || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_LinkTargetItem */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_LinkTargetItem, &IID_IShellItem, (void**)&punk);
+            ok(hr == E_NOINTERFACE || broken(hr == E_INVALIDARG /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_LinkTargetItem, &IID_IUnknown, (void**)&punk);
+            ok(hr == E_NOINTERFACE || broken(hr == E_INVALIDARG /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_PropertyStore */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_PropertyStore, &IID_IPropertyStore, (void**)&punk);
+            ok(hr == E_NOINTERFACE || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_PropertyStore, &IID_IPropertyStoreFactory, (void**)&punk);
+            ok(hr == E_NOINTERFACE || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_ThumbnailHandler */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_ThumbnailHandler, &IID_IUnknown, (void**)&punk);
+            ok(hr == E_INVALIDARG || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_AssociationArray */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_AssociationArray, &IID_IQueryAssociations, (void**)&punk);
+            ok(hr == S_OK || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+
+            /* BHID_EnumAssocHandlers */
+            hr = IShellItem_BindToHandler(psi, NULL, &BHID_EnumAssocHandlers, &IID_IUnknown, (void**)&punk);
+            ok(hr == E_NOINTERFACE || broken(hr == MK_E_NOOBJECT /* XP */), "Got 0x%08x\n", hr);
+            if(SUCCEEDED(hr)) IUnknown_Release(punk);
+        }
+
+        IShellItem_Release(psi);
+    }
+    else
+        skip("Failed to create ShellItem.\n");
+
+    pILFree(pidl_desktop);
+}
+
 static void test_SHParseDisplayName(void)
 {
     LPITEMIDLIST pidl1, pidl2;
@@ -3902,6 +4053,7 @@ START_TEST(shlfolder)
     test_SHGetItemFromObject();
     test_ShellItemCompare();
     test_SHChangeNotify();
+    test_ShellItemBindToHandler();
 
     OleUninitialize();
 }
diff --git a/include/shlguid.h b/include/shlguid.h
index 190d55e..3af4398 100644
--- a/include/shlguid.h
+++ b/include/shlguid.h
@@ -174,4 +174,21 @@ DEFINE_GUID(EP_PreviewPane, 0x893C63D1, 0x45C8, 0x4D17, 0xBE, 0x19, 0x22, 0x3B,
 DEFINE_GUID(EP_QueryPane, 0x65BCDE4F, 0x4F07, 0x4F27, 0x83, 0xA7, 0x1A, 0xFC, 0xA4, 0xDF, 0x7D, 0xDD);
 DEFINE_GUID(EP_AdvQueryPane, 0xB4E9DB8B, 0x34BA, 0x4C39, 0xB5, 0xCC, 0x16, 0xA1, 0xBD, 0x2C, 0x41, 0x1C);
 
+/* IShellItem/IShellItemArray BindToHandler */
+DEFINE_GUID(BHID_SFObject,    0x3981E224, 0xF559, 0x11D3, 0x8E,0x3A, 0x00,0xC0,0x4F,0x68,0x37,0xD5);
+DEFINE_GUID(BHID_SFUIObject,  0x3981E225, 0xF559, 0x11D3, 0x8E,0x3A, 0x00,0xC0,0x4F,0x68,0x37,0xD5);
+DEFINE_GUID(BHID_SFViewObject,0x3981E226, 0xF559, 0x11D3, 0x8E,0x3A, 0x00,0xC0,0x4F,0x68,0x37,0xD5);
+DEFINE_GUID(BHID_Storage,     0x3981E227, 0xF559, 0x11D3, 0x8E,0x3A, 0x00,0xC0,0x4F,0x68,0x37,0xD5);
+DEFINE_GUID(BHID_Stream,      0x1CEBB3AB, 0x7C10, 0x499A, 0xA4,0x17, 0x92,0xCA,0x16,0xC4,0xCB,0x83);
+DEFINE_GUID(BHID_StorageEnum, 0x4621A4E3, 0xF0D6, 0x4773, 0x8A,0x9C, 0x46,0xE7,0x7B,0x17,0x48,0x40);
+DEFINE_GUID(BHID_Transfer,    0xD5E346A1, 0xF753, 0x4932, 0xB4,0x03, 0x45,0x74,0x80,0x0E,0x24,0x98);
+DEFINE_GUID(BHID_EnumItems,   0x94F60519, 0x2850, 0x4924, 0xAA,0x5A, 0xD1,0x5E,0x84,0x86,0x80,0x39);
+DEFINE_GUID(BHID_DataObject,  0xB8C0BD9F, 0xED24, 0x455C, 0x83,0xE6, 0xD5,0x39,0x0C,0x4F,0xE8,0xC4);
+DEFINE_GUID(BHID_Filter,      0x38D08778, 0xF557, 0x4690, 0x9E,0xBF, 0xBA,0x54,0x70,0x6A,0xD8,0xF7);
+DEFINE_GUID(BHID_LinkTargetItem,   0x3981E228, 0xF559, 0x11D3, 0x8E,0x3A, 0x00,0xC0,0x4F,0x68,0x37,0xD5);
+DEFINE_GUID(BHID_PropertyStore,    0x0384E1A4, 0x1523, 0x439C, 0xA4,0xC8, 0xAB,0x91,0x10,0x52,0xF5,0x86);
+DEFINE_GUID(BHID_ThumbnailHandler, 0x7B2E650A, 0x8E20, 0x4F4A, 0xB0,0x9E, 0x65,0x97,0xAF,0xC7,0x2F,0xB0);
+DEFINE_GUID(BHID_AssociationArray, 0xBEA9EF17, 0x82F1, 0x4F60, 0x92,0x84, 0x4F,0x8D,0xB7,0x5C,0x3B,0xE9);
+DEFINE_GUID(BHID_EnumAssocHandlers,0xB8AB0B9C, 0xC2EC, 0x4F7A, 0x91,0x8D, 0x31,0x49,0x00,0xE6,0x28,0x0A);
+
 #endif /* __WINE_SHLGUID_H */
-- 
1.7.2




More information about the wine-patches mailing list