	page ,132
;	SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
;	SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
TITLE	PART4 COMMAND Transient routines.
;/*
; *                      Microsoft Confidential
; *                      Copyright (C) Microsoft Corporation 1991
; *                      All Rights Reserved.
; */

;	Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER

.xlist
.xcref
	include dossym.inc
	include bpb.inc
	include syscall.inc
	include filemode.inc
	include sf.inc
	include comseg.asm
	include comsw.asm		;ac000;
	include comequ.asm
	include ioctl.inc		;an000;
.list
.cref

DATARES SEGMENT PUBLIC BYTE             ;AN020;AC068;
        EXTRN   append_flag:byte        ;AN020;AC068;
        EXTRN   append_state:word       ;AN020;AC068;
DATARES ENDS                            ;AN020;AC068;

TRANDATA	SEGMENT PUBLIC BYTE	;AC000;
	EXTRN	badcpmes_ptr:word	;AC022;
	EXTRN	Extend_buf_ptr:word	;AC000;
	EXTRN	Extend_buf_sub:byte	;AN000;
	EXTRN	inornot_ptr:word
	EXTRN	msg_disp_class:byte	;AC000;
	EXTRN	parse_erase:byte	;AC000;
	EXTRN	parse_mrdir:byte	;AC000;
	EXTRN	parse_rename:byte	;AC000;
	EXTRN	parse_vol:byte		;AC000;
	EXTRN	PauseMes_ptr:word
	EXTRN	renerr_ptr:word
	EXTRN	slash_p_syn:word	;AC000;
	EXTRN	volmes_ptr:word 	;AC000;
	EXTRN	volmes_ptr_2:word	;AC000;
	EXTRN	volsermes_ptr:word	;AC000;
TRANDATA	ENDS

TRANSPACE	SEGMENT PUBLIC BYTE	;AC000;
	EXTRN	bytcnt:word
	EXTRN	charbuf:byte
	EXTRN	comsw:word
	EXTRN	curdrv:byte
	EXTRN	destinfo:byte
	EXTRN	destisdir:byte
	EXTRN	dirbuf:byte
	EXTRN	msg_numb:word		;AN022;
	EXTRN	one_char_val:byte
	EXTRN	parse1_addr:dword	;AN000;
	EXTRN	parse1_syn:word 	;AN000;
        EXTRN   resseg:word             ;AN020;AC068;
	EXTRN	srcbuf:byte		;AN000;
	EXTRN	string_ptr_2:word	;AN000;
	EXTRN	TPA:word
	EXTRN	vol_drv:byte
	EXTRN	vol_ioctl_buf:byte	;AC000;
	EXTRN	vol_label:byte		;AC000;
	EXTRN	vol_serial:dword	;AC000;
	EXTRN	zflag:byte

	extrn	TypeFilSiz:dword
TRANSPACE	ENDS

TRANCODE	SEGMENT PUBLIC BYTE

ASSUME	CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

;---------------

TRANSPACE	SEGMENT PUBLIC BYTE	;AC000;
	EXTRN	arg:byte		; the arg structure!
transpace   ends
;---------------

	EXTRN	cerror:near
	EXTRN	error_output:near
	EXTRN	notest2:near
	EXTRN	slashp_erase:near	;AN000;
	EXTRN	std_printf:near
	EXTRN	tcommand:near

	PUBLIC	badpath_err		;AN022;
	PUBLIC	crename
	PUBLIC	DisAppend
	PUBLIC	erase
	PUBLIC	extend_setup		;AN022;
	PUBLIC	Get_ext_error_number	;AN022;
	PUBLIC	pause
	PUBLIC	Set_ext_error_msg	;AN000;
	PUBLIC	typefil
	PUBLIC	volume


assume	ds:trangroup,es:trangroup

	break	Pause
assume	ds:trangroup,es:trangroup

PAUSE:
	mov	dx,offset trangroup:pausemes_ptr
	call	std_printf
	invoke	GetKeystroke
	invoke	crlf2
	return

	break	Erase

;****************************************************************
;*
;* ROUTINE:	DEL/ERASE - erase file(s)
;*
;* FUNCTION:	PARSE command line for file or path name and /P
;*		and invoke PATHCRUNCH.	If an error occurs, set
;*		up an error message and transfer control to CERROR.
;*		Otherwise, transfer control to NOTEST2 if /P not
;*		entered or SLASHP_ERASE if /P entered.
;*
;* INPUT:	command line at offset 81H
;*
;* OUTPUT:	if no error:
;*		FCB at 5ch set up with filename(s) entered
;*		Current directory set to entered directory
;*
;****************************************************************

