home *** CD-ROM | disk | FTP | other *** search
-
- ; FILENAME: IEXECDOS.ASM
- ;
- ; Copyright (c) 1990, 1992 by Borland International, Inc.
- ;
- ; DESCRIPTION: This module implements the routines that handle calling
- ; DOS to perform a command on each file that is found by WHEREIS.
- ; This module uses ideal mode syntax.
- ;
- ; This module looks for the location of COMMAND.COM to enable the
- ; running of the commands. Since many matching files may be found,
- ; and COMMAND.COM is called to execute the given DOS command for each
- ; file that is found, it is best if COMMAND.COM is located in a ramdisk.
- ;
- ; ASSEMBLY INSTRUCTIONS: To assemble this module use the following
- ; TASM command line.
- ;
- ; TASM /m /dMDL=memorymodel iparam
- ;
- ; /m in the above command line allows TASM to resolve jumps and other
- ; operations to their shortest form and get rid of extra NOPs.
- ; 'memorymodel' in the above command line may be replaced by TINY, SMALL,
- ; MEDIUM, COMPACT, LARGE or HUGE. If assembling this module to run on
- ; a 286/386 machine, turn on the P286 directive in order to take advantage of
- ; 286/386 specific instructions. I.E.
- ;
- ; TASM /m /dMDL=memorymodel /jP286 iparam
- ;
-
- ;DO_SAMPLE_COMMAND equ 1 ; Enable this to execute a sample DIR command
- ; ; when the command line is being parsed.
-
- jumps
-
- %tabsize 4
-
- ifndef MDL
- display "Error: This module requires that you provide a memory model"
- display " definition on the command line. I.E. /dMDL=SMALL."
- err ; Force a fatal error
- else
-
- ideal ; Use TASM's Ideal mode
- % model MDL,pascal ; Define the memory model
-
- include "dos.inc"
- include "idos.inc"
- include "kbd.inc"
- include "iwhglobl.inc"
- include "imacros.mac"
-
- dataseg
- NO_COMMAND_GIVEN equ 0
- COMMAND_GIVEN equ 1
- DosCommandGiven db NO_COMMAND_GIVEN
-
- COMMAND_BUFFER_LENGTH equ 200
- ; Stores the command given on command line
- DosCommandBuffer db COMMAND_BUFFER_LENGTH dup (?)
-
- ; The DOS command in quotes will include some special escape sequences
- ; that will cause the name of the file to be inserted in various ways.
- ;
- ; %1 - The full path, filename and extension
- ; %2 - Filename and extension (no path)
- ; %3 - Only the path
- ; %4 - Only the filename before the extension followed by a .
- ; %5 - Only the extension, preceeded by a .
-
- ; This is placed at the start of COMMAND.COM command strings.
- StartOfBuff db '/C ',0
-
- ; Store the actual command that is executed. Any %x directives in
- ; the above command buffer are converted to their actual values
- ; as the above command is transfered into the following buffer.
- ; 32 extra bytes are an overrun buffer.
- CommandToDo db COMMAND_BUFFER_LENGTH+32 dup (?)
-
- ; Needed for the call to execute COMMAND.COM
- ParamBlock dw 7 dup (0)
-
- ComspecTag db 'COMSPEC=',0
-
- ; Pointer into the environment block for start of COMMAND.COM location
- ComspecSeg dw 0 ;Not changed from zero if no comspec found.
- ComspecOfs dw ?
-
- MakePascalString NoComspecMssg,<"COMSPEC= not found in environment!",13,10>
-
- codeseg
-
- ; The environment block is a group of null terminated strings.
- ; A string beginning with zero signals the end of the eviroment block.
-
- proc SearchEnvironment
- ; This routine searches for a variable in the environment block.
- ;
- ; Input
- ; DS:SI - Points to a string like "NAME=" which is to be
- ; found in the environment. It should be an ASCIIZ string.
- ; Output
- ; If the variable is found,
- ; AL - 0
- ; ES:DI - Points to string after the = sign in the environment.
- ; If the variable is not found,
- ; AL is nonzero.
- ; Registers modified
- ; all
-
- cld ;Set direction for scanning to increment
-
- ; Set ES:DI to environment block
- push ds
- mov ax,@data ; Reset to our datasegment since the "NAME="
- ; might be in another segment.
- mov ds,ax
- mov es,[PspAddress]
- mov es,[es:psp.EnvironmentBlock]
- xor di,di
- pop ds
- @@CheckEnvironmentEnd:
- mov bx,si ;initialize BX pointer to name to find
- mov al,[byte es:di]
- or al,al
- je @@MatchFailed ;jump if end is found
-
- @@CheckNextByte:
-
- mov al,[bx] ;get character to match.
-
- or al,al ;if end of name we are done!
- jz @@MatchCompleted ; (AL will be zero)
-
- cmp al,[byte es:di] ;compare to char in environment block
- jne @@FindNextString ;jump if match failed
- inc bx
- inc di
- jmp @@CheckNextByte
-
- @@FindNextString:
- xor al,al ;scan forward in Environment Block
- mov cx,0FFFFh ;for zero byte.
- repnz scasb
- jmp @@CheckEnvironmentEnd ;go compare next string
-
- @@MatchFailed:
- inc al ;return al<>0 as failure flag
-
- @@MatchCompleted: ;all matched, return ES:DI pointing
- ; to parameter. al = 0
- ret
- endp SearchEnvironment
-
-
- ifdef DO_SAMPLE_COMMAND
- ; Show a sample of the proper way to call COMMAND.COM
- dataseg
- SampleCommand db 9,'/C DIR C:',13
- codeseg
- proc SampleDosCommand
- ; This routine calls COMMAND.COM to do the DIR command.
- ;
- mov cx,seg SampleCommand
- mov dx,offset SampleCommand
- call DoDosCommand
- ret
- endp SampleDosCommand
- endif
-
- proc DoDosCommand
- ; This procedure executes the command string pointed at by DX:CX
- ; by giving it to COMMAND.COM.
- ; This routine is not reentrant because of local code segment
- ; data storage at end of routine.
- ;
- ; Input
- ; None
- ; Output
- ; None
- ; Calling conventions
- ; NA
- ; Registers modified
- ; all
-
- push ds
- mov ax,seg ParamBlock
- mov es,ax
- mov bx,offset ParamBlock
-
- mov [word es:bx+4],cx ; Load the location of the command tail
- mov [word es:bx+2],dx ; for the command.
-
- mov [Orig_SS],SS
- mov [Orig_SP],SP
-
- mov ax,[ComSpecSeg]
- or ax,ax
- jz @@Skip ; Skip over EXEC if our segment is still zero.
- ; That means that no Comspec was found.
-
- mov dx,[ComspecOfs]
- mov ds,ax
-
- mov ax,4b00h
- int 21h
- @@Skip:
- mov ss,[Orig_SS]
- mov sp,[Orig_SP]
- pop ds
- ret
-
- ; Preserves the location of our stack.
- Orig_SS dw ?
- Orig_SP dw ?
- endp DoDosCommand
-
- proc ParseDosCommand
- ; This procedure initializes all variables and data structures
- ; used for executing the DOS command.
- ;
- ; Input
- ; ES:DI - Points to DOS command which is surrounded by quotes.
- ; It is a pascal style string
- ; Output
- ; Carry set if a command has already been specified
- ; Calling conventions
- ; NA
- ; Registers modified
- ; all
-
- cmp [DosCommandGiven],COMMAND_GIVEN
- jne @@FirstUse
- stc ; An error because a command was already specified
- jmp @@Exit
-
- @@FirstUse:
- push es di ; Preserve pointer to DOS command
- ; We need to find COMMAND.COM before we can know that we can
- ; do a DOS command.
- mov si,offset ComspecTag ;DS:SI string to match
- call SearchEnvironment ;go search environment
- or al,al
- jne ComspecNotFound
-
- mov [ComspecSeg],es ; If it was found, ES:DI is stored.
- mov [ComspecOfs],di
- jz FreeExtraMemory
-
- ComspecNotFound:
- call WritePascalString,ds,offset NoComspecMssg
-
- FreeExtraMemory:
- ; We need to give up extra memory.
- mov bx,zzzzzseg ; Location of first segment of free memory
- mov ax,[PspAddress] ; PSP segment
- sub bx,ax ; BX now contains paragraphs used
- ; by this program.
- mov es,ax
- mov ah,4ah
- int 21h
-
- ifdef DO_SAMPLE_COMMAND
- call SampleDosCommand
- endif
- pop di es ; Restore pointer to DOS command
-
- ; Check if the final character is a quote and
- ; remove it if it is.
- xor bh,bh ; Get length of string in BX
- mov bl,[es:di]
-
- mov al,[es:di+bx] ; Load last character of string
- call IsDelimiter
- jnc RemoveLeadingQuote
-
- RemoveTrailingQuote:
- dec ntBlocES:DI] ; Remove the trailing delimiter
- e
- kkkkkkkkkkFEC if oul M
- ; Res6locES:f string extra memory.
- EC if oul M
- ment follow
- mov bl,[edi] C stnt mov es,[PspAd 21h
-
- ifdef DO_SAMPLE_COtrailing del SampleDosCommaopymov bx,offoter
- e bove co
-
- ; Chec r bh,bh mov bx,si jmp para mov bl,[e ;aopynt NA
- VEN
-
- COMMAND_B,O jzVEN
-
- COMMAND_Brs modified
- ;g
- ommerve ; PresemmandGiven],COandGi ; BX now containventions
- ; NA
- ; Registcl
-
- No cmp stse
-
- deleCommand
- tion of our stackrs modif
- ifdef DO_SAExtraMlsComma aommanE ret ; Preserves thelStrinr are convrine neMMAND
- sffoter
- Comma+4],cxe thnving delimies thelSE ret ; Prese ; BD AL upPh,
- re inN
-
-
- re inN ComspecSeg e proper way to caE ret ; Preserv.
- Orig_SS dw ?
- is exe ret
- e e ,OS candGi,a+4]rv.
- Oeacomp inD.COM comCOMMAND.COM lizes all variables and data sax:]
- - jz:
- n
- ; les and data sd
- -o jz:
- ce D OS command which is surroundedn at end of routine.
- ;
- ; Input
- ; None
- ; Output
- ; Nonee cep sthe location of the cD AL upPh, [ComspecSeg], of the ce inN
-
- ] paragraphs used
- ce inN ]k]
- ; Calling co proc P Calling conventions
- ; NA
- ; Registers modifise
- f free lank mt eove cox+4],cx ; LoadDIR C: ; BX no,
- ; uto Registerstions
- ; NA
- s transfere ; BX now contains paragraphs used
- dCOMMAND.COM ransfere ; BX now contaikkF NABUFFER_LENGTH r bh,bhched, return p CronmtFound:
- call o Paraailio not copye.
- ment folliriabp @@Exit
-
- ote andu
- lerve
- a %gment is still zero.COMMAND.COM ransfereit
-
- F4],oveult
-
- ifdef DOmov
-
- ; Checcl,c @@CheckEnvironmentEnd AExtr is a quowhichlow
- mov jmp cES:DI] ; EnvironmentEnd AEx lock is a group of null terminated strings.
- ; A string beginning with zero signals the end of the eviroment block.
-
- proc SearchEnvironment
- ; This routine searches for a variable in the environment block.
- ;
- ; Input
- ; DS:SI - Points to a string like "NAME=" which is to be
- ; found in the environment. It should be an ASCIIZ string.
- ; Output
- ; If the variable is found,
- ; AL - 0
- ; ES:DI - Points to string after the = sign in the environment.
- ; If the variable is not found,
- ; AL is nonzero.
- ; Registers modified
- ; all
-
- cld ;Set direction for scanning to increment
-
- ; Set ES:DI to environment block
- push ds
- mov ax,@data ; Reset to our datasegment since the "NAME="
- ; might be in another segment.
- mov ds,ax
- mov es,[PspAddress]
- mov es,[es:psp.EnvironmentBlock]
- xor di,di
- pop ds
- @@CheckEnvironmentEnd:
- mov bx,si ;initialize BX pointer to name to find
- mov al,[byte es:di]
- or al,al
- je @@MatchFailed ;jump if end is found
-
- @@CheckNextByte:
-
- mov al,[bx] ;get character to match.
-
- or al,al ;if end of name we are done!
- jz @@MatchCompleted ; (AL will be zero)
-
- cmp al,[byte es:di] ;compare to char in environment block
- jne @@FindNextString ;jump if match failed
- inc bx
- inc di
- jmp @@CheckNextByte
-
- @@FindNextString:
- xor al,al ;scan forward in Environment Block
- mov cx,0FFFFh ;for zero byte.
- repnz scasb
- jmp @@CheckEnvironmentEnd ;go compare next string
-
- @@MatchFailed:
- inc al ;return al<>0 as failure flag
-
- @@MatchCompleted: ;all matched, return ES:DI pointing
- ; to parameter. al = 0
- ret
- endp SearchEnvironment
-
-
- ifdef DO_SAMPLE_COMMAND
- ; Show a sample of the proper way to call COMMAND.COM
- dataseg
- SampleCommand db 9,'/C DIR C:',13
- codeseg
- proc SampleDosCommand
- ; This routine calls COMMAND.COM to do the DIR command.
- ;
- mov cx,seg SampleCommand
- mov dx,offset SampleCommand
- call DoDosCommand
- ret
- endp SampleDosCommand
- endif
-
- proc DoDosCommand
- ; This procedure executes the command string pointed at by DX:CX
- ; by giving it to COMMAND.COM.
- ; This routine is not reentrant because of local code segment
- ; data storage at end of routine.
- ;
- ; Input
- ; None
- ; Output
- ; None
- ; Calling conventions
- ; NA
- ; Registers modified
- ; all
-
- push ds
- mov ax,seg ParamBlock
- mov es,ax
- mov bx,offset ParamBlock
-
- mov [word es:bx+4],cx ; Load the location of the command tail
- mov [word es:bx+2],dx ; for the command.
-
- mov [Orig_SS],SS
- mov [Orig_SP],SP
-
- mov ax,[ComSpecSeg]
- or ax,ax
- jz @@Skip ; Skip over EXEC if our segment is still zero.
- ; That means that no Comspec was found.
-
- mov dx,[ComspecOfs]
- mov ds,ax
-
- mov ax,4b00h
- int 21h
- @@Skip:
- mov ss,[Orig_SS]
- mov sp,[Orig_SP]
- pop ds
- ret
-
- ; Preserves the location of our stack.
- Orig_SS dw ?
- Orig_SP dw ?
- endp DoDosCommand
-
- proc ParseDosCommand
- ; This procedure initializes all variables and data structures
- ; used for executing the DOS command.
- ;
- ; Input
- ; ES:DI - Points to DOS command which is surrounded by quotes.
- ; It is a pascal style string
- ; Output
- ; Carry set if a command has already been specified
- ; Calling conventions
- ; NA
- ; Registers modified
- ; all
-
- cmp [DosCommandGiven],COMMAND_GIVEN
- jne @@FirstUse
- stc ; An error because a command was already specified
- jmp @@Exit
-
- @@FirstUse:
- push es di ; Preserve pointer to DOS command
- ; We need to find COMMAND.COM before we can know that we can
- ; do a DOS command.
- mov si,offset ComspecTag ;DS:SI string to match
- call SearchEnvironment ;go search environment
- or al,al
- jne ComspecNotFound
-
- mov [ComspecSeg],es ; If it was found, ES:DI is stored.
- mov [ComspecOfs],di
- jz FreeExtraMemory
-
- ComspecNotFound:
- call WritePascalString,ds,offset NoComspecMssg
-
- FreeExtraMemory:
- ; We need to give up extra memory.
- mov bx,zzzzzseg ; Location of first segment of free memory
- mov ax,[PspAddress] ; PSP segment
- sub bx,ax ; BX now contains paragraphs used
- ; by this program.
- mov es,ax
- mov ah,4ah
- int 21h
-
- ifdef DO_SAMPLE_COMMAND
- call SampleDosCommand
- endif
- pop di es ; Restore pointer to DOS command
-
- ; Check if the final character is a quote and
- ; remove it if it is.
- xor bh,bh ; Get length of string in BX
- mov bl,[es:di]
-
- mov al,[es:di+bx] ; Load last character of string
- call IsDelimiter
- jnc RemoveLeadingQuote
-
- RemoveTrailingQuote:
- dec ntBlocES:DI] ; Remove the trailing delimiter
- e
- kkkkkkkkkkFEC if oul M
- ; Res6locES:f string extra memory.
- EC if oul M
- ment follow
- mov bl,[edi] C stnt mov es,[PspAd 21h
-
- ifdef DO_SA