- Implement ISFHelper_fnCopyItems for desktop shellfolder
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 17 Sep 2009 22:57:50 +0000 (22:57 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 17 Sep 2009 22:57:50 +0000 (22:57 +0000)
- 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
reactos/dll/win32/shell32/shv_def_cmenu.c

index ce2ed6b..6e44ac2 100644 (file)
@@ -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 =
index 109918a..ea146a9 100644 (file)
@@ -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;
 }