* FindFirst enhanced for file sizes >2 GB

git-svn-id: trunk@18843 -
This commit is contained in:
Tomas Hajny 2011-08-25 21:17:30 +00:00
parent 8a9763018f
commit 6aecc69389
2 changed files with 245 additions and 113 deletions

View File

@ -73,6 +73,25 @@ type
end; end;
PFileStatus4=^TFileStatus4; 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) TFileFindBuf3=object(TFileStatus)
NextEntryOffset: cardinal; {Offset of next entry} NextEntryOffset: cardinal; {Offset of next entry}
DateCreation, {Date of file creation.} DateCreation, {Date of file creation.}
@ -110,6 +129,43 @@ type
end; end;
PFileFindBuf4=^TFileFindBuf4; 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 TFSInfo = record
case word of case word of
1: 1:
@ -246,10 +302,13 @@ type
PStartData=^TStartData; PStartData=^TStartData;
const const
ilStandard = 1; ilStandard = 1; (* Use TFileStatus3/TFindFileBuf3 *)
ilQueryEAsize = 2; ilQueryEASize = 2; (* Use TFileStatus4/TFindFileBuf4 *)
ilQueryEAs = 3; ilQueryEAs = 3;
ilQueryFullName = 5; ilQueryFullName = 5;
ilStandardL = 11; (* Use TFileStatus3L/TFindFileBuf3L *)
ilQueryEASizeL = 12; (* Use TFileStatus4L/TFindFileBuf4L *)
ilQueryEAsL = 13;
quFIFO = 0; quFIFO = 0;
quLIFO = 1; quLIFO = 1;
@ -580,7 +639,7 @@ end;
function FileExists (const FileName: string): boolean; function FileExists (const FileName: string): boolean;
begin begin
if Directory = '' then if FileName = '' then
Result := false Result := false
else else
Result := FileGetAttr (ExpandFileName (Directory)) and Result := FileGetAttr (ExpandFileName (Directory)) and
@ -588,104 +647,133 @@ begin
end; end;
type TRec = record type
T, D: word; TRec = record
end; T, D: word;
PSearchRec = ^SearchRec; end;
PSearchRec = ^SearchRec;
function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint; function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint;
var SR: PSearchRec; var
FStat: PFileFindBuf3; SR: PSearchRec;
Count: cardinal; FStat: PFileFindBuf3L;
Err: cardinal; Count: cardinal;
Err: cardinal;
begin begin
if os_mode = osOS2 then if os_mode = osOS2 then
begin begin
New (FStat); New (FStat);
Rslt.FindHandle := THandle ($FFFFFFFF); Rslt.FindHandle := THandle ($FFFFFFFF);
Count := 1; Count := 1;
Err := DosFindFirst (PChar (Path), Rslt.FindHandle, if FSApi64 then
Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
ilStandard); Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandardL)
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
else else
begin Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
Err := DOS.DosError; Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandard);
GetMem (SR, SizeOf (SearchRec)); if (Err = 0) and (Count = 0) then
Rslt.FindHandle := longint(SR); Err := 18;
DOS.FindFirst (Path, Attr, SR^); FindFirst := -Err;
FindFirst := -DOS.DosError; if Err = 0 then
if DosError = 0 then begin
begin Rslt.ExcludeAttr := 0;
Rslt.Time := SR^.Time; TRec (Rslt.Time).T := FStat^.TimeLastWrite;
Rslt.Size := SR^.Size; TRec (Rslt.Time).D := FStat^.DateLastWrite;
Rslt.Attr := SR^.Attr; if FSApi64 then
Rslt.ExcludeAttr := 0; begin
Rslt.Name := SR^.Name; Rslt.Size := FStat^.FileSize;
end; Rslt.Name := FStat^.Name;
DOS.DosError := Err; Rslt.Attr := FStat^.AttrFile;
end; 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; end;
function FindNext (var Rslt: TSearchRec): longint; function FindNext (var Rslt: TSearchRec): longint;
var SR: PSearchRec; var
FStat: PFileFindBuf3; SR: PSearchRec;
Count: cardinal; FStat: PFileFindBuf3L;
Err: cardinal; Count: cardinal;
Err: cardinal;
begin begin
if os_mode = osOS2 then if os_mode = osOS2 then
begin begin
New (FStat); New (FStat);
Count := 1; Count := 1;
Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^), Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^), Count);
Count); if (Err = 0) and (Count = 0) then
if (Err = 0) and (Count = 0) then Err := 18; Err := 18;
FindNext := -Err; FindNext := -Err;
if Err = 0 then if Err = 0 then
begin begin
Rslt.Name := FStat^.Name; Rslt.ExcludeAttr := 0;
Rslt.Size := FStat^.FileSize; TRec (Rslt.Time).T := FStat^.TimeLastWrite;
Rslt.Attr := FStat^.AttrFile; TRec (Rslt.Time).D := FStat^.DateLastWrite;
Rslt.ExcludeAttr := 0; if FSApi64 then
TRec (Rslt.Time).T := FStat^.TimeLastWrite; begin
TRec (Rslt.Time).D := FStat^.DateLastWrite; Rslt.Size := FStat^.FileSize;
end; Rslt.Name := FStat^.Name;
Dispose (FStat); Rslt.Attr := FStat^.AttrFile;
end end
else else
begin begin
SR := PSearchRec (Rslt.FindHandle); Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
if SR <> nil then Rslt.Name := PFileFindBuf3 (FStat)^.Name;
begin Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
DOS.FindNext (SR^); end;
FindNext := -DosError; end;
if DosError = 0 then Dispose (FStat);
begin end
Rslt.Time := SR^.Time; else
Rslt.Size := SR^.Size; begin
Rslt.Attr := SR^.Attr; SR := PSearchRec (Rslt.FindHandle);
Rslt.ExcludeAttr := 0; if SR <> nil then
Rslt.Name := SR^.Name; begin
end; DOS.FindNext (SR^);
end; FindNext := -DosError;
end; 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; end;

