home *** CD-ROM | disk | FTP | other *** search
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;
- ; Name : GetFiles.ASM
- ;
- ; Revised : 4/21/90
- ;
- ; Purpose : This QB FUNCTION which reads ALL the ENTRIES in a given
- ; DIRECTORY PATHNAME which match the passed ASCIIZ STRING
- ; parameter, below, 'PathName'.
- ;
- ; Notes : - Due to the structure of the program successful assembly
- ; requires the Microsoft MACRO ASSEMBLER, V 5.1 +.
- ; - This routine should be declared in your source program
- ; as an EXTERNAL FUNCTION routine, via the statement -
- ;
- ; DECLARE FUNCTION GetFiles%(PathName$, FSeg%, FOff%)
- ;
- ; Parameters : - The parameters to the above CALL are defined as follows:
- ;
- ; PathName - The ASCIIZ string of a given DOS PATHNAME to be read.
- ; This should end with a filespec to be matched,
- ; (eg, "*.COM") or with the "*.*" for ALL files.
- ; - THIS MUST END WITH A CHR$(0) CHARACTER!!
- ;
- ; FSeg - The SEGMENT address of the DYNAMIC ARRAY used to
- ; hold the output of this routine.
- ; - This array MUST be defined as DYNAMIC, MUST be
- ; defined as STRING * 12 (fixed length strings, each 12
- ; bytes long), and MUST be <= 5458 STRINGS in size.
- ; - Note that the first element is 0, not 1.
- ; - Note that it would be an odd path which has more
- ; than 5,458 files in it!!
- ;
- ; FOff - The OFFSET address of the above array.
- ;
- ; - The easiest way to CALL this FUNCTION is as follows -
- ;
- ; NmbrOfFiles% = GetFiles% (PathName, VARSEG(FNarray(0)), VARPTR(FNarray(0)))
- ;
- ; - In the above example, NmbrOfFiles% will be adjusted to
- ; reflect the fact that FNarray(0) is the first element, so that
- ; your program can use a statement such as
- ; FOR x% = 0 to NmbrOfFiles% ...
- ; - If you specify a "*.*" search criteria, the entries
- ; for "." and ".." will be returned as elements 0 and 1,
- ; respectively.
- ; - Note that this FUNCTION finds ALL DIRECTORY ENTRIES,
- ; regardless of the value of the attribute byte for any
- ; particular entry.
- ;
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- .MODEL MEDIUM,BASIC
- .DATA
-
- NewDTABuffer DB 128 dup(0)
- DTABuff EQU OFFSET NewDTABuffer
- DTAFileName EQU DTABuff + 30
-
- FileName DB ' .'
- FileExt DB ' '
-
- FILEBUF EQU OFFSET FileName
-
- ClrStrng DB ' . '
-
- ;-----------------------------------------------------------------------------
-
- .CODE
-
- GetFiles proc USES DS ES SI DI, PATHNAME:word, VARSEG:word, VAROFF:word
- LOCAL OldDTASeg:word, OldDTAOff:word, PathToUse:word, FileCtr:word, DimSeg:word, DimOff:word
-
- mov FileCtr,1 ; Initialize counter for files found
- ;*****************************************************************************
- ; - Since this routine makes extensive use of the DTA, we will protect
- ; the DTA which the CALLing program uses by setting up a new DTA,
- ; temporarily, for this routine to use. Therefore, we must store the
- ; SEGMENT:OFFSET address of the current DTA so that we can restore it
- ; on exit from this routine
- ;*****************************************************************************
- mov AH,02Fh ; "GET DTA ADDR" Service of int 21h
- int 21h
- mov OldDTASeg,ES ; Save the entry value for the DTA,
- mov OldDTAOff,BX ; both segment and offset
- ;*****************************************************************************
- ; - Now we can get the passed parameters for the SEGMENT and OFFSET of
- ; the DYNAMIC array which will hold the file names.
- ; Then we can the passed DRIVE parameter and change the current default
- ; drive and path to ROOT DIRECTORY of the passed DRIVE
- ;*****************************************************************************
- mov BX,VARSEG ; Save the SEGMENT portion of the
- mov AX,[BX] ; address of FNarray() in the
- mov DimSeg,AX ; DimSeg variable.
-
- mov BX,VAROFF ; Save the OFFSET portion of the
- mov AX,[BX] ; address of FNarray() in the
- mov DimOff,AX ; DimOff variable.
-
- mov BX,PATHNAME ; BX = the address of the passed parm, PathName
- mov DX,[BX+2] ; Note that DS:DX = offset of ASCIIZ PathName
- mov PathToUse,DX ; Store this address for later use
-
- Start_Program:
- mov AX,DimSeg ; ES:DI = FNarray(0)
- mov ES,AX
- mov DI,DimOff
-
- mov DX,DTABuff ; Prepare to create a NEW DTA
- mov AH,01Ah ; "SET DTA ADDR" Service of int 21h
- int 21h
- clc ; Clear Carry Flag to start
- Find_First_Match:
- mov SI,DTABuff ; Point SI at start of NewDTABuffer
- mov CX,16h ; Find ANY ATTRIBUTE file
- mov DX,PathToUse ; DS:DX = passed ASCIIZ PathName parm
- mov AH,04Eh ; "FIND FIRST MATCH" Service of int 21h
- int 21h
-
- jnc Found_A_File ; If CARRY, disk is 100% EMPTY
- jmp short Ret_To_Caller
- Found_A_File:
- push DS
- pop ES ; Be sure that ES = DS for this
- mov DI,FILEBUF
- mov SI,DTAFileName ; SI = start of FileName in NewDTABuffer
- mov CX,8 ; (which CANNOT be > 8 bytes long)
- Record_The_FileName:
- lodsb
- cmp AL,'.' ; Find the "." between FileName and Ext
- je Record_The_Ext
- cmp AL,0 ; Some damned files have hex 0 in them!
- jne NotHexZero
- mov AL,20h ; Substitute blank space for the hex 0
- NotHexZero:
- stosb
- loop Record_The_FileName
- Record_The_Ext:
- cmp Byte Ptr[SI],'.' ; This could be the "." between FileName
- jne RTE_A ; and the FileExt if FileName is
- inc SI ; EXACTLY 8 chars long!
- RTE_A:
- mov DI,OFFSET FileExt
- Record_FileExt:
- lodsb
- cmp AL,0 ; If AL = 0 = end of the filename.ext
- je TransferFileName
- stosb
- jmp short Record_FileExt
-
- TransferFileName:
- mov DI,DimOff
- mov AX,DimSeg
- mov ES,AX
- mov SI,FILEBUF
- mov CX,6
- rep MOVSW
-
- mov AX,DimOff ; Correct the pointer in DimOff by
- add AX,12 ; adding length of one filename
- mov DimOff,AX
-
- push DS
- pop ES ; Make ES = DS again
- inc FileCtr ; Keep Count of files recorded
-
- mov DI,FILEBUF
- mov SI,OFFSET ClrStrng ; SI = start of ClrStrng, which is a
- mov CX,6 ; string of blank spaces which
- rep MOVSW ; clears out FileName
-
- mov DI,DTAFileName ; ES:DI=start of FileName in NewDTABuff
- mov CX,49 ; We will MOVe 49 words here (98 bytes)
- xor AX,AX ; AX = hex 0 to clear this data item
- CDALoop:
- stosw
- loop CDALoop ; Store all 49 WORDs (98 bytes)
- mov SI,DTABuff
- Get_Next_Match:
- mov SI,DTABuff ; SI = start of DTABuff for next match
- mov CX,16h
- mov DX,PathToUse ; DX = start of file match criteria
- mov AH,04Fh ; "FIND NEXT MATCH" Service of int 21h
- int 21h
- jc Ret_To_Caller
- jmp Found_A_File
- Ret_To_Caller:
- push DS ; Save DS temporarily
- mov AX,OldDTASeg ; Here we restore entry DTA address
- mov DS,AX
- mov DX,OldDTAOff
- mov AH,01Ah ; "SET DTA ADDR" Service of int 21h
- int 21h
-
- pop DS ; Now restore DS from BX
- mov AX,FileCtr ; Return number of files (not
- dec AX ; including directories),
- ; adjust for FNarray(0).
- ret ; PROGRAM TERMINATION
- GetFiles ENDP
- END
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-