Source code of Windows XP (NT5)
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.

1163 lines
22 KiB

  1. ;-----------------------------------------------------------------------;
  2. ; ;
  3. ; RIPAUX.ASM - ;
  4. ; ;
  5. ; Debugging Support Routines ;
  6. ; ;
  7. ;-----------------------------------------------------------------------;
  8. TITLE RIPAUX.ASM - Debugging Support Routines
  9. ;-----------------------------------------------------------------------;
  10. ; INCLUDES ;
  11. ;-----------------------------------------------------------------------;
  12. ?RIPAUX = 1
  13. .xlist
  14. win3deb = 1
  15. include kernel.inc
  16. include newexe.inc
  17. .list
  18. ;-----------------------------------------------------------------------;
  19. ; DATA SEGMENT DEFINITION ;
  20. ;-----------------------------------------------------------------------;
  21. DataBegin
  22. externD pDisableProc
  23. if ROM
  24. externD prevInt21Proc
  25. endif
  26. if KDEBUG
  27. externW fWinX
  28. externW hExeHead
  29. externB szDebugStr
  30. externW DebugOptions
  31. externW DebugFilter
  32. externB fKTraceOut ; Used by DebugWrite to ignore traces
  33. else
  34. externB szExitStr1
  35. externB szExitStr2
  36. externB szFatalExit
  37. endif
  38. DataEnd
  39. ifdef WOW
  40. externFP FatalExitC
  41. endif
  42. ;-----------------------------------------------------------------------;
  43. ; CODE SEGMENT DEFINITION ;
  44. ;-----------------------------------------------------------------------;
  45. sBegin CODE
  46. assumes CS,CODE
  47. assumes DS,NOTHING
  48. assumes ES,NOTHING
  49. ;-----------------------------------------------------------------------;
  50. ; EXTERNS ;
  51. ;-----------------------------------------------------------------------;
  52. externFP ExitKernel
  53. externFP FatalAppExit
  54. if KDEBUG
  55. externFP KOutDebugStr
  56. externNP DebugOutput2
  57. externNP LogParamError2
  58. else
  59. ife ROM
  60. externD prevInt21Proc
  61. endif
  62. externFP InternalDisableDOS
  63. endif
  64. externNP DebugLogError
  65. externNP DebugLogParamError
  66. ; SAVEREGS - Preserve all registers
  67. ;
  68. SAVEREGS macro
  69. if PMODE32
  70. .386
  71. push ds ; preserve all registers
  72. push es
  73. push fs
  74. push gs
  75. pushad
  76. .286p
  77. else
  78. push ds
  79. push es
  80. pusha
  81. endif; PMODE32
  82. endm
  83. ; RESTOREREGS - Restore registeres preserved with SAVEREGS
  84. ;
  85. RESTOREREGS macro
  86. if PMODE32
  87. .386
  88. popad
  89. pop gs
  90. pop fs
  91. pop es
  92. pop ds
  93. .286p
  94. else
  95. popa
  96. pop es
  97. pop ds
  98. endif; PMODE32
  99. endm
  100. ; In Win3.1, different code is used for FatalExit on retail
  101. ; and debug builds. WOW uses the code below derived from the
  102. ; debug wrapper for FatalExitC. FatalExitC is a thunk to
  103. ; WOW32's WK32FatalExit thunk.
  104. cProc FatalExit,<PUBLIC,FAR>
  105. parmW errCode
  106. cBegin nogen
  107. push bp
  108. mov bp, sp
  109. push ds
  110. pusha
  111. setkernelds
  112. push [bp+6]
  113. cCall FatalExitC
  114. popa
  115. pop ds
  116. INT3_DEBUG ; Stop here so WDEB386 can generate same stack trace.
  117. pop bp
  118. ret 2
  119. cEnd nogen
  120. if KDEBUG
  121. BegData
  122. szCRLF db 13,10,0
  123. EndData
  124. ; trashes ES - but caller saves it
  125. cProc KOutDSStr,<PUBLIC,FAR>,<ds>
  126. parmW string
  127. cBegin
  128. if PMODE32
  129. .386p
  130. pushad ; save upper 16 bits of EAX, etc
  131. push fs
  132. push gs
  133. .286p
  134. endif
  135. pushf
  136. push cs
  137. push ds
  138. push es
  139. push ss
  140. pusha
  141. SetKernelDS
  142. mov si,string
  143. call KOutDebugStr ; expects pusha right before call
  144. popa
  145. add sp, 8 ; don't need to restore seg regs
  146. popf
  147. if PMODE32
  148. .386p
  149. pop gs
  150. pop fs
  151. popad
  152. .286p
  153. endif
  154. cEnd
  155. cProc _krDebugTest,<PUBLIC, FAR, NONWIN>,<DS>
  156. ParmW flags
  157. ParmW psz
  158. LocalW axSave
  159. LocalW bxSave
  160. LocalW esSave
  161. LocalB fBreakPrint
  162. cBegin
  163. assumes ds,NOTHING
  164. mov axSave,ax ; save these regs before they're trashed
  165. mov bxSave,bx
  166. mov esSave,es
  167. ;
  168. ; If this .exe hasn't been relocated yet, just call FatalExit.
  169. ;
  170. mov ax,cs:MyCSDS
  171. cmp ax,1000h ;; DATA should be selector, not addr
  172. jc @F
  173. jmp kdtnobreak
  174. @@:
  175. mov es,ax
  176. assumes es,DATA
  177. ;
  178. ; First use DebugOptions to determine whether we should print anything
  179. ; and/or break with a fatalexit.
  180. ;
  181. errnz low(DBF_SEVMASK)
  182. errnz low(DBF_TRACE)
  183. errnz low(DBF_WARNING)
  184. errnz low(DBF_ERROR)
  185. errnz low(DBF_FATAL)
  186. mov bx,es:DebugOptions
  187. mov ax,flags
  188. and ah,high(DBF_SEVMASK)
  189. mov al,2 ; fBreak = FALSE, fPrint = TRUE
  190. cmp ah,high(DBF_TRACE)
  191. jnz notrace
  192. push ax
  193. mov es:fKTraceOut, 1 ; Set flag for DebugWrite
  194. mov ax,flags ; if (!((flags & DBF_FILTERMASK) & DebugFilter))
  195. and ax,DBF_FILTERMASK
  196. test ax,es:DebugFilter
  197. pop ax
  198. jnz @F
  199. and al,not 2 ; fPrint = FALSE
  200. jmp short kdtnobreak
  201. @@:
  202. test bx,DBO_TRACEBREAK ; else if (DebugOptions & DBO_TRACEBREAK)
  203. jnz kdtbreak ; fBreak = TRUE
  204. jmp short kdtnobreak
  205. notrace:
  206. cmp ah,high(DBF_WARNING)
  207. jnz nowarn
  208. test bx,DBO_WARNINGBREAK
  209. jnz kdtbreak
  210. jmp short kdtnobreak
  211. nowarn:
  212. cmp ah,high(DBF_ERROR)
  213. jnz dofatal
  214. test bx,DBO_NOERRORBREAK
  215. jnz kdtnobreak
  216. jmp short kdtbreak
  217. dofatal:
  218. test bx,DBO_NOFATALBREAK
  219. jnz kdtnobreak
  220. errn$ kdtbreak
  221. kdtbreak:
  222. or al,1 ; fBreak = TRUE
  223. kdtnobreak:
  224. ;
  225. ; If DBO_SILENT, then fPrint = FALSE
  226. ;
  227. test bx,DBO_SILENT
  228. jz @F
  229. and al,not 2
  230. @@:
  231. mov fBreakPrint,al
  232. ;
  233. ; if (fBreak || fPrint)
  234. ; print out the string
  235. ;
  236. or al,al ; if !(fBreak | fPrint)
  237. jz kdtnoprint
  238. assumes es,NOTHING
  239. mov es,esSave ; restore registers
  240. mov ax,axSave
  241. mov bx,bxSave
  242. push psz
  243. call KOutDSStr ; output the string
  244. ifndef WOW
  245. push offset szCRLF
  246. call KOutDSStr
  247. endif
  248. kdtnoprint:
  249. test fBreakPrint,1 ; if fBreak, then FatalExit
  250. jz kdtexit
  251. kdtdobreak:
  252. cCall FatalExit,<flags>
  253. kdtexit:
  254. SetKernelDS es
  255. mov es:fKTraceOut,0 ; Clear DebugWrite flag
  256. mov ax, axSave
  257. mov bx, bxSave
  258. mov es, esSave
  259. cEnd
  260. ifdef DISABLE
  261. flags equ word ptr [bp+6]
  262. msg equ word ptr [bp+8]
  263. appDS equ word ptr [bp-2]
  264. appAX equ word ptr [bp-4]
  265. ;myDS equ word ptr [bp-6]
  266. _krDebugTest proc far ;Per-component - check right flags
  267. public _krDebugTest
  268. push bp
  269. mov bp, sp
  270. push ds ; at BP-2
  271. push ax ; at BP-4
  272. mov ax, _DATA
  273. cmp ax, 1000h ;; DATA should be selector, not addr
  274. jnc skip
  275. mov ds, ax
  276. assume ds:_DATA
  277. mov ax, [flags] ; See if component enabled
  278. and ax, [_krInfoLevel]
  279. and al, byte ptr [_Win3InfoLevel] ; See if system enabled
  280. cmp ax, [flags]
  281. jnz skip
  282. push bx ; Print it, so format message
  283. test al, DEB_ERRORS
  284. mov bx, dataoffset STR_krError
  285. jnz @F
  286. test al, DEB_WARNS
  287. mov bx, dataoffset STR_krWarn
  288. jnz @F
  289. test al, DEB_TRACES
  290. mov bx, dataoffset STR_krTrace
  291. jz short deb_no_msg_type
  292. @@: push bx
  293. call KOutDSStr
  294. deb_no_msg_type:
  295. mov bx, dataoffset STR_krTable
  296. or ah, ah
  297. jz deb_show_it
  298. @@: add bx, 2 ; get next string table entry
  299. shr ah, 1 ; find which category
  300. jnz @B
  301. deb_show_it:
  302. push [bx] ;; push parameter
  303. call KOutDSStr
  304. pop bx ;; restore reg
  305. mov ax, [appAX] ; print message passed in
  306. push ds
  307. mov ds, appDS ; restore App ds for error strings
  308. push [msg]
  309. call KOutDSStr
  310. pop ds ; restore kernel DS
  311. mov ax, [flags] ; shall we have a breakpoint?
  312. and ax, [_krBreakLevel]
  313. and al, byte ptr _Win3BreakLevel
  314. cmp ax, [flags]
  315. jnz skip
  316. INT3_DEBUG
  317. skip:
  318. test byte ptr [flags], DEB_FERRORS
  319. jz @F
  320. push 0
  321. push cs:MyCSDS
  322. push word ptr [bp+8]
  323. cCall FatalAppExit ;,<0,DGROUP,[bp+8]>
  324. @@:
  325. pop ax
  326. pop ds
  327. pop bp
  328. retf
  329. _krDebugTest endp
  330. endif; DISABLE
  331. endif; KDEBUG
  332. ife KDEBUG ; RETAIL ONLY SECTION STARTS HERE!
  333. ifndef WOW ; WOW uses only the "debug" version
  334. ; of FatalExit which calls FatalExitC.
  335. ; FatalExitC is thunked in WOW, the
  336. ; version in rip.c is disabled.
  337. ;-----------------------------------------------------------------------;
  338. ; ;
  339. ; FatalExit() - ;
  340. ; ;
  341. ;-----------------------------------------------------------------------;
  342. ; Retail version. The Debug version is in RIP.C.
  343. assumes ds, nothing
  344. assumes es, nothing
  345. cProc FatalExit,<PUBLIC,FAR>
  346. parmW errCode
  347. cBegin
  348. SetKernelDS
  349. push 0
  350. push ds
  351. push dataOffset szFatalExit
  352. cCall IFatalAppExit ;,<0, ds, dataOffset szUndefDyn>
  353. cEnd
  354. cProc FatalExitDeath,<PUBLIC,FAR>
  355. parmW errCode
  356. localD pbuf
  357. localV buf,6
  358. cBegin
  359. if 0
  360. mov ax,4CFFh
  361. int 21h
  362. else
  363. SetKernelDS
  364. cCall TextMode ; Is USER started?
  365. ; cmp pDisableProc.sel,0
  366. ; je fex1
  367. ; cCall pDisableProc ; Yes, Call USER's DisableOEMLayer()
  368. ; ; to get to the text screen
  369. ; jmps fex1a
  370. ;fex1:
  371. ; mov ax, 6 ; set text mode
  372. ; int 10h
  373. ;fex1a:
  374. ; Is Int 21h hooked?
  375. cmp prevInt21Proc.sel,0
  376. je fex2
  377. cCall InternalDisableDOS ; Yes, disable Int 21h
  378. fex2:
  379. mov cx,errCode ; No output if error code is zero
  380. jcxz fe4
  381. ; Write "FatalExit = " message to STDOUT.
  382. mov bx,1
  383. mov dx,dataOffset szExitStr1
  384. mov cx,20
  385. mov ah,40h
  386. int 21h
  387. ; Error code of FFFF means Stack Overflow.
  388. mov dx,errCode
  389. inc dx
  390. jnz fe1
  391. mov dx,dataOffset szExitStr2 ; "Stack Overflow" message
  392. mov cx,17
  393. mov ah,40h
  394. int 21h
  395. jmps fe4
  396. UnSetKernelDS
  397. fe1:
  398. ; Write out error code in Hex.
  399. dec dx
  400. push ss
  401. pop es
  402. lea di,buf
  403. mov ax,'x' shl 8 OR '0'
  404. stosw
  405. mov cx,4
  406. rol dx,cl ; Rotate most significant into view
  407. fe2:
  408. mov ax,dx
  409. and ax,0Fh
  410. push cx
  411. mov cl,4
  412. rol dx,cl ; Rotate next byte into view
  413. pop cx
  414. add al,'0'
  415. cmp al,'9'
  416. jbe fe3
  417. add al,'A'-':'
  418. fe3:
  419. stosb
  420. loop fe2
  421. mov ax,10 shl 8 OR 13
  422. stosw
  423. xor ax,ax
  424. stosb
  425. lea dx,buf
  426. push ss
  427. pop ds
  428. mov cx,8
  429. mov bx,1
  430. mov ah,40h
  431. int 21h ; Write it out
  432. fe4:
  433. mov ax,errcode
  434. cCall ExitKernel,<ax>
  435. endif
  436. cEnd
  437. endif ; ifndef WOW
  438. else ; DEBUG ONLY SECTION STARTS HERE!
  439. ;-----------------------------------------------------------------------;
  440. ; ;
  441. ; GetSymFileName() - ;
  442. ; ;
  443. ;-----------------------------------------------------------------------;
  444. assumes ds, nothing
  445. assumes es, nothing
  446. ifdef WOW
  447. cProc GetSymFileName,<PUBLIC,FAR>,<ds,si,di>
  448. else
  449. cProc GetSymFileName,<PUBLIC,NEAR>,<ds,si,di>
  450. endif
  451. ParmW hExe
  452. ParmD lpName
  453. cBegin
  454. cld
  455. les di,lpName
  456. SetKernelDS
  457. ;; cmp fWinX,0
  458. ;; je slowboot
  459. ;; mov ax,hExe
  460. ;; cmp hExeHead,ax
  461. ;; mov ds,ax
  462. ;; UnSetKernelDS
  463. ;; je makename
  464. ;; mov si,ds:[ne_pfileinfo]
  465. ;; or si,si
  466. ;; jnz havename
  467. ;;makename:
  468. ;; mov si,ds:[ne_restab]
  469. ;; xor ax,ax
  470. ;; lodsb
  471. ;; mov cx,ax
  472. ;; rep movsb
  473. ;;appendext:
  474. ;; mov ax,'S.'
  475. ;; stosw
  476. ;; mov ax,'MY'
  477. ;; stosw
  478. ;; xor ax,ax
  479. ;; stosb
  480. ;; jmps namedone
  481. ;;
  482. ;;slowboot:
  483. mov ds,hExe
  484. mov si,ds:[ne_pfileinfo]
  485. havename:
  486. add si,opFile
  487. nameloop:
  488. lodsb
  489. cmp al,'.'
  490. je appendext
  491. stosb
  492. jmp nameloop
  493. appendext:
  494. mov ax,'S.'
  495. stosw
  496. mov ax,'MY'
  497. stosw
  498. xor ax,ax
  499. stosb
  500. les ax,lpName
  501. mov dx,es
  502. cEnd
  503. ;-----------------------------------------------------------------------;
  504. ; ;
  505. ; OpenSymFile() - ;
  506. ; ;
  507. ;-----------------------------------------------------------------------;
  508. assumes ds, nothing
  509. assumes es, nothing
  510. ifdef WOW
  511. cProc OpenSymFile,<PUBLIC,FAR>,<ds,si,di>
  512. else
  513. cProc OpenSymFile,<PUBLIC,NEAR>,<ds,si,di>
  514. endif
  515. ParmD path
  516. LocalV Buffer,MaxFileLen
  517. cBegin
  518. lds dx,path ; get pointer to pathname
  519. mov di,3D40h ; open file function code (SHARE_DENY_NONE)
  520. ; We don't use open test for existance, rather we use get
  521. ; file attributes. This is because if we are using Novell
  522. ; netware, opening a file causes Novell to execute its
  523. ; own path searching logic, but we want our code to do it.
  524. mov ax,4300h ; Get file attributes
  525. int 21h ; Does the file exist?
  526. jc opnnov ; No, then don't do the operation
  527. mov ax,di ; Yes, open the file then
  528. int 21h
  529. jnc opn2
  530. opnnov:
  531. mov ax, -1
  532. opn2: mov bx,ax
  533. cEnd
  534. ;-----------------------------------------------------------------------;
  535. ; ;
  536. ; GetDebugString() - ;
  537. ; ;
  538. ;-----------------------------------------------------------------------;
  539. ; Finds the 'strIndex'-th string in 'szDebugStr'. The strings are defined
  540. ; in STRINGS.ASM.
  541. assumes ds, nothing
  542. assumes es, nothing
  543. ifdef WOW
  544. cProc GetDebugString,<PUBLIC,FAR>,<di>
  545. else
  546. cProc GetDebugString,<PUBLIC,NEAR>,<di>
  547. endif
  548. parmW strIndex
  549. cBegin
  550. SetKernelDS es
  551. mov di,dataOffset szDebugStr
  552. mov bx,strIndex
  553. cld
  554. gds1:
  555. dec bx
  556. jl gdsx
  557. xor ax,ax
  558. mov cx,-1
  559. repne scasb
  560. cmp es:[di],al
  561. jne gds1
  562. xor di,di
  563. mov es,di
  564. gdsx:
  565. mov ax,di
  566. mov dx,es
  567. UnSetKernelDS es
  568. cEnd
  569. ;-----------------------------------------------------------------------;
  570. ; ;
  571. ; GetExeHead() - ;
  572. ; ;
  573. ;-----------------------------------------------------------------------;
  574. assumes ds, nothing
  575. assumes es, nothing
  576. ifdef WOW
  577. cProc GetExeHead,<PUBLIC,FAR>
  578. else
  579. cProc GetExeHead,<PUBLIC,NEAR>
  580. endif
  581. cBegin nogen
  582. push ds
  583. SetKernelDS
  584. mov ax,[hExeHead]
  585. pop ds
  586. UnSetKernelDS
  587. ret
  588. cEnd nogen
  589. ;-----------------------------------------------------------------------;
  590. ; ;
  591. ; LSHL() - ;
  592. ; ;
  593. ;-----------------------------------------------------------------------;
  594. ifdef WOW
  595. if KDEBUG
  596. sEnd CODE
  597. sBegin MISCCODE
  598. assumes cs, MISCCODE
  599. endif
  600. endif
  601. assumes ds, nothing
  602. assumes es, nothing
  603. cProc LSHL,<PUBLIC,NEAR>
  604. cBegin nogen
  605. pop bx
  606. pop cx
  607. pop ax
  608. xor dx,dx
  609. lshl1:
  610. shl ax,1
  611. rcl dx,1
  612. loop lshl1
  613. jmp bx
  614. cEnd nogen
  615. ifdef WOW
  616. if KDEBUG
  617. sEnd MISCCODE
  618. sBegin CODE
  619. assumes CS,CODE
  620. endif
  621. endif
  622. ;-----------------------------------------------------------------------;
  623. ; ;
  624. ; FarKernelError() - ;
  625. ; ;
  626. ; 05-09-91 EarleH modified to save and restore all registers. ;
  627. ; ;
  628. ;-----------------------------------------------------------------------;
  629. ; Far entry point for KernelError(). Allows the multitude of calls to
  630. ; KernelError() be made as near calls.
  631. assumes ds, nothing
  632. assumes es, nothing
  633. cProc FarKernelError,<PUBLIC,FAR,NODATA>
  634. cBegin nogen
  635. push bp
  636. mov bp,sp
  637. SAVEREGS
  638. mov ax, _DATA
  639. mov ds, ax
  640. ; push [bp+14]
  641. push [bp+12]
  642. push ds ; seg of string
  643. push [bp+10]
  644. push [bp+8]
  645. push [bp+6]
  646. mov bp,[bp]
  647. ifdef WOW
  648. cCall <far ptr Far_KernelError>
  649. else
  650. call KernelError
  651. endif
  652. or ax, ax
  653. RESTOREREGS
  654. pop bp
  655. jz @F
  656. INT3_DEBUG
  657. @@:
  658. ret 10
  659. cEnd nogen
  660. ;-----------------------------------------------------------------------;
  661. ; ;
  662. ; NearKernelError() - ;
  663. ; ;
  664. ; 05-09-91 EarleH modified to save and restore all registers. ;
  665. ; ;
  666. ;-----------------------------------------------------------------------;
  667. ifndef WOW
  668. cProc NearKernelError,<PUBLIC,NEAR,NODATA>
  669. cBegin nogen
  670. push bp
  671. mov bp,sp
  672. SAVEREGS
  673. mov ax, _DATA
  674. mov ds, ax
  675. ; push [bp+12] ; only pass 4 words now
  676. push [bp+10] ; err code
  677. push ds ; seg of string
  678. push [bp+8] ; offset of string
  679. push [bp+6]
  680. push [bp+4]
  681. mov bp,[bp] ; hide this stack frame
  682. call KernelError
  683. or ax, ax
  684. RESTOREREGS
  685. pop bp
  686. jz @F
  687. INT3_DEBUG
  688. @@:
  689. ret 8
  690. cEnd nogen
  691. endif ;; ! WOW
  692. ;-----------------------------------------------------------------------;
  693. ; ;
  694. ; IsCodeSelector() - ;
  695. ; ;
  696. ;-----------------------------------------------------------------------;
  697. ifdef WOW
  698. cProc IsCodeSelector,<PUBLIC,FAR>
  699. else
  700. cProc IsCodeSelector,<PUBLIC,NEAR>
  701. endif
  702. parmW Candidate
  703. cBegin
  704. mov ax,Candidate
  705. lar dx,ax
  706. jz lar_passed
  707. xor ax,ax
  708. jmp ics_ret
  709. lar_passed:
  710. xor ax,ax
  711. test dh,00001000b ; Executable segment descriptor?
  712. jz ics_ret ; No
  713. push cs ; Yes
  714. pop dx
  715. and dx,3
  716. and Candidate,3 ; RPL matches that of CS?
  717. cmp dx,Candidate
  718. jne ics_ret ; No
  719. inc ax ; Yes
  720. ics_ret:
  721. cEnd
  722. endif; DEBUG ; DEBUG ONLY SECTION ENDS HERE
  723. ;-----------------------------------------------------------------------;
  724. ; ;
  725. ; DebugBreak() - ;
  726. ; ;
  727. ;-----------------------------------------------------------------------;
  728. assumes ds, nothing
  729. assumes es, nothing
  730. if KDEBUG
  731. db_tab dw db_t, db_w, db_e, db_f, db_k, db_3
  732. db_len equ ($ - db_tab) / 2
  733. endif
  734. cProc DebugBreak,<PUBLIC,FAR>
  735. cBegin nogen
  736. if KDEBUG
  737. cmp ax, 0DACh
  738. jnz db_3
  739. cmp bx, db_len
  740. jae db_3
  741. shl bx, 1
  742. jmp db_tab[bx]
  743. db_t: krDebugOut DEB_TRACE, "Test trace"
  744. jmps db_end
  745. db_w: krDebugOut DEB_WARN, "Test warning"
  746. jmps db_end
  747. db_e: krDebugOut DEB_ERROR, "Test error"
  748. jmps db_end
  749. db_f: krDebugOut DEB_FERROR, "Test fatal error"
  750. jmps db_end
  751. db_k: kerror 0, "This is a kernel error"
  752. jmps db_end
  753. db_3:
  754. endif
  755. INT3_DEBUG ; Jump to debugger if installed
  756. db_end:
  757. ret
  758. cEnd nogen
  759. ;-----------------------------------------------------------------------;
  760. ; ;
  761. ; TextMode() - Enter text mode for debugging load failure ;
  762. ; ;
  763. ;-----------------------------------------------------------------------;
  764. assumes ds, nothing
  765. assumes es, nothing
  766. cProc TextMode,<PUBLIC,NEAR,NODATA>,<ds>
  767. cBegin
  768. SetKernelDS
  769. cmp word ptr [pDisableProc+2],0
  770. je tm1
  771. cCall [pDisableProc]
  772. jmps tm2
  773. tm1:
  774. ifdef NEC_98
  775. mov ah,41h ;graphic picture stop display
  776. int 18h
  777. mov ah,0Ch ;text picture start disply
  778. int 18h
  779. else ; NEC_98
  780. mov ax, 3
  781. int 10h
  782. endif ; NEC_98
  783. tm2:
  784. cEnd
  785. ;-----------------------------------------------------------------------;
  786. ; ;
  787. ; DoAbort() - ;
  788. ; ;
  789. ;-----------------------------------------------------------------------;
  790. assumes ds, nothing
  791. assumes es, nothing
  792. cProc DoAbort,<PUBLIC,NEAR>
  793. cBegin nogen
  794. SetKernelDS
  795. cCall TextMode
  796. ; cmp word ptr [pDisableProc+2],0
  797. ; je doa1
  798. ; cCall [pDisableProc]
  799. ;doa1:
  800. mov ax,1
  801. cCall ExitKernel,<ax>
  802. UnSetKernelDS
  803. cEnd nogen
  804. ;-----------------------------------------------------------------------;
  805. ;
  806. ; HandleParamError
  807. ;
  808. ; This entry point is jumped to by the parameter validation code of
  809. ; USER and GDI (and KERNEL). Its job is to parse the error code
  810. ; and, if necessary, RIP or jmp to the error handler routine
  811. ;
  812. ; Stack on entry: Far return addr to validation code
  813. ; Saved error handler offset
  814. ; Saved BP
  815. ; API far ret addr
  816. ;
  817. ;-----------------------------------------------------------------------;
  818. ERR_WARNING equ 08000h ; from error.h/windows.h/layer.inc
  819. LabelFP <PUBLIC, HandleParamError>
  820. push bp
  821. mov bp,sp
  822. push bx ; save err code
  823. push bx ; push err code
  824. push [bp+4] ; push err return addr as place where error occured
  825. push [bp+2]
  826. push cx ; push parameter
  827. push ax
  828. call far ptr LogParamError ; yell at the guy
  829. pop bx
  830. pop bp
  831. test bh,high(ERR_WARNING) ; warn or fail?
  832. errnz low(ERR_WARNING)
  833. jnz @F
  834. pop bx
  835. pop ax ; pop far return addr
  836. pop bx ; get error handler address
  837. pop bp ; restore BP
  838. and bp,not 1 ; Make even in case "inc bp" for ATM
  839. push ax
  840. push bx ; far return to handler
  841. xor ax,ax ; set dx:ax == 0 for default return value
  842. cwd
  843. xor cx,cx ; set cx == 0 too, for kernel error returns
  844. mov es,ax ; clear ES just in case it contains
  845. ; a Windows DLL's DS...
  846. @@:
  847. retf
  848. cProc DebugFillBuffer,<PUBLIC, FAR, PASCAL, NONWIN>,<DI>
  849. ParmD lpb
  850. ParmW cb
  851. cBegin
  852. if KDEBUG
  853. assumes ES,data
  854. mov ax,_DATA
  855. mov es,ax
  856. test es:DebugOptions,DBO_BUFFERFILL
  857. assumes ES,nothing
  858. jz dfbexit
  859. les di,lpb
  860. mov cx,cb
  861. mov ax,(DBGFILL_BUFFER or (DBGFILL_BUFFER shl 8))
  862. cld
  863. shr cx,1
  864. rep stosw
  865. rcl cx,1
  866. rep stosb
  867. dfbexit:
  868. endif; KDEBUG
  869. cEnd
  870. ;========================================================================
  871. ;
  872. ; void FAR _cdecl DebugOutput(UINT flags, LPCSTR lpszFmt, ...);
  873. ;
  874. ; NOTE: there is a CMACROS bug with C that causes the parameter offsets
  875. ; to be calculated incorrectly. Offsets calculated by hand here.
  876. ;
  877. cProc DebugOutput,<PUBLIC, FAR, C, NONWIN>
  878. flags equ <[bp+2+4]> ; parmW flags point past ret addr & saved bp
  879. lpszFmt equ <[bp+2+4+2]> ; parmD lpszFmt
  880. cBegin
  881. if KDEBUG
  882. push bp ; generate a stack frame
  883. mov bp,sp
  884. SAVEREGS ; save all registers
  885. push ds
  886. SetKernelDS
  887. lea ax,flags ; point at flags, lpszFmt, and rest of arguments
  888. push ss
  889. push ax
  890. call DebugOutput2
  891. UnsetKernelDS
  892. pop ds
  893. or ax,ax ; test break flag
  894. RESTOREREGS
  895. pop bp
  896. jz @F ; break if needed
  897. INT3_DEBUG
  898. @@:
  899. endif
  900. cEnd
  901. ;========================================================================
  902. ;
  903. ; void WINAPI LogError(UINT err, void FAR* lpInfo);
  904. ;
  905. cProc LogError,<PUBLIC, FAR, PASCAL, NONWIN>
  906. ParmD err
  907. ParmW lpInfo
  908. cBegin
  909. SAVEREGS
  910. assumes ds,NOTHING
  911. cCall DebugLogError,<err, lpInfo>
  912. RESTOREREGS
  913. cEnd
  914. ;========================================================================
  915. ;
  916. ; void WINAPI LogParamError(UINT err, FARPROC lpfn, void FAR* param);
  917. ;
  918. cProc LogParamError,<PUBLIC, FAR, PASCAL, NONWIN>
  919. ParmW err
  920. ParmD lpfn
  921. ParmD param
  922. cBegin
  923. assumes ds,NOTHING
  924. SAVEREGS
  925. ; Call debugger hook (note the reversed parameter order)
  926. ;
  927. cCall DebugLogParamError,<param, lpfn, err>
  928. if KDEBUG
  929. push ds
  930. SetKernelDS
  931. assumes ds,DATA
  932. mov bx, [bp+0] ; address of faulting code
  933. mov bx, ss:[bx+0]
  934. ; mov bx, ss:[bx+0]
  935. mov bx, ss:[bx+4]
  936. cCall LogParamError2,<err, lpfn, param, bx>
  937. UnsetKernelDS
  938. pop ds
  939. assumes ds,NOTHING
  940. or ax,ax ; test break flag
  941. endif
  942. RESTOREREGS
  943. if KDEBUG
  944. jz @F ; break if needed
  945. INT3_DEBUG
  946. @@:
  947. endif
  948. cEnd
  949. ;-----------------------------------------------------------------------
  950. sEnd CODE
  951. if KDEBUG
  952. ifdef WOW
  953. sBegin MISCCODE
  954. assumes cs, MISCCODE
  955. assumes ds, nothing
  956. assumes es, nothing
  957. externFP KernelError
  958. ;-----------------------------------------------------------------------;
  959. ; allows KernelError to be called from _TEXT code segment
  960. cProc Far_KernelError,<PUBLIC,FAR>
  961. parmW errcode
  962. parmD lpmsg1
  963. parmD lpmsg2
  964. cBegin
  965. push [bp+14]
  966. push [bp+12]
  967. push [bp+10]
  968. push [bp+8]
  969. push [bp+6]
  970. call far ptr KernelError
  971. cEnd
  972. sEnd MISCCODE
  973. endif ;; WOW
  974. endif ;; KDEBUG
  975. end