home *** CD-ROM | disk | FTP | other *** search
-
- name dos_cmd
-
-
- save macro p1,p2,p3,p4,p5,p6,p7,p8,p9
- irp y,<p1,p2,p3,p4,p5,p6,p7,p8,p9>
- ifnb <y>
- push y
- endif
- endm
- restore macro
- irp z,<p9,p8,p7,p6,p5,p4,p3,p2,p1>
- ifnb <z>
- pop z
- endif
- endm
- endm
- endm
-
-
- dseg segment byte public 'data'
-
- comspec db 'COMSPEC',0
-
- dseg ends
-
-
- cseg segment byte public 'code'
-
-
- public dos_command
-
- comment `
-
- Routine to execute any DOS command.
-
- Calling stack:
- <sp+00> -> flag word -
- 0 execute COMMAND.COM, using the command line
- 1 load a copy of COMMAND.COM, no command line
- present.
- (if sp+00 = 0)
- <sp+02> -> dword pointer to command line (ASCIZ string)
-
- Returns:
- AX contains return code from command.
-
- Notes:
- Requires getenv to get the COMSPEC environment variable, and
- run_program to execute COMMAND.COM.
-
- `
-
- assume cs:cseg,ds:dseg
-
- extrn getenv:near
- extrn run_program:near
-
-
- dos_command proc near
-
- CommandFlag equ word ptr [bp+4]
- DosCmdLine equ dword ptr [bp+6]
- push bp ; Save incoming fp
- mov bp,sp ; Get a new fp
- save bx,si,di,ds,es ; Save registers
- mov bx,bp ; Save our current fp
- sub sp,76 ; Room for COMSPEC value
- mov bp,sp ; Pointer to it
- mov byte ptr [bp],76 ; Set length of buffer
- push ss ; Set up parameters for getenv
- push bp
- mov ax,dseg ; Get the data seg we need
- push ax
- mov ax,offset comspec ; Pointer to the string
- push ax
- call getenv ; Get COMSPEC value
- xchg bp,bx ; Get our fp back
- cmp CommandFlag,0 ; Need to use the command line?
- je UseCommandLine ; Yes, so do it
- sub sp,2 ; Need 2 bytes on the stack
- mov di,sp ; Get pointer to them
- push ss
- pop es
- mov ax,0d00h ; Put 2 bytes onto stack
- stosw
- sub di,2 ; Point to them again
- push es ; Put pointer on stack
- push di
- jmp short StackFNPointer ; Continue
- UseCommandLine:
- lds si,DosCmdLine ; Get pointer to command line
- sub sp,80h ; Allow room for command line
- mov di,sp ; Get pointer to area
- push ss ; Need the segment
- pop es
- push bx ; Save pointer to file name
- mov bx,di ; Point to length byte
- inc di ; Point to buffer area
- mov byte ptr ss:[bx],3 ; Set length byte
- mov al,'/' ; Put the switch into the command line
- stosb
- mov al,'C'
- stosb
- mov al,' '
- stosb
- mov cx,123 ; Max length we'll use
- StoreCmdLine:
- lodsb ; Get a byte of the command line
- or al,al ; Is it the terminator?
- jz NoMoreCmdLine ; Yep. No more command line
- stosb ; Put that baby away
- inc byte ptr ss:[bx] ; Increment line length
- loop StoreCmdLine ; Loop for max or until terminator
- NoMoreCmdLine:
- mov al,0dh ; Put in terminating <cr>
- stosb
- pop bx ; Get pointer to file name back
- mov ax,sp ; Get the pointer to command line
- push ss ; Put pointer on the stack
- push ax ; (dword pointer)
- StackFNPointer:
- push ss
- inc bx
- push bx ; Put pointer to file name on stack
- call run_program ; Run the program
- sub bp,10
- mov sp,bp ; Cut the stack back
- restore ; Get registers back
- add bp,10
- cmp CommandFlag,0 ; Did we use a command line?
- jnz PopLess ; No, so pop fewer bytes
- pop bp ; Restore fp
- ret 6 ; Return to caller
- ;
- PopLess:
- pop bp ; Restore fp
- ret 2 ; Return with smaller stack cutback
-
- dos_command endp
-
-
- cseg ends
-
- end
-