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.

1560 lines
34 KiB

  1. TITLE LDINT - Loader interrupt procedure
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc
  7. include dbgsvc.inc
  8. include bop.inc
  9. include kdos.inc
  10. include gpcont.inc ; SHERLOCK
  11. ifdef WOW
  12. include vint.inc
  13. include softpc.inc
  14. endif
  15. NOTEXT = 1
  16. NOGDICAPMASKS = 1
  17. NOMB = 1
  18. NOVK = 1
  19. NOWH = 1
  20. NOMST = 1
  21. NORASTOPS = 1
  22. NOMETAFILE = 1
  23. NOMDI = 1
  24. NOWINMESSAGES = 1
  25. NOSYSMETRICS = 1
  26. NOCOLOR = 1
  27. NOCOMM = 1
  28. NOKERNEL = 1
  29. include windows.inc ; YIKES!!!
  30. .list
  31. FAULTSTACKFRAME struc
  32. fsf_BP dw ? ; Saved BP
  33. fsf_msg dw ? ; Near pointer to message describing fault
  34. fsf_prev_IP dw ? ; IP of previous fault handler
  35. fsf_prev_CS dw ? ; CS of previous fault handler
  36. fsf_ret_IP dw ? ; DPMI fault handler frame follows
  37. fsf_ret_CS dw ?
  38. fsf_err_code dw ?
  39. fsf_faulting_IP dw ?
  40. fsf_faulting_CS dw ?
  41. fsf_flags dw ?
  42. fsf_SP dw ?
  43. fsf_SS dw ?
  44. FAULTSTACKFRAME ends
  45. fsf_OFFSET = fsf_ret_IP - fsf_msg
  46. UAE_STRING_LEN equ 192d
  47. MIN_SP equ 256d
  48. externFP ExitKernel
  49. externFP WowDivideOverflowEx
  50. DataBegin
  51. ;externB syserr
  52. externB szAbort
  53. externB szAbortCaption
  54. externB szNukeApp
  55. externB szWillClose
  56. externB szBlame
  57. externB szSnoozer
  58. externB szInModule
  59. externB szAt
  60. externB szII
  61. externB szGP
  62. externB szSF
  63. externB szNP
  64. externB szLoad
  65. ;externB szDiscard
  66. externB szPF
  67. externB Kernel_Flags
  68. externB fBooting
  69. externW curTDB
  70. ;externW pGlobalHeap
  71. externW DemandLoadSel
  72. externD pSErrProc
  73. externD pUserGetFocus
  74. externD pUserGetWinTask
  75. externD pUserIsWindow
  76. externD lpGPChain
  77. if kdebug
  78. globalw wFaultSegNo,0
  79. endif
  80. if KDEBUG
  81. staticW INT3Fcs,0
  82. endif
  83. globalW FaultHandler,<codeOffset HandleFault>
  84. externD pPostMessage
  85. ifdef WOW
  86. externD FastBop
  87. externD prevInt01proc
  88. externD prevInt03proc
  89. externD oldInt00proc
  90. externW DebugWOW
  91. externW gdtdsc
  92. endif
  93. DataEnd
  94. sBegin DATA
  95. externW gmove_stack
  96. externW TraceOff
  97. sEnd DATA
  98. sBegin CODE
  99. assumes CS,CODE
  100. if SHERLOCK
  101. externNP GPContinue
  102. endif
  103. externD prevIntx6proc
  104. externD prevInt0Cproc
  105. externD prevInt0Dproc
  106. externD prevInt0Eproc
  107. externD prevInt3Fproc
  108. externNP LoadSegment
  109. ;externNP MyLock
  110. ifndef WOW
  111. externNP htoa
  112. endif
  113. externNP GetOwner
  114. externNP GetPureName
  115. externNP TextMode
  116. externNP Int21Handler
  117. ;externNP DebugPostLoadMessage
  118. externFP GlobalLRUNewest
  119. externFP GlobalHandleNorip
  120. externFP HasGPHandler
  121. externFP AllocSelector
  122. externFP IFreeSelector
  123. assumes ds, nothing
  124. assumes es, nothing
  125. ifdef WOW
  126. Entry macro name
  127. public name
  128. align 2
  129. name&:
  130. endm
  131. endif
  132. ;-----------------------------------------------------------------------;
  133. ; Display_Box_of_Doom -- Display the Unrecoverable Application Error
  134. ; box that everyone seems to dislike so much.
  135. ;
  136. ; Entry:
  137. ; Action Reserved, must be zero
  138. ; lpText String to display, NULL for default
  139. ;
  140. ; Returns:
  141. ; AX = 1 Cancel
  142. ; AX = 2 OK
  143. ;
  144. ; Registers Destroyed:
  145. ; AX, BX, CX, DX, SI, DI
  146. ;
  147. ; History:
  148. ; Thu 16-May-1991 -by- Earle R. Horton
  149. ;
  150. ;-----------------------------------------------------------------------;
  151. assumes ds,nothing
  152. assumes es,nothing
  153. cProc Display_Box_of_Doom,<PUBLIC,NEAR>
  154. parmW action
  155. parmD lpText
  156. cBegin
  157. SetKernelDS
  158. if KDEBUG
  159. xor bx,bx
  160. or action,bx
  161. jz @F
  162. kerror 00FFh,<Action not 0 in FatalAppExit>,bx,bx
  163. @@:
  164. endif
  165. push es ; added 10 feb 1990
  166. mov es,curTDB ; did app disable exception
  167. test es:[TDB_ErrMode],02h ; message box?
  168. pop es
  169. jnz nf_dont_ask
  170. cmp pSErrProc.sel, 0 ; Can we put up message box?
  171. jnz short nf_ask ; yes, do it
  172. ; no, have debugger?
  173. nf_dont_ask:
  174. mov ax,1
  175. test Kernel_Flags[2],KF2_SYMDEB
  176. jnz nf_ret ; yes, call debugger
  177. inc ax
  178. jmps nf_ret ; no, have to nuke the app
  179. nf_ask:
  180. push es
  181. mov ax,lpText.sel
  182. or ax,ax
  183. jz nf_default_string
  184. push ax
  185. push lpText.off
  186. jmps nf_pushed_string
  187. nf_default_string:
  188. push ds
  189. mov ax,dataOffset szAbort ; lpText
  190. push ax
  191. nf_pushed_string:
  192. push ds ; lpCaption
  193. mov ax, dataOffset szAbortCaption
  194. push ax
  195. xor ax,ax ; Assume no debugger, blank first button
  196. mov cx,ax
  197. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  198. jz @F ; No
  199. mov cx,SEB_CANCEL ; Yes, use Cancel button
  200. @@:
  201. push cx
  202. ; push SEB_OK+SEB_DEFBUTTON
  203. push SEB_CLOSE + SEB_DEFBUTTON
  204. push ax
  205. call ds:[pSErrProc] ; Put up the system error message
  206. pop es
  207. nf_ret:
  208. cEnd
  209. ;-----------------------------------------------------------------------;
  210. ; FatalAppExit -- Called by apps. to request an application error
  211. ; message box.
  212. ;
  213. ; Entry:
  214. ; Action Reserved, must be zero
  215. ; lpText String to display, NULL for default
  216. ;
  217. ; Returns:
  218. ; Returns to caller if Cancel button pressed
  219. ;
  220. ; Registers Destroyed:
  221. ;
  222. ; History:
  223. ; Sun 22-Oct-1989 15:18:57 -by- David N. Weise [davidw]
  224. ; Tonyg wrote it!
  225. ; Fri 24-May-1991 EarleH totally rewrote it, so there!
  226. ;
  227. ;-----------------------------------------------------------------------;
  228. assumes ds,nothing
  229. assumes es,nothing
  230. cProc IFatalAppExit,<PUBLIC,FAR>
  231. parmW action
  232. parmD lpText
  233. cBegin
  234. cmp seg_lpText,0
  235. jne fae_string
  236. mov off_lpText,offset szAbort
  237. mov seg_lpText,seg szAbort
  238. fae_string:
  239. cCall Display_Box_of_Doom,<action,lpText>
  240. cmp ax,1 ; Cancel pressed?
  241. je fae_ret
  242. jmp KillApp
  243. fae_ret:
  244. cEnd
  245. ; ------------------------------------------------------------------
  246. ;
  247. ; FormatFaultString -- Special purpose "sprintf()"
  248. ; Only used for the Box of Doom
  249. ;
  250. ; ------------------------------------------------------------------
  251. cProc FormatFaultString,<PUBLIC,NEAR>,<si,di,ds,es>
  252. parmD lpstr
  253. parmW pStr ; Assumed in Kernel's DS
  254. parmD csip
  255. cBegin
  256. SetKernelDS
  257. cld
  258. les di, lpstr ; Form string in ES:DI
  259. call CurApName
  260. lea si, szSnoozer ; " has caused an error in Windows"
  261. call strcpy
  262. mov si, pStr ; Copy the fault string
  263. call strcpy
  264. lea si, szInModule ; "in Module: <unknown>"
  265. call strcpy
  266. push es
  267. push di
  268. cCall GetOwner,<seg_csip> ; Can we find a module to blame?
  269. or ax, ax
  270. jz NoOwner
  271. mov es, ax
  272. cmp es:[ne_magic], NEMAGIC
  273. jne NoOwner
  274. mov bx, seg_csip ; Have the module, can we get the
  275. and bl, not SEG_RING ; segment number?
  276. mov di,es:[ne_segtab]
  277. mov ax,1
  278. mov cx, es:[ne_cseg]
  279. getsegno:
  280. mov dx, es:[di].ns_handle
  281. and dl, not SEG_RING
  282. cmp dx, bx
  283. jz gotsegno
  284. add di,SIZE NEW_SEG1
  285. inc ax
  286. loop getsegno
  287. jmps nosegno ; No, report the selector instead
  288. gotsegno:
  289. mov seg_csip, ax ; Print Segment #
  290. nosegno:
  291. mov di, es:[ne_pfileinfo] ; Now blame the module
  292. add di, opFile
  293. call GetPureName
  294. mov si, di
  295. smov ds, es
  296. UnSetKernelDS
  297. pop di
  298. pop es
  299. ifdef FE_SB
  300. find_space:
  301. cmp byte ptr es:[di-1],' ' ; prepare space before mod name
  302. jz copy_name
  303. dec di
  304. jmps find_space
  305. copy_name:
  306. else ; !FE_SB
  307. sub di, 9 ; Get rid of <unknown>
  308. endif ; !FE_SB
  309. call strcpy
  310. SetKernelDS
  311. jmps GotOwner
  312. NoOwner:
  313. pop di
  314. pop es
  315. GotOwner:
  316. lea si, szAt
  317. call strcpy
  318. ifdef WOW
  319. cCall <far ptr Far_htoa>,<es,di,seg_csip>
  320. else
  321. cCall htoa,<es,di,seg_csip>
  322. endif
  323. mov di, ax
  324. mov es, dx
  325. mov byte ptr es:[di], ':'
  326. inc di
  327. ifdef WOW
  328. cCall <far ptr Far_htoa>,<es,di,off_csip>
  329. else
  330. cCall htoa,<es,di,off_csip>
  331. endif
  332. mov es, dx
  333. mov di, ax
  334. lea si, szNukeApp
  335. call strcpy
  336. call CurApName
  337. lea si, szWillClose
  338. call strcpy
  339. cEnd
  340. CurApName proc near
  341. SetKernelDS
  342. lea si, szBlame ; Default task to blame
  343. cmp curTDB, 0 ; Have a task to blame?
  344. je DefaultCaption ; nope, use default
  345. mov ds, curTDB
  346. UnSetKernelDS
  347. mov si, TDB_ModName
  348. DefaultCaption:
  349. mov cx, 8
  350. copy_appname:
  351. lodsb
  352. stosb
  353. or al, al ; Null padded in TDB
  354. loopne copy_appname
  355. jne no_null
  356. dec di ; Toss extra space
  357. no_null:
  358. SetKernelDS
  359. ret
  360. CurApName endp
  361. public strcpy
  362. strcpy proc near
  363. lodsb
  364. stosb
  365. or al, al
  366. jnz strcpy
  367. dec di ; Ignore Null
  368. ret
  369. strcpy endp
  370. ;-----------------------------------------------------------------------;
  371. ;
  372. ; KillApp -- Calls USER to tell it that the application is going away,
  373. ; then tells DOS to kill it.
  374. ;
  375. ; ENTRY: None
  376. ; EXIT: None, doesn't
  377. ;
  378. ; Registers modified: Huh?
  379. ;
  380. ;-----------------------------------------------------------------------;
  381. KillApp proc near
  382. SetKernelDS
  383. test fBooting, 1
  384. jz @F
  385. mov ax, 1
  386. cCall ExitKernel,<ax>
  387. @@: mov ax,4CFFH ; They said OK to Nuke app.
  388. DOSCALL
  389. UnSetKernelDS
  390. KillApp endp
  391. ;-----------------------------------------------------------------------;
  392. ; FaultFilter -- Called by HandleFault, NestedFault, and routines that
  393. ; use the same stack frame. Look at the faulting CS:IP on the exception
  394. ; handler frame, and make sure that CS is Ring 3, LDT. If it is not
  395. ; pop the near return address from the stack and chain the exception
  396. ; to the next handler. This will be the DPMI server, which will crash
  397. ; Windows back to DOS. We ought to try to close up a few things first.
  398. ;-----------------------------------------------------------------------;
  399. ReSetKernelDS
  400. public FaultFilter
  401. FaultFilter proc near
  402. mov al,byte ptr [bp].fsf_faulting_CS
  403. and al, SEG_RING_MASK ; Check it was Ring 3, LDT
  404. cmp al, SEG_RING
  405. je @F
  406. ;
  407. ; The faulting CS's ring bits do not match up. We will not handle
  408. ; this fault, because we assume it happened in the DPMI provider,
  409. ; and is a Real Bad one. Since the default handler is going to
  410. ; abort here, it would be nice to let the user down real easy.
  411. ; Restoring the display to text mode would be nice, at the very
  412. ; minimum.
  413. ;
  414. cCall TextMode
  415. ret ; Hypocrite!
  416. @@:
  417. ;
  418. ; Check for faults on POP FS and POP GS. If found, fix them up. We need to
  419. ; fix up faults in the register restoration of both KRNL386 (WOW16Return) and
  420. ; MMSYSTEM (MULTI_MEDIA_ISR386). Monty Pythons Complete Waste of Time is an app
  421. ; which frees selectors in FS across message boundries.
  422. ;
  423. ifdef WOW
  424. push ds
  425. mov ax, word ptr [bp].fsf_faulting_CS
  426. mov ds, ax
  427. mov si, word ptr [bp].fsf_faulting_IP
  428. cmp word ptr [si], 0A10Fh ; pop fs
  429. je HandFSGSflt
  430. cmp word ptr [si], 0A90Fh ; pop gs
  431. je HandFSGSflt
  432. jmp short NoFSGSflt
  433. HandFSGSflt:
  434. if KDEBUG
  435. Trace_Out "POP GS/FS fault fixed up!"
  436. endif
  437. mov ds, [bp].fsf_SS
  438. mov si, [bp].fsf_SP
  439. mov word ptr [si], 0
  440. pop ds ; restore kernel DS
  441. pop ax ; don't do EH_Chain
  442. push codeOffset EH_ret ; use "handled it" return instead
  443. ret
  444. NoFSGSflt:
  445. pop ds
  446. endif
  447. pop ax ; toss chain return
  448. push codeOffset EH_ret ; use "handled it" return
  449. mov si,word ptr FaultHandler ; SI = Handler
  450. push si
  451. mov word ptr FaultHandler,codeOffset NestedFault
  452. if KDEBUG
  453. test byte ptr [bp].fsf_flags+1,2 ; IF set in faulting frame?
  454. jnz @F
  455. Trace_Out "Fault with interrupts disabled!"
  456. @@:
  457. endif
  458. cmp [bp].fsf_SP,128d
  459. jb ff_stack
  460. cCall HasGPHandler, <[bp].fsf_faulting_CS, [bp].fsf_faulting_IP>
  461. or ax, ax
  462. jz ff_real_fault
  463. mov ds, [bp].fsf_SS
  464. mov bx, [bp].fsf_SP
  465. sub [bp].fsf_SP, 4
  466. mov cx, [bp].fsf_err_code ; put error code on stack
  467. mov [bx-2],cx
  468. mov dx, [bp].fsf_faulting_IP
  469. mov [bx-4],dx ; and faulting IP
  470. mov [bp].fsf_faulting_IP, ax ; continue at gp fault handler
  471. jmps ff_ret
  472. ff_real_fault:
  473. ifdef WOW
  474. test DebugWOW,DW_DEBUG
  475. jz ff_no_wdebug
  476. xor ax,ax ; 0 in AX defaults to not handled
  477. push DBG_GPFAULT2
  478. FBOP BOP_DEBUGGER,,FastBop
  479. add sp,+2
  480. or ax, ax
  481. jnz ff_ret ; Alright! they handled the exception!
  482. ; Get us back to the app please!
  483. ; Otherwise, they chose to continue the exception
  484. ff_no_wdebug:
  485. endif
  486. if SHERLOCK
  487. cCall GPContinue ; We know BP points to
  488. or ax, ax ; the fault frame!
  489. jnz ff_ret
  490. endif
  491. ff_stack:
  492. call si ; call our fault handler
  493. ff_ret:
  494. SetKernelDS
  495. pop FaultHandler
  496. ret
  497. FaultFilter endp
  498. ifdef WOW
  499. ;-----------------------------------------------------------------------;
  500. ;
  501. ; single_step
  502. ;
  503. ;-----------------------------------------------------------------------;
  504. Entry single_step
  505. push ds
  506. SetKernelDS ds
  507. push ax
  508. ; QCWIN traces through code which it has no source code for. This means
  509. ; its ends up tracing through the 16-bit to 32-bit transition code and
  510. ; when it traces on the call fword instruction, it cause 32-bit trace
  511. ; interrupt which breaks into the kd> On a retail build with no
  512. ; debugger attached, it might work.
  513. ; To work around the problem we turn off the TraceFlag here if wow16cal
  514. ; has requested it.
  515. test TraceOff,1h
  516. jnz ss_turn_off_trace_flag
  517. test DebugWOW,DW_DEBUG
  518. jz ss_no_wdebug
  519. xor ax,ax ; 0 in AX defaults to not handled
  520. push DBG_SINGLESTEP
  521. FBOP BOP_DEBUGGER,,FastBop
  522. add sp,+2
  523. or ax, ax
  524. jnz ss_ret ; Alright! they handled the exception!
  525. ; Get us back to the app please!
  526. ss_no_wdebug:
  527. ; Otherwise, they chose to continue the exception
  528. pop ax
  529. pop ds
  530. jmp cs:[prevInt01proc]
  531. ; Tell api code (wow16cal) to turn on trace flag at end of next api
  532. ss_turn_off_trace_flag:
  533. sub sp,2 ; Make it look like "normalized" fault frame
  534. push bp
  535. mov bp,sp
  536. or TraceOff,2h
  537. and [bp].fsf_flags,NOT FLG_TRAP ; turn off the trap flag
  538. pop bp
  539. add sp,2
  540. ss_ret:
  541. pop ax
  542. pop ds
  543. UnSetKernelDS ds
  544. retf
  545. ;-----------------------------------------------------------------------;
  546. ;
  547. ; breakpoint
  548. ;
  549. ;-----------------------------------------------------------------------;
  550. Entry breakpoint
  551. push ds
  552. SetKernelDS ds
  553. push ax
  554. test DebugWOW,DW_DEBUG
  555. jz br_no_wdebug
  556. xor ax,ax ; 0 in AX defaults to not handled
  557. push DBG_BREAK
  558. FBOP BOP_DEBUGGER,,FastBop
  559. add sp,+2
  560. or ax, ax
  561. jnz bp_ret ; Alright! they handled the exception!
  562. ; Get us back to the app please!
  563. br_no_wdebug:
  564. ; Otherwise, they chose to continue the exception
  565. pop ax
  566. pop ds
  567. jmp cs:[prevInt03proc]
  568. bp_ret:
  569. pop ax
  570. pop ds
  571. UnSetKernelDS ds
  572. retf
  573. ;-----------------------------------------------------------------------;
  574. ;
  575. ; divide_overflow
  576. ;
  577. ;-----------------------------------------------------------------------;
  578. Entry divide_overflow
  579. ; at this point all of the registers contain the same values as they did
  580. ; at the time the faulting instruction was hit
  581. ; -- except for: cs:ip and ss:sp
  582. push ds
  583. SetKernelDS ds
  584. push ax
  585. test DebugWOW,DW_DEBUG
  586. jz di_no_wdebug
  587. xor ax,ax ; 0 in AX defaults to not handled
  588. push DBG_DIVOVERFLOW
  589. FBOP BOP_DEBUGGER,,FastBop
  590. .286p
  591. add sp,+2
  592. or ax, ax
  593. jnz do_ret ; Alright! they handled the exception!
  594. ; Get us back to the app please!
  595. di_no_wdebug:
  596. ; Otherwise, they chose to continue the exception
  597. ; check to see if we want to hack this exception for them
  598. push es
  599. mov es, curTDB
  600. mov ax, es:[TDB_WOWCompatFlagsEx2]
  601. pop es
  602. test ax, 2 ; HIWORD(WOWCFEX_DIVIDEOVERFLOWPATCH)
  603. jz di_no_patch1
  604. .386p
  605. pop ax ; get the original ax
  606. ; push ax ; restore the stack (don't need to do this since we exit
  607. ; via do_ret2 -- we want to preserve our *change* to AX
  608. push ebx ; preserve ebx
  609. mov bx, sp
  610. push eax ; make room for two dword local vars local[1]
  611. push eax ; local[0]
  612. push eax ; push original dividend registers
  613. push edx
  614. push word ptr ss:[bx+14] ;get segment of faulting instruction
  615. push word ptr ss:[bx+12] ;get offset of faulting instruction
  616. mov bx,sp ; push pointer to local[0]
  617. add bx,12 ; point to local[0]
  618. push ss
  619. push bx
  620. ;call into wow32 returns with new divisor in al, ax, or dx:ax --
  621. ;depending on the instruction
  622. cCall WowDivideOverflowEx
  623. or ax,ax ; if both ax & dx are 0, it was an edx:eax form
  624. jnz di_got_it ; so we have to get eax & edx from local[]
  625. or dx,dx
  626. jnz di_got_it
  627. pop eax ; get eax & edx from local[]
  628. pop edx
  629. pop ebx ; restore original ebx
  630. jmp do_ret2
  631. di_got_it:
  632. pop ebx ; get rid of local[] dwords
  633. pop ebx
  634. pop ebx ; restore original ebx
  635. jmp do_ret2;
  636. .286p
  637. di_no_patch1:
  638. pop ax
  639. pop ds
  640. jmp cs:[oldInt00proc]
  641. do_ret:
  642. pop ax
  643. do_ret2: ; AX already popped -- we want to preserve our change to AX
  644. pop ds
  645. UnSetKernelDS ds
  646. retf
  647. endif
  648. ;-----------------------------------------------------------------------;
  649. ;
  650. ; Set_GO_BP
  651. ;
  652. ;-----------------------------------------------------------------------;
  653. public Set_GO_BP
  654. Set_GO_BP proc near
  655. mov cx, [bp].fsf_faulting_CS ; Faulting CS
  656. mov bx, [bp].fsf_faulting_IP ; Faulting IP
  657. DebInt 40h
  658. ; mov ax, 40h ; 16 bit forced go command
  659. ; int 41h ; Call debugger
  660. ;ifdef JAPAN
  661. ; INT41SIGNATURE
  662. ;endif
  663. ret
  664. Set_GO_BP endp
  665. ;-----------------------------------------------------------------------;
  666. ;
  667. ; ExitFault -- Fault at Exit Time!!!
  668. ;
  669. ; ENTRY: BP points to fault frame described above
  670. ;
  671. ; EXIT: Returns to DPMI.
  672. ;
  673. ; Registers Modified: None
  674. ;
  675. ;-----------------------------------------------------------------------;
  676. ReSetKernelDS
  677. public ExitFault
  678. ExitFault proc near
  679. if KDEBUG
  680. Trace_Out "Fault at Exit Time!!!"
  681. endif
  682. ;
  683. ; If a kernel debugger is loaded, pop out at the nested fault, and
  684. ; take no prisoners.
  685. ;
  686. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  687. jz @F
  688. jmp Set_GO_BP
  689. @@:
  690. jmps HandleFault
  691. ExitFault endp
  692. public BUNNY_351
  693. BUNNY_351 proc far
  694. push ds
  695. SetKernelDS
  696. mov FaultHandler,codeOffset ExitFault
  697. pop ds
  698. ret
  699. BUNNY_351 endp
  700. ;-----------------------------------------------------------------------;
  701. ;
  702. ; MY_RETF -- Executes a far return.
  703. ;
  704. ;-----------------------------------------------------------------------;
  705. MY_RETF proc near
  706. retf
  707. MY_RETF endp
  708. ;-----------------------------------------------------------------------;
  709. ;
  710. ; NestedFault -- Called when a fault handler Faults!!!
  711. ;
  712. ; ENTRY: BP points to fault frame described above
  713. ;
  714. ; EXIT: Returns to DPMI.
  715. ;
  716. ; Registers Modified: None
  717. ;
  718. ;-----------------------------------------------------------------------;
  719. ReSetKernelDS
  720. public NestedFault
  721. NestedFault proc near
  722. if KDEBUG
  723. Trace_Out "Nested Fault!!!"
  724. endif
  725. ;
  726. ; If a kernel debugger is loaded, pop out at the nested fault, and
  727. ; take no prisoners.
  728. ;
  729. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  730. jz @F
  731. jmp Set_GO_BP
  732. @@:
  733. jmps HandleFault
  734. NestedFault endp
  735. ;-----------------------------------------------------------------------;
  736. ;
  737. ; HandleFault -- Puts up the System Error box for a Fault. Terminates
  738. ; the application or enters the debugger.
  739. ;
  740. ; ENTRY: BP points to fault frame described above
  741. ;
  742. ; EXIT: Returns to DPMI. If Cancel is pressed, we tell
  743. ; WDEB to set a GO breakpoint at the faulting instruction
  744. ; first. If OK is pressed, then the CS:IP on the DPMI
  745. ; fault frame is modified to point to KillApp, and the
  746. ; SS:SP points to a temp. stack owned by Kernel.
  747. ;
  748. ; Registers Modified: None
  749. ;
  750. ;-----------------------------------------------------------------------;
  751. ReSetKernelDS
  752. public HandleFault
  753. HandleFault proc near
  754. mov ax, lpGPChain.sel ; Do we have a private GP handler?
  755. mov lpGPChain.sel, 0 ; Prevent re-entrancy
  756. cmp ax, [bp].fsf_SS
  757. jnz We_Can_Handle_It
  758. test Kernel_Flags[2],KF2_SYMDEB ; Debugger?
  759. jz @F
  760. mov lpGPChain.sel,ax
  761. jmp Set_GO_BP
  762. @@:
  763. ; If we want to chain back for any
  764. mov bx, lpGPChain.off ; faults, then set up the stack of
  765. mov [bp].fsf_SP, bx ; the handler, and continue execution
  766. mov [bp].fsf_faulting_CS, cs ; at a RETF in Kernel
  767. mov [bp].fsf_faulting_IP, offset MY_RETF
  768. cmp [pPostMessage.sel],0 ; is there a USER around yet?
  769. je @F
  770. pusha
  771. push es
  772. cCall [pPostMessage],<-1,WM_SYSTEMERROR,1,0,0>
  773. pop es
  774. popa
  775. @@:
  776. if kdebug
  777. mov es, ax
  778. mov ax, es:[bx+2]
  779. mov bx, es:[bx]
  780. krDebugOut DEB_ERROR, "Fault detected - handled by %AX2 #AX:#BX"
  781. endif
  782. jmp HandleFault_Exit
  783. We_Can_Handle_It:
  784. sub sp, UAE_STRING_LEN ; Room for string
  785. mov si, sp
  786. cCall FormatFaultString,<ss,si,[bp].fsf_msg,[bp].fsf_faulting_CS,[bp].fsf_faulting_IP>
  787. push bp
  788. xor bp,bp ; Some people are picky...
  789. cCall Display_Box_of_Doom,<0,ss,si>
  790. pop bp
  791. add sp, UAE_STRING_LEN
  792. or ax, ax
  793. jne @F
  794. INT3_DEBUG ; Failed call - no USER
  795. @@:
  796. cmp ax, 1 ; Button 1 (Cancel) pressed?
  797. jne @F
  798. jmp Set_GO_BP
  799. @@:
  800. test fBooting, 1 ; No, they said to Nuke app.
  801. jnz no_signal_proc
  802. mov ds, curTDB
  803. UnSetKernelDS
  804. cmp ds:[TDB_USignalProc].sel,0
  805. jz no_signal_proc
  806. mov bx,0666h
  807. mov di, -1
  808. cCall ds:[TDB_USignalProc],<ds,bx,di,ds:[TDB_Module],ds:[TDB_Queue]>
  809. ;
  810. ; Since we are on a nice big fat juicy fault handler stack now, we can call
  811. ; Windows to clean up after the task.
  812. ;
  813. mov bx,SG_EXIT
  814. cCall ds:[TDB_USignalProc],<ds,bx,di,ds:[TDB_Module],ds:[TDB_Queue]>
  815. mov ds:[TDB_USignalProc].sel,0
  816. no_signal_proc:
  817. mov [bp].fsf_SP,dataOffset gmove_stack
  818. mov [bp].fsf_SS,seg gmove_stack
  819. mov [bp].fsf_faulting_CS,cs
  820. lea ax,KillApp
  821. mov [bp].fsf_faulting_IP,ax
  822. HandleFault_Exit:
  823. ret
  824. HandleFault endp
  825. ; ------------------------------------------------------------------
  826. ;
  827. ; ExceptionHandlerProc -- Common entry point for exception handlers
  828. ;
  829. ; ------------------------------------------------------------------
  830. public ExceptionHandlerProc
  831. ExceptionHandlerProc proc far
  832. push bp
  833. mov bp,sp
  834. pusha
  835. push ds
  836. SetKernelDS
  837. push es
  838. EH_Popup:
  839. call FaultFilter
  840. EH_Chain:
  841. pop es
  842. pop ds
  843. UnsetKernelDS
  844. popa
  845. pop bp
  846. add sp,2 ; remove message from stack
  847. retf ; chain to prev handler
  848. EH_ret:
  849. pop es
  850. pop ds
  851. popa
  852. pop bp
  853. add sp,fsf_OFFSET
  854. retf
  855. ExceptionHandlerProc endp
  856. ; ------------------------------------------------------------------
  857. ;
  858. ; This macro sets up the stack frame for entry to the generic
  859. ; exception handler.
  860. ;
  861. ; ------------------------------------------------------------------
  862. ExceptionHandlerPrologue macro name,msg,chain
  863. public name
  864. name:
  865. push word ptr chain + 2
  866. push word ptr chain
  867. push offset msg
  868. endm
  869. ; ------------------------------------------------------------------
  870. ;
  871. ; This macro sets up the stack frame, then jumps to the generic
  872. ; exception handler.
  873. ;
  874. ; ------------------------------------------------------------------
  875. ExceptionHandler macro name,msg,chain
  876. ExceptionHandlerPrologue name,msg,chain
  877. jmp ExceptionHandlerProc
  878. assumes ds, nothing
  879. assumes es, nothing
  880. endm
  881. ; ------------------------------------------------------------------
  882. ;
  883. ; Four fatal ones.
  884. ;
  885. ; ------------------------------------------------------------------
  886. ExceptionHandler StackFault,szSF,prevInt0Cproc
  887. ExceptionHandler GPFault,szGP,prevInt0Dproc
  888. ExceptionHandler invalid_op_code_exception,szII,prevIntx6proc
  889. ExceptionHandler page_fault,szPF,prevInt0Eproc
  890. ExceptionHandler LoadSegFailed,szLoad,prevInt3Fproc
  891. ; ------------------------------------------------------------------
  892. ;
  893. ; The not present fault is used to demand-load segments from newexe
  894. ; files. If we find out that something bogus has happened, then
  895. ; we just jump into the fault handler.
  896. ;
  897. ; ------------------------------------------------------------------
  898. ExceptionHandlerPrologue SegmentNotPresentFault,szNP,prevInt3Fproc
  899. push bp
  900. mov bp,sp
  901. pusha
  902. push ds
  903. SetKernelDS
  904. push es
  905. mov al,byte ptr [bp].fsf_faulting_CS
  906. and al, SEG_RING_MASK ; Check it was Ring 1, LDT
  907. cmp al, SEG_RING
  908. je @F
  909. jmp EH_Chain
  910. @@:
  911. mov al,byte ptr [bp].fsf_err_code
  912. test al, SEL_LDT ; Check it was LDT
  913. jne @F
  914. jmp EH_Chain
  915. @@:
  916. if KDEBUG
  917. test byte ptr [bp].fsf_flags+1,2 ; IF set in faulting frame?
  918. jnz @F
  919. Trace_Out "Segment not present fault with interrupts disabled!"
  920. @@:
  921. endif
  922. FSTI
  923. ;
  924. ; Don't discard the segment that we have to return to!!!
  925. ;
  926. cCall GlobalHandleNorip,<[bp].fsf_faulting_CS>
  927. test cl,GA_DISCARDABLE
  928. jz @F
  929. cCall GlobalLRUNewest,<ax>
  930. @@:
  931. mov bx,[bp].fsf_err_code
  932. seg_reload:
  933. and bx, NOT 7h ; get the not present selector
  934. or bl, SEG_RING ; Correct RING bits
  935. if KDEBUG
  936. mov INT3Fcs, bx ; Save in case of error
  937. endif
  938. ; On WOW we don't copy the owner to the real LDT since it is slow to call
  939. ; the NT Kernel, so we read our copy of it directly.
  940. ; see set_discarded_sel_owner mattfe mar 23 93
  941. mov es,cs:gdtdsc
  942. mov cx,bx ; save bx
  943. and bl, not 7
  944. mov es,es:[bx].dsc_owner
  945. mov bx,cx ; restore
  946. StoH bl ; Need handle
  947. cmp es:[ne_magic],NEMAGIC ; If owner is not a module
  948. jnz bad_seg_load ; (i.e., an instance or garbage)
  949. ; get out of here.
  950. mov di,es:[ne_segtab]
  951. mov ax,1
  952. mov cx, es:[ne_cseg]
  953. jcxz bad_seg_load
  954. dorten:
  955. cmp es:[di].ns_handle,bx
  956. jz got_seg_no
  957. add di,SIZE NEW_SEG1
  958. inc ax
  959. loop dorten
  960. ; program has referenced garbage...
  961. bad_seg_load:
  962. jmp EH_Popup
  963. got_seg_no:
  964. ;
  965. ; If we already are on the exception handler stack, then we want to make
  966. ; sure that we don't overwrite the original stack frame. Copy our
  967. ; stack frame variables down by the difference between SP and SP before
  968. ; we got called.
  969. ;
  970. push ax
  971. mov ax,ss
  972. cmp ax,word ptr [bp].fsf_SS
  973. pop ax
  974. jne stack_OK
  975. push ax
  976. push bx
  977. push bp
  978. lea bp,word ptr [bp].fsf_SS
  979. mov ax,sp
  980. dec ax
  981. dec ax
  982. @@:
  983. push word ptr [bp]
  984. dec bp
  985. dec bp
  986. cmp bp,ax
  987. jne @B
  988. pop bp
  989. pop bx
  990. pop ax
  991. ;
  992. ; Figured out what this was supposed to be by tracing up to here
  993. ; in the debugger.
  994. ;
  995. sub bp,32h
  996. stack_OK:
  997. push es
  998. mov bx,ax
  999. UnsetKernelDS
  1000. mov ax,ss
  1001. mov ds,ax
  1002. les di,dword ptr [bp].fsf_SP
  1003. dec di
  1004. dec di
  1005. std
  1006. ;
  1007. ; Push an IRET frame on the faulting stack.
  1008. ;
  1009. lea si,[bp].fsf_flags
  1010. mov cx,3
  1011. rep movsw
  1012. ;
  1013. ; Push our saved registers on the faulting stack.
  1014. ;
  1015. lea si,[bp]
  1016. mov cx,11 ; BP + PUSHA + ES + DS
  1017. rep movsw
  1018. pop ax
  1019. ;
  1020. ; Push arguments to LoadSegment on the faulting stack.
  1021. ;
  1022. stosw ; hExe
  1023. mov ax,bx
  1024. stosw ; segno
  1025. mov ax,-1
  1026. stosw
  1027. stosw
  1028. inc di
  1029. inc di
  1030. ;
  1031. ; Point the faulting stack at the new location.
  1032. ;
  1033. mov [bp].fsf_SP,di
  1034. ;
  1035. ; Tell DPMI to return to us instead of the faulting code.
  1036. ;
  1037. mov [bp].fsf_faulting_CS,cs
  1038. mov [bp].fsf_faulting_IP,offset let_them_do_it
  1039. lea sp,[bp].fsf_ret_IP
  1040. if kdebug
  1041. SetKernelDS
  1042. mov wFaultSegNo, bx
  1043. UnSetKernelDS
  1044. endif
  1045. retf
  1046. let_them_do_it:
  1047. SetKernelDS
  1048. xor cx, cx ; we try to keep a selector reserved
  1049. xchg cx, DemandLoadSel ; for scratch use while demand
  1050. jcxz @f ; loading segments--free it to make
  1051. cCall IFreeSelector,<cx> ; it available now
  1052. @@:
  1053. cCall LoadSegment
  1054. push ax ; reserve a selector for the next
  1055. cCall AllocSelector,<0> ; time we demand load a segment
  1056. mov DemandLoadSel, ax
  1057. pop cx ; LoadSegment result
  1058. jcxz SegLoaderFailure
  1059. if kdebug
  1060. push bx
  1061. mov bx, wFaultSegNo
  1062. krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "Demand load %CX2(#bx) on %SS2"
  1063. pop bx
  1064. endif
  1065. pop es
  1066. pop ds
  1067. UnsetKernelDS
  1068. popa
  1069. pop bp
  1070. ;** Check to see if we're about to restart an instruction in
  1071. ;** a not present segment. This would only occur if the
  1072. ;** segment was discarded because of the segment load we
  1073. ;** just did.
  1074. IF KDEBUG
  1075. push bp ;Make a stack frame
  1076. mov bp,sp
  1077. push ax
  1078. mov bp,[bp + 4] ;Get the CS
  1079. lar ax,bp ;See if the CS is valid
  1080. test ax,8000h ;Is it present?
  1081. jnz @F ;Yes, don't complain
  1082. mov ax,bp
  1083. Trace_Out <'LDINT: Trying to restart discarded caller (#AX)'>
  1084. @@:
  1085. pop ax
  1086. pop bp
  1087. ENDIF
  1088. iret
  1089. public SegLoaderFailure
  1090. SegLoaderFailure proc near
  1091. ;
  1092. ; segment loader was unable to load the segment!!!
  1093. ; Restore all the registers, create a fake DPMI frame, then
  1094. ; complain about the problem. Lets the user break into the
  1095. ; debugger, if installed, on Cancel. Creating and destroying
  1096. ; the fake DPMI frame is inconvenient and messy, but it lets
  1097. ; us handle the problem in common fault code.
  1098. ;
  1099. pop es
  1100. pop ds
  1101. UnsetKernelDS
  1102. popa
  1103. sub sp,4
  1104. mov bp,sp ; BP -> xx xx BP IP CS FL
  1105. push word ptr [bp+4] ; push app's BP
  1106. push ax ; get a temporary register
  1107. mov ax,[bp+6] ; IP
  1108. mov [bp+2],ax
  1109. mov ax,[bp+8] ; CS
  1110. mov [bp+4],ax
  1111. mov ax,[bp+10] ; Flags
  1112. mov [bp+6],ax
  1113. mov [bp+10],ss
  1114. lea ax,[bp+12]
  1115. mov [bp+8],ax
  1116. pop ax
  1117. pop bp
  1118. call far ptr LoadSegFailed ; BP -> RETIP RETCS EC IP CS FL SP SS
  1119. push bp
  1120. mov bp,sp ; BP -> BP EC IP CS FL SP SS
  1121. mov [bp+2],ax
  1122. mov ax,[bp+8] ; Flags
  1123. mov [bp+12],ax
  1124. mov ax,[bp+6] ; CS
  1125. mov [bp+10],ax
  1126. mov ax,[bp+4] ; IP
  1127. mov [bp+8],ax
  1128. pop bp
  1129. pop ax
  1130. add sp,4
  1131. iret
  1132. SegLoaderFailure endp
  1133. ;ENDIF
  1134. ;-----------------------------------------------------------------------;
  1135. ; default_sig_handler
  1136. ;
  1137. ;
  1138. ; Entry:
  1139. ;
  1140. ; Returns:
  1141. ;
  1142. ; Registers Destroyed:
  1143. ;
  1144. ; History:
  1145. ; Wed 10-Jan-1990 22:32:34 -by- David N. Weise [davidw]
  1146. ; Wrote it!
  1147. ;-----------------------------------------------------------------------;
  1148. assumes ds,nothing
  1149. assumes es,nothing
  1150. cProc default_sig_handler,<PUBLIC,FAR>
  1151. cBegin nogen
  1152. ret
  1153. cEnd nogen
  1154. ;-----------------------------------------------------------------------;
  1155. ;
  1156. ; Panic -- Called by ToolHelp when it gets a bad stack fault or any
  1157. ; other fault with SP suspiciously low.
  1158. ;
  1159. ;-----------------------------------------------------------------------;
  1160. assumes ds,nothing
  1161. assumes es,nothing
  1162. cProc Panic,<PUBLIC,NEAR>
  1163. cBegin
  1164. if KDEBUG
  1165. Trace_Out "KERNEL: Panic called!!!"
  1166. endif
  1167. int 1
  1168. jmp KillApp
  1169. cEnd
  1170. ;-----------------------------------------------------------------------;
  1171. ; DoSignal
  1172. ;
  1173. ;
  1174. ; Entry:
  1175. ;
  1176. ; Returns:
  1177. ;
  1178. ; Registers Destroyed:
  1179. ;
  1180. ; History:
  1181. ; Wed 10-Jan-1990 22:52:52 -by- David N. Weise [davidw]
  1182. ; Wrote it!
  1183. ;-----------------------------------------------------------------------;
  1184. assumes ds,nothing
  1185. assumes es,nothing
  1186. cProc DoSignal,<PUBLIC,FAR>,<ax,bx,cx,dx,di,si,es>
  1187. cBegin
  1188. SetKernelDS
  1189. cmp pUserGetFocus.sel,0 ; is there a USER yet?
  1190. jz ds_exit
  1191. call pUserGetFocus
  1192. or ax,ax
  1193. jz ds_exit
  1194. mov si,ax
  1195. cCall pUserIsWindow,<ax>
  1196. or ax,ax
  1197. jz ds_exit
  1198. cCall pUserGetWinTask,<si>
  1199. mov ds,ax
  1200. TDB_check_DS
  1201. cmp ds:[TDB_SigAction],2 ; send it on?
  1202. jnz ds_exit
  1203. mov ax,1
  1204. xor bx,bx
  1205. cCall ds:[bx].TDB_ASignalProc,<bx,ax>
  1206. ds_exit:
  1207. cEnd
  1208. sEnd CODE
  1209. sBegin MISCCODE
  1210. assumes cs, misccode
  1211. assumes ds, nothing
  1212. assumes es, nothing
  1213. externNP MISCMapDStoDATA
  1214. ifdef WOW
  1215. externFP htoa
  1216. assumes ds,nothing
  1217. assumes es,nothing
  1218. ;-----------------------------------------------------------------------;
  1219. ; allows htoa to be called from _TEXT code segment
  1220. cProc Far_htoa,<PUBLIC,FAR>
  1221. parmD lpstr
  1222. parmW val
  1223. cBegin
  1224. push [bp+10]
  1225. push [bp+8]
  1226. push [bp+6]
  1227. call far ptr htoa
  1228. cEnd
  1229. endif ;; WOW
  1230. ;-----------------------------------------------------------------------;
  1231. ; SetSigHandler
  1232. ;
  1233. ; SetSigHandler notifies Windows of a handler for a signal.
  1234. ; It may also be used to ignore a signal or install a default
  1235. ; action for a signal.
  1236. ;
  1237. ; Entry:
  1238. ; parmD lpprocRoutine Signal handler
  1239. ; parmD lpDPrevAddress Previous handler (returned)
  1240. ; parmD lpWPrevAction Previous action (returned)
  1241. ; parmW Action Indicate request type
  1242. ; parmW SigNumber Signal number of interest
  1243. ;
  1244. ; Returns:
  1245. ;
  1246. ; Registers Destroyed:
  1247. ;
  1248. ; History:
  1249. ; Mon 25-Dec-1989 00:36:01 -by- David N. Weise [davidw]
  1250. ; Wrote it!
  1251. ;-----------------------------------------------------------------------;
  1252. assumes ds,nothing
  1253. assumes es,nothing
  1254. cProc SetSigHandler,<PUBLIC,FAR>,<di,si,ds>
  1255. parmD lpprocRoutine
  1256. parmD lpDPrevAddress
  1257. parmD lpWPrevAction
  1258. parmW Action
  1259. parmW SigNumber
  1260. cBegin
  1261. call MISCMapDStoDATA
  1262. ReSetKernelDS
  1263. cmp SigNumber,1 ; is it SIGINTR?
  1264. jnz dssh_return_success ; ignore if not
  1265. cmp Action,4 ; is it reset Signal?
  1266. jz @F
  1267. push ds
  1268. mov ds,curTDB
  1269. assumes ds,nothing
  1270. mov ax,Action
  1271. xchg ax,ds:[TDB_SigAction]
  1272. les bx,lpWPrevAction
  1273. mov cx,es
  1274. or cx,bx
  1275. jz @F
  1276. mov es:[bx],ax
  1277. @@:
  1278. mov dx,lpprocRoutine.sel
  1279. mov ax,lpprocRoutine.off
  1280. cmp Action,0 ; put in default handler?
  1281. jnz ssg_stick_it_in
  1282. mov dx,SEG default_sig_handler
  1283. mov ax,codeOffset default_sig_handler
  1284. ssg_stick_it_in:
  1285. xchg dx,ds:[TDB_ASignalProc].sel
  1286. xchg ax,ds:[TDB_ASignalProc].off
  1287. cmp Action,4 ; is it reset Signal?
  1288. jz @F
  1289. les bx,lpDPrevAddress
  1290. mov cx,es
  1291. or cx,bx
  1292. jz @F
  1293. mov es:[bx].sel,dx
  1294. mov es:[bx].off,ax
  1295. pop ds
  1296. @@:
  1297. dssh_return_success:
  1298. xor ax,ax ; return success
  1299. dssh_exit:
  1300. cEnd
  1301. ;----------------------------------------------------------------------------
  1302. ;
  1303. ; SwapRecording(Flag)
  1304. ;
  1305. ; Flag = 0 => Stop recording
  1306. ; = 1 => Start recording only Swaps, Discards and Returns
  1307. ; = 2 => Start recording Calls in addition to Swaps, Discards and
  1308. ; returns.
  1309. ; Destroys AL register
  1310. ;----------------------------------------------------------------------------
  1311. ; Retail Version
  1312. cProc ISwapRecording,<PUBLIC, FAR>
  1313. ; parmW Flag
  1314. cBegin nogen
  1315. retf 2
  1316. cEnd nogen
  1317. sEnd MISCCODE
  1318. end