mirror of
https://github.com/winscp/winscp.git
synced 2026-10-28 15:35:08 +03:00
When trying to open an inaccessible local directory, display an error message, instead of silently doing nothing
Source commit: 12da4e9bdee074951e9c4da15d445d15fe971221
This commit is contained in:
@@ -404,6 +404,7 @@ function DropFiles(
|
||||
RenameOnCollision: Boolean; IsRecycleBin: Boolean; ConfirmDelete: Boolean; ConfirmOverwrite: Boolean; Paste: Boolean;
|
||||
Sender: TObject; OnDDFileOperation: TDDFileOperationEvent;
|
||||
out SourcePath: string; out SourceIsDirectory: Boolean): Boolean;
|
||||
procedure CheckCanOpenDirectory(Path: string);
|
||||
|
||||
var
|
||||
LastClipBoardOperation: TClipBoardOperation;
|
||||
@@ -619,6 +620,24 @@ begin
|
||||
else Result := False;
|
||||
end; {GetShellDisplayName}
|
||||
|
||||
procedure CheckCanOpenDirectory(Path: string);
|
||||
var
|
||||
DosError: Integer;
|
||||
SRec: SysUtils.TSearchRec;
|
||||
begin
|
||||
if not DirectoryExistsFix(Path) then
|
||||
raise Exception.CreateFmt(SDirNotExists, [Path]);
|
||||
DosError := SysUtils.FindFirst(ApiPath(IncludeTrailingPathDelimiter(Path) + '*.*'), FileAttr, SRec);
|
||||
if DosError = 0 then
|
||||
begin
|
||||
FindClose(SRec);
|
||||
end
|
||||
else
|
||||
begin
|
||||
RaiseLastOSError;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TIconUpdateThread }
|
||||
|
||||
constructor TIconUpdateThread.Create(Owner: TDirView);
|
||||
@@ -934,9 +953,12 @@ begin
|
||||
// do checks before passing directory to drive view, because
|
||||
// it would truncate non-existing directory to first superior existing
|
||||
Value := ReplaceStr(Value, '/', '\');
|
||||
while ExcludeTrailingPathDelimiter(Value) <> Value do
|
||||
begin
|
||||
Value := ExcludeTrailingPathDelimiter(Value);
|
||||
end;
|
||||
|
||||
if not DirectoryExists(ApiPath(Value)) then
|
||||
raise Exception.CreateFmt(SDirNotExists, [Value]);
|
||||
CheckCanOpenDirectory(Value);
|
||||
|
||||
if Assigned(FDriveView) and
|
||||
(FDriveView.Directory <> Value) then
|
||||
@@ -946,8 +968,6 @@ begin
|
||||
else
|
||||
if FPath <> Value then
|
||||
try
|
||||
while (Length(Value) > 0) and (Value[Length(Value)] = '\') do
|
||||
SetLength(Value, Length(Value) - 1);
|
||||
PathChanging(not FNotRelative);
|
||||
FPath := Value;
|
||||
Load(True);
|
||||
@@ -2748,7 +2768,7 @@ begin
|
||||
if PFileRec(Item.Data)^.IsDirectory then
|
||||
begin
|
||||
FileName := ItemFullFileName(Item);
|
||||
if not DirectoryExists(FileName) then
|
||||
if not DirectoryExistsFix(FileName) then
|
||||
begin
|
||||
Reload2;
|
||||
if Assigned(FDriveView) and Assigned(FDriveView.Selected) then
|
||||
@@ -2760,13 +2780,13 @@ begin
|
||||
else
|
||||
FileName := ResolveFileShortCut(ItemFullFileName(Item), True);
|
||||
|
||||
if DirectoryExists(FileName) then
|
||||
if DirectoryExistsFix(FileName) then
|
||||
begin
|
||||
Path := FileName;
|
||||
Exit;
|
||||
end
|
||||
else
|
||||
if not FileExists(ApiPath(FileName)) then
|
||||
if not FileExistsFix(ApiPath(FileName)) then
|
||||
begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
@@ -1021,9 +1021,10 @@ begin
|
||||
Result := False;
|
||||
end
|
||||
else
|
||||
if not DirectoryExists(ApiPath(Path)) then
|
||||
begin
|
||||
MessageDlg(Format(SDirNotExists, [Path]), mtError, [mbOK], 0);
|
||||
try
|
||||
CheckCanOpenDirectory(Path);
|
||||
except
|
||||
Application.HandleException(Self);
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -79,6 +79,8 @@ procedure SetAppTerminated(Value: Boolean);
|
||||
procedure ForceColorChange(Control: TWinControl);
|
||||
|
||||
function IsUncPath(Path: string): Boolean;
|
||||
function FileExistsFix(Path: string): Boolean;
|
||||
function DirectoryExistsFix(Path: string): Boolean;
|
||||
|
||||
function SupportsDarkMode: Boolean;
|
||||
procedure AllowDarkModeForWindow(Control: TWinControl; Allow: Boolean); overload;
|
||||
@@ -990,6 +992,38 @@ begin
|
||||
Result := (Copy(Path, 1, 2) = '\\') or (Copy(Path, 1, 2) = '//');
|
||||
end;
|
||||
|
||||
const ERROR_CANT_ACCESS_FILE = 1920;
|
||||
|
||||
function DoExists(R: Boolean; Path: string): Boolean;
|
||||
var
|
||||
Error: Integer;
|
||||
begin
|
||||
Result := R;
|
||||
if not Result then
|
||||
begin
|
||||
Error := GetLastError();
|
||||
if (Error = ERROR_CANT_ACCESS_FILE) or // returned when resolving symlinks in %LOCALAPPDATA%\Microsoft\WindowsApps
|
||||
(Error = ERROR_ACCESS_DENIED) then // returned for %USERPROFILE%\Application Data symlink
|
||||
begin
|
||||
Result := DirectoryExists(ApiPath(ExtractFileDir(Path)));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function FileExistsFix(Path: string): Boolean;
|
||||
begin
|
||||
// WORKAROUND
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
Result := DoExists(FileExists(ApiPath(Path)), Path);
|
||||
end;
|
||||
|
||||
function DirectoryExistsFix(Path: string): Boolean;
|
||||
begin
|
||||
// WORKAROUND
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
Result := DoExists(DirectoryExists(ApiPath(Path)), Path);
|
||||
end;
|
||||
|
||||
type TPreferredAppMode = (pamDefault, pamAllowDark, pamForceDark, pamForceLight, pamMax);
|
||||
|
||||
var
|
||||
|
||||
@@ -40,16 +40,6 @@
|
||||
extern const UnicodeString PageantTool = L"pageant.exe";
|
||||
extern const UnicodeString PuttygenTool = L"puttygen.exe";
|
||||
//---------------------------------------------------------------------------
|
||||
static bool __fastcall FileExistsFix(const UnicodeString & Path)
|
||||
{
|
||||
// WORKAROUND
|
||||
::SetLastError(ERROR_SUCCESS);
|
||||
return
|
||||
FileExists(ApiPath(Path)) ||
|
||||
// returned when resolving symlinks in %LOCALAPPDATA%\Microsoft\WindowsApps
|
||||
(GetLastError() == ERROR_CANT_ACCESS_FILE);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall FindFile(UnicodeString & Path)
|
||||
{
|
||||
bool Result = FileExistsFix(Path);
|
||||
|
||||
Reference in New Issue
Block a user