Jactry Zeng : shell32: Implement SHCreateItemFromRelativeName.

Alexandre Julliard julliard at winehq.org
Wed Aug 16 09:06:25 CDT 2017


Module: wine
Branch: master
Commit: 604809027525a946d589e7271ae93800e5043612
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=604809027525a946d589e7271ae93800e5043612

Author: Jactry Zeng <jzeng at codeweavers.com>
Date:   Mon Aug 14 21:33:56 2017 +0800

shell32: Implement SHCreateItemFromRelativeName.

Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/shell32/shell32.spec      |  1 +
 dlls/shell32/shellitem.c       | 49 ++++++++++++++++++++++++
 dlls/shell32/tests/shlfolder.c | 84 ++++++++++++++++++++++++++++++++++++++++++
 include/shobjidl.idl           |  1 +
 4 files changed, 135 insertions(+)

diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec
index 780fa50..e8bbf37 100644
--- a/dlls/shell32/shell32.spec
+++ b/dlls/shell32/shell32.spec
@@ -344,6 +344,7 @@
 @ stdcall SHCreateDirectoryExW(long wstr ptr)
 @ stdcall SHCreateItemFromIDList(ptr ptr ptr)
 @ stdcall SHCreateItemFromParsingName(wstr ptr ptr ptr)
+@ stdcall SHCreateItemFromRelativeName(ptr wstr ptr ptr ptr)
 @ stub SHCreateProcessAsUserW
 @ stdcall SHCreateShellItem(ptr ptr ptr ptr)
 @ stdcall SHCreateShellItemArray(ptr ptr long ptr ptr)
diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c
index 1e19f7c..cc607ec 100644
--- a/dlls/shell32/shellitem.c
+++ b/dlls/shell32/shellitem.c
@@ -637,6 +637,55 @@ HRESULT WINAPI SHCreateItemFromParsingName(PCWSTR pszPath,
     return ret;
 }
 
+HRESULT WINAPI SHCreateItemFromRelativeName(IShellItem *parent, PCWSTR name, IBindCtx *pbc,
+                                            REFIID riid, void **ppv)
+{
+    LPITEMIDLIST pidl_folder = NULL, pidl = NULL;
+    IShellFolder *desktop = NULL, *folder = NULL;
+    HRESULT hr;
+
+    TRACE("(%p, %s, %p, %s, %p)\n", parent, wine_dbgstr_w(name), pbc, debugstr_guid(riid), ppv);
+
+    if(!ppv)
+        return E_INVALIDARG;
+    *ppv = NULL;
+    if(!name)
+        return E_INVALIDARG;
+
+    hr = SHGetIDListFromObject((IUnknown*)parent, &pidl_folder);
+    if(hr != S_OK)
+        return hr;
+
+    hr = SHGetDesktopFolder(&desktop);
+    if(hr != S_OK)
+        goto cleanup;
+
+    if(!_ILIsDesktop(pidl_folder))
+    {
+        hr = IShellFolder_BindToObject(desktop, pidl_folder, NULL, &IID_IShellFolder,
+                                       (void**)&folder);
+        if(hr != S_OK)
+            goto cleanup;
+    }
+
+    hr = IShellFolder_ParseDisplayName(folder ? folder : desktop, NULL, pbc, (LPWSTR)name,
+                                       NULL, &pidl, NULL);
+    if(hr != S_OK)
+        goto cleanup;
+    hr = SHCreateItemFromIDList(pidl, riid, ppv);
+
+cleanup:
+    if(pidl_folder)
+        ILFree(pidl_folder);
+    if(pidl)
+        ILFree(pidl);
+    if(desktop)
+        IShellFolder_Release(desktop);
+    if(folder)
+        IShellFolder_Release(folder);
+    return hr;
+}
+
 HRESULT WINAPI SHCreateItemFromIDList(PCIDLIST_ABSOLUTE pidl, REFIID riid, void **ppv)
 {
     IPersistIDList *persist;
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 9e7127d..1b9956e 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -58,6 +58,7 @@ static void (WINAPI *pILFree)(LPITEMIDLIST);
 static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
 static HRESULT (WINAPI *pSHCreateItemFromIDList)(PCIDLIST_ABSOLUTE pidl, REFIID riid, void **ppv);
 static HRESULT (WINAPI *pSHCreateItemFromParsingName)(PCWSTR,IBindCtx*,REFIID,void**);
+static HRESULT (WINAPI *pSHCreateItemFromRelativeName)(IShellItem*,PCWSTR,IBindCtx*,REFIID,void**);
 static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
 static HRESULT (WINAPI *pSHCreateShellItemArray)(LPCITEMIDLIST,IShellFolder*,UINT,LPCITEMIDLIST*,IShellItemArray**);
 static HRESULT (WINAPI *pSHCreateShellItemArrayFromIDLists)(UINT, PCIDLIST_ABSOLUTE*, IShellItemArray**);
@@ -66,6 +67,7 @@ static HRESULT (WINAPI *pSHCreateShellItemArrayFromShellItem)(IShellItem*, REFII
 static LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
 static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
 static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPathAW)(LPCVOID);
+static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID,DWORD,HANDLE,PWSTR*);
 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*);
