Browse Source

--- Merging r18220 into '.':
U rtl/go32v2/sysutils.pp
--- Merging r18843 into '.':
U rtl/emx/sysutils.pp
U rtl/os2/sysutils.pp
--- Merging r18846 into '.':
G rtl/go32v2/sysutils.pp
G rtl/emx/sysutils.pp
G rtl/os2/sysutils.pp
--- Merging r18885 into '.':
U rtl/watcom/sysutils.pp

# revisions: 18220,18843,18846,18885
------------------------------------------------------------------------
r18220 | pierre | 2011-08-16 17:01:20 +0200 (Tue, 16 Aug 2011) | 1 line
Changed paths:
M /trunk/rtl/go32v2/sysutils.pp

* Handle -1 return if GetFileAttr call inside DirectoryExists
------------------------------------------------------------------------
------------------------------------------------------------------------
r18843 | hajny | 2011-08-25 23:17:30 +0200 (Thu, 25 Aug 2011) | 1 line
Changed paths:
M /trunk/rtl/emx/sysutils.pp
M /trunk/rtl/os2/sysutils.pp

* FindFirst enhanced for file sizes >2 GB
------------------------------------------------------------------------
------------------------------------------------------------------------
r18846 | hajny | 2011-08-25 23:34:44 +0200 (Thu, 25 Aug 2011) | 1 line
Changed paths:
M /trunk/rtl/emx/sysutils.pp
M /trunk/rtl/go32v2/sysutils.pp
M /trunk/rtl/os2/sysutils.pp

* FileExists fixed - wildcards not accepted any longer
------------------------------------------------------------------------
------------------------------------------------------------------------
r18885 | hajny | 2011-08-29 00:22:29 +0200 (Mon, 29 Aug 2011) | 1 line
Changed paths:
M /trunk/rtl/watcom/sysutils.pp

* fixes for FileExists and DirectoryExists
------------------------------------------------------------------------

git-svn-id: branches/fixes_2_6@18955 -

marco 14 years ago
parent
commit
20a87e93d0
4 changed files with 287 additions and 155 deletions
  1. 181 92
      rtl/emx/sysutils.pp
  2. 11 13
      rtl/go32v2/sysutils.pp
  3. 74 30
      rtl/os2/sysutils.pp
  4. 21 20
      rtl/watcom/sysutils.pp

+ 181 - 92
rtl/emx/sysutils.pp

@@ -73,6 +73,25 @@ type
         end;
         PFileStatus4=^TFileStatus4;
 
+        TFileStatus3L = object (TFileStatus)
+            DateCreation,               {Date of file creation.}
+            TimeCreation,               {Time of file creation.}
+            DateLastAccess,             {Date of last access to file.}
+            TimeLastAccess,             {Time of last access to file.}
+            DateLastWrite,              {Date of last modification of file.}
+            TimeLastWrite:word;         {Time of last modification of file.}
+            FileSize,                   {Size of file.}
+            FileAlloc:int64;         {Amount of space the file really
+                                         occupies on disk.}
+            AttrFile:cardinal;          {Attributes of file.}
+        end;
+        PFileStatus3L=^TFileStatus3L;
+
+        TFileStatus4L=object(TFileStatus3L)
+            cbList:cardinal;            {Length of entire EA set.}
+        end;
+        PFileStatus4L=^TFileStatus4L;
+
         TFileFindBuf3=object(TFileStatus)
             NextEntryOffset: cardinal;  {Offset of next entry}
             DateCreation,               {Date of file creation.}
@@ -110,6 +129,43 @@ type
         end;
         PFileFindBuf4=^TFileFindBuf4;
 
+        TFileFindBuf3L=object(TFileStatus)
+            NextEntryOffset: cardinal;  {Offset of next entry}
+            DateCreation,               {Date of file creation.}
+            TimeCreation,               {Time of file creation.}
+            DateLastAccess,             {Date of last access to file.}
+            TimeLastAccess,             {Time of last access to file.}
+            DateLastWrite,              {Date of last modification of file.}
+            TimeLastWrite:word;         {Time of last modification of file.}
+            FileSize,                   {Size of file.}
+            FileAlloc:int64;            {Amount of space the file really
+                                         occupies on disk.}
+            AttrFile:cardinal;          {Attributes of file.}
+            Name:shortstring;           {Also possible to use as ASCIIZ.
+                                         The byte following the last string
+                                         character is always zero.}
+        end;
+        PFileFindBuf3L=^TFileFindBuf3L;
+
+        TFileFindBuf4L=object(TFileStatus)
+            NextEntryOffset: cardinal;  {Offset of next entry}
+            DateCreation,               {Date of file creation.}
+            TimeCreation,               {Time of file creation.}
+            DateLastAccess,             {Date of last access to file.}
+            TimeLastAccess,             {Time of last access to file.}
+            DateLastWrite,              {Date of last modification of file.}
+            TimeLastWrite:word;         {Time of last modification of file.}
+            FileSize,                   {Size of file.}
+            FileAlloc:int64;            {Amount of space the file really
+                                         occupies on disk.}
+            AttrFile:cardinal;          {Attributes of file.}
+            cbList:cardinal;            {Size of the file's extended attributes.}
+            Name:shortstring;           {Also possible to use as ASCIIZ.
+                                         The byte following the last string
+                                         character is always zero.}
+        end;
+        PFileFindBuf4L=^TFileFindBuf4L;
+
  TFSInfo = record
             case word of
              1:
@@ -246,10 +302,13 @@ type
  PStartData=^TStartData;
 
 const
- ilStandard      = 1;
- ilQueryEAsize   = 2;
- ilQueryEAs      = 3;
- ilQueryFullName = 5;
+ ilStandard      =  1; (* Use TFileStatus3/TFindFileBuf3 *)
+ ilQueryEASize   =  2; (* Use TFileStatus4/TFindFileBuf4 *)
+ ilQueryEAs      =  3;
+ ilQueryFullName =  5;
+ ilStandardL     = 11; (* Use TFileStatus3L/TFindFileBuf3L *)
+ ilQueryEASizeL  = 12; (* Use TFileStatus4L/TFindFileBuf4L *)
+ ilQueryEAsL     = 13;
 
  quFIFO     = 0;
  quLIFO     = 1;
@@ -580,112 +639,142 @@ end;
 
 function FileExists (const FileName: string): boolean;
 begin
-  if Directory = '' then
+  if FileName = '' then
    Result := false
   else
-   Result := FileGetAttr (ExpandFileName (Directory)) and
-                                                     faDirectory = faDirectory;
+   Result := FileGetAttr (ExpandFileName (FileName)) and
+                                               (faDirectory or faVolumeID) = 0;
+(* Neither VolumeIDs nor directories are files. *)
 end;
 
 
-type    TRec = record
-            T, D: word;
-        end;
-        PSearchRec = ^SearchRec;
+type
+  TRec = record
+   T, D: word;
+  end;
+  PSearchRec = ^SearchRec;
 
 function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint;
 
-var SR: PSearchRec;
-    FStat: PFileFindBuf3;
-    Count: cardinal;
-    Err: cardinal;
+var
+  SR: PSearchRec;
+  FStat: PFileFindBuf3L;
+  Count: cardinal;
+  Err: cardinal;
 
 begin
-    if os_mode = osOS2 then
-        begin
-            New (FStat);
-            Rslt.FindHandle := THandle ($FFFFFFFF);
-            Count := 1;
-            Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
-                   Attr and FindResvdMask, FStat, SizeOf (FStat^), Count,
-                                                                   ilStandard);
-            if (Err = 0) and (Count = 0) then Err := 18;
-            FindFirst := -Err;
-            if Err = 0 then
-                begin
-                    Rslt.Name := FStat^.Name;
-                    Rslt.Size := FStat^.FileSize;
-                    Rslt.Attr := FStat^.AttrFile;
-                    Rslt.ExcludeAttr := 0;
-                    TRec (Rslt.Time).T := FStat^.TimeLastWrite;
-                    TRec (Rslt.Time).D := FStat^.DateLastWrite;
-                end;
-            Dispose (FStat);
-        end
+  if os_mode = osOS2 then
+   begin
+    New (FStat);
+    Rslt.FindHandle := THandle ($FFFFFFFF);
+    Count := 1;
+    if FSApi64 then
+     Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
+            Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandardL)
     else
