From 6c7f6477d0617fd2539120c5fc9a60b174f5ca6d Mon Sep 17 00:00:00 2001
From: martinprikryl <martinprikryl>
Date: Wed, 4 Nov 2015 14:11:29 +0000
Subject: [PATCH] WinSCP 5.7.6 2015-11-04
 http://winscp.net/eng/docs/history?a=5.7.6

---
 dotnet/Session.cs                             |  4 +
 .../ReadOnlyInteropCollectionHelper.cs        |  5 +
 dotnet/interopcollections/StringCollection.cs |  5 +
 dotnet/properties/AssemblyInfo.cs             |  6 +-
 source/Console.cbproj                         |  2 +-
 source/DragExt.cbproj                         |  2 +-
 source/DragExt64.rc                           |  4 +-
 source/WinSCP.cbproj                          |  4 +-
 source/components/UnixDirView.cpp             | 36 ++++----
 source/components/UnixDriveView.cpp           | 21 +++--
 source/core/FtpFileSystem.cpp                 | 92 +++++++++++++------
 source/core/FtpFileSystem.h                   |  1 +
 source/core/Script.cpp                        | 12 +++
 source/core/SecureShell.cpp                   |  4 +
 source/core/SessionData.cpp                   |  8 +-
 source/core/SessionData.h                     |  6 +-
 source/core/SessionInfo.cpp                   |  4 +-
 source/core/WebDAVFileSystem.cpp              | 32 ++++---
 source/filezilla/FtpControlSocket.cpp         | 16 +++-
 source/filezilla/FtpListResult.cpp            | 33 +++++--
 source/filezilla/FtpListResult.h              |  6 +-
 source/forms/CustomScpExplorer.cpp            | 60 ++++++------
 source/resource/TextsCore.h                   |  1 +
 source/resource/TextsCore1.rc                 |  1 +
 source/windows/TerminalManager.cpp            |  7 +-
 source/windows/WinMain.cpp                    |  2 +-
 26 files changed, 243 insertions(+), 131 deletions(-)

diff --git a/dotnet/Session.cs b/dotnet/Session.cs
index ed5c0e3e..06f2d628 100644
--- a/dotnet/Session.cs
+++ b/dotnet/Session.cs
@@ -1239,6 +1239,10 @@ private void ProcessOutputDataReceived(object sender, OutputDataReceivedEventArg
         {
             Logger.WriteLine("Scheduling output: [{0}]", e.Data);
             Output.InternalAdd(e.Data);
+            if (Output.Count > 1000)
+            {
+                Output.InternalRemoveFirst();
+            }
             GotOutput();
             ScheduleEvent(() => RaiseOutputDataReceived(e.Data));
         }
diff --git a/dotnet/internal/ReadOnlyInteropCollectionHelper.cs b/dotnet/internal/ReadOnlyInteropCollectionHelper.cs
index b2bf8cb4..f88cf875 100644
--- a/dotnet/internal/ReadOnlyInteropCollectionHelper.cs
+++ b/dotnet/internal/ReadOnlyInteropCollectionHelper.cs
@@ -11,6 +11,11 @@ public void InternalAdd(T item)
             _list.Add(item);
         }
 
+        public void InternalRemoveFirst()
+        {
+            _list.RemoveAt(0);
+        }
+
         public T this[int index]
         {
             get
diff --git a/dotnet/interopcollections/StringCollection.cs b/dotnet/interopcollections/StringCollection.cs
index 6ccfa0df..92a90a4e 100644
--- a/dotnet/interopcollections/StringCollection.cs
+++ b/dotnet/interopcollections/StringCollection.cs
@@ -83,6 +83,11 @@ internal void InternalAdd(string item)
             _helper.InternalAdd(item);
         }
 
+        internal void InternalRemoveFirst()
+        {
+            _helper.InternalRemoveFirst();
+        }
+
         private readonly ReadOnlyInteropCollectionHelper<string> _helper = new ReadOnlyInteropCollectionHelper<string>();
     }
 }
diff --git a/dotnet/properties/AssemblyInfo.cs b/dotnet/properties/AssemblyInfo.cs
index 3a9d817d..fa7320c0 100644
--- a/dotnet/properties/AssemblyInfo.cs
+++ b/dotnet/properties/AssemblyInfo.cs
@@ -19,9 +19,9 @@
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("a0b93468-d98a-4845-a234-8076229ad93f")]
 
-[assembly: AssemblyVersion("1.2.9.0")]
-[assembly: AssemblyFileVersion("1.2.9.0")]
-[assembly: AssemblyInformationalVersionAttribute("5.7.5.0")]
+[assembly: AssemblyVersion("1.2.10.0")]
+[assembly: AssemblyFileVersion("1.2.10.0")]
+[assembly: AssemblyInformationalVersionAttribute("5.7.6.0")]
 
 [assembly: CLSCompliant(true)]
 
diff --git a/source/Console.cbproj b/source/Console.cbproj
index eb55d6e2..f4bfe9e6 100644
--- a/source/Console.cbproj
+++ b/source/Console.cbproj
@@ -65,7 +65,7 @@
 			<ProjectType>CppConsoleApplication</ProjectType>
 			<SanitizedProjectName>Console</SanitizedProjectName>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.1.0.0;InternalName=console;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.7.5.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.1.0.0;InternalName=console;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.7.6.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>4</VerInfo_MajorVer>
 			<VerInfo_MinorVer>1</VerInfo_MinorVer>
diff --git a/source/DragExt.cbproj b/source/DragExt.cbproj
index cb506b67..a1f283bd 100644
--- a/source/DragExt.cbproj
+++ b/source/DragExt.cbproj
@@ -66,7 +66,7 @@
 			<SanitizedProjectName>DragExt</SanitizedProjectName>
 			<VerInfo_DLL>true</VerInfo_DLL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.7.5.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.7.6.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>
 			<VerInfo_Release>1</VerInfo_Release>
