Browse Source

Bug 1644: Workaround for bug in Windows 10 1803 preventing drag & drop downloads to Windows Explorer via shell extension.

https://winscp.net/tracker/1644
(cherry picked from commit b65abacbe97da4f7e404a110f29707f4c15f2607)

# Conflicts:
#	source/forms/CustomScpExplorer.cpp

Source commit: 95f0887cd88df878a506ebe2b7480352a32e4032
Martin Prikryl 7 years ago
parent
commit
66cfa92f81

+ 2 - 2
source/DragExt.cbproj

@@ -49,9 +49,9 @@
 		<SanitizedProjectName>DragExt</SanitizedProjectName>
 		<SanitizedProjectName>DragExt</SanitizedProjectName>
 		<VerInfo_DLL>true</VerInfo_DLL>
 		<VerInfo_DLL>true</VerInfo_DLL>
 		<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
 		<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-		<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP ($(Platform));FileVersion=1.3.0.0;InternalName=dragext;LegalCopyright=(c) 2000-2018 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.13.2.0;ReleaseType=stable;WWW=https://winscp.net/</VerInfo_Keys>
+		<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP ($(Platform));FileVersion=2.0.0.0;InternalName=dragext;LegalCopyright=(c) 2000-2018 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.13.2.0;ReleaseType=stable;WWW=https://winscp.net/</VerInfo_Keys>
 		<VerInfo_Locale>1033</VerInfo_Locale>
 		<VerInfo_Locale>1033</VerInfo_Locale>
-		<VerInfo_MinorVer>3</VerInfo_MinorVer>
+		<VerInfo_MajorVer>2</VerInfo_MajorVer>
 	</PropertyGroup>
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Base_Win64)'!=''">
 	<PropertyGroup Condition="'$(Base_Win64)'!=''">
 		<OutputName>DragExt64</OutputName>
 		<OutputName>DragExt64</OutputName>

+ 17 - 8
source/core/Common.cpp