-        begin
-            Err := DOS.DosError;
-            GetMem (SR, SizeOf (SearchRec));
-            Rslt.FindHandle := longint(SR);
-            DOS.FindFirst (Path, Attr, SR^);
-            FindFirst := -DOS.DosError;
-            if DosError = 0 then
-                begin
-                    Rslt.Time := SR^.Time;
-                    Rslt.Size := SR^.Size;
-                    Rslt.Attr := SR^.Attr;
-                    Rslt.ExcludeAttr := 0;
-                    Rslt.Name := SR^.Name;
-                end;
-            DOS.DosError := Err;
-        end;
+     Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
+            Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandard);
+    if (Err = 0) and (Count = 0) then
+     Err := 18;
+    FindFirst := -Err;
+    if Err = 0 then
+     begin
+      Rslt.ExcludeAttr := 0;
+      TRec (Rslt.Time).T := FStat^.TimeLastWrite;
+      TRec (Rslt.Time).D := FStat^.DateLastWrite;
+      if FSApi64 then
+       begin
+        Rslt.Size := FStat^.FileSize;
+        Rslt.Name := FStat^.Name;
+        Rslt.Attr := FStat^.AttrFile;
+       end
+      else
+       begin
+        Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
+        Rslt.Name := PFileFindBuf3 (FStat)^.Name;
+        Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
+       end;
+     end
+    else
+     FindClose (Rslt);
+    Dispose (FStat);
+   end
+  else
+   begin
+    Err := DOS.DosError;
+    GetMem (SR, SizeOf (SearchRec));
+    Rslt.FindHandle := longint(SR);
+    DOS.FindFirst (Path, Attr, SR^);
+    FindFirst := -DOS.DosError;
+    if DosError = 0 then
+     begin
+      Rslt.Time := SR^.Time;
+(* Extend the supported file sizes from 2 GB to 4 GB at least. *)
+      Rslt.Size := cardinal (SR^.Size);
+      Rslt.Attr := SR^.Attr;
+      Rslt.ExcludeAttr := 0;
+      Rslt.Name := SR^.Name;
+     end;
+    DOS.DosError := Err;
+   end;
 end;
 
 
 function FindNext (var Rslt: TSearchRec): longint;
 
-var SR: PSearchRec;
-    FStat: PFileFindBuf3;
-    Count: cardinal;
-    Err: cardinal;
+var
+  SR: PSearchRec;
+  FStat: PFileFindBuf3L;
+  Count: cardinal;
+  Err: cardinal;
 
 begin
-    if os_mode = osOS2 then
-        begin
-            New (FStat);
-            Count := 1;
-            Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^),
-                                                                        Count);
-            if (Err = 0) and (Count = 0) then Err := 18;
-            FindNext := -Err;
-            if Err = 0 then
-                begin
-                    Rslt.Name := FStat^.Name;
-                    Rslt.Size := FStat^.FileSize;
-                    Rslt.Attr := FStat^.AttrFile;
-                    Rslt.ExcludeAttr := 0;
-                    TRec (Rslt.Time).T := FStat^.TimeLastWrite;
-                    TRec (Rslt.Time).D := FStat^.DateLastWrite;
-                end;
-            Dispose (FStat);
-        end
-    else
-        begin
-            SR := PSearchRec (Rslt.FindHandle);
-            if SR <> nil then
-                begin
-                    DOS.FindNext (SR^);
-                    FindNext := -DosError;
-                    if DosError = 0 then
-                        begin
-                            Rslt.Time := SR^.Time;
-                            Rslt.Size := SR^.Size;
-                            Rslt.Attr := SR^.Attr;
-                            Rslt.ExcludeAttr := 0;
-                            Rslt.Name := SR^.Name;
-                        end;
-                end;
-        end;
+  if os_mode = osOS2 then
+   begin
+    New (FStat);
+    Count := 1;
+    Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^), Count);
+    if (Err = 0) and (Count = 0) then
+     Err := 18;
+    FindNext := -Err;
+    if Err = 0 then
+     begin
+      Rslt.ExcludeAttr := 0;
+      TRec (Rslt.Time).T := FStat^.TimeLastWrite;
+      TRec (Rslt.Time).D := FStat^.DateLastWrite;
+      if FSApi64 then
+       begin
+        Rslt.Size := FStat^.FileSize;
+        Rslt.Name := FStat^.Name;
+        Rslt.Attr := FStat^.AttrFile;
+       end
+      else
+       begin
+        Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
+        Rslt.Name := PFileFindBuf3 (FStat)^.Name;
+        Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
+       end;
+     end;
+    Dispose (FStat);
+   end
+  else
+   begin
+    SR := PSearchRec (Rslt.FindHandle);
+    if SR <> nil then
+     begin
+      DOS.FindNext (SR^);
+      FindNext := -DosError;
+      if DosError = 0 then
+       begin
+        Rslt.Time := SR^.Time;
+(* Extend the supported file sizes from 2 GB to 4 GB at least. *)
+        Rslt.Size := cardinal (SR^.Size);
+        Rslt.Attr := SR^.Attr;
+        Rslt.ExcludeAttr := 0;
+        Rslt.Name := SR^.Name;
+       end;
+     end;
+   end;
 end;
 
 

+ 11 - 13
rtl/go32v2/sysutils.pp

@@ -285,18 +285,13 @@ end;
 
 
 Function FileExists (Const FileName : String) : Boolean;
-Var
-  Sr : Searchrec;
 begin
