shell32: Implement SHCreateItemInKnownFolder.

Signed-off-by: Jactry Zeng <jzeng@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jactry Zeng 2017-08-14 21:34:03 +08:00 committed by Alexandre Julliard
parent 6048090275
commit 5451c7d04f
4 changed files with 148 additions and 0 deletions

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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);")
/*****************************************************************************