diff --git a/source/DragExt64.rc b/source/DragExt64.rc
index 826ab4e3..ab360e92 100644
--- a/source/DragExt64.rc
+++ b/source/DragExt64.rc
@@ -1,6 +1,6 @@
 1 VERSIONINFO
 FILEVERSION 1,2,1,0
-PRODUCTVERSION 5,7,5,0
+PRODUCTVERSION 5,7,6,0
 FILEOS 0x4
 FILETYPE 0x2
 {
@@ -16,7 +16,7 @@ FILETYPE 0x2
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "dragext64.dll\0"
             VALUE "ProductName", "WinSCP\0"
-            VALUE "ProductVersion", "5.7.5.0\0"
+            VALUE "ProductVersion", "5.7.6.0\0"
             VALUE "ReleaseType", "stable\0"
             VALUE "WWW", "http://winscp.net/\0"
         }
diff --git a/source/WinSCP.cbproj b/source/WinSCP.cbproj
index e03e8c58..4753d695 100644
--- a/source/WinSCP.cbproj
+++ b/source/WinSCP.cbproj
@@ -83,11 +83,11 @@
 			<SanitizedProjectName>WinSCP</SanitizedProjectName>
 			<UsingDelphiRTL>true</UsingDelphiRTL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.7.5.0;InternalName=winscp;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.7.5.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.7.6.0;InternalName=winscp;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.7.6.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>5</VerInfo_MajorVer>
 			<VerInfo_MinorVer>7</VerInfo_MinorVer>
-			<VerInfo_Release>5</VerInfo_Release>
+			<VerInfo_Release>6</VerInfo_Release>
 		</PropertyGroup>
 	<PropertyGroup Condition="'$(Base_Win32)'!=''">
 			<Defines>IDE;STRICT;$(Defines)</Defines>
