Browse Source

ADD: FileIsReadOnly function

Alexander Koblov 1 year ago
parent
commit
7720dd970e
2 changed files with 141 additions and 0 deletions
  1. 110 0
      components/doublecmd/dclinux.pas
  2. 31 0
      components/doublecmd/dcosutils.pas

+ 110 - 0
components/doublecmd/dclinux.pas

@@ -0,0 +1,110 @@
+{
+  Double Commander
+  -------------------------------------------------------------------------
+  This unit contains Linux specific functions
+
+  Copyright (C) 2023 Alexander Koblov ([email protected])
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program. If not, see <https://www.gnu.org/licenses/>
+}
+
+unit DCLinux;
+
+{$mode objfpc}{$H+}
+{$packrecords c}
+
+interface
+
+uses
+  Classes, SysUtils, BaseUnix, Unix;
+
+const
+  FS_IOC_GETFLAGS = $80086601;
+  FS_IOC_SETFLAGS = $40086602;
+  (*
+   * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
+  *)
+  FS_SECRM_FL     = $00000001; //* Secure deletion */
+  FS_UNRM_FL      = $00000002; //* Undelete */
+  FS_COMPR_FL     = $00000004; //* Compress file */
+  FS_SYNC_FL      = $00000008; //* Synchronous updates */
+  FS_IMMUTABLE_FL = $00000010; //* Immutable file */
+  FS_APPEND_FL    = $00000020; //* Writes to file may only append */
+  FS_NODUMP_FL    = $00000040; //* Do not dump file */
+  FS_NOATIME_FL   = $00000080; //* Do not update atime */
+
+  FS_FL_USER_VISIBLE    = $0003DFFF; //* User visible flags */
+  FS_FL_USER_MODIFIABLE = $000380FF; //* User modifiable flags */
+
+type
+  TFlagName = record
+    Flag: UInt32;
+    Name: AnsiChar;
+  end;
+
+const
+  FlagsName: array[1..8] of TFlagName = (
+    (Flag: FS_SECRM_FL;        Name: 's'),
+    (Flag: FS_UNRM_FL;         Name: 'u'),
+    (Flag: FS_SYNC_FL;         Name: 'S'),
+    (Flag: FS_IMMUTABLE_FL;    Name: 'i'),
+    (Flag: FS_APPEND_FL;       Name: 'a'),
+    (Flag: FS_NODUMP_FL;       Name: 'd'),
+    (Flag: FS_NOATIME_FL;      Name: 'A'),
+    (Flag: FS_COMPR_FL;        Name: 'c')
+  );
+
+function FormatFileFlags(Flags: UInt32): String;
+function FileGetFlags(Handle: THandle; out Flags: UInt32): Boolean;
+function mbFileGetFlags(const FileName: String; out Flags: UInt32): Boolean;
+
+implementation
+
+uses
+  DCUnix, DCConvertEncoding, DCOSUtils;
+
+function FormatFileFlags(Flags: UInt32): String;
+var
+  Index: Integer;
+begin
+  Result:=StringOfChar('-', Length(FlagsName));
+  for Index:= 1 to High(FlagsName) do
+  begin
+    if Flags and FlagsName[Index].Flag <> 0 then
+    begin
+      Result[Index]:= FlagsName[Index].Name;
+    end;
+  end;
+end;
+
+function FileGetFlags(Handle: THandle; out Flags: UInt32): Boolean;
+begin
+  Result:= (FpIOCtl(Handle, FS_IOC_GETFLAGS, @Flags) >= 0);
+end;
+
+function mbFileGetFlags(const FileName: String; out Flags: UInt32): Boolean;
+var
+  Handle: THandle;
+begin
+  Handle:= mbFileOpen(FileName, fmOpenRead or fmShareDenyNone);
+  Result:= Handle <> feInvalidHandle;
+  if Result then
+  begin
+    Result:= (FpIOCtl(Handle, FS_IOC_GETFLAGS, @Flags) >= 0);
+    FileClose(Handle);
+  end;
+end;
+
+end.
+

+ 31 - 0
components/doublecmd/dcosutils.pas

@@ -31,6 +31,9 @@ uses
 {$IFDEF UNIX}
   , BaseUnix, DCUnix
 {$ENDIF}
+{$IFDEF LINUX}
+  , DCLinux
+{$ENDIF}
 {$IFDEF HAIKU}
   , DCHaiku
 {$ENDIF}
@@ -232,6 +235,7 @@ function mbFileSize(const FileName: String): Int64;
 function FileGetSize(Handle: System.THandle): Int64;
 function FileFlush(Handle: System.THandle): Boolean;
 function FileFlushData(Handle: System.THandle): Boolean;
+function FileIsReadOnly(Handle: System.THandle): Boolean;
 function FileAllocate(Handle: System.THandle; Size: Int64): Boolean;
 { Directory handling functions}
 function mbGetCurrentDir: String;
@@ -1404,6 +1408,33 @@ begin
 end;
 {$ENDIF}
 
+function FileIsReadOnly(Handle: System.THandle): Boolean;
+{$IF DEFINED(MSWINDOWS)}
+var
+  Info: BY_HANDLE_FILE_INFORMATION;
+begin
+  if GetFileInformationByHandle(Handle, Info) then
+    Result:= (Info.dwFileAttributes and (faReadOnly or faHidden or faSysFile) <> 0)
+  else
+    Result:= False;
+end;
+{$ELSEIF DEFINED(LINUX)}
+var
+  Flags: UInt32;
+begin
+  if FileGetFlags(Handle, Flags) then
+  begin
+    if (Flags and (FS_IMMUTABLE_FL or FS_APPEND_FL) <> 0) then
+      Exit(True);
+  end;
+  Result:= False;
+end;
+{$ELSE}
+begin
+  Result:= False;
+end;
+{$ENDIF}
+
 function FileAllocate(Handle: System.THandle; Size: Int64): Boolean;
 {$IF DEFINED(LINUX)}
 var