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