[Back to DIRS SWAG index]  [Back to Main SWAG index]  [Original]

{
Okay everyone, a temporary kludge.. it works at least.  I'll try releasing a
full Windows 95 unit later on which will replace all the DOS functions with
new ones or something along those lines.  I ended up buying _Programmer's
Guide to Microsoft Windows 95_ from Microsoft Press.
*** D:\BP\WORK\LFN.PAS }

program LFNDir;
{$N+}

{si=1 instead of 0 gives a normal DOS date/time instead of the 100ns
stuff}

uses DOS, Strings;

const

{ File attribute constants }

  ReadOnly  = $0001;
  Hidden    = $0002;
  SysFile   = $0004;
  VolumeID  = $0008;
  Directory = $0010;
  Archive   = $0020;
  AnyFile   = $003F;
  TempFile  = $0100;

var

{ Error status variable }

LFNError: word;

type

  FindData = record
Attributes: longint;
  CreationTime,
  LastAccessTime,
  ModificationTime: comp;  {<- old MS-DOS one}
  FileSizeHigh,
  FileSizeLow: longint;
  Reserved: array[1..8] of byte;
  LongFileName: array[1..260] of char;
  FileName: array[1..14] of char;
  End;

function ASCIZToString (ASCIZ: array of Char): String;
begin
ASCIZToString := StrPas (@ASCIZ);
end;

function FindFirst (Path: String; Attr: word; var F: FindData): word;
assembler;
asm
  mov     LFNError, 0

push    ds
  lds     si, Path
  mov     dx, si
  inc     dx
  mov     cl, [si]

@@StringToPChar:
  inc     si
  dec     cl
  jnz     @@StringToPChar

  inc     si
  mov     byte ptr [si], 0

  les     di, F

  mov     cx, Attr
  mov     ax, 714Eh
  mov     si, 1

  int     21h                          ;{CF set on error}
  pop     ds
  jnc     @@NoCarry

  mov     LFNError, ax
  jmp     @@Exit

@@NoCarry:
cmp     ax, 7100h
  jne     @@Exit

  mov     LFNError, ax

@@Exit:
end;

procedure FindNext (var F: FindData; FileFindHandle: word); assembler;
asm
  mov     LFNError, 0

  mov     ax, 714Fh
  mov     si, 1
  mov     bx, FileFindHandle
  les     di, F

  int     21h

  jnc     @@NoCarry

  mov     LFNError, ax
  jmp     @@Exit

@@NoCarry:
cmp     ax, 7100h
  jne     @@Exit

  mov     LFNError, ax

@@Exit:
end;

procedure FindClose (FileFindHandle: word); assembler;
asm
  mov     LFNError, 0

  mov     ax, 71A1h
  mov     bx, FileFindHandle

  int     21h

  jnc     @@NoCarry

  mov     LFNError, ax
  jmp     @@Exit

@@NoCarry:
cmp     ax, 7100h
  jne     @@Exit

  mov     LFNError, ax

@@Exit:
end;

const
nshpers: longint = 1000000000 div 100;
sixty:word=60;
  thirtysixhundred:word=3600;
  hoursconst:longint=86400;

