* 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);
UINT cfShellIDList; /* clipboardformat for IDropTarget */
BOOL fAcceptFmt; /* flag for pending Drop */
-} IGenericSFImpl;
+} IGenericSFImpl, *LPIGenericSFImpl;
static const IUnknownVtbl unkvt;
static const IShellFolder2Vtbl sfvt;
static const IDropTargetVtbl dtvt;
static const ISFHelperVtbl shvt;
-static inline IGenericSFImpl *impl_from_IShellFolder2( IShellFolder2 *iface )
+static LPIGenericSFImpl __inline impl_from_IShellFolder2( IShellFolder2 *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblShellFolder));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblShellFolder));
}
-static inline IGenericSFImpl *impl_from_IPersistFolder3( IPersistFolder3 *iface )
+static LPIGenericSFImpl __inline impl_from_IPersistFolder3( IPersistFolder3 *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblPersistFolder3));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblPersistFolder3));
}
-static inline IGenericSFImpl *impl_from_IDropTarget( IDropTarget *iface )
+static LPIGenericSFImpl __inline impl_from_IDropTarget( IDropTarget *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblDropTarget));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblDropTarget));
}
-static inline IGenericSFImpl *impl_from_ISFHelper( ISFHelper *iface )
+static LPIGenericSFImpl __inline impl_from_ISFHelper( ISFHelper *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblSFHelper));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblSFHelper));
}
/* build the full pathname to the element */
lstrcpynW(szPath, This->sPathTarget, MAX_PATH - 1);
PathAddBackslashW(szPath);
- len = lstrlenW(szPath);
+ len = wcslen(szPath);
lstrcpynW(szPath + len, szElement, MAX_PATH - len);
/* get the pidl */
*ppvOut = NULL;
if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
- pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
- This->pidlRoot, apidl, cidl);
- hr = S_OK;
- } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
+ hr = CDefFolderMenu_Create2(This->pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)iface, NULL, 0, NULL, (IContextMenu**)&pObj);
+ } else if (IsEqualIID (riid, &IID_IDataObject)){
+ if (cidl >= 1) {
pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner,
This->pidlRoot, apidl, cidl);
hr = S_OK;
+ }
+ else
+ {
+ pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, (LPCITEMIDLIST*)&This->pidlRoot, 1);
+ hr = S_OK;
+ }
} else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
pidl = ILCombine (This->pidlRoot, apidl[0]);
pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
{
lstrcpynW(pszPath, This->sPathTarget, MAX_PATH);
PathAddBackslashW(pszPath);
- len = lstrlenW(pszPath);
+ len = wcslen(pszPath);
}
_ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len);
if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
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);
}
}
TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest));
+ if (!memcmp(szSrc, szDest, (wcslen(szDest)+1) * sizeof(WCHAR)))
+ {
+ /* src and destination is the same */
+ HRESULT hr = S_OK;
+ if (pPidlOut)
+ hr = _ILCreateFromPathW(szDest, pPidlOut);
+
+ return hr;
+ }
+
if (MoveFileW (szSrc, szDest)) {
HRESULT hr = S_OK;
IEnumIDList *penum;
HRESULT hr;
WCHAR wszText[MAX_PATH];
- const WCHAR wszNewFolder[] = {'N','e','w',' ','F','o','l','d','e','r',0 };
+ WCHAR wszNewFolder[25];
const WCHAR wszFormat[] = {'%','s',' ','%','d',0 };
+ LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, sizeof(wszNewFolder)/sizeof(WCHAR));
+
TRACE ("(%p)(%p %u)\n", This, pwszName, uLen);
if (uLen < sizeof(wszNewFolder)/sizeof(WCHAR) + 3)
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;
sizeof (wszTempText));
LoadStringW (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, wszCaption,
sizeof (wszCaption));
- sprintfW (wszText, wszTempText, wszNewDir);
+ swprintf (wszText, wszTempText, wszNewDir);
MessageBoxW (hwnd, wszText, wszCaption, MB_OK | MB_ICONEXCLAMATION);
}
* Builds a list of paths like the one used in SHFileOperation from a table of
* PIDLs relative to the given base folder
*/
-static WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
+WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
{
WCHAR *wszPathsList;
WCHAR *wszListPos;
int iPathLen;
int i;
- iPathLen = lstrlenW(wszBasePath);
+ iPathLen = wcslen(wszBasePath);
wszPathsList = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)*cidl+1);
wszListPos = wszPathsList;
lstrcpynW(wszListPos, wszBasePath, MAX_PATH);
/* FIXME: abort if path too long */
_ILSimpleGetTextW(pidls[i], wszListPos+iPathLen, MAX_PATH-iPathLen);
- wszListPos += lstrlenW(wszListPos)+1;
+ wszListPos += wcslen(wszListPos)+1;
}
*wszListPos=0;
return wszPathsList;
SHFree(pidl);
}
- wszCurrentPath += lstrlenW(wszCurrentPath)+1;
+ wszCurrentPath += wcslen(wszCurrentPath)+1;
}
HeapFree(GetProcessHeap(), 0, wszPathsList);
return ret;
ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
LPCITEMIDLIST * apidl)
{
- UINT i;
IPersistFolder2 *ppf2 = NULL;
- char szSrcPath[MAX_PATH],
- szDstPath[MAX_PATH];
+ WCHAR szSrcPath[MAX_PATH];
+ WCHAR szTargetPath[MAX_PATH];
+ SHFILEOPSTRUCTW op;
+ LPITEMIDLIST pidl;
+ LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName;
+ int res, length;
+ HRESULT hr;
+ STRRET strRet;
IGenericSFImpl *This = impl_from_ISFHelper(iface);
TRACE ("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
- IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2,
- (LPVOID *) & ppf2);
- if (ppf2) {
- LPITEMIDLIST pidl;
+ hr = IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2, (LPVOID *) & ppf2);
+ if (SUCCEEDED(hr))
+ {
+ 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);
- if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
- for (i = 0; i < cidl; i++) {
- SHGetPathFromIDListA (pidl, szSrcPath);
- PathAddBackslashA (szSrcPath);
- _ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath),
- MAX_PATH);
-
- if (!WideCharToMultiByte(CP_ACP, 0, This->sPathTarget, -1, szDstPath, MAX_PATH, NULL, NULL))
- szDstPath[0] = '\0';
- PathAddBackslashA (szDstPath);
- _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath),
- MAX_PATH);
- MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath);
- }
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);
}
- IPersistFolder2_Release (ppf2);
+
+ HeapFree(GetProcessHeap(), 0, pszSrcList);
+ HeapFree(GetProcessHeap(), 0, pszTargetList);
+
+ if (res)
+ return E_FAIL;
+ else
+ return S_OK;
}
- return S_OK;
+ return E_FAIL;
}
static const ISFHelperVtbl shvt =
/* set my path */
if (SHGetPathFromIDListW (pidl, wszTemp)) {
- int len = strlenW(wszTemp);
+ int len = wcslen(wszTemp);
This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
if (!This->sPathTarget)
return E_OUTOFMEMORY;
if (ppfti->csidl != -1) {
if (SHGetSpecialFolderPathW (0, wszTemp, ppfti->csidl,
ppfti->csidl & CSIDL_FLAG_CREATE)) {
- int len = strlenW(wszTemp);
+ int len = wcslen(wszTemp);
This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
if (!This->sPathTarget)
return E_OUTOFMEMORY;
memcpy(This->sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR));
}
} else if (ppfti->szTargetParsingName[0]) {
- int len = strlenW(ppfti->szTargetParsingName);
+ int len = wcslen(ppfti->szTargetParsingName);
This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
if (!This->sPathTarget)
return E_OUTOFMEMORY;
(len + 1) * sizeof(WCHAR));
} else if (ppfti->pidlTargetFolder) {
if (SHGetPathFromIDListW(ppfti->pidlTargetFolder, wszTemp)) {
- int len = strlenW(wszTemp);
+ int len = wcslen(wszTemp);
This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
if (!This->sPathTarget)
return E_OUTOFMEMORY;