From 6049b93ebc2b99a59e966355776a052e27becde9 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 17 Sep 2009 22:57:50 +0000 Subject: [PATCH] - Implement ISFHelper_fnCopyItems for desktop shellfolder - Check if the target folder desktop - Fixes copying of files to desktop See issue #4845 for more details. svn path=/trunk/; revision=43068 --- reactos/dll/win32/shell32/shfldr_desktop.c | 100 ++++++++++++++++++++- reactos/dll/win32/shell32/shv_def_cmenu.c | 15 +++- 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/reactos/dll/win32/shell32/shfldr_desktop.c b/reactos/dll/win32/shell32/shfldr_desktop.c index ce2ed6bae29..6e44ac2b32f 100644 --- a/reactos/dll/win32/shell32/shfldr_desktop.c +++ b/reactos/dll/win32/shell32/shfldr_desktop.c @@ -1284,10 +1284,108 @@ ISF_Desktop_ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST static HRESULT WINAPI ISF_Desktop_ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl) { + IPersistFolder2 *ppf2 = NULL; + WCHAR szSrcPath[MAX_PATH]; + WCHAR szTargetPath[MAX_PATH]; + SHFILEOPSTRUCTW op; + LPITEMIDLIST pidl; + LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList; + int res; + STRRET strRet; IGenericSFImpl *This = impl_from_ISFHelper(iface); TRACE ("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl); - return E_NOTIMPL; + + IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2, (LPVOID *) & ppf2); + if (ppf2) + { + if (FAILED(IPersistFolder2_GetCurFolder (ppf2, &pidl))) + { + IPersistFolder2_Release(ppf2); + return E_FAIL; + } + IPersistFolder2_Release(ppf2); + + if (FAILED(IShellFolder_GetDisplayNameOf(pSFFrom, pidl, SHGDN_FORPARSING, &strRet))) + { + SHFree (pidl); + return E_FAIL; + } + + if (FAILED(StrRetToBufW(&strRet, pidl, szSrcPath, MAX_PATH))) + { + SHFree (pidl); + return E_FAIL; + } + SHFree (pidl); + + pszSrc = PathAddBackslashW (szSrcPath); + + wcscpy(szTargetPath, This->sPathTarget); + pszTarget = PathAddBackslashW (szTargetPath); + + pszSrcList = build_paths_list(szSrcPath, cidl, apidl); + pszTargetList = build_paths_list(szTargetPath, cidl, apidl); + + if (!pszSrcList || !pszTargetList) + { + if (pszSrcList) + HeapFree(GetProcessHeap(), 0, pszSrcList); + + if (pszTargetList) + HeapFree(GetProcessHeap(), 0, pszTargetList); + + SHFree (pidl); + IPersistFolder2_Release (ppf2); + return E_OUTOFMEMORY; + } + ZeroMemory(&op, sizeof(op)); + if (!pszSrcList[0]) + { + /* remove trailing backslash */ + pszSrc--; + pszSrc[0] = L'\0'; + op.pFrom = szSrcPath; + } + else + { + op.pFrom = pszSrcList; + } + + if (!pszTargetList[0]) + { + /* remove trailing backslash */ + if (pszTarget - szTargetPath > 3) + { + pszTarget--; + pszTarget[0] = L'\0'; + } + else + { + pszTarget[1] = L'\0'; + } + + op.pTo = szTargetPath; + } + else + { + op.pTo = pszTargetList; + } + op.hwnd = GetActiveWindow(); + op.wFunc = FO_COPY; + op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR; + + res = SHFileOperationW(&op); + + HeapFree(GetProcessHeap(), 0, pszSrc); + HeapFree(GetProcessHeap(), 0, pszTarget); + + if (res) + return E_FAIL; + else + return S_OK; + } + return E_FAIL; } static const ISFHelperVtbl vt_FSFldr_ISFHelper = diff --git a/reactos/dll/win32/shell32/shv_def_cmenu.c b/reactos/dll/win32/shell32/shv_def_cmenu.c index 109918a91fe..ea146a9cbe9 100644 --- a/reactos/dll/win32/shell32/shv_def_cmenu.c +++ b/reactos/dll/win32/shell32/shv_def_cmenu.c @@ -1083,9 +1083,18 @@ DoPaste( IPersistFolder2_Release(ppf2); if (SUCCEEDED(hr)) { - hr = IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfTarget); + if (_ILIsDesktop(pidl)) + { + /* use desktop shellfolder */ + psfTarget = psfDesktop; + } + else + { + /* retrieve target desktop folder */ + hr = IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfTarget); + } + TRACE("psfTarget %x %p, Desktop %u\n", hr, psfTarget, _ILIsDesktop(pidl)); ILFree(pidl); - TRACE("psfTarget %p\n", psfTarget); } } } @@ -1146,7 +1155,7 @@ DoPaste( _ILFreeaPidl(apidl, lpcida->cidl); ReleaseStgMedium(&medium); IDataObject_Release(pda); -ERR("CP result %x\n",hr); + TRACE("CP result %x\n",hr); return S_OK; } -- 2.17.1