mirror of
https://github.com/reactos/reactos.git
synced 2024-07-14 00:25:05 +00:00
[SHELL32] -CFSDropTarget: Simplyfy the code path that handles the CFSTR_SHELLIDLIST format. Don't use FOF_MULTIDESTFILES to keep things simple. CORE-13176
svn path=/trunk/; revision=75623
This commit is contained in:
parent
3c6b222f15
commit
9fee94b692
|
@ -30,30 +30,21 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell);
|
||||||
* Builds a list of paths like the one used in SHFileOperation from a table of
|
* Builds a list of paths like the one used in SHFileOperation from a table of
|
||||||
* PIDLs relative to the given base folder
|
* PIDLs relative to the given base folder
|
||||||
*/
|
*/
|
||||||
WCHAR *
|
static WCHAR* BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
|
||||||
BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls, BOOL bRelative)
|
|
||||||
{
|
{
|
||||||
WCHAR *pwszPathsList;
|
WCHAR *pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1);
|
||||||
WCHAR *pwszListPos;
|
WCHAR *pwszListPos = pwszPathsList;
|
||||||
int iPathLen, i;
|
|
||||||
|
|
||||||
iPathLen = wcslen(wszBasePath);
|
for (int i = 0; i < cidl; i++)
|
||||||
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]))
|
FileStructW* pDataW = _ILGetFileStructW(pidls[i]);
|
||||||
|
if (!pDataW)
|
||||||
|
{
|
||||||
|
ERR("Got garbage pidl\n");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
wcscpy(pwszListPos, wszBasePath);
|
PathCombineW(pwszListPos, wszBasePath, pDataW->wszName);
|
||||||
pwszListPos += iPathLen;
|
|
||||||
|
|
||||||
if (_ILIsFolder(pidls[i]) && bRelative)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* FIXME: abort if path too long */
|
|
||||||
_ILSimpleGetTextW(pidls[i], pwszListPos, MAX_PATH - iPathLen);
|
|
||||||
pwszListPos += wcslen(pwszListPos) + 1;
|
pwszListPos += wcslen(pwszListPos) + 1;
|
||||||
}
|
}
|
||||||
*pwszListPos = 0;
|
*pwszListPos = 0;
|
||||||
|
@ -68,119 +59,42 @@ BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls, BOOL bRelati
|
||||||
HRESULT WINAPI CFSDropTarget::CopyItems(IShellFolder * pSFFrom, UINT cidl,
|
HRESULT WINAPI CFSDropTarget::CopyItems(IShellFolder * pSFFrom, UINT cidl,
|
||||||
LPCITEMIDLIST * apidl, BOOL bCopy)
|
LPCITEMIDLIST * apidl, BOOL bCopy)
|
||||||
{
|
{
|
||||||
CComPtr<IPersistFolder2> ppf2 = NULL;
|
LPWSTR pszSrcList;
|
||||||
WCHAR szSrcPath[MAX_PATH];
|
|
||||||
WCHAR szTargetPath[MAX_PATH];
|
|
||||||
SHFILEOPSTRUCTW op;
|
|
||||||
LPITEMIDLIST pidl;
|
|
||||||
LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName;
|
|
||||||
int res, length;
|
|
||||||
HRESULT hr;
|
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);
|
TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
|
||||||
|
|
||||||
hr = pSFFrom->QueryInterface (IID_PPV_ARG(IPersistFolder2, &ppf2));
|
STRRET strretFrom;
|
||||||
if (SUCCEEDED(hr))
|
hr = pSFFrom->GetDisplayNameOf(NULL, SHGDN_FORPARSING, &strretFrom);
|
||||||
{
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
hr = ppf2->GetCurFolder(&pidl);
|
return hr;
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = SHGetPathFromIDListW(pidl, szSrcPath);
|
pszSrcList = BuildPathsList(strretFrom.pOleStr, cidl, apidl);
|
||||||
SHFree(pidl);
|
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;
|
||||||
|
|
||||||
if (FAILED(hr))
|
SHFILEOPSTRUCTW op = {0};
|
||||||
return hr;
|
op.pFrom = pszSrcList;
|
||||||
|
op.pTo = wszTargetPath;
|
||||||
|
op.hwnd = GetActiveWindow();
|
||||||
|
op.wFunc = bCopy ? FO_COPY : FO_MOVE;
|
||||||
|
op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
|
||||||
|
|
||||||
pszSrc = PathAddBackslashW(szSrcPath);
|
int res = SHFileOperationW(&op);
|
||||||
|
|
||||||
wcscpy(szTargetPath, sPathTarget);
|
HeapFree(GetProcessHeap(), 0, pszSrcList);
|
||||||
pszTarget = PathAddBackslashW(szTargetPath);
|
|
||||||
|
|
||||||
pszSrcList = BuildPathsList(szSrcPath, cidl, apidl, FALSE);
|
if (res)
|
||||||
pszTargetList = BuildPathsList(szTargetPath, cidl, apidl, TRUE);
|
return E_FAIL;
|
||||||
|
else
|
||||||
if (!pszSrcList || !pszTargetList)
|
return S_OK;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CFSDropTarget::CFSDropTarget():
|
CFSDropTarget::CFSDropTarget():
|
||||||
|
@ -554,8 +468,7 @@ HRESULT WINAPI CFSDropTarget::_DoDrop(IDataObject *pDataObject,
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
|
pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
|
||||||
TRACE("Source file (just the first) = %s\n", debugstr_w(pszSrcList));
|
ERR("Source file (just the first) = %s, target path = %s\n", debugstr_w(pszSrcList), debugstr_w(wszTargetPath));
|
||||||
TRACE("Target path = %s\n", debugstr_w(wszTargetPath));
|
|
||||||
|
|
||||||
SHFILEOPSTRUCTW op;
|
SHFILEOPSTRUCTW op;
|
||||||
ZeroMemory(&op, sizeof(op));
|
ZeroMemory(&op, sizeof(op));
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
#ifndef _CFSDROPTARGET_H_
|
#ifndef _CFSDROPTARGET_H_
|
||||||
#define _CFSDROPTARGET_H_
|
#define _CFSDROPTARGET_H_
|
||||||
|
|
||||||
WCHAR *BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls, BOOL bRelative);
|
|
||||||
|
|
||||||
class CFSDropTarget :
|
class CFSDropTarget :
|
||||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||||
public IDropTarget
|
public IDropTarget
|
||||||
|
|
Loading…
Reference in a new issue