Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

376 lines
12 KiB

page ,132
; SCCSID = @(#)tprintf.asm 4.3 85/07/02
; SCCSID = @(#)tprintf.asm 4.3 85/07/02
TITLE COMMAND Transient Printf routine
;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
;
; Revision History
; ================
;
; M025 SR 9/12/90 Removed calls to SetStdInOn,SetStdInOff
; SetStdOutOn & SetStdOutOff.
;
;****************************************************************
;*
;* ROUTINE: STD_PRINTF/STD_EPRINTF
;*
;* FUNCTION: Set up to print out a message using SYSDISPMSG.
;* Set up substitutions if utility message. Make
;* sure any changes to message variables in TDATA
;* are reset to avoid reloading the transient.
;*
;* INPUT: Msg_Disp_Class - set to message class
;* Msg_Cont_Flag - set to control flags
;* DS points to transient segment
;*
;* if utility message:
;* DX points to a block with message number
;* (word), number of substitutions (byte),
;* followed by substitution list if there
;* are substitutions. If substitutions
;* are not in transient segment they must
;* be set.
;* else
;* AX set to message number
;*
;* OUTPUT: none
;*
;****************************************************************
.xlist
.xcref
INCLUDE comsw.asm ;AC000;
INCLUDE DOSSYM.INC
INCLUDE comseg.asm
INCLUDE comequ.asm ;AN000;
INCLUDE SYSMSG.INC ;AN000;
.list
.cref
datares segment public
extrn pipeflag:byte
datares ends
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
EXTRN extend_buf_off:word ;AN000;
EXTRN Extend_Buf_ptr:word ;AN000;
EXTRN Extend_Buf_seg:word ;AN000;
EXTRN Msg_Cont_Flag:byte ;AN000;
EXTRN Msg_disp_Class:byte ;AN000;
EXTRN pipeemes_ptr:word
TRANDATA ENDS
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
EXTRN msg_flag:byte ;AN022;
EXTRN print_err_flag:word ;AN000;
EXTRN RESSEG:WORD
EXTRN String_ptr_2:word ;AC000;
EXTRN Subst_buffer:byte ;AN061;
;AD061; EXTRN String_ptr_2_sb:word ;AN000;
; include data area for message services
MSG_UTILNAME <COMMAND> ;AN000; define utility name
MSG_SERVICES <MSGDATA> ;AN000;
PRINTF_HANDLE DW ? ;AC000;
TRANSPACE ENDS ;AC000;
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
EXTRN cerror:near
EXTRN crlf2:near
EXTRN tcommand:near ;AN026;
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000;
PUBLIC TSYSGETMSG ;AN000;
PUBLIC TSYSLOADMSG ;AN000;
PUBLIC Printf_Init
printf_init proc far
call std_printf
ret
printf_init endp
Public Printf_Crlf
PRINTF_CRLF:
CALL STD_PRINTF
CALL CRLF2
RET
PUBLIC Std_EPrintf
STD_EPRINTF:
mov Printf_Handle,2 ;AC000;Print to STDERR
jmp short NEW_PRINTF ;AC000;
PUBLIC Std_Printf
STD_PRINTF:
mov Printf_Handle,1 ;AC000;Print to STDOUT
NEW_PRINTF:
push ax ;AN000;save registers
push bx ;AN000;
push cx ;AN000;
push es ;AN000;get local ES
push ds ;AN000;
pop es ;AN000;
push di ;AN000;
push si ;AN000;
push dx ;AN000;
assume es:trangroup ;AN000;
;AD061; mov string_ptr_2_sb,0 ;AN000;initialize
mov print_err_flag,0 ;AN000;
UTILITY_SETUP:
mov si,dx ;AN000;Get offset of message number
lodsw ;AN000;load message number
push ax ;AN000;save it
lodsb ;AN000;get number of substitutions
mov cl,al ;AN000;set up CX as # of subst
xor ch,ch ;AN000; SI now points to subst list
pop ax ;AN000;get message number back
cmp cx,0 ;AN000;Any substitutions?
jz READY_TO_PRINT ;AN000;No - continue
;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment
;AD061; push cx ;AN000;save substitution count
;AD061;SET_SUBST:
;AD061; mov bx,dx ;AN000;get dx into base register
;AD061; cmp word ptr [bx],0 ;AN000;has segment been set?
;AD061; jnz SUBST_SEG_SET ;AN000;if not 0, don't replace it
;AD061; test word ptr [bx+3],date_type ;AN000;if date or time - don't set segment
;AD061; jnz subst_seg_set ;AN000;yes - skip it
;AD061; mov word ptr [bx],cs ;AN000;put segment of subst parm in list
;AD061;SUBST_SEG_SET:
;AD061; add dx,Parm_Block_Size ;AN000;point to position of next segment
;AD061; loop SET_SUBST ;AN000;keep replacing until complete
;AD061; pop cx ;AN000;
;AD061;NO_REPLACEMENT:
;AD061; mov bx,parm_off_pos [si] ;AN000;get subst offset
;AD061; cmp bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection
;AD061; jnz ready_to_print ;AN000;we already have address
;AD061; mov dx,string_ptr_2 ;AN000;get address in string_ptr_2
;AD061; mov parm_off_pos [si],dx ;AN000;put proper address in table
;AD061; mov string_ptr_2_sb,si ;AN000;save block changed
mov di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer
push di ;AN061; save it
push cx ;AN061; save number of subst
MOVE_SUBST:
push cx ;AN061;save number of subst
mov bx,si ;AN061;save start of sublist
mov cx,parm_block_size ;AN061;get size of sublist
rep movsb ;AN061;move sublist
test byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time?
jz move_subst_cont ;AN061;no - no need to reset
mov word ptr [bx.$M_S_VALUE],0 ;AN061;reset original date or time to 0
mov word ptr [bx.$M_S_VALUE+2],0 ;AN061;
MOVE_SUBST_CONT: ;AN061;
pop cx ;AN061;get number of subst back
loop move_subst ;AN061;move cx sublists
pop cx ;AN061;get number of subst
push ax ;AN061;save message number
cmp Msg_Disp_Class,Util_Msg_Class ;AN061;Is this a utility message
jz CHECK_FIX ;AN061;YES - go see if substitutions
mov msg_flag,ext_msg_class ;AN061;set message flag
mov di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block
xor ax,ax ;AN061;clear ax register
stosw ;AN061;clear out message number
stosb ;AN061;clear out subst count
CHECK_FIX: ;AN061;
pop ax ;AN061;get message number back
pop di ;AN061;get start of sublists
mov si,di ;AN061;get into SI for msgserv
mov bx,si ;AN061;get into BX for addressing
push cx ;AN061;save number of subst
SET_SUBST: ;AN061;store the segment of the subst
cmp word ptr [bx.$M_S_VALUE+2],0 ;AN061;was it set already?
jnz subst_seg_set ;AN061;if not 0, don't replace it
test byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time
jnz subst_seg_set ;AN061;yes - skip it
mov word ptr [bx.$M_S_VALUE+2],cs ;AN061;set segment value
SUBST_SEG_SET: ;AN061;
add bx,parm_block_size ;AN061;go to next sublist
loop set_subst ;AN061;loop CX times
pop cx ;AN061;get number of subst back
mov bx,si ;AN061;get start of sublist to BX
cmp word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection?
jnz ready_to_print ;AN061;no - we already have address
mov dx,string_ptr_2 ;AN061;get address in string_ptr_2
mov word ptr [bx.$M_S_VALUE],dx ;AN061;put it into the subst block
READY_TO_PRINT:
mov bx,Printf_Handle ;AN000;get print handle
mov dl,Msg_Cont_Flag ;AN000;set up control flag
mov dh,Msg_Disp_Class ;AN000;set up display class
mov Msg_Cont_Flag,No_Cont_Flag ;AN061;reset flags to avoid
mov Msg_Disp_Class,Util_Msg_Class ;AN061; transient reload
;AD061; push bx ;AN026; save registers
;AD061; push cx ;AN026;
;AD061; push dx ;AN026;
;AD061; push si ;AN026;
;AD061; push di ;AN026;
push ds ;AN026;
push es ;AN026;
call SYSDISPMSG ;AN000;call Rod
pop es ;AN026; restore registers
pop ds ;AN026;
;AD061; pop di ;AN026;
;AD061; pop si ;AN026;
;AD061; pop dx ;AN026;
;AD061; pop cx ;AN026;
;AD061; pop bx ;AN026;
jnc Print_success ;AN000; everything went okay
mov print_err_flag,ax ;AN000;
print_success:
;AD061; cmp Msg_Disp_Class,Util_Msg_Class ;AN000;Is this a utility message
;AD061; jz CHECK_FIX ;AN000;YES - go see if substitutions
;AD061; mov msg_flag,ext_msg_class ;AN022;set message flag
;AD061; mov di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block
;AD061; xor ax,ax ;AN000;clear ax register
;AD061; stosw ;AN000;clear out message number
;AD061; stosb ;AN000;clear out subst count
;AD061; CHECK_FIX:
;AD061; pop dx ;AN000;restore dx
;AD061; cmp cx,0 ;AN000;Any substitutions?
;AD061; jz NO_FIXUP ;AN000;No - leave
;AD061; mov si,dx ;AN000;Reset changes so transient won't reload
;AD061; add si,Ptr_Seg_Pos ;AN000;Point to position of first segment
;AD061;FIX_SUBST:
;AD061; mov word ptr [si],0 ;AN000;reset segment to 0
;AD061; add si,Parm_Block_Size ;AN000;point to position of next segment
;AD061; loop FIX_SUBST ;AN000;keep replacing until complete
;AD061; cmp string_ptr_2_sb,no_subst ;AN000;was double indirection used?
;AD061; jz no_fixup ;AN000;no - we're finished
;AD061; mov si,string_ptr_2_sb ;AN000;get offset changed
;AD061; mov parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2
;AD061;NO_FIXUP:
;AD061; mov Msg_Cont_Flag,No_Cont_Flag ;AN000;reset flags to avoid
;AD061; mov Msg_Disp_Class,Util_Msg_Class ;AN000; transient reload
pop dx ;AN061;restore dx
pop si ;AN000;restore registers
pop di ;AN000;
pop es ;AN000;restore registers
pop cx ;AN000;
pop bx ;AN000;
pop ax ;AN000;
cmp print_err_flag,0 ;AN000; if an error occurred - handle it
jnz print_err ;AN000;
ret ;AC000;
print_err:
push cs
pop es
cmp Printf_Handle,2 ;AN026;Print to STDERR?
jnz not_stderr ;AN026;no - continue
jmp tcommand ;AN026;Yes - hopless - just exit
not_stderr:
mov ax,print_err_flag ;AN026;get extended error number back
mov es,[resseg] ; No, set up for error, load the
assume es:resgroup ; right error msg, and jmp to cerror.
test PipeFlag,-1
jz go_to_error
invoke PipeOff
mov dx,offset trangroup:pipeemes_ptr
jmp short print_err_exit ;AC000;
go_to_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
PRINT_ERR_EXIT: ;AC000;
push cs
pop es
JMP CERROR
;****************************************************************
;*
;* ROUTINE: TSYSLOADMSG
;*
;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate
;* names since these routines are also used in the
;* resident.
;*
;* INPUT: Inputs to SYSLOADMSG
;*
;* OUTPUT: Outputs from SYSLOADMSG
;*
;****************************************************************
TSYSLOADMSG PROC NEAR ;AN000;
push bx ;AN000;
call sysloadmsg ;AN000; call routine
pop bx ;AN000;
ret ;AN000; exit
TSYSLOADMSG ENDP ;AN000;
;****************************************************************
;*
;* ROUTINE: TSYSGETMSG
;*
;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate
;* names since these routines are also used in the
;* resident.
;*
;* INPUT: Inputs to SYSGETMSG
;*
;* OUTPUT: Outputs from SYSGETMSG
;*
;****************************************************************
TSYSGETMSG PROC NEAR ;AN000;
push cx ;AN000;
call sysgetmsg ;AN000; call routine
pop cx ;AN000;
ret ;AN000; exit
TSYSGETMSG ENDP ;AN000;
MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services
MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services
PRINTF_LAST LABEL WORD
include msgdcl.inc
TRANCODE ENDS
END