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.

303 lines
6.3 KiB

  1. ; GPCont.asm - code to allow continuation after GP faults
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc ; ne_restab
  5. include gpcont.inc
  6. .list
  7. if SHERLOCK
  8. FAULTSTACKFRAME struc
  9. fsf_BP dw ? ; Saved BP
  10. fsf_msg dw ? ; Near pointer to message describing fault
  11. fsf_prev_IP dw ? ; IP of previous fault handler
  12. fsf_prev_CS dw ? ; CS of previous fault handler
  13. fsf_ret_IP dw ? ; DPMI fault handler frame follows
  14. fsf_ret_CS dw ?
  15. fsf_err_code dw ?
  16. fsf_faulting_IP dw ?
  17. fsf_faulting_CS dw ?
  18. fsf_flags dw ?
  19. fsf_SP dw ?
  20. fsf_SS dw ?
  21. FAULTSTACKFRAME ends
  22. fsf_DS equ word ptr -10
  23. fsf_ES equ word ptr -10
  24. fsf_FS equ word ptr -10
  25. fsf_GS equ word ptr -10
  26. ;flag bits set in gpRegs
  27. strCX = 1
  28. strSI = 2
  29. strDI = 4
  30. segDS = 8
  31. segES = 16
  32. segFS = 32
  33. segGS = 64
  34. ifdef WOW
  35. sBegin MISCCODE
  36. externFP DisAsm86
  37. assumes ds,nothing
  38. assumes es,nothing
  39. ;-----------------------------------------------------------------------;
  40. ; allows DisAsm86 to be called from _TEXT code segment
  41. cProc Far_DisAsm86,<PUBLIC,FAR>,<dx>
  42. parmD cp
  43. cBegin
  44. mov ax,cp.off
  45. mov dx,cp.sel
  46. cCall <far ptr DisAsm86>,<dx,ax>
  47. cEnd
  48. sEnd MISCCODE
  49. endif ;; WOW
  50. DataBegin
  51. externB szGPCont
  52. szKernel db 6,'KERNEL'
  53. szUser db 4,'USER'
  54. szDrWatson db 'DRWATSON'
  55. externW gpTrying ; retrying current operation
  56. externW gpEnable ; user has enabled GP continue
  57. externW gpSafe ; current instruction is safe
  58. externW gpInsLen ; length of faulting instruction
  59. externW gpRegs ; bit field of modified regs
  60. externD pSErrProc ; pointer to SysErrBox in USER
  61. DataEnd
  62. externFP IsBadCodePtr
  63. externFP FarFindExeInfo
  64. sBegin CODE
  65. assumes CS,CODE
  66. ifndef WOW
  67. externNP DisAsm86
  68. endif
  69. externNP GetOwner
  70. ;extern int far pascal SysErrorBox(char far *text, char far *caption,
  71. ; int b1, int b2, int b3);
  72. SEB_OK = 1 ; Button with "OK".
  73. SEB_CANCEL = 2 ; Button with "Cancel"
  74. SEB_YES = 3 ; Button with "&Yes"
  75. SEB_NO = 4 ; Button with "&No"
  76. SEB_RETRY = 5 ; Button with "&Retry"
  77. SEB_ABORT = 6 ; Button with "&Abort"
  78. SEB_IGNORE = 7 ; Button with "&Ignore"
  79. SEB_CLOSE = 8 ; Button with "Close"
  80. SEB_DEFBUTTON = 8000h ; Mask to make this button default
  81. SEB_BTN1 = 1 ; Button 1 was selected
  82. SEB_BTN2 = 2 ; Button 1 was selected
  83. SEB_BTN3 = 3 ; Button 1 was selected
  84. ;Name: int PrepareToParty(char *modName)
  85. ;Desc: Checks whether we can continue the current app by skipping an
  86. ; instruction. If so, it performs the side effects of the
  87. ; instruction. This must be called after a call to DisAsm86() has
  88. ; set the gpXxxx global vars.
  89. ;Bugs: Should do more checking, should check for within a device driver,
  90. cProc PrepareToParty,<PUBLIC,NEAR>,<si,di>
  91. parmD modName
  92. parmD appName
  93. cBegin
  94. ReSetKernelDS
  95. mov ax, [gpEnable] ; User enabled continue
  96. test ax, 1 ; We know how to continue
  97. jz ptp_poop
  98. cld
  99. dec [modName.off] ; include length byte in compare
  100. les di, [modName]
  101. test ax, 4 ; can continue in KERNEL?
  102. jnz @F
  103. lea si, szKernel
  104. mov cx, 7
  105. repe cmpsb
  106. jz ptp_poop ; fault in Kernel is fatal
  107. @@: test ax, 8 ; can continue in USER?
  108. jnz @F
  109. mov di, modName.off
  110. lea si, szUser
  111. mov cx, 5
  112. repe cmpsb
  113. jz ptp_poop ; fault in User is fatal
  114. @@: cmp [gpTrying], 0
  115. jne ptp_exit ; AX != 0 - do it again
  116. cmp pSErrProc.sel, 0 ; Is USER loaded?
  117. je ptp_poop
  118. mov ax, dataoffset szGPCont
  119. mov bx, SEB_CLOSE or SEB_DEFBUTTON ; dumb cmacros
  120. cCall [pSErrProc],<ds, ax, appName, bx, 0, SEB_IGNORE>
  121. cmp ax, SEB_BTN3
  122. jne ptp_poop
  123. ; mov [gpTrying], 100
  124. jmps ptp_exit ; AX != 0
  125. ptp_poop: ; every party needs a pooper
  126. xor ax, ax
  127. ptp_exit:
  128. cEnd
  129. UnSetKernelDS
  130. cProc SafeDisAsm86,<NEAR,PUBLIC>
  131. parmD cp
  132. cBegin
  133. ReSetKernelDS
  134. mov [gpSafe], 0 ; assume unsafe
  135. mov bx, cp.off ; make sure we can disassemble
  136. add bx, 10 ; at least a 10-byte instruction
  137. jc sda_exit ; offset wrap-around - failed
  138. cCall IsBadCodePtr,<seg_cp, bx>
  139. or ax, ax
  140. jnz sda_exit
  141. ifdef WOW
  142. cCall <far ptr Far_DisAsm86>,<cp>
  143. else
  144. cCall DisAsm86,<cp>
  145. endif
  146. mov [gpInsLen], ax
  147. sda_exit:
  148. cEnd
  149. ; return value in DX:AX and ES:AX (your choice), sets Z flag if failure
  150. cProc FindSegName,<NEAR,PUBLIC>,<ds>
  151. parmW segval
  152. cBegin
  153. cCall GetOwner,<segval>
  154. mov dx, ax
  155. or ax, ax
  156. jz fsn_exit
  157. mov es, ax
  158. mov ax, es:[ne_restab]
  159. inc ax
  160. fsn_exit:
  161. cEnd
  162. public GPContinue
  163. GPContinue proc near
  164. push si ; instruction length
  165. test [gpEnable], 1
  166. jz s_fail
  167. cCall SafeDisAsm86,<[bp].fsf_faulting_CS,[bp].fsf_faulting_IP>
  168. test [gpSafe], 1
  169. jz s_fail
  170. push ds
  171. push dataoffset szDrWatson
  172. push 8
  173. Call FarFindExeInfo
  174. or ax, ax
  175. jnz s_fail
  176. cCall FindSegName,<[bp].fsf_faulting_CS>
  177. jz s_fail
  178. push dx
  179. push ax
  180. cCall FindSegName,<[bp].fsf_SS>
  181. jz s_fail4
  182. push dx
  183. push ax
  184. cCall PrepareToParty
  185. or ax, ax
  186. jz s_fail
  187. ; Perform side-effects
  188. mov ax, [gpRegs] ; Invalid value to DS?
  189. test ax, segDS
  190. jz @F
  191. mov [bp].fsf_DS, 0
  192. @@: test ax, segES ; Invalid value to ES?
  193. jz @F
  194. mov [bp].fsf_ES, 0
  195. .386p
  196. @@: xor bx, bx ; Invalid value to FS?
  197. test ax, segFS
  198. jz short @F
  199. mov fs, bx
  200. @@: test ax, segGS ; Invalid value to GS?
  201. jz short @F
  202. mov gs, bx
  203. .286p
  204. @@:
  205. test ax, 0
  206. ; check other reg side effects
  207. mov bx, [gpInsLen] ; Fixup IP for instruction length
  208. add [bp].fsf_faulting_IP, bx
  209. mov ax, 1
  210. jmps s_end
  211. s_fail4:
  212. add sp, 4
  213. s_fail:
  214. xor ax, ax
  215. s_end:
  216. pop si
  217. ret
  218. GPContinue endp
  219. sEnd CODE
  220. endif ; SHERLOCK
  221. end
  222. regs.ip += faultlen; /* set at top of func - don't reuse
  223. if ((int)gpStack < 0) {
  224. for (i=0; i<8; i++) stack[i+gpStack] = stack[i];
  225. } else if (gpStack) {
  226. for (i=7; i>=0; i--) stack[i+gpStack] = stack[i];
  227. }
  228. regs.sp += gpStack << 1;
  229. if (gpRegs & strCX) {
  230. len = regs.cx * memSize;
  231. regs.cx = 0;
  232. } else len = memSize;
  233. if (gpRegs & strSI) { /* doesn't handle 32 bit regs
  234. regs.si += len;
  235. if (regs.si < (word)len) /* if overflow, set to big value
  236. regs.si = 0xfff0; /* so global vars in heap don't get
  237. } /* trashed when we continue
  238. if (gpRegs & strDI) {
  239. regs.di += len;
  240. if (regs.di < (word)len) regs.di = 0xfff0;
  241. }
  242. }
  243. return party;
  244. } /* Sherlock