'=========================================================================== ' Subject: FILE EXIST ROUTINE Date: 12-12-89 (00:00) ' Author: Randy Sharpe Code: QB, PDS ' Origin: harryst@castel.nl Packet: DOS.ABC '=========================================================================== ' DOS Interrupt File Exist Routine ' Written for QuickBASIC 4.5 ' Randy Sharpe CIS 72425,1247 ' December 12, 1989 ' '***************************************************************************** ' Include the data within the "***" 's in the ' top of your program ' You may eliminate this block by instead adding the metacommand: ' "$include qb.bi in your code, but it contains some extra goodies ' you probably won't need. ' If running within QuickBASIC environment, you must load quickbasic ' using "/l qb.qlb"; this will load the "quick library" version of ' qb.lib. When producing an exe file from OUTSIDE of QuickBASIC using ' bc and link, be sure to "link-in" QB.LIB. Typically, this is ' accomplished by typing the following on the LIBRARIES line when ' prompted by LINK: ' ' BCOM45 + QB (+ any other libs you may have) ' This will link in the necessary object code for CALL INTERRUPT. ' If producing an EXE from within QuickBASIC environment, all will ' be handled automatically. ' TYPE RegType ax AS INTEGER 'AH/AL regs bx AS INTEGER 'BH/BL regs cx AS INTEGER 'CH/CL regs dx AS INTEGER 'DH/DL regs bp AS INTEGER 'base pointer si AS INTEGER 'source index reg di AS INTEGER 'destination index reg Flags AS INTEGER 'flags reg END TYPE DIM SHARED InRegs AS RegType, OutRegs AS RegType, True, False DECLARE SUB DoesFileExist (FileExists!, FileName$) DECLARE SUB INTERRUPT (IntNumber AS INTEGER, InRegs AS RegType, OutRegs AS RegType) False = 0 True = NOT False '**************************************************************************** ' Main 'assign the filename string to search for-can contain path/drive 'such as c:\editor\test.txt-if you intend to allow * and ?, your code 'in DoesFileExist must be set up for multiple occurences CLS INPUT "Please Enter File Name To Search For: ", FileName$ CALL DoesFileExist(FileExists!, FileName$) 'test the exist Boolean to see if we found the file-this is normally ' where we test FileExists! and branch to either a get-file routine ' or error message-below code segment is for testing only IF FileExists! THEN 'CALL ReadFile(FileName$) 'call the file read routine PRINT FileName$; " Found" 'test purposes ELSE 'CALL FileNotFoundErrMsg(FileName$) 'call the error message routine PRINT FileName$; " Not Found" 'test purposes END IF SUB DoesFileExist (FileExists, FileName$) ' '---------------------------------------------------------------------------- ' ' Input : File name to search for in FileName$. This filename may contain ' drive/path info, but will default to current if absent. It may ' also contain wildcard and pattern match chars "*" and "?". ' Process : Does a DOS INT21, service 4E to find the first occurence (if ' any) of file string contained in FileName$ in designated path & ' dir (if you need to find all occurences, you must continue ' all ensuing searches with INT21H, service 4FH). For a read, we ' want it to exist, but for a write, we want to give a message if ' it does exist to make sure user wants to overwrite it. For ' technical reference for this interrupt, see Microsoft Basic ' Language Reference. ' Output : Exist Boolean in FileExists ' Coupling : Called by Main ' Calls DOS Interrupt 21, service 4E ' Note : The following is a description of the carry-flag test: ' ' The following data is returned by INT21 for found/not found: ' ' If file is not found: ' OutRegs.Flags : FFFFF003H (-4093D) ' F F F F F 0 0 3 ' 1111 1111 1111 1111 1111 0000 0000 0011 <---this bit = CF 'By AND'ing with 0000 0000 0000 0000 0000 0000 0000 0001 '1H we can test ======================================= 'the carry bit 0000 0000 0000 0000 0000 0000 0000 0001 => bit is set when ' file not found ' If file is found: ' ' OutRegs.Flags = FFFFF003H (-4094D) ' F F F F F 0 0 2 ' 1111 1111 1111 1111 1111 0000 0000 0010 <---this bit = CF 'By AND'ing 1H: 0000 0000 0000 0000 0000 0000 0000 0001 ' ======================================= ' 0000 0000 0000 0000 0000 0000 0000 0000 => bit is reset when ' file is found ' 'If you desired to know further details about why file was not found, you 'could perform tests on OutRegs.ax. This would tell you if path not found, 'no such directory, etc. ' 'The above technique may be modified to perform any DOS interrupt, making 'it a powerful (and fast) alternative to other techniques such as SHELL ' ' A WORD ABOUT * and ? - This routine is designed only to give a "there/not ' there indication of a designated file. When using the wildcard and pattern ' match chars * and ?, you are typically doing some operation such as ' a directory or a group delete. As it stands, this routine will only tell ' you that a file does or doesn't exist. For example, if you ask for *.bas, ' it will say that there is or isn't some file with a bas extension. To list ' these files is beyond the scope of this routine, and requires the use ' of another DOS Interrupt 21 service (4FH) within a conditional loop. '---------------------------------------------------------------------------- 'we will use the default Disk Transfer Area in PSP - you may set 'your own if desired using INT21(1AH). 'place a null onto end of the filenme for the DOS interrupt IntFileName$ = FileName$ + CHR$(0) 'put interrupt service # 4E hex (78 dec) into ah, zeros into al InRegs.ax = &H4E00 'put starting segment memory addr of filename into dh & offset addr into 'dl reg using sadd fn InRegs.dx = SADD(IntFileName$) 'search for "normal" file attributes only, no hidden, system, etc. InRegs.cx = &H0 'call the interrupt CALL INTERRUPT(&H21, InRegs, OutRegs) 'mask off all but carry flag bit of flag reg by 'ANDing' flag reg 'with 0000000000000001 (1 hex) CarryFlag& = (OutRegs.Flags AND &H1) 'a short-cut way to assign true/falseness, since CF will be 0 or 1 FileExists! = CarryFlag& - 1 'another way to test cary flag 'IF CarryFlag& = 1 THEN ' FileExists = False 'ELSE ' FileExists = True 'END IF END SUB