home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / basic / library / qb_pds / qb_lib / filedir.asm < prev    next >
Encoding:
Assembly Source File  |  1991-01-29  |  13.0 KB  |  404 lines

  1. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. ;
  3. ;    Module Name    : FileDir.ASM
  4. ;
  5. ;       Last Revised    : 07/04/90 08:45am
  6. ;
  7. ;       Purpose         : This is a specialized function which reads ALL the
  8. ;                         ENTRIES in a given DIRECTORY PATHNAME which match
  9. ;                         the passed parameter, below, 'PathName'.
  10. ;              Note you MUST define a DYNAMIC array to hold the
  11. ;               output from this routine in your source program
  12. ;              before you use this.
  13. ;
  14. ;       Assumptions     : Due to the structure of the program, successful
  15. ;                         assembly requires the Microsoft MACRO ASSEMBLER,
  16. ;                         V 5.1 +
  17. ;
  18. ;       This routine would be declared in your source program as an EXTERNAL
  19. ;       FUNCTION routine, via the statement -
  20. ;
  21. ;               DECLARE FUNCTION FileDir% (PathName$, FSeg%, FOff%)
  22. ;
  23. ;       Parameters      : The parameters to the above CALL are defined as
  24. ;                         follows:
  25. ;
  26. ;              PathName - the ASCIIZ string of a given DOS PATHNAME to be
  27. ;                         read, including a filespec or "*.*" - REMEMBER that
  28. ;              ASCIIZ strings ALWAYS end with a CHR$(0) character!
  29. ;
  30. ;               FSeg    - The SEGMENT address of the DYNAMIC ARRAY used to
  31. ;                         hold the output of this routine.
  32. ;                           This array MUST be defined as DYNAMIC, MUST be
  33. ;                         defined as STRING * 42 (fixed length strings, each
  34. ;                         42 bytes long), and MUST be <= 1550 STRINGS in size.
  35. ;                           Therefore, this routine will return NO MORE THAN
  36. ;                         1550 STRINGS$ of data from the disk(ette).
  37. ;
  38. ;       IF YOU DO NOT MAKE THE ARRAY LARGE ENOUGH TO HOLD ALL THE ENTRIES,
  39. ;       THIS PROGRAM WILL BEHAVE  UNPREDICTABLY!
  40. ;
  41. ;              FNOff    - The OFFSET address of the above array.
  42. ;
  43. ;
  44. ;       The easiest way to CALL this FUNCTION is as follows -
  45. ;
  46. ;   NmbrOfFiles% = FileDir (PathName, VARSEG(FNarray(0)), VARPTR(FNarray(0)))
  47. ;
  48. ;       The format of each string is defined below in the .DATA item starting
  49. ;       with "FileName".
  50. ;       This is similar to the DOS "DIR" list format, except that there is 1
  51. ;       space between all items, and the LAST item is the base 10 equivalent
  52. ;       of the file's current attribute byte.
  53. ;    All entries returned in the FNarray are in full ASCII text, suitable
  54. ;    for screen display or sending direct to the printer.
  55. ;
  56. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  57.  
  58.     .MODEL    MEDIUM,BASIC
  59.     .DATA
  60.  
  61.     NewDTABuffer    DB    128 dup(0)
  62.     DTABuff        EQU    OFFSET    NewDTABuffer
  63.     DTAFileAttr    EQU    DTABuff + 21
  64.     DTAFileTime    EQU    DTABuff + 22
  65.     DTAFileDate    EQU    DTABuff + 24
  66.     DTAFileSize    EQU    DTABuff + 26
  67.     DTAFileName    EQU    DTABuff + 30
  68.  
  69.         FileName        DB      '        .'
  70.     FileExt        DB    '   '
  71.                         DB      ' '
  72.         FileSize        DB      '         '
  73.                         DB      ' '
  74.     FileMM        DB    '00-'
  75.     FileDD        DB    '00-'
  76.     FileYY        DB    '1900'
  77.                         DB      ' '
  78.         FileTime        DB      '00:00'         ; This 24 hour clock allows easy SORTing
  79.                         DB      ' '
  80.         FileAttr        DB      '  '
  81.  
  82.     FILEBUF        EQU    OFFSET    FileName
  83.  
  84.         ClrStrng        DB      '        .              00-00-1900 00:00   '
  85.  
  86. ;============================================================================
  87.  
  88.     .CODE
  89.  
  90.     FileDir    PROC USES DS ES SI DI, PATHNAME:WORD, VARSEG:WORD, VAROFF:WORD
  91.         LOCAL   OldDTASeg:WORD, OldDTAOff:WORD, PathToUse:WORD, FileCtr:WORD, \
  92.                 DimSeg:WORD, DimOff:WORD
  93.  
  94. ;****************************************************************************
  95. ;                         Start Of Main Program Code
  96. ;****************************************************************************
  97.  
  98.         mov     FileCtr,0               ; Initialize counter for files found
  99.  
  100. ;*****************************************************************************
  101. ;       Since this routine makes extensive use of the DTA, we will protect the
  102. ;       original DTA which the CALLing program uses by setting up a new DTA,
  103. ;       temporarily, for this routine to use.
  104. ;       Therefore, we must store the SEGMENT:OFFSET address of the current DTA
  105. ;       so that we can restore it on exit from this routine.
  106. ;*****************************************************************************
  107.  
  108.         mov     AH,02Fh                 ; "GET DTA ADDR" Service of int 21h
  109.     int    21h
  110.         mov     OldDTASeg,ES            ; Save the entry value for the DTA
  111.     mov    OldDTAOff,BX
  112.  
  113. ;*****************************************************************************
  114. ;       Now we can get the passed parameters for the SEGMENT and OFFSET of the
  115. ;       DYNAMIC array which will hold the file names.
  116. ;       Then we can get the passed DRIVE parameter and change the current
  117. ;       default drive and path to ROOT DIRECTORY of the passed DRIVE.
  118. ;*****************************************************************************
  119.  
  120.         mov     BX,VARSEG               ; Save the SEGMENT portion of the
  121.         mov     AX,[BX]                 ;       address of FNarray() in the
  122.         mov     DimSeg,AX               ;       DimSeg variable.
  123.         mov     BX,VAROFF               ; Save the OFFSET portion of the
  124.         mov     AX,[BX]                 ;       address of FNarray() in the
  125.         mov     DimOff,AX               ;       DimOff variable.
  126.  
  127.         mov     BX,PATHNAME             ; BX = the addr. of the passed PathName
  128.         mov     DX,[BX+2]               ; Note that DS:DX = offset of ASCIIZ
  129.                                         ;       PathName
  130.         mov     PathToUse,DX            ; Store this address for later use
  131.  
  132. ;-----------------------------------------------------------------------------
  133.  
  134. Start_Program:
  135.  
  136.         mov     AX,DimSeg               ; Now we point ES:DI at FNarray(0)
  137.     mov    ES,AX
  138.     mov    DI,DimOff
  139.  
  140.         mov     DX,DTABuff              ; Prepare to create a NEW DTA temporarily
  141.         mov     AH,01Ah                 ; "SET DTA ADDR" Service of int 21h
  142.     int    21h
  143.  
  144.         clc                             ; Clear Carry Flag to start
  145.  
  146. Find_First_Match:
  147.  
  148.         mov     SI,DTABuff              ; Point SI at start of NewDTABuffer
  149.         mov     CX,16h                  ; Find ANY ATTRIBUTE file
  150.         mov     DX,PathToUse            ; DS:DX = passed ASCIIZ PathName parm
  151.         mov     AH,04Eh                 ; "FIND FIRST MATCH" Service of int 21h
  152.     int    21h
  153.  
  154.         jnc     Found_A_File            ; If CARRY, disk is 100% EMPTY
  155.     jmp    Ret_To_Caller
  156.  
  157. Found_A_File:
  158.  
  159.         push    DS
  160.         pop     ES                      ; Be sure that ES = DS for this
  161.  
  162.         mov     DI,OFFSET FileAttr      ; Point DI at start of FileAttr
  163.     mov    SI,DTAFileAttr
  164.         mov     AL,[SI]                 ; Put File Attrib into AL
  165.         call    EightBitToASCII
  166.  
  167.     mov    DI,FILEBUF
  168.         mov     SI,DTAFileName          ; SI points at start of FileName in the NewDTABuffer
  169.         mov     CX,8                    ;     (which CANNOT be > 8 bytes long)
  170.  
  171. Record_The_FileName:
  172.  
  173.     lodsb
  174.         cmp     AL,'.'                  ; Find the "." between FileName and Ext
  175.     je    Record_The_Ext
  176.     cmp    AL,0
  177.     jne    NotHexZero
  178.     mov    AL,20h
  179.  
  180. NotHexZero:
  181.  
  182.     stosb
  183.     loop Record_The_FileName
  184.  
  185. Record_The_Ext:
  186.  
  187.         cmp     Byte Ptr[SI],'.'        ; This could be the "." between FileName
  188.         jne     RTE_A                   ;       and the FileExt if FileName is
  189.         inc     SI                      ;       EXACTLY 8 chars long!
  190.  
  191. RTE_A:
  192.  
  193.     mov    DI,OFFSET FileExt
  194.  
  195. Record_FileExt:
  196.  
  197.     lodsb
  198.     cmp    AL,0
  199.     je    Record_FileTime
  200.     stosb
  201.     jmp    short    Record_FileExt
  202.  
  203. ;*****************************************************************************
  204. ;       At this point, we have recorded the FileName, The FileExt, and the
  205. ;       FileAttr.  Now we will record the File's Date and Time.
  206. ;*****************************************************************************
  207.  
  208. Record_FileTime:
  209.  
  210.     mov    DI,OFFSET FileTime
  211.     mov    SI,DTAFileTime
  212.         mov     AX,[SI]                 ; AX = TIME File last modified
  213.  
  214.         and     AX,0F800h               ; MASK to get the HOURS value
  215.     mov    CL,11
  216.     shr    AX,CL
  217.         call    EightBitToASCII         ; Record the HOURS value in ASCII form
  218.  
  219.         mov     AX,[SI]                 ; Put TIME value into AX again
  220.     mov    DI,OFFSET FileTime
  221.         add     DI,3                    ; Point DI at MINUTES area of FileTime
  222.  
  223.         and     AX,07E0h                ; MASK to get MINUTES value
  224.     mov    CL,5
  225.     shr    AX,CL
  226.         call    EightBitToASCII         ; Record the MINUTES in ASCII form
  227.  
  228.     mov    DI,OFFSET FileMM
  229.     mov    SI,DTABuff
  230.     add    SI,24
  231.         mov     AX,[SI]                 ; AX now = DATE file last modified
  232.  
  233.         and     AX,01E0h                ; MASK DATE to get Month value
  234.     mov    CL,05
  235.     shr    AX,CL
  236.         call    EightBitToASCII         ; Record MONTH as ASCII
  237.  
  238.         mov     AX,[SI]                 ; Put DATE back into AX
  239.         mov     DI,OFFSET FileDD
  240.         and     AX,001Fh                ; MASK DATE to get Days
  241.         call    EightBitToASCII         ; Record DAYS as ASCII
  242.  
  243.     mov    DI,OFFSET FileYY
  244.         mov     AX,[SI]                 ; AX = DATE again
  245.         and     AX,0FE00h               ; MASK to get YEARS since 1980
  246.     mov    CL,09
  247.     shr    AX,CL
  248.     cmp    AL,20h
  249.     ja    Next_Century
  250.     add    AL,80
  251.     add    DI,2
  252.     jmp    short    Record_The_Year
  253.  
  254. Next_Century:
  255.  
  256.     mov    Byte Ptr[DI],32h
  257.     mov    Byte Ptr[DI+1],30h
  258.     inc    DI
  259.     inc    DI
  260.     sub    AL,20h
  261.  
  262. Record_The_Year:
  263.  
  264.     call EightBitToASCII
  265.  
  266. ;*****************************************************************************
  267. ;    Now we will record the File's Size in Bytes, and then we are done
  268. ;*****************************************************************************
  269.  
  270.     mov    SI,DTAFileSize
  271.     mov    DI,OFFSET FileSize
  272.     add    DI,8
  273.     mov    AX,[SI]
  274.         mov     DX,[SI+2]               ; FileSize now in DX:AX
  275.  
  276.         push    BP
  277.         xchg    BP,DX
  278.     mov    BX,0Ah
  279.     mov    CL,030h
  280.  
  281. File_Size_One:
  282.  
  283.     cmp    BP,0
  284.     jz    File_Size_Two
  285.  
  286.         xchg    BP,AX
  287.     xor    DX,DX
  288.     div    BX
  289.         xchg    BP,AX
  290.     div    BX
  291.     or    DL,CL
  292.     mov    [DI],DL
  293.     dec    DI
  294.     jmp    SHORT    File_Size_One
  295.  
  296. File_Size_Two:
  297.  
  298.     xor    DX,DX
  299.     div    BX
  300.     or    DL,CL
  301.     mov    [DI],DL
  302.     dec    DI
  303.     cmp    AX,0
  304.     jnz    File_Size_Two
  305.     pop    BP
  306.  
  307. ;*****************************************************************************
  308. ;    Now we can transfer this data into FNarray()
  309. ;*****************************************************************************
  310.  
  311.     mov    DI,DimOff
  312.     mov    AX,DimSeg
  313.     mov    ES,AX
  314.     mov    SI,FILEBUF
  315.     mov    CX,21
  316.     rep    MOVSW
  317.  
  318.     mov    AX,DimOff
  319.     add    AX,42
  320.     mov    DimOff,AX
  321.  
  322.         push    DS
  323.         pop     ES                      ; Make ES = DS again
  324.         inc     FileCtr                 ; Keep Count of files recorded
  325.  
  326.     mov    DI,FILEBUF
  327.     mov    SI,OFFSET ClrStrng
  328.     mov    CX,21
  329.         rep     MOVSW                   ; Clear out the FileName area for next time
  330.  
  331. Get_Next_Match:
  332.  
  333.         mov     DI,DTAFileName          ; ES:DI = start of FileName in NewDTABuff
  334.         mov     CX,49                   ; We will MOVe 49 words here (98 bytes)
  335.     xor    AX,AX
  336.  
  337. CD_Loop:
  338.  
  339.     stosw
  340.     loop CD_Loop
  341.  
  342.     mov    SI,DTABuff
  343.     mov    CX,16h
  344.     mov    DX,PathToUse
  345.         mov     AH,04Fh                 ; "FIND NEXT MATCH" Service of int 21h
  346.     int    21h
  347.  
  348.     jc    Ret_To_Caller
  349.     jmp    Found_A_File
  350.  
  351. Ret_To_Caller:
  352.  
  353.         push    DS                      ; Save DS temporarily
  354.  
  355.         mov     AX,OldDTASeg            ; Here we restore the entry DTA addr
  356.     mov    DS,AX
  357.     mov    DX,OldDTAOff
  358.         mov     AH,01Ah                 ; "SET DTA ADDR" Service of int 21h
  359.     int    21h
  360.  
  361.         pop     DS                      ; Now restore DS from BX
  362.         mov     AX,FileCtr              ; Return number of files (not
  363.                                         ;       including directories)
  364.  
  365.         ret                             ; PROGRAM TERMINATION
  366.  
  367. FileDir  ENDP
  368.  
  369. ;*****************************************************************************
  370. ;                          End Of Main Program Code
  371. ;*****************************************************************************
  372. ;                             Sub-Routine Section
  373. ;*****************************************************************************
  374.  
  375. EightBitToASCII         PROC    NEAR    ; Converts an 8-bit value in AL to
  376.                                         ;      ASCII equivalent.  On entry,
  377.         mov     DL,AL                   ;      ES:DI must point to the start
  378.         inc     DI                      ;      of a buffer large enough to
  379.         xor     CX,CX                   ;      hold the number.
  380.  
  381. EBTA_One:
  382.  
  383.     mov    AL,DL
  384.     xor    AH,AH
  385.     mov    CL,10
  386.     div    CL
  387.  
  388.     mov    DL,AL
  389.     mov    AL,AH
  390.     add    AL,30h
  391.     mov    [DI],AL
  392.     dec    DI
  393.     cmp    DL,0
  394.     jnz    EBTA_One
  395.     ret
  396.  
  397. EightBitToASCII         ENDP
  398.  
  399. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  400. ;
  401.                         END
  402. ;
  403. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  404.