From 6fbfb7cd1dfc1904c0748670db3c468d748438bc Mon Sep 17 00:00:00 2001 From: David Hedberg Date: Mon, 16 Aug 2010 09:17:30 +0200 Subject: [PATCH] shell32: Partial implementation of IShellItem::BindToHandler. --- 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 dbf9b4d0170..32840201288 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 6c0b6f20004..e731f073fcf 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 190d55e43de..3af4398209c 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 */