📄 iexecdos.asm
字号:
; 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 [byte ES:DI] ; Remove the trailing delimiter
RemoveLeadingQuote:
push es di ; Preserve the location of the DOS command
mov cx, 1 ; Remove the first character
mov ax, 1 ; from the string
call DeleteChar,es,di
pop di es ; Restore the location
; Copy the command to the DOS command buffer
xor ah,ah
mov al,[byte es:di]
inc ax
call ByteCopy,es,di,seg DosCommandBuffer,Offset DosCommandBuffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -