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.

336 lines
8.7 KiB

  1. page ,132
  2. title Command Stub
  3. ;/*
  4. ; * Microsoft Confidential
  5. ; * Copyright (C) Microsoft Corporation 1991
  6. ; * All Rights Reserved.
  7. ; */
  8. ;
  9. ; Revision History
  10. ; ================
  11. ;
  12. ; M003 SR 07/16/90 Check if UMB loading enabled and if so
  13. ; turn it off on return from Exec
  14. ;
  15. ; M005 SR 07/20/90 Carousel hack. Added a hard-coded far
  16. ; jump to the actual int 2fh entry
  17. ; point to fix Carousel problems.
  18. ;
  19. ; M009 SR 08/01/90 Restore the UMB state before the Exec
  20. ; from the saved state in LoadHiFlg.
  21. ;
  22. ; M035 SR 10/27/90 Enable interrupts at the start of
  23. ; the dispatch code. Otherwise interrupts
  24. ; remain disabled through a whole
  25. ; of code which is not good.
  26. ;
  27. ; M049 SR 1/16/91 Bug #5075. Reworked the scheduling
  28. ; strategy. There is no common
  29. ; dispatcher now. Each entry point
  30. ; now checks A20 and then does a far
  31. ; jump to the appropriate code. This
  32. ; added about 15 bytes of code but the
  33. ; speed increase and reentrancy are
  34. ; well worth the price.
  35. ;
  36. ;
  37. ;This file contains the low memory stub for command.com which hooks all the
  38. ;entry points into the resident command.com and directs the calls to the
  39. ;appropriate routines in the resident code which may be located in HIMEM.
  40. ; The stub has been made part of the resident data and will always
  41. ;be duplicated on every invocation of command.com. However, the only stubs
  42. ;that actually hook the interrupt vectors belong to either the first
  43. ;command.com or to any other command.com executed with the /p switch.
  44. ; The stub also keeps track of the current active data segment. The
  45. ;INIT code of each command.com updates this variable via an int 2fh mechanism
  46. ;with its own data segment. The INIT code also updates a pointer in its data
  47. ;segment to the previous resident data segment. Whenever a command.com exits,
  48. ;the exit code picks up the previous data segment pointer from the current
  49. ;data segment and patches it into the CurResDataSeg variable in the stub.
  50. ; Right now the stub does not bother about A20 switching. We assume
  51. ;A20 is always on. It just does a far jump to the resident code with the
  52. ;value of the current data segment in one of the registers. A20 toggle
  53. ;support maybe added as a future enhancement, if the need is felt.
  54. ;
  55. include comseg.asm
  56. include xmm.inc
  57. INIT segment
  58. extrn ConProc:near
  59. INIT ends
  60. CODERES segment
  61. extrn MsgInt2fHandler :near
  62. extrn Int_2e :near
  63. extrn Contc :near
  64. extrn DskErr :near
  65. CODERES ends
  66. DATARES segment
  67. assume cs:DATARES,ds:nothing,es:nothing,ss:nothing
  68. Org 0
  69. ZERO = $
  70. Org 100h
  71. ProgStart:
  72. jmp RESGROUP:ConProc
  73. db ? ;make following table word-alligned
  74. ;
  75. ;All the entry points declared below are patched in at INIT time with the
  76. ;proper segment and offset values after the resident code segment has been
  77. ;moved to its final location
  78. ;
  79. public Int2f_Entry, Int2e_Entry, Ctrlc_Entry, CritErr_Entry, Lodcom_Entry
  80. public Exec_Entry, RemCheck_Entry, TrnLodCom1_Entry, MsgRetrv_Entry
  81. public HeadFix_Entry
  82. public XMMCallAddr, ComInHMA
  83. ;!!!WARNING!!!
  84. ; All the dword ptrs from Int2f_Entry till MsgRetrv_Entry should be contiguous
  85. ;because the init routine 'Patch_stub' (in init.asm) relies on this to patch
  86. ;in the correct segments and offsets
  87. ;
  88. Int2f_Entry label dword
  89. dw offset RESGROUP:MsgInt2fHandler ;Address of int 2fh handler
  90. dw 0
  91. Int2e_Entry label dword
  92. dw offset RESGROUP:Int_2e ;Address of int 2eh handler
  93. dw 0
  94. Ctrlc_Entry label dword
  95. dw offset RESGROUP:ContC ;Address of Ctrl-C handler
  96. dw 0
  97. CritErr_Entry label dword
  98. dw offset RESGROUP:DskErr ;Address of critical error handler
  99. dw 0
  100. Exec_Entry dd ? ;Entry from transient to Ext_Exec
  101. RemCheck_Entry dd ? ;Entry from transient to TRemCheck
  102. TrnLodCom1_Entry dd ? ;Entry from transient to LodCom1
  103. LodCom_Entry dd ? ;Entry after exit from command.com
  104. MsgRetrv_Entry dd ? ;Entry from external to MsgRetriever
  105. HeadFix_Entry dd ? ;Entry from trans to HeadFix
  106. UMBOff_Entry dd ? ;Entry from here to UMBOff routine; M003
  107. XMMCallAddr dd ? ;Call address for XMM functions
  108. ComInHMA db 0 ;Flags if command.com in HMA
  109. public Int2f_Trap, Int2e_Trap, Ctrlc_Trap, CritErr_Trap
  110. public Exec_Trap, RemCheck_Trap, LodCom_Trap, MsgRetrv_Trap, TrnLodcom1_Trap
  111. public HeadFix_Trap
  112. Int2f_Trap:
  113. sti
  114. call CheckA20
  115. push ds ;push current ds value
  116. push cs ;push resident data segment value
  117. jmp Int2f_Entry
  118. Int2e_Trap:
  119. sti
  120. call CheckA20
  121. push ds ;push current ds value
  122. push cs ;push resident data segment value
  123. jmp Int2e_Entry
  124. Ctrlc_Trap:
  125. sti
  126. call CheckA20
  127. push ds ;push current ds value
  128. push cs ;push resident data segment value
  129. jmp Ctrlc_Entry
  130. CritErr_Trap:
  131. sti
  132. call CheckA20
  133. push ds ;push current ds value
  134. push cs ;push resident data segment value
  135. jmp CritErr_Entry
  136. Exec_Trap:
  137. call CheckA20
  138. push ds ;push current ds value
  139. push cs ;push resident data segment value
  140. jmp Exec_Entry
  141. RemCheck_Trap:
  142. call CheckA20
  143. push ds ;push current ds value
  144. push cs ;push resident data segment value
  145. jmp RemCheck_Entry
  146. TrnLodCom1_Trap:
  147. call CheckA20
  148. push ds ;push current ds value
  149. push cs ;push resident data segment value
  150. jmp TrnLodCom1_Entry
  151. LodCom_Trap:
  152. call CheckA20
  153. push ds ;push current ds value
  154. push cs ;push resident data segment value
  155. jmp LodCom_Entry
  156. MsgRetrv_Trap:
  157. call CheckA20
  158. push ds ;push current ds value
  159. push cs ;push resident data segment value
  160. jmp MsgRetrv_Entry
  161. HeadFix_Trap:
  162. call CheckA20
  163. push ds ;push current ds value
  164. push cs ;push resident data segment value
  165. jmp HeadFix_Entry
  166. CheckA20 proc
  167. pushf ;save current flags
  168. push ax
  169. cmp cs:ComInHMA,0 ;is resident in HMA?
  170. jz A20_on ;no, jump to resident
  171. call QueryA20
  172. jnc A20_on ;A20 is on, jump to resident
  173. call EnableA20 ;turn A20 on
  174. A20_on:
  175. pop ax
  176. popf ;flags have to be unchanged
  177. ret
  178. CheckA20 endp
  179. ;
  180. ; M005; This is a far jump to the actual int 2fh entry point. The renormalized
  181. ; M005; int 2fh cs:ip points here. We hardcode a far jump here to the int 2fh
  182. ; M005; handler. Note that we have to hardcode a jump and we cannot use any
  183. ; M005; pointers because our cs is going to be different. The segment to
  184. ; M005; jump to is patched in at init time. (in init.asm)
  185. ;
  186. public Carousel_i2f_Hook ; M005
  187. Carousel_i2f_Hook: ; M005
  188. db 0eah ; far jump opcode; M005
  189. dw offset DATARES:Int2f_Trap ; int 2fh offset ; M005
  190. dw ? ; int 2fh segment; M005
  191. QueryA20 proc near
  192. push bx
  193. push ax
  194. mov ah, XMM_QUERY_A20
  195. call cs:XMMCallAddr
  196. or ax, ax
  197. pop ax
  198. pop bx
  199. jnz short QA20_ON ; AX = 1 => ON
  200. stc ; OFF
  201. ret
  202. QA20_ON:
  203. clc ; ON
  204. ret
  205. QueryA20 endp
  206. EnableA20 proc near
  207. push bx
  208. push ax
  209. mov ah, XMM_LOCAL_ENABLE_A20
  210. call cs:XMMCallAddr
  211. or ax, ax
  212. jz XMMerror ; AX = 0 fatal error
  213. pop ax
  214. pop bx
  215. ret
  216. ;
  217. ;If we get an error, we just loop forever
  218. ;
  219. XMMerror:
  220. jmp short XMMerror
  221. EnableA20 endp
  222. ;
  223. ;The Exec call has to be issued from the data segment. The reason for this
  224. ;is TSRs. When a TSR does a call to terminate and stay resident, the call
  225. ;returns with all registers preserved and so all our segment registers are
  226. ;still set up. However, if the TSR unloads itself later on, it still
  227. ;comes back here. In this case the segment registers and the stack are
  228. ;not set up and random things can happen. The only way to setup all the
  229. ;registers is to use the cs value and this can only be done when we are in
  230. ;the data segment ourselves. So, this piece of code had to be moved from
  231. ;the code segment to the data segment.
  232. ;
  233. extrn RStack:WORD
  234. extrn LoadHiFlg:BYTE
  235. public Issue_Exec_Call
  236. Issue_Exec_Call:
  237. int 21h
  238. ;
  239. ;We disable interrupts while changing the stack because there is a bug in
  240. ;some old 8088 processors where interrupts are let through while ss & sp
  241. ;are being changed.
  242. ;
  243. cli
  244. push cs
  245. pop ss
  246. mov sp,offset DATARES:RStack ;stack is set up
  247. sti
  248. push cs
  249. pop ds ;ds = DATARES
  250. ;
  251. ; M009; Restore UMB state to that before Exec
  252. ;
  253. ;; save execution status(carry flag)
  254. ;; and the error code(AL)
  255. pushf ;save flags ; M003
  256. push ax
  257. mov al,LoadHiFlg ;current UMB state ; M009
  258. test al,80h ;did we try to loadhigh? ;M009
  259. jz no_lh ;no, dont restore ;M009
  260. and al,7fh ;clear indicator bit ;M009
  261. call dword ptr UMBOff_Entry ;restore UMB state ; M009
  262. no_lh: ; M009
  263. and LoadHiFlg,7fh ;clear loadhigh indicator bit
  264. ;M009
  265. pop ax
  266. popf ; M003; *bugbug -- popff??
  267. ;
  268. ;We now jump to the stub trap which returns us to the resident code. All
  269. ;flags are preserved by the stub code.
  270. ;
  271. jmp Exec_Trap
  272. DATARES ends
  273. end ProgStart
  274.