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.

375 lines
12 KiB

  1. page ,132
  2. ; SCCSID = @(#)tprintf.asm 4.3 85/07/02
  3. ; SCCSID = @(#)tprintf.asm 4.3 85/07/02
  4. TITLE COMMAND Transient Printf routine
  5. ;/*
  6. ; * Microsoft Confidential
  7. ; * Copyright (C) Microsoft Corporation 1991
  8. ; * All Rights Reserved.
  9. ; */
  10. ;
  11. ; Revision History
  12. ; ================
  13. ;
  14. ; M025 SR 9/12/90 Removed calls to SetStdInOn,SetStdInOff
  15. ; SetStdOutOn & SetStdOutOff.
  16. ;
  17. ;****************************************************************
  18. ;*
  19. ;* ROUTINE: STD_PRINTF/STD_EPRINTF
  20. ;*
  21. ;* FUNCTION: Set up to print out a message using SYSDISPMSG.
  22. ;* Set up substitutions if utility message. Make
  23. ;* sure any changes to message variables in TDATA
  24. ;* are reset to avoid reloading the transient.
  25. ;*
  26. ;* INPUT: Msg_Disp_Class - set to message class
  27. ;* Msg_Cont_Flag - set to control flags
  28. ;* DS points to transient segment
  29. ;*
  30. ;* if utility message:
  31. ;* DX points to a block with message number
  32. ;* (word), number of substitutions (byte),
  33. ;* followed by substitution list if there
  34. ;* are substitutions. If substitutions
  35. ;* are not in transient segment they must
  36. ;* be set.
  37. ;* else
  38. ;* AX set to message number
  39. ;*
  40. ;* OUTPUT: none
  41. ;*
  42. ;****************************************************************
  43. .xlist
  44. .xcref
  45. INCLUDE comsw.asm ;AC000;
  46. INCLUDE DOSSYM.INC
  47. INCLUDE comseg.asm
  48. INCLUDE comequ.asm ;AN000;
  49. INCLUDE SYSMSG.INC ;AN000;
  50. .list
  51. .cref
  52. datares segment public
  53. extrn pipeflag:byte
  54. datares ends
  55. TRANDATA SEGMENT PUBLIC BYTE ;AC000;
  56. EXTRN extend_buf_off:word ;AN000;
  57. EXTRN Extend_Buf_ptr:word ;AN000;
  58. EXTRN Extend_Buf_seg:word ;AN000;
  59. EXTRN Msg_Cont_Flag:byte ;AN000;
  60. EXTRN Msg_disp_Class:byte ;AN000;
  61. EXTRN pipeemes_ptr:word
  62. TRANDATA ENDS
  63. TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
  64. EXTRN msg_flag:byte ;AN022;
  65. EXTRN print_err_flag:word ;AN000;
  66. EXTRN RESSEG:WORD
  67. EXTRN String_ptr_2:word ;AC000;
  68. EXTRN Subst_buffer:byte ;AN061;
  69. ;AD061; EXTRN String_ptr_2_sb:word ;AN000;
  70. ; include data area for message services
  71. MSG_UTILNAME <COMMAND> ;AN000; define utility name
  72. MSG_SERVICES <MSGDATA> ;AN000;
  73. PRINTF_HANDLE DW ? ;AC000;
  74. TRANSPACE ENDS ;AC000;
  75. TRANCODE SEGMENT PUBLIC BYTE ;AC000;
  76. EXTRN cerror:near
  77. EXTRN crlf2:near
  78. EXTRN tcommand:near ;AN026;
  79. ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000;
  80. PUBLIC TSYSGETMSG ;AN000;
  81. PUBLIC TSYSLOADMSG ;AN000;
  82. PUBLIC Printf_Init
  83. printf_init proc far
  84. call std_printf
  85. ret
  86. printf_init endp
  87. Public Printf_Crlf
  88. PRINTF_CRLF:
  89. CALL STD_PRINTF
  90. CALL CRLF2
  91. RET
  92. PUBLIC Std_EPrintf
  93. STD_EPRINTF:
  94. mov Printf_Handle,2 ;AC000;Print to STDERR
  95. jmp short NEW_PRINTF ;AC000;
  96. PUBLIC Std_Printf
  97. STD_PRINTF:
  98. mov Printf_Handle,1 ;AC000;Print to STDOUT
  99. NEW_PRINTF:
  100. push ax ;AN000;save registers
  101. push bx ;AN000;
  102. push cx ;AN000;
  103. push es ;AN000;get local ES
  104. push ds ;AN000;
  105. pop es ;AN000;
  106. push di ;AN000;
  107. push si ;AN000;
  108. push dx ;AN000;
  109. assume es:trangroup ;AN000;
  110. ;AD061; mov string_ptr_2_sb,0 ;AN000;initialize
  111. mov print_err_flag,0 ;AN000;
  112. UTILITY_SETUP:
  113. mov si,dx ;AN000;Get offset of message number
  114. lodsw ;AN000;load message number
  115. push ax ;AN000;save it
  116. lodsb ;AN000;get number of substitutions
  117. mov cl,al ;AN000;set up CX as # of subst
  118. xor ch,ch ;AN000; SI now points to subst list
  119. pop ax ;AN000;get message number back
  120. cmp cx,0 ;AN000;Any substitutions?
  121. jz READY_TO_PRINT ;AN000;No - continue
  122. ;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment
  123. ;AD061; push cx ;AN000;save substitution count
  124. ;AD061;SET_SUBST:
  125. ;AD061; mov bx,dx ;AN000;get dx into base register
  126. ;AD061; cmp word ptr [bx],0 ;AN000;has segment been set?
  127. ;AD061; jnz SUBST_SEG_SET ;AN000;if not 0, don't replace it
  128. ;AD061; test word ptr [bx+3],date_type ;AN000;if date or time - don't set segment
  129. ;AD061; jnz subst_seg_set ;AN000;yes - skip it
  130. ;AD061; mov word ptr [bx],cs ;AN000;put segment of subst parm in list
  131. ;AD061;SUBST_SEG_SET:
  132. ;AD061; add dx,Parm_Block_Size ;AN000;point to position of next segment
  133. ;AD061; loop SET_SUBST ;AN000;keep replacing until complete
  134. ;AD061; pop cx ;AN000;
  135. ;AD061;NO_REPLACEMENT:
  136. ;AD061; mov bx,parm_off_pos [si] ;AN000;get subst offset
  137. ;AD061; cmp bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection
  138. ;AD061; jnz ready_to_print ;AN000;we already have address
  139. ;AD061; mov dx,string_ptr_2 ;AN000;get address in string_ptr_2
  140. ;AD061; mov parm_off_pos [si],dx ;AN000;put proper address in table
  141. ;AD061; mov string_ptr_2_sb,si ;AN000;save block changed
  142. mov di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer
  143. push di ;AN061; save it
  144. push cx ;AN061; save number of subst
  145. MOVE_SUBST:
  146. push cx ;AN061;save number of subst
  147. mov bx,si ;AN061;save start of sublist
  148. mov cx,parm_block_size ;AN061;get size of sublist
  149. rep movsb ;AN061;move sublist
  150. test byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time?
  151. jz move_subst_cont ;AN061;no - no need to reset
  152. mov word ptr [bx.$M_S_VALUE],0 ;AN061;reset original date or time to 0
  153. mov word ptr [bx.$M_S_VALUE+2],0 ;AN061;
  154. MOVE_SUBST_CONT: ;AN061;
  155. pop cx ;AN061;get number of subst back
  156. loop move_subst ;AN061;move cx sublists
  157. pop cx ;AN061;get number of subst
  158. push ax ;AN061;save message number
  159. cmp Msg_Disp_Class,Util_Msg_Class ;AN061;Is this a utility message
  160. jz CHECK_FIX ;AN061;YES - go see if substitutions
  161. mov msg_flag,ext_msg_class ;AN061;set message flag
  162. mov di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block
  163. xor ax,ax ;AN061;clear ax register
  164. stosw ;AN061;clear out message number
  165. stosb ;AN061;clear out subst count
  166. CHECK_FIX: ;AN061;
  167. pop ax ;AN061;get message number back
  168. pop di ;AN061;get start of sublists
  169. mov si,di ;AN061;get into SI for msgserv
  170. mov bx,si ;AN061;get into BX for addressing
  171. push cx ;AN061;save number of subst
  172. SET_SUBST: ;AN061;store the segment of the subst
  173. cmp word ptr [bx.$M_S_VALUE+2],0 ;AN061;was it set already?
  174. jnz subst_seg_set ;AN061;if not 0, don't replace it
  175. test byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time
  176. jnz subst_seg_set ;AN061;yes - skip it
  177. mov word ptr [bx.$M_S_VALUE+2],cs ;AN061;set segment value
  178. SUBST_SEG_SET: ;AN061;
  179. add bx,parm_block_size ;AN061;go to next sublist
  180. loop set_subst ;AN061;loop CX times
  181. pop cx ;AN061;get number of subst back
  182. mov bx,si ;AN061;get start of sublist to BX
  183. cmp word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection?
  184. jnz ready_to_print ;AN061;no - we already have address
  185. mov dx,string_ptr_2 ;AN061;get address in string_ptr_2
  186. mov word ptr [bx.$M_S_VALUE],dx ;AN061;put it into the subst block
  187. READY_TO_PRINT:
  188. mov bx,Printf_Handle ;AN000;get print handle
  189. mov dl,Msg_Cont_Flag ;AN000;set up control flag
  190. mov dh,Msg_Disp_Class ;AN000;set up display class
  191. mov Msg_Cont_Flag,No_Cont_Flag ;AN061;reset flags to avoid
  192. mov Msg_Disp_Class,Util_Msg_Class ;AN061; transient reload
  193. ;AD061; push bx ;AN026; save registers
  194. ;AD061; push cx ;AN026;
  195. ;AD061; push dx ;AN026;
  196. ;AD061; push si ;AN026;
  197. ;AD061; push di ;AN026;
  198. push ds ;AN026;
  199. push es ;AN026;
  200. call SYSDISPMSG ;AN000;call Rod
  201. pop es ;AN026; restore registers
  202. pop ds ;AN026;
  203. ;AD061; pop di ;AN026;
  204. ;AD061; pop si ;AN026;
  205. ;AD061; pop dx ;AN026;
  206. ;AD061; pop cx ;AN026;
  207. ;AD061; pop bx ;AN026;
  208. jnc Print_success ;AN000; everything went okay
  209. mov print_err_flag,ax ;AN000;
  210. print_success:
  211. ;AD061; cmp Msg_Disp_Class,Util_Msg_Class ;AN000;Is this a utility message
  212. ;AD061; jz CHECK_FIX ;AN000;YES - go see if substitutions
  213. ;AD061; mov msg_flag,ext_msg_class ;AN022;set message flag
  214. ;AD061; mov di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block
  215. ;AD061; xor ax,ax ;AN000;clear ax register
  216. ;AD061; stosw ;AN000;clear out message number
  217. ;AD061; stosb ;AN000;clear out subst count
  218. ;AD061; CHECK_FIX:
  219. ;AD061; pop dx ;AN000;restore dx
  220. ;AD061; cmp cx,0 ;AN000;Any substitutions?
  221. ;AD061; jz NO_FIXUP ;AN000;No - leave
  222. ;AD061; mov si,dx ;AN000;Reset changes so transient won't reload
  223. ;AD061; add si,Ptr_Seg_Pos ;AN000;Point to position of first segment
  224. ;AD061;FIX_SUBST:
  225. ;AD061; mov word ptr [si],0 ;AN000;reset segment to 0
  226. ;AD061; add si,Parm_Block_Size ;AN000;point to position of next segment
  227. ;AD061; loop FIX_SUBST ;AN000;keep replacing until complete
  228. ;AD061; cmp string_ptr_2_sb,no_subst ;AN000;was double indirection used?
  229. ;AD061; jz no_fixup ;AN000;no - we're finished
  230. ;AD061; mov si,string_ptr_2_sb ;AN000;get offset changed
  231. ;AD061; mov parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2
  232. ;AD061;NO_FIXUP:
  233. ;AD061; mov Msg_Cont_Flag,No_Cont_Flag ;AN000;reset flags to avoid
  234. ;AD061; mov Msg_Disp_Class,Util_Msg_Class ;AN000; transient reload
  235. pop dx ;AN061;restore dx
  236. pop si ;AN000;restore registers
  237. pop di ;AN000;
  238. pop es ;AN000;restore registers
  239. pop cx ;AN000;
  240. pop bx ;AN000;
  241. pop ax ;AN000;
  242. cmp print_err_flag,0 ;AN000; if an error occurred - handle it
  243. jnz print_err ;AN000;
  244. ret ;AC000;
  245. print_err:
  246. push cs
  247. pop es
  248. cmp Printf_Handle,2 ;AN026;Print to STDERR?
  249. jnz not_stderr ;AN026;no - continue
  250. jmp tcommand ;AN026;Yes - hopless - just exit
  251. not_stderr:
  252. mov ax,print_err_flag ;AN026;get extended error number back
  253. mov es,[resseg] ; No, set up for error, load the
  254. assume es:resgroup ; right error msg, and jmp to cerror.
  255. test PipeFlag,-1
  256. jz go_to_error
  257. invoke PipeOff
  258. mov dx,offset trangroup:pipeemes_ptr
  259. jmp short print_err_exit ;AC000;
  260. go_to_error:
  261. mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
  262. mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
  263. mov Extend_Buf_ptr,ax ;AN000; get message number in control block
  264. PRINT_ERR_EXIT: ;AC000;
  265. push cs
  266. pop es
  267. JMP CERROR
  268. ;****************************************************************
  269. ;*
  270. ;* ROUTINE: TSYSLOADMSG
  271. ;*
  272. ;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate
  273. ;* names since these routines are also used in the
  274. ;* resident.
  275. ;*
  276. ;* INPUT: Inputs to SYSLOADMSG
  277. ;*
  278. ;* OUTPUT: Outputs from SYSLOADMSG
  279. ;*
  280. ;****************************************************************
  281. TSYSLOADMSG PROC NEAR ;AN000;
  282. push bx ;AN000;
  283. call sysloadmsg ;AN000; call routine
  284. pop bx ;AN000;
  285. ret ;AN000; exit
  286. TSYSLOADMSG ENDP ;AN000;
  287. ;****************************************************************
  288. ;*
  289. ;* ROUTINE: TSYSGETMSG
  290. ;*
  291. ;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate
  292. ;* names since these routines are also used in the
  293. ;* resident.
  294. ;*
  295. ;* INPUT: Inputs to SYSGETMSG
  296. ;*
  297. ;* OUTPUT: Outputs from SYSGETMSG
  298. ;*
  299. ;****************************************************************
  300. TSYSGETMSG PROC NEAR ;AN000;
  301. push cx ;AN000;
  302. call sysgetmsg ;AN000; call routine
  303. pop cx ;AN000;
  304. ret ;AN000; exit
  305. TSYSGETMSG ENDP ;AN000;
  306. MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services
  307. MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services
  308. PRINTF_LAST LABEL WORD
  309. include msgdcl.inc
  310. TRANCODE ENDS
  311. END
  312.