assume	ds:trangroup,es:trangroup

ERASE:
	mov	si,81H				;AC000; get command line
	mov	comsw,0 			;AN000; clear switch indicator
	mov	di,offset trangroup:parse_erase ;AN000; Get adderss of PARSE_erase
	xor	cx,cx				;AN000; clear cx,dx

erase_scan:
	xor	dx,dx				;AN000;
	invoke	parse_with_msg			;AC018; call parser
	cmp	ax,end_of_line			;AN000; are we at end of line?
	jz	good_line			;AN000; yes - done parsing
	cmp	ax,result_no_error		;AC000; did we have an error?
	jnz	errj2				;AC000; yes exit

	cmp	parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered?
	je	set_erase_prompt		;AN000; yes - go set prompt

;
; Must be filespec since no other matches occurred. move filename to srcbuf
;
	push	si				;AC000; save position in line
	lds	si,parse1_addr			;AC000; get address of filespec
	cmp	byte ptr[si+1],colon_char	;AC000; drive specified?
	jnz	Erase_drive_ok			;AC000; no - continue
	cmp	byte ptr[si+2],end_of_line_out	;AC000; was only drive entered?
	jnz	erase_drive_ok			;AC000; no - continue
	mov	ax,error_file_not_found 	;AN022; get message number in control block
	jmp	short extend_setup		;AC000; exit

erase_drive_ok:
	invoke	move_to_srcbuf			;AC000; move to srcbuf
	pop	si				;AC000; get position back
	jmp	short erase_scan		;AN000; continue parsing

set_erase_prompt:
	cmp	comsw,0 			;AN018; was /P already entered?
	jz	ok_to_set_erase_prompt		;AN018; no go set switch
	mov	ax,moreargs_ptr 		;AN018; set up too many arguments
	invoke	setup_parse_error_msg		;AN018; set up an error message
	jmp	short errj2			;AN018; exit

ok_to_set_erase_prompt: 			;AN018;
	inc	comsw				;AN000; indicate /p specified
	jmp	short erase_scan		;AN000; continue parsing

good_line:					;G  We know line is good
	invoke	pathcrunch
	jnc	checkdr
	mov	ax,[msg_numb]			;AN022; get message number
	cmp	ax,0				;AN022; was message flag set?
	jnz	extend_setup			;AN022; yes - print out message
	cmp	[destisdir],0			; No CHDIRs worked
	jnz	badpath_err			;AC022; see if they should have

checkdr:
	cmp	comsw,0 			;AN000; was /p specified
	jz	notest2j			;AN000; no - go to notest2
	jmp	slashp_erase			;AN000; yes - go to slashp_erase

notest2j:
	jmp	notest2

badpath_err:					;AN022; "Path not found" message
	mov	ax,error_path_not_found 	;AN022; set up error number

extend_setup:					;AN022;
	mov	msg_disp_class,ext_msg_class	;AN022; set up extended error msg class
	mov	dx,offset TranGroup:Extend_Buf_ptr ;AC022; get extended message pointer
	mov	Extend_Buf_ptr,ax		;AN022; get message number in control block
errj2:						;AC022; exit jump
	jmp	Cerror				;AN022;

	break	Rename

; ****************************************************************
; *
; * ROUTINE:	 CRENAME - rename file(s)
; *
; * FUNCTION:	 PARSE command line for one full filespec and one
; *		 filename.  Invoke PATHCRUNCH on the full filespec.
; *		 Make sure the second filespec only contains a
; *		 filename.  If both openands are valid, attempt
; *		 to rename the file.
; *
; * INPUT:	 command line at offset 81H
; *
; * OUTPUT:	 none
; *
; ****************************************************************

assume	ds:trangroup,es:trangroup

CRENAME:

	mov	si,81H				;AC000; Point to command line
	mov	di,offset trangroup:parse_rename;AN000; Get adderss of PARSE_RENAME
	xor	cx,cx				;AN000; clear cx,dx
	xor	dx,dx				;AN000;
	invoke	parse_with_msg			;AC018; call parser
	cmp	ax,result_no_error		;AC000; did we have an error?
