Browse Source

Refactoring checksum calculation to share more code between FTP and SFTP in anticipation of reusing it for SCP/Shell

Source commit: 9a5138737031573ad64085fa64ef8fdd7fca8f77
Martin Prikryl 3 years ago
parent
commit
03e38c75ae

+ 6 - 0
source/core/FileSystems.cpp

@@ -23,3 +23,9 @@ UnicodeString __fastcall TCustomFileSystem::GetHomeDirectory()
   NotImplemented();
   return EmptyStr;
 }
+//---------------------------------------------------------------------------
+UnicodeString TCustomFileSystem::CalculateFilesChecksumInitialize(const UnicodeString & DebugUsedArg(Alg))
+{
+  NotImplemented();
+  return EmptyStr;
+}

+ 5 - 3
source/core/FileSystems.h

@@ -47,9 +47,11 @@ public:
     const TRemoteFile * File, const TRemoteProperties * Properties,
     TChmodSessionAction & Action) = 0;
   virtual bool __fastcall LoadFilesProperties(TStrings * FileList) = 0;
-  virtual void __fastcall CalculateFilesChecksum(const UnicodeString & Alg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum) = 0;
+  virtual UnicodeString CalculateFilesChecksumInitialize(const UnicodeString & Alg);
+  virtual void __fastcall CalculateFilesChecksum(
+    const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
+    TCalculatedChecksumEvent OnCalculatedChecksum,
+    TFileOperationProgressType * OperationProgress, bool FirstLevel) = 0;
   virtual void __fastcall CopyToLocal(TStrings * FilesToCopy,
     const UnicodeString TargetDir, const TCopyParamType * CopyParam,
     int Params, TFileOperationProgressType * OperationProgress,

+ 43 - 87
source/core/FtpFileSystem.cpp

@@ -1098,14 +1098,14 @@ bool __fastcall TFTPFileSystem::LoadFilesProperties(TStrings * /*FileList*/)
   return false;
 }
 //---------------------------------------------------------------------------