diff --git a/source/components/UnixDirView.cpp b/source/components/UnixDirView.cpp
index 8df1f18c..d3bc4dba 100644
--- a/source/components/UnixDirView.cpp
+++ b/source/components/UnixDirView.cpp
@@ -429,25 +429,29 @@ void __fastcall TUnixDirView::PerformItemDragDropOperation(TListItem * Item,
 #ifndef DESIGN_ONLY
   if (OnDDFileOperation)
   {
-    assert(DragDropFilesEx->FileList->Count > 0);
+    // Could be empty if the source application does not provide any files;
+    // or if the IDataObject fails GetData, like Visual Studio Code 0.8.0:
+    // https://code.visualstudio.com/issues/detail/19410
+    if (DragDropFilesEx->FileList->Count > 0)
+    {
+      UnicodeString SourceDirectory;
+      UnicodeString TargetDirectory;
 
-    UnicodeString SourceDirectory;
-    UnicodeString TargetDirectory;
+      SourceDirectory = ExtractFilePath(DragDropFilesEx->FileList->Items[0]->Name);
+      if (Item)
+      {
+        assert(ITEMFILE->IsDirectory && (Terminal->Files->IndexOf(ITEMFILE) >= 0));
+        TargetDirectory = ITEMFILE->FullFileName;
+      }
+      else
+      {
+        TargetDirectory = Path;
+      }
 
-    SourceDirectory = ExtractFilePath(DragDropFilesEx->FileList->Items[0]->Name);
-    if (Item)
-    {
-      assert(ITEMFILE->IsDirectory && (Terminal->Files->IndexOf(ITEMFILE) >= 0));
-      TargetDirectory = ITEMFILE->FullFileName;
+      bool DoFileOperation = true;
+      OnDDFileOperation(this, Effect, SourceDirectory, TargetDirectory,
+        DoFileOperation);
     }
-    else
-    {
-      TargetDirectory = Path;
-    }
-
-    bool DoFileOperation = true;
-    OnDDFileOperation(this, Effect, SourceDirectory, TargetDirectory,
-      DoFileOperation);
   }
 #else
   USEDPARAM(Item);
diff --git a/source/components/UnixDriveView.cpp b/source/components/UnixDriveView.cpp
index cfbe5127..87a3d021 100644
--- a/source/components/UnixDriveView.cpp
+++ b/source/components/UnixDriveView.cpp
@@ -528,18 +528,21 @@ void __fastcall TCustomUnixDriveView::PerformDragDropFileOperation(
 {
   if (OnDDFileOperation)
   {
-    assert(DragDropFilesEx->FileList->Count > 0);
-    assert(Node != NULL);
+    // see a comment in TUnixDirView::PerformItemDragDropOperation
+    if (DragDropFilesEx->FileList->Count > 0)
+    {
+      assert(Node != NULL);
 
-    UnicodeString SourceDirectory;
-    UnicodeString TargetDirectory;
+      UnicodeString SourceDirectory;
+      UnicodeString TargetDirectory;
 
-    SourceDirectory = ExtractFilePath(DragDropFilesEx->FileList->Items[0]->Name);
-    TargetDirectory = NodeData(Node)->Directory;
+      SourceDirectory = ExtractFilePath(DragDropFilesEx->FileList->Items[0]->Name);
+      TargetDirectory = NodeData(Node)->Directory;
 
-    bool DoFileOperation = true;
-    OnDDFileOperation(this, Effect, SourceDirectory, TargetDirectory,
-      DoFileOperation);
+      bool DoFileOperation = true;
+      OnDDFileOperation(this, Effect, SourceDirectory, TargetDirectory,
+        DoFileOperation);
+    }
   }
 }
 //---------------------------------------------------------------------------
diff --git a/source/core/FtpFileSystem.cpp b/source/core/FtpFileSystem.cpp
index ea2714c7..3eed5fbb 100644
--- a/source/core/FtpFileSystem.cpp
+++ b/source/core/FtpFileSystem.cpp
@@ -382,6 +382,8 @@ void __fastcall TFTPFileSystem::Open()
     }
   }
 
+  FTransferActiveImmediately = (Data->FtpTransferActiveImmediately == asOn);
+
   UnicodeString HostName = Data->HostNameExpanded;
   UnicodeString UserName = Data->UserNameExpanded;
   UnicodeString Password = Data->Password;
@@ -743,6 +745,15 @@ void __fastcall TFTPFileSystem::CollectUsage()
   {
     FTerminal->Configuration->Usage->Inc(L"OpenedSessionsFTPSyncplify");
   }
+  // 220-Idea FTP Server v0.80 (xxx.home.pl) [xxx.xxx.xxx.xxx]
+  // 220 Ready
+  // ...
+  // SYST
+  // UNIX Type: L8
+  else if (ContainsText(FWelcomeMessage, L"Idea FTP Server"))
+  {
+    FTerminal->Configuration->Usage->Inc(L"OpenedSessionsFTPIdea");
+  }
   else
   {
     FTerminal->Configuration->Usage->Inc(L"OpenedSessionsFTPOther");
@@ -2431,7 +2442,7 @@ void __fastcall TFTPFileSystem::AutoDetectTimeDifference(TRemoteFileList * FileL
         TDateTime UtcModification = UtcFile->Modification;
         delete UtcFile;
 
-        FTimeDifference = SecondsBetween(UtcModification, File->Modification);
+        FTimeDifference = static_cast<__int64>(SecsPerDay * (UtcModification - File->Modification));
 
         UnicodeString LogMessage;
         if (FTimeDifference == 0)
@@ -2563,10 +2574,9 @@ void __fastcall TFTPFileSystem::DoReadFile(const UnicodeString & AFileName,
     if (File != NULL)
     {
       AFile = File->Duplicate();
+      ApplyTimeDifference(AFile);
     }
 
-    ApplyTimeDifference(AFile);
-
     FLastDataSent = Now();
   }
   __finally
@@ -2597,41 +2607,50 @@ void __fastcall TFTPFileSystem::ReadFile(const UnicodeString FileName,
   }
   else
   {
-    // FZAPI does not have efficient way to read properties of one file.
-    // In case we need properties of set of files from the same directory,
-    // cache the file list for future
-    if ((FFileListCache != NULL) &&
-        UnixSamePath(Path, FFileListCache->Directory) &&
-        (UnixIsAbsolutePath(FFileListCache->Directory) ||
-        (FFileListCachePath == CurrentDirectory)))
+    if (IsUnixRootPath(FileName))
     {
-      AFile = FFileListCache->FindFile(NameOnly);
+      AFile = new TRemoteDirectoryFile();
+      AFile->FullFileName = FileName;
+      AFile->FileName = L"";
     }
-    // if cache is invalid or file is not in cache, (re)read the directory
-    if (AFile == NULL)
+    else
     {
-      TRemoteFileList * FileListCache = new TRemoteFileList();
-      FileListCache->Directory = Path;
-      try
+      // FZAPI does not have efficient way to read properties of one file.
+      // In case we need properties of set of files from the same directory,
+      // cache the file list for future
+      if ((FFileListCache != NULL) &&
+          UnixSamePath(Path, FFileListCache->Directory) &&
+          (UnixIsAbsolutePath(FFileListCache->Directory) ||
+          (FFileListCachePath == CurrentDirectory)))
       {
-        ReadDirectory(FileListCache);
+        AFile = FFileListCache->FindFile(NameOnly);
       }
-      catch(...)
+      // if cache is invalid or file is not in cache, (re)read the directory
+      if (AFile == NULL)
       {
-        delete FileListCache;
-        throw;
+        TRemoteFileList * FileListCache = new TRemoteFileList();
+        FileListCache->Directory = Path;
+        try
+        {
+          ReadDirectory(FileListCache);
+        }
+        catch(...)
+        {
+          delete FileListCache;
+          throw;
+        }
+        // set only after we successfully read the directory,
+        // otherwise, when we reconnect from ReadDirectory,
+        // the FFileListCache is reset from ResetCache.
+        delete FFileListCache;
+        FFileListCache = FileListCache;
+        FFileListCachePath = GetCurrentDirectory();
+
+        AFile = FFileListCache->FindFile(NameOnly);
       }
-      // set only after we successfully read the directory,
-      // otherwise, when we reconnect from ReadDirectory,
-      // the FFileListCache is reset from ResetCache.
-      delete FFileListCache;
-      FFileListCache = FileListCache;
-      FFileListCachePath = GetCurrentDirectory();
 
-      AFile = FFileListCache->FindFile(NameOnly);
+      Own = false;
     }
-
-    Own = false;
   }
 
   if (AFile == NULL)
@@ -2982,7 +3001,7 @@ int __fastcall TFTPFileSystem::GetOptionVal(int OptionID) const
       break;
 
     case OPTION_MPEXT_TRANSFER_ACTIVE_IMMEDIATELY:
-      Result = Data->FtpTransferActiveImmediately;
+      Result = FTransferActiveImmediately;
       break;
 
     case OPTION_MPEXT_REMOVE_BOM:
@@ -3455,6 +3474,10 @@ void __fastcall TFTPFileSystem::HandleReplyStatus(UnicodeString Response)
   //  SIZE
   // 211 End
 
+  // This format is according to RFC 2228.
+  // Is used by ProFTPD when  MultilineRFC2228 is enabled
+  // http://www.proftpd.org/docs/directives/linked/config_ref_MultilineRFC2228.html
+
   // 211-Features:
   // 211-MDTM
   // 211-REST STREAM
@@ -3471,6 +3494,8 @@ void __fastcall TFTPFileSystem::HandleReplyStatus(UnicodeString Response)
   //     MDTM
   // 211 END
 
+  // Partially duplicated in CFtpControlSocket::OnReceive
+
   bool HasCodePrefix =
     (Response.Length() >= 3) &&
     TryStrToInt(Response.SubString(1, 3), Code) &&
@@ -3531,6 +3556,13 @@ void __fastcall TFTPFileSystem::HandleReplyStatus(UnicodeString Response)
         {
           FTerminal->DisplayBanner(FWelcomeMessage);
         }
+        // Idea FTP Server v0.80
+        if ((FTerminal->SessionData->FtpTransferActiveImmediately == asAuto) &&
+            FWelcomeMessage.Pos(L"Idea FTP Server") > 0)
+        {
+          FTerminal->LogEvent(L"The server requires TLS/SSL handshake on transfer connection before responding 1yz to STOR/APPE");
+          FTransferActiveImmediately = true;
+        }
       }
     }
     else if (FLastCommand == PASS)
diff --git a/source/core/FtpFileSystem.h b/source/core/FtpFileSystem.h
index dbb3f675..d1b9dd57 100644
--- a/source/core/FtpFileSystem.h
+++ b/source/core/FtpFileSystem.h
@@ -268,6 +268,7 @@ friend class TFileListHelper;
   std::unique_ptr<TStrings> FHashAlgs;
   bool FSupportsAnyChecksumFeature;
   UnicodeString FLastCommandSent;
+  bool FTransferActiveImmediately;
   mutable UnicodeString FOptionScratch;
 };
 //---------------------------------------------------------------------------
