home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / basic / library / qb_pds / qb_lib / getfiles.asm < prev    next >
Encoding:
Assembly Source File  |  1990-04-21  |  6.8 KB  |  203 lines

  1. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. ;
  3. ;    Name :     GetFiles.ASM
  4. ;
  5. ;    Revised :     4/21/90
  6. ;
  7. ;    Purpose :     This QB FUNCTION which reads ALL the ENTRIES in a given 
  8. ;        DIRECTORY PATHNAME which match the passed ASCIIZ STRING 
  9. ;        parameter, below, 'PathName'.
  10. ;
  11. ;      Notes :     - Due to the structure of the program successful assembly 
  12. ;        requires the Microsoft MACRO ASSEMBLER, V 5.1 +.
  13. ;        - This routine should be declared in your source program 
  14. ;        as an EXTERNAL FUNCTION routine, via the statement -
  15. ;
  16. ;        DECLARE FUNCTION GetFiles%(PathName$, FSeg%, FOff%)
  17. ;
  18. ; Parameters :     - The parameters to the above CALL are defined as follows:
  19. ;
  20. ;        PathName - The ASCIIZ string of a given DOS PATHNAME to be read.
  21. ;            This should end with a filespec to be matched,
  22. ;            (eg, "*.COM") or with the "*.*" for ALL files.
  23. ;             - THIS MUST END WITH A CHR$(0) CHARACTER!!
  24. ;
  25. ;        FSeg      - The SEGMENT address of the DYNAMIC ARRAY used to 
  26. ;            hold the output of this routine.
  27. ;             - This array MUST be defined as DYNAMIC, MUST be 
  28. ;            defined as STRING * 12 (fixed length strings, each 12 
  29. ;            bytes long), and MUST be <= 5458 STRINGS in size.
  30. ;             - Note that the first element is 0, not 1.
  31. ;             - Note that it would be an odd path which has more
  32. ;            than 5,458 files in it!!
  33. ;
  34. ;        FOff      - The OFFSET address of the above array.
  35. ;
  36. ;        - The easiest way to CALL this FUNCTION is as follows -
  37. ;
  38. ;  NmbrOfFiles% = GetFiles% (PathName, VARSEG(FNarray(0)), VARPTR(FNarray(0)))
  39. ;
  40. ;        - In the above example, NmbrOfFiles% will be adjusted to 
  41. ;        reflect the fact that FNarray(0) is the first element, so that
  42. ;        your program can use a statement such as
  43. ;            FOR x% = 0 to NmbrOfFiles% ...
  44. ;        - If you specify a "*.*" search criteria, the entries
  45. ;        for "." and ".." will be returned as elements 0 and 1,
  46. ;        respectively.
  47. ;        - Note that this FUNCTION finds ALL DIRECTORY ENTRIES,
  48. ;        regardless of the value of the attribute byte for any 
  49. ;        particular entry.
  50. ;
  51. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  52.  
  53.     .MODEL    MEDIUM,BASIC
  54.     .DATA
  55.  
  56.     NewDTABuffer    DB    128 dup(0)
  57.     DTABuff        EQU    OFFSET    NewDTABuffer
  58.     DTAFileName    EQU    DTABuff + 30
  59.  
  60.     FileName        DB    '        .'
  61.     FileExt        DB    '   '
  62.  
  63.     FILEBUF        EQU    OFFSET    FileName
  64.  
  65.     ClrStrng        DB    '        .   '
  66.  
  67. ;-----------------------------------------------------------------------------
  68.  
  69.     .CODE
  70.  
  71. GetFiles    proc USES DS ES SI DI, PATHNAME:word, VARSEG:word, VAROFF:word
  72. LOCAL    OldDTASeg:word, OldDTAOff:word, PathToUse:word, FileCtr:word, DimSeg:word, DimOff:word
  73.  
  74.     mov    FileCtr,1        ; Initialize counter for files found
  75. ;*****************************************************************************
  76. ;    - Since this routine makes extensive use of the DTA, we will protect
  77. ;    the DTA which the CALLing program uses by setting up a new DTA,
  78. ;       temporarily, for this routine to use.  Therefore, we must store the
  79. ;    SEGMENT:OFFSET address of the current DTA so that we can restore it
  80. ;    on exit from this routine
  81. ;*****************************************************************************
  82.     mov    AH,02Fh            ; "GET DTA ADDR" Service of int 21h
  83.     int    21h
  84.     mov    OldDTASeg,ES        ; Save the entry value for the DTA,
  85.     mov    OldDTAOff,BX        ;       both segment and offset
  86. ;*****************************************************************************
  87. ;    - Now we can get the passed parameters for the SEGMENT and OFFSET of 
  88. ;    the DYNAMIC array which will hold the file names.
  89. ;       Then we can the passed DRIVE parameter and change the current default
  90. ;    drive and path to ROOT DIRECTORY of the passed DRIVE
  91. ;*****************************************************************************
  92.     mov    BX,VARSEG         ; Save the SEGMENT portion of the
  93.     mov    AX,[BX]            ;    address of FNarray() in the
  94.     mov    DimSeg,AX         ;    DimSeg variable.
  95.  
  96.     mov    BX,VAROFF         ; Save the OFFSET portion of the
  97.     mov    AX,[BX]            ;    address of FNarray() in the
  98.     mov    DimOff,AX         ;    DimOff variable.
  99.  
  100.     mov    BX,PATHNAME        ; BX = the address of the passed parm, PathName
  101.     mov    DX,[BX+2]         ; Note that DS:DX = offset of ASCIIZ PathName
  102.     mov    PathToUse,DX        ; Store this address for later use
  103.  
  104. Start_Program:
  105.     mov    AX,DimSeg         ; ES:DI = FNarray(0)
  106.     mov    ES,AX
  107.     mov    DI,DimOff
  108.  
  109.     mov    DX,DTABuff        ; Prepare to create a NEW DTA
  110.     mov    AH,01Ah            ; "SET DTA ADDR" Service of int 21h
  111.     int    21h
  112.     clc                ; Clear Carry Flag to start
  113. Find_First_Match:
  114.     mov    SI,DTABuff        ; Point SI at start of NewDTABuffer
  115.     mov    CX,16h            ; Find ANY ATTRIBUTE file
  116.     mov    DX,PathToUse        ; DS:DX = passed ASCIIZ PathName parm
  117.     mov    AH,04Eh            ; "FIND FIRST MATCH" Service of int 21h
  118.     int    21h
  119.  
  120.     jnc    Found_A_File        ; If CARRY, disk is 100% EMPTY
  121.     jmp    short    Ret_To_Caller
  122. Found_A_File:
  123.     push    DS
  124.     pop    ES            ; Be sure that ES = DS for this
  125.     mov    DI,FILEBUF
  126.     mov    SI,DTAFileName        ; SI = start of FileName in NewDTABuffer
  127.     mov    CX,8             ;    (which CANNOT be > 8 bytes long)
  128. Record_The_FileName:
  129.     lodsb
  130.     cmp    AL,'.'            ; Find the "." between FileName and Ext
  131.     je    Record_The_Ext
  132.     cmp    AL,0            ; Some damned files have hex 0 in them!
  133.     jne    NotHexZero
  134.     mov    AL,20h            ; Substitute blank space for the hex 0
  135. NotHexZero:
  136.     stosb
  137.     loop Record_The_FileName
  138. Record_The_Ext:
  139.     cmp    Byte Ptr[SI],'.'    ; This could be the "." between FileName
  140.     jne    RTE_A            ;    and the FileExt if FileName is
  141.     inc    SI            ;    EXACTLY 8 chars long!
  142. RTE_A:
  143.     mov    DI,OFFSET FileExt
  144. Record_FileExt:
  145.     lodsb
  146.     cmp    AL,0             ; If AL = 0 = end of the filename.ext
  147.     je    TransferFileName
  148.     stosb
  149.     jmp    short    Record_FileExt
  150.  
  151. TransferFileName:
  152.     mov    DI,DimOff
  153.     mov    AX,DimSeg
  154.     mov    ES,AX
  155.     mov    SI,FILEBUF
  156.     mov    CX,6
  157.     rep    MOVSW
  158.  
  159.     mov    AX,DimOff        ; Correct the pointer in DimOff by
  160.     add    AX,12            ;    adding length of one filename
  161.     mov    DimOff,AX
  162.  
  163.     push     DS
  164.     pop    ES            ; Make ES = DS again
  165.     inc    FileCtr            ; Keep Count of files recorded
  166.  
  167.     mov    DI,FILEBUF        
  168.     mov    SI,OFFSET ClrStrng    ; SI = start of ClrStrng, which is a
  169.     mov    CX,6            ;    string of blank spaces which
  170.     rep    MOVSW            ;     clears out FileName
  171.  
  172.     mov    DI,DTAFileName         ; ES:DI=start of FileName in NewDTABuff
  173.     mov    CX,49            ; We will MOVe 49 words here (98 bytes)
  174.     xor    AX,AX            ; AX = hex 0 to clear this data item
  175. CDALoop:
  176.     stosw
  177.     loop CDALoop            ; Store all 49 WORDs (98 bytes)
  178.     mov    SI,DTABuff
  179. Get_Next_Match:
  180.     mov    SI,DTABuff        ; SI = start of DTABuff for next match
  181.     mov    CX,16h
  182.     mov    DX,PathToUse        ; DX = start of file match criteria
  183.     mov    AH,04Fh            ; "FIND NEXT MATCH" Service of int 21h
  184.     int    21h
  185.     jc    Ret_To_Caller
  186.     jmp    Found_A_File
  187. Ret_To_Caller:
  188.     push     DS            ; Save DS temporarily
  189.     mov    AX,OldDTASeg        ; Here we restore entry DTA address
  190.     mov    DS,AX
  191.     mov    DX,OldDTAOff
  192.     mov    AH,01Ah            ; "SET DTA ADDR" Service of int 21h
  193.     int    21h
  194.  
  195.     pop    DS            ; Now restore DS from BX
  196.     mov    AX,FileCtr        ; Return number of files (not 
  197.     dec    AX            ;    including directories),
  198.                     ;    adjust for FNarray(0).
  199.     ret                ; PROGRAM TERMINATION
  200. GetFiles    ENDP
  201.         END
  202. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  203.