-UnicodeString __fastcall TFTPFileSystem::DoCalculateFileChecksum(
-  bool UsingHashCommand, const UnicodeString & Alg, TRemoteFile * File)
+UnicodeString __fastcall TFTPFileSystem::DoCalculateFileChecksum(const UnicodeString & Alg, TRemoteFile * File)
 {
   // Overview of server supporting various hash commands is at:
   // https://datatracker.ietf.org/doc/html/draft-bryan-ftpext-hash-02#appendix-B
 
   UnicodeString CommandName;
 
+  bool UsingHashCommand = UsingHashCommandChecksum(Alg);
   if (UsingHashCommand)
   {
     CommandName = HashCommand;
@@ -1215,82 +1215,49 @@ UnicodeString __fastcall TFTPFileSystem::DoCalculateFileChecksum(
   return LowerCase(Hash);
 }
 //---------------------------------------------------------------------------
-void __fastcall TFTPFileSystem::DoCalculateFilesChecksum(bool UsingHashCommand,
+void __fastcall TFTPFileSystem::CalculateFilesChecksum(
   const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
   TCalculatedChecksumEvent OnCalculatedChecksum,
   TFileOperationProgressType * OperationProgress, bool FirstLevel)
 {
-  TOnceDoneOperation OnceDoneOperation; // not used
+  FTerminal->CalculateSubFoldersChecksum(Alg, FileList, OnCalculatedChecksum, OperationProgress, FirstLevel);
 
   int Index = 0;
+  TOnceDoneOperation OnceDoneOperation; // not used
   while ((Index < FileList->Count) && !OperationProgress->Cancel)
   {
     TRemoteFile * File = (TRemoteFile *)FileList->Objects[Index];
     DebugAssert(File != NULL);
 
-    if (File->IsDirectory)
+    if (!File->IsDirectory)
     {
-      if (FTerminal->CanRecurseToDirectory(File) &&
-          IsRealFile(File->FileName) &&
-          // recurse into subdirectories only if we have callback function
-          (OnCalculatedChecksum != NULL))
+      TChecksumSessionAction Action(FTerminal->ActionLog);
+      try
       {
         OperationProgress->SetFile(File->FileName);
-        TRemoteFileList * SubFiles =
-          FTerminal->CustomReadDirectoryListing(File->FullFileName, false);
-
-        if (SubFiles != NULL)
+        Action.FileName(FTerminal->AbsolutePath(File->FullFileName, true));
+        bool Success = false;
+        try
         {
-          TStrings * SubFileList = new TStringList();
-          bool Success = false;
-          try
-          {
-            OperationProgress->SetFile(File->FileName);
-
-            for (int Index = 0; Index < SubFiles->Count; Index++)
-            {
-              TRemoteFile * SubFile = SubFiles->Files[Index];
-              SubFileList->AddObject(SubFile->FullFileName, SubFile);
-            }
-
-            // do not collect checksums for files in subdirectories,
-            // only send back checksums via callback
-            DoCalculateFilesChecksum(UsingHashCommand, Alg, SubFileList, NULL,
-              OnCalculatedChecksum, OperationProgress, false);
+          UnicodeString Checksum = DoCalculateFileChecksum(Alg, File);
 
-            Success = true;
+          if (OnCalculatedChecksum != NULL)
+          {
+            OnCalculatedChecksum(File->FileName, Alg, Checksum);
           }
-          __finally
+          Action.Checksum(Alg, Checksum);
+          if (Checksums != NULL)
           {
-            delete SubFiles;
-            delete SubFileList;
-
-            if (FirstLevel)
-            {
-              OperationProgress->Finish(File->FileName, Success, OnceDoneOperation);
-            }
+            Checksums->Add(Checksum);
           }
+          Success = true;
         }
-      }
-    }
-    else
-    {
-      TChecksumSessionAction Action(FTerminal->ActionLog);
-      try
-      {
-        OperationProgress->SetFile(File->FileName);
-        Action.FileName(FTerminal->AbsolutePath(File->FullFileName, true));
-
-        UnicodeString Checksum = DoCalculateFileChecksum(UsingHashCommand, Alg, File);
-
-        if (OnCalculatedChecksum != NULL)
-        {
-          OnCalculatedChecksum(File->FileName, Alg, Checksum);
-        }
-        Action.Checksum(Alg, Checksum);
-        if (Checksums != NULL)
+        __finally
         {
-          Checksums->Add(Checksum);
+          if (FirstLevel)
+          {
+            OperationProgress->Finish(File->FileName, Success, OnceDoneOperation);
+          }
         }
       }
       catch (Exception & E)
@@ -1311,41 +1278,30 @@ void __fastcall TFTPFileSystem::DoCalculateFilesChecksum(bool UsingHashCommand,
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TFTPFileSystem::CalculateFilesChecksum(const UnicodeString & Alg,
-  TStrings * FileList, TStrings * Checksums,
-  TCalculatedChecksumEvent OnCalculatedChecksum)
+UnicodeString TFTPFileSystem::CalculateFilesChecksumInitialize(const UnicodeString & Alg)
 {
-  TFileOperationProgressType Progress(&FTerminal->DoProgress, &FTerminal->DoFinished);
-  FTerminal->OperationStart(Progress, foCalculateChecksum, osRemote, FileList->Count);
-
-  try
+  UnicodeString NormalizedAlg = FindIdent(FindIdent(Alg, FHashAlgs.get()), FChecksumAlgs.get());
+  if (UsingHashCommandChecksum(NormalizedAlg))
   {
-    UnicodeString NormalizedAlg = FindIdent(FindIdent(Alg, FHashAlgs.get()), FChecksumAlgs.get());
-
-    bool UsingHashCommand = (FHashAlgs->IndexOf(NormalizedAlg) >= 0);
-    if (UsingHashCommand)
-    {
-      // The server should understand lowercase alg name by spec,
-      // but we should use uppercase anyway
-      SendCommand(FORMAT(L"OPTS %s %s", (HashCommand, UpperCase(NormalizedAlg))));
-      GotReply(WaitForCommandReply(), REPLY_2XX_CODE);
-    }
-    else if (FChecksumAlgs->IndexOf(NormalizedAlg) >= 0)
-    {
-      // will use algorithm-specific command
-    }
-    else
-    {
-      throw Exception(FMTLOAD(UNKNOWN_CHECKSUM, (Alg)));
-    }
-
-    DoCalculateFilesChecksum(UsingHashCommand, NormalizedAlg, FileList, Checksums, OnCalculatedChecksum,
-      &Progress, true);
+    // The server should understand lowercase alg name by spec,
+    // but we should use uppercase anyway
+    SendCommand(FORMAT(L"OPTS %s %s", (HashCommand, UpperCase(NormalizedAlg))));
+    GotReply(WaitForCommandReply(), REPLY_2XX_CODE);
   }
-  __finally
+  else if (FChecksumAlgs->IndexOf(NormalizedAlg) >= 0)
   {
-    FTerminal->OperationStop(Progress);
+    // will use algorithm-specific command
   }
+  else
+  {
+    throw Exception(FMTLOAD(UNKNOWN_CHECKSUM, (Alg)));
+  }
+  return NormalizedAlg;
+}
+//---------------------------------------------------------------------------
+bool TFTPFileSystem::UsingHashCommandChecksum(const UnicodeString & Alg)
+{
+  return (FHashAlgs->IndexOf(Alg) >= 0);
 }
 //---------------------------------------------------------------------------
 bool __fastcall TFTPFileSystem::ConfirmOverwrite(

+ 7 - 8
source/core/FtpFileSystem.h

@@ -40,9 +40,11 @@ public:
     const TRemoteFile * File, const TRemoteProperties * Properties,
     TChmodSessionAction & Action);
   virtual bool __fastcall LoadFilesProperties(TStrings * FileList);
-  virtual void __fastcall CalculateFilesChecksum(const UnicodeString & Alg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum);
+  virtual UnicodeString CalculateFilesChecksumInitialize(const UnicodeString & Alg);
+  void __fastcall CalculateFilesChecksum(
+    const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
+    TCalculatedChecksumEvent OnCalculatedChecksum,
+    TFileOperationProgressType * OperationProgress, bool FirstLevel);
   virtual void __fastcall CopyToLocal(TStrings * FilesToCopy,
     const UnicodeString TargetDir, const TCopyParamType * CopyParam,
     int Params, TFileOperationProgressType * OperationProgress,
@@ -199,11 +201,8 @@ protected:
   inline bool __fastcall NeedAutoDetectTimeDifference();
   bool __fastcall LookupUploadModificationTime(
     const UnicodeString & FileName, TDateTime & Modification, TModificationFmt ModificationFmt);
-  UnicodeString __fastcall DoCalculateFileChecksum(bool UsingHashCommand, const UnicodeString & Alg, TRemoteFile * File);
-  void __fastcall DoCalculateFilesChecksum(bool UsingHashCommand, const UnicodeString & Alg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum,
-    TFileOperationProgressType * OperationProgress, bool FirstLevel);
+  UnicodeString __fastcall DoCalculateFileChecksum(const UnicodeString & Alg, TRemoteFile * File);
+  bool UsingHashCommandChecksum(const UnicodeString & Alg);
   void __fastcall HandleFeatReply();
   void __fastcall ResetFeatures();
   void ProcessFeatures();

+ 4 - 3
source/core/S3FileSystem.cpp

@@ -1647,9 +1647,10 @@ bool __fastcall TS3FileSystem::LoadFilesProperties(TStrings * FileList)
   return Result;
 }
 //---------------------------------------------------------------------------
-void __fastcall TS3FileSystem::CalculateFilesChecksum(const UnicodeString & /*Alg*/,
-    TStrings * /*FileList*/, TStrings * /*Checksums*/,
-    TCalculatedChecksumEvent /*OnCalculatedChecksum*/)
+void __fastcall TS3FileSystem::CalculateFilesChecksum(
+  const UnicodeString & DebugUsedArg(Alg), TStrings * DebugUsedArg(FileList), TStrings * DebugUsedArg(Checksums),
+  TCalculatedChecksumEvent,
+  TFileOperationProgressType *, bool DebugUsedArg(FirstLevel))
 {
   DebugFail();
 }

+ 4 - 3
source/core/S3FileSystem.h

@@ -54,9 +54,10 @@ public:
     const TRemoteFile * File, const TRemoteProperties * Properties,
     TChmodSessionAction & Action);
   virtual bool __fastcall LoadFilesProperties(TStrings * FileList);
-  virtual void __fastcall CalculateFilesChecksum(const UnicodeString & Alg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum);
+  virtual void __fastcall CalculateFilesChecksum(
+    const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
+    TCalculatedChecksumEvent OnCalculatedChecksum,
+    TFileOperationProgressType * OperationProgress, bool FirstLevel);
   virtual void __fastcall CopyToLocal(TStrings * FilesToCopy,
     const UnicodeString TargetDir, const TCopyParamType * CopyParam,
     int Params, TFileOperationProgressType * OperationProgress,

+ 4 - 3
source/core/ScpFileSystem.cpp

@@ -1308,9 +1308,10 @@ bool __fastcall TSCPFileSystem::LoadFilesProperties(TStrings * /*FileList*/ )
   return false;
 }
 //---------------------------------------------------------------------------
-void __fastcall TSCPFileSystem::CalculateFilesChecksum(const UnicodeString & /*Alg*/,
-  TStrings * /*FileList*/, TStrings * /*Checksums*/,
-  TCalculatedChecksumEvent /*OnCalculatedChecksum*/)
+void __fastcall TSCPFileSystem::CalculateFilesChecksum(
+  const UnicodeString & DebugUsedArg(Alg), TStrings * DebugUsedArg(FileList), TStrings * DebugUsedArg(Checksums),
+  TCalculatedChecksumEvent,
+  TFileOperationProgressType *, bool DebugUsedArg(FirstLevel))
 {
   DebugFail();
 }

+ 4 - 3
source/core/ScpFileSystem.h

@@ -30,9 +30,10 @@ public:
     const TRemoteFile * File, const TRemoteProperties * Properties,
     TChmodSessionAction & Action);
   virtual bool __fastcall LoadFilesProperties(TStrings * FileList);
-  virtual void __fastcall CalculateFilesChecksum(const UnicodeString & Alg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum);
+  virtual void __fastcall CalculateFilesChecksum(
+    const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
+    TCalculatedChecksumEvent OnCalculatedChecksum,
+    TFileOperationProgressType * OperationProgress, bool FirstLevel);
   virtual void __fastcall CopyToLocal(TStrings * FilesToCopy,
     const UnicodeString TargetDir, const TCopyParamType * CopyParam,
     int Params, TFileOperationProgressType * OperationProgress,

+ 18 - 82
source/core/SftpFileSystem.cpp

@@ -4056,68 +4056,30 @@ bool __fastcall TSFTPFileSystem::LoadFilesProperties(TStrings * FileList)
   return Result;
 }
 //---------------------------------------------------------------------------
-void __fastcall TSFTPFileSystem::DoCalculateFilesChecksum(
-  const UnicodeString & Alg, const UnicodeString & SftpAlg,
-  TStrings * FileList, TStrings * Checksums,
+void __fastcall TSFTPFileSystem::CalculateFilesChecksum(
+  const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
   TCalculatedChecksumEvent OnCalculatedChecksum,
   TFileOperationProgressType * OperationProgress, bool FirstLevel)
 {
-  TOnceDoneOperation OnceDoneOperation; // not used
-
-  // recurse into subdirectories only if we have callback function
-  if (OnCalculatedChecksum != NULL)
-  {
-    for (int Index = 0; Index < FileList->Count; Index++)
-    {
-      TRemoteFile * File = (TRemoteFile *)FileList->Objects[Index];
-      DebugAssert(File != NULL);
-      if (File->IsDirectory && FTerminal->CanRecurseToDirectory(File) &&
-          IsRealFile(File->FileName))
-      {
-        OperationProgress->SetFile(File->FileName);
-        TRemoteFileList * SubFiles =
-          FTerminal->CustomReadDirectoryListing(File->FullFileName, false);
-
-        if (SubFiles != NULL)
-        {
-          TStrings * SubFileList = new TStringList();
-          bool Success = false;
-          try
-          {
-            OperationProgress->SetFile(File->FileName);
-
-            for (int Index = 0; Index < SubFiles->Count; Index++)
-            {
-              TRemoteFile * SubFile = SubFiles->Files[Index];
-              SubFileList->AddObject(SubFile->FullFileName, SubFile);
-            }
-
-            // do not collect checksums for files in subdirectories,
-            // only send back checksums via callback
-            DoCalculateFilesChecksum(Alg, SftpAlg, SubFileList, NULL,
-              OnCalculatedChecksum, OperationProgress, false);
-
-            Success = true;
-          }
-          __finally
-          {
-            delete SubFiles;
-            delete SubFileList;
-
-            if (FirstLevel)
-            {
-              OperationProgress->Finish(File->FileName, Success, OnceDoneOperation);
-            }
-          }
-        }
-      }
-    }
-  }
+  FTerminal->CalculateSubFoldersChecksum(Alg, FileList, OnCalculatedChecksum, OperationProgress, FirstLevel);
 
   static int CalculateFilesChecksumQueueLen = 5;
   TSFTPCalculateFilesChecksumQueue Queue(this);
+  TOnceDoneOperation OnceDoneOperation; // not used
   try
   {
+    UnicodeString SftpAlg;
+    int Index = FChecksumAlgs->IndexOf(Alg);
+    if (Index >= 0)
+    {
+      SftpAlg = FChecksumSftpAlgs->Strings[Index];
+    }
+    else
+    {
+      // try user-specified alg
+      SftpAlg = Alg;
+    }
+
     if (Queue.Init(CalculateFilesChecksumQueueLen, SftpAlg, FileList))
     {
       TSFTPPacket Packet;
@@ -4191,35 +4153,9 @@ void __fastcall TSFTPFileSystem::DoCalculateFilesChecksum(
   // queue is discarded here
 }
 //---------------------------------------------------------------------------
-void __fastcall TSFTPFileSystem::CalculateFilesChecksum(const UnicodeString & Alg,
-  TStrings * FileList, TStrings * Checksums,
-  TCalculatedChecksumEvent OnCalculatedChecksum)
+UnicodeString TSFTPFileSystem::CalculateFilesChecksumInitialize(const UnicodeString & Alg)
 {
-  TFileOperationProgressType Progress(&FTerminal->DoProgress, &FTerminal->DoFinished);
-
-  UnicodeString NormalizedAlg = FindIdent(Alg, FChecksumAlgs.get());
-  UnicodeString SftpAlg;
-  int Index = FChecksumAlgs->IndexOf(NormalizedAlg);
-  if (Index >= 0)
-  {
-    SftpAlg = FChecksumSftpAlgs->Strings[Index];
-  }
-  else
-  {
-    // try user-specified alg
-    SftpAlg = NormalizedAlg;
-  }
-
-  FTerminal->OperationStart(Progress, foCalculateChecksum, osRemote, FileList->Count);
-  try
-  {
-    DoCalculateFilesChecksum(NormalizedAlg, SftpAlg, FileList, Checksums, OnCalculatedChecksum,
-      &Progress, true);
-  }
-  __finally
-  {
-    FTerminal->OperationStop(Progress);
-  }
+  return FindIdent(Alg, FChecksumAlgs.get());
 }
 //---------------------------------------------------------------------------
 void __fastcall TSFTPFileSystem::CustomCommandOnFile(const UnicodeString /*FileName*/,

+ 5 - 8
source/core/SftpFileSystem.h

@@ -42,9 +42,11 @@ public:
     const TRemoteFile * File, const TRemoteProperties * Properties,
     TChmodSessionAction & Action);
   virtual bool __fastcall LoadFilesProperties(TStrings * FileList);
-  virtual void __fastcall CalculateFilesChecksum(const UnicodeString & Alg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum);
+  virtual UnicodeString CalculateFilesChecksumInitialize(const UnicodeString & Alg);
+  virtual void __fastcall CalculateFilesChecksum(
+    const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
+    TCalculatedChecksumEvent OnCalculatedChecksum,
+    TFileOperationProgressType * OperationProgress, bool FirstLevel);
   virtual void __fastcall CopyToLocal(TStrings * FilesToCopy,
     const UnicodeString TargetDir, const TCopyParamType * CopyParam,
     int Params, TFileOperationProgressType * OperationProgress,
@@ -162,11 +164,6 @@ protected:
   void __fastcall TryOpenDirectory(const UnicodeString Directory);
   bool __fastcall SupportsExtension(const UnicodeString & Extension) const;
   void __fastcall ResetConnection();
-  void __fastcall DoCalculateFilesChecksum(
-    const UnicodeString & Alg, const UnicodeString & SftpAlg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum,
-    TFileOperationProgressType * OperationProgress, bool FirstLevel);
   void __fastcall RegisterChecksumAlg(const UnicodeString & Alg, const UnicodeString & SftpAlg);
   void __fastcall DoDeleteFile(const UnicodeString FileName, unsigned char Type);
 

+ 67 - 1
source/core/Terminal.cpp

@@ -4497,11 +4497,77 @@ bool TTerminal::CalculateFilesSize(TStrings * FileList, __int64 & Size, TCalcula
   return Params.Result;
 }
 //---------------------------------------------------------------------------
+void __fastcall TTerminal::CalculateSubFoldersChecksum(
+  const UnicodeString & Alg, TStrings * FileList, TCalculatedChecksumEvent OnCalculatedChecksum,
+  TFileOperationProgressType * OperationProgress, bool FirstLevel)
+{
+  // recurse into subdirectories only if we have callback function
+  if (OnCalculatedChecksum != NULL)
+  {
+    int Index = 0;
+    TOnceDoneOperation OnceDoneOperation; // unused
+    while ((Index < FileList->Count) && !OperationProgress->Cancel)
+    {
+      TRemoteFile * File = DebugNotNull(dynamic_cast<TRemoteFile *>(FileList->Objects[Index]));
+
+      if (File->IsDirectory &&
+          CanRecurseToDirectory(File) &&
+          IsRealFile(File->FileName))
+      {
+        OperationProgress->SetFile(File->FileName);
+        std::unique_ptr<TRemoteFileList> SubFiles(CustomReadDirectoryListing(File->FullFileName, false));
+
+        if (SubFiles.get() != NULL)
+        {
+          std::unique_ptr<TStrings> SubFileList(new TStringList());
+          bool Success = false;
+          try
+          {
+            OperationProgress->SetFile(File->FileName);
+
+            for (int Index = 0; Index < SubFiles->Count; Index++)
+            {
+              TRemoteFile * SubFile = SubFiles->Files[Index];
+              SubFileList->AddObject(SubFile->FullFileName, SubFile);
+            }
+
+            // do not collect checksums for files in subdirectories,
+            // only send back checksums via callback
+            FFileSystem->CalculateFilesChecksum(Alg, SubFileList.get(), NULL, OnCalculatedChecksum, OperationProgress, false);
+
+            Success = true;
+          }
+          __finally
+          {
+            if (FirstLevel)
+            {
+              OperationProgress->Finish(File->FileName, Success, OnceDoneOperation);
+            }
+          }
+        }
+      }
+      Index++;
+    }
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TTerminal::CalculateFilesChecksum(const UnicodeString & Alg,
   TStrings * FileList, TStrings * Checksums,
   TCalculatedChecksumEvent OnCalculatedChecksum)
 {
-  FFileSystem->CalculateFilesChecksum(Alg, FileList, Checksums, OnCalculatedChecksum);
+  TFileOperationProgressType Progress(&DoProgress, &DoFinished);
+  OperationStart(Progress, foCalculateChecksum, osRemote, FileList->Count);
+
+  try
+  {
+    UnicodeString NormalizedAlg = FFileSystem->CalculateFilesChecksumInitialize(Alg);
+
+    FFileSystem->CalculateFilesChecksum(NormalizedAlg, FileList, Checksums, OnCalculatedChecksum, &Progress, true);
+  }
+  __finally
+  {
+    OperationStop(Progress);
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::RenameFile(const TRemoteFile * File,

+ 3 - 0
source/core/Terminal.h

@@ -488,6 +488,9 @@ protected:
   void __fastcall UpdateTargetTime(HANDLE Handle, TDateTime Modification, TDSTMode DSTMode);
   TRemoteFile * CheckRights(const UnicodeString & EntryType, const UnicodeString & FileName, bool & WrongRights);
   bool IsValidFile(TRemoteFile * File);
+  void __fastcall CalculateSubFoldersChecksum(
+    const UnicodeString & Alg, TStrings * FileList, TCalculatedChecksumEvent OnCalculatedChecksum,
+    TFileOperationProgressType * OperationProgress, bool FirstLevel);
 
   UnicodeString __fastcall EncryptFileName(const UnicodeString & Path, bool EncryptNewFiles);
   UnicodeString __fastcall DecryptFileName(const UnicodeString & Path, bool DecryptFullPath, bool DontCache);

+ 4 - 3
source/core/WebDAVFileSystem.cpp

@@ -1134,9 +1134,10 @@ bool __fastcall TWebDAVFileSystem::LoadFilesProperties(TStrings * /*FileList*/)
   return false;
 }
 //---------------------------------------------------------------------------
-void __fastcall TWebDAVFileSystem::CalculateFilesChecksum(const UnicodeString & /*Alg*/,
-    TStrings * /*FileList*/, TStrings * /*Checksums*/,
-    TCalculatedChecksumEvent /*OnCalculatedChecksum*/)
+void __fastcall TWebDAVFileSystem::CalculateFilesChecksum(
+  const UnicodeString & DebugUsedArg(Alg), TStrings * DebugUsedArg(FileList), TStrings * DebugUsedArg(Checksums),
+  TCalculatedChecksumEvent,
+  TFileOperationProgressType *, bool DebugUsedArg(FirstLevel))
 {
   DebugFail();
 }

+ 4 - 3
source/core/WebDAVFileSystem.h

@@ -39,9 +39,10 @@ public:
     const TRemoteFile * File, const TRemoteProperties * Properties,
     TChmodSessionAction & Action);
   virtual bool __fastcall LoadFilesProperties(TStrings * FileList);
-  virtual void __fastcall CalculateFilesChecksum(const UnicodeString & Alg,
-    TStrings * FileList, TStrings * Checksums,
-    TCalculatedChecksumEvent OnCalculatedChecksum);
+  virtual void __fastcall CalculateFilesChecksum(
+    const UnicodeString & Alg, TStrings * FileList, TStrings * Checksums,
+    TCalculatedChecksumEvent OnCalculatedChecksum,
+    TFileOperationProgressType * OperationProgress, bool FirstLevel);
   virtual void __fastcall CopyToLocal(TStrings * FilesToCopy,
     const UnicodeString TargetDir, const TCopyParamType * CopyParam,
     int Params, TFileOperationProgressType * OperationProgress,