Jactry Zeng : shell32: Implement SHCreateItemInKnownFolder.

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


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

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

shell32: Implement SHCreateItemInKnownFolder.

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       |  35 +++++++++++++
 dlls/shell32/tests/shlfolder.c | 111 +++++++++++++++++++++++++++++++++++++++++
 include/shobjidl.idl           |   1 +
 4 files changed, 148 insertions(+)

diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec
index e8bbf37..dd4accb 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 SHCreateItemInKnownFolder(ptr long wstr ptr ptr)
 @ stdcall SHCreateItemFromRelativeName(ptr wstr ptr ptr ptr)
 @ stub SHCreateProcessAsUserW
 @ stdcall SHCreateShellItem(ptr ptr ptr ptr)
diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c
index cc607ec..8fc767e 100644
--- a/dlls/shell32/shellitem.c
+++ b/dlls/shell32/shellitem.c
@@ -711,6 +711,41 @@ HRESULT WINAPI SHCreateItemFromIDList(PCIDLIST_ABSOLUTE pidl, REFIID riid, void
     return ret;
 }
 
+HRESULT WINAPI SHCreateItemInKnownFolder(REFKNOWNFOLDERID rfid, DWORD flags,
+                                         PCWSTR filename, REFIID riid, void **ppv)
+{
+    HRESULT hr;
+    IShellItem *parent = NULL;
+    LPITEMIDLIST pidl = NULL;
+
+    TRACE("(%p, %x, %s, %s, %p)\n", rfid, flags, wine_dbgstr_w(filename),
+          debugstr_guid(riid), ppv);
+
+    if(!rfid || !ppv)
+        return E_INVALIDARG;
+
+    *ppv = NULL;
+    hr = SHGetKnownFolderIDList(rfid, flags, NULL, &pidl);
+    if(hr != S_OK)
+        return hr;
+
+    hr = SHCreateItemFromIDList(pidl, &IID_IShellItem, (void**)&parent);
+    if(hr != S_OK)
+    {
+        ILFree(pidl);
+        return hr;
+    }
+
+    if(filename)
+        hr = SHCreateItemFromRelativeName(parent, filename, NULL, riid, ppv);
+    else
+        hr = IShellItem_QueryInterface(parent, riid, ppv);
+
+    ILFree(pidl);
+    IShellItem_Release(parent);
+    return hr;
+}
+
 HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj,
     DATAOBJ_GET_ITEM_FLAGS dwFlags, REFIID riid, void **ppv)
 {
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 1b9956e..739e685 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -59,6 +59,7 @@ 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 *pSHCreateItemInKnownFolder)(REFKNOWNFOLDERID,DWORD,PCWSTR,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**);
@@ -118,6 +119,7 @@ static void init_function_pointers(void)
     MAKEFUNC(SHCreateItemFromIDList);
     MAKEFUNC(SHCreateItemFromParsingName);
     MAKEFUNC(SHCreateItemFromRelativeName);
+    MAKEFUNC(SHCreateItemInKnownFolder);
     MAKEFUNC(SHCreateShellItem);
     MAKEFUNC(SHCreateShellItemArray);
     MAKEFUNC(SHCreateShellItemArrayFromIDLists);
@@ -2603,6 +2605,115 @@ static void test_SHCreateShellItem(void)
     else
         win_skip("No SHCreateItemFromRelativeName or SHGetKnownFolderPath\n");
 
