[SHELL32] -CFSDropTarget: Simplyfy the code path that handles the CFSTR_SHELLIDLIST...
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Sat, 19 Aug 2017 11:19:06 +0000 (11:19 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Sat, 19 Aug 2017 11:19:06 +0000 (11:19 +0000)
svn path=/trunk/; revision=75623

reactos/dll/win32/shell32/droptargets/CFSDropTarget.cpp
reactos/dll/win32/shell32/droptargets/CFSDropTarget.h

index e9e93e2..287138e 100644 (file)
@@ -30,30 +30,21 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell);
  * 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)
+static WCHAR* BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
 {
-    WCHAR *pwszPathsList;
-    WCHAR *pwszListPos;
-    int iPathLen, i;
+    WCHAR *pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1);
+    WCHAR *pwszListPos = pwszPathsList;
 
-    iPathLen = wcslen(wszBasePath);
-    pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1);
-    pwszListPos = pwszPathsList;
-
-    for (i = 0; i < cidl; i++)
+    for (int i = 0; i < cidl; i++)
     {
-        if (!_ILIsFolder(pidls[i]) && !_ILIsValue(pidls[i]))
-            continue;
-
-        wcscpy(pwszListPos, wszBasePath);
-        pwszListPos += iPathLen;
-
-        if (_ILIsFolder(pidls[i]) && bRelative)
+        FileStructW* pDataW = _ILGetFileStructW(pidls[i]);
+        if (!pDataW)
+        {
+            ERR("Got garbage pidl\n");
             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 @@ BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls, BOOL bRelati
 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];
 
-    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;
+    wcscpy(wszTargetPath, sPathTarget);
+    //Double NULL terminate.
+    wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
 
-        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);
+    TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
 
-            pszFileName = wcsrchr(pszSrcList, '\\');
-            pszFileName++;
+    STRRET strretFrom;
+    hr = pSFFrom->GetDisplayNameOf(NULL, SHGDN_FORPARSING, &strretFrom);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
 
-            if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length))
-            {
-                wcscat(szTargetPath, L" ");
-            }
+    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;
 
-            wcscat(szTargetPath, pszFileName);
-            op.pTo = szTargetPath;
+    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;
 
-            res = SHFileOperationW(&op);
-        }
+    int res = SHFileOperationW(&op);
 
-        HeapFree(GetProcessHeap(), 0, pszSrcList);
-        HeapFree(GetProcessHeap(), 0, pszTargetList);
+    HeapFree(GetProcessHeap(), 0, pszSrcList);
 
-        if (res)
-            return E_FAIL;
-        else
-            return S_OK;
-    }
-    return E_FAIL;
+    if (res)
+        return E_FAIL;
+    else
+        return S_OK;
 }
 
 CFSDropTarget::CFSDropTarget():
@@ -554,8 +468,7 @@ HRESULT WINAPI CFSDropTarget::_DoDrop(IDataObject *pDataObject,
                 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));
index 5e58204..e6c063d 100644 (file)
@@ -23,8 +23,6 @@
 #ifndef _CFSDROPTARGET_H_
 #define _CFSDROPTARGET_H_
 
-WCHAR *BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls, BOOL bRelative);
-
 class CFSDropTarget :
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IDropTarget