From: Zebediah Figura zfigura@codeweavers.com
--- dlls/shell32/tests/shlfolder.c | 299 +++++++++++++++++++++++++++++++++ include/shlobj.h | 1 + 2 files changed, 300 insertions(+)
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 29785793355..4a8da5028a2 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -5604,6 +5604,304 @@ static void test_SHBindToFolderIDListParent(void) ok(pidl_last == NULL, "got %p\n", pidl_last); }
+static void test_copy_paste(void) +{ + CMINVOKECOMMANDINFO invoke_info = {.cbSize = sizeof(invoke_info)}; + WCHAR cwd[MAX_PATH], temp_path[MAX_PATH], path[MAX_PATH]; + ITEMIDLIST *pidl, *src_pidl, *dst_pidl, *pidls[2]; + IShellFolder *tmp_folder, *dst_folder; + IContextMenu *src_menu, *dst_menu; + const DROPFILES *dropfiles; + const WCHAR *filenameW; + IDataObject *data_obj; + const CIDA *cida; + STGMEDIUM medium; + FORMATETC format; + DWORD *effect; + HRESULT hr; + BOOL ret; + + format.dwAspect = DVASPECT_CONTENT; + format.ptd = NULL; + format.tymed = TYMED_HGLOBAL; + format.lindex = -1; + + GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd); + GetTempPathW(ARRAY_SIZE(temp_path), temp_path); + SetCurrentDirectoryW(temp_path); + + ret = CreateDirectoryW(L"testcopy_src", NULL); + ok(ret, "Got error %lu.\n", GetLastError()); + + ret = CreateDirectoryW(L"testcopy_dst", NULL); + ok(ret, "Got error %lu.\n", GetLastError()); + + hr = SHParseDisplayName(temp_path, NULL, &pidl, 0, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = SHBindToObject(NULL, pidl, NULL, &IID_IShellFolder, (void **)&tmp_folder); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ILFree(pidl); + + hr = IShellFolder_ParseDisplayName(tmp_folder, NULL, NULL, (WCHAR *)L"testcopy_src", NULL, &src_pidl, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IShellFolder_ParseDisplayName(tmp_folder, NULL, NULL, (WCHAR *)L"testcopy_dst", NULL, &dst_pidl, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IShellFolder_BindToObject(tmp_folder, dst_pidl, NULL, &IID_IShellFolder, (void **)&dst_folder); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IShellFolder_GetUIObjectOf(tmp_folder, NULL, 1, (const ITEMIDLIST **)&src_pidl, + &IID_IContextMenu, NULL, (void **)&src_menu); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = OleSetClipboard(NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + /* Cut. */ + + invoke_info.lpVerb = "cut"; + hr = IContextMenu_InvokeCommand(src_menu, &invoke_info); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + trace("%p ole %p shell %p\n", data_obj->lpVtbl->SetData, GetModuleHandleW(L"ole32"), GetModuleHandleW(L"shell32")); + + format.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ReleaseStgMedium(&medium); + format.cfFormat = CF_HDROP; + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ReleaseStgMedium(&medium); + format.cfFormat = RegisterClipboardFormatA(CFSTR_FILENAMEA); + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ReleaseStgMedium(&medium); + format.cfFormat = RegisterClipboardFormatW(CFSTR_FILENAMEW); + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ReleaseStgMedium(&medium); + + format.cfFormat = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW); + hr = IDataObject_GetData(data_obj, &format, &medium); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr == S_OK) + { + effect = GlobalLock(medium.hGlobal); + ok(*effect == DROPEFFECT_MOVE, "Got effect %#lx.\n", *effect); + GlobalUnlock(medium.hGlobal); + ReleaseStgMedium(&medium); + } + + IDataObject_Release(data_obj); + + ret = GetFileAttributesW(L"testcopy_src"); + ok(ret != INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret); + + hr = IShellFolder_GetUIObjectOf(tmp_folder, NULL, 1, (const ITEMIDLIST **)&dst_pidl, + &IID_IContextMenu, NULL, (void **)&dst_menu); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + invoke_info.lpVerb = "paste"; + hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ret = MoveFileExW(L"testcopy_dst/testcopy_src", L"testcopy_src", 0); + todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + + /* Copy. */ + + invoke_info.lpVerb = "copy"; + hr = IContextMenu_InvokeCommand(src_menu, &invoke_info); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + format.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ReleaseStgMedium(&medium); + + format.cfFormat = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW); + hr = IDataObject_GetData(data_obj, &format, &medium); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr == S_OK) + { + effect = GlobalLock(medium.hGlobal); + ok(*effect == (DROPEFFECT_COPY | DROPEFFECT_LINK), "Got effect %#lx.\n", *effect); + GlobalUnlock(medium.hGlobal); + ReleaseStgMedium(&medium); + } + + IDataObject_Release(data_obj); + + ret = GetFileAttributesW(L"testcopy_src"); + ok(ret != INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret); + + hr = IShellFolder_GetUIObjectOf(tmp_folder, NULL, 1, (const ITEMIDLIST **)&dst_pidl, + &IID_IContextMenu, NULL, (void **)&dst_menu); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + invoke_info.lpVerb = "paste"; + hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ret = GetFileAttributesW(L"testcopy_src"); + ok(ret != INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret); + + ret = RemoveDirectoryW(L"testcopy_dst/testcopy_src"); + todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + + /* Manually change the drop effect back to "cut". */ + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + format.cfFormat = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW); + medium.tymed = TYMED_HGLOBAL; + medium.hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeof(DWORD)); + effect = GlobalLock(medium.hGlobal); + *effect = DROPEFFECT_MOVE; + GlobalUnlock(medium.hGlobal); + hr = IDataObject_SetData(data_obj, &format, &medium, TRUE); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + + IDataObject_Release(data_obj); + + invoke_info.lpVerb = "paste"; + hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ret = MoveFileExW(L"testcopy_dst/testcopy_src", L"testcopy_src", 0); + todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + + /* Paste into a background menu. */ + + IContextMenu_Release(dst_menu); + + invoke_info.lpVerb = "copy"; + hr = IContextMenu_InvokeCommand(src_menu, &invoke_info); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IShellFolder_CreateViewObject(dst_folder, NULL, &IID_IContextMenu, (void **)&dst_menu); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + invoke_info.lpVerb = "paste"; + hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ret = GetFileAttributesW(L"testcopy_src"); + ok(ret != INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret); + + ret = RemoveDirectoryW(L"testcopy_dst/testcopy_src"); + todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + + /* Paste into a selection comprising multiple directories. In this case the + * first directory is used, and the second is just ignored. + * This same behaviour can of course be observed when using the UI. */ + + IContextMenu_Release(dst_menu); + + ret = CreateDirectoryW(L"testcopy_dst2", NULL); + ok(ret, "Got error %lu.\n", GetLastError()); + + hr = IShellFolder_ParseDisplayName(tmp_folder, NULL, NULL, (WCHAR *)L"testcopy_dst2", NULL, &pidls[0], NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + pidls[1] = dst_pidl; + + hr = IShellFolder_GetUIObjectOf(tmp_folder, NULL, 2, (const ITEMIDLIST **)pidls, + &IID_IContextMenu, NULL, (void **)&dst_menu); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + invoke_info.lpVerb = "paste"; + hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ret = RemoveDirectoryW(L"testcopy_dst2/testcopy_src"); + todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + ret = GetFileAttributesW(L"testcopy_dst/testcopy_src"); + ok(ret == INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret); + + /* Cut multiple files, and test the clipboard contents. */ + + invoke_info.lpVerb = "cut"; + hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + format.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + cida = GlobalLock(medium.hGlobal); + ok(cida->cidl == 2, "Got count %u.\n", cida->cidl); + GlobalUnlock(medium.hGlobal); + ReleaseStgMedium(&medium); + + format.cfFormat = CF_HDROP; + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + dropfiles = GlobalLock(medium.hGlobal); + ok(dropfiles->pFiles == sizeof(DROPFILES), "Got offset %lu.\n", dropfiles->pFiles); + ok(dropfiles->fWide == TRUE, "Got wide %u.\n", dropfiles->fWide); + filenameW = (const WCHAR *)((const char *)dropfiles + dropfiles->pFiles); + swprintf(path, ARRAY_SIZE(path), L"%stestcopy_dst2", temp_path); + ok(!wcscmp(filenameW, path), "Got path %s.\n", debugstr_w(filenameW)); + filenameW += wcslen(filenameW) + 1; + swprintf(path, ARRAY_SIZE(path), L"%stestcopy_dst", temp_path); + ok(!wcscmp(filenameW, path), "Got path %s.\n", debugstr_w(filenameW)); + filenameW += wcslen(filenameW) + 1; + ok(!filenameW[0], "Got path %s.\n", debugstr_w(filenameW)); + GlobalUnlock(medium.hGlobal); + ReleaseStgMedium(&medium); + + format.cfFormat = RegisterClipboardFormatA(CFSTR_FILENAMEA); + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ReleaseStgMedium(&medium); + + format.cfFormat = RegisterClipboardFormatW(CFSTR_FILENAMEW); + hr = IDataObject_GetData(data_obj, &format, &medium); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + filenameW = GlobalLock(medium.hGlobal); + swprintf(path, ARRAY_SIZE(path), L"%stestcopy_dst2", temp_path); + ok(!wcscmp(filenameW, path), "Got path %s.\n", debugstr_w(filenameW)); + GlobalUnlock(medium.hGlobal); + ReleaseStgMedium(&medium); + + IDataObject_Release(data_obj); + + ILFree(pidls[0]); + + /* Paste with nothing in the clipboard. */ + + hr = OleSetClipboard(NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + invoke_info.lpVerb = "paste"; + hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); + todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + + ret = RemoveDirectoryW(L"testcopy_src"); + ok(ret, "Got error %lu.\n", GetLastError()); + ret = RemoveDirectoryW(L"testcopy_dst"); + ok(ret, "Got error %lu.\n", GetLastError()); + ret = RemoveDirectoryW(L"testcopy_dst2"); + ok(ret, "Got error %lu.\n", GetLastError()); + + IContextMenu_Release(src_menu); + IContextMenu_Release(dst_menu); + ILFree(src_pidl); + ILFree(dst_pidl); + IShellFolder_Release(dst_folder); + IShellFolder_Release(tmp_folder); + SetCurrentDirectoryW(cwd); +} + START_TEST(shlfolder) { init_function_pointers(); @@ -5651,6 +5949,7 @@ START_TEST(shlfolder) test_SHLimitInputEdit(); test_SHGetSetFolderCustomSettings(); test_SHOpenFolderAndSelectItems(); + test_copy_paste();
OleUninitialize(); } diff --git a/include/shlobj.h b/include/shlobj.h index f4376e1c338..327ab981648 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -77,6 +77,7 @@ typedef int GPFIDL_FLAGS; WINSHELLAPI void WINAPI SHFree(void*); WINSHELLAPI UINT WINAPI SHAddFromPropSheetExtArray(HPSXA,LPFNADDPROPSHEETPAGE,LPARAM); WINSHELLAPI void* WINAPI SHAlloc(ULONG) __WINE_ALLOC_SIZE(1) __WINE_DEALLOC(SHFree) __WINE_MALLOC; +WINSHELLAPI HRESULT WINAPI SHBindToObject(IShellFolder *, const ITEMIDLIST *, IBindCtx *, REFIID, void **); WINSHELLAPI HRESULT WINAPI SHCoCreateInstance(LPCWSTR,const CLSID*,IUnknown*,REFIID,LPVOID*); WINSHELLAPI HPSXA WINAPI SHCreatePropSheetExtArray(HKEY,LPCWSTR,UINT); WINSHELLAPI HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY,LPCWSTR,UINT,IDataObject*);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/shell32/shlview_cmenu.c | 24 ------------------------ 1 file changed, 24 deletions(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index 4df296ec042..eef089f4812 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -1341,30 +1341,6 @@ static HRESULT DoPaste(ContextMenu *This)
IDataObject_Release(pda); } -#if 0 - HGLOBAL hMem; - - OpenClipboard(NULL); - hMem = GetClipboardData(CF_HDROP); - - if(hMem) - { - char * pDropFiles = GlobalLock(hMem); - if(pDropFiles) - { - int len, offset = sizeof(DROPFILESTRUCT); - - while( pDropFiles[offset] != 0) - { - len = strlen(pDropFiles + offset); - TRACE("%s\n", pDropFiles + offset); - offset += len+1; - } - } - GlobalUnlock(hMem); - } - CloseClipboard(); -#endif return hr; }
From: Zebediah Figura zfigura@codeweavers.com
And simplify the control flow a bit while we're at it. --- dlls/shell32/shlview_cmenu.c | 275 +++++++++++++++++------------------ 1 file changed, 134 insertions(+), 141 deletions(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index eef089f4812..e00306ee2a9 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -311,6 +311,138 @@ static void DoCopyOrCut(ContextMenu *This, HWND hwnd, BOOL cut) } }
+static HRESULT paste_pidls(ContextMenu *menu, ITEMIDLIST **pidls, unsigned int count) +{ + IShellFolder *desktop_folder; + HRESULT hr = S_OK; + + if (FAILED(hr = SHGetDesktopFolder(&desktop_folder))) + return hr; + + for (unsigned int i = 0; SUCCEEDED(hr) && i < count; i++) + { + IShellFolder *folder = NULL; + ITEMIDLIST *pidl_dir; + ITEMIDLIST *pidl_item; + + pidl_dir = ILClone(pidls[i]); + ILRemoveLastID(pidl_dir); + pidl_item = ILFindLastID(pidls[i]); + hr = IShellFolder_BindToObject(desktop_folder, pidl_dir, NULL, &IID_IShellFolder, (void **)&folder); + + if (folder) + { + ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL; + + hr = IShellFolder_QueryInterface(menu->parent, &IID_ISFHelper, (void **)&psfhlpdst); + if (SUCCEEDED(hr)) + hr = IShellFolder_QueryInterface(folder, &IID_ISFHelper, (void **)&psfhlpsrc); + + if (psfhlpdst && psfhlpsrc) + { + hr = ISFHelper_CopyItems(psfhlpdst, folder, 1, (LPCITEMIDLIST*)&pidl_item); + /* FIXME handle move + ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item); + */ + } + if (psfhlpdst) + ISFHelper_Release(psfhlpdst); + if (psfhlpsrc) + ISFHelper_Release(psfhlpsrc); + IShellFolder_Release(folder); + } + ILFree(pidl_dir); + } + + IShellFolder_Release(desktop_folder); + return hr; +} + +static HRESULT do_paste(ContextMenu *menu) +{ + IDataObject *data; + HRESULT hr; + STGMEDIUM medium; + FORMATETC formatetc; + HRESULT format_hr; + + if (FAILED(hr = OleGetClipboard(&data))) + return hr; + + InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL); + format_hr = IDataObject_GetData(data, &formatetc, &medium); + if (SUCCEEDED(format_hr)) + { + CIDA *cida = GlobalLock(medium.hGlobal); + ITEMIDLIST **pidls; + ITEMIDLIST *pidl; + + if (cida) + { + pidls = _ILCopyCidaToaPidl(&pidl, cida); + if (pidls) + { + hr = paste_pidls(menu, pidls, cida->cidl); + _ILFreeaPidl(pidls, cida->cidl); + SHFree(pidl); + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + GlobalUnlock(medium.hGlobal); + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + ReleaseStgMedium(&medium); + } + else + { + InitFormatEtc(formatetc, CF_HDROP, TYMED_HGLOBAL); + format_hr = IDataObject_GetData(data, &formatetc, &medium); + if (SUCCEEDED(format_hr)) + { + WCHAR path[MAX_PATH]; + ITEMIDLIST **pidls; + UINT count; + + count = DragQueryFileW(medium.hGlobal, -1, NULL, 0); + pidls = SHAlloc(count * sizeof(ITEMIDLIST*)); + if (pidls) + { + for (unsigned int i = 0; i < count; i++) + { + DragQueryFileW(medium.hGlobal, i, path, ARRAY_SIZE(path)); + if (!(pidls[i] = ILCreateFromPathW(path))) + { + hr = E_FAIL; + break; + } + } + if (SUCCEEDED(hr)) + hr = paste_pidls(menu, pidls, count); + _ILFreeaPidl(pidls, count); + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + ReleaseStgMedium(&medium); + } + } + + if (FAILED(format_hr)) + { + ERR("Cannot paste any clipboard formats.\n"); + hr = format_hr; + } + + IDataObject_Release(data); + return hr; +} + /************************************************************************** * Properties_AddPropSheetCallback * @@ -1205,145 +1337,6 @@ static void DoNewFolder(ContextMenu *This, IShellView *view) } }
-static HRESULT paste_pidls(ContextMenu *This, ITEMIDLIST **pidls, UINT count) -{ - IShellFolder *psfDesktop; - UINT i; - HRESULT hr = S_OK; - - /* bind to the source shellfolder */ - hr = SHGetDesktopFolder(&psfDesktop); - if (FAILED(hr)) - return hr; - - for (i = 0; SUCCEEDED(hr) && i < count; i++) { - ITEMIDLIST *pidl_dir = NULL; - ITEMIDLIST *pidl_item; - IShellFolder *psfFrom = NULL; - - pidl_dir = ILClone(pidls[i]); - ILRemoveLastID(pidl_dir); - pidl_item = ILFindLastID(pidls[i]); - hr = IShellFolder_BindToObject(psfDesktop, pidl_dir, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom); - - if (psfFrom) - { - /* get source and destination shellfolder */ - ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL; - hr = IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst); - if (SUCCEEDED(hr)) - hr = IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc); - - /* do the copy/move */ - if (psfhlpdst && psfhlpsrc) - { - hr = ISFHelper_CopyItems(psfhlpdst, psfFrom, 1, (LPCITEMIDLIST*)&pidl_item); - /* FIXME handle move - ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item); - */ - } - if(psfhlpdst) ISFHelper_Release(psfhlpdst); - if(psfhlpsrc) ISFHelper_Release(psfhlpsrc); - IShellFolder_Release(psfFrom); - } - ILFree(pidl_dir); - } - - IShellFolder_Release(psfDesktop); - return hr; -} - -static HRESULT DoPaste(ContextMenu *This) -{ - IDataObject * pda; - HRESULT hr; - - TRACE("\n"); - - hr = OleGetClipboard(&pda); - if(SUCCEEDED(hr)) - { - STGMEDIUM medium; - FORMATETC formatetc; - HRESULT format_hr; - - TRACE("pda=%p\n", pda); - - /* Set the FORMATETC structure*/ - InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL); - - /* Get the pidls from IDataObject */ - format_hr = IDataObject_GetData(pda,&formatetc,&medium); - if(SUCCEEDED(format_hr)) - { - LPITEMIDLIST * apidl; - LPITEMIDLIST pidl; - - LPIDA lpcida = GlobalLock(medium.hGlobal); - TRACE("cida=%p\n", lpcida); - if(lpcida) - { - apidl = _ILCopyCidaToaPidl(&pidl, lpcida); - if (apidl) - { - hr = paste_pidls(This, apidl, lpcida->cidl); - _ILFreeaPidl(apidl, lpcida->cidl); - SHFree(pidl); - } - else - hr = HRESULT_FROM_WIN32(GetLastError()); - GlobalUnlock(medium.hGlobal); - } - else - hr = HRESULT_FROM_WIN32(GetLastError()); - ReleaseStgMedium(&medium); - } - - if(FAILED(format_hr)) - { - InitFormatEtc(formatetc, CF_HDROP, TYMED_HGLOBAL); - format_hr = IDataObject_GetData(pda,&formatetc,&medium); - if(SUCCEEDED(format_hr)) - { - WCHAR path[MAX_PATH]; - UINT i, count; - ITEMIDLIST **pidls; - - TRACE("CF_HDROP=%p\n", medium.hGlobal); - count = DragQueryFileW(medium.hGlobal, -1, NULL, 0); - pidls = SHAlloc(count*sizeof(ITEMIDLIST*)); - if (pidls) - { - for (i = 0; i < count; i++) - { - DragQueryFileW(medium.hGlobal, i, path, ARRAY_SIZE(path)); - if ((pidls[i] = ILCreateFromPathW(path)) == NULL) - { - hr = E_FAIL; - break; - } - } - if (SUCCEEDED(hr)) - hr = paste_pidls(This, pidls, count); - _ILFreeaPidl(pidls, count); - } - else - hr = HRESULT_FROM_WIN32(GetLastError()); - ReleaseStgMedium(&medium); - } - } - - if (FAILED(format_hr)) - { - ERR("there are no supported and retrievable clipboard formats\n"); - hr = format_hr; - } - - IDataObject_Release(pda); - } - return hr; -} - static HRESULT WINAPI BackgroundMenu_InvokeCommand( IContextMenu3 *iface, LPCMINVOKECOMMANDINFO lpcmi) @@ -1380,7 +1373,7 @@ static HRESULT WINAPI BackgroundMenu_InvokeCommand( } else if (!strcmp(lpcmi->lpVerb, "paste")) { - DoPaste(This); + do_paste(This); } else { @@ -1400,7 +1393,7 @@ static HRESULT WINAPI BackgroundMenu_InvokeCommand( break;
case FCIDM_SHVIEW_INSERT: - DoPaste(This); + do_paste(This); break;
case FCIDM_SHVIEW_PROPERTIES:
From: Zebediah Figura zfigura@codeweavers.com
Make the logic in do_paste() a bit more idiomatic. --- dlls/shell32/shlview_cmenu.c | 66 +++++++++++++++++------------------- 1 file changed, 32 insertions(+), 34 deletions(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index e00306ee2a9..6951bbd4216 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -358,20 +358,24 @@ static HRESULT paste_pidls(ContextMenu *menu, ITEMIDLIST **pidls, unsigned int c return hr; }
+static HRESULT get_data_format(IDataObject *data, UINT cf, STGMEDIUM *medium) +{ + FORMATETC format; + + InitFormatEtc(format, cf, TYMED_HGLOBAL); + return IDataObject_GetData(data, &format, medium); +} + static HRESULT do_paste(ContextMenu *menu) { IDataObject *data; HRESULT hr; STGMEDIUM medium; - FORMATETC formatetc; - HRESULT format_hr;
if (FAILED(hr = OleGetClipboard(&data))) return hr;
- InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL); - format_hr = IDataObject_GetData(data, &formatetc, &medium); - if (SUCCEEDED(format_hr)) + if (SUCCEEDED(get_data_format(data, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), &medium))) { CIDA *cida = GlobalLock(medium.hGlobal); ITEMIDLIST **pidls; @@ -398,45 +402,39 @@ static HRESULT do_paste(ContextMenu *menu) } ReleaseStgMedium(&medium); } - else + else if (SUCCEEDED(get_data_format(data, CF_HDROP, &medium))) { - InitFormatEtc(formatetc, CF_HDROP, TYMED_HGLOBAL); - format_hr = IDataObject_GetData(data, &formatetc, &medium); - if (SUCCEEDED(format_hr)) - { - WCHAR path[MAX_PATH]; - ITEMIDLIST **pidls; - UINT count; + WCHAR path[MAX_PATH]; + ITEMIDLIST **pidls; + UINT count;
- count = DragQueryFileW(medium.hGlobal, -1, NULL, 0); - pidls = SHAlloc(count * sizeof(ITEMIDLIST*)); - if (pidls) + count = DragQueryFileW(medium.hGlobal, -1, NULL, 0); + pidls = SHAlloc(count * sizeof(ITEMIDLIST*)); + if (pidls) + { + for (unsigned int i = 0; i < count; i++) { - for (unsigned int i = 0; i < count; i++) + DragQueryFileW(medium.hGlobal, i, path, ARRAY_SIZE(path)); + if (!(pidls[i] = ILCreateFromPathW(path))) { - DragQueryFileW(medium.hGlobal, i, path, ARRAY_SIZE(path)); - if (!(pidls[i] = ILCreateFromPathW(path))) - { - hr = E_FAIL; - break; - } + hr = E_FAIL; + break; } - if (SUCCEEDED(hr)) - hr = paste_pidls(menu, pidls, count); - _ILFreeaPidl(pidls, count); } - else - { - hr = HRESULT_FROM_WIN32(GetLastError()); - } - ReleaseStgMedium(&medium); + if (SUCCEEDED(hr)) + hr = paste_pidls(menu, pidls, count); + _ILFreeaPidl(pidls, count); + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); } + ReleaseStgMedium(&medium); } - - if (FAILED(format_hr)) + else { ERR("Cannot paste any clipboard formats.\n"); - hr = format_hr; + hr = E_FAIL; }
IDataObject_Release(data);
From: Zebediah Figura zfigura@codeweavers.com
Don't convert the source to PIDLs just to convert it back to paths. --- dlls/shell32/shlview_cmenu.c | 64 +++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 23 deletions(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index 6951bbd4216..aa89e14346e 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -366,7 +366,7 @@ static HRESULT get_data_format(IDataObject *data, UINT cf, STGMEDIUM *medium) return IDataObject_GetData(data, &format, medium); }
-static HRESULT do_paste(ContextMenu *menu) +static HRESULT do_paste(ContextMenu *menu, HWND hwnd) { IDataObject *data; HRESULT hr; @@ -404,31 +404,49 @@ static HRESULT do_paste(ContextMenu *menu) } else if (SUCCEEDED(get_data_format(data, CF_HDROP, &medium))) { - WCHAR path[MAX_PATH]; - ITEMIDLIST **pidls; - UINT count; + const DROPFILES *dropfiles = GlobalLock(medium.hGlobal); + IPersistFolder2 *dst_persist; + SHFILEOPSTRUCTW op = {0}; + WCHAR dst_path[MAX_PATH]; + ITEMIDLIST *dst_pidl; + int ret; + + if (FAILED(hr = IShellFolder_QueryInterface(menu->parent, &IID_IPersistFolder2, (void **)&dst_persist))) + { + WARN("Failed to get IPersistFolder2, hr %#lx.\n", hr); + IDataObject_Release(data); + return hr; + }
- count = DragQueryFileW(medium.hGlobal, -1, NULL, 0); - pidls = SHAlloc(count * sizeof(ITEMIDLIST*)); - if (pidls) + hr = IPersistFolder2_GetCurFolder(dst_persist, &dst_pidl); + IPersistFolder2_Release(dst_persist); + if (FAILED(hr)) { - for (unsigned int i = 0; i < count; i++) - { - DragQueryFileW(medium.hGlobal, i, path, ARRAY_SIZE(path)); - if (!(pidls[i] = ILCreateFromPathW(path))) - { - hr = E_FAIL; - break; - } - } - if (SUCCEEDED(hr)) - hr = paste_pidls(menu, pidls, count); - _ILFreeaPidl(pidls, count); + ERR("Failed to get dst folder pidl, hr %#lx.\n", hr); + IDataObject_Release(data); + return hr; } - else + + if (!SHGetPathFromIDListW(dst_pidl, dst_path)) { - hr = HRESULT_FROM_WIN32(GetLastError()); + ERR("Failed to get path, hr %#lx.\n", hr); + ILFree(dst_pidl); + IDataObject_Release(data); + return E_FAIL; } + + op.hwnd = hwnd; + op.wFunc = FO_COPY; + op.pFrom = (const WCHAR *)((const char *)dropfiles + dropfiles->pFiles); + op.pTo = dst_path; + op.fFlags = FOF_ALLOWUNDO; + if ((ret = SHFileOperationW(&op))) + { + WARN("Failed to copy, ret %d.\n", ret); + hr = E_FAIL; + } + + GlobalUnlock(medium.hGlobal); ReleaseStgMedium(&medium); } else @@ -1371,7 +1389,7 @@ static HRESULT WINAPI BackgroundMenu_InvokeCommand( } else if (!strcmp(lpcmi->lpVerb, "paste")) { - do_paste(This); + do_paste(This, lpcmi->hwnd); } else { @@ -1391,7 +1409,7 @@ static HRESULT WINAPI BackgroundMenu_InvokeCommand( break;
case FCIDM_SHVIEW_INSERT: - do_paste(This); + do_paste(This, lpcmi->hwnd); break;
case FCIDM_SHVIEW_PROPERTIES:
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/shell32/shlview_cmenu.c | 53 ++++++++++++++-------------------- dlls/shell32/tests/shlfolder.c | 2 +- 2 files changed, 22 insertions(+), 33 deletions(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index aa89e14346e..729f543ef51 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -311,50 +311,39 @@ static void DoCopyOrCut(ContextMenu *This, HWND hwnd, BOOL cut) } }
-static HRESULT paste_pidls(ContextMenu *menu, ITEMIDLIST **pidls, unsigned int count) +static HRESULT paste_pidls(ContextMenu *menu, const ITEMIDLIST *src_parent, ITEMIDLIST **pidls, unsigned int count) { - IShellFolder *desktop_folder; + IShellFolder *src_folder; HRESULT hr = S_OK;
- if (FAILED(hr = SHGetDesktopFolder(&desktop_folder))) + if (FAILED(hr = SHBindToObject(NULL, src_parent, NULL, &IID_IShellFolder, (void **)&src_folder))) + { + ERR("Failed to get folder from source PIDL, hr %#lx.\n", hr); return hr; + }
for (unsigned int i = 0; SUCCEEDED(hr) && i < count; i++) { - IShellFolder *folder = NULL; - ITEMIDLIST *pidl_dir; - ITEMIDLIST *pidl_item; + ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL;
- pidl_dir = ILClone(pidls[i]); - ILRemoveLastID(pidl_dir); - pidl_item = ILFindLastID(pidls[i]); - hr = IShellFolder_BindToObject(desktop_folder, pidl_dir, NULL, &IID_IShellFolder, (void **)&folder); + hr = IShellFolder_QueryInterface(menu->parent, &IID_ISFHelper, (void **)&psfhlpdst); + if (SUCCEEDED(hr)) + hr = IShellFolder_QueryInterface(src_folder, &IID_ISFHelper, (void **)&psfhlpsrc);
- if (folder) + if (psfhlpdst && psfhlpsrc) { - ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL; - - hr = IShellFolder_QueryInterface(menu->parent, &IID_ISFHelper, (void **)&psfhlpdst); - if (SUCCEEDED(hr)) - hr = IShellFolder_QueryInterface(folder, &IID_ISFHelper, (void **)&psfhlpsrc); - - if (psfhlpdst && psfhlpsrc) - { - hr = ISFHelper_CopyItems(psfhlpdst, folder, 1, (LPCITEMIDLIST*)&pidl_item); - /* FIXME handle move - ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item); - */ - } - if (psfhlpdst) - ISFHelper_Release(psfhlpdst); - if (psfhlpsrc) - ISFHelper_Release(psfhlpsrc); - IShellFolder_Release(folder); + hr = ISFHelper_CopyItems(psfhlpdst, src_folder, 1, (LPCITEMIDLIST *)&pidls[i]); + /* FIXME handle move + ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item); + */ } - ILFree(pidl_dir); + if (psfhlpdst) + ISFHelper_Release(psfhlpdst); + if (psfhlpsrc) + ISFHelper_Release(psfhlpsrc); }
- IShellFolder_Release(desktop_folder); + IShellFolder_Release(src_folder); return hr; }
@@ -386,7 +375,7 @@ static HRESULT do_paste(ContextMenu *menu, HWND hwnd) pidls = _ILCopyCidaToaPidl(&pidl, cida); if (pidls) { - hr = paste_pidls(menu, pidls, cida->cidl); + hr = paste_pidls(menu, pidl, pidls, cida->cidl); _ILFreeaPidl(pidls, cida->cidl); SHFree(pidl); } diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 4a8da5028a2..39953dd9dda 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -5797,7 +5797,7 @@ static void test_copy_paste(void) ok(ret != INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret);
ret = RemoveDirectoryW(L"testcopy_dst/testcopy_src"); - todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + ok(ret, "Got error %lu.\n", GetLastError());
/* Paste into a selection comprising multiple directories. In this case the * first directory is used, and the second is just ignored.
From: Zebediah Figura zfigura@codeweavers.com
Based on a patch by Michael Müller.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34319 --- dlls/shell32/shell32.rc | 1 + dlls/shell32/shlview_cmenu.c | 67 ++++++++++++++++++++++++++++++++-- dlls/shell32/tests/shlfolder.c | 16 +++++--- 3 files changed, 74 insertions(+), 10 deletions(-)
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc index f47698524bb..970bd9a59c6 100644 --- a/dlls/shell32/shell32.rc +++ b/dlls/shell32/shell32.rc @@ -95,6 +95,7 @@ BEGIN BEGIN MENUITEM "C&ut", FCIDM_SHVIEW_CUT MENUITEM "&Copy", FCIDM_SHVIEW_COPY + MENUITEM "&Paste", FCIDM_SHVIEW_INSERT MENUITEM SEPARATOR MENUITEM "Create &Link", FCIDM_SHVIEW_CREATELINK MENUITEM "&Delete", FCIDM_SHVIEW_DELETE diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index 729f543ef51..cb7ce331897 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -157,6 +157,35 @@ static ULONG WINAPI ContextMenu_Release(IContextMenu3 *iface) return ref; }
+static BOOL can_paste(const ITEMIDLIST *dst_pidl) +{ + IDataObject *data; + FORMATETC format; + + if (!(_ILIsFolder(dst_pidl) || _ILIsDrive(dst_pidl))) + return FALSE; + + if (FAILED(OleGetClipboard(&data))) + return FALSE; + + InitFormatEtc(format, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL); + if (SUCCEEDED(IDataObject_QueryGetData(data, &format))) + { + IDataObject_Release(data); + return TRUE; + } + + InitFormatEtc(format, CF_HDROP, TYMED_HGLOBAL); + if (SUCCEEDED(IDataObject_QueryGetData(data, &format))) + { + IDataObject_Release(data); + return TRUE; + } + + IDataObject_Release(data); + return FALSE; +} + static UINT max_menu_id(HMENU hmenu, UINT offset, UINT last) { int i; @@ -252,6 +281,11 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu( EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME - FCIDM_BASE + idCmdFirst, enable); }
+ /* It's legal to paste into more than one pidl at once. In that case + * the first is used and the rest are ignored. */ + if (!can_paste(This->apidl[0])) + RemoveMenu(hmenu, FCIDM_SHVIEW_INSERT - FCIDM_BASE + idCmdFirst, MF_BYCOMMAND); + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst); } return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); @@ -311,7 +345,8 @@ static void DoCopyOrCut(ContextMenu *This, HWND hwnd, BOOL cut) } }
-static HRESULT paste_pidls(ContextMenu *menu, const ITEMIDLIST *src_parent, ITEMIDLIST **pidls, unsigned int count) +static HRESULT paste_pidls(IShellFolder *dst_folder, + const ITEMIDLIST *src_parent, ITEMIDLIST **pidls, unsigned int count) { IShellFolder *src_folder; HRESULT hr = S_OK; @@ -326,7 +361,7 @@ static HRESULT paste_pidls(ContextMenu *menu, const ITEMIDLIST *src_parent, ITEM { ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL;
- hr = IShellFolder_QueryInterface(menu->parent, &IID_ISFHelper, (void **)&psfhlpdst); + hr = IShellFolder_QueryInterface(dst_folder, &IID_ISFHelper, (void **)&psfhlpdst); if (SUCCEEDED(hr)) hr = IShellFolder_QueryInterface(src_folder, &IID_ISFHelper, (void **)&psfhlpsrc);
@@ -357,6 +392,7 @@ static HRESULT get_data_format(IDataObject *data, UINT cf, STGMEDIUM *medium)
static HRESULT do_paste(ContextMenu *menu, HWND hwnd) { + IShellFolder *dst_folder; IDataObject *data; HRESULT hr; STGMEDIUM medium; @@ -364,6 +400,21 @@ static HRESULT do_paste(ContextMenu *menu, HWND hwnd) if (FAILED(hr = OleGetClipboard(&data))) return hr;
+ if (menu->cidl) + { + if (FAILED(hr = IShellFolder_BindToObject(menu->parent, menu->apidl[0], + NULL, &IID_IShellFolder, (void **)&dst_folder))) + { + WARN("Failed to get destination folder, hr %#lx.\n", hr); + return hr; + } + } + else + { + dst_folder = menu->parent; + IShellFolder_AddRef(dst_folder); + } + if (SUCCEEDED(get_data_format(data, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), &medium))) { CIDA *cida = GlobalLock(medium.hGlobal); @@ -375,7 +426,7 @@ static HRESULT do_paste(ContextMenu *menu, HWND hwnd) pidls = _ILCopyCidaToaPidl(&pidl, cida); if (pidls) { - hr = paste_pidls(menu, pidl, pidls, cida->cidl); + hr = paste_pidls(dst_folder, pidl, pidls, cida->cidl); _ILFreeaPidl(pidls, cida->cidl); SHFree(pidl); } @@ -400,7 +451,7 @@ static HRESULT do_paste(ContextMenu *menu, HWND hwnd) ITEMIDLIST *dst_pidl; int ret;
- if (FAILED(hr = IShellFolder_QueryInterface(menu->parent, &IID_IPersistFolder2, (void **)&dst_persist))) + if (FAILED(hr = IShellFolder_QueryInterface(dst_folder, &IID_IPersistFolder2, (void **)&dst_persist))) { WARN("Failed to get IPersistFolder2, hr %#lx.\n", hr); IDataObject_Release(data); @@ -928,6 +979,9 @@ static HRESULT WINAPI ItemMenu_InvokeCommand( TRACE("Verb FCIDM_SHVIEW_CUT\n"); DoCopyOrCut(This, lpcmi->hwnd, TRUE); break; + case FCIDM_SHVIEW_INSERT: + do_paste(This, lpcmi->hwnd); + break; case FCIDM_SHVIEW_PROPERTIES: TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n"); DoOpenProperties(This, lpcmi->hwnd); @@ -946,6 +1000,8 @@ static HRESULT WINAPI ItemMenu_InvokeCommand( DoCopyOrCut(This, lpcmi->hwnd, FALSE); else if (strcmp(lpcmi->lpVerb,"cut")==0) DoCopyOrCut(This, lpcmi->hwnd, TRUE); + else if (!strcmp(lpcmi->lpVerb, "paste")) + do_paste(This, lpcmi->hwnd); else if (strcmp(lpcmi->lpVerb,"properties")==0) DoOpenProperties(This, lpcmi->hwnd); else { @@ -988,6 +1044,9 @@ static HRESULT WINAPI ItemMenu_GetCommandString(IContextMenu3 *iface, UINT_PTR c case FCIDM_SHVIEW_DELETE: cmdW = L"delete"; break; + case FCIDM_SHVIEW_INSERT: + cmdW = L"paste"; + break; case FCIDM_SHVIEW_PROPERTIES: cmdW = L"properties"; break; diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 39953dd9dda..25e75c90c83 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -5706,10 +5706,12 @@ static void test_copy_paste(void)
invoke_info.lpVerb = "paste"; hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(hr == S_OK, "Got hr %#lx.\n", hr);
ret = MoveFileExW(L"testcopy_dst/testcopy_src", L"testcopy_src", 0); todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + if (!ret && GetLastError() == ERROR_ALREADY_EXISTS) + RemoveDirectoryW(L"testcopy_dst/testcopy_src");
/* Copy. */
@@ -5747,13 +5749,13 @@ static void test_copy_paste(void)
invoke_info.lpVerb = "paste"; hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(hr == S_OK, "Got hr %#lx.\n", hr);
ret = GetFileAttributesW(L"testcopy_src"); ok(ret != INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret);
ret = RemoveDirectoryW(L"testcopy_dst/testcopy_src"); - todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + ok(ret, "Got error %lu.\n", GetLastError());
/* Manually change the drop effect back to "cut". */
@@ -5773,10 +5775,12 @@ static void test_copy_paste(void)
invoke_info.lpVerb = "paste"; hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(hr == S_OK, "Got hr %#lx.\n", hr);
ret = MoveFileExW(L"testcopy_dst/testcopy_src", L"testcopy_src", 0); todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + if (!ret && GetLastError() == ERROR_ALREADY_EXISTS) + RemoveDirectoryW(L"testcopy_dst/testcopy_src");
/* Paste into a background menu. */
@@ -5818,10 +5822,10 @@ static void test_copy_paste(void)
invoke_info.lpVerb = "paste"; hr = IContextMenu_InvokeCommand(dst_menu, &invoke_info); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(hr == S_OK, "Got hr %#lx.\n", hr);
ret = RemoveDirectoryW(L"testcopy_dst2/testcopy_src"); - todo_wine ok(ret, "Got error %lu.\n", GetLastError()); + ok(ret, "Got error %lu.\n", GetLastError()); ret = GetFileAttributesW(L"testcopy_dst/testcopy_src"); ok(ret == INVALID_FILE_ATTRIBUTES, "Got %#x.\n", ret);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143652
Your paranoid android.
=== w1064v1809 (32 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w1064_tsign (32 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w10pro64 (32 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w10pro64_en_AE_u8 (32 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w11pro64 (32 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w1064v1809 (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w1064_2qxl (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w1064_adm (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w1064_tsign (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w10pro64 (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w10pro64_ar (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w10pro64_ja (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w10pro64_zh_CN (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== w11pro64_amd (64 bit report) ===
shell32: shlfolder.c:5891: Test failed: Got hr 0.
=== debian11b (64 bit WoW report) ===
wldap32: parse.c:417: Test failed: ldap_connect failed 0x51 parse.c:427: Test failed: ldap_set_optionW should fail: 0 parse.c:431: Test failed: ldap_search_sA failed 0x51 parse.c:432: Test failed: expected res != NULL parse.c:602: Test failed: ldap_connect should succeed, got 0x51 parse.c:604: Test failed: ldap_start_tls_sA should fail, got 0x51 parse.c:205: Test failed: ldap_addA should succeed, got 0xffffffff parse.c:207: Test failed: ldap_addA should succeed, got 0xffffffff parse.c:209: Test failed: ldap_addA should succeed, got 0xffffffff parse.c:216: Test failed: ldap_add_sA should fail, got 0x51 parse.c:218: Test failed: ldap_add_sA should fail, got 0x51 parse.c:220: Test failed: ldap_add_sA should fail, got 0x51 parse.c:227: Test failed: ldap_add_extA should succeed, got 0x51 parse.c:229: Test failed: ldap_add_extA should succeed, got 0x51 parse.c:233: Test failed: ldap_add_extA should succeed, got 0x51 parse.c:240: Test failed: ldap_add_ext_sA should fail, got 0x51 parse.c:242: Test failed: ldap_add_ext_sA should fail, got 0x51 parse.c:244: Test failed: ldap_add_ext_sA should fail, got 0x51 parse.c:259: Test failed: ldap_modifyA should succeed, got 0xffffffff parse.c:261: Test failed: ldap_modifyA should succeed, got 0xffffffff parse.c:263: Test failed: ldap_modifyA should succeed, got 0xffffffff parse.c:270: Test failed: ldap_modify_sA should fail, got 0x51 parse.c:272: Test failed: ldap_modify_sA should fail, got 0x51 parse.c:274: Test failed: ldap_modify_sA should fail, got 0x51 parse.c:281: Test failed: ldap_modify_extA should succeed, got 0x51 parse.c:283: Test failed: ldap_modify_extA should succeed, got 0x51 parse.c:287: Test failed: ldap_modify_extA should succeed, got 0x51 parse.c:294: Test failed: ldap_modify_ext_sA should fail, got 0x51 parse.c:296: Test failed: ldap_modify_ext_sA should fail, got 0x51 parse.c:298: Test failed: ldap_modify_ext_sA should fail, got 0x51 parse.c:311: Test failed: ldap_compareA should succeed, got 0xffffffff parse.c:315: Test failed: ldap_compareA should succeed, got 0xffffffff parse.c:317: Test failed: ldap_compareA should succeed, got 0xffffffff parse.c:324: Test failed: ldap_compare_sA should fail, got 0x51 parse.c:328: Test failed: ldap_compare_sA should fail, got 0x51 parse.c:330: Test failed: ldap_compare_sA should fail, got 0x51 parse.c:337: Test failed: ldap_compare_extA should succeed, got 0x51 parse.c:341: Test failed: ldap_compare_extA should succeed, got 0x51 parse.c:343: Test failed: ldap_compare_extA should succeed, got 0x51 parse.c:345: Test failed: ldap_compare_extA should succeed, got 0x51 parse.c:349: Test failed: ldap_compare_extA should succeed, got 0x51 parse.c:356: Test failed: ldap_compare_ext_sA should fail, got 0x51 parse.c:360: Test failed: ldap_compare_ext_sA should fail, got 0x51 parse.c:362: Test failed: ldap_compare_ext_sA should fail, got 0x51 parse.c:364: Test failed: ldap_compare_ext_sA should fail, got 0x51 parse.c:54: Test failed: ldap_create_sort_controlA failed 0x51
Report validation errors: wldap32:parse crashed (c0000005)