@@ -115,6 +117,7 @@ static void init_function_pointers(void)
     MAKEFUNC(SHBindToParent);
     MAKEFUNC(SHCreateItemFromIDList);
     MAKEFUNC(SHCreateItemFromParsingName);
+    MAKEFUNC(SHCreateItemFromRelativeName);
     MAKEFUNC(SHCreateShellItem);
     MAKEFUNC(SHCreateShellItemArray);
     MAKEFUNC(SHCreateShellItemArrayFromIDLists);
@@ -127,6 +130,7 @@ static void init_function_pointers(void)
     MAKEFUNC(SHGetSpecialFolderPathW);
     MAKEFUNC(SHGetSpecialFolderLocation);
     MAKEFUNC(SHParseDisplayName);
+    MAKEFUNC(SHGetKnownFolderPath);
     MAKEFUNC(SHGetNameFromIDList);
     MAKEFUNC(SHGetItemFromDataObject);
     MAKEFUNC(SHGetIDListFromObject);
@@ -2519,6 +2523,86 @@ static void test_SHCreateShellItem(void)
     else
         win_skip("No SHCreateItemFromIDList\n");
 
+    /* SHCreateItemFromRelativeName */
+    if(pSHCreateItemFromRelativeName && pSHGetKnownFolderPath)
+    {
+        IShellItem *shellitem_desktop = NULL;
+        WCHAR *desktop_path, *displayname;
+        WCHAR testfile_path[MAX_PATH] = {0};
+        HANDLE file;
+        LPITEMIDLIST pidl_desktop_testfile = NULL;
+        int order;
+
+        ret = pSHCreateShellItem(NULL, NULL, pidl_desktop, &shellitem_desktop);
+        ok(ret == S_OK, "SHCreateShellItem failed: 0x%08x.\n", ret);
+
+        shellitem = (void*)0xdeadbeef;
+        ret = pSHCreateItemFromRelativeName(shellitem_desktop, NULL, NULL, &IID_IShellItem,
+                                            (void**)&shellitem);
+        ok(ret == E_INVALIDARG, "Expected 0x%08x but SHCreateItemFromRelativeName return: 0x%08x.\n",
+           E_INVALIDARG, ret);
+        ok(shellitem == NULL, "shellitem was %p.\n", shellitem);
+
+        /* Test with a non-existent file */
+        shellitem = (void*)0xdeadbeef;
+        ret = pSHCreateItemFromRelativeName(shellitem_desktop, testfileW, NULL, &IID_IShellItem,
+                                            (void**)&shellitem);
+        ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+           "Expected 0x%08x but SHCreateItemFromRelativeName return: 0x%08x.\n",
+           HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), ret);
+        ok(shellitem == NULL, "shellitem was %p.\n", shellitem);
+
+        /* Create a file for testing in desktop folder */
+        pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &desktop_path);
+        lstrcatW(testfile_path, desktop_path);
+        myPathAddBackslashW(testfile_path);
+        lstrcatW(testfile_path, testfileW);
+        file = CreateFileW(testfile_path, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
+        ok(file != INVALID_HANDLE_VALUE, "CreateFileW failed! Last error: 0x%08x.\n", GetLastError());
+        CloseHandle(file);
+
+        shellitem = (void*)0xdeadbeef;
+        ret = pSHCreateItemFromRelativeName(shellitem_desktop, testfileW, NULL, &IID_IShellItem,
+                                            (void**)&shellitem);
+        ok(ret == S_OK, "SHCreateItemFromRelativeName failed: 0x%08x.\n", ret);
+        ok(shellitem != NULL, "shellitem was %p.\n", shellitem);
+        if(SUCCEEDED(ret))
+        {
+            ret = IShellItem_GetDisplayName(shellitem, 0, &displayname);
+            ok(ret == S_OK, "IShellItem_GetDisplayName failed: 0x%08x.\n", ret);
+            ok(!lstrcmpW(displayname, testfileW), "got wrong display name: %s.\n", wine_dbgstr_w(displayname));
+            CoTaskMemFree(displayname);
+
+            shellitem2 = (void*)0xdeadbeef;
+            ret = pSHCreateItemFromRelativeName(shellitem_desktop, testfileW, NULL, &IID_IShellItem,
+                                                (void**)&shellitem2);
+            ok(ret == S_OK, "SHCreateItemFromRelativeName failed: 0x%08x.\n", ret);
+            ret = IShellItem_Compare(shellitem, shellitem2, 0, &order);
+            ok(ret == S_OK, "IShellItem_Compare failed: 0x%08x.\n", ret);
+            ok(!order, "order got wrong value: %d.\n", order);
+            IShellItem_Release(shellitem2);
+
+            shellitem2 = (void*)0xdeadbeef;
+            ret = IShellFolder_ParseDisplayName(desktopfolder, NULL, NULL, testfileW, NULL,
+                                                &pidl_desktop_testfile, NULL);
+            ok(ret == S_OK, "ParseDisplayName failed 0x%08x.\n", ret);
+            ret = pSHCreateItemFromIDList(pidl_desktop_testfile, &IID_IShellItem, (void**)&shellitem2);
+            ret = IShellItem_Compare(shellitem, shellitem2, 0, &order);
+            ok(ret == S_OK, "IShellItem_Compare fail: 0x%08x.\n", ret);
+            ok(!order, "order got wrong value: %d.\n", order);
+            pILFree(pidl_desktop_testfile);
+            IShellItem_Release(shellitem2);
+
+            IShellItem_Release(shellitem);
+        }
+
+        DeleteFileW(testfile_path);
+        CoTaskMemFree(desktop_path);
+        IShellItem_Release(shellitem_desktop);
+    }
+    else
+        win_skip("No SHCreateItemFromRelativeName or SHGetKnownFolderPath\n");
+
     DeleteFileA(".\\testfile");
     pILFree(pidl_abstestfile);
     pILFree(pidl_testfile);
diff --git a/include/shobjidl.idl b/include/shobjidl.idl
index 571fbab..83fcbce 100644
--- a/include/shobjidl.idl
+++ b/include/shobjidl.idl
@@ -601,6 +601,7 @@ cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(DATAOBJ_GET_ITEM_FLAGS)")
 cpp_quote("HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWSTR *ppszName);")
 cpp_quote("HRESULT WINAPI SHCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);")
 cpp_quote("HRESULT WINAPI SHCreateItemFromIDList(PCIDLIST_ABSOLUTE pidl, REFIID riid, void **ppv);")
+cpp_quote("HRESULT WINAPI SHCreateItemFromRelativeName(IShellItem *parent, PCWSTR name, IBindCtx *pbc, 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);")




More information about the wine-cvs mailing list