Author: gadamopoulos Date: Sat Aug 19 11:19:06 2017 New Revision: 75623
URL: http://svn.reactos.org/svn/reactos?rev=75623&view=rev Log: [SHELL32] -CFSDropTarget: Simplyfy the code path that handles the CFSTR_SHELLIDLIST format. Don't use FOF_MULTIDESTFILES to keep things simple. CORE-13176
Modified: trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.cpp trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.h
Modified: trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/droptarge... ============================================================================== --- trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.cpp [iso-8859-1] Sat Aug 19 11:19:06 2017 @@ -30,30 +30,21 @@ * Builds a list of paths like the one used in SHFileOperation from a table of * PIDLs relative to the given base folder */ -WCHAR * -BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls, BOOL bRelative) -{ - WCHAR *pwszPathsList; - WCHAR *pwszListPos; - int iPathLen, i; - - iPathLen = wcslen(wszBasePath); - pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1); - pwszListPos = pwszPathsList; - - for (i = 0; i < cidl; i++) - { - if (!_ILIsFolder(pidls[i]) && !_ILIsValue(pidls[i])) +static WCHAR* BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls) +{ + WCHAR *pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1); + WCHAR *pwszListPos = pwszPathsList; + + for (int i = 0; i < cidl; i++) + { + FileStructW* pDataW = _ILGetFileStructW(pidls[i]); + if (!pDataW) + { + ERR("Got garbage pidl\n"); continue; - - wcscpy(pwszListPos, wszBasePath); - pwszListPos += iPathLen; - - if (_ILIsFolder(pidls[i]) && bRelative) - continue; - - /* FIXME: abort if path too long */ - _ILSimpleGetTextW(pidls[i], pwszListPos, MAX_PATH - iPathLen); + } + + PathCombineW(pwszListPos, wszBasePath, pDataW->wszName); pwszListPos += wcslen(pwszListPos) + 1; } *pwszListPos = 0; @@ -68,119 +59,42 @@ HRESULT WINAPI CFSDropTarget::CopyItems(IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl, BOOL bCopy) { - CComPtr<IPersistFolder2> ppf2 = NULL; - WCHAR szSrcPath[MAX_PATH]; - WCHAR szTargetPath[MAX_PATH]; - SHFILEOPSTRUCTW op; - LPITEMIDLIST pidl; - LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName; - int res, length; + LPWSTR pszSrcList; HRESULT hr; + WCHAR wszTargetPath[MAX_PATH + 1]; + + wcscpy(wszTargetPath, sPathTarget); + //Double NULL terminate. + wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
- hr = pSFFrom->QueryInterface (IID_PPV_ARG(IPersistFolder2, &ppf2)); - if (SUCCEEDED(hr)) - { - hr = ppf2->GetCurFolder(&pidl); - if (FAILED(hr)) - { - return hr; - } - - hr = SHGetPathFromIDListW(pidl, szSrcPath); - SHFree(pidl); - - if (FAILED(hr)) - return hr; - - pszSrc = PathAddBackslashW(szSrcPath); - - wcscpy(szTargetPath, sPathTarget); - pszTarget = PathAddBackslashW(szTargetPath); - - pszSrcList = BuildPathsList(szSrcPath, cidl, apidl, FALSE); - pszTargetList = BuildPathsList(szTargetPath, cidl, apidl, TRUE); - - if (!pszSrcList || !pszTargetList) - { - if (pszSrcList) - HeapFree(GetProcessHeap(), 0, pszSrcList); - - if (pszTargetList) - HeapFree(GetProcessHeap(), 0, pszTargetList); - - SHFree(pidl); - 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; - op.fFlags = 0; - } - else - { - op.pTo = pszTargetList; - op.fFlags = FOF_MULTIDESTFILES; - } - op.hwnd = GetActiveWindow(); - op.wFunc = bCopy ? FO_COPY : FO_MOVE; - op.fFlags |= FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR; - - res = SHFileOperationW(&op); - - if (res == DE_SAMEFILE) - { - length = wcslen(szTargetPath); - - pszFileName = wcsrchr(pszSrcList, '\'); - pszFileName++; - - if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length)) - { - wcscat(szTargetPath, L" "); - } - - wcscat(szTargetPath, pszFileName); - op.pTo = szTargetPath; - - res = SHFileOperationW(&op); - } - - HeapFree(GetProcessHeap(), 0, pszSrcList); - HeapFree(GetProcessHeap(), 0, pszTargetList); - - if (res) - return E_FAIL; - else - return S_OK; - } - return E_FAIL; + STRRET strretFrom; + hr = pSFFrom->GetDisplayNameOf(NULL, SHGDN_FORPARSING, &strretFrom); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + pszSrcList = BuildPathsList(strretFrom.pOleStr, cidl, apidl); + ERR("Source file (just the first) = %s, target path = %s\n", debugstr_w(strretFrom.pOleStr), debugstr_w(sPathTarget)); + CoTaskMemFree(strretFrom.pOleStr); + if (!pszSrcList) + return E_OUTOFMEMORY; + + SHFILEOPSTRUCTW op = {0}; + op.pFrom = pszSrcList; + op.pTo = wszTargetPath; + op.hwnd = GetActiveWindow(); + op.wFunc = bCopy ? FO_COPY : FO_MOVE; + op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR; + + int res = SHFileOperationW(&op); + + HeapFree(GetProcessHeap(), 0, pszSrcList); + + if (res) + return E_FAIL; + else + return S_OK; }
CFSDropTarget::CFSDropTarget(): @@ -554,8 +468,7 @@ return E_FAIL; } pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles); - TRACE("Source file (just the first) = %s\n", debugstr_w(pszSrcList)); - TRACE("Target path = %s\n", debugstr_w(wszTargetPath)); + ERR("Source file (just the first) = %s, target path = %s\n", debugstr_w(pszSrcList), debugstr_w(wszTargetPath));
SHFILEOPSTRUCTW op; ZeroMemory(&op, sizeof(op));
Modified: trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/droptarge... ============================================================================== --- trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/droptargets/CFSDropTarget.h [iso-8859-1] Sat Aug 19 11:19:06 2017 @@ -22,8 +22,6 @@
#ifndef _CFSDROPTARGET_H_ #define _CFSDROPTARGET_H_ - -WCHAR *BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls, BOOL bRelative);
class CFSDropTarget : public CComObjectRootEx<CComMultiThreadModelNoCS>,