1
0
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:
Martin Prikryl
2020-09-09 16:01:30 +00:00
parent 4990b0dfdf
commit 1fbcd416d8
4 changed files with 65 additions and 20 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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);