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.

568 lines
16 KiB

  1. TITLE TASKING.ASM - WOW Tasking Support
  2. PAGE ,132
  3. ;
  4. ; WOW v1.0
  5. ;
  6. ; Copyright (c) 1991, Microsoft Corporation
  7. ;
  8. ; TASKING.ASM
  9. ; WOW Tasking Support on 16 bit side - also see wkman.c
  10. ;
  11. ; History:
  12. ; 23-May-91 Matt Felton (mattfe) Created
  13. ; 12-FEB-92 Cleanup
  14. ;
  15. .xlist
  16. include kernel.inc
  17. include tdb.inc
  18. include newexe.inc
  19. include wow.inc
  20. include vint.inc
  21. .list
  22. .386
  23. if KDEBUG
  24. externFP OutputDebugString
  25. endif
  26. DataBegin
  27. externB Kernel_InDOS
  28. externB Kernel_flags
  29. externB InScheduler
  30. ifndef WOW
  31. externB fProfileDirty
  32. endif
  33. externW WinFlags
  34. externW cur_drive_owner
  35. externW curTDB
  36. externW Win_PDB
  37. externW LockTDB
  38. externW headTDB
  39. externW hShell
  40. externW pGlobalHeap
  41. externW hExeHead
  42. externW f8087
  43. externD pIsUserIdle
  44. externW wCurTaskSS
  45. externW wCurTaskBP
  46. globalw gwHackpTDB,0
  47. globalw gwHackTaskSS,0
  48. globalw gwHackTaskSP,0
  49. externW PagingFlags
  50. DataEnd
  51. ifdef WOW
  52. externFP ExitKernelThunk
  53. externFP WowInitTask
  54. externFP Yield
  55. externFP WOW16CallNewTaskRet
  56. externFP WowKillTask
  57. externFP WOW16DoneBoot
  58. externFP WOWGetCurrentDirectory
  59. externFP ExitCall
  60. externFP WowSyncTask
  61. endif
  62. sBegin CODE
  63. assumes cs,CODE
  64. assumes ds,NOTHING
  65. assumes es,NOTHING
  66. externNP LoadSegment
  67. externNP DeleteTask
  68. externNP InsertTask
  69. externNP ShrinkHeap
  70. ifdef WOW
  71. externNP Int21Handler
  72. endif
  73. if SDEBUG
  74. externNP DebugSwitchOut
  75. externNP DebugSwitchIn
  76. endif
  77. ;-----------------------------------------------------------------------;
  78. ; StartWOWTask ;
  79. ; ;
  80. ; Start a WOW 32 Task ;
  81. ; ;
  82. ; Arguments: ;
  83. ; Parmw1 -> TDB Of New Task ;
  84. ; Parmw2 New Task SS ;
  85. ; Parmw3 New Task SP ;
  86. ; Returns: ;
  87. ; AX - TRUE/FALSE if we we able to create a new WOW task ;
  88. ; Error Returns: ;
  89. ; none ;
  90. ; Registers Preserved: ;
  91. ; ;
  92. ; Registers Destroyed: ;
  93. ; BX,CX,DX ;
  94. ; Calls: ;
  95. ; See Notes ;
  96. ; History: ;
  97. ; ;
  98. ; Fre 24-May-1991 14:30 -by- Matthew A. Felton [mattfe] ;
  99. ; Created ;
  100. ;-----------------------------------------------------------------------;
  101. ; The 16-Bit Kernel has created the new task and its ready to go
  102. ; 1. Temporarily Switch to New Task Stack S2
  103. ; 2. Fake Far Return from Thunk to point to StartW16Task
  104. ; 3. Thunk to WOW32 - This will create a new Thread and call Win32 InitTask()
  105. ; Note InitTask() will not return from the non-preemptive scheduler until
  106. ; This thread does a Yield.
  107. ; 4. When the thunk returns is jmps to WOW16TaskStarted on S2 leaving
  108. ; S2 ready for the new task when it returns
  109. ; 5. Restore S1 - Original Task Stack
  110. ; 6. Return Back to LoadModule who will Yield and start T2 going.
  111. assumes ds, nothing
  112. assumes es, nothing
  113. cProc StartWOWTask,<PUBLIC,FAR>
  114. parmW pTDB
  115. parmW wTaskSS
  116. parmW wTaskSP
  117. cBegin
  118. SetKernelDS ds
  119. mov es,pTDB ; Get New Task TDB, will use later
  120. push curTDB ; Save our TDB
  121. push bp ; save BP (we don't exit wow16cal directly)
  122. mov di,ss ; Save Current Task Stack
  123. mov cx,sp ; di=ss cx=sp
  124. ; switch to new task stack temporarily
  125. FCLI ; Disable Ints Till We get Back
  126. ; To presever new fram
  127. mov si,wTaskSP ; Grab this before SS goes away
  128. mov ss,wTaskSS ; Switch to new task stack.
  129. mov sp,si ;
  130. mov curTDB,es ; Set curTDB to new task
  131. ;
  132. pushf
  133. pop ax
  134. or ax,0200h ; Re-enable interrupts
  135. push ax
  136. push es ; hTask
  137. mov es, es:[TDB_pModule] ; exehdr
  138. mov ax, es:[ne_expver]
  139. mov dx, es:[ne_flags]
  140. and dx, NEWINPROT ; prop. font bit
  141. push es ; hModule
  142. push es ; Pointer to module name
  143. push es:ne_restab
  144. push es ; Pointer to module path
  145. push word ptr es:ne_crc+2
  146. push dx ; expwinver. argument for WOWINITTASK
  147. push ax
  148. mov es, curTDB ; resotre es, just being safe
  149. ; thunk to wow32 to create a thread and task
  150. push cs ; Fake Out FAR Return to StartW16Task
  151. push offset StartW16Task
  152. jmp WowInitTask ; Start Up the W32 Thread
  153. public WOW16TaskStarted
  154. WOW16TaskStarted:
  155. mov ss,di ; Restore Calling Task Stack
  156. mov sp,cx
  157. pop bp
  158. pop curTDB ; Restore real CurTDB
  159. FSTI ; OK we look like old task
  160. cEnd
  161. ;
  162. ; First code executed By New Task - Setup Registers and Go
  163. ;
  164. StartW16Task:
  165. add sp,+12
  166. pop ax ; Flags
  167. mov bp,sp
  168. xchg ax,[bp+20] ; Put flags down & pick up cs
  169. xchg ax,[bp+18] ; Put cs down & pick up ip
  170. xchg ax,[bp+16] ; Put ip down & pick up bp
  171. mov bp,ax
  172. dec bp
  173. pop dx
  174. pop bx
  175. pop es
  176. pop cx
  177. pop ax
  178. pop di
  179. pop si
  180. pop ds
  181. call SyncTask
  182. iret ; App Code Starts From Here
  183. ; ExitKernel
  184. ;
  185. ; Enter When the 16 bit Kernel is going away -- never returns.
  186. ; In WOW this is a register-args wrapper for the stack-args
  187. ; thunk ExitKernelThunk.
  188. public ExitKernel
  189. ExitKernel:
  190. cCall ExitKernelThunk, <ax>
  191. INT3_NEVER ; ExitKernel never returns.
  192. ; BootSchedule
  193. ;
  194. ; Entered When Bogus Boot Task goes Away - treated same as task exit.
  195. public BootSchedule
  196. BootSchedule:
  197. CheckKernelDS DS ; Make Sure we Address Kernel DS
  198. mov [curTDB],0 ; Make No Task the Current Task
  199. jmp WOW16DONEBOOT
  200. ; ExitSchedule
  201. ;
  202. ; We get here when a 16 bit task has exited - go kill this task
  203. ; Win32 non-preemptive scheduler will wake someone else to run.
  204. public ExitSchedule
  205. ExitSchedule:
  206. CheckKernelDS DS ; Make Sure we Address Kernel DS
  207. mov ax,[LockTDB] ; If I am the locked TDB then clear flag
  208. cmp ax,[curTDB]
  209. jnz @f
  210. mov [LockTDB],0
  211. @@:
  212. mov [curTDB],0 ; Make No Task the Current Task
  213. call ShrinkHeap
  214. jmp WowKillTask ; Go Kill Myself (NEVER RETURNS)
  215. ;-----------------------------------------------------------------------;
  216. ; SwitchTask - This is NOT a subroutine DO NOT CALL IT
  217. ;
  218. ; This routine does a Win 3.1 compatible task switch.
  219. ;
  220. ; Arguments:
  221. ; AX == Next Tasks TDB pointer
  222. ; Returns:
  223. ; nothing
  224. ; Error Returns:
  225. ; nothing
  226. ; Registers Preserved:
  227. ;
  228. ; Registers Destroyed:
  229. ;
  230. ; Calls:
  231. ; SaveState
  232. ; RestoreState
  233. ;
  234. ; History:
  235. ; 22-May-91 Matt Felton (MattFe) Created
  236. ; Using idea's from Win 3.1 Schedule.Asm
  237. ;
  238. ;-----------------------------------------------------------------------;
  239. assumes ds, nothing
  240. assumes es, nothing
  241. public SwitchTask
  242. SwitchTask:
  243. CheckKernelDS ds
  244. ReSetKernelDS ds
  245. inc InScheduler ; set flag for INT 24...
  246. cmp curTDB,0 ; Previous Task Gone Away ?
  247. jnz @f ; No ->
  248. ; Yes
  249. mov di,ax ; DI = New TDB
  250. mov ds,ax ; DS = New TDB
  251. jmps dont_save_state ; Get Set for this new guy
  252. @@:
  253. push ax ; Save Next Tasks TDB pointer
  254. ; COMPAT 22-May-91 Mattfe, Idle callout for funky screen drivers is done by
  255. ; the Windows scheduler - that will not happen either from WOW. INT 28
  256. ; and Win386 1689 int2f call
  257. ; There was PokeAtSegments code which during idle time brought back segments !
  258. ; Do Debuggers Care that the stack frame of registers looks like a Windows stack frame
  259. ; when we do the debugger callout ? - check with someone in CVW land.
  260. mov es,curTDB ; ES = Previous Task TDB
  261. mov ax,es ; Don't SS,SP For DEAD Task
  262. or ax,ax
  263. jz @F
  264. mov ax,wCurTaskSS ; FAKE Out TDB_taskSS,SP so that
  265. mov es:[TDB_taskSS],ax ; The Old Task Task_BP looks right
  266. mov ax,wCurTaskBP
  267. sub ax,(Task_BP-Task_DX)
  268. mov es:[TDB_taskSP],ax
  269. @@:
  270. pop ds ; DS = Next Task TDB
  271. UnSetKernelDS ds
  272. if KDEBUG
  273. ; Assertion Check TDB_taskSS == SS for current Task
  274. mov ax,ds:[TDB_taskSS]
  275. mov di,ss
  276. cmp di,ax
  277. jz @F
  278. ; int 3
  279. @@:
  280. endif; KDEBUG
  281. mov di,ds ; DI = destination task
  282. xor si,si ; SI is an argument to RestoreState
  283. mov ax,es ; NOTE TDB_SS,SP Are note Correct
  284. or ax,ax ; might affect debugger compatability.
  285. jz short dont_save_state
  286. cmp es:[TDB_sig],TDB_SIGNATURE
  287. jnz short dont_save_state
  288. mov si,es ; SI = Old Task
  289. cCall SaveState,<si>
  290. if SDEBUG
  291. push ds
  292. mov ds,ax
  293. call DebugSwitchOut ; Note Stack Frame is not Compatible
  294. pop ds ; Do we care ?
  295. endif
  296. dont_save_state:
  297. SetKernelDS es
  298. mov curTDB,di
  299. mov ax, ds:[TDB_PDB] ; Set our idea of the PDB
  300. mov Win_PDB, ax
  301. SetKernelDS es
  302. cmp di,0 ; the first task, will never get 0
  303. jz dont_restore_state
  304. or Kernel_flags,kf_restore_CtrlC OR kf_restore_disk
  305. if SDEBUG
  306. call DebugSwitchIn
  307. endif
  308. dont_restore_state:
  309. ; Switch to new task stack.
  310. mov curTDB,di
  311. dec InScheduler ; reset flag for INT 24
  312. SetKernelDS ds ; Set the Kernel DS again
  313. ;the word at [vf_wES] is a selector that's about to be popped into
  314. ;the ES in WOW16CallNewTaskRet. this selector could be the TDB of
  315. ;a task that just died, in which case it's invalid. so let's
  316. ;shove something in there that won't cause a GP when we do the POP ES.
  317. ;
  318. ; In some cases we are switching tasks while returning to a callback.
  319. ; When this happens our stack is a CBVDMFRAME instead of a VDMFRAME.
  320. ; We only want to shove a safe ES,FS,GS value when it's a VDMFRAME and
  321. ; we're returning from an API call rather than calling back to
  322. ; 16-bit code.
  323. ;
  324. ; Regardless of which frame we're using, ss:sp points to wRetID.
  325. mov bx, sp
  326. cmp WORD PTR ss:[bx], RET_DEBUGRETURN ; if (wRetID > RET_DEBUGRETURN)
  327. ja dont_stuff_regs ; goto dont_stuff_regs
  328. sub bx,vf_wTDB + 2 ;bx is now start of VDMFRAME struct
  329. mov ss:[bx+vf_wES],es ;put something safe in there
  330. ;Win31 does not save fs, gs over task switches, so we zero them out here
  331. mov word ptr ss:[bx+vf_wFS],0 ;put something safe in there
  332. mov word ptr ss:[bx+vf_wGS],0 ;put something safe in there
  333. dont_stuff_regs:
  334. if KDEBUG
  335. mov bx, sp
  336. cmp WORD PTR ss:[bx], RET_TASKSTARTED
  337. jne @f
  338. INT3_NEVER ; We need to stuff ES for RET_TASKSTARTED
  339. ; if we hit this breakpoint.
  340. @@:
  341. endif
  342. ; Hung App Support
  343. ; If the new task is the one we want to kill then force it to exit
  344. mov bx,curTDB ; if ( curTDB == LockTDB )
  345. cmp bx,LockTDB
  346. jnz SW_DontKillIt
  347. mov ax,4CFFH ; YES -> Exit
  348. DOSCALL
  349. INT3_NEVER
  350. SW_DontKillIt:
  351. jmp WOW16CallNewTaskRet ; Continue with the new task.
  352. ;-----------------------------------------------------------------------;
  353. ; SaveState ;
  354. ; ;
  355. ; Saves the state of the current MS-DOS process. This means the per ;
  356. ; task interrupt vectors, the drive and directory, EEMS land if any, ;
  357. ; and old app stuff if any. ;
  358. ; ;
  359. ; Arguments: ;
  360. ; parmW destination ;
  361. ; ;
  362. ; Returns: ;
  363. ; DS returned in AX. ;
  364. ; ;
  365. ; Error Returns: ;
  366. ; ;
  367. ; Registers Preserved: ;
  368. ; ;
  369. ; Registers Destroyed: ;
  370. ; ;
  371. ; Calls: ;
  372. ; ;
  373. ; History: ;
  374. ; ;
  375. ; Mon 07-Aug-1989 21:53:42 -by- David N. Weise [davidw] ;
  376. ; Removed the WinOldApp support. ;
  377. ; ;
  378. ; Tue Feb 03, 1987 08:21:53p -by- David N. Weise [davidw] ;
  379. ; Got rid of the rest of the DOS version dependencies. ;
  380. ; ;
  381. ; Thu Jan 22, 1987 03:15:15a -by- David N. Weise [davidw] ;
  382. ; Took out the saving of the ^C state, DTA address, and ErrorMode. ;
  383. ; ;
  384. ; Sun Jan 04, 1987 04:40:44p -by- David N. Weise [davidw] ;
  385. ; Added this nifty comment block. ;
  386. ;-----------------------------------------------------------------------;
  387. assumes ds, nothing
  388. assumes es, nothing
  389. cProc SaveState,<PUBLIC,NEAR>,<si,di,ds>
  390. parmW destination
  391. cBegin
  392. cld
  393. SetKernelDS
  394. mov ax,f8087
  395. UnSetKernelDS
  396. mov ds,destination
  397. or ax,ax
  398. if 0
  399. jz short no_fstcw
  400. .8087
  401. fstcw ds:[TDB_FCW]
  402. endif
  403. no_fstcw:
  404. test ds:[TDB_Drive],10000000b; if hi bit set....
  405. jnz short ss_ret ; ...no need to get dir
  406. mov ah,19h
  407. DOSCALL
  408. mov dl,al
  409. inc dl
  410. or al,10000000b
  411. mov ds:[TDB_Drive],al ; save it (A=0, B=1, etc.)
  412. mov si,TDB_LFNDirectory
  413. mov byte ptr [si],'\' ; set "\"
  414. inc si
  415. ; get Long path
  416. cCall WowGetCurrentDirectory,<80h, ds, si>
  417. or dx, dx
  418. jz short ss_ret
  419. mov byte ptr [si-1],0 ; indicate error with null byte
  420. ss_ret: mov ax,ds
  421. cEnd
  422. ;-----------------------------------------------------------------------;
  423. ; RestoreState ;
  424. ; ;
  425. ; Restores the MS-DOS interrupt vectors in real mode. ;
  426. ; ;
  427. ; Arguments: ;
  428. ; none ;
  429. ; Returns: ;
  430. ; none ;
  431. ; Error Returns: ;
  432. ; none ;
  433. ; Registers Preserved: ;
  434. ; BX,CX,DX,DI,SI,DS,ES ;
  435. ; Registers Destroyed: ;
  436. ; AX ;
  437. ; Calls: ;
  438. ; nothing ;
  439. ; History: ;
  440. ; ;
  441. ; Mon 07-Aug-1989 21:53:42 -by- David N. Weise [davidw] ;
  442. ; Removed the WinOldApp support. ;
  443. ; ;
  444. ; Tue Feb 03, 1987 08:21:53p -by- David N. Weise [davidw] ;
  445. ; Got rid of the rest of the DOS version dependencies. ;
  446. ; ;
  447. ; Thu Jan 22, 1987 03:15:15a -by- David N. Weise [davidw] ;
  448. ; Took out the restoring of the ^C state, DTA address, and ErrorMode. ;
  449. ; ;
  450. ; Sun Jan 04, 1987 04:45:31p -by- David N. Weise [davidw] ;
  451. ; Added this nifty comment block. ;
  452. ;-----------------------------------------------------------------------;
  453. ; SyncTask
  454. ;
  455. ; Enter: when new task starts
  456. ; check if the new task is blocked by appshelp
  457. cProc SyncTask,<PUBLIC,NEAR> <ax,bx,cx,dx,di,si,es,ds>
  458. cBegin
  459. STL:
  460. cCall WowSyncTask
  461. cmp ax, 0
  462. je @F
  463. jg STL
  464. call ExitCall
  465. @@:
  466. cEnd
  467. sEnd CODE
  468. end