mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
In UWP, files can be downloaded directly to an external drop location even without a loaded drag&drop shell extension.
Part of "Make WinSCP available in Windows Store (UWP/AppX package)" https://winscp.net/tracker/1639 (UWP-only subset of dev branch commitdc85563) Counters DownloadsDragDropQueue + DownloadsDragDropFakeFile (cherry picked from commitdc855630a2) # Conflicts: # source/resource/TextsWin.h # source/resource/TextsWin1.rc # translations/translate.web.ini Source commit: 5c7069bac3e08f2f19c227d38eaffe989e73f4f8
This commit is contained in:
@@ -96,7 +96,10 @@
|
||||
<BuildOrder>3</BuildOrder>
|
||||
</DelphiCompile>
|
||||
<DelphiCompile Include="packages\my\CompThread.pas">
|
||||
<BuildOrder>4</BuildOrder>
|
||||
<BuildOrder>22</BuildOrder>
|
||||
</DelphiCompile>
|
||||
<DelphiCompile Include="packages\my\DirectoryMonitor.pas">
|
||||
<BuildOrder>23</BuildOrder>
|
||||
</DelphiCompile>
|
||||
<ResFiles Include="packages\my\DiscMon.dcr">
|
||||
<BuildOrder>6</BuildOrder>
|
||||
|
||||
@@ -208,7 +208,7 @@ DllMain(HINSTANCE HInstance, DWORD Reason, LPVOID /*Reserved*/)
|
||||
|
||||
if (GRefThisDll == 0)
|
||||
{
|
||||
GLogMutex = CreateMutex(NULL, false, L"WinSCPDragExtLogMutex");
|
||||
GLogMutex = CreateMutex(NULL, false, DRAG_EXT_RUNNING_MUTEX);
|
||||
|
||||
for (int Root = 0; Root <= 1; Root++)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#define DRAG_EXT_MAPPING L"WinSCPDragExtMapping"
|
||||
#define DRAG_EXT_MUTEX L"WinSCPDragExtMutex"
|
||||
#define DRAG_EXT_RUNNING_MUTEX L"WinSCPDragExtLogMutex"
|
||||
#define DRAG_EXT_DUMMY_DIR_PREFIX L"scp"
|
||||
#define DRAG_EXT_DUMMY_DIR_PREFIX_LEN 3
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <Consts.hpp>
|
||||
#include <DateUtils.hpp>
|
||||
#include <TB2Common.hpp>
|
||||
#include <DirectoryMonitor.hpp>
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
#pragma link "CustomDirView"
|
||||
@@ -6583,7 +6584,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDCreateDragFileList(
|
||||
|
||||
if (WinConfiguration->DDExtEnabled)
|
||||
{
|
||||
if (!WinConfiguration->DDExtInstalled)
|
||||
if (!IsUWP() && !WinConfiguration->DDExtInstalled)
|
||||
{
|
||||
Configuration->Usage->Inc(L"DownloadsDragDropExternalExtNotInstalled");
|
||||
throw ExtException(NULL, LoadStr(DRAGEXT_TARGET_NOT_INSTALLED2), HELP_DRAGEXT_TARGET_NOT_INSTALLED);
|
||||
@@ -6592,19 +6593,61 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDCreateDragFileList(
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::DDFakeCreated(TObject * /*Sender*/, const UnicodeString FileName)
|
||||
{
|
||||
if (DebugAlwaysTrue(!FDragExtFakeDirectory.IsEmpty()) &&
|
||||
SameText(ExtractFileName(FileName), ExtractFileName(FDragExtFakeDirectory)))
|
||||
{
|
||||
FFakeFileDropTarget = FileName;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::DDExtInitDrag(TFileList * FileList,
|
||||
bool & Created)
|
||||
{
|
||||
FFakeFileDropTarget = UnicodeString();
|
||||
FDragExtFakeDirectory =
|
||||
ExcludeTrailingBackslash(WinConfiguration->TemporaryDir());
|
||||
if (!ForceDirectories(ApiPath(FDragExtFakeDirectory)))
|
||||
{
|
||||
throw Exception(FMTLOAD(CREATE_TEMP_DIR_ERROR, (FDragExtFakeDirectory)));
|
||||
}
|
||||
if (IsUWP())
|
||||
{
|
||||
FileSetAttr(ApiPath(FDragExtFakeDirectory), faHidden);
|
||||
}
|
||||
FileList->AddItem(NULL, FDragExtFakeDirectory);
|
||||
|
||||
Created = true;
|
||||
|
||||
if (IsUWP() && !WinConfiguration->IsDDExtRunning())
|
||||
{
|
||||
FDragFakeMonitors = new TObjectList();
|
||||
for (char Drive = FirstDrive; Drive <= LastDrive; Drive++)
|
||||
{
|
||||
std::unique_ptr<TDirectoryMonitor> Monitor(new TDirectoryMonitor(this));
|
||||
DriveInfo->ReadDriveStatus(Drive, dsSize | dsImageIndex);
|
||||
TDriveInfoRec * DriveInfoRec = DriveInfo->Data[Drive];
|
||||
if (DriveInfoRec->Valid &&
|
||||
(DriveInfoRec->DriveType != DRIVE_CDROM))
|
||||
{
|
||||
try
|
||||
{
|
||||
Monitor->Path = UnicodeString(Drive) + L":\\";
|
||||
Monitor->WatchSubtree = true;
|
||||
Monitor->WatchFilters = FILE_NOTIFY_CHANGE_DIR_NAME;
|
||||
Monitor->OnCreated = DDFakeCreated;
|
||||
Monitor->Active = true;
|
||||
FDragFakeMonitors->Add(Monitor.release());
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
// Ignore errors watching not-ready drives
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FDDExtMapFile = CreateFileMappingA((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE,
|
||||
0, sizeof(TDragExtCommStruct), AnsiString(DRAG_EXT_MAPPING).c_str());
|
||||
|
||||
@@ -6669,6 +6712,11 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
|
||||
// Drops of local files (uploads) are handled in QueueDDProcessDropped.
|
||||
SAFE_DESTROY(FDDFileList);
|
||||
|
||||
if (IsUWP() && !FFakeFileDropTarget.IsEmpty())
|
||||
{
|
||||
RemoveDir(ApiPath(FFakeFileDropTarget));
|
||||
}
|
||||
|
||||
if ((FDDExtMapFile != NULL) || (FDDTargetControl == QueueView3))
|
||||
{
|
||||
try
|
||||
@@ -6712,9 +6760,9 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
|
||||
}
|
||||
|
||||
TTransferOperationParam Param;
|
||||
bool Internal;
|
||||
UnicodeString CounterName;
|
||||
bool ForceQueue;
|
||||
if (!DDGetTarget(Param.TargetDirectory, ForceQueue, Internal))
|
||||
if (!DDGetTarget(Param.TargetDirectory, ForceQueue, CounterName))
|
||||
{
|
||||
// we get drInvalid both if d&d was intercepted by ddext,
|
||||
// and when users drops on no-drop location.
|
||||
@@ -6731,7 +6779,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
|
||||
}
|
||||
else
|
||||
{
|
||||
// download using ddext
|
||||
// download using fake file
|
||||
Param.Temp = false;
|
||||
Param.DragDrop = true;
|
||||
if (ForceQueue)
|
||||
@@ -6746,8 +6794,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
|
||||
if (RemoteFileControlFileOperation(Sender, Operation,
|
||||
(WinConfiguration->DDTransferConfirmation == asOff), &Param))
|
||||
{
|
||||
Configuration->Usage->Inc(
|
||||
Internal ? L"DownloadsDragDropInternal" : L"DownloadsDragDropExternalExt");
|
||||
Configuration->Usage->Inc(CounterName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6756,8 +6803,14 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
|
||||
{
|
||||
CloseHandle(FDDExtMapFile);
|
||||
FDDExtMapFile = NULL;
|
||||
if (IsUWP())
|
||||
{
|
||||
delete FDragFakeMonitors;
|
||||
FDragFakeMonitors = NULL;
|
||||
}
|
||||
RemoveDir(ApiPath(FDragExtFakeDirectory));
|
||||
FDragExtFakeDirectory = L"";
|
||||
FFakeFileDropTarget = UnicodeString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6789,16 +6842,23 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDGiveFeedback(
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCustomScpExplorerForm::DDGetTarget(
|
||||
UnicodeString & Directory, bool & ForceQueue, bool & Internal)
|
||||
UnicodeString & Directory, bool & ForceQueue, UnicodeString & CounterName)
|
||||
{
|
||||
bool Result;
|
||||
if (FDDTargetControl == QueueView3)
|
||||
{
|
||||
Directory = DefaultDownloadTargetDirectory();
|
||||
Result = true;
|
||||
Internal = true;
|
||||
CounterName = L"DownloadsDragDropQueue";
|
||||
ForceQueue = true;
|
||||
}
|
||||
else if (IsUWP() && !FFakeFileDropTarget.IsEmpty())
|
||||
{
|
||||
Directory = ExcludeTrailingBackslash(ExtractFilePath(FFakeFileDropTarget));
|
||||
Result = true;
|
||||
ForceQueue = false;
|
||||
CounterName = L"DownloadsDragDropFakeFile";
|
||||
}
|
||||
else
|
||||
{
|
||||
ForceQueue = false;
|
||||
@@ -6820,7 +6880,7 @@ bool __fastcall TCustomScpExplorerForm::DDGetTarget(
|
||||
if (Result)
|
||||
{
|
||||
Directory = ExtractFilePath(CommStruct->DropDest);
|
||||
Internal = false;
|
||||
CounterName = L"DownloadsDragDropExternalExt";
|
||||
}
|
||||
UnmapViewOfFile(CommStruct);
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ private:
|
||||
TStringList * FErrorList;
|
||||
HANDLE FDDExtMutex;
|
||||
UnicodeString FDragExtFakeDirectory;
|
||||
TObjectList * FDragFakeMonitors;
|
||||
TStrings * FDelayedDeletionList;
|
||||
TTimer * FDelayedDeletionTimer;
|
||||
TStrings * FDDFileList;
|
||||
@@ -327,6 +328,7 @@ protected:
|
||||
TPoint FLastContextPopupScreenPoint;
|
||||
bool FRemoteDirViewWasFocused;
|
||||
bool FDoNotIdleCurrentTerminal;
|
||||
UnicodeString FFakeFileDropTarget;
|
||||
|
||||
virtual bool __fastcall CopyParamDialog(TTransferDirection Direction,
|
||||
TTransferType Type, bool Temp, TStrings * FileList,
|
||||
@@ -419,8 +421,9 @@ protected:
|
||||
bool __fastcall ExecuteFileOperation(TFileOperation Operation, TOperationSide Side,
|
||||
TStrings * FileList, bool NoConfirmation, void * Param);
|
||||
virtual bool __fastcall DDGetTarget(UnicodeString & Directory,
|
||||
bool & ForceQueue, bool & Internal);
|
||||
bool & ForceQueue, UnicodeString & CounterName);
|
||||
virtual void __fastcall DDExtInitDrag(TFileList * FileList, bool & Created);
|
||||
void __fastcall DDFakeCreated(TObject * Sender, const UnicodeString FileName);
|
||||
virtual void __fastcall SideEnter(TOperationSide Side);
|
||||
virtual TOperationSide __fastcall GetSide(TOperationSide Side);
|
||||
TStrings * __fastcall PanelExport(TOperationSide Side, TPanelExport Export);
|
||||
|
||||
@@ -1214,8 +1214,8 @@ void __fastcall TPreferencesDialog::UpdateControls()
|
||||
}
|
||||
SetLabelHintPopup(CopyParamLabel, InfoStr);
|
||||
|
||||
EnableControl(DDExtEnabledButton, WinConfiguration->DDExtInstalled);
|
||||
EnableControl(DDExtEnabledLabel, WinConfiguration->DDExtInstalled);
|
||||
EnableControl(DDExtEnabledButton, IsUWP() || WinConfiguration->DDExtInstalled);
|
||||
EnableControl(DDExtEnabledLabel, DDExtEnabledButton->Enabled);
|
||||
EnableControl(DDExtDisabledPanel, DDExtDisabledButton->Checked);
|
||||
EnableControl(DDTemporaryDirectoryEdit, DDCustomTemporaryDirectoryButton->Enabled &&
|
||||
DDCustomTemporaryDirectoryButton->Checked);
|
||||
|
||||
@@ -1343,7 +1343,7 @@ object PreferencesDialog: TPreferencesDialog
|
||||
Width = 364
|
||||
Height = 17
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
Caption = 'Use &shell extension'
|
||||
Caption = 'Determine drop target by dragging a &fake file'
|
||||
TabOrder = 1
|
||||
OnClick = ControlChange
|
||||
end
|
||||
@@ -1353,7 +1353,7 @@ object PreferencesDialog: TPreferencesDialog
|
||||
Width = 356
|
||||
Height = 17
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
Caption = 'Use &temporary folder'
|
||||
Caption = 'Download files via &temporary folder'
|
||||
TabOrder = 2
|
||||
OnClick = ControlChange
|
||||
end
|
||||
|
||||
@@ -1449,7 +1449,7 @@ void __fastcall TScpCommanderForm::LocalFileControlDDDragOver(TObject * /*Sender
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TScpCommanderForm::DDGetTarget(
|
||||
UnicodeString & Directory, bool & ForceQueue, bool & Internal)
|
||||
UnicodeString & Directory, bool & ForceQueue, UnicodeString & CounterName)
|
||||
{
|
||||
bool Result;
|
||||
if (!FDDExtTarget.IsEmpty())
|
||||
@@ -1457,12 +1457,12 @@ bool __fastcall TScpCommanderForm::DDGetTarget(
|
||||
Directory = FDDExtTarget;
|
||||
FDDExtTarget = L"";
|
||||
Result = true;
|
||||
Internal = true;
|
||||
CounterName = L"DownloadsDragDropInternal";
|
||||
ForceQueue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = TCustomScpExplorerForm::DDGetTarget(Directory, ForceQueue, Internal);
|
||||
Result = TCustomScpExplorerForm::DDGetTarget(Directory, ForceQueue, CounterName);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -536,7 +536,7 @@ protected:
|
||||
TOperationSide Side);
|
||||
bool __fastcall InternalDDDownload(UnicodeString & TargetDirectory);
|
||||
virtual bool __fastcall DDGetTarget(
|
||||
UnicodeString & Directory, bool & ForceQueue, bool & Internal);
|
||||
UnicodeString & Directory, bool & ForceQueue, UnicodeString & CounterName);
|
||||
virtual void __fastcall DDExtInitDrag(TFileList * FileList, bool & Created);
|
||||
virtual void __fastcall SideEnter(TOperationSide Side);
|
||||
void __fastcall SaveCommandLine();
|
||||
|
||||
@@ -493,6 +493,7 @@ void __fastcall TWinConfiguration::Default()
|
||||
FDDWarnLackOfTempSpace = true;
|
||||
FDDWarnLackOfTempSpaceRatio = 1.1;
|
||||
FDDExtEnabled = DDExtInstalled;
|
||||
FDDFakeFile = true;
|
||||
FDDExtTimeout = MSecsPerSec;
|
||||
FDeleteToRecycleBin = true;
|
||||
FSelectDirectories = false;
|
||||
@@ -915,6 +916,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool & SessionList)
|
||||
KEY(Bool, UseSharedBookmarks); \
|
||||
KEY(Integer, LocaleSafe); \
|
||||
KEY(Bool, DDExtEnabled); \
|
||||
KEY(Bool, DDFakeFile); \
|
||||
KEY(Integer, DDExtTimeout); \
|
||||
KEY(Bool, DefaultDirIsHome); \
|
||||
KEY(Bool, TemporaryDirectoryAppendSession); \
|
||||
@@ -1605,6 +1607,23 @@ bool __fastcall TWinConfiguration::GetDDExtInstalled()
|
||||
return (FDDExtInstalled > 0);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TWinConfiguration::IsDDExtRunning()
|
||||
{
|
||||
bool Result;
|
||||
if (!DDExtInstalled)
|
||||
{
|
||||
Result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
HANDLE H = OpenMutex(SYNCHRONIZE, False, DRAG_EXT_RUNNING_MUTEX);
|
||||
Result = (H != NULL);
|
||||
CloseHandle(H);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
RawByteString __fastcall TWinConfiguration::StronglyRecryptPassword(RawByteString Password, UnicodeString Key)
|
||||
{
|
||||
RawByteString Dummy;
|
||||
@@ -1799,9 +1818,28 @@ void __fastcall TWinConfiguration::SetDDTemporaryDirectory(UnicodeString value)
|
||||
SET_CONFIG_PROPERTY(DDTemporaryDirectory);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TWinConfiguration::GetDDExtEnabled()
|
||||
{
|
||||
if (IsUWP())
|
||||
{
|
||||
return FDDFakeFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FDDExtEnabled;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::SetDDExtEnabled(bool value)
|
||||
{
|
||||
SET_CONFIG_PROPERTY(DDExtEnabled);
|
||||
if (IsUWP())
|
||||
{
|
||||
SET_CONFIG_PROPERTY(DDFakeFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_CONFIG_PROPERTY(DDExtEnabled);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::SetDDExtTimeout(int value)
|
||||
|
||||
@@ -355,6 +355,7 @@ private:
|
||||
UnicodeString FDDTemporaryDirectory;
|
||||
bool FDDWarnLackOfTempSpace;
|
||||
bool FDDExtEnabled;
|
||||
bool FDDFakeFile;
|
||||
int FDDExtInstalled;
|
||||
int FDDExtTimeout;
|
||||
bool FConfirmClosingSession;
|
||||
@@ -464,6 +465,7 @@ private:
|
||||
void __fastcall SetDDTemporaryDirectory(UnicodeString value);
|
||||
void __fastcall SetDDWarnLackOfTempSpace(bool value);
|
||||
void __fastcall SetDDExtEnabled(bool value);
|
||||
bool __fastcall GetDDExtEnabled();
|
||||
void __fastcall SetDDExtTimeout(int value);
|
||||
void __fastcall SetConfirmClosingSession(bool value);
|
||||
void __fastcall SetDDWarnLackOfTempSpaceRatio(double value);
|
||||
@@ -577,6 +579,8 @@ protected:
|
||||
void __fastcall ReleaseExtensionTranslations();
|
||||
void __fastcall LoadExtensionTranslations();
|
||||
|
||||
__property bool DDFakeFile = { read=FDDFakeFile, write=FDDFakeFile };
|
||||
|
||||
public:
|
||||
__fastcall TWinConfiguration();
|
||||
virtual __fastcall ~TWinConfiguration();
|
||||
@@ -612,6 +616,7 @@ public:
|
||||
UnicodeString __fastcall ExtensionStringTranslation(const UnicodeString & ExtensionId, const UnicodeString & S);
|
||||
UnicodeString __fastcall UniqueExtensionName(const UnicodeString & ExtensionName, int Counter);
|
||||
UnicodeString __fastcall GetProvisionaryExtensionId(const UnicodeString & FileName);
|
||||
bool __fastcall IsDDExtRunning();
|
||||
|
||||
static void __fastcall RestoreFont(const TFontConfiguration & Configuration, TFont * Font);
|
||||
static void __fastcall StoreFont(TFont * Font, TFontConfiguration & Configuration);
|
||||
@@ -646,7 +651,7 @@ public:
|
||||
__property bool UseSharedBookmarks = { read = FUseSharedBookmarks, write = SetUseSharedBookmarks};
|
||||
__property UnicodeString DDTemporaryDirectory = { read=FDDTemporaryDirectory, write=SetDDTemporaryDirectory };
|
||||
__property bool DDWarnLackOfTempSpace = { read=FDDWarnLackOfTempSpace, write=SetDDWarnLackOfTempSpace };
|
||||
__property bool DDExtEnabled = { read=FDDExtEnabled, write=SetDDExtEnabled };
|
||||
__property bool DDExtEnabled = { read=GetDDExtEnabled, write=SetDDExtEnabled };
|
||||
__property bool DDExtInstalled = { read=GetDDExtInstalled };
|
||||
__property int DDExtTimeout = { read=FDDExtTimeout, write=SetDDExtTimeout };
|
||||
__property bool ConfirmClosingSession = { read=FConfirmClosingSession, write=SetConfirmClosingSession };
|
||||
|
||||
Reference in New Issue
Block a user