View File

@ -73,6 +73,25 @@ type
end; end;
PFileStatus4=^TFileStatus4; 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) TFileFindBuf3=object(TFileStatus)
NextEntryOffset: cardinal; {Offset of next entry} NextEntryOffset: cardinal; {Offset of next entry}
DateCreation, {Date of file creation.} DateCreation, {Date of file creation.}
@ -291,10 +310,13 @@ type
end; end;
const const
ilStandard = 1; ilStandard = 1; (* Use TFileStatus3/TFindFileBuf3 *)
ilQueryEAsize = 2; ilQueryEASize = 2; (* Use TFileStatus4/TFindFileBuf4 *)
ilQueryEAs = 3; ilQueryEAs = 3;
ilQueryFullName = 5; ilQueryFullName = 5;
ilStandardL = 11; (* Use TFileStatus3L/TFindFileBuf3L *)
ilQueryEASizeL = 12; (* Use TFileStatus4L/TFindFileBuf4L *)
ilQueryEAsL = 13;
quFIFO = 0; quFIFO = 0;
quLIFO = 1; quLIFO = 1;
@ -608,7 +630,7 @@ type TRec = record
function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint; function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint;
var SR: PSearchRec; var SR: PSearchRec;
FStat: PFileFindBuf3; FStat: PFileFindBuf3L;
Count: cardinal; Count: cardinal;
Err: cardinal; Err: cardinal;
I: cardinal; I: cardinal;
@ -617,23 +639,36 @@ begin
New (FStat); New (FStat);
Rslt.FindHandle := THandle ($FFFFFFFF); Rslt.FindHandle := THandle ($FFFFFFFF);
Count := 1; 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); 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; FindFirst := -Err;
if Err = 0 then if Err = 0 then
begin begin
Rslt.Name := FStat^.Name;
Rslt.Size := FStat^.FileSize;
Rslt.Attr := FStat^.AttrFile;
Rslt.ExcludeAttr := 0; Rslt.ExcludeAttr := 0;
TRec (Rslt.Time).T := FStat^.TimeLastWrite; TRec (Rslt.Time).T := FStat^.TimeLastWrite;
TRec (Rslt.Time).D := FStat^.DateLastWrite; TRec (Rslt.Time).D := FStat^.DateLastWrite;
end else if (Rslt.Findhandle<>0) then if FSApi64 then
begin begin
FindClose(Rslt); Rslt.Size := FStat^.FileSize;
end; 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); Dispose (FStat);
end; end;
@ -641,24 +676,33 @@ end;
function FindNext (var Rslt: TSearchRec): longint; function FindNext (var Rslt: TSearchRec): longint;
var var
SR: PSearchRec; SR: PSearchRec;
FStat: PFileFindBuf3; FStat: PFileFindBuf3L;
Count: cardinal; Count: cardinal;
Err: cardinal; Err: cardinal;
begin begin
New (FStat); New (FStat);
Count := 1; Count := 1;
Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^), Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^), Count);
Count); if (Err = 0) and (Count = 0) then
if (Err = 0) and (Count = 0) then Err := 18; Err := 18;
FindNext := -Err; FindNext := -Err;
if Err = 0 then if Err = 0 then
begin begin
Rslt.Name := FStat^.Name;
Rslt.Size := FStat^.FileSize;
Rslt.Attr := FStat^.AttrFile;
Rslt.ExcludeAttr := 0; Rslt.ExcludeAttr := 0;
TRec (Rslt.Time).T := FStat^.TimeLastWrite; TRec (Rslt.Time).T := FStat^.TimeLastWrite;
TRec (Rslt.Time).D := FStat^.DateLastWrite; 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; end;
Dispose (FStat); Dispose (FStat);
end; end;