home *** CD-ROM | disk | FTP | other *** search
- PAGE 55,132
- ;
- ; name exec -- system call for .EXE files
- ;
- ; synopsis status = exec(cmd);
- ; int status; error returns
- ; char *cmd; command to execute
- ;
- ;
- ; description This function accepts a string with the pathname and
- ; parameters of a command to be executed and executes it.
- ; See Appendix F. of the DOS 2.0 Reference Manual for more
- ; information.
- ;
- ; returns 0: Successful
- ; -1: Insufficient Memory
- ; -2: Access Denied
- ; -3: No such command
- ; -4: Invalid command format
- ; -5: Memory control blocks destroyed
- ; -6: Invalid memory block address
- ;
- ; cautions Use only with .EXE files built with the Lattice C
- ; compiler, and linked with C.OBJ.
- ;
- ; authors Written by Darrel Plank. Modified from the macro by Brad
- ; Davis (b-davis@utah-cs). The prolog and epilog are modified
- ; from Jim Holtman's macros for Pascal. Modified by Marco Papa
- ; (papa.use-cse@csnet-relay) to work with .EXE files.
- ;
-
- PROLOG MACRO
- PUSH BP
- MOV BP,SP
- ENDM
-
- EPILOG MACRO NUM
- POP BP
- RET
- ENDM
-
- EXECVAL EQU 0
- OVLVAL EQU 3
- FNCINT EQU 21H
- SETBLK EQU 4AH
- EXECF EQU 4BH
- CR EQU 0DH
-
- PSP STRUC
- INTVECT DW ?
- TOM DW ?
- RES1 DB ?
- DOSLONG DB 5 DUP (?)
- TERMINA DD ?
- CTRLBRK DD ?
- CRITERR DD ?
- DOS1 DB 22 DUP (?)
- ENVIRO DW ?
- DOS2 DB 46 DUP (?)
- FPA1 DB 16 DUP (?)
- FPA2 DB 20 DUP (?)
- UPA DB 128 DUP (?)
- PSP ENDS
-
- EXECDEF STRUC
- NENVIRO DW
- COMMND DW 2 DUP (0)
- FCB5CH DW 2 DUP (0)
- FCB6CH DW 2 DUP (0)
- EXECDEF ENDS
-
- PGROUP GROUP PROG
- PROG SEGMENT BYTE PUBLIC 'prog'
- ASSUME CS:PGROUP
-
- PUBLIC EXEC
- EXEC PROC NEAR
- PROLOG
- PUSH DS
- PUSH ES
- ;
- ; free up as much memory as we can
- ;
- MOV AX,CS ; Code Segment to AX
- PUSH ES ; Save ES for later
- SUB AX,10H ; point to PSP ****
- MOV ES,AX
- MOV BX,SS
- SUB BX,AX
- ADD BX,1000H ; 64K for stack segment
- MOV AH,SETBLK
- INT FNCINT
- JNC NEAR PTR LBL1
- POP ES
- JMP NEAR PTR LBL2
- LBL1: POP ES ; Get ES's original value
- ;
- ; Save SS and SP registers
- ;
- MOV CS:SPSAVE,SP
- MOV CS:SSSAVE,SS
- ;
- ; set up the parameter block
- ;
- MOV CS:EXECBLK.NENVIRO,0 ; Inherit envir. from parent
- MOV AX,3700H ; Undocumented call for SWITCHAR
- ;
- ; W A R N I N G: The following function call is undocumented and is
- ; liable to disappear or change in future versions of DOS.
- ;
- INT FNCINT
- MOV CS:COMMAND[1],DL ; Switchar
- MOV DX,4[BP] ; Address of the command
- MOV SI,DX
- MOV DI,DX
- CLD
- XOR AL,AL
- MOV CX,100H ; Longest string can be 100h
- REPNE SCASB ; Find Null termination
- SUB DX,DI
- NEG DX
- MOV CX,DX
- DEC CX
- ADD DX,2
- MOV CS:COMMAND[0],DL ; Save command length
- LEA DI,CS:COMMAND[4]
- MOV AX,CS
- MOV ES,AX
- REP MOVSB ; Copy command into our buffer
- ASSUME DS:PGROUP
- MOV AX,CS
- MOV DS,AX ; DS points at code segment
- MOV BYTE PTR [DI],CR ; Put in Carriage Return
- LEA DX,COMMAND
- MOV EXECBLK.COMMND[0],DX
- MOV EXECBLK.COMMND[2],DS
- MOV BX,OFFSET EXECBLK
- SUB AX,10H ; AH points to PSP ****
- MOV DS,AX ; DS points to PSP also ****
- XOR SI,SI
- MOV DS,[SI].ENVIRO ; Get environment address
- ASSUME DS:NOTHING
- LEA SI,CS:COMSPEC ; Point SI at env. variable name
- PUSH DS ; Swap
- PUSH ES ; ES
- POP DS ; and
- POP ES ; DS
- CALL GETENV
- PUSH DS ; Swap
- PUSH ES ; them
- POP DS ; back
- POP ES ; again
- MOV AH,EXECF
- MOV AL,EXECVAL ; OVLVAL here for overlay
- INT FNCINT
- MOV SS,CS:SSSAVE
- MOV SP,CS:SPSAVE
- JC NEAR PTR LBL2
- MOV AX,0 ; Successful exec
- JMP NEAR PTR FINE
- LBL2: MOV SI,AX
- MOV AL,CS:ERRORS[SI] ; Get error code
- MOV AH,0FFH ; Sign extension - Assume Negative
- FINE: POP ES
- POP DS
- EPILOG 1
- EXECBLK EXECDEF <>
- ;
- ; first byte of command is length excluding the length byte and the
- ; trailing \r. Second byte is switchar.
- ;
- COMMAND DB 2 DUP(?),"C ",254 DUP(?)
- COMSPEC DB "COMSPEC",0
- SPSAVE DW
- SSSAVE DW
- ERRORS DB ?
- DB ?
- DB -3 ; No such command
- DB ?
- DB ?
- DB -2 ; Access denied
- DB ?
- DB -5 ; Memory control blocks destroyed
- DB -1 ; Insufficient memory
- DB -6 ; Invalid memory block address
- DB ?
- DB -4 ; Invalid command format
-
- EXEC ENDP
-
- ;
- ; Getenv expects ES to have the environment paragraph and DS:SI to point
- ; to an ASCIIZ string with the desired environment variable in it.
- ; It returns the address of the proper string in ES:DX.
- ;
-
- PUBLIC GETENV
- GETENV PROC NEAR
-
- PROLOG
- PUSH AX
- PUSH CX
- PUSH SI
- PUSH DI
- MOV CS:VARNAME,SI ; Save offset of env. name
- XOR DI,DI
- ;
- ; At this point ds:si points to dummy variable environment name and
- ; es:di points to environment.
- ;
- CLD ;Forward string operations
- TOP:
- LODSB ;Get a char. of env. name
- CMP AL,0 ;If we're at the end
- JNE NEAR PTR LBL3
- CMP BYTE PTR ES:[DI],'=' ;Check for match
- JNE NEAR PTR LBL4
- ;
- ; We matched
- ;
- INC DI ;Move beyond '='
- MOV DX,DI
- POP DI
- POP SI
- POP CX
- POP AX
- EPILOG 2
- LBL4:
- ;
- ; At this point we found the end of the Env. variable name but it didn't
- ; match because the env. string was too long
- ;
- MOV CX,-1
- REPNE SCASB ;Find the end of the env. string
- CMP BYTE PTR ES:[DI],0
- JNE LBL3
- MOV AX,-1 ;End of environment area
- POP DI
- POP SI
- POP CX
- POP AX
- EPILOG 2
- LBL3:
- ;
- ; Check if the next character matches
- ;
- AND AX,11011111b ;Capitalize the character in ax
- SCASB
- JE TOP
- ;
- ; If we get here we don't have a match so move on
- ;
- MOV SI,CS:VARNAME ;Go back to start of env. string
- XOR AX,AX
- MOV CX,-1
- REPNE SCASB ;Go to next env. variable
- CMP BYTE PTR ES:[DI],0
- JNE TOP
- MOV AX,-1 ;End of environment area
- POP DI
- POP SI
- POP CX
- POP AX
- EPILOG 2
-
- VARNAME DW ?
-
- GETENV ENDP
-
- PROG ENDS
- END
-