* 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,15 +647,17 @@ begin
end; end;
type TRec = record type
TRec = record
T, D: word; T, D: word;
end; end;
PSearchRec = ^SearchRec; 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;
FStat: PFileFindBuf3L;
Count: cardinal; Count: cardinal;
Err: cardinal; Err: cardinal;
@ -606,20 +667,35 @@ begin
New (FStat); New (FStat);
Rslt.FindHandle := THandle ($FFFFFFFF); Rslt.FindHandle := THandle ($FFFFFFFF);
Count := 1; Count := 1;
if FSApi64 then
Err := DosFindFirst (PChar (Path), Rslt.FindHandle, Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandardL)
ilStandard); else
if (Err = 0) and (Count = 0) then Err := 18; 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; 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;
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
else
FindClose (Rslt);
Dispose (FStat); Dispose (FStat);
end end
else else
@ -632,7 +708,8 @@ begin
if DosError = 0 then if DosError = 0 then
begin begin
Rslt.Time := SR^.Time; Rslt.Time := SR^.Time;
Rslt.Size := SR^.Size; (* Extend the supported file sizes from 2 GB to 4 GB at least. *)
Rslt.Size := cardinal (SR^.Size);
Rslt.Attr := SR^.Attr; Rslt.Attr := SR^.Attr;
Rslt.ExcludeAttr := 0; Rslt.ExcludeAttr := 0;
Rslt.Name := SR^.Name; Rslt.Name := SR^.Name;
@ -644,8 +721,9 @@ end;
function FindNext (var Rslt: TSearchRec): longint; function FindNext (var Rslt: TSearchRec): longint;
var SR: PSearchRec; var
FStat: PFileFindBuf3; SR: PSearchRec;
FStat: PFileFindBuf3L;
Count: cardinal; Count: cardinal;
Err: cardinal; Err: cardinal;
@ -654,18 +732,27 @@ begin
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
@ -679,7 +766,8 @@ begin
if DosError = 0 then if DosError = 0 then
begin begin
Rslt.Time := SR^.Time; Rslt.Time := SR^.Time;
Rslt.Size := SR^.Size; (* Extend the supported file sizes from 2 GB to 4 GB at least. *)
Rslt.Size := cardinal (SR^.Size);
Rslt.Attr := SR^.Attr; Rslt.Attr := SR^.Attr;
Rslt.ExcludeAttr := 0; Rslt.ExcludeAttr := 0;
Rslt.Name := SR^.Name; Rslt.Name := SR^.Name;

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,22 +639,35 @@ begin
New (FStat); New (FStat);
Rslt.FindHandle := THandle ($FFFFFFFF); Rslt.FindHandle := THandle ($FFFFFFFF);
Count := 1; Count := 1;
if FSApi64 then
Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandardL)
else
Err := DosFindFirst (PChar (Path), Rslt.FindHandle, 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;
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
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;