746 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			746 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
| 	page ,132
 | ||
| 	title	COMMAND - resident code for COMMAND.COM
 | ||
| 	name	COMMAND
 | ||
| ;/*
 | ||
| ; *                      Microsoft Confidential
 | ||
| ; *                      Copyright (C) Microsoft Corporation 1991
 | ||
| ; *                      All Rights Reserved.
 | ||
| ; */
 | ||
| 
 | ||
| ;*****************************************************************************
 | ||
| ;
 | ||
| ; MODULE:	       COMMAND.COM
 | ||
| ;
 | ||
| ; DESCRIPTIVE NAME:    Default DOS command interpreter
 | ||
| ;
 | ||
| ; FUNCTION:	       This version of COMMAND is divided into three distinct
 | ||
| ;		       parts.  First is the resident portion, which includes
 | ||
| ;		       handlers for interrupts	23H (Cntrl-C), 24H (fatal
 | ||
| ;		       error), and 2EH (command line execute); it also has
 | ||
| ;		       code to test and, if necessary, reload the transient
 | ||
| ;		       portion. Following the resident is the init code, which
 | ||
| ;		       is overwritten after use.  Then comes the transient
 | ||
| ;		       portion, which includes all command processing (whether
 | ||
| ;		       internal or external).  The transient portion loads at
 | ||
| ;		       the end of physical memory, and it may be overlayed by
 | ||
| ;		       programs that need as much memory as possible. When the
 | ||
| ;		       resident portion of command regains control from a user
 | ||
| ;		       program, a check sum is performed on the transient
 | ||
| ;		       portion to see if it must be reloaded.  Thus programs
 | ||
| ;		       which do not need maximum memory will save the time
 | ||
| ;		       required to reload COMMAND when they terminate.
 | ||
| ;
 | ||
| ; ENTRY POINT:	       PROGSTART
 | ||
| ;
 | ||
| ; INPUT:	       command line at offset 81H
 | ||
| ;
 | ||
| ; EXIT_NORMAL:	       No exit from root level command processor.  Can exit
 | ||
| ;		       from a secondary command processor via the EXIT
 | ||
| ;		       internal command.
 | ||
| ;
 | ||
| ; EXIT_ERROR:	       Exit to prior command processor if possible, otherwise
 | ||
| ;		       hang the system.
 | ||
| ;
 | ||
| ; INTERNAL REFERENCES:
 | ||
| ;
 | ||
| ;     ROUTINES:        See the COMMAND Subroutine Description Document
 | ||
| ;		       (COMMAND.DOC)
 | ||
| ;
 | ||
| ;     DATA AREAS:      See the COMMAND Subroutine Description Document
 | ||
| ;		       (COMMAND.DOC)
 | ||
| ;
 | ||
| ; EXTERNAL REFERENCES:
 | ||
| ;
 | ||
| ;      ROUTINES:       none
 | ||
| ;
 | ||
| ;      DATA AREAS:     none
 | ||
| ;
 | ||
| ;*****************************************************************************
 | ||
| ;
 | ||
| ;			      REVISION HISTORY
 | ||
| ;			      ----------------
 | ||
| ;
 | ||
| ; DOS 1.00 to DOS 3.30
 | ||
| ; --------------------------
 | ||
| ; SEE REVISION LOG IN COPY.ASM ALSO
 | ||
| ;
 | ||
| ; REV 1.17
 | ||