@@ -2779,17 +2779,26 @@ UnicodeString __fastcall WindowsProductName()
   return Result;
   return Result;
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-UnicodeString __fastcall WindowsVersion()
+static OSVERSIONINFO __fastcall GetWindowsVersion()
 {
 {
-  UnicodeString Result;
-  OSVERSIONINFO OSVersionInfo;
-  OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo);
+  OSVERSIONINFO Result;
+  memset(&Result, 0, sizeof(Result));
+  Result.dwOSVersionInfoSize = sizeof(Result);
   // Cannot use the VCL Win32MajorVersion+Win32MinorVersion+Win32BuildNumber as
   // Cannot use the VCL Win32MajorVersion+Win32MinorVersion+Win32BuildNumber as
   // on Windows 10 due to some hacking in InitPlatformId, the Win32BuildNumber is lost
   // on Windows 10 due to some hacking in InitPlatformId, the Win32BuildNumber is lost
-  if (GetVersionEx(&OSVersionInfo) != 0)
-  {
-    Result = FORMAT(L"%d.%d.%d", (int(OSVersionInfo.dwMajorVersion), int(OSVersionInfo.dwMinorVersion), int(OSVersionInfo.dwBuildNumber)));
-  }
+  GetVersionEx(&Result);
+  return Result;
+}
+//---------------------------------------------------------------------------
+int __fastcall GetWindowsBuild()
+{
+  return GetWindowsVersion().dwBuildNumber;
+}
+//---------------------------------------------------------------------------
+UnicodeString __fastcall WindowsVersion()
+{
+  OSVERSIONINFO OSVersionInfo = GetWindowsVersion();
+  UnicodeString Result = FORMAT(L"%d.%d.%d", (int(OSVersionInfo.dwMajorVersion), int(OSVersionInfo.dwMinorVersion), int(OSVersionInfo.dwBuildNumber)));
   return Result;
   return Result;
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------

+ 1 - 0
source/core/Common.h

@@ -137,6 +137,7 @@ LCID __fastcall GetDefaultLCID();
 UnicodeString __fastcall DefaultEncodingName();
 UnicodeString __fastcall DefaultEncodingName();
 UnicodeString __fastcall WindowsProductName();
 UnicodeString __fastcall WindowsProductName();
 bool _fastcall GetWindowsProductType(DWORD & Type);
 bool _fastcall GetWindowsProductType(DWORD & Type);
+int __fastcall GetWindowsBuild();
 UnicodeString __fastcall WindowsVersion();
 UnicodeString __fastcall WindowsVersion();
 UnicodeString __fastcall WindowsVersionLong();
 UnicodeString __fastcall WindowsVersionLong();
 bool __fastcall IsDirectoryWriteable(const UnicodeString & Path);
 bool __fastcall IsDirectoryWriteable(const UnicodeString & Path);

+ 6 - 1
source/dragext/DragExt.cpp

@@ -729,7 +729,12 @@ STDMETHODIMP_(UINT) CShellExt::CopyCallback(HWND /*Hwnd*/, UINT Func, UINT /*Fla
       FLastTicks = Ticks;
       FLastTicks = Ticks;
       const wchar_t* BackPtr = wcsrchr(SrcFile, L'\\');
       const wchar_t* BackPtr = wcsrchr(SrcFile, L'\\');
 
 
-      if ((BackPtr != NULL) &&
+      // WORKAROUND: Windows 10 1803 sends empty DestFile
+      if (wcslen(DestFile) == 0)
+      {
+        Debug(L"empty dest file");
+      }
+      else if ((BackPtr != NULL) &&
           (wcsncmp(BackPtr + 1, DRAG_EXT_DUMMY_DIR_PREFIX,
           (wcsncmp(BackPtr + 1, DRAG_EXT_DUMMY_DIR_PREFIX,
             DRAG_EXT_DUMMY_DIR_PREFIX_LEN) == 0))
             DRAG_EXT_DUMMY_DIR_PREFIX_LEN) == 0))
       {
       {

+ 11 - 6
source/forms/CustomScpExplorer.cpp

@@ -156,6 +156,11 @@ public:
   TTerminal * Terminal;
   TTerminal * Terminal;
 };
 };
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
+bool UseDirectoryMonitorDragDrop()
+{
+  return IsUWP() || (GetWindowsBuild() >= 17134);
+}
+//---------------------------------------------------------------------------
 __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
 __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
     FFormRestored(false),
     FFormRestored(false),
     TForm(Owner)
     TForm(Owner)
@@ -6584,7 +6589,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDCreateDragFileList(
 
 
   if (WinConfiguration->DDExtEnabled)
   if (WinConfiguration->DDExtEnabled)
   {
   {
-    if (!IsUWP() && !WinConfiguration->DDExtInstalled)
+    if (!UseDirectoryMonitorDragDrop() && !WinConfiguration->DDExtInstalled)
     {
     {
       Configuration->Usage->Inc(L"DownloadsDragDropExternalExtNotInstalled");
       Configuration->Usage->Inc(L"DownloadsDragDropExternalExtNotInstalled");
       throw ExtException(NULL, LoadStr(DRAGEXT_TARGET_NOT_INSTALLED2), HELP_DRAGEXT_TARGET_NOT_INSTALLED);
       throw ExtException(NULL, LoadStr(DRAGEXT_TARGET_NOT_INSTALLED2), HELP_DRAGEXT_TARGET_NOT_INSTALLED);
@@ -6612,7 +6617,7 @@ void __fastcall TCustomScpExplorerForm::DDExtInitDrag(TFileList * FileList,
   {
   {
     throw Exception(FMTLOAD(CREATE_TEMP_DIR_ERROR, (FDragExtFakeDirectory)));
     throw Exception(FMTLOAD(CREATE_TEMP_DIR_ERROR, (FDragExtFakeDirectory)));
   }
   }
-  if (IsUWP())
+  if (UseDirectoryMonitorDragDrop())
   {
   {
     FileSetAttr(ApiPath(FDragExtFakeDirectory), faHidden);
     FileSetAttr(ApiPath(FDragExtFakeDirectory), faHidden);
   }
   }
@@ -6620,7 +6625,7 @@ void __fastcall TCustomScpExplorerForm::DDExtInitDrag(TFileList * FileList,
 
 
   Created = true;
   Created = true;
 
 
-  if (IsUWP() && !WinConfiguration->IsDDExtRunning())
+  if ((IsUWP() && !WinConfiguration->IsDDExtRunning()) || (GetWindowsBuild() >= 17134))
   {
   {
     FDragFakeMonitors = new TObjectList();
     FDragFakeMonitors = new TObjectList();
     for (char Drive = FirstDrive; Drive <= LastDrive; Drive++)
     for (char Drive = FirstDrive; Drive <= LastDrive; Drive++)
@@ -6712,7 +6717,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
   // Drops of local files (uploads) are handled in QueueDDProcessDropped.
   // Drops of local files (uploads) are handled in QueueDDProcessDropped.
   SAFE_DESTROY(FDDFileList);
   SAFE_DESTROY(FDDFileList);
 
 
-  if (IsUWP() && !FFakeFileDropTarget.IsEmpty())
+  if (UseDirectoryMonitorDragDrop() && !FFakeFileDropTarget.IsEmpty())
   {
   {
     RemoveDir(ApiPath(FFakeFileDropTarget));
     RemoveDir(ApiPath(FFakeFileDropTarget));
   }
   }
@@ -6803,7 +6808,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
     {
     {
       CloseHandle(FDDExtMapFile);
       CloseHandle(FDDExtMapFile);
       FDDExtMapFile = NULL;
       FDDExtMapFile = NULL;
-      if (IsUWP())
+      if (UseDirectoryMonitorDragDrop())
       {
       {
         delete FDragFakeMonitors;
         delete FDragFakeMonitors;
         FDragFakeMonitors = NULL;
         FDragFakeMonitors = NULL;
@@ -6852,7 +6857,7 @@ bool __fastcall TCustomScpExplorerForm::DDGetTarget(
     CounterName = L"DownloadsDragDropQueue";
     CounterName = L"DownloadsDragDropQueue";
     ForceQueue = true;
     ForceQueue = true;
   }
   }
-  else if (IsUWP() && !FFakeFileDropTarget.IsEmpty())
+  else if (UseDirectoryMonitorDragDrop() && !FFakeFileDropTarget.IsEmpty())
   {
   {
     Directory = ExcludeTrailingBackslash(ExtractFilePath(FFakeFileDropTarget));
     Directory = ExcludeTrailingBackslash(ExtractFilePath(FFakeFileDropTarget));
     Result = true;
     Result = true;