{procedure extime (time:comp;var dt:DateTime); assembler;
asm
  les     di, dt
  add     di, OFFSET DateTime. Minute
  mov     ax, es:[di]
end;}
(*
procedure expandtime (time: comp; var dt:DateTime);
assembler;
{
time = number of 100 nanosecond intervals since midnight, 1st January, 1601
yes, 1601.
second = (time / 10000000) mod 60
minute = ((time / 10000000) mod 3600) div 60

}
var
Dummy: Word;

asm

;{
COMMENT ENDCOMMENT
  blah
  blah
ENDCOMMENT
;}

  les     di, dt
  add     di, OFFSET DateTime. Sec

  ;{find seconds}
  finit                                ;{clear the stack for me!}
  fild    time                         ;{load the time into ST(0)}
  fidiv   nshpers                      ;{get the number of seconds since..}
  fst     ST(1)                        ;{save a copy for later..}
  fild    sixty                        ;{ST(0) := 60; (time -> ST(1))}
  fxch                                 ;{swap ST(1) and (0)}
  fprem                                ;{ST(0) := ST(0) mod ST(1);}
  fistp   word ptr es:[di]             ;{dt. sec := ST(0)}
  sub     di, 2                        ;{es:[di] points to dt. min}

  ;{find minutes}
  fistp   Dummy                        ;{get rid of ST(0) (60)}
  fst     ST(2)                        ;{save a copy of new time for later..}
  fild    thirtysixhundred             ;{ST(0) := 3600; (time -> ST(1))}
  fxch                                 ;{exchange ST0/1}
  fprem                                ;{ST(0) := ST(0) mod ST(1);}
  fxch                                 ;{exchange ST0/1}
  fistp   Dummy                        ;{get rid of ST(0) (3600)}
  fidiv   sixty                        ;{ST(0) := ST(0) / ST(1) (60)}
  fst     ST(1)                        ;{make a copy of minutes for later..}
  frndint                              ;{round off ST(1) to nearest int.}
  fcom                                 ;{compare rounded & unrounded}
  fstsw   ax                           ;{store FPU status to ax}
  sahf                                 ;{store ah to CPU status}
{ jp      Error}                       ;{C2 (->parity) set on compare error}
  jc      @@NotGreater                 ;{C0 (->carry) set on less or error}
  jz      @@NotGreater                 ;{C3 (->zero) set on equal or error}
                                       ;{correct for rounding up! (no trunc)}
  fld1                                 ;{ST(0) := 1 (round (minutes) -> ST(1))
  fsub                                 ;{ST(0) := ST(0) - ST(1) (minutes-1)}
@@NotGreater:                          ;{minutes was rounded down, or cont.}
  fistp   word ptr es:[di]             ;{dt. min := ST(0)}
  sub     di, 2                        ;{es:[di] points to dt. hour}

  ;{find hours}
  fistp   Dummy                        ;{get rid of ST(0) (60)}
  fst     ST(2)                        ;{save a copy of new time for later..}
  fild    hoursconst                   ;{ST(0) := 3600*24; (time -> ST(1))}
  fxch                                 ;{exchange ST0/1}
  fprem                                ;{ST(0) := ST(0) mod ST(1);}
  fxch                                 ;{exchange ST0/1}
  fistp   Dummy                        ;{get rid of ST(0) (3600)}
  fidiv   thirtysixhundred             ;{ST(0) := ST(0) / ST(1) (3600)}
  fst     ST(1)                        ;{make a copy of minutes for later..}
  frndint                              ;{round off ST(1) to nearest int.}
  fcom                                 ;{compare rounded & unrounded}
  fstsw   ax                           ;{store FPU status to ax}
  sahf                                 ;{store ah to CPU status}
{ jp      Error}                       ;{C2 (->parity) set on compare error}
  jc      @@NotGreater2                ;{C0 (->carry) set on less or error}
  jz      @@NotGreater2                ;{C3 (->zero) set on equal or error}
                                       ;{correct for rounding up! (no trunc)}
  fld1                                 ;{ST(0) := 1 (round (minutes) -> ST(1))
  fsub                                 ;{ST(0) := ST(0) - ST(1) (minutes-1)}
@@NotGreater2:                         ;{minutes was rounded down, or cont.}
  fistp   word ptr es:[di]             ;{dt. min := ST(0)}
  sub     di, 2                        ;{es:[di] points to dt. hour}

end;


{  fxchg
  fild    nshpers

  fdiv}

{begin
  time := trunc (time / (1000*1000*1000/100));
  second := time mod 60;
  minute := time mod (60*60) div 60;
  hour := time mod (60*60*60) div (60*60);
end;}
*)
function long (c: comp):word; assembler;
asm
mov dx, word ptr c[2]
  mov ax, word ptr c[0]
end;

var
Find: FindData;
  FileFindHandle: Word;
  dt: DateTime;

begin
  { change this to suit your drive !! }
  FileFindHandle := FindFirst ('d:\PROGRAM FILES\*.*', 255, Find);

  repeat
  If Not (LFNError = 0) Then begin
      halt;
    end;
    unpacktime (long (find. modificationtime), dt);
    {expandtime (find. modificationtime, dt);}

  WriteLn (ASCIZToString (Find. FileName),
ASCIZToString (Find. LongFileName), dt. hour, ':', dt. min, ':', dt. sec);
{    writeln (x);}
    FindNext (Find, FileFindHandle);
  Until (LFNError <> 0);

  FindClose (FileFindHandle);
End.

[Back to DIRS SWAG index]  [Back to Main SWAG index]  [Original]