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.

326 lines
12 KiB

  1. ;**************************************************************************
  2. ;* TASK2.ASM
  3. ;*
  4. ;* Assembly support for the task enumeration routines.
  5. ;*
  6. ;**************************************************************************
  7. INCLUDE TOOLPRIV.INC
  8. PMODE32 = 0
  9. PMODE = 0
  10. SWAPPRO = 0
  11. INCLUDE TDB.INC
  12. ifdef WOW
  13. INCLUDE WOW.INC
  14. endif
  15. ;** Data
  16. sBegin DATA
  17. lpfnRetAddr DD 0 ;Return address after stack switch
  18. sEnd
  19. ;** External functions
  20. externNP HelperHandleToSel
  21. externNP HelperVerifySeg
  22. externFP GetCurrentTask
  23. externFP DirectedYield
  24. ifdef WOW
  25. externFP PostAppMessage
  26. endif
  27. ;** Functions
  28. .286p
  29. sBegin CODE
  30. assumes CS,CODE
  31. assumes DS,DATA
  32. ; TaskSetCSIP
  33. ; Allows the user to set the CS:IP of a sleeping task so that it will
  34. ; begin execution at this address when the task is yielded to.
  35. ; Returns the old address.
  36. cProc TaskSetCSIP, <PUBLIC,FAR>, <si>
  37. parmW hTask
  38. parmW wCS
  39. parmW wIP
  40. cBegin
  41. assumes DS,nothing
  42. assumes ES,nothing
  43. ;** If this is the current task, do nothing: we only work on
  44. ;** sleeping tasks
  45. cCall GetCurrentTask ;Gets current task in AX
  46. mov bx,hTask ;Get desired task
  47. cmp ax,bx ;Same?
  48. jne @F ;No, it's OK
  49. xor ax,ax ;Return a DWORD zero
  50. cwd
  51. jmp SHORT TC_End
  52. @@:
  53. ;** Get the TDB SS:SP
  54. mov es,bx ;Point to TDB with ES
  55. les si,DWORD PTR es:[TDB_TaskSP] ;Get a pointer to the task stack
  56. ifdef WOW
  57. ;
  58. ; ES:SI now points to the place where we had the TDB's SS:SP pointing
  59. ; This spot in wow is actually the SS:BP frame of the WOW16CALL
  60. ; function. The definitions for this frame come from WOW.INC (WOW.H).
  61. ; The addition of this strange value adjusts the SS:SP pointer back
  62. ; onto the stack, undoing a previous adjustment in TASKING.ASM
  63. add si,(vf_vpCSIP-vf_wThunkCSIP)
  64. endif
  65. ;** Change the CS:IP
  66. mov ax,wIP ;Get the new IP value
  67. xchg ax,es:[si].Task_IP ;Swap with the old one
  68. mov dx,wCS ;Get the new CS value
  69. xchg dx,es:[si].Task_CS ;Swap with the old one
  70. TC_End:
  71. cEnd
  72. ; TaskGetCSIP
  73. ; Gets the next CS:IP that this task will run at.
  74. cProc TaskGetCSIP, <PUBLIC,FAR>, <si>
  75. parmW hTask
  76. cBegin
  77. assumes DS,nothing
  78. assumes ES,nothing
  79. ;** If this is the current task, do nothing: we only work on
  80. ;** sleeping tasks
  81. cCall GetCurrentTask ;Gets current task in AX
  82. mov bx,hTask ;Get desired task
  83. cmp ax,bx ;Same?
  84. jne @F ;No, it's OK
  85. xor ax,ax ;Return a DWORD zero
  86. cwd
  87. jmp SHORT TG_End
  88. @@:
  89. ;** Get the TDB SS:SP
  90. mov es,bx ;Point to TDB with ES
  91. les si,DWORD PTR es:[TDB_TaskSP] ;Get a pointer to the task stack
  92. ifdef WOW
  93. ;
  94. ; ES:SI now points to the place where we had the TDB's SS:SP pointing
  95. ; This spot in wow is actually the SS:BP frame of the WOW16CALL
  96. ; function. The definitions for this frame come from WOW.INC (WOW.H).
  97. ; The addition of this strange value adjusts the SS:SP pointer back
  98. ; onto the stack, undoing a previous adjustment in TASKING.ASM
  99. add si,(vf_vpCSIP-vf_wThunkCSIP)
  100. endif
  101. ;** Change the CS:IP
  102. mov ax,es:[si].Task_IP ;Get the CS:IP to return
  103. mov dx,es:[si].Task_CS
  104. TG_End:
  105. cEnd
  106. ; TaskSwitch
  107. ; Switches to the indicated task from the current one.
  108. ; Returns FALSE if it couldn't task switch.
  109. ; Jumps to the address given by lpJmpAddr
  110. cProc TaskSwitch, <PUBLIC,FAR>, <si,di>
  111. parmW hTask
  112. parmD lpJmpAddr
  113. cBegin
  114. push ds
  115. mov ax, _DATA ;Make sure to set DS
  116. mov ds, ax
  117. assumes ds,DATA
  118. ;** Check to make sure TOOLHELP is installed
  119. cmp wLibInstalled,0 ;Library installed?
  120. pop ds
  121. assumes ds,nothing
  122. jnz @F ;Yes
  123. xor ax,ax ;Return FALSE
  124. jmp TS_End ;No. Fail the API
  125. @@:
  126. ;** Get the task handle
  127. cCall GetCurrentTask ;Get the current task
  128. cmp ax,hTask ;Switch to current task?
  129. jne @F ;No, it's OK
  130. xor ax,ax ;Yes, we can't do that so return FALSE
  131. ifdef WOW
  132. jmp TS_End
  133. else
  134. jmp SHORT TS_End
  135. endif
  136. @@: cCall HelperVerifySeg, <hTask,TDB_sig+1> ;Verify the segment
  137. or ax,ax ;Segment OK?
  138. jz TS_End ;Nope. Get out
  139. mov es,hTask ;Get the TDB
  140. xor ax,ax ;Get a zero just in case
  141. cmp es:[TDB_sig], TDB_SIGNATURE ;Signature match?
  142. jne TS_End ;Return FALSE
  143. ;** Poke in the address to jump to
  144. mov si,es ;Save the hTask
  145. lea ax,TS_FromYield ;Point to new task address
  146. cCall TaskSetCSIP, <si,cs,ax> ;Set the new address
  147. mov es,si ;Get hTask back
  148. ;** Save the jump address from the stack so we can jump to it later
  149. push ds
  150. mov ax,_DATA ;Point to our data segment
  151. mov ds,ax
  152. assumes ds,DATA
  153. mov ax,WORD PTR lpJmpAddr[0];Get the low word of the ret address
  154. mov WORD PTR lpfnRetAddr[0],ax
  155. mov ax,WORD PTR lpJmpAddr[2];Get the selector value
  156. mov WORD PTR lpfnRetAddr[2],ax
  157. pop ds
  158. ifdef WOW
  159. ;** Force a task switch by posting a message. This is because the
  160. ;** event count is not used under WOW.
  161. cCall PostAppMessage,<es, 0, 0, 0, 0>
  162. else
  163. ;** Force a task switch by tampering with the event count
  164. inc es:[TDB_nEvents] ;Force at least one event so we
  165. ; will switch to this task next
  166. endif ;WOW
  167. ;** Switch to the new task. DirectedYield() returns only when this
  168. ;** task is next scheduled
  169. cCall DirectedYield, <si> ;Switch to the new task
  170. mov ax,1 ;Return TRUE
  171. jmp SHORT TS_End ;Get out
  172. ;** Restore from the directed yield
  173. TS_FromYield:
  174. ;** Make a stack frame to work on. We can't trash any regs
  175. PUBLIC TS_FromYield
  176. sub sp,4 ;Save room for a far ret frame
  177. push bp ;Make a stack frame
  178. mov bp,sp
  179. pusha ;Save everything
  180. push ds
  181. push es
  182. ;** Get our jump address from our DS and put in far ret frame
  183. mov ax,_DATA ;Get the TOOLHELP DS
  184. mov ds,ax
  185. mov ax,WORD PTR lpfnRetAddr[0] ;Get the offset
  186. mov [bp + 2],ax ;Put it on the stack
  187. mov ax,WORD PTR lpfnRetAddr[2] ;Get the selector
  188. mov [bp + 4],ax ;Put on the stack
  189. ;** Restore the event count
  190. mov es,segKernel ;Get the KERNEL segment
  191. mov bx,npwTDBCur ;Get the current task pointer
  192. mov es,es:[bx] ;Get the TDB pointer in ES
  193. ifndef WOW
  194. dec es:[TDB_nEvents] ;Clear the dummy event we put in
  195. endif
  196. ;** Clear the stack and 'return' to the new address
  197. pop es
  198. pop ds
  199. popa
  200. pop bp
  201. retf
  202. TS_End:
  203. cEnd
  204. ; TaskInfo
  205. ;
  206. ; Returns information about the task with the given block handle
  207. cProc TaskInfo, <PUBLIC,NEAR>, <si,di,ds>
  208. parmD lpTask
  209. parmW wTask
  210. cBegin
  211. ;** Start by verifying the selector
  212. mov ax,wTask ;Get the selector
  213. cCall HelperHandleToSel, <ax> ;Convert it to a selector
  214. push ax ;Save it
  215. mov bx,TDBSize
  216. cCall HelperVerifySeg, <ax,bx>
  217. pop bx ;Get selector back
  218. or ax,ax ;FALSE return?
  219. jnz TI_SelOk ;Selector's OK
  220. xor ax,ax ;Return FALSE
  221. jmp TI_End
  222. TI_SelOk:
  223. ;** Verify that the TDB signature matches
  224. mov ds,bx ;Point with DS
  225. cmp ds:[TDB_sig],TDB_SIGNATURE ;Is this really a TDB?
  226. jz TI_SigOk ;Must be
  227. xor ax,ax ;Return FALSE
  228. jmp SHORT TI_End
  229. TI_SigOk:
  230. ;** Now, get information from the TDB
  231. les di,lpTask ;Point to destination buffer
  232. mov ax,ds:[TDB_next] ;Get the next TDB handle
  233. mov es:[di].te_hNext,ax ;Save in public structure
  234. mov ax,wTask ;Get this task's handle
  235. mov es:[di].te_hTask,ax ;Save in buffer
  236. mov ax,ds:[TDB_Parent] ;Get this task's parent
  237. mov es:[di].te_hTaskParent,ax ;Save
  238. mov ax,ds:[TDB_taskSS] ;Get the SS
  239. mov es:[di].te_wSS,ax
  240. mov ax,ds:[TDB_taskSP] ;Get the SP
  241. mov es:[di].te_wSP,ax
  242. mov ax,ds:[TDB_nEvents] ;Event counter
  243. mov es:[di].te_wcEvents,ax
  244. mov ax,ds:[TDB_Queue] ;Queue pointer
  245. mov es:[di].te_hQueue,ax
  246. mov ax,ds:[TDB_PDB] ;Offset of DOS PSP
  247. mov es:[di].te_wPSPOffset,ax
  248. mov ax,ds:[TDB_Module] ;Instance handle (DS) of task
  249. mov es:[di].te_hInst,ax
  250. mov ax,ds:[TDB_pModule] ;Module database handle
  251. mov es:[di].te_hModule,ax
  252. mov cx,8 ;Copy module name
  253. push di ;Save structure pointer
  254. mov si,TDB_ModName ;Point to the string
  255. add di,te_szModule ; and to the string dest
  256. cld
  257. repnz movsb ;Copy the string
  258. mov BYTE PTR es:[di],0 ;Zero terminate it
  259. pop di ;Get structure pointer back
  260. ;** Get information from the stack segment. Vars from KDATA.ASM
  261. mov ax,es:[di].te_wSS ;Get the SS value
  262. verr ax ;OK to read here?
  263. jnz TI_SkipThis ;No, so don't do it
  264. mov ds,ax ;Point with DS
  265. mov ax,ds:[0ah] ;Lowest value of SP allowed
  266. mov es:[di].te_wStackTop,ax ;Save in structure
  267. mov ax,ds:[0ch] ;Get stack minimum value so far
  268. mov es:[di].te_wStackMinimum,ax ;Save in structure
  269. mov ax,ds:[0eh] ;Largest value of SP allowed
  270. mov es:[di].te_wStackBottom,ax ;Save in structure
  271. ;** Return TRUE on success
  272. TI_SkipThis:
  273. mov ax,1 ;Return TRUE code
  274. TI_End:
  275. cEnd
  276. sEnd
  277. END