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.

145 lines
5.4 KiB

  1. PAGE 60,150
  2. ;***************************************************************************
  3. ;* TERMINAT.ASM
  4. ;*
  5. ;* Assembly code routine used for the TOOLHELP.DLL app terminate
  6. ;* routine.
  7. ;*
  8. ;***************************************************************************
  9. INCLUDE TOOLPRIV.INC
  10. INCLUDE TDB.INC
  11. ;** Symbols
  12. I_EXCEPTION EQU 0
  13. I_INTERRUPT EQU 1
  14. MAX_INTERRUPT EQU 5
  15. GIVE_WDEB386 EQU 8000h
  16. Q_HACK_30 EQU 54h
  17. .286p
  18. ;** Data
  19. sBegin DATA
  20. wTermFlags DW ? ;Save terminate flags across Yield
  21. sEnd
  22. ;** Imported values
  23. externFP InterruptUnRegister
  24. externFP NotifyUnRegister
  25. externFP GetCurrentTask
  26. externFP FatalAppExit
  27. externFP TaskSetCSIP
  28. externFP DirectedYield
  29. externFP TaskSwitch
  30. sBegin CODE
  31. assumes CS,CODE
  32. assumes DS,DATA
  33. ; TerminateApp
  34. ; Terminates the task in one of two ways: TERMINATE_NORMAL or
  35. ; TERMINATE_USER_DISPLAY. TERMINATE_NORMAL calls KERNEL to display
  36. ; the UAE box and terminates the app. TERMINATE_USER_DISPLAY also
  37. ; terminates the app but assumes the user has displayed some warning.
  38. ; If the task passed in is not the current task, this function does
  39. ; the DirectedYield() to switch to the correct task before terminating
  40. ; it.
  41. ; This function does not return when terminating the current task
  42. ; except when WDEB386 is installed and the (undocumented) GIVE_WDEB386
  43. ; flag is set.
  44. ; Caller: TerminateApp(
  45. ; HANDLE hTask, (If NULL, does current task)
  46. ; WORD wFlags)
  47. cProc TerminateApp, <FAR,PUBLIC>, <si,di,ds>
  48. parmW hTask
  49. parmW wFlags
  50. cBegin
  51. mov ax, _DATA ;Get our DS
  52. mov ds, ax
  53. ;** Save the flags in the DS so we can get after DYield
  54. mov ax,wFlags ;Get the parameter flags
  55. mov wTermFlags,ax ;Save them
  56. ;** Get the task value
  57. cCall GetCurrentTask ;Get the task
  58. mov si,hTask ;Get the hTask value
  59. or si,si ;Zero?
  60. jnz TA_10 ;No
  61. mov es,ax ;Point ES at current task
  62. jmp SHORT TA_NukeCurrent ;In this case we always nuke current
  63. TA_10:
  64. ;** If this is the current task, just nuke it and don't return
  65. cmp ax,si ;Current?
  66. mov es,si ;Point ES at task
  67. je TA_NukeCurrent ;Yes, nuke it directly
  68. ;** Switch to the new task and prepare to nuke it
  69. lea ax,TA_NewTask ;Get address of new task entry
  70. cCall TaskSwitch, <si,cs,ax> ;Switch to this task
  71. jmp SHORT TA_End ;Get out
  72. ;** We're in the new task now
  73. TA_NewTask:
  74. mov ax,_DATA ;Get the TOOLHELP DS
  75. mov ds,ax
  76. mov es,segKernel ;Get the KERNEL segment
  77. mov bx,npwTDBCur ;Get the current task pointer
  78. mov es,es:[bx] ;Get the TDB pointer in ES
  79. ;** HACK ALERT!!!! In order to get USER to allow us to terminate
  80. ;* this app, we are manually nuking the semaphore. This is
  81. ;* at a fixed offsets in the Q structure and only needs to
  82. ;** be done in 3.0
  83. test wTHFlags,TH_WIN30 ;In 3.0?
  84. jz TA_NukeCurrent ;No, don't do this ugly hack
  85. push es ;Save ES while we play with the queue
  86. mov es,es:[TDB_Queue] ;ES points to queue now
  87. mov bx,Q_HACK_30 ;Get 3.0 offset
  88. mov WORD PTR es:[bx],0 ;Clear the semaphore count
  89. mov WORD PTR es:[bx + 2],0 ; and the semaphore value to wait for
  90. pop es ;ES points to TDB again
  91. TA_NukeCurrent:
  92. ;** Check the flag values. If NO_UAE_BOX, tell KERNEL
  93. ;** not to display the normal UAE box.
  94. test wTermFlags,NO_UAE_BOX ;Display the box?
  95. jz TA_20 ;Yes, so skip this stuff
  96. or es:[TDB_ErrMode],02 ;Set the no display box flag
  97. TA_20:
  98. ;** Terminate the app using KERNEL
  99. cCall FatalAppExit, <0,0,0> ;Do it
  100. ;** If we're flagged that this is an internal terminate, we just want
  101. ;* to return if WDEB is installed so that we can pass the
  102. ;** fault on. To do this, we must return here to the caller.
  103. test wFlags,GIVE_WDEB386 ;Internal entry?
  104. jnz TA_End ;Yes, don't nuke app
  105. ;** If KERNEL doesn't nuke the app (does this if WDEB386
  106. ;** is installed), nuke it ourselves (no UAE box)
  107. mov es,segKernel ;Get the KERNEL segment
  108. mov bx,npwTDBCur ;Get the current task pointer
  109. mov es,es:[bx] ; in ES
  110. cmp WORD PTR es:[TDB_USignalProc] + 2,0 ;USER signal proc?
  111. jz @F ;No
  112. mov bx,0666h ;Death knell
  113. mov di, -1
  114. cCall es:[TDB_USignalProc],<es,bx,di,es:[TDB_Module],es:[TDB_Queue]>
  115. @@: mov ax,4CFFH ;Nuke the app
  116. int 21h ;We don't return here
  117. TA_End:
  118. cEnd
  119. sEnd
  120. END