mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[0.4.9][SHELL32] Copy without FILE_ATTRIBUTE_READONLY from a CDROM CORE-18089 (#4386)
That problem in the shell was unhidden when we switched from our own to the MS-PL CDFS-driver in 0.4.8-dev-164-gec6b3ecbe4
because our own old CDFS driver erroneously never reported any CD file being read-only. Fix picked from 0.4.15-dev-4348-g513d0a6d2d
While backporting the fix, I decided to port back also some EOL-whitespace-stripping in that file.
This commit is contained in:
parent
2986b27f7d
commit
275c4442bb
1 changed files with 36 additions and 13 deletions
|
@ -549,7 +549,7 @@ static void _SetOperationTexts(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest) {
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||||||
op->szBuilderString, 0, 0, szFinalString, sizeof(szFinalString), (va_list*)args);
|
op->szBuilderString, 0, 0, szFinalString, sizeof(szFinalString), (va_list*)args);
|
||||||
|
|
||||||
|
@ -572,11 +572,11 @@ DWORD CALLBACK SHCopyProgressRoutine(
|
||||||
FILE_OPERATION *op = (FILE_OPERATION *) lpData;
|
FILE_OPERATION *op = (FILE_OPERATION *) lpData;
|
||||||
|
|
||||||
if (op->progress) {
|
if (op->progress) {
|
||||||
/*
|
/*
|
||||||
* This is called at the start of each file. To keop less state,
|
* This is called at the start of each file. To keop less state,
|
||||||
* I'm adding the file to the completed size here, and the re-subtracting
|
* I'm adding the file to the completed size here, and the re-subtracting
|
||||||
* it when drawing the progress bar.
|
* it when drawing the progress bar.
|
||||||
*/
|
*/
|
||||||
if (dwCallbackReason & CALLBACK_STREAM_SWITCH)
|
if (dwCallbackReason & CALLBACK_STREAM_SWITCH)
|
||||||
op->completedSize.QuadPart += TotalFileSize.QuadPart;
|
op->completedSize.QuadPart += TotalFileSize.QuadPart;
|
||||||
|
|
||||||
|
@ -584,7 +584,7 @@ DWORD CALLBACK SHCopyProgressRoutine(
|
||||||
TotalFileSize.QuadPart +
|
TotalFileSize.QuadPart +
|
||||||
TotalBytesTransferred.QuadPart
|
TotalBytesTransferred.QuadPart
|
||||||
, op->totalSize.QuadPart);
|
, op->totalSize.QuadPart);
|
||||||
|
|
||||||
|
|
||||||
op->bCancelled = op->progress->HasUserCancelled();
|
op->bCancelled = op->progress->HasUserCancelled();
|
||||||
}
|
}
|
||||||
|
@ -711,6 +711,21 @@ static DWORD SHNotifyMoveFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BO
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL SHIsCdRom(LPCWSTR path)
|
||||||
|
{
|
||||||
|
WCHAR tmp[] = { L"A:\\" };
|
||||||
|
|
||||||
|
if (!path || !path[0])
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (path[1] != UNICODE_NULL && path[1] != ':')
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
tmp[0] = path[0];
|
||||||
|
|
||||||
|
return GetDriveTypeW(tmp) == DRIVE_CDROM;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* SHNotifyCopyFile [internal]
|
* SHNotifyCopyFile [internal]
|
||||||
*
|
*
|
||||||
|
@ -751,6 +766,14 @@ static DWORD SHNotifyCopyFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BO
|
||||||
ret = CopyFileExW(src, dest, SHCopyProgressRoutine, op, &op->bCancelled, bFailIfExists);
|
ret = CopyFileExW(src, dest, SHCopyProgressRoutine, op, &op->bCancelled, bFailIfExists);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
// We are copying from a CD-ROM volume, which is readonly
|
||||||
|
if (SHIsCdRom(src))
|
||||||
|
{
|
||||||
|
attribs = GetFileAttributesW(dest);
|
||||||
|
attribs &= ~FILE_ATTRIBUTE_READONLY;
|
||||||
|
SetFileAttributesW(dest, attribs);
|
||||||
|
}
|
||||||
|
|
||||||
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, dest, NULL);
|
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, dest, NULL);
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1433,7 +1456,7 @@ static HRESULT copy_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *f
|
||||||
return ERROR_CANCELLED;
|
return ERROR_CANCELLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op->progress != NULL)
|
if (op->progress != NULL)
|
||||||
op->bCancelled |= op->progress->HasUserCancelled();
|
op->bCancelled |= op->progress->HasUserCancelled();
|
||||||
/* Vista return code. XP would return e.g. ERROR_FILE_NOT_FOUND, ERROR_ALREADY_EXISTS */
|
/* Vista return code. XP would return e.g. ERROR_FILE_NOT_FOUND, ERROR_ALREADY_EXISTS */
|
||||||
|
@ -1673,7 +1696,7 @@ static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flF
|
||||||
move_to_dir(op, entryToMove, fileDest);
|
move_to_dir(op, entryToMove, fileDest);
|
||||||
else
|
else
|
||||||
SHNotifyMoveFileW(op, entryToMove->szFullPath, fileDest->szFullPath, IsAttribDir(entryToMove->attributes));
|
SHNotifyMoveFileW(op, entryToMove->szFullPath, fileDest->szFullPath, IsAttribDir(entryToMove->attributes));
|
||||||
|
|
||||||
if (op->progress != NULL)
|
if (op->progress != NULL)
|
||||||
op->bCancelled |= op->progress->HasUserCancelled();
|
op->bCancelled |= op->progress->HasUserCancelled();
|
||||||
/* Should fire on progress dialog only */
|
/* Should fire on progress dialog only */
|
||||||
|
@ -1767,9 +1790,9 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
|
||||||
op.bManyItems = (flFrom.dwNumFiles > 1);
|
op.bManyItems = (flFrom.dwNumFiles > 1);
|
||||||
|
|
||||||
if (lpFileOp->wFunc != FO_RENAME && !(lpFileOp->fFlags & FOF_SILENT)) {
|
if (lpFileOp->wFunc != FO_RENAME && !(lpFileOp->fFlags & FOF_SILENT)) {
|
||||||
ret = CoCreateInstance(CLSID_ProgressDialog,
|
ret = CoCreateInstance(CLSID_ProgressDialog,
|
||||||
NULL,
|
NULL,
|
||||||
CLSCTX_INPROC_SERVER,
|
CLSCTX_INPROC_SERVER,
|
||||||
IID_PPV_ARG(IProgressDialog, &op.progress));
|
IID_PPV_ARG(IProgressDialog, &op.progress));
|
||||||
if (FAILED(ret))
|
if (FAILED(ret))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -2047,7 +2070,7 @@ EXTERN_C HRESULT WINAPI SHPathPrepareForWriteA(HWND hwnd, IUnknown *modless, LPC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The two following background operations were modified from filedefext.cpp
|
* The two following background operations were modified from filedefext.cpp
|
||||||
* They use an inordinate amount of mutable state across the string functions,
|
* They use an inordinate amount of mutable state across the string functions,
|
||||||
* so are not easy to follow and care is required when modifying.
|
* so are not easy to follow and care is required when modifying.
|
||||||
|
@ -2058,11 +2081,11 @@ _FileOpCountManager(FILE_OPERATION *op, const FILE_LIST *from)
|
||||||
{
|
{
|
||||||
DWORD ticks = GetTickCount();
|
DWORD ticks = GetTickCount();
|
||||||
FILE_ENTRY *entryToCount;
|
FILE_ENTRY *entryToCount;
|
||||||
|
|
||||||
for (UINT i = 0; i < from->dwNumFiles; i++)
|
for (UINT i = 0; i < from->dwNumFiles; i++)
|
||||||
{
|
{
|
||||||
entryToCount = &from->feFiles[i];
|
entryToCount = &from->feFiles[i];
|
||||||
|
|
||||||
WCHAR theFileName[MAX_PATH];
|
WCHAR theFileName[MAX_PATH];
|
||||||
StringCchCopyW(theFileName, MAX_PATH, entryToCount->szFullPath);
|
StringCchCopyW(theFileName, MAX_PATH, entryToCount->szFullPath);
|
||||||
_FileOpCount(op, theFileName, IsAttribDir(entryToCount->attributes), &ticks);
|
_FileOpCount(op, theFileName, IsAttribDir(entryToCount->attributes), &ticks);
|
||||||
|
|
Loading…
Reference in a new issue