1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00

Bug 1677: Do not fail transfer if file selected for transfer, but excluded by file mask, is deleted during operation

https://winscp.net/tracker/1677

Source commit: 88d21caaae8bbd140229a313bd8aadb159706750
This commit is contained in:
Martin Prikryl
2018-09-17 13:28:24 +00:00
parent 708196e8d9
commit 93fc1a2807
6 changed files with 55 additions and 23 deletions

View File

@@ -1421,6 +1421,12 @@ bool __fastcall FileSearchRec(const UnicodeString FileName, TSearchRec & Rec)
return Result;
}
//---------------------------------------------------------------------------
void CopySearchRec(const TSearchRec & Source, TSearchRec & Dest)
{
// Strangely isses a compiler warning (W8111 due to TSearchRec::Time), when used in Script.cpp, but not here.
Dest = Source;
}
//---------------------------------------------------------------------------
bool __fastcall IsRealFile(const UnicodeString & FileName)
{
return (FileName != THISDIRECTORY) && (FileName != PARENTDIRECTORY);

View File

@@ -192,6 +192,7 @@ private:
typedef void __fastcall (__closure* TProcessLocalFileEvent)
(const UnicodeString & FileName, const TSearchRecSmart & Rec, void * Param);
bool __fastcall FileSearchRec(const UnicodeString FileName, TSearchRec & Rec);
void CopySearchRec(const TSearchRec & Source, TSearchRec & Dest);
struct TSearchRecChecked : public TSearchRecSmart
{
UnicodeString Path;

View File

@@ -1710,7 +1710,7 @@ void __fastcall TSCPFileSystem::SCPSource(const UnicodeString FileName,
OperationProgress->SetFile(FileName, false);
if (!FTerminal->AllowLocalFileTransfer(FileName, CopyParam, OperationProgress))
if (!FTerminal->AllowLocalFileTransfer(FileName, NULL, CopyParam, OperationProgress))
{
throw ESkipFile();
}

View File

@@ -716,9 +716,10 @@ TStrings * __fastcall TScript::CreateFileList(TScriptProcParams * Parameters, in
TStrings * __fastcall TScript::CreateLocalFileList(TScriptProcParams * Parameters,
int Start, int End, TFileListType ListType)
{
TStrings * Result = new TStringList();
TStringList * Result = new TStringList();
try
{
Result->OwnsObjects = true;
UnicodeString LatestFileName;
TDateTime LatestModification; // initialized to 0
@@ -748,7 +749,9 @@ TStrings * __fastcall TScript::CreateLocalFileList(TScriptProcParams * Parameter
if (SearchRec.IsRealFile())
{
UnicodeString FileName = Directory + SearchRec.Name;
Result->Add(FileName);
TLocalFile * LocalFile = new TLocalFile;
CopySearchRec(SearchRec, LocalFile->SearchRec);
Result->AddObject(FileName, LocalFile);
if (SearchRec.TimeStamp > LatestModification)
{
LatestFileName = FileName;

View File

@@ -5128,37 +5128,42 @@ bool __fastcall TTerminal::DoAllowRemoteFileTransfer(
!IsEmptyRemoteDirectory(File, CopyParam, DisallowTemporaryTransferFiles));
}
//---------------------------------------------------------------------------
bool __fastcall TTerminal::AllowLocalFileTransfer(UnicodeString FileName,
bool __fastcall TTerminal::AllowLocalFileTransfer(
const UnicodeString & FileName, const TSearchRecSmart * SearchRec,
const TCopyParamType * CopyParam, TFileOperationProgressType * OperationProgress)
{
bool Result = true;
// optimization (though in most uses of the method, the caller actually knows TSearchRec already, so it could pass it here)
// optimization (though in most uses of the method, the caller actually knows TSearchRec already, so it passes it here
if (Log->Logging || !CopyParam->AllowAnyTransfer())
{
TSearchRecSmart SearchRec;
FILE_OPERATION_LOOP_BEGIN
TSearchRecSmart ASearchRec;
if (SearchRec == NULL)
{
if (!FileSearchRec(FileName, SearchRec))
FILE_OPERATION_LOOP_BEGIN
{
RaiseLastOSError();
if (!FileSearchRec(FileName, ASearchRec))
{
RaiseLastOSError();
}
}
FILE_OPERATION_LOOP_END(FMTLOAD(FILE_NOT_EXISTS, (FileName)));
SearchRec = &ASearchRec;
}
FILE_OPERATION_LOOP_END(FMTLOAD(FILE_NOT_EXISTS, (FileName)));
if (!DoAllowLocalFileTransfer(FileName, SearchRec, CopyParam, false))
if (!DoAllowLocalFileTransfer(FileName, *SearchRec, CopyParam, false))
{
LogEvent(FORMAT(L"File \"%s\" excluded from transfer", (FileName)));
Result = false;
}
else if (CopyParam->SkipTransfer(FileName, SearchRec.IsDirectory()))
else if (CopyParam->SkipTransfer(FileName, SearchRec->IsDirectory()))
{
OperationProgress->AddSkippedFileSize(SearchRec.Size);
OperationProgress->AddSkippedFileSize(SearchRec->Size);
Result = false;
}
if (Result)
{
LogFileDetails(FileName, SearchRec.GetLastWriteTime(), SearchRec.Size);
LogFileDetails(FileName, SearchRec->GetLastWriteTime(), SearchRec->Size);
}
}
return Result;
@@ -6722,6 +6727,12 @@ void __fastcall TTerminal::DoCopyToRemote(
{
bool Success = false;
UnicodeString FileName = FilesToCopy->Strings[Index];
TSearchRecSmart * SearchRec = NULL;
if (FilesToCopy->Objects[Index] != NULL)
{
TLocalFile * LocalFile = dynamic_cast<TLocalFile *>(FilesToCopy->Objects[Index]);
SearchRec = &LocalFile->SearchRec;
}
try
{
@@ -6737,7 +6748,7 @@ void __fastcall TTerminal::DoCopyToRemote(
DirectoryModified(FullTargetDir + FileNameOnly, true);
}
}
SourceRobust(FileName, FullTargetDir, CopyParam, Params, OperationProgress, Flags | tfFirstLevel);
SourceRobust(FileName, SearchRec, FullTargetDir, CopyParam, Params, OperationProgress, Flags | tfFirstLevel);
Success = true;
}
catch (ESkipFile & E)
@@ -6758,7 +6769,8 @@ void __fastcall TTerminal::DoCopyToRemote(
}
//---------------------------------------------------------------------------
void __fastcall TTerminal::SourceRobust(
const UnicodeString & FileName, const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
const UnicodeString & FileName, const TSearchRecSmart * SearchRec,
const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
TFileOperationProgressType * OperationProgress, unsigned int Flags)
{
TUploadSessionAction Action(ActionLog);
@@ -6770,7 +6782,7 @@ void __fastcall TTerminal::SourceRobust(
bool ChildError = false;
try
{
Source(FileName, TargetDir, CopyParam, Params, OperationProgress, Flags, Action, ChildError);
Source(FileName, SearchRec, TargetDir, CopyParam, Params, OperationProgress, Flags, Action, ChildError);
}
catch (Exception & E)
{
@@ -6847,7 +6859,7 @@ void __fastcall TTerminal::DirectorySource(
{
if (SearchRec.IsRealFile())
{
SourceRobust(FileName, DestFullName, CopyParam, Params, OperationProgress, (Flags & ~(tfFirstLevel | tfAutoResume)));
SourceRobust(FileName, &SearchRec, DestFullName, CopyParam, Params, OperationProgress, (Flags & ~(tfFirstLevel | tfAutoResume)));
// FTP: if any file got uploaded (i.e. there were any file in the directory and at least one was not skipped),
// do not try to create the directory, as it should be already created by FZAPI during upload
PostCreateDir = false;
@@ -6968,14 +6980,15 @@ void __fastcall TTerminal::UpdateSource(const TLocalFileHandle & Handle, const T
}
//---------------------------------------------------------------------------
void __fastcall TTerminal::Source(
const UnicodeString & FileName, const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
const UnicodeString & FileName, const TSearchRecSmart * SearchRec,
const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
TFileOperationProgressType * OperationProgress, unsigned int Flags, TUploadSessionAction & Action, bool & ChildError)
{
Action.FileName(ExpandUNCFileName(FileName));
OperationProgress->SetFile(FileName, false);
if (!AllowLocalFileTransfer(FileName, CopyParam, OperationProgress))
if (!AllowLocalFileTransfer(FileName, SearchRec, CopyParam, OperationProgress))
{
throw ESkipFile();
}

View File

@@ -309,7 +309,8 @@ protected:
__int64 * ATime, __int64 * Size, bool TryWriteReadOnly = true);
void __fastcall OpenLocalFile(
const UnicodeString & FileName, unsigned int Access, TLocalFileHandle & Handle, bool TryWriteReadOnly = true);
bool __fastcall AllowLocalFileTransfer(UnicodeString FileName,
bool __fastcall AllowLocalFileTransfer(
const UnicodeString & FileName, const TSearchRecSmart * SearchRec,
const TCopyParamType * CopyParam, TFileOperationProgressType * OperationProgress);
bool __fastcall HandleException(Exception * E);
void __fastcall CalculateFileSize(UnicodeString FileName,
@@ -447,10 +448,12 @@ protected:
TStrings * FilesToCopy, const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
TFileOperationProgressType * OperationProgress, unsigned int Flags, TOnceDoneOperation & OnceDoneOperation);
void __fastcall SourceRobust(
const UnicodeString & FileName, const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
const UnicodeString & FileName, const TSearchRecSmart * SearchRec,
const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
TFileOperationProgressType * OperationProgress, unsigned int Flags);
void __fastcall Source(
const UnicodeString & FileName, const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
const UnicodeString & FileName, const TSearchRecSmart * SearchRec,
const UnicodeString & TargetDir, const TCopyParamType * CopyParam, int Params,
TFileOperationProgressType * OperationProgress, unsigned int Flags, TUploadSessionAction & Action, bool & ChildError);
void __fastcall DirectorySource(
const UnicodeString & DirectoryName, const UnicodeString & TargetDir, const UnicodeString & DestDirectoryName,
@@ -886,4 +889,10 @@ struct TLocalFileHandle
__int64 Size;
};
//---------------------------------------------------------------------------
class TLocalFile : public TObject
{
public:
TSearchRecSmart SearchRec;
};
//---------------------------------------------------------------------------
#endif