+    /* SHCreateItemInKnownFolder */
+    if(pSHCreateItemInKnownFolder && pSHGetKnownFolderPath)
+    {
+        WCHAR *desktop_path;
+        WCHAR testfile_path[MAX_PATH] = {0};
+        HANDLE file;
+        WCHAR *displayname = NULL;
+        int order;
+        LPITEMIDLIST pidl_desktop_testfile = NULL;
+
+        shellitem = (void*)0xdeadbeef;
+        ret = pSHCreateItemInKnownFolder(&FOLDERID_Desktop, 0, NULL, &IID_IShellItem,
+                                         (void**)&shellitem);
+        ok(ret == S_OK, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret);
+        ok(shellitem != NULL, "shellitem was %p.\n", shellitem);
+        if(SUCCEEDED(ret))
+        {
+            shellitem2 = (void*)0xdeadbeef;
+            ret = pSHCreateShellItem(NULL, NULL, pidl_desktop, &shellitem2);
+            ok(SUCCEEDED(ret), "SHCreateShellItem returned %x\n", ret);
+            if(SUCCEEDED(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);
+            }
+            IShellItem_Release(shellitem);
+        }
+
+        /* Test with a non-existent file */
+        shellitem = (void*)0xdeadbeef;
+        ret = pSHCreateItemInKnownFolder(&FOLDERID_Desktop, 0, testfileW, &IID_IShellItem,
+                                         (void**)&shellitem);
+        ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+           "Expected 0x%08x but SHCreateItemInKnownFolder return: 0x%08x.\n",
+           HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), ret);
+        ok(shellitem == NULL, "shellitem was %p.\n", shellitem);
+
+        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 = pSHCreateItemInKnownFolder(&FOLDERID_Desktop, 0, testfileW, &IID_IShellItem,
+                                         (void**)&shellitem);
+        ok(ret == S_OK, "SHCreateItemInKnownFolder 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 = pSHCreateItemInKnownFolder(&FOLDERID_Desktop, 0, testfileW, &IID_IShellItem,
+                                             (void**)&shellitem2);
+            ok(ret == S_OK, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret);
+            ok(shellitem2 != NULL, "shellitem was %p.\n", shellitem);
+            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(SUCCEEDED(ret), "ParseDisplayName returned %x.\n", ret);
+            ret = pSHCreateItemFromIDList(pidl_desktop_testfile, &IID_IShellItem, (void**)&shellitem2);
+            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);
+            pILFree(pidl_desktop_testfile);
+            IShellItem_Release(shellitem2);
+
+            IShellItem_Release(shellitem);
+        }
+
+        shellitem = (void*)0xdeadbeef;
+        ret = pSHCreateItemInKnownFolder(&FOLDERID_Documents, 0, NULL, &IID_IShellItem,
+                                         (void**)&shellitem);
+        ok(ret == S_OK, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret);
+        ok(shellitem != NULL, "shellitem was %p.\n", shellitem);
+        if(SUCCEEDED(ret))
+        {
+            shellitem2 = (void*)0xdeadbeef;
+            ret = pSHCreateItemInKnownFolder(&FOLDERID_Documents, 0, NULL, &IID_IShellItem,
+                                             (void**)&shellitem2);
+            ok(ret == S_OK, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret);
+            ok(shellitem2 != NULL, "shellitem was %p.\n", shellitem);
+            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);
+
+            IShellItem_Release(shellitem);
+        }
+        DeleteFileW(testfile_path);
+        CoTaskMemFree(desktop_path);
+    }
+    else
+        win_skip("No SHCreateItemInKnownFolder or SHGetKnownFolderPath\n");
+
     DeleteFileA(".\\testfile");
     pILFree(pidl_abstestfile);
     pILFree(pidl_testfile);
diff --git a/include/shobjidl.idl b/include/shobjidl.idl
index 83fcbce..f1b85a8 100644
--- a/include/shobjidl.idl
+++ b/include/shobjidl.idl
@@ -608,6 +608,7 @@ cpp_quote("HRESULT WINAPI SHGetItemFromObject(IUnknown *punk, REFIID riid, void
 cpp_quote("HRESULT WINAPI SHCreateShellItemArray(PCIDLIST_ABSOLUTE pidlParent, IShellFolder* psf, UINT cidl, PCUITEMID_CHILD_ARRAY ppidl, IShellItemArray **ppsiItemArray);")
 cpp_quote("HRESULT WINAPI SHCreateShellItemArrayFromShellItem(IShellItem *psi, REFIID riid, void **ppv);")
 cpp_quote("HRESULT WINAPI SHCreateShellItemArrayFromIDLists(UINT cidl, PCIDLIST_ABSOLUTE_ARRAY pidl_array, IShellItemArray **psia);")
+cpp_quote("HRESULT WINAPI SHCreateItemInKnownFolder(REFKNOWNFOLDERID rfid, DWORD flags, PCWSTR filename, REFIID riid, void **ppv);")
 cpp_quote("HRESULT WINAPI SHCreateShellItemArrayFromDataObject(IDataObject *pdo, REFIID riid, void **ppv);")
 
 /*****************************************************************************




More information about the wine-cvs mailing list