- Fix a bug which broke build
[reactos.git] / reactos / dll / win32 / shell32 / shfldr_desktop.c
index bbe8e68..c051553 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "wingdi.h"
-#include "winuser.h"
-
-#include "ole2.h"
-#include "shlguid.h"
-
-#include "enumidlist.h"
-#include "pidl.h"
-#include "undocshell.h"
-#include "shell32_main.h"
-#include "shresdef.h"
-#include "shlwapi.h"
-#include "shellfolder.h"
-#include "wine/debug.h"
-#include "debughlp.h"
-#include "shfldr.h"
+#include <precomp.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL (shell);
 
@@ -71,7 +40,7 @@ typedef struct {
 
     UINT cfShellIDList;        /* clipboardformat for IDropTarget */
     BOOL fAcceptFmt;        /* flag for pending Drop */
-} IGenericSFImpl;
+} IGenericSFImpl, *LPIGenericSFImpl;
 
 WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls);
 int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
@@ -128,7 +97,7 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
     return E_NOINTERFACE;
 }
 
-static inline IGenericSFImpl *impl_from_ISFHelper( ISFHelper *iface )
+static LPIGenericSFImpl __inline impl_from_ISFHelper( ISFHelper *iface )
 {
     return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblSFHelper));
 }
@@ -177,7 +146,7 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface,
     {
         szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
         TRACE ("-- element: %s\n", debugstr_w (szElement));
-        SHCLSIDFromStringW (szElement + 2, &clsid);
+        CLSIDFromString (szElement + 2, &clsid);
         pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
     }
     else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
@@ -344,7 +313,7 @@ static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags)
                     DWORD size;
                     LONG r;
 
-                    size = sizeof (iid);
+                    size = sizeof (iid) / sizeof (iid[0]);
                     r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
                     if (ERROR_SUCCESS == r)
                     {
@@ -680,7 +649,7 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
     {
         if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
             (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
-            strcpyW(pszPath, This->sPathTarget);
+            wcscpy(pszPath, This->sPathTarget);
         else
             HCR_GetClassNameW(&CLSID_ShellDesktop, pszPath, MAX_PATH);
     }
@@ -718,9 +687,9 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
                     WCHAR szRegPath[100];
                     LONG r;
 
-                    lstrcpyW (szRegPath, clsidW);
+                    wcscpy (szRegPath, clsidW);
                     SHELL32_GUIDToStringW (clsid, &szRegPath[6]);
-                    lstrcatW (szRegPath, shellfolderW);
+                    wcscat (szRegPath, shellfolderW);
                     r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
                                     wantsForParsingW, NULL, NULL, NULL);
                     if (r == ERROR_SUCCESS)
@@ -764,7 +733,7 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
             {
                 lstrcpynW(pszPath, This->sPathTarget, MAX_PATH - 1);
                 PathAddBackslashW(pszPath);
-                cLen = lstrlenW(pszPath);
+                cLen = wcslen(pszPath);
             }
 
             _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
@@ -859,11 +828,21 @@ static HRESULT WINAPI ISF_Desktop_fnSetNameOf (IShellFolder2 * iface,
     if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) {
         WCHAR *ext = PathFindExtensionW(szSrc);
         if(*ext != '\0') {
-            INT len = strlenW(szDest);
+            INT len = wcslen(szDest);
             lstrcpynW(szDest + len, ext, MAX_PATH - len);
         }
     }
 
+    if (!memcmp(szSrc, szDest, (wcslen(szDest)+1) * sizeof(WCHAR)))
+    {
+        /* src and destination is the same */
+        hr = S_OK;
+        if (pPidlOut)
+            hr = _ILCreateFromPathW(szDest, pPidlOut);
+
+        return hr;
+    }
+
     TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest));
     if (MoveFileW (szSrc, szDest))
     {
@@ -1014,7 +993,7 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
     ISF_Desktop_fnMapColumnToSCID
 };
 
-static inline IGenericSFImpl *impl_from_IPersistFolder2( IPersistFolder2 *iface )
+static LPIGenericSFImpl __inline impl_from_IPersistFolder2( IPersistFolder2 *iface )
 {
     return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpPF2));
 }
@@ -1162,7 +1141,7 @@ next:
          dwFetched) {
             _ILSimpleGetTextW (pidl, wszText, MAX_PATH);
             if (0 == lstrcmpiW (wszText, pwszName)) {
-                snprintfW (pwszName, uLen, wszFormat, wszNewFolder, i++);
+                _snwprintf (pwszName, uLen, wszFormat, wszNewFolder, i++);
                 if (i > 99) {
                     hr = E_FAIL;
                     break;
@@ -1296,7 +1275,7 @@ ISF_Desktop_ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST
             SHFree(pidl);
         }
 
-        wszCurrentPath += lstrlenW(wszCurrentPath)+1;
+        wszCurrentPath += wcslen(wszCurrentPath)+1;
     }
     HeapFree(GetProcessHeap(), 0, wszPathsList);
     return ret;
@@ -1305,10 +1284,128 @@ 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, pszFileName;
+    int res, length;
+    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);
+
+        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;
 }
 
 static const ISFHelperVtbl vt_FSFldr_ISFHelper =
@@ -1355,8 +1452,8 @@ HRESULT WINAPI ISF_Desktop_Constructor (
         sf->lpPF2 = &vt_FSFldr_PersistFolder2;
         sf->lpvtblSFHelper = &vt_FSFldr_ISFHelper;
         sf->pidlRoot = _ILCreateDesktop();    /* my qualified pidl */
-        sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
-        lstrcpyW( sf->sPathTarget, szMyPath );
+        sf->sPathTarget = SHAlloc( (wcslen(szMyPath) + 1)*sizeof(WCHAR) );
+        wcscpy( sf->sPathTarget, szMyPath );
 
         if (InterlockedCompareExchangePointer((void *)&cached_sf, sf, NULL) != NULL)
         {