;;	jz	crename_no_parse_error		;AC000; no - continue
	jnz	crename_parse_error		;AC000; Yes, fail. (need long jump)

;
;  Get first file name returned from parse into our buffer
;
crename_no_parse_error:
	push	si				;AN000; save position in line
	lds	si,parse1_addr			;AN000; get address of filespec
	invoke	move_to_srcbuf			;AN000; move to srcbuf
	pop	si				;AN000; restore position in line

	xor	dx,dx				;AN000; clear dx
	invoke	parse_with_msg			;AC018; call parser
	cmp	ax,result_no_error		;AN000; did we have an error?
	JNZ	crename_parse_error		;AN000; Yes, fail.

;
;  Check the second file name for drive letter colon
;
	push	si				;AN000; save position in line
	lds	si,parse1_addr			;AC000; get address of path

	mov	al,':'                          ;AC000;
	cmp	[si+1],al			;AC000; Does the 2nd parm have a drive spec?
	jnz	ren_no_drive			;AN000; Yes, error
	mov	msg_disp_class,parse_msg_class	;AN000; set up parse error msg class
	mov	dx,offset TranGroup:Extend_Buf_ptr  ;AC000; get extended message pointer
	mov	Extend_Buf_ptr,BadParm_ptr	;AN000; get "Invalid parameter" message number

	pop	si				;AN000;
crename_parse_error:				;AC022;
	jmp	short errj			;AC000;

;
;  Get second file name returned from parse into the fCB.  Save
;  character after file name so we can later check to make sure it
;  isn't a path character.
;

ren_no_drive:
	mov	di,FCB+10H			;AC000; set up to parse second file name
	mov	ax,(Parse_File_Descriptor SHL 8) OR 01H ;AC000;
	int	21h			;AC000; do the function
	lodsb					;AC000; Load char after filename
	mov	one_char_val,al 		;AN000; save char after filename
	pop	si				;AN000; get line position back

;
; We have source and target.  See if any args beyond.
;

	mov	di,offset trangroup:parse_rename;AC000; get address of parse_rename
	invoke	parse_check_eol 		;AC000; are we at end of line?
	jnz	crename_parse_error		;AN000; no, fail.

	invoke	pathcrunch
	mov	dx,offset trangroup:badcpmes_ptr
	jz	errj2				; If 1st parm a dir, print error msg
	jnc	notest3
	mov	ax,[msg_numb]			;AN022; get message number
	cmp	ax,0				;AN022; was message flag set?
	jnz	extend_setup			;AN022; yes - print out message
	cmp	[destisdir],0			; No CHDIRs worked
	jz	notest3 			; see if they should have
	Jmp	badpath_err			;AC022; set up error

notest3:
	mov	al,one_char_val 		;AN000; move char into AX
	mov	dx,offset trangroup:inornot_ptr ; Load invalid fname error ptr
	invoke	pathchrcmp			; Is the char in al a path sep?
	jz	errj				; Yes, error - 2nd arg must be
						;  filename only.

	mov	ah,FCB_Rename
	mov	dx,FCB
	int	21h
	cmp	al, 0FFH			; Did an error occur??
	jnz	renameok

	invoke	get_ext_error_number		;AN022; get extended error
	SaveReg <AX>				;AC022; Save results
	mov	al, 0FFH			; Restore original error state

renameok:
	push	ax
	invoke	restudir
	pop	ax
	inc	al
	retnz

	RestoreReg  <AX>			;AC022; get the error number back
	cmp	ax,error_file_not_found 	;AN022; error file not found?
	jz	use_renerr			;AN022; yes - use generic error message
	cmp	ax,error_access_denied		;AN022; error file not found?
	jz	use_renerr			;AN022; yes - use generic error message
	jmp	extend_setup			;AN022; need long jump - use extended error

use_renerr:
	mov	dx,offset trangroup:RenErr_ptr	;AC022;

ERRJ:
	jmp	Cerror

ret56:	ret

	break	Type

;****************************************************************
;*
;* ROUTINE:	TYPEFIL - Display the contents of a file to the
;*		standard output device
;*
;* SYNTAX:	TYPE filespec
;*
;* FUNCTION:	If a valid filespec is found, read the file until
;*		1Ah and display the contents to STDOUT.
;*
;* INPUT:	command line at offset 81H
;*
;* OUTPUT:	none
;*
;****************************************************************

assume	ds:trangroup,es:trangroup