| ;    05/19/82  Fixed bug in BADEXE error (relocation error must return to
 | ||
| ;	       resident since the EXELOAD may have overwritten the transient.
 | ||
| ;
 | ||
| ; REV 1.18
 | ||
| ;    05/21/82  IBM version always looks on drive A
 | ||
| ;	       MSVER always looks on default drive
 | ||
| ;
 | ||
| ; REV 1.19
 | ||
| ;    06/03/82  Drive spec now entered in command line
 | ||
| ;    06/07/82  Added VER command (print DOS version number) and VOL command
 | ||
| ;	       (print volume label)
 | ||
| ;
 | ||
| ; REV 1.20
 | ||
| ;    06/09/82  Prints "directory" after directories
 | ||
| ;    06/13/82  MKDIR, CHDIR, PWD, RMDIR added
 | ||
| ;
 | ||
| ; REV 1.50
 | ||
| ;	       Some code for new 2.0 DOS, sort of HACKey.  Not enough time to
 | ||
| ;	       do it right.
 | ||
| ;
 | ||
| ; REV 1.70
 | ||
| ;	       EXEC used to fork off new processes
 | ||
| ;
 | ||
| ; REV 1.80
 | ||
| ;	       C switch for single command execution
 | ||
| ;
 | ||
| ; REV 1.90
 | ||
| ;	       Batch uses XENIX
 | ||
| ;
 | ||
| ; Rev 2.00
 | ||
| ;	       Lots of neato stuff
 | ||
| ;	       IBM 2.00 level
 | ||
| ;
 | ||
| ; Rev 2.01
 | ||
| ;	       'D' switch for date time suppression
 | ||
| ;
 | ||
| ; Rev 2.02
 | ||
| ;	       Default userpath is NUL rather than BIN
 | ||
| ;		       same as IBM
 | ||
| ;	       COMMAND split into pieces
 | ||
| ;
 | ||
| ; Rev 2.10
 | ||
| ;	       INTERNATIONAL SUPPORT
 | ||
| ;
 | ||
| ; Rev 2.50
 | ||
| ;	       all the 2.x new stuff -MU
 | ||
| ;
 | ||
| ; Rev 3.30     (Ellen G)
 | ||
| ;	       CALL internal command (TBATCH2.ASM)
 | ||
| ;	       CHCP internal command (TCMD2B.ASM)
 | ||
| ;	       INT 24H support of abort, retry, ignore, and fail prompt
 | ||
| ;	       @ sign suppression of batch file line
 | ||
| ;	       Replaceable environment value support in batch files
 | ||
| ;	       INT 2FH calls for APPEND
 | ||
| ;	       Lots of PTR fixes!
 | ||
| ;
 | ||
| ; Beyond 3.30 to forever  (Ellen G)
 | ||
| ; ----------------------
 | ||
| ;
 | ||
| ; A000 DOS 4.00  -	Use SYSPARSE for internal commands
 | ||
| ;			Use Message Retriever services
 | ||
| ;			/MSG switch for resident extended error msg
 | ||
| ;			Convert to new capitalization support
 | ||
| ;			Better error recovery on CHCP command
 | ||
| ;			Code page file tag support
 | ||
| ;			TRUENAME internal command
 | ||
| ;			Extended screen line support
 | ||
| ;			/P switch on DEL/ERASE command
 | ||
| ;			Improved file redirection error recovery
 | ||
| ;	(removed)	Improved batch file performance
 | ||
| ;			Unconditional DBCS support
 | ||
| ;			Volume serial number support
 | ||
| ;	(removed)	COMMENT=?? support
 | ||
| ;
 | ||
| ; A001	PTM P20 	Move system_cpage from TDATA to TSPC
 | ||
| ;
 | ||
| ; A002	PTM P74 	Fix PRESCAN so that redirection symbols do not
 | ||
| ;			require delimiters.
 | ||
| ;
 | ||
| ; A003	PTM P5,P9,P111	Included in A000 development
 | ||
| ;
 | ||
| ; A004	PTM P86 	Fix IF command to turn off piping before
 | ||
| ;			executing
 | ||
| ;
 | ||
| ; A005	DCR D17 	If user specifies an extension on the command
 | ||
| ;			line search for that extension only.
 | ||
| ;
 | ||
| ; A006	DCR D15 	New message for MkDir - "Directory already
 | ||
| ;			exists"
 | ||
| ;
 | ||
| ; A007	DCR D2		Change CTTY so that a write is done before XDUP
 | ||
| ;
 | ||
| ; A008	PTM P182	Change COPY to set default if invalid function
 | ||
| ;			returned from code page call.
 | ||
| ;
 | ||
| ; A009	PTM P179	Add CRLF to invalid disk change message
 | ||
| ;
 | ||
| ; A010	DCR D43 	Allow APPEND to do a far call to SYSPARSE in
 | ||
| ;			transient COMMAND.
 | ||
| ;
 | ||
| ; A011	DCR D130	Change redirection to overwrite an EOF mark
 | ||
| ;			before appending to a file.
 | ||
| ;
 | ||
| ; A012	PTM P189	Fix redirection error recovery.
 | ||
| ;
 | ||
| ; A013	PTM P330	Change date format
 | ||
| ;
 | ||
| ; A014	PTM P455	Fix echo parsing
 | ||
| ;
 | ||
| ; A015	PTM P517	Fix DIR problem with * vs *.
 | ||
| ;
 | ||
| ; A016	PTM P354	Fix extended error message addressing
 | ||
| ;
 | ||
| ; A017	PTM P448	Fix appending to 0 length files
 | ||
| ;
 | ||
| ; A018	PTM P566,P3903	Fix parse error messages to print out parameter
 | ||
| ;			the parser fails on. Fail on duplicate switches.
 | ||
| ;
 | ||
| ; A019	PTM P542	Fix device name to be printed correctly during
 | ||
| ;			critical error
 | ||
| ;
 | ||
| ; A020	DCR D43 	Set append state off while in DIR
 | ||
| ;
 | ||
| ; A021	PTM P709	Fix CTTY printing ascii characters.
 | ||
| ;
 | ||
| ; A022	DCR D209	Enhanced error recovery
 | ||
| ;
 | ||
| ; A023	PTM P911	Fix ANSI.SYS IOCTL structure.
 | ||
| ;
 | ||
| ; A024	PTM P899	Fix EXTOPEN open modes.
 | ||
| ;
 | ||
| ; A025	PTM P922	Fix messages and optimize PARSE switches
 | ||
| ;
 | ||
| ; A026	DCR D191	Change redirection error recovery support.
 | ||
| ;
 | ||
| ; A027	PTM P991	Fix so that KAUTOBAT & AUTOEXEC are terminated
 | ||
| ;			with a carriage return.
 | ||
| ;
 | ||
| ; A028	PTM P1076	Print a blank line before printing invalid
 | ||
| ;			date and invalid time messages.
 | ||
| ;
 | ||
| ; A029	PTM P1084	Eliminate calls to parse_check_eol in DATE
 | ||
| ;			and TIME.
 | ||
| ;
 | ||
| ; A030	DCR D201	New extended attribute format.
 | ||
| ;
 | ||
| ; A031	PTM P1149	Fix DATE/TIME add blank before prompt.
 | ||
| ;
 | ||
| ; A032	PTM P931	Fix =ON, =OFF for BREAK, VERIFY, ECHO
 | ||
| ;
 | ||
| ; A033	PTM P1298	Fix problem with system crashes on ECHO >""
 | ||
| ;
 | ||
| ; A034	PTM P1387	Fix COPY D:fname+,, to work
 | ||
| ;
 | ||
| ; A035	PTM P1407	Fix so that >> (appending) to a device does
 | ||
| ;			do a read to determine eof.
 | ||
| ;
 | ||
| ; A036	PTM P1406	Use 69h instead of 44h to get volume serial
 | ||
| ;			so that ASSIGN works correctly.
 | ||
| ;
 | ||
| ; A037	PTM P1335	Fix COMMAND /C with FOR
 | ||
| ;
 | ||
| ; A038	PTM P1635	Fix COPY so that it doesn't accept /V /V
 | ||
| ;
 | ||
| ; A039	DCR D284	Change invalid code page tag from -1 to 0.
 | ||
| ;
 | ||
| ; A040	PTM P1787	Fix redirection to cause error when no file is
 | ||
| ;			specified.
 | ||
| ;
 | ||
| ; A041	PTM P1705	Close redirected files after internal APPEND
 | ||
| ;			executes.
 | ||
| ;
 | ||
| ; A042	PTM P1276	Fix problem of APPEND paths changes in batch
 | ||
| ;			files causing loss of batch file.
 | ||
| ;
 | ||
| ; A043	PTM P2208	Make sure redirection is not set up twice for
 | ||
| ;			CALL'ed batch files.
 | ||
| ;
 | ||
| ; A044	PTM P2315	Set switch on PARSE so that 0ah is not used
 | ||
| ;			as an end of line character
 | ||
| ;
 | ||
| ; A045	PTM P2560	Make sure we don't lose parse, critical error,
 | ||
| ;			and extended message pointers when we EXIT if
 | ||
| ;			COMMAND /P is the top level process.
 | ||
| ;
 | ||
| ; A046	PTM P2690	Change COPY message "fn File not found" to
 | ||
| ;			"File not found - fn"
 | ||
| ;
 | ||
| ; A047	PTM P2819	Fix transient reload prompt message
 | ||
| ;
 | ||
| ; A048	PTM P2824	Fix COPY path to be upper cased.  This was broken
 | ||
| ;			when DBCS code was added.
 | ||
| ;
 | ||
| ; A049	PTM P2891	Fix PATH so that it doesn't accept extra characters
 | ||
| ;			on line.
 | ||
| ;
 | ||
| ; A050	PTM P3030	Fix TYPE to work properly on files > 64K
 | ||
| ;
 | ||
| ; A051	PTM P3011	Fix DIR header to be compatible with prior releases.
 | ||
| ;
 | ||
| ; A052	PTM P3063,P3228 Fix COPY message for invalid filename on target.
 | ||
| ;
 | ||
| ; A053	PTM P2865	Fix DIR to work in 40 column mode.
 | ||
| ;
 | ||
| ; A054	PTM P3407	Code reduction and critical error on single line
 | ||
| ;	PTM P3672	(Change to single parser exported under P3407)
 | ||
| ;
 | ||
| ; A055	PTM P3282	Reset message service variables in INT 23h to fix
 | ||
| ;			problems with breaking out of INT 24h
 | ||
| ;
 | ||
| ; A056	PTM P3389	Fix problem of environment overlaying transient.
 | ||
| ;
 | ||
| ; A057	PTM P3384	Fix COMMAND /C so that it works if there is no space
 | ||
| ;			before the "string".  EX: COMMAND /CDIR
 | ||
| ;
 | ||
| ; A058	PTM P3493	Fix DBCS so that CPARSE eats second character of
 | ||
| ;			DBCS switch.
 | ||
| ;
 | ||
| ; A059	PTM P3394	Change the TIME command to right align the display of
 | ||
| ;			the time.
 | ||
| ;
 | ||
| ; A060	PTM P3672	Code reduction - change PARSE and EXTENDED ERROR
 | ||
| ;			messages to be disk based.  Only keep them if /MSG
 | ||
| ;			is used.
 | ||
| ;
 | ||
| ; A061	PTM P3928	Fix so that transient doesn't reload when breaking
 | ||
| ;			out of internal commands, due to substitution blocks
 | ||
| ;			not being reset.
 | ||
| ;
 | ||
| ; A062	PTM P4079	Fix segment override for fetching address of environment
 | ||
| ;			of parent copy of COMMAND when no COMSPEC exists in
 | ||
| ;			secondary copy of environment.	Change default slash in
 | ||
| ;			default comspec string to backslash.
 | ||
| ;
 | ||
| ; A063	PTM P4140	REDIRECTOR and IFSFUNC changed interface for getting
 | ||
| ;			text for critical error messages.
 | ||
| ;
 | ||
| ; A064	PTM P4934	Multiplex number for ANSI.SYS changed due to conflict
 | ||
| ;	5/20/88 	with Microsoft product already shipped.
 | ||
| ;
 | ||
| ; A065	PTM P4935	Multiplex number for SHELL changed due to conflict
 | ||
| ;	 5/20/88	with Microsoft product already shipped.
 | ||
| ;
 | ||
| ; A066	PTM P4961	DIR /W /P scrolled first line off the screen in some
 | ||
| ;	 5/24/88	cases; where the listing would barely fit without the
 | ||
| ;			header and space remaining.
 | ||
| ;
 | ||
| ; A067	PTM P5011	For /E: values of 993 to 1024 the COMSPEC was getting
 | ||
| ;	 6/6/88 	trashed.  Turns out that the SETBLOCK for the new
 | ||
| ;			environment was putting a "Z block" marker in the old
 | ||
| ;			environment.  The fix is to move to the old environment
 | ||
| ;			to the new environment before doing the SETBLOCK.
 | ||
| ;
 | ||
| ; A068  PTM P5568       IR79754 APPEND /x:on not working properly with DIR/VOL
 | ||
| ;        09/19/88       because the check for APPEND needed to be performed
 | ||
| ;                       before the DIR's findfirst.
 | ||
| ;
 | ||
| ; A069  PTM P5726       IR80540 COMSPEC_flag not properly initialized and
 | ||
| ;        10/30/88       executed.  Causing AUSTIN problem testing LAN/DW4 re-
 | ||
| ;                       loading trans w/new comspec with no user change comspec.
 | ||
| ;
 | ||
| ; A070  PTM P5734       IR80484 Batch file causes sys workspace to be corrupted.
 | ||
| ;        11/05/88       Expansion of environment variables into batch line of
 | ||
| ;                       128 chars was not being counted and "%" which should be
 | ||
| ;                       ignored were being counted.
 | ||
| ;
 | ||
| ; A071  PTM P5854       IR82061 Invalid COMMAND.COM when Word Perfect, Prompt
 | ||
| ;        03/02/89       used.  Comspec_flag was not in protected data file be-
 | ||
| ;                       ing included in checksum and was being overwritten by
 | ||
| ;                       WP.  Moved var from Tspc to Tdata so Trans would reload.
 | ||
| ;                       Also removed fix A069 (because flag now protected).
 | ||
| ;
 | ||
| ; C001  VERSION 4.1     Add new internal command - SERVICE - to display the DOS
 | ||
| ;        07/25/89       version and CSD version in U.S. date format.  Files
 | ||
| ;                       changed - TRANMSG,.SKL,COMMAND1,TDATA,TCMD2A,USA.MSG
 | ||
| ;
 | ||
| ;***********************************************************************************
 | ||
| 
 | ||
| ;
 | ||
| ;	Revision History
 | ||
| ;	================
 | ||
| ;
 | ||
| ;	M021	SR	08/23/90	Fixed Ctrl-C handler to handle Ctrl-C
 | ||
| ;				at init time (date/time prompt)
 | ||
| ;
 | ||
| 
 | ||
| 
 | ||
| .xcref
 | ||
| .xlist
 | ||
| 	include dossym.inc		; basic DOS symbol set
 | ||
| 	include syscall.inc		; DOS function names
 | ||
| 	include comsw.asm		; build version info
 | ||
| 	include comequ.asm		; common command.com symbols
 | ||
| 	include resmsg.equ		; resident message names
 | ||
| 
 | ||
| 	include comseg.asm		;segment ordering
 | ||
| .list
 | ||
| .cref
 | ||
| 
 | ||
| CODERES segment public byte
 | ||
| CODERES ends
 | ||
| 
 | ||
| DATARES 	segment public byte
 | ||
| 		extrn	AccDen:byte
 | ||
| 		extrn	Batch:word
 | ||
| 		extrn	EchoFlag:byte
 | ||
| 		extrn	ExeBad:byte
 | ||
| 		extrn	ExecEMes:byte
 | ||
| 		extrn	ExecErrSubst:byte
 | ||
| 		extrn	ExtCom:byte
 | ||
| 		extrn	ForFlag:byte
 | ||
| 		extrn	IfFlag:byte
 | ||
| 		extrn	InitFlag:BYTE
 | ||
| 		extrn	Nest:word
 | ||
| 		extrn	PipeFlag:byte
 | ||
| 		extrn	RBadNam:byte
 | ||
| 		extrn	RetCode:word
 | ||
| 		extrn	SingleCom:word
 | ||
| 		extrn	TooBig:byte
 | ||
| 
 | ||
| 		extrn	OldDS:word
 | ||
|                 EXTRN   SCS_REENTERED:BYTE
 | ||
|                 EXTRN   SCS_CMDPROMPT:BYTE
 | ||
| 
 | ||
| DATARES 	ends
 | ||
| 
 | ||
| 
 | ||
| INIT		segment public para
 | ||
| 		extrn	ConProc:near
 | ||
| 		extrn	Init_Contc_SpecialCase:near
 | ||
| INIT		ends
 | ||
| 
 | ||
| 
 | ||
| 		include envdata.asm
 | ||
| 
 | ||
| Prompt32        equ     1
 | ||
| 
 | ||
| ;***	START OF RESIDENT PORTION
 | ||
| 
 | ||
| CODERES segment public byte
 | ||
| 
 | ||
| 	public	Ext_Exec
 | ||
| 	public	ContC
 | ||
| 	public	Exec_Wait
 | ||
| 	public	Exec_Ret
 | ||
| 
 | ||
| 	assume	cs:CODERES,ds:NOTHING,es:NOTHING,ss:NOTHING
 | ||
| 
 | ||
| 	extrn	LodCom:near
 | ||
| 	extrn	LodCom1:near
 | ||
| 
 | ||
| 	org	0
 | ||
| Zero	=	$
 | ||
| 
 | ||
| ;;	org	80h - 1
 | ||
| ;;ResCom	label byte
 | ||
| ;;	public	ResCom
 | ||
| 
 | ||
| ;;	org	100h
 | ||
| 
 | ||
| public	StartCode
 | ||
| StartCode:
 | ||
| ;;	jmp	RESGROUP:ConProc
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| ;***	EXEC error handling
 | ||
| ;
 | ||
| ;	COMMAND has issued an EXEC system call and it has returned an error.
 | ||
| ;	We examine the error code and select an appropriate message.
 | ||
| 
 | ||
| ;	Bugbug:	optimize reg usage in following code?  Careful of DX!
 | ||
| ;	Condense the error scan?
 | ||
| ;	RBADNAM is checked by transient, no need here?
 | ||
| ;	Move below Ext_Exec.
 | ||
| 
 | ||
| Exec_Err:
 | ||
| ;SR;
 | ||
| ; ds,es are setup when the transient jumps to Ext_Exec. So segment regs are
 | ||
| ;in order here
 | ||
| 
 | ||
| 	assume	ds:DATARES,es:DATARES
 | ||
| 
 | ||
| ;	Bugbug:	can we use byte compares here?
 | ||
| ;	Might be able to use byte msg#s, too.
 | ||
| 
 | ||
| ;	Store errors in a 3 or 4 byte table.  Msg #s in another.
 | ||
| ;	Speed not high priority here.
 | ||
| 
 | ||
| ;	Move this to transient.
 | ||
| 
 | ||
| 	mov	bx,offset DATARES:RBadNam
 | ||
| 	cmp	al,ERROR_FILE_NOT_FOUND
 | ||
| 	je	GotExecEMes		  	; bad command
 | ||
| 	mov	bx,offset DATARES:TooBig
 | ||
| 	cmp	al,ERROR_NOT_ENOUGH_MEMORY
 | ||
| 	je	GotExecEMes		 	; file not found
 | ||
| 	mov	bx,offset DATARES:ExeBad
 | ||
| 	cmp	al,ERROR_BAD_FORMAT
 | ||
| 	je	GotExecEMes		 	; bad exe file
 | ||
| 	mov	bx,offset DATARES:AccDen
 | ||
| 	cmp	al,ERROR_ACCESS_DENIED
 | ||
| 	je	GotExecEMes		 	; access denied
 | ||
| 
 | ||
| Default_Message:
 | ||
| 	mov	bx,offset DATARES:ExecEMes	; default message
 | ||
| 	mov	si,offset DATARES:ExecErrSubst ; get address of subst block
 | ||
| 
 | ||
| GotExecEMes:
 | ||
|         mov     dx,bx                           ; DX = ptr to msg
 | ||
| ;; williamh: no reason of doing this. When command.com receives a command,
 | ||
| ;;	     it means the VDM process has been created successfully and there
 | ||
| ;;	     is no way for the parent process to know that we are not able
 | ||
| ;;	     to launch the program and therefore, it won't display any error
 | ||
| ;;	     message for us.
 | ||
| ;;	 cmp	 byte ptr [scs_reentered],1
 | ||
| ;;	 jne	 NoErrMsg
 | ||
| ;;	 cmp	 byte ptr [scs_cmdprompt],Prompt32
 | ||
| ;;	 je	 NoErrMsg
 | ||
|         invoke  RPrint
 | ||
| NoErrMsg:
 | ||
| 	jmp	short NoExec
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| ;***	EXEC call
 | ||
| ;
 | ||
| ;	The transient has set up everything for an EXEC system call.
 | ||
| ;	For cleanliness, we issue the EXEC here in the resident 
 | ||
| ;	so that we may be able to recover cleanly upon success.
 | ||
| ;
 | ||
| ;	CS,DS,ES,SS = DATARES seg addr
 | ||
| 
 | ||
| Ext_Exec:
 | ||
| ;SR;
 | ||
| ; The words put on the stack by the stub will be popped off when we finally
 | ||
| ;jump to LodCom ( by LodCom).
 | ||
| ;
 | ||
| ;;	int	21h			; do the exec
 | ||
| 
 | ||
| Exec_Ret:
 | ||
| 	jc	Exec_Err		; exec failed
 | ||
| 
 | ||
| ;	The exec has completed.  Retrieve the exit code.
 | ||
| 
 | ||
| Exec_Wait:
 | ||
| 	mov	ah,WAITPROCESS		; get errorlevel
 | ||
| 	int	21h			; get the return code
 | ||
| 	mov	RetCode,ax
 | ||
| 
 | ||
| ;	See if we can reload the transient.  The external command
 | ||
| ;	may have overwritten part of the transient.
 | ||
| 
 | ||
| NoExec:
 | ||
| ;SR;
 | ||
| ; ds = es = ss = DATARES when we jump to LodCom
 | ||
| ;
 | ||
| 	jmp	LodCom
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| ;***	Int 23 (ctrl-c) handler
 | ||
| ;
 | ||
| ;	This is the default system INT 23 handler.  All processes
 | ||
| ;	(including COMMAND) get it by default.  There are some
 | ||
| ;	games that are played:  We ignore ^C during most of the
 | ||
| ;	INIT code.  This is because we may perform an ALLOC and
 | ||
| ;	diddle the header!  Also, if we are prompting for date/time
 | ||
| ;	in the init code, we are to treat ^C as empty responses.
 | ||
| 
 | ||
| 
 | ||
| ;	Bugbug:	put init ctrl-c handling in init module.
 | ||
| 
 | ||
| ;SR;
 | ||
| ; The stub has pushed the previous ds and DATARES onto the stack. We get
 | ||
| ;both these values off the stack now
 | ||
| ;
 | ||
| ContC	proc	far
 | ||
| 
 | ||
| 	assume	cs:CODERES,ds:NOTHING,es:NOTHING,ss:NOTHING
 | ||
| 
 | ||
| 	pop	ds			;ds = DATARES
 | ||
| 	assume	ds:DATARES
 | ||
| ;	pop	OldDS			;OldDS = old ds
 | ||
| 
 | ||
| 	test	InitFlag,INITINIT		; in initialization?
 | ||
| 	jz	NotAtInit			; no
 | ||
| 	test	InitFlag,INITSPECIAL		; doing special stuff?
 | ||
| 	jz	CmdIRet 			; no, ignore ^C
 | ||
| 	pop	ds			; restore before jumping; M021
 | ||
| 	jmp	RESGROUP:Init_ContC_SpecialCase ; Yes, go handle it
 | ||
| CmdIret:
 | ||
| ;SR;
 | ||
| ; Restore ds to its previous value
 | ||
| ;
 | ||
| 
 | ||
| ;	mov	ds,OLdDS		;
 | ||
| 	pop	ds
 | ||
| 	iret				; yes, ignore the ^C
 | ||
| 
 | ||
| NotAtInit:
 | ||
| 	test	InitFlag,INITCTRLC		; are we already in a ^C?
 | ||
| 	jz	NotInit 			; nope too.
 | ||
| 
 | ||
| ;*	We are interrupting ourselves in this ^C handler.  We need
 | ||
| ;	to set carry and return to the user sans flags only if the
 | ||
| ;	system call was a 1-12 one.  Otherwise, we ignore the ^C.
 | ||
| 
 | ||
| 	cmp	ah,1
 | ||
| 	jb	CmdIRet
 | ||
| 	cmp	ah,12
 | ||
| 	ja	CmdIRet
 | ||
| 
 | ||
| 	pop	ds			;restore ds to old value
 | ||
| 	add	sp,6				; remove int frame
 | ||
| 	stc
 | ||
| 
 | ||
| ;	mov	ds,OldDS		;restore ds to its old value
 | ||
| 	ret	2				; remove those flags...
 | ||
| 
 | ||
| NotInit:
 | ||
| 
 | ||
| ;*	We have now received a ^C for some process (maybe ourselves
 | ||
| ;	but not at INIT).
 | ||
| ;	
 | ||
| ;	Note that we are running on the user's stack!!!  Bad news if
 | ||
| ;	any of the system calls below go and issue another INT
 | ||
| ;	24...  Massive stack overflow!  Another bad point is that
 | ||
| ;	SavHand will save an already saved handle, thus losing a
 | ||
| ;	possible redirection...
 | ||
| ;	
 | ||
| ;	All we need to do is set the flag to indicate nested ^C. 
 | ||
| ;	The above code will correctly flag the ^C diring the
 | ||
| ;	message output and prompting while ignoring the ^C the rest
 | ||
| ;	of the time.
 | ||
| ;	
 | ||
| ;	Clean up: flush disk.  If we are in the middle of a batch
 | ||
| ;	file, we ask if he wants to terminate it.  If he does, then
 | ||
| ;	we turn off all internal flags and let the DOS abort.
 | ||
| 
 | ||
| 	or	InitFlag,INITCTRLC	; nested ^c is on
 | ||
| 	sti
 | ||
| 
 | ||
| ;;	push	cs			; el yucko!  change the user's ds!!
 | ||
| ;;	pop	ds
 | ||
| ;;	assume	ds:RESGROUP
 | ||
| 
 | ||
| 	pop	ax			;discard the old ds value
 | ||
| 
 | ||
| 	mov	ax,SingleCom
 | ||
| 	or	ax,ax
 | ||
| 	jnz	NoReset
 | ||
| 	push	ax
 | ||
| 	mov	ah,DISK_RESET
 | ||
| 	int	21h			; reset disks in case files were open
 | ||
| 	pop	ax
 | ||
| 
 | ||
| NoReset:
 | ||
| 
 | ||
| ;	In the generalized version of FOR, PIPE and BATCH, we would
 | ||
| ;	walk the entire active list and free each segment.  Here,
 | ||
| ;	we just free the single batch segment.
 | ||
| 
 | ||
| 	test	Batch,-1
 | ||
| 	jz	ContCTerm
 | ||
| 	or	ax,ax
 | ||
| 	jnz	ContCTerm
 | ||
| 	invoke	SavHand
 | ||
| 	invoke	AskEnd			; ask if user wants to end batch
 | ||
| 
 | ||
| ;	If the carry flag is clear, we do NOT free up the batch file
 | ||
| 
 | ||
| 	jnc	ContBatch
 | ||
| 	mov	cl,EchoFlag		; get current echo flag
 | ||
| 	push	bx
 | ||
| 
 | ||
| ClearBatch:
 | ||
| 	mov	es,Batch		; get batch segment
 | ||
| 	mov	di,BatFile		; get offset of batch file name
 | ||
| ;	Bugbug:	verify the following shell interface still works
 | ||
| ;;	mov	ax,MULT_SHELL_BRK	; does the SHELL want this terminated?
 | ||
| ;;	int	2Fh			; call the SHELL
 | ||
| ;;	cmp	al,SHELL_ACTION 	; does shell want this batch?
 | ||
| ;;	je	Shell_Bat_Cont		; yes - keep it
 | ||
| 
 | ||
| 	mov	bx,es:BatForPtr		; get old FOR segment
 | ||
| 	cmp	bx,0			; is a FOR in progress
 | ||
| 	je	no_bat_for		; no - don't deallocate
 | ||
| 	push	es			;
 | ||
| 	mov	es,bx			; yes - free it up...
 | ||
| 	mov	ah,DEALLOC		;
 | ||
| 	int	21h			;
 | ||
| 	pop	es			; restore to batch segment
 | ||
| 
 | ||
| No_Bat_For:
 | ||
| 	mov	cl,es:BatEchoFlag	; get old echo flag
 | ||
| 	mov	bx,es:BatLast	 	; get old batch segment
 | ||
| 	mov	ah,DEALLOC		; free it up...
 | ||
| 	int	21h
 | ||
| 	mov	Batch,bx		; get ready to deallocate next batch
 | ||
| 	dec	nest			; is there another batch file?
 | ||
| 	jnz	ClearBatch		; keep going until no batch file
 | ||
| 
 | ||
| 
 | ||
| ;	We are terminating a batch file; restore the echo status
 | ||
| 
 | ||
| 
 | ||
| Shell_Bat_Cont: 			; continue batch for SHELL
 | ||
| 
 | ||
| 	pop	bx
 | ||
| 	mov	EchoFlag,cl		; reset echo status
 | ||
| 	mov	PipeFlag,0		; turn off pipeflag
 | ||
| ContBatch:
 | ||
| 	invoke	Crlf			; print out crlf before returning
 | ||
| 	invoke	RestHand
 | ||
| 
 | ||
| ;	Yes, we are terminating.  Turn off flags and allow the DOS to abort.
 | ||
| 
 | ||
| ContCTerm:
 | ||
| 	xor	ax,ax			; indicate no read
 | ||
| 	mov	bp,ax
 | ||
| 
 | ||
| ;	The following resetting of the state flags is good for the
 | ||
| ;	generalized batch processing.
 | ||
| 
 | ||
| 	mov	IfFlag,al		; turn off iffing
 | ||
| 	mov	ForFlag,al		; turn off for processing
 | ||
| 	call	ResPipeOff
 | ||
| 	cmp	SingleCom,ax		; see if we need to set singlecom
 | ||
| 	jz	NoSetSing
 | ||
| 	mov	SingleCom,-1		; cause termination on 
 | ||
| 					;  pipe, batch, for
 | ||
| NoSetSing:
 | ||
| 
 | ||
| ;	If we are doing an internal command, go through the reload process.
 | ||
| ;	If we are doing an external, let DOS abort the process.
 | ||
| ;	In both cases, we are now done with the ^C processing.
 | ||
| 
 | ||
| 	and	InitFlag,not INITCTRLC
 | ||
| 	cmp	ExtCom,al
 | ||
| 	jnz	DoDAb				; internal ^c
 | ||
| 	jmp	LodCom1
 | ||
| DoDAb:
 | ||
| 	stc					; tell dos to abort
 | ||
| 
 | ||
| ;SR;
 | ||
| ;We dont need to restore ds here because we are forcing DOS to  do an abort
 | ||
| ;by setting carry and leaving flags on the stack
 | ||
| ;
 | ||
| 	ret					; Leave flags on stack
 | ||
| ContC	endp
 | ||
| 
 | ||
| 
 | ||
| ;SR;
 | ||
| ; ds = DATARES on entry. This routine is called from DskErr and LodCom1 and
 | ||
| ;both have ds = DATARES
 | ||
| ;
 | ||
| 
 | ||
| ResPipeOff:
 | ||
| 	public	ResPipeOff
 | ||
| 
 | ||
| 	assume	ds:DATARES,es:NOTHING
 | ||
| 
 | ||
| 	savereg <ax>
 | ||
| 	xor	ax,ax
 | ||
| 	xchg	PipeFlag,al
 | ||
| 	or	al,al
 | ||
| 	jz	NoPipePop
 | ||
| 	shr	EchoFlag,1
 | ||
| NoPipePop:
 | ||
| 	restorereg  <ax>
 | ||
| 	return
 | ||
| 
 | ||
| 
 | ||
| CODERES ends
 | ||
| 	end
 | ||
| 
 |