[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]