[PATCH 1/5] shell32: Implement SHGetItemFromObject. (resend)

David Hedberg david.hedberg at gmail.com
Sun Jul 25 12:08:14 CDT 2010


Rebased against latest git.

---
 dlls/shell32/shell32.spec      |    1 +
 dlls/shell32/shellitem.c       |   15 ++++++++
 dlls/shell32/tests/shlfolder.c |   78 ++++++++++++++++++++++++++++++++++++++++
 include/shobjidl.idl           |    1 +
 4 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec
index c11f20e..ed61f0b 100644
--- a/dlls/shell32/shell32.spec
+++ b/dlls/shell32/shell32.spec
@@ -362,6 +362,7 @@
 @ stdcall SHGetIDListFromObject(ptr ptr)
 @ stdcall SHGetInstanceExplorer(long)
 @ stdcall SHGetItemFromDataObject(ptr long ptr ptr)
+@ stdcall SHGetItemFromObject(ptr ptr ptr)
 @ stdcall SHGetLocalizedName(wstr ptr long ptr)
 @ stdcall SHGetMalloc(ptr)
 @ stdcall SHGetNameFromIDList(ptr long ptr)
diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c
index 6abc02c..27b2d53 100644
--- a/dlls/shell32/shellitem.c
+++ b/dlls/shell32/shellitem.c
@@ -535,3 +535,18 @@ HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj,
 
     return ret;
 }
+
+HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void **ppv)
+{
+    LPITEMIDLIST pidl;
+    HRESULT ret;
+
+    ret = SHGetIDListFromObject(punk, &pidl);
+    if(SUCCEEDED(ret))
+    {
+        ret = SHCreateItemFromIDList(pidl, riid, ppv);
+        ILFree(pidl);
+    }
+
+    return ret;
+}
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index cf7150e..4a81b95 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -64,6 +64,7 @@ static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPathAW)(LPCVOID);
 static HRESULT (WINAPI *pSHGetNameFromIDList)(PCIDLIST_ABSOLUTE,SIGDN,PWSTR*);
 static HRESULT (WINAPI *pSHGetItemFromDataObject)(IDataObject*,DATAOBJ_GET_ITEM_FLAGS,REFIID,void**);
 static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*);
+static HRESULT (WINAPI *pSHGetItemFromObject)(IUnknown*,REFIID,void**);
 
 static void init_function_pointers(void)
 {
@@ -88,6 +89,7 @@ static void init_function_pointers(void)
     MAKEFUNC(SHGetNameFromIDList);
     MAKEFUNC(SHGetItemFromDataObject);
     MAKEFUNC(SHGetIDListFromObject);
+    MAKEFUNC(SHGetItemFromObject);
 #undef MAKEFUNC
 
 #define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord)))
@@ -2627,6 +2629,81 @@ static void test_SHGetIDListFromObject(void)
     pILFree(pidl_desktop);
 }
 
+static void test_SHGetItemFromObject(void)
+{
+    IUnknownImpl *punkimpl;
+    IShellFolder *psfdesktop;
+    LPITEMIDLIST pidl;
+    IShellItem *psi;
+    IUnknown *punk;
+    HRESULT hres;
+    struct if_count ifaces[] =
+        { {&IID_IPersistIDList, 0},
+          {&IID_IPersistFolder2, 0},
+          {&IID_IDataObject, 0},
+          {&IID_IParentAndItem, 0},
+          {&IID_IFolderView, 0},
+          {NULL, 0} };
+
+    if(!pSHGetItemFromObject)
+    {
+        skip("No SHGetItemFromObject.\n");
+        return;
+    }
+
+    SHGetDesktopFolder(&psfdesktop);
+
+    if(0)
+    {
+        /* Crashes with Windows 7 */
+        hres = pSHGetItemFromObject((IUnknown*)psfdesktop, &IID_IUnknown, (void**)NULL);
+        hres = pSHGetItemFromObject(NULL, &IID_IUnknown, (void**)NULL);
+        hres = pSHGetItemFromObject((IUnknown*)psfdesktop, NULL, (void**)&punk);
+    }
+
+    hres = pSHGetItemFromObject(NULL, &IID_IUnknown, (void**)&punk);
+    ok(hres == E_NOINTERFACE, "Got 0x%08x\n", hres);
+
+    punkimpl = HeapAlloc(GetProcessHeap(), 0, sizeof(IUnknownImpl));
+    punkimpl->lpVtbl = &vt_IUnknown;
+    punkimpl->ifaces = ifaces;
+    punkimpl->unknown = 0;
+
+    /* The same as SHGetIDListFromObject */
+    hres = pSHGetIDListFromObject((IUnknown*)punkimpl, &pidl);
+    ok(hres == E_NOINTERFACE, "Got %x\n", hres);
+    ok(ifaces[0].count, "interface not requested.\n");
+    ok(ifaces[1].count, "interface not requested.\n");
+    ok(ifaces[2].count, "interface not requested.\n");
+    todo_wine
+        ok(ifaces[3].count || broken(!ifaces[3].count /*vista*/),
+           "interface not requested.\n");
+    ok(ifaces[4].count || broken(!ifaces[4].count /*vista*/),
+       "interface not requested.\n");
+
+    ok(!punkimpl->unknown, "Got %d unknown.\n", punkimpl->unknown);
+    HeapFree(GetProcessHeap(), 0, punkimpl);
+
+    /* Test IShellItem */
+    hres = pSHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
+    ok(hres == S_OK, "Got 0x%08x\n", hres);
+    if(SUCCEEDED(hres))
+    {
+        IShellItem *psi2;
+        hres = pSHGetItemFromObject((IUnknown*)psi, &IID_IShellItem, (void**)&psi2);
+        ok(hres == S_OK, "Got 0x%08x\n", hres);
+        if(SUCCEEDED(hres))
+        {
+            todo_wine
+                ok(psi == psi2, "Different instances (%p != %p).\n", psi, psi2);
+            IShellItem_Release(psi2);
+        }
+        IShellItem_Release(psi);
+    }
+
+    IShellFolder_Release(psfdesktop);
+}
+
 static void test_SHParseDisplayName(void)
 {
     LPITEMIDLIST pidl1, pidl2;
@@ -3135,6 +3212,7 @@ START_TEST(shlfolder)
     test_SHGetNameFromIDList();
     test_SHGetItemFromDataObject();
     test_SHGetIDListFromObject();
+    test_SHGetItemFromObject();
 
     OleUninitialize();
 }
diff --git a/include/shobjidl.idl b/include/shobjidl.idl
index 43a2672..8a90f64 100644
--- a/include/shobjidl.idl
+++ b/include/shobjidl.idl
@@ -509,6 +509,7 @@ cpp_quote("HRESULT WINAPI SHCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *
 cpp_quote("HRESULT WINAPI SHCreateItemFromIDList(PCIDLIST_ABSOLUTE pidl, REFIID riid, void **ppv);")
 cpp_quote("HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj, DATAOBJ_GET_ITEM_FLAGS dwFlags, REFIID riid, void **ppv);")
 cpp_quote("HRESULT WINAPI SHGetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl);")
+cpp_quote("HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void **ppv);")
 
 /*****************************************************************************
  * IShellItemFilter interface
-- 
1.7.1.1




More information about the wine-patches mailing list