-  DOS.FindFirst(FileName,$3f,sr);
-  if DosError = 0 then
-   begin
-     { No volumeid,directory }
-     Result:=(sr.attr and $18)=0;
-     Dos.FindClose(sr);
-   end
+  if FileName = '' then
+   Result := false
   else
-   Result:=false;
+   Result := FileGetAttr (ExpandFileName (FileName)) and
+                                               (faDirectory or faVolumeID) = 0;
+(* Neither VolumeIDs nor directories are files. *)
 end;
 
 
@@ -304,7 +299,7 @@ Function DirectoryExists (Const Directory : String) : Boolean;
 Var
   Dir : String;
   drive : byte;
-  StoredIORes : longint;
+  FADir, StoredIORes : longint;
 begin
   Dir:=Directory;
   if (length(dir)=2) and (dir[2]=':') and
@@ -335,11 +330,14 @@ begin
 {$endif}
   if (Length (Dir) > 1) and
     (Dir [Length (Dir)] in AllowDirectorySeparators) and
-(* Do not remove '\' after ':' (root directory of a drive) 
+(* Do not remove '\' after ':' (root directory of a drive)
    or in '\\' (invalid path, possibly broken UNC path). *)
      not (Dir [Length (Dir) - 1] in (AllowDriveSeparators + AllowDirectorySeparators)) then
     dir:=copy(dir,1,length(dir)-1);
-  Result := FileGetAttr (Dir) and faDirectory = faDirectory;
+(* FileGetAttr returns -1 on error *)
+  FADir := FileGetAttr (Dir);
+  Result := (FADir <> -1) and
+            ((FADir and faDirectory) = faDirectory);
 end;
 
 

+ 74 - 30
rtl/os2/sysutils.pp

@@ -73,6 +73,25 @@ type
         end;
         PFileStatus4=^TFileStatus4;
 
+        TFileStatus3L = object (TFileStatus)
+            DateCreation,               {Date of file creation.}
+            TimeCreation,               {Time of file creation.}
+            DateLastAccess,             {Date of last access to file.}
+            TimeLastAccess,             {Time of last access to file.}
+            DateLastWrite,              {Date of last modification of file.}
+            TimeLastWrite:word;         {Time of last modification of file.}
+            FileSize,                   {Size of file.}
+            FileAlloc:int64;         {Amount of space the file really
+                                         occupies on disk.}
+            AttrFile:cardinal;          {Attributes of file.}
+        end;
+        PFileStatus3L=^TFileStatus3L;
+
+        TFileStatus4L=object(TFileStatus3L)
+            cbList:cardinal;            {Length of entire EA set.}
+        end;
+        PFileStatus4L=^TFileStatus4L;
+
         TFileFindBuf3=object(TFileStatus)
             NextEntryOffset: cardinal;  {Offset of next entry}
             DateCreation,               {Date of file creation.}
@@ -291,10 +310,13 @@ type
  end;
 
 const
- ilStandard      = 1;
- ilQueryEAsize   = 2;
- ilQueryEAs      = 3;
- ilQueryFullName = 5;
+ ilStandard      =  1; (* Use TFileStatus3/TFindFileBuf3 *)
+ ilQueryEASize   =  2; (* Use TFileStatus4/TFindFileBuf4 *)
+ ilQueryEAs      =  3;
+ ilQueryFullName =  5;
+ ilStandardL     = 11; (* Use TFileStatus3L/TFindFileBuf3L *)
+ ilQueryEASizeL  = 12; (* Use TFileStatus4L/TFindFileBuf4L *)
+ ilQueryEAsL     = 13;
 
  quFIFO     = 0;
  quLIFO     = 1;
@@ -590,16 +612,16 @@ end;
 
 
 function FileExists (const FileName: string): boolean;
-var
-  SR: TSearchRec;
-  RC: longint;
 begin
-  FileExists:=False;
-  if FindFirst (FileName, faAnyFile and not (faDirectory), SR) = 0
-    then FileExists := True;
-  FindClose(SR);
+  if FileName = '' then
+   Result := false
+  else
+   Result := FileGetAttr (ExpandFileName (FileName)) and
+                                               (faDirectory or faVolumeID) = 0;
+(* Neither VolumeIDs nor directories are files. *)
 end;
 
+
 type    TRec = record
             T, D: word;
         end;
@@ -608,7 +630,7 @@ type    TRec = record
 function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint;
 
 var SR: PSearchRec;
-    FStat: PFileFindBuf3;
+    FStat: PFileFindBuf3L;
     Count: cardinal;
     Err: cardinal;
     I: cardinal;
@@ -617,23 +639,36 @@ begin
   New (FStat);
   Rslt.FindHandle := THandle ($FFFFFFFF);
   Count := 1;
-  Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
+  if FSApi64 then
+   Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
+            Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandardL)
+  else
+   Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
             Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandard);
-  if (Err = 0) and (Count = 0) then Err := 18;
+  if (Err = 0) and (Count = 0) then
+   Err := 18;
   FindFirst := -Err;
   if Err = 0 then
-  begin
-    Rslt.Name := FStat^.Name;
-    Rslt.Size := FStat^.FileSize;
-    Rslt.Attr := FStat^.AttrFile;
+   begin
     Rslt.ExcludeAttr := 0;
     TRec (Rslt.Time).T := FStat^.TimeLastWrite;
     TRec (Rslt.Time).D := FStat^.DateLastWrite;
-  end else if (Rslt.Findhandle<>0) then
-  begin
-    FindClose(Rslt); 
-  end;
-  
+    if FSApi64 then
+     begin
+      Rslt.Size := FStat^.FileSize;
+      Rslt.Name := FStat^.Name;
+      Rslt.Attr := FStat^.AttrFile;
+     end
+    else
+     begin
+      Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
+      Rslt.Name := PFileFindBuf3 (FStat)^.Name;
+      Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
+     end;
+   end
+  else
+   FindClose(Rslt);
+
   Dispose (FStat);
 end;
 
@@ -641,24 +676,33 @@ end;
 function FindNext (var Rslt: TSearchRec): longint;
 var
   SR: PSearchRec;
-  FStat: PFileFindBuf3;
+  FStat: PFileFindBuf3L;
   Count: cardinal;
   Err: cardinal;
 begin
   New (FStat);
   Count := 1;
-  Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^),
-                                                              Count);
-  if (Err = 0) and (Count = 0) then Err := 18;
+  Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^), Count);
+  if (Err = 0) and (Count = 0) then
+   Err := 18;
   FindNext := -Err;
   if Err = 0 then
   begin
-    Rslt.Name := FStat^.Name;
-    Rslt.Size := FStat^.FileSize;
-    Rslt.Attr := FStat^.AttrFile;
     Rslt.ExcludeAttr := 0;
     TRec (Rslt.Time).T := FStat^.TimeLastWrite;
     TRec (Rslt.Time).D := FStat^.DateLastWrite;
+    if FSApi64 then
+     begin
+      Rslt.Size := FStat^.FileSize;
+      Rslt.Name := FStat^.Name;
+      Rslt.Attr := FStat^.AttrFile;
+     end
+    else
+     begin
+      Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
+      Rslt.Name := PFileFindBuf3 (FStat)^.Name;
+      Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
+     end;
   end;
   Dispose (FStat);
 end;

+ 21 - 20
rtl/watcom/sysutils.pp

@@ -289,33 +289,34 @@ end;
 
 
 Function FileExists (Const FileName : String) : Boolean;
-Var
-  Sr : Searchrec;
 begin
-  DOS.FindFirst(FileName,$3f,sr);
-  if DosError = 0 then
-   begin
-     { No volumeid,directory }
-     Result:=(sr.attr and $18)=0;
-     Dos.FindClose(sr);
-   end
+  if FileName = '' then
+   Result := false
   else
-   Result:=false;
+   Result := FileGetAttr (ExpandFileName (FileName)) and
+                                               (faDirectory or faVolumeID) = 0;
+(* Neither VolumeIDs nor directories are files. *)
 end;
 
 
-Function DirectoryExists (Const Directory : String) : Boolean;
-Var
-  Sr : Searchrec;
+function DirectoryExists (const Directory: string): boolean;
+var
+  L: longint;
 begin
-  DOS.FindFirst(Directory,$3f,sr);
-  if DosError = 0 then
-   begin
-     Result:=(sr.attr and $10)=$10;
-     Dos.FindClose(sr);
-   end
+  if Directory = '' then
+   Result := false
   else
-   Result:=false;
+   begin
+    if (Directory [Length (Directory)] in AllowDirectorySeparators) and
+                                              (Length (Directory) > 1) and
+(* Do not remove '\' after ':' (root directory of a drive) 
+   or in '\\' (invalid path, possibly broken UNC path). *)
+      not (Directory [Length (Directory) - 1] in AllowDriveSeparators + AllowDirectorySeparators) then
+     L := FileGetAttr (ExpandFileName (Copy (Directory, 1, Length (Directory) - 1)))
+    else
+     L := FileGetAttr (ExpandFileName (Directory));
+    Result := (L > 0) and (L and faDirectory = faDirectory);
+   end;
 end;