diff --git a/source/core/Script.cpp b/source/core/Script.cpp
index 6930a872..4772fd85 100644
--- a/source/core/Script.cpp
+++ b/source/core/Script.cpp
@@ -569,6 +569,12 @@ TStrings * __fastcall TScript::CreateFileList(TScriptProcParams * Parameters, in
       for (int i = Start; i <= End; i++)
       {
         UnicodeString FileName = Parameters->Param[i];
+
+        if (SimpleUnixExcludeTrailingBackslash(FileName) != FileName)
+        {
+          PrintLine(LoadStr(SCRIPT_AMBIGUOUS_SLASH_IN_PATH));
+        }
+
         if (FLAGSET(ListType, fltDirectories))
         {
           TRemoteFile * File = new TRemoteFile();
@@ -686,6 +692,12 @@ TStrings * __fastcall TScript::CreateLocalFileList(TScriptProcParams * Parameter
       // (it actually won't make a difference functionally as we fall back to adding
       // the path as is in "else" branch, but the comment "let it fail later" won't stand)
       UnicodeString FileName = ExcludeTrailingBackslash(Parameters->Param[i]);
+
+      if (FileName != Parameters->Param[i])
+      {
+        PrintLine(LoadStr(SCRIPT_AMBIGUOUS_SLASH_IN_PATH));
+      }
+
       if (FLAGSET(ListType, fltMask))
       {
         TSearchRecChecked SearchRec;
diff --git a/source/core/SecureShell.cpp b/source/core/SecureShell.cpp
index 4611ed0a..061efd10 100644
--- a/source/core/SecureShell.cpp
+++ b/source/core/SecureShell.cpp
@@ -2353,6 +2353,10 @@ void __fastcall TSecureShell::CollectUsage()
   {
     Configuration->Usage->Inc(L"OpenedSessionsSSHSyncplify");
   }
+  else if (ContainsText(FSessionInfo.SshImplementation, L"zFTPServer"))
+  {
+    Configuration->Usage->Inc(L"OpenedSessionsSSHzFTP");
+  }
   else
   {
     Configuration->Usage->Inc(L"OpenedSessionsSSHOther");
diff --git a/source/core/SessionData.cpp b/source/core/SessionData.cpp
index e101a888..cdf44d7e 100644
--- a/source/core/SessionData.cpp
+++ b/source/core/SessionData.cpp
@@ -211,7 +211,7 @@ void __fastcall TSessionData::Default()
   FtpAccount = L"";
   FtpPingInterval = 30;
   FtpPingType = ptDummyCommand;
-  FtpTransferActiveImmediately = false;
+  FtpTransferActiveImmediately = asAuto;
   Ftps = ftpsNone;
   MinTlsVersion = tls10;
   MaxTlsVersion = tls12;
@@ -657,7 +657,7 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool & Rewr
   FtpAccount = Storage->ReadString(L"FtpAccount", FtpAccount);
   FtpPingInterval = Storage->ReadInteger(L"FtpPingInterval", FtpPingInterval);
   FtpPingType = static_cast<TPingType>(Storage->ReadInteger(L"FtpPingType", FtpPingType));
-  FtpTransferActiveImmediately = Storage->ReadBool(L"FtpTransferActiveImmediately", FtpTransferActiveImmediately);
+  FtpTransferActiveImmediately = static_cast<TAutoSwitch>(Storage->ReadInteger(L"FtpTransferActiveImmediately2", FtpTransferActiveImmediately));
   Ftps = static_cast<TFtps>(Storage->ReadInteger(L"Ftps", Ftps));
   FtpListAll = TAutoSwitch(Storage->ReadInteger(L"FtpListAll", FtpListAll));
   FtpHost = TAutoSwitch(Storage->ReadInteger(L"FtpHost", FtpHost));
@@ -920,7 +920,7 @@ void __fastcall TSessionData::Save(THierarchicalStorage * Storage,
       WRITE_DATA(String, FtpAccount);
       WRITE_DATA(Integer, FtpPingInterval);
       WRITE_DATA(Integer, FtpPingType);
-      WRITE_DATA(Bool, FtpTransferActiveImmediately);
+      WRITE_DATA_EX(Integer, L"FtpTransferActiveImmediately2", FtpTransferActiveImmediately, );
       WRITE_DATA(Integer, Ftps);
       WRITE_DATA(Integer, FtpListAll);
       WRITE_DATA(Integer, FtpHost);
@@ -2650,7 +2650,7 @@ void __fastcall TSessionData::SetFtpPingType(TPingType value)
   SET_SESSION_PROPERTY(FtpPingType);
 }
 //---------------------------------------------------------------------------
-void __fastcall TSessionData::SetFtpTransferActiveImmediately(bool value)
+void __fastcall TSessionData::SetFtpTransferActiveImmediately(TAutoSwitch value)
 {
   SET_SESSION_PROPERTY(FtpTransferActiveImmediately);
 }
diff --git a/source/core/SessionData.h b/source/core/SessionData.h
index 799485f5..e88bc894 100644
--- a/source/core/SessionData.h
+++ b/source/core/SessionData.h
@@ -181,7 +181,7 @@ friend class TStoredSessionList;
   UnicodeString FFtpAccount;
   int FFtpPingInterval;
   TPingType FFtpPingType;
-  bool FFtpTransferActiveImmediately;
+  TAutoSwitch FFtpTransferActiveImmediately;
   TFtps FFtps;
   TTlsVersion FMinTlsVersion;
   TTlsVersion FMaxTlsVersion;
@@ -332,7 +332,7 @@ friend class TStoredSessionList;
   void __fastcall SetFtpAccount(UnicodeString value);
   void __fastcall SetFtpPingInterval(int value);
   void __fastcall SetFtpPingType(TPingType value);
-  void __fastcall SetFtpTransferActiveImmediately(bool value);
+  void __fastcall SetFtpTransferActiveImmediately(TAutoSwitch value);
   void __fastcall SetFtps(TFtps value);
   void __fastcall SetMinTlsVersion(TTlsVersion value);
   void __fastcall SetMaxTlsVersion(TTlsVersion value);
@@ -522,7 +522,7 @@ friend class TStoredSessionList;
   __property int FtpPingInterval  = { read=FFtpPingInterval, write=SetFtpPingInterval };
   __property TDateTime FtpPingIntervalDT  = { read=GetFtpPingIntervalDT };
   __property TPingType FtpPingType = { read = FFtpPingType, write = SetFtpPingType };
-  __property bool FtpTransferActiveImmediately = { read = FFtpTransferActiveImmediately, write = SetFtpTransferActiveImmediately };
+  __property TAutoSwitch FtpTransferActiveImmediately = { read = FFtpTransferActiveImmediately, write = SetFtpTransferActiveImmediately };
   __property TFtps Ftps = { read = FFtps, write = SetFtps };
   __property TTlsVersion MinTlsVersion = { read = FMinTlsVersion, write = SetMinTlsVersion };
   __property TTlsVersion MaxTlsVersion = { read = FMaxTlsVersion, write = SetMaxTlsVersion };
diff --git a/source/core/SessionInfo.cpp b/source/core/SessionInfo.cpp
index 45e55028..16c20b21 100644
--- a/source/core/SessionInfo.cpp
+++ b/source/core/SessionInfo.cpp
@@ -1173,9 +1173,9 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
           ADF(L"TLS/SSL versions: %s-%s", (GetTlsVersionName(Data->MinTlsVersion), GetTlsVersionName(Data->MaxTlsVersion)));
         }
         // kind of hidden option, so do not reveal it unless it is set
-        if (Data->FtpTransferActiveImmediately)
+        if (Data->FtpTransferActiveImmediately != asAuto)
         {
-          ADF(L"Transfer active immediately: %s", (BooleanToEngStr(Data->FtpTransferActiveImmediately)));
+          ADF(L"Transfer active immediately: %s", (BugFlags[Data->FtpTransferActiveImmediately]));
         }
       }
       ADF(L"Local directory: %s, Remote directory: %s, Update: %s, Cache: %s",
diff --git a/source/core/WebDAVFileSystem.cpp b/source/core/WebDAVFileSystem.cpp
index ff83cd6b..ef805505 100644
--- a/source/core/WebDAVFileSystem.cpp
+++ b/source/core/WebDAVFileSystem.cpp
@@ -878,15 +878,13 @@ void TWebDAVFileSystem::NeonPropsResult(
   UTF8String UnescapedUri = PathUnescape(Uri->path).c_str();
   UnicodeString Path = StrFromNeon(UnescapedUri);
 
-  Path = UnixExcludeTrailingBackslash(Path);
-
   TReadFileData & Data = *static_cast<TReadFileData *>(UserData);
   if (Data.FileList != NULL)
   {
     UnicodeString FileListPath = Data.FileSystem->AbsolutePath(Data.FileList->Directory, false);
     if (UnixSamePath(Path, FileListPath))
     {
-      Path = UnixIncludeTrailingBackslash(Path) + L"..";
+      Path = UnixIncludeTrailingBackslash(UnixIncludeTrailingBackslash(Path) + L"..");
     }
     std::unique_ptr<TRemoteFile> File(new TRemoteFile(NULL));
     File->Terminal = Data.FileSystem->FTerminal;
@@ -910,7 +908,10 @@ const char * __fastcall TWebDAVFileSystem::GetProp(const ne_prop_result_set * Re
 void __fastcall TWebDAVFileSystem::ParsePropResultSet(TRemoteFile * File,
   const UnicodeString & Path, const ne_prop_result_set * Results)
 {
-  File->FullFileName = Path;
+  File->FullFileName = UnixExcludeTrailingBackslash(Path);
+  // Some servers do not use DAV:collection tag, but indicate the folder by trailing slash only.
+  // It seems that all servers actually use the trailing slash, including IIS, mod_Dav, IT Hit, OpenDrive, etc.
+  bool Collection = (File->FullFileName != Path);
   File->FileName = UnixExtractFileName(File->FullFileName);
   const char * ContentLength = GetProp(Results, PROP_CONTENT_LENGTH);
   // some servers, for example iFiles, do not provide "getcontentlength" for folders
@@ -945,18 +946,25 @@ void __fastcall TWebDAVFileSystem::ParsePropResultSet(TRemoteFile * File,
       }
     }
   }
-  bool Collection = false;
-  const char * ResourceType = GetProp(Results, PROP_RESOURCE_TYPE);
-  if (ResourceType != NULL)
+
+  // optimization
+  if (!Collection)
   {
-    // property has XML value
-    UnicodeString AResourceType = ResourceType;
-    // this is very poor parsing
-    if (ContainsText(ResourceType, L"<DAV:collection"))
+    // This is possibly redundant code as all servers we know (see a comment above)
+    // indicate the folder by trailing slash too
+    const char * ResourceType = GetProp(Results, PROP_RESOURCE_TYPE);
+    if (ResourceType != NULL)
     {
-      Collection = true;
+      // property has XML value
+      UnicodeString AResourceType = ResourceType;
+      // this is very poor parsing
+      if (ContainsText(ResourceType, L"<DAV:collection"))
+      {
+        Collection = true;
+      }
     }
   }
+
   File->Type = Collection ? FILETYPE_DIRECTORY : FILETYPE_DEFAULT;
   // this is MS extension (draft-hopmann-collection-props-00)
   const char * IsHidden = GetProp(Results, PROP_HIDDEN);
diff --git a/source/filezilla/FtpControlSocket.cpp b/source/filezilla/FtpControlSocket.cpp
index 5cd0d042..7051ebbb 100644
--- a/source/filezilla/FtpControlSocket.cpp
+++ b/source/filezilla/FtpControlSocket.cpp
@@ -1226,14 +1226,20 @@ void CFtpControlSocket::OnReceive(int nErrorCode)
 				{
 					ShowStatus(A2CT(m_RecvBuffer.back()), FZ_LOG_REPLY);
 				}
-				//Check for multi-line responses
+				// Check for multi-line responses
+				// Partially duplicated in TFTPFileSystem::HandleReplyStatus
 				if (m_RecvBuffer.back().GetLength() > 3)
 				{
 					if (m_MultiLine != "")
 					{
 						if (m_RecvBuffer.back().Left(4) != m_MultiLine)
 						{
-							DiscardLine(m_RecvBuffer.back());
+							CStringA line = m_RecvBuffer.back();
+							if (line.Left(4) == m_MultiLine.Left(3) + '-')
+							{
+								line = line.Mid(4, line.GetLength() - 4);
+							}
+							DiscardLine(line);
  							m_RecvBuffer.pop_back();
 						}
 						else // end of multi-line found
@@ -1699,7 +1705,7 @@ void CFtpControlSocket::List(BOOL bFinish, int nError /*=FALSE*/, CServerPath pa
 		pData->pDirectoryListing = new t_directory;
 		if (COptions::GetOptionVal(OPTION_DEBUGSHOWLISTING))
 			m_pTransferSocket->m_pListResult->SendToMessageLog(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID);
-		pData->pDirectoryListing->direntry = m_pTransferSocket->m_pListResult->getList(num, pData->ListStartTime);
+		pData->pDirectoryListing->direntry = m_pTransferSocket->m_pListResult->getList(num, pData->ListStartTime, false);
 		pData->pDirectoryListing->num = num;
 		if (m_pTransferSocket->m_pListResult->m_server.nServerType & FZ_SERVERTYPE_SUB_FTP_VMS && m_CurrentServer.nServerType & FZ_SERVERTYPE_FTP)
 			m_CurrentServer.nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
@@ -2541,7 +2547,7 @@ void CFtpControlSocket::ListFile(CString filename, const CServerPath &path)
 			pListResult->AddData(buffer, size);
 			if (COptions::GetOptionVal(OPTION_DEBUGSHOWLISTING))
 				pListResult->SendToMessageLog(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID);
-			pData->direntry = pListResult->getList(num, CTime::GetCurrentTime());
+			pData->direntry = pListResult->getList(num, CTime::GetCurrentTime(), true);
 			if (pListResult->m_server.nServerType & FZ_SERVERTYPE_SUB_FTP_VMS && m_CurrentServer.nServerType & FZ_SERVERTYPE_FTP)
 				m_CurrentServer.nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
 			delete pListResult;
@@ -2893,7 +2899,7 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 			pData->pDirectoryListing=new t_directory;
 			if (COptions::GetOptionVal(OPTION_DEBUGSHOWLISTING))
 				m_pTransferSocket->m_pListResult->SendToMessageLog(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID);
-			pData->pDirectoryListing->direntry=m_pTransferSocket->m_pListResult->getList(num, pData->ListStartTime);
+			pData->pDirectoryListing->direntry=m_pTransferSocket->m_pListResult->getList(num, pData->ListStartTime, false);
 			pData->pDirectoryListing->num=num;
 			if (m_pTransferSocket->m_pListResult->m_server.nServerType&FZ_SERVERTYPE_SUB_FTP_VMS && m_CurrentServer.nServerType&FZ_SERVERTYPE_FTP)
 				m_CurrentServer.nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
diff --git a/source/filezilla/FtpListResult.cpp b/source/filezilla/FtpListResult.cpp
index cb3c8b9f..8dcfa5c1 100644
--- a/source/filezilla/FtpListResult.cpp
+++ b/source/filezilla/FtpListResult.cpp
@@ -422,7 +422,7 @@ CFtpListResult::~CFtpListResult()
 		delete [] m_curline;
 }
 
-t_directory::t_direntry *CFtpListResult::getList(int &num, CTime EntryTime)
+t_directory::t_direntry *CFtpListResult::getList(int &num, CTime EntryTime, bool mlst)
 {
 	#ifdef _DEBUG
 	USES_CONVERSION;
@@ -435,7 +435,7 @@ t_directory::t_direntry *CFtpListResult::getList(int &num, CTime EntryTime)
 		char *tmpline = new char[strlen(line) + 1];
 		strcpy(tmpline, line);
 		t_directory::t_direntry direntry;
-		if (parseLine(tmpline, strlen(tmpline), direntry, tmp))
+		if (parseLine(tmpline, strlen(tmpline), direntry, tmp, mlst))
 		{
 			delete [] tmpline;
 			if (tmp)
@@ -507,14 +507,14 @@ t_directory::t_direntry *CFtpListResult::getList(int &num, CTime EntryTime)
 	return res;
 }
 
-BOOL CFtpListResult::parseLine(const char *lineToParse, const int linelen, t_directory::t_direntry &direntry, int &nFTPServerType)
+BOOL CFtpListResult::parseLine(const char *lineToParse, const int linelen, t_directory::t_direntry &direntry, int &nFTPServerType, bool mlst)
 {
 	USES_CONVERSION;
 
 	nFTPServerType = 0;
 	direntry.ownergroup = _T("");
 
-	if (parseAsMlsd(lineToParse, linelen, direntry))
+	if (parseAsMlsd(lineToParse, linelen, direntry, mlst))
 		return TRUE;
 
 	if (parseAsUnix(lineToParse, linelen, direntry))
@@ -556,6 +556,7 @@ BOOL CFtpListResult::parseLine(const char *lineToParse, const int linelen, t_dir
 	return FALSE;
 }
 
+// Used only with LISTDEBUG
 void CFtpListResult::AddData(char *data, int size)
 {
 	#ifdef _DEBUG
@@ -605,7 +606,7 @@ void CFtpListResult::AddData(char *data, int size)
 		int tmp;
 		char *tmpline = new char[strlen(line) + 1];
 		strcpy(tmpline, line);
-		if (parseLine(tmpline, strlen(tmpline), direntry, tmp))
+		if (parseLine(tmpline, strlen(tmpline), direntry, tmp, false))
 		{
 			delete [] tmpline;
 			if (tmp)
@@ -1288,7 +1289,7 @@ BOOL CFtpListResult::parseAsEPLF(const char *line, const int linelen, t_director
 	return FALSE;
 }
 
-BOOL CFtpListResult::parseAsMlsd(const char *line, const int linelen, t_directory::t_direntry &direntry)
+BOOL CFtpListResult::parseAsMlsd(const char *line, const int linelen, t_directory::t_direntry &direntry, bool mlst)
 {
 	#ifdef _DEBUG
 	USES_CONVERSION;
@@ -1342,7 +1343,9 @@ BOOL CFtpListResult::parseAsMlsd(const char *line, const int linelen, t_director
 		if (factname == _T("type"))
 		{
 			if (!value.CompareNoCase(_T("dir")))
+			{
 				direntry.dir = TRUE;
+			}
 			// This is syntax used by proftpd by default
 			// http://www.proftpd.org/docs/modules/mod_facts.html
 			// They claim it's the correct one.
@@ -1367,9 +1370,23 @@ BOOL CFtpListResult::parseAsMlsd(const char *line, const int linelen, t_director
 				if ((value.GetLength() > 14) && (value[13] == ':'))
 					direntry.linkTarget = value.Mid(14);
 			}
-			else if (!value.CompareNoCase(_T("cdir")) ||
-					 !value.CompareNoCase(_T("pdir")))
+			else if (!value.CompareNoCase(L"cdir"))
+			{
+				// ProFTPD up to 1.3.6rc1 and 1.3.5a incorrectly uses "cdir" for the current working directory.
+				// So at least in MLST, where this would be the only entry, we treat it like "dir".
+				if (mlst)
+				{
+					direntry.dir = TRUE;
+				}
+				else
+				{
+					return FALSE;
+				}
+			}
+			else if (!value.CompareNoCase(L"pdir"))
+			{
 				return FALSE;
+			}
 		}
 		else if (factname == _T("size"))
 		{
diff --git a/source/filezilla/FtpListResult.h b/source/filezilla/FtpListResult.h
index d4ea06f2..32de64d8 100644
--- a/source/filezilla/FtpListResult.h
+++ b/source/filezilla/FtpListResult.h
@@ -61,17 +61,17 @@ class CFtpListResult : public CApiLog
 	void AddData(char *data,int size);
 	CFtpListResult(t_server server, bool *bUTF8 = 0);
 	virtual ~CFtpListResult();
-	t_directory::t_direntry *getList(int &num, CTime EntryTime);
+	t_directory::t_direntry *getList(int &num, CTime EntryTime, bool mlst);
 
 private:
 	typedef std::list<t_directory::t_direntry> tEntryList;
 	tEntryList m_EntryList;
 	
-	BOOL parseLine(const char *lineToParse, const int linelen, t_directory::t_direntry &direntry, int &nFTPServerType);
+	BOOL parseLine(const char *lineToParse, const int linelen, t_directory::t_direntry &direntry, int &nFTPServerType, bool mlst);
 
 	BOOL parseAsVMS(const char *line, const int linelen, t_directory::t_direntry &direntry);
 	BOOL parseAsEPLF(const char *line, const int linelen, t_directory::t_direntry &direntry);
-	BOOL parseAsMlsd(const char *line, const int linelen, t_directory::t_direntry &direntry);
+	BOOL parseAsMlsd(const char *line, const int linelen, t_directory::t_direntry &direntry, bool mlst);
 	BOOL parseAsUnix(const char *line, const int linelen, t_directory::t_direntry &direntry);
 	BOOL parseAsDos(const char *line, const int linelen, t_directory::t_direntry &direntry);
 	BOOL parseAsOther(const char *line, const int linelen, t_directory::t_direntry &direntry);
diff --git a/source/forms/CustomScpExplorer.cpp b/source/forms/CustomScpExplorer.cpp
index b741ce0e..8bc96064 100644
--- a/source/forms/CustomScpExplorer.cpp
+++ b/source/forms/CustomScpExplorer.cpp
@@ -474,6 +474,9 @@ bool __fastcall TCustomScpExplorerForm::CommandLineFromAnotherInstance(
       // so it's likely that our window is not visible,
       // and user won't see what is going on
       Application->BringToFront();
+      // reload sessions as we may be asked to open a session
+      // just stored by another instance
+      StoredSessions->Load();
       UnicodeString SessionName = Params.Param[1];
       std::unique_ptr<TObjectList> DataList(new TObjectList());
       UnicodeString DownloadFile; // unused
@@ -5735,7 +5738,7 @@ void __fastcall TCustomScpExplorerForm::WMQueryEndSession(TMessage & Message)
   // handle the abrupt termination caused by subsequent WM_ENDSESSION cleanly.
   // Hence the process termination might be safer :)
   if ((Message.LParam != ENDSESSION_CRITICAL) &&
-      (!FQueue->IsEmpty || (FProgressForm != NULL)))
+      (((FQueue != NULL) && !FQueue->IsEmpty) || (FProgressForm != NULL)))
   {
     Message.Result = FALSE;
   }
@@ -6763,39 +6766,42 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDragDropFileOperation(
       break;
   };
 
-  TStrings * FileList = new TStringList();
-  try
+  TDragDropFilesEx * DragDropFilesEx = DragDropFiles(Sender);
+  // see a comment in TUnixDirView::PerformItemDragDropOperation
+  if (DragDropFilesEx->FileList->Count > 0)
   {
-    TDragDropFilesEx * DragDropFilesEx = DragDropFiles(Sender);
-
-    for (int Index = 0; Index < DragDropFilesEx->FileList->Count; Index++)
-    {
-      FileList->Add(DragDropFilesEx->FileList->Items[Index]->Name);
-    }
-
-    FDragDropOperation = true;
-    TTransferOperationParam Param;
-    Param.TargetDirectory = TargetPath;
-    // upload, no temp dirs
-    Param.Temp = false;
-    Param.DragDrop = true;
-    if (ExecuteFileOperation(Operation, osLocal, FileList,
-          (WinConfiguration->DDTransferConfirmation == asOff), &Param))
+    TStrings * FileList = new TStringList();
+    try
     {
-      if (IsFileControl(DropSourceControl, osLocal))
+      for (int Index = 0; Index < DragDropFilesEx->FileList->Count; Index++)
       {
-        Configuration->Usage->Inc(L"UploadsDragDropInternal");
+        FileList->Add(DragDropFilesEx->FileList->Items[Index]->Name);
       }
-      else
+
+      FDragDropOperation = true;
+      TTransferOperationParam Param;
+      Param.TargetDirectory = TargetPath;
+      // upload, no temp dirs
+      Param.Temp = false;
+      Param.DragDrop = true;
+      if (ExecuteFileOperation(Operation, osLocal, FileList,
+            (WinConfiguration->DDTransferConfirmation == asOff), &Param))
       {
-        Configuration->Usage->Inc(L"UploadsDragDropExternal");
+        if (IsFileControl(DropSourceControl, osLocal))
+        {
+          Configuration->Usage->Inc(L"UploadsDragDropInternal");
+        }
+        else
+        {
+          Configuration->Usage->Inc(L"UploadsDragDropExternal");
+        }
       }
     }
-  }
-  __finally
-  {
-    FDragDropOperation = false;
-    delete FileList;
+    __finally
+    {
+      FDragDropOperation = false;
+      delete FileList;
+    }
   }
 }
 //---------------------------------------------------------------------------
diff --git a/source/resource/TextsCore.h b/source/resource/TextsCore.h
index 75dc29a6..3e0972fb 100644
--- a/source/resource/TextsCore.h
+++ b/source/resource/TextsCore.h
@@ -240,6 +240,7 @@
 #define UNKNOWN_CHECKSUM        715
 #define CIPHER_NOT_VERIFIED     716
 #define KEX_NOT_VERIFIED        717
+#define SCRIPT_AMBIGUOUS_SLASH_IN_PATH 729
 
 #define CORE_CONFIRMATION_STRINGS 300
 #define CONFIRM_PROLONG_TIMEOUT3 301
diff --git a/source/resource/TextsCore1.rc b/source/resource/TextsCore1.rc
index 5d103077..e26996a3 100644
--- a/source/resource/TextsCore1.rc
+++ b/source/resource/TextsCore1.rc
@@ -210,6 +210,7 @@ BEGIN
   UNKNOWN_CHECKSUM, "Checksum algorithm '%s' is not supported."
   CIPHER_NOT_VERIFIED, "Cipher %s was not verified!"
   KEX_NOT_VERIFIED, "Key-exchange algorithm %s was not verified!"
+  SCRIPT_AMBIGUOUS_SLASH_IN_PATH, "Selecting files using a path ending with slash is ambiguous. Remove the slash to select the folder. Append * mask to select all files in the folder."
 
   CORE_CONFIRMATION_STRINGS, "CORE_CONFIRMATION"
   CONFIRM_PROLONG_TIMEOUT3, "Host is not communicating for %d seconds.\n\nWait for another %0:d seconds?"
diff --git a/source/windows/TerminalManager.cpp b/source/windows/TerminalManager.cpp
index 637cb660..68c37843 100644
--- a/source/windows/TerminalManager.cpp
+++ b/source/windows/TerminalManager.cpp
@@ -791,8 +791,11 @@ bool __fastcall TTerminalManager::HandleMouseWheel(WPARAM WParam, LPARAM LParam)
     TWinControl * Control = FindVCLWindow(Point);
     if (Control != NULL)
     {
-      TCustomForm * Form = ValidParentForm(Control);
-      if (Form->Active)
+      TCustomForm * Form = GetParentForm(Control);
+      // Only case we expect the parent form to be NULL is on the Find/Replace dialog,
+      // which is owned by VCL's internal TRedirectorWindow.
+      assert((Form != NULL) || (Control->ClassName() == L"TRedirectorWindow"));
+      if ((Form != NULL) && Form->Active)
       {
         // Send it only to windows we tested it with.
         // Though we should sooner or later remote this test and pass it to all our windows.
diff --git a/source/windows/WinMain.cpp b/source/windows/WinMain.cpp
index 2ecb48a8..744cd9a4 100644
--- a/source/windows/WinMain.cpp
+++ b/source/windows/WinMain.cpp
@@ -350,7 +350,7 @@ void __fastcall UpdateStaticUsage()
       {
         unsigned int DpiX;
         unsigned int DpiY;
-        GetDpiForMonitor(Screen->Monitors[0]->Handle, MDT_Default, &DpiX, &DpiY);
+        GetDpiForMonitor(Screen->Monitors[Index]->Handle, MDT_Default, &DpiX, &DpiY);
 
         if (DpiX != DpiY)
         {