TYPEFIL:
	mov	si,81H
	mov	di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR
	xor	cx,cx				;AN000; clear cx,dx
	xor	dx,dx				;AN000;
	invoke	parse_with_msg			;AC018; call parser
	cmp	ax,result_no_error		;AC000; did we have an error?
	jnz	typefil_parse_error		;AN000; yes - issue error message

	push	si				;AC000; save position in line
	lds	si,parse1_addr			;AC000; get address of filespec
	invoke	move_to_srcbuf			;AC000; move to srcbuf
	pop	si				;AC000; get position back
	mov	di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir
	invoke	parse_check_eol 		;AC000; are we at end of line?
	jz	gottarg 			;AC000; yes - continue

typefil_parse_error:				;AN000; no - set up error message and exit
	jmp	Cerror

gottarg:
	invoke	setpath
	test	[destinfo],00000010b		; Does the filespec contain wildcards
	jz	nowilds 			; No, continue processing
	mov	dx,offset trangroup:inornot_ptr ; Yes, report error
	jmp	Cerror
nowilds:
	mov	ax,ExtOpen SHL 8		;AC000; open the file
	mov	bx,read_open_mode		;AN000; get open mode for TYPE
	xor	cx,cx				;AN000; no special files
	mov	dx,read_open_flag		;AN000; set up open flags
	mov	si,offset trangroup:srcbuf	;AN030; get file name
	int	21h
	jnc	typecont			; If open worked, continue. Otherwise load

Typerr: 					;AN022;
	push	cs				;AN022; make sure we have local segment
	pop	ds				;AN022;
	invoke	set_ext_error_msg		;AN022;
	mov	string_ptr_2,offset trangroup:srcbuf ;AC022; get address of failed string
	mov	Extend_buf_sub,one_subst	;AC022; put number of subst in control block
	jmp	cerror				;AC022; exit

typecont:
	mov	bx,ax				;AC000; get  Handle
;M043
; We should do the LSEEK for filesize only if this handle belongs to a file
;and not if it belongs to a device. If device, set TypeFilSiz+2 to -1 to
;indicate it is a device.
;
	mov	ax,(IOCTL shl 8) or 0
	int	21h

	test	dl,80h				;is it a device?
	jz	not_device			;no, a file

	mov	word ptr TypeFilSiz+2,-1 		;indicate it is a device
	jmp	short dotype
not_device:

;SR;
; Find the filesize by seeking to the end and then reset file pointer to
;start of file
;
	mov	ax,(LSEEK shl 8) or 2
	xor	dx,dx
	mov	cx,dx				;seek  to end of file
	int	21h

	mov	word ptr TypeFilSiz,ax
	mov	word ptr TypeFilSiz+2,dx		;store filesize

	mov	ax,(LSEEK shl 8) or 0
	xor	dx,dx
	int	21h	              			;reset file pointer to start
dotype:						;M043
	mov	zflag,0 			; Reset ^Z flag
	mov	ds,[TPA]
	xor	dx,dx
ASSUME	DS:NOTHING

typelp:
	cmp	cs:[zflag],0			;AC050; Is the ^Z flag set?
	retnz					; Yes, return
	mov	cx,cs:[bytcnt]			;AC056; No, continue
;
;Update the filesize left to read
;
	cmp	word ptr cs:TypeFilSiz+2,-1	;is it a device? M043
	je	typ_read			;yes, just read from it; M043

	cmp	word ptr cs:TypeFilSiz+2,0		;more than 64K left?
	jz	lt64k				;no, do word subtraction
	sub	word ptr cs:TypeFilSiz, cx
	sbb	word ptr cs:TypeFilSiz+2, 0 	;update filesize
      	jmp	short typ_read			;do the read
lt64k:
	cmp	cx,word ptr cs:TypeFilSiz		;readsize <= buffer?
	jbe	gtbuf				;yes, just update readsize
;
;Buffer size is larger than bytes to read
;
	mov	cx,word ptr cs:TypeFilSiz
	jcxz	typelp_ret
	mov	word ptr cs:TypeFilSiz,0
	jmp	short typ_read
gtbuf:
	sub	word ptr cs:TypeFilSiz,cx	   	;update filesize remaining
typ_read:
	mov	ah,read
	int	21h
	jnc	@f				;M043
	jmp	typerr				;M043
@@:						;M043
;M043;	jc	typerr				;AN022; Exit if error

	mov	cx,ax
	jcxz	typelp_ret			;AC000; exit if nothing read
	push	ds
	pop	es				; Check to see if a ^Z was read.
assume es:nothing
	xor	di,di
	push	ax
	mov	al,1ah
	repnz	scasb
	pop	ax
	xchg	ax,cx
	cmp	ax,0
	jnz	foundz				; Yes, handle it
	cmp	byte ptr [di-1],1ah		; No, double check
	jnz	typecont2			; No ^Z, continue

foundz:
	sub	cx,ax				; Otherwise change cx so that only those
	dec	cx				;  bytes up to but NOT including the ^Z
	push	cs				;  will be typed.
	pop	es
assume es:trangroup
	not	zflag				; Turn on ^Z flag so that the routine

typecont2:					;  will quit after this write.
	push	bx
	mov	bx,1
	mov	ah,write
	int	21h
	pop	bx
	jc	Error_outputj
	cmp	ax,cx
	jnz	@f				;M043
	jmp	typelp				;M043
@@:						;M043
;M043;	jz	typelp
	dec	cx
	cmp	ax,cx
	retz					; One less byte OK (^Z)

Error_outputj:
	mov	bx,1
	mov	ax,IOCTL SHL 8
	int	21h
	test	dl,devid_ISDEV
	retnz					; If device, no error message
	jmp	error_output

typelp_ret:
	ret

	break	Volume
assume	ds:trangroup,es:trangroup

;
; VOLUME command displays the volume ID on the specified drive
;
VOLUME:

	mov	si,81H
	mov	di,offset trangroup:parse_vol	;AN000; Get adderss of PARSE_VOL
	xor	cx,cx				;AN000; clear cx,dx
	xor	dx,dx				;AN000;
	invoke	parse_with_msg			;AC018; call parser
	cmp	ax,end_of_line			;AC000; are we at end of line?
	jz	OkVolArg			;AC000; Yes, display default volume ID
	cmp	ax,result_no_error		;AC000; did we have an error?
	jnz	BadVolArg			;AC000; Yes, fail.
;
; We have parsed off the drive.  See if there are any more chars left
;

	mov	di,offset trangroup:parse_vol	;AC000; get address of parse_vol
	xor	dx,dx				;AC000;
	invoke	parse_check_eol 		;AC000; call parser
	jz	OkVolArg			;AC000; yes, end of road
;
; The line was not interpretable.  Report an error.
;
badvolarg:
	jmp	Cerror




;***	DisAppend - disable APPEND
;
;	ENTRY	nothing
;
;	EXIT	nothing
;
;	USED	AX,BX
;
;	EFFECTS
;
;	  APPEND is disabled.  If it was active, it will be re-enabled
;	  after the command finishes, by the HeadFix routine.
;
;	NOTE
;
;	  This routine must not be called more than once during a single
;	  command cycle.  The second call would permanently disable APPEND.

DisAppend	proc

	assume	ds:TRANGROUP,es:NOTHING

	push	ds			; save DS
	push	es			; save ES
	push	di

	mov	ax,APPENDINSTALL	; AX = Append Installed Check code
	int	2Fh			; talk to APPEND via multiplex
	or	al,al
	jz	daRet			; APPEND not installed, return

	mov	ax,APPENDDOS		; AX = Get Append Version code
	int	2Fh			; talk to APPEND via multiplex
	cmp	ax,0FFFFh
	jne	daRet			; it's not a local version, return

	mov	ax,APPENDGETSTATE	; AX = Get Function State code
	int	2Fh			; talk to APPEND via multiplex

	mov	ds,ResSeg		; DS = resident seg addr

	assume	ds:RESGROUP

	mov	Append_State,bx		; Append_State = saved APPEND state
	mov	Append_Flag,-1		; Append_Flag = true, restore state

	xor	bx,bx			; BX = APPEND state = off
	mov	AX,APPENDSETSTATE	; AX = Set Append State code
	int	2Fh			; talk to APPEND via multiplex

daRet:	pop	di
	pop	es			; restore ES
	pop	ds			; restore DS

	assume	ds:TRANGROUP

	ret

DisAppend	endp



;
; Find the Volume ID on the disk.
;
PUBLIC	OkVolArg
OKVOLARG:
	assume	ds:TRANGROUP,es:TRANGROUP

	call	DisAppend			; disable APPEND
	invoke	crlf2
	mov	al,blank			;AN051; Print out a blank
	invoke	print_char			;AN051;   before volume message
	push	ds
	pop	es
;
; Volume IDs are only findable via extended FCBs or find_first with attributes
; of volume_id ONLY.
;

	mov	di,FCB-7			; Point to extended FCB beginning
	mov	al,-1				; Tag to indicate Extention
	stosb
	xor	ax,ax				; Zero padding to volume label
	stosw
	stosw
	stosb
	mov	al,attr_volume_ID		; Look for volume label
	stosb
	inc	di				; Skip drive byte; it is already set
	mov	cx,11				; fill in remainder of file
	mov	al,'?'
	rep	stosb
;
; Set up transfer address (destination of search first information)
;
	mov	dx,offset trangroup:dirbuf
	mov	ah,set_DMA
	int	21h
;
; Do the search
;
	mov	dx,FCB-7
	mov	ah,Dir_Search_First
	int	21h

;********************************
; Print volume ID info

	push	ax				;AC000; AX return from SEARCH_FIRST for VOL ID
	mov	al,DS:[FCB]			;AC000; get drive letter
	add	al,'@'
	cmp	al,'@'
	jnz	drvok
	mov	al,[curdrv]
	add	al,capital_A
drvok:
	mov	vol_drv,al			;AC000; get drive letter into argument
	pop	ax				;AC000; get return code back
	or	al,al				;AC000; volume label found?
	jz	Get_vol_name			;AC000; volume label exists - go get it
	mov	dx,offset trangroup:VolMes_ptr_2 ;AC000; set up no volume message
	jmp	short print_serial		;AC000; go print it

Get_vol_name:
	mov	di,offset trangroup:charbuf
	mov	dx,di
	mov	si,offset trangroup:dirbuf + 8	;AN000;  3/3/KK
	mov	cx,11				;AN000;  3/3/KK
	rep	movsb				;AN000;  3/3/KK

	xor	al,al				;AC000; store a zero to terminate the string
	stosb
	mov	dx,offset trangroup:VolMes_ptr	;AC000; set up message

PRINT_SERIAL:

;
; Attempt to get the volume serial number from the disk.  If an error
; occurs, do not print volume serial number.
;

	push	dx				;AN000; save message offset
	mov	ax,(GetSetMediaID SHL 8)	;AC036; Get the volume serial info
	mov	bl,DS:[FCB]			;AN000; get drive number from FCB
	mov	dx,offset trangroup:vol_ioctl_buf ;AN000;target buffer
	int	21h			;AN000; do the call
	pop	dx				;AN000; get message offset back
	jc	printvol_end			;AN000; if error, just go print label
	call	std_printf			;AC000; go print volume message
	mov	al,blank			;AN051; Print out a blank
	invoke	print_char			;AN051;   before volume message
	mov	dx,offset trangroup:VolSerMes_ptr ;AN000; get serial number message

printvol_end:
	jmp	std_printf			;AC000; go print and exit


;****************************************************************
;*
;* ROUTINE:	Set_ext_error_msg
;*
;* FUNCTION:	Sets up extended error message for printing
;*
;* INPUT:	return from INT 21
;*
;* OUTPUT:	extended error message set up in extended error
;*		buffer.
;*
;****************************************************************

Set_ext_error_msg proc near			;AN000;

	call	get_ext_error_number		;AC022; get the extended error
	mov	msg_disp_class,ext_msg_class	;AN000; set up extended error msg class
	mov	dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
	mov	Extend_Buf_ptr,ax		;AN000; get message number in control block
	stc					;AN000; make sure carry is set

	ret					;AN000; return

Set_ext_error_msg endp				;AN000;

;****************************************************************
;*
;* ROUTINE:	Get_ext_error_number
;*
;* FUNCTION:	Does get extended error function call
;*
;* INPUT:	return from INT 21
;*
;* OUTPUT:	AX - extended error number
;*
;****************************************************************

Get_ext_error_number proc near			;AN022;

	SaveReg <BX,CX,DX,SI,DI,BP,ES,DS>	;AN022; save registers
	mov	ah,GetExtendedError		;AN022; get extended error
	xor	bx,bx				;AN022; clear BX
	int	21h			;AN022;
	RestoreReg  <DS,ES,BP,DI,SI,DX,CX,BX>	;AN022; restore registers

	ret					;AN022; return

Get_ext_error_number endp			;AN022;

trancode    ends
	    end
