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