View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0020042FPCRTLpublic2011-08-24 12:322013-04-08 22:31
ReporterSalvatore Licciardi 
Assigned To 
PrioritynormalSeverityminorReproducibilityhave not tried
StatusnewResolutionopen 
PlatformGo32v2OSDOSOS Versionall possible
Product Version2.4.4Product Build 
Target VersionFixed in Version 
Summary0020042: FindFirst /Next size not work on DOS real with file_size>2 GB
DescriptionSee program and comment below...

 Program Example43;
 { This program demonstrates the FindFirst function }
 Uses SysUtils;
 Var Info : TSearchRec;
     Count : Longint;
 Begin
   Count:=0;
 // If FindFirst ('z:\--------.nt6\*.iso',faAnyFile and faDirectory,Info)=0 then
   If FindFirst ('o:\*.iso',faAnyFile and faDirectory,Info)=0 then
     begin
     Repeat
       Inc(Count);
       With Info do
         begin
         If (Attr and faDirectory) = faDirectory then
           Write('Dir : ');
         Writeln (Name:40,Size:15);
         end;
     Until FindNext(info)<>0;
     end;
   FindClose(Info);
   Writeln ('Finished search. Found ',Count,' matches');
 End.

// output
Running "c:\temp\d244\ffirst2exe "
Windows Vista ITA_x32.iso -1710178304
Finished search Found 1 matches

// I try Dos version on WinXP and Dos real mode. Under winXp on win32 target , problem is absent. I don't test other target.

// documentation
 TSearchRec
 Record describing a search handle or result

 Declaration
 Source position: filutilh.inc line 17

   typ e TSearchRec = record
    Time: LongInt; Timestamp of the file.
    Size: Int64; Size of the file.
    Attr: LongInt; Attributes of the file.
    Name: TFilename; File name (no directory part)
    ExcludeAttr: LongInt; Attributes to exclude from search (do not use).
    FindHandle: Pointer; Internal OS handle (do not use).
    Mode: TMode; Unix File mode. Only used on Unix systems.
    PathOnly: AnsiString; Path component of the file
  end;
TagsNo tags attached.
FPCOldBugId
Fixed in Revision
Attached Files

- Relationships

-  Notes
(0051066)
Tomas Hajny (manager)
2011-08-24 12:49

What is the operating system (including version) and what kind of filesystem did you use for accessing a file > 2GB under "real DOS"? Anyway, the fix will probably consist from a typecast of the returned value for size in the Dos.FindFirst call from longint (Dos.SearchRec) to cardinal within the assignment in SysUtils.FindFirst and SysUtils.FindNext implementations. However, files > 2GB are not supported in real DOS as far as I know so you'll probably face a lot of other issues there (not only related to FPC).
(0051069)
Salvatore Licciardi (reporter)
2011-08-24 16:05
edited on: 2011-08-24 16:25

filesystem is fat32, on Dos 7.10 (win98).

The dir command return correct info

(0051075)
Marco van de Voort (manager)
2011-08-24 17:22
edited on: 2011-08-24 17:26

There are three tsearchrecs:
- the public unit dos one (with longint size field)
- the LFN version in the unit dos implementation (2x 32-bit longint in hi/lo order, so not INT64able)
- The sysutils public one (which has size=int64)

The sysutils functions call the dos functions which forces the size through the legacy dos unit interface.

On other OSes we solved this by deprecating unit Dos, but this is less logical for DOS, so probably need a bit of code duplication for the relevant functions

(0051077)
Tomas Hajny (manager)
2011-08-24 17:48

Admittedly, I forgot that FAT32 was supported for W98. :-(

Marco is right regarding the necessary duplication. This by itself has IMHO nothing to do to declaring unit Dos deprecated or not - we simply either keep unit Dos compatible to TP/BP (Dos.SearchRec can never support a file size > 2 GB) which implies also "compatibility" to TP/BP limitations, or we change it to remove TP/BP limitations but decrease the compatibility at the same time. In any case, there is indeed no reason to keep such limitation in SysUtils.
(0051131)
Marco van de Voort (manager)
2011-08-25 20:18
edited on: 2011-08-25 20:18

I meant more that we kept fairly strict TP/BP compatibility of unit DOS till now.

It doesn't make to sense to break it for the OS that makes most use of it.

But codeduplication is IMHO not a problem, so fixing it by copy LFN* into sysutils is fine by me.

(0066872)
Paul Robinson (reporter)
2013-04-08 22:21
edited on: 2013-04-08 22:31

Use SysUtils, the functions are almost identical and instead of using a LongInt for filesize, which, since it is signed, only allows up to 2 GB (2147483647 or 2^31-1), uses Int64, which allows for files of 2^63-1, (9223372036854775807) which should be enough to hold you latest 3HD movie. :)

I had to switch to SysUtils because I had a .gz file I downloaded that was about 2.15 billion bytes, and it came up in a directory search as having a negagive size. In fact, I had reported this back about 10 years ago when Free Pascal had its own installer and it was checking disk space and was coming up with negative free space when the user had more than 2 GB of free space. I can imagine what that would do now, this computer has only 755 GB of free space out of the terabyte it started with.

SysUtils functions have the same name as the equivalent in DOS, they use a slightly different set of types for results. The following example lists every file in a directory, listing the directories in cyan blue

uses
   CRT,
  SysUtils;
var
     Dir : TSearchRec ;
     Path:String;
     Count,
     FileError,
     FileAttr:LongInt;
     K,
     DefTextAttr: Byte;

begin
   DefTextAttr:= CRT.TextAttr;
   Count := 0 ;
   FileAttr := $FF;

// FileError := FindFirst ( 'C:\*' , $FF , Dir )
   FileError := FindFirst ( '\\netdrive\somedirectory\*' , FileAttr , Dir ) ;
   WriteLn ('FileName'+Space (32) , 'FileSize' : 9 ,'Attr':6) ;
   K := 0;
   while ( FileError=0 ) do
   begin
      if ((dir.attr and fadirectory)<>0) then
        textcolor(Cyan)
      else
        textcolor(DefTextAttr);
      inc(K);
      inc(Count);
      if length(Dir.name)>40 then
      begin
         Writeln ( Dir.Name);
         write(Space(40));
      end
      else
         Write ( Dir.Name+Space(40-Length(Dir.Name)));
      Writeln ( Dir.Size:11,dir.attr:6 );
      if K>9 then
       begin
          readln;
          K:=0;
       end;
      FileError := FindNext (Dir) ;
   end ;
   FindClose(Dir) ;
   textcolor(DefTextAttr);
   readln;
end.


- Issue History
Date Modified Username Field Change
2011-08-24 12:32 Salvatore Licciardi New Issue
2011-08-24 12:49 Tomas Hajny Note Added: 0051066
2011-08-24 16:05 Salvatore Licciardi Note Added: 0051069
2011-08-24 16:25 Salvatore Licciardi Note Edited: 0051069
2011-08-24 17:22 Marco van de Voort Note Added: 0051075
2011-08-24 17:26 Marco van de Voort Note Edited: 0051075
2011-08-24 17:48 Tomas Hajny Note Added: 0051077
2011-08-25 20:18 Marco van de Voort Note Added: 0051131
2011-08-25 20:18 Marco van de Voort Note Edited: 0051131
2013-04-08 22:21 Paul Robinson Note Added: 0066872
2013-04-08 22:31 Paul Robinson Note Edited: 0066872 View Revisions



MantisBT 1.2.12[^]
Copyright © 2000 - 2012 MantisBT Group
Powered by Mantis Bugtracker