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.

1423 lines
32 KiB

  1. .xlist
  2. include kernel.inc
  3. include tdb.inc
  4. include pdb.inc
  5. include kdos.inc
  6. include eems.inc
  7. include protect.inc
  8. ifdef WOW
  9. include vint.inc
  10. endif
  11. .list
  12. externFP LoadLibrary
  13. externFP LoadModule
  14. externFP GlobalFree,
  15. externFP GlobalFreeAll
  16. externFP GlobalCompact
  17. externFP FreeModule
  18. externFP GlobalDOSFree
  19. externFP FreeSelector
  20. externFP GetProcAddress ; WIN32S
  21. externFP ISetErrorMode ; WIN32S
  22. externFP ISetHandleCount
  23. externFP ExitKernelThunk
  24. externNP DPMIProc
  25. extrn BUNNY_351:FAR
  26. ifdef WOW
  27. DRIVE_REMOTE equ 4
  28. externW headTDB
  29. externFP lstrlen
  30. externFP WOWSetIdleHook
  31. externFP GetDriveType
  32. externFP WowShutdownTimer
  33. externFP WowTrimWorkingSet
  34. externB fShutdownTimerStarted
  35. externW cur_drive_owner
  36. endif
  37. externW pStackBot
  38. ;externW pStackMin
  39. externW pStackTop
  40. DataBegin
  41. externB Kernel_flags
  42. externB num_tasks
  43. externB Kernel_InDOS
  44. externB Kernel_InINT24
  45. externB WOAName
  46. externB grab_name
  47. externB fBooting
  48. externB graphics
  49. externB fExitOnLastApp
  50. externW cur_dos_PDB
  51. externW Win_PDB
  52. externW headPDB
  53. externW topPDB
  54. externW curTDB
  55. externW curDTA
  56. externW PHTcount
  57. externW gmove_stack
  58. externW MyCSSeg
  59. externW wExitingTDB
  60. externD lpSystemDir
  61. if KDEBUG
  62. externW allocTask
  63. endif
  64. if ROM
  65. externD prevInt21Proc
  66. endif
  67. externD lpint21
  68. externD pExitProc
  69. if PMODE32
  70. externD pDisplayCritSec
  71. externW PagingFlags
  72. externD lpReboot
  73. endif
  74. ifdef FE_SB
  75. ifndef KOREA
  76. externD pJpnSysProc
  77. endif
  78. endif
  79. DataEnd
  80. sBegin DATA
  81. externW gmove_stack
  82. ifdef PMODE32
  83. ifndef WOW
  84. WIN32S = 1 ; enable code for Win32S support
  85. endif
  86. endif
  87. ifdef WIN32S
  88. ; Win32S support
  89. selExecPE DW 0
  90. offExecPE DW 0
  91. endif
  92. sEnd DATA
  93. assumes DS,NOTHING
  94. sBegin CODE
  95. assumes CS,CODE
  96. ife ROM
  97. externD prevInt21Proc
  98. endif
  99. externNP Real_DOS
  100. externNP PathDrvDSDX
  101. externNP SetErrorDrvDSDX
  102. externNP SetCarryRet
  103. externNP ExitSchedule
  104. externNP UnlinkObject
  105. externNP final_call_for_DOS
  106. externNP cmp_sel_address
  107. externNP free_sel
  108. externNP SegToSelector
  109. if SDEBUG
  110. externNP DebugExitCall
  111. endif
  112. externNP DeleteTask
  113. ;-----------------------------------------------------------------------;
  114. ; Set_DTA (DOS Call 1Ah) ;
  115. ; ;
  116. ; Simply records on a task basis the DTA. ;
  117. ; ;
  118. ; Arguments: ;
  119. ; ;
  120. ; Returns: ;
  121. ; ;
  122. ; Error Returns: ;
  123. ; ;
  124. ; Registers Preserved: ;
  125. ; ;
  126. ; Registers Destroyed: ;
  127. ; ;
  128. ; Calls: ;
  129. ; ;
  130. ; History: ;
  131. ; ;
  132. ; Sat Jan 10, 1987 09:19:36p -by- David N. Weise [davidw] ;
  133. ; Wrote it. ;
  134. ;-----------------------------------------------------------------------;
  135. assumes ds, nothing
  136. assumes es, nothing
  137. cProc Set_DTA,<PUBLIC,NEAR>
  138. cBegin nogen
  139. push es
  140. SetKernelDS es
  141. mov curDTA.off,dx
  142. mov curDTA.sel,ds
  143. mov es,curTDB
  144. UnSetKernelDS es
  145. cmp es:[TDB_sig],TDB_SIGNATURE
  146. jne Set_DTA_noTDB
  147. mov es:[TDB_DTA].off,dx
  148. mov es:[TDB_DTA].sel,ds
  149. Set_DTA_noTDB:
  150. pop es
  151. jmp final_call_for_DOS
  152. cEnd nogen
  153. ;-----------------------------------------------------------------------;
  154. ; SaveRegs ;
  155. ; ;
  156. ; Does what it says. ;
  157. ; ;
  158. ; Arguments: ;
  159. ; ;
  160. ; Returns: ;
  161. ; ;
  162. ; Error Returns: ;
  163. ; ;
  164. ; Registers Preserved: ;
  165. ; ;
  166. ; Registers Destroyed: ;
  167. ; ;
  168. ; Calls: ;
  169. ; ;
  170. ; History: ;
  171. ; ;
  172. ; Fri Jan 16, 1987 09:57:49p -by- David N. Weise [davidw] ;
  173. ; Added this nifty comment block. ;
  174. ;-----------------------------------------------------------------------;
  175. assumes ds, nothing
  176. assumes es, nothing
  177. cProc SaveRegs,<PUBLIC,NEAR>
  178. cBegin nogen
  179. xchg dx, user_DX ; Return address in DX
  180. push es
  181. push bx
  182. push ax
  183. push cx
  184. push si
  185. push di
  186. and USER_FL,11111110b ; clc flag
  187. push dx
  188. mov dx, user_DX ; Rescue DX for what it's worth
  189. cld
  190. ret
  191. cEnd nogen
  192. ;-----------------------------------------------------------------------;
  193. ; RestoreRegs ;
  194. ; ;
  195. ; Does what it says and (used to cli). ;
  196. ; ;
  197. ; Arguments: ;
  198. ; ;
  199. ; Returns: ;
  200. ; ;
  201. ; Error Returns: ;
  202. ; ;
  203. ; Registers Preserved: ;
  204. ; ;
  205. ; Registers Destroyed: ;
  206. ; ;
  207. ; Calls: ;
  208. ; ;
  209. ; History: ;
  210. ; ;
  211. ; Fri Jan 16, 1987 10:00:41p -by- David N. Weise [davidw] ;
  212. ; Added this nifty comment block. ;
  213. ;-----------------------------------------------------------------------;
  214. assumes ds, nothing
  215. assumes es, nothing
  216. cProc RestoreRegs,<PUBLIC,NEAR>
  217. cBegin nogen
  218. pop di ; Return address
  219. xchg di, user_BP ; Insert for ret later, get saved BP
  220. mov bp, di
  221. dec bp
  222. pop di
  223. pop si
  224. pop cx
  225. pop ax
  226. pop bx
  227. pop es
  228. pop dx
  229. pop ds
  230. ret ; SP points to user_BP
  231. cEnd nogen
  232. ;-----------------------------------------------------------------------;
  233. ; ;
  234. ; Handle the Int21 func 67 call "Set Maximum Handle Count" ;
  235. ; ;
  236. ;-----------------------------------------------------------------------;
  237. cProc SetMaxHandleCount,<PUBLIC,NEAR>
  238. cBegin nogen
  239. pop ds
  240. pop bp ; clean up stack
  241. dec bp
  242. cmp bx, 255
  243. ja smhc_err1
  244. push bx
  245. push cx
  246. push dx
  247. cCall ISetHandleCount,<bx>
  248. pop dx
  249. pop cx
  250. pop bx
  251. cmp ax, bx ; did we get everything?
  252. jne smhc_err2
  253. clc
  254. jmp smhcexit
  255. smhc_err1:
  256. mov ax,4 ; too many open files
  257. stc ; set carry flag
  258. jmp smhcexit
  259. smhc_err2:
  260. mov ax,8 ; not enough memory
  261. stc ; set carry flag
  262. smhcexit:
  263. STIRET
  264. ret
  265. cEnd nogen
  266. ;-----------------------------------------------------------------------;
  267. ; Set_Vector (DOS Call 25h) ;
  268. ; Get_Vector (DOS Call 35h) ;
  269. ; ;
  270. ; ;
  271. ; Arguments: ;
  272. ; ;
  273. ; Returns: ;
  274. ; ;
  275. ; Error Returns: ;
  276. ; ;
  277. ; Registers Preserved: ;
  278. ; ;
  279. ; Registers Destroyed: ;
  280. ; ;
  281. ; Calls: ;
  282. ; ;
  283. ; History: ;
  284. ; ;
  285. ; Sat Jan 17, 1987 01:48:29a -by- David N. Weise [davidw] ;
  286. ; Added this nifty comment block. ;
  287. ;-----------------------------------------------------------------------;
  288. assumes ds, nothing
  289. assumes es, nothing
  290. cProc Set_Vector,<PUBLIC,NEAR>
  291. cBegin nogen
  292. push di
  293. push es
  294. call IsItIntercepted
  295. jnz notintercepted
  296. SetKernelDS es
  297. mov es, CurTDB ; We intercepted it, change
  298. UnSetKernelDS es ; vector in the TDB
  299. mov es:[di].off, dx
  300. mov es:[di].sel, ds
  301. jmps sv_done ; And just return
  302. notintercepted:
  303. SetKernelDS es
  304. cmp fBooting,1
  305. jz sv_no_restrictions
  306. cmp graphics,0 ; in the stand alone OS/2 box?
  307. jz @F
  308. ;ifdef JAPAN
  309. ifdef NOT_USE_BY_NT_JAPANESE
  310. push ax
  311. push bx ; 04/23/91 -yukini
  312. mov bx,0
  313. cCall [pJpnSysProc], <bx,ax> ; call System.JapanInquireSystem to
  314. ; get vector can be modified or not.
  315. test ax,ax
  316. pop bx
  317. pop ax
  318. jz sv_done ; jump if cannot be modified
  319. else
  320. cmp al,1Bh
  321. jz sv_done
  322. cmp al,1Ch
  323. jz sv_done
  324. endif
  325. @@: cmp al,21h ; trying to reset our traps?
  326. jz sv_done
  327. cmp al,24h ; trying to reset our traps?
  328. jz sv_done
  329. cmp al,2fh ; setting idle detect vector?
  330. jnz sv_no_restrictions ; no, proceed normally
  331. push ax
  332. push dx
  333. push ds
  334. cCall WOWSetIdleHook ; set the real hook back in Win32
  335. pop ds
  336. pop dx
  337. pop ax
  338. jmp bodacious_cowboys
  339. sv_no_restrictions:
  340. cmp al,21h
  341. jnz bodacious_cowboys
  342. mov lpint21.off,dx
  343. mov lpint21.sel,ds
  344. bodacious_cowboys:
  345. call real_DOS
  346. sv_done:
  347. pop es
  348. pop di
  349. pop ds
  350. pop bp ; clean up stack
  351. dec bp
  352. STIRET
  353. cEnd nogen
  354. assumes ds, nothing
  355. assumes es, nothing
  356. cProc Get_Vector,<PUBLIC,NEAR>
  357. cBegin nogen
  358. pop ds
  359. pop bp ; clean up stack
  360. dec bp
  361. push di
  362. call IsItIntercepted
  363. jnz notintercepted1
  364. push ds ; We intercepted it, get the
  365. SetKernelDS ; vector from the TDB
  366. mov ds, CurTDB
  367. UnSetKernelDS
  368. mov bx, [di]
  369. mov es, [di+2]
  370. pop ds
  371. pop di
  372. jmps gv_done
  373. notintercepted1:
  374. pop di
  375. call real_DOS
  376. gv_done:
  377. STIRET
  378. cEnd nogen
  379. cProc IsItIntercepted,<PUBLIC,NEAR>
  380. cBegin nogen
  381. mov di, TDB_INTVECS
  382. cmp al, 00h
  383. je yes_intercepted
  384. add di, 4
  385. cmp al, 02h
  386. je yes_intercepted
  387. add di, 4
  388. cmp al, 04h
  389. je yes_intercepted
  390. add di, 4
  391. cmp al, 06h
  392. je yes_intercepted
  393. add di, 4
  394. cmp al, 07h
  395. je yes_intercepted
  396. add di, 4
  397. cmp al, 3Eh
  398. je yes_intercepted
  399. add di, 4
  400. cmp al, 75h
  401. yes_intercepted:
  402. ret
  403. cEnd nogen
  404. ;-----------------------------------------------------------------------;
  405. ; ExecCall (DOS Call 4Bh) ;
  406. ; ;
  407. ; ;
  408. ; Arguments: ;
  409. ; ;
  410. ; Returns: ;
  411. ; ;
  412. ; Error Returns: ;
  413. ; ;
  414. ; Registers Preserved: ;
  415. ; ;
  416. ; Registers Destroyed: ;
  417. ; ;
  418. ; Calls: ;
  419. ; ;
  420. ; History: ;
  421. ; ;
  422. ; Mon 07-Aug-1989 23:39:59 -by- David N. Weise [davidw] ;
  423. ; Added support for long command lines to WinOldApp. ;
  424. ; ;
  425. ; Sat Jan 17, 1987 01:39:44a -by- David N. Weise [davidw] ;
  426. ; Added this nifty comment block. ;
  427. ;-----------------------------------------------------------------------;
  428. assumes ds, nothing
  429. assumes es, nothing
  430. cProc ExecCall,<PUBLIC,NEAR>
  431. cBegin nogen
  432. call PathDrvDSDX ; Check drive
  433. jnc EC1 ; Drive OK
  434. call SetErrorDrvDSDX ; Set up errors
  435. jmp SetCarryRet ; Error
  436. EC1: call SaveRegs
  437. call far ptr FarExecCall
  438. call RestoreRegs
  439. STIRET
  440. cEnd nogen
  441. ;-----------------------------------------------------------------------;
  442. ; TerminatePDB ;
  443. ; ;
  444. ; It calls DOS to terminate the current task. ;
  445. ; ;
  446. ; Arguments: ;
  447. ; DI = exit code ;
  448. ; Returns: ;
  449. ; nothing ;
  450. ; Error Returns: ;
  451. ; nothing ;
  452. ; Registers Preserved: ;
  453. ; none ;
  454. ; Registers Destroyed: ;
  455. ; ;
  456. ; Calls: ;
  457. ; ;
  458. ; History: ;
  459. ; ;
  460. ;-----------------------------------------------------------------------;
  461. assumes ds, nothing
  462. assumes es, nothing
  463. cProc TerminatePDB,<PUBLIC,NEAR>
  464. cBegin nogen
  465. SetKernelDS ES
  466. mov bx, ds ; DS is PDB being terminated
  467. cmp cur_dos_PDB, bx ; Ensure DOS/anyone on the
  468. je short @F ; int 21h chain has correct PDB
  469. mov ah, 50h
  470. pushf
  471. call prevInt21Proc
  472. @@:
  473. mov ax, ds:[PDB_Parent_PID] ; Parent PDB
  474. mov Win_PDB, ax ; These will be changed by DOS
  475. mov cur_dos_PDB, ax
  476. or Kernel_Flags[2],KF2_WIN_EXIT
  477. mov ax,di ; AL = exit code
  478. mov ah, 0 ; Alternative exit for PMODE which returns
  479. call real_DOS ; let DOS clean up
  480. UnSetKernelDS es
  481. errn$ DosExitReturn
  482. cEnd nogen
  483. ;
  484. ; The DOS terminate call above will return to
  485. ; the following label, DosExitReturn. This is
  486. ; a separate procedure in order to be declared FAR.
  487. ;
  488. assumes ds, nothing
  489. assumes es, nothing
  490. cProc DosExitReturn,<PUBLIC,FAR>
  491. cBegin nogen
  492. SetKernelDS ES
  493. mov Kernel_InDOS,0
  494. mov Kernel_InINT24,0
  495. and Kernel_Flags[2],NOT KF2_WIN_EXIT
  496. retn
  497. cEnd nogen
  498. ;-----------------------------------------------------------------------;
  499. ; ExitCall (DOS Call 4Ch) ;
  500. ; ;
  501. ; It terminates the current task. ;
  502. ; ;
  503. ; Arguments: ;
  504. ; AL = exit code ;
  505. ; Returns: ;
  506. ; nothing ;
  507. ; Error Returns: ;
  508. ; nothing ;
  509. ; Registers Preserved: ;
  510. ; none ;
  511. ; Registers Destroyed: ;
  512. ; none ;
  513. ; Calls: ;
  514. ; TerminatePDB ;
  515. ; GlobalFreeAll ;
  516. ; UnlinkObject ;
  517. ; DeleteTask ;
  518. ; GlobalFree ;
  519. ; FreeModule ;
  520. ; History: ;
  521. ; ;
  522. ; Mon 07-Aug-1989 23:39:59 -by- David N. Weise [davidw] ;
  523. ; Removed WinOldApp support. ;
  524. ; ;
  525. ; Sun Apr 26, 1987 03:20:05p -by- David N. Weise [davidw] ;
  526. ; Made it switch stacks to the temp_stack because of EMS. ;
  527. ; ;
  528. ; Mon Sep 29, 1986 04:06:08p -by- Charles Whitmer [chuckwh] ;
  529. ; Made it kill all threads in the current process. ;
  530. ; ;
  531. ; Mon Sep 29, 1986 03:27:12p -by- Charles Whitmer [chuckwh] ;
  532. ; Made it call UnlinkObject rather than do the work inline. ;
  533. ; ;
  534. ; Mon Sep 29, 1986 09:22:08a -by- Charles Whitmer [chuckwh] ;
  535. ; Documented it. ;
  536. ;-----------------------------------------------------------------------;
  537. assumes ds, nothing
  538. assumes es, nothing
  539. cProc ExitCall,<PUBLIC,NEAR>
  540. cBegin nogen
  541. ifdef WOW
  542. ; Set to a Known DIR so that if an app was running over the network
  543. ; the user can disconnect once the app terminates.
  544. ; This also allows a subdirectory to be removed after a Win16 app
  545. ; had that dir as the current dir, but was terminated.
  546. SetKernelDS
  547. push ax
  548. push si
  549. push dx
  550. push ds
  551. lds si,lpSystemDir ; ds:si points to system directory
  552. mov dl,[si] ; put drive letter into AL
  553. add dl,-65 ; subtract 'A' to get drive number
  554. mov ah,0Eh
  555. call real_DOS ; select disk
  556. add si,2 ; let SI point to the first '\' past d:
  557. mov al,[si + 1] ; save first character after '\'
  558. push ax
  559. mov byte ptr [si + 1],0 ; null-terminate string after root dir
  560. mov dx,si
  561. mov ah,3Bh
  562. call real_DOS ; select directory
  563. pop ax
  564. mov [si + 1],al ; restore string to its original state
  565. ;
  566. ; During task exit/abort ntdos $abort notifies the debugger of the
  567. ; "module unload" of the EXE using the full path to the EXE that
  568. ; follows the environment block. We don't want ntdos to make the
  569. ; module unload callout because we do it ourself during our
  570. ; DelModule of the EXE module. So we have a protocol, we zero
  571. ; the environment selector in our PDB, DPMI translates this to
  572. ; segment zero properly, and ntdos skips the callout if the environment
  573. ; segment is zero.
  574. ;
  575. pop ds
  576. ReSetKernelDS
  577. mov es,[curTDB] ; DS = current TDB
  578. mov es, es:[TDB_PDB]
  579. xor ax,ax
  580. mov word ptr es:[PDB_environ], ax
  581. pop dx
  582. pop si
  583. pop ax
  584. endif
  585. if SDEBUG
  586. ;** Save the TDB of the currently exiting task. We check for this
  587. ;** in DebugWrite so that we don't get recursive
  588. ;** debug strings at task exit time. This is a gross hack
  589. ;** for QCWin and their numerous param validation errors.
  590. mov bx,curTDB ;Get current task handle
  591. mov wExitingTDB,bx ;Save as exiting TDB
  592. cCall DebugExitCall ;Passes exit code in AL
  593. endif ; SDEBUG
  594. if PMODE32
  595. .386
  596. smov fs, 0
  597. smov gs, 0
  598. .286p
  599. xchg di,ax ; DI = exit code
  600. cmp graphics,1 ; is there a display driver around?
  601. jnz @F
  602. mov ax,1
  603. ifndef WOW ; WOW doesn't have a display dirver to call
  604. cCall pDisplayCritSec,<ax> ; tell display driver to shut up
  605. endif
  606. or Kernel_Flags[2],KF2_WIN386CRAZINESS
  607. @@: mov ds,curTDB ; DS = current TDB
  608. assumes ds,nothing
  609. else
  610. xchg di,ax ; DI = exit code
  611. mov ds,curTDB ; DS = current TDB
  612. UnSetKernelDS
  613. endif
  614. ; We may have gotten here due to stack checking. Let's make sure
  615. ; that we are on a stack we can deal with.
  616. test ds:[TDB_flags],TDBF_OS2APP
  617. jz @F
  618. mov ax,sp
  619. mov ss:[pStackBot],ax
  620. @@: xor ax,ax
  621. mov ss:[pStackTop],ax
  622. ; remove the PDB from the chain
  623. mov es,ds:[TDB_PDB]
  624. mov dx,PDB_Chain
  625. mov bx,dataOffset HeadPDB
  626. call UnlinkObject
  627. xor si,si ; source of zero
  628. ; Dec total # of tasks, if last task in system, then quit Windows completely.
  629. smov es,ds
  630. assumes es,nothing
  631. SetKernelDS
  632. ifdef WOW
  633. cmp fExitOnLastApp,0 ; Quit WOW when the last app dies ?
  634. jz @f
  635. cmp num_tasks,2 ; Last Task (ingnoring WOWEXEC) ?
  636. jz last_task
  637. @@:
  638. endif
  639. dec num_tasks
  640. jnz not_the_last_task
  641. last_task:
  642. IF PMODE32
  643. ;** Unhook local reboot VxD stuff
  644. cmp WORD PTR lpReboot[2], 0 ;Reboot handler installed?
  645. je @F ;No
  646. push es
  647. mov ax, 0201h ;Reboot VxD #201: Set callback addr
  648. xor di, di ;Zero CS means no SYS VM local
  649. mov es, di
  650. call [lpReboot] ; reboot handler
  651. pop es
  652. @@:
  653. ENDIF
  654. call BUNNY_351
  655. ifndef WOW ; For WOW ex just want to get out of here - no need to call USER16 or GDI16
  656. cCall pExitProc,<si,si> ; this does not return
  657. endif
  658. cCall ExitKernelThunk,<si>
  659. assumes es, nothing
  660. not_the_last_task:
  661. ; Signal( hTask, SG_EXIT, ExitCode, 0, Queue ) if we have a user signal proc
  662. push es
  663. cmp es:[si].TDB_USignalProc.sel,si
  664. jz no_signal_proc
  665. mov bx,SG_EXIT
  666. cCall es:[si].TDB_USignalProc,<es,bx,di,es:[si].TDB_Module,es:[si].TDB_Queue>
  667. no_signal_proc:
  668. pop es
  669. mov bl,6
  670. DPMICALL 0202h ; DPMI get exception handler vector
  671. push cx
  672. push dx
  673. mov cx,cs
  674. lea dx,exit_call_guts
  675. mov bl,6
  676. DPMICALL 0203h ; DPMI set exception handler vector
  677. pop dx
  678. pop cx
  679. ;
  680. ; Generate an invalid opcode exception fault. This causes DPMI to call
  681. ; our "exception handler."
  682. ;
  683. db 0fh,0ffh
  684. exit_call_guts:
  685. FSTI ; we're called with ints disabled
  686. mov bp,sp ; BP -> RETIP RETCS EC IP CS FL SP SS
  687. ;
  688. ; Restore the previous invalid exception handler vector.
  689. ;
  690. mov bl,6
  691. DPMICALL 0203h
  692. ;
  693. ; Point the return stack at Kernel's temporary stack.
  694. ;
  695. mov ax,dataOffset gmove_stack
  696. mov [bp+12],ax
  697. mov ax,seg gmove_stack
  698. mov [bp+14],ax
  699. ;
  700. ; Replace the return address on the DPMI fault handler routine with
  701. ; our exit code.
  702. ;
  703. lea ax,ExitSchedule
  704. mov [bp+6],ax
  705. mov [bp+8],cs
  706. push es
  707. cCall GlobalFreeAll,<si> ; free up all task data
  708. pop es
  709. ; Remove from queue.
  710. push es
  711. cCall DeleteTask,<es>
  712. pop es
  713. mov ds,es:[TDB_PDB] ; DS = current PDB
  714. UnsetKernelDS ; DS is PDB to terminate
  715. call TerminatePDB ; Call DOS to close down files etc.
  716. ReSetKernelDS ES ; TerminatePDB returned with ES set
  717. xor bp,bp ; set up valid frame
  718. mov ds,curTDB
  719. ; If this task has a PHT, decrement the PHT count and clear the pointer
  720. ; and zap the PHT pointer so we don't look at it anymore.
  721. ; NOTE - BP contains a convenient zero.
  722. mov ax,ds:[TDB_PHT].sel
  723. or ax,ds:[TDB_PHT].off
  724. jz no_PHT
  725. mov ds:[TDB_PHT].sel,bp
  726. mov ds:[TDB_PHT].off,bp
  727. dec PHTcount ; dec # tasks with PHT's
  728. no_PHT:
  729. UnSetKernelDS es
  730. cCall FreeModule,<ds:[TDB_Module]> ; Free the module for this task
  731. xor ax,ax
  732. mov ds:[TDB_sig],ax ; Mark TDB as invalid
  733. ;** Nuke any JFN that is outside the PDB. We can tell that the
  734. ;** JFN points outside the PDB if the offset is zero. PDB
  735. ;** JFN's never have a zero offset and outside ones always do.
  736. push ds
  737. mov ds, ds:[TDB_PDB]
  738. cmp WORD PTR ds:[PDB_JFN_Pointer][0], 0 ;JFN pointer into PDB?
  739. jne EC_NoFreeJFN ;Yes, don't free anything
  740. push WORD PTR ds:[PDB_JFN_Table] ;Get our selector
  741. call GlobalDOSFree
  742. EC_NoFreeJFN:
  743. SetKernelDS
  744. cmp num_tasks,1 ; Last task? (except wowexec)
  745. jne @f ; branch if not last task
  746. if 0
  747. ; This code is unneeded because if we're a separate VDM, we exit above when
  748. ; the last task exited.
  749. cmp fExitOnLastApp, 0 ; Shared WOW?
  750. jne @F ; branch if not shared WOW
  751. endif
  752. cCall WowShutdownTimer, <1> ; start shutdown timer
  753. mov fShutdownTimerStarted, 1
  754. cCall GlobalCompact,<-1, -1> ; free up as many pages as possible
  755. cCall WowTrimWorkingSet ; trim working set to minimum
  756. @@:
  757. mov bx, topPDB
  758. mov Win_PDB, bx
  759. mov cur_dos_PDB, bx
  760. mov ah, 50h
  761. pushf
  762. call prevInt21Proc ; Set PDB to KERNEL's
  763. pop ds
  764. UnSetKernelDS
  765. xchg bx, ds:[TDB_PDB]
  766. cCall free_sel,<bx> ; Free the PDB selector
  767. call far ptr FreeTDB ; Tosses PDB's memory
  768. SetKernelDS
  769. ifndef WOW
  770. mov curTDB,0 ; We can use this, setting curTDB = 0
  771. else
  772. ;; We do this a little later - see tasking.asm exitschedule
  773. endif
  774. if PMODE32 ; in rmode as well in the next rev
  775. or PagingFlags, 8 ; to save a few bytes.
  776. endif
  777. ;** Task has been nuked. Clear the DebugWrite task exiting flag
  778. mov wExitingTDB,0
  779. ; fix current drive owner
  780. mov ax, cur_drive_owner
  781. cmp ax, curTDB
  782. jnz @f
  783. ; so it is the owner of a current drive -- nuke it
  784. mov cur_drive_owner, 0
  785. @@:
  786. if 0 ; We could call this on every task exit -- need to see if
  787. ; it slows down Winstone 94, if it's needed after we use MEM_RESET
  788. ; If you enable this call, disable the similar call just above.
  789. cCall WowTrimWorkingSet ; trim working set to minimum
  790. endif
  791. retf ; To ExitSchedule
  792. cEnd nogen
  793. assumes ds, nothing
  794. assumes es, nothing
  795. cProc FreeTDB, <PUBLIC,FAR>
  796. cBegin nogen
  797. cCall FreeSelector,<ds:[TDB_MPI_Sel]>
  798. mov ax,ds
  799. if KDEBUG
  800. ;
  801. ; If we're freeing the alloc break task, zero out the global.
  802. ;
  803. SetKernelDS
  804. cmp ax,allocTask
  805. jnz @F
  806. mov allocTask,0
  807. @@:
  808. UnSetKernelDS
  809. endif
  810. smov ds,0
  811. cCall GlobalDOSFree,<ax>
  812. ret
  813. cEnd nogen
  814. ;-----------------------------------------------------------------------;
  815. ; set_PDB (DOS Call 50h) ;
  816. ; ;
  817. ; This is an undocumented DOS call to set the current PDB. ;
  818. ; DOS does not check for ^C's on this call, in fact it never turns ;
  819. ; on the interrupts. ;
  820. ; ;
  821. ; Arguments: ;
  822. ; ;
  823. ; Returns: ;
  824. ; ;
  825. ; Error Returns: ;
  826. ; ;
  827. ; Registers Preserved: ;
  828. ; ;
  829. ; Registers Destroyed: ;
  830. ; ;
  831. ; Calls: ;
  832. ; ;
  833. ; History: ;
  834. ; ;
  835. ; Fri Jan 23, 1987 07:07:14p -by- David N. Weise [davidw] ;
  836. ; Wrote it. ;
  837. ;-----------------------------------------------------------------------;
  838. assumes ds, nothing
  839. assumes es, nothing
  840. cProc set_PDB,<PUBLIC,NEAR>
  841. cBegin nogen
  842. SetKernelDS
  843. mov cur_dos_PDB,bx
  844. mov Win_PDB,bx
  845. mov ds,curTDB
  846. assumes ds,nothing
  847. mov ds:[TDB_PDB],bx
  848. call real_DOS
  849. pop ds
  850. pop bp ; clean up stack
  851. dec bp
  852. STIRET
  853. cEnd nogen
  854. ;-----------------------------------------------------------------------;
  855. ; get_PDB ;
  856. ; ;
  857. ; This is an undocumented DOS call to set the current PDB. ;
  858. ; DOS does not check for ^C's on this call, in fact it never turns ;
  859. ; on the interrupts. ;
  860. ; Trapping this is superfluous is real mode but necessary in protect ;
  861. ; mode since the DOS extender may not be doing the segment ;
  862. ; translation properly. ;
  863. ; ;
  864. ; Entry: ;
  865. ; ;
  866. ; Returns: ;
  867. ; ;
  868. ; Registers Destroyed: ;
  869. ; ;
  870. ; History: ;
  871. ; Tue 13-Jun-1989 18:22:16 -by- David N. Weise [davidw] ;
  872. ; Wrote it. ;
  873. ;-----------------------------------------------------------------------;
  874. assumes ds,nothing
  875. assumes es,nothing
  876. cProc get_PDB,<PUBLIC,NEAR>
  877. cBegin nogen
  878. SetKernelDS
  879. call real_DOS
  880. mov bx,cur_dos_PDB
  881. pop ds
  882. pop bp ; clean up stack
  883. dec bp
  884. STIRET
  885. cEnd nogen
  886. sEnd code
  887. sBegin NRESCODE
  888. assumes cs, NRESCODE
  889. assumes ds, nothing
  890. assumes es, nothing
  891. externNP MapDStoDATA
  892. ;-----------------------------------------------------------------------;
  893. ; BuildPDB ;
  894. ; ;
  895. ; ;
  896. ; Arguments: ;
  897. ; ;
  898. ; Returns: ;
  899. ; ;
  900. ; Error Returns: ;
  901. ; ;
  902. ; Registers Preserved: ;
  903. ; ;
  904. ; Registers Destroyed: ;
  905. ; ;
  906. ; Calls: ;
  907. ; ;
  908. ; History: ;
  909. ; ;
  910. ; Thu 04-Jan-1990 20:15:27 -by- David N. Weise [davidw] ;
  911. ; Made it avoid closing cached files if the PDB being copied is not ;
  912. ; the topPDB. This is for supporting inheriting a parents files. ;
  913. ; ;
  914. ; Mon 11-Sep-1989 19:13:52 -by- David N. Weise [davidw] ;
  915. ; Removed returning validity in AX, and removed copying of FCBs. ;
  916. ; ;
  917. ; Mon 07-Aug-1989 23:39:59 -by- David N. Weise [davidw] ;
  918. ; Added support for long command lines to WinOldApp. ;
  919. ; ;
  920. ; Sun Jan 18, 1987 00:27:52a -by- David N. Weise [davidw] ;
  921. ; Added this nifty comment block. ;
  922. ;-----------------------------------------------------------------------;
  923. assumes ds, nothing
  924. assumes es, nothing
  925. cProc BuildPDB,<PUBLIC,FAR>,<si,di>
  926. ParmW oldPDB
  927. ParmW newPDB
  928. ParmD ParmBlock
  929. ParmW newSize
  930. ParmW fWOA
  931. cBegin
  932. call MapDStoDATA
  933. ReSetKernelDS
  934. push Win_PDB ; Save current PDB
  935. mov bx,oldPDB ; set current PDB for copy
  936. mov Win_PDB, bx
  937. mov dx,newPDB
  938. mov si,newSize
  939. mov ah,55h ; duplicate PDB
  940. int 21h
  941. mov bx, oldPDB
  942. mov dx, newPDB
  943. mov cur_dos_PDB, dx ; DOS call 55h sets the PDB to this
  944. nothing_to_close:
  945. pop Win_PDB ; restore former PDB
  946. xor di,di
  947. mov cx, MyCSSeg
  948. mov ds,dx
  949. UnSetKernelDS
  950. mov es,dx
  951. add si,dx
  952. mov ax,oldPDB
  953. mov [di].PDB_Parent_PID,ax ; parent = OldPDB
  954. mov [di].PDB_Block_Len,si
  955. mov [di].PDB_Exit.off,codeOffset DosExitReturn
  956. mov [di].PDB_Exit.sel, cx
  957. ; No private global heap yet.
  958. mov [di].PDB_GlobalHeap.lo,di
  959. mov [di].PDB_GlobalHeap.hi,di
  960. ; Set up proper command line stuff.
  961. lds si,ParmBlock
  962. lds si,ds:[si].lpcmdline ; command line
  963. mov di,PDB_DEF_DTA
  964. mov cx,di
  965. cmp fWOA,0
  966. jz @F ; Winoldap can have long command line
  967. mov cx,ds:[si] ; get byte count
  968. cld
  969. movsb ; copy count byte
  970. inc cx
  971. inc si
  972. @@: rep movsb ; Store command line.
  973. cEnd
  974. cProc FarExecCall,<PUBLIC,FAR>
  975. cBegin nogen
  976. ; Check if file extension is .COM, .BAT, .PIF, if so it needs emulation...
  977. cld
  978. les di,User_DSDX
  979. ifdef WOW
  980. ;
  981. ; Wow LoadModule handles all forms of exec including
  982. ; pe images, com, bat, pif files etc.
  983. ;
  984. lds si,User_ESBX
  985. regptr esdx,es,dx
  986. regptr dssi,ds,si
  987. cCall LoadModule,<esdx,dssi>
  988. cmp ax, LME_MAXERR ; check for error...
  989. jae ex8
  990. jmp short ex7 ; no, return error
  991. else
  992. mov cx,-1
  993. xor al,al
  994. repnz scasb ; scan to end of string
  995. neg cx
  996. dec cx ; cx has length (including null)
  997. mov ax,es:[di-5]
  998. or ah,20h
  999. mov bx,es:[di-3] ; complete check for .COM
  1000. or bx,2020h ; convert to lower case
  1001. cmp ax,'c.' ; check for .COM file extension
  1002. jnz ex1b ; no match...attempt load module
  1003. cmp bx,'mo'
  1004. jz ex4 ; yes! go immediatly to GO
  1005. ex1b: cmp ax,'b.' ; check for .BAT extension...
  1006. jnz ex1c
  1007. cmp bx,'ta'
  1008. jz ex4
  1009. ex1c: cmp ax,'p.' ; check for .PIF extension...
  1010. jnz ex2
  1011. cmp bx,'fi'
  1012. jz ex4
  1013. ex2: lds si,User_ESBX
  1014. regptr esdx,es,dx
  1015. regptr dssi,ds,si
  1016. push cx ; save length of string
  1017. cCall LoadModule,<esdx,dssi>
  1018. pop cx
  1019. cmp ax, LME_MAXERR ; check for error...
  1020. jb ex3
  1021. jmp ex8
  1022. ex3: cmp ax, LME_INVEXE ; wrong format?
  1023. jz ex4
  1024. cmp ax, LME_EXETYPE ; quick basic app
  1025. jz ex4
  1026. cmp ax, LME_PE ; Win32 PE format
  1027. jz @F
  1028. jmp ex7 ; no, return error
  1029. @@:
  1030. ifdef WIN32S
  1031. push cx
  1032. ; Win32S support - (AviN) 11-19-91
  1033. lds si,User_DSDX
  1034. push ds
  1035. push si
  1036. lds si,User_ESBX
  1037. push ds:[si+4] ; CmdLine sel
  1038. push ds:[si+2] ; offset
  1039. les bx, ds:[si+6] ; FCB1
  1040. push es:[bx+2] ; nCmdShow
  1041. call FAR PTR ExecPE
  1042. pop cx
  1043. cmp ax, 32
  1044. jbe @F
  1045. jmp ex8
  1046. @@:
  1047. cmp ax, 11 ; NOT PE
  1048. je @F
  1049. jmp ex7
  1050. @@:
  1051. ; end of Win32S support
  1052. endif
  1053. ex4:
  1054. ; Run an old application
  1055. ;
  1056. ; If we are running in the OS/2 3x box, we do not support running old
  1057. ; apps. If someone trys this, put up a nasty message and return with
  1058. ; an error. (Thu 12-Nov-1987 : bobgu)
  1059. mov dx,cx ; save length of file name
  1060. sub sp,256 ; make room for command line
  1061. smov es,ss
  1062. mov di,sp
  1063. lds si,User_ESBX
  1064. lds si,ds:[si].lpcmdline
  1065. xor ax,ax
  1066. xor cx,cx
  1067. mov cl,ds:[si]
  1068. inc cx
  1069. movsb
  1070. stosb
  1071. rep movsb
  1072. mov cx,dx
  1073. lds si,User_DSDX
  1074. rep movsb
  1075. mov byte ptr es:[di][-1],10 ; terminate with line feed
  1076. mov di,sp
  1077. add es:[di],dx
  1078. mov bx,es
  1079. push ds
  1080. call MapDStoDATA
  1081. smov es, ds
  1082. pop ds
  1083. ReSetKernelDS es
  1084. test Kernel_flags[2],KF2_DOSX ; DOSX winoldap doesn't need special
  1085. jnz @F ; special handling
  1086. mov ax,dataOffset grab_name
  1087. push bx
  1088. push dx
  1089. push es
  1090. cCall LoadLibrary,<es,ax>
  1091. pop es
  1092. pop dx
  1093. pop bx
  1094. cmp ax,32
  1095. jae @F
  1096. add sp, 256 ; undo damage to stack
  1097. jmps ex7
  1098. @@:
  1099. or Kernel_flags[1],KF1_WINOLDAP
  1100. lds si,User_ESBX
  1101. mov ds:[si].lpcmdline.off,di
  1102. mov ds:[si].lpcmdline.sel,bx
  1103. mov dx,dataOffset WOAName
  1104. regptr esdx,es,dx
  1105. regptr dssi,ds,si
  1106. cCall LoadModule,<esdx,dssi>
  1107. assumes es, nothing
  1108. add sp,256
  1109. cmp ax,32 ; check for error...
  1110. jae ex8
  1111. cmp ax,2 ; file not found?
  1112. jnz ex7 ; no, return error
  1113. mov al,23 ; flag WINOLDAP error
  1114. ;; ndef wow
  1115. endif
  1116. ex7: or User_FL,1 ; set carry flag
  1117. or ax,ax ; out of memory?
  1118. jnz ex8
  1119. mov ax,8h ; yes, return proper error code
  1120. ex8: mov User_AX,ax ; return AX value
  1121. ret
  1122. cEnd nogen
  1123. ifdef WIN32S
  1124. SZW32SYS db "W32SYS.DLL", 0
  1125. ExecPEOrd equ 3
  1126. ;-----------------------------------------------------------------------;
  1127. ; ExecPE
  1128. ; Get ExecPE address in W32SYS.DLL, and call it
  1129. ; 11-13-91 AviN created
  1130. ;-----------------------------------------------------------------------;
  1131. cProc ExecPE,<PUBLIC,FAR>
  1132. cBegin nogen
  1133. push ds
  1134. mov ax, SEG selExecPE
  1135. mov ds, ax
  1136. assumes DS, DATA
  1137. mov dx, selExecPE ; check for a valid address
  1138. or dx, dx
  1139. jnz ep_x
  1140. mov ax, offExecPE
  1141. or ax, ax
  1142. jnz ep_err ; already failed, don't try again
  1143. cCall ISetErrorMode, <8000h>
  1144. push ax
  1145. lea ax, SZW32SYS
  1146. cCall LoadLibrary,<cs, ax>
  1147. pop dx
  1148. push ax
  1149. cCall ISetErrorMode,<dx> ; restore original error mode
  1150. pop ax
  1151. cmp ax, 32
  1152. jbe ep_err
  1153. push ax
  1154. push 0
  1155. push ExecPEOrd
  1156. cCall GetProcAddress
  1157. or dx,dx
  1158. jz ep_err
  1159. mov selExecPE, dx
  1160. mov offExecPE, ax
  1161. ep_x:
  1162. pop ax ; saved DS
  1163. push selExecPE ; jmp to ExecPE
  1164. push offExecPE
  1165. mov ds, ax
  1166. retf
  1167. ep_err:
  1168. ; if w32sys support no available return
  1169. mov ax, 11 ; invalid module format
  1170. mov offExecPE, ax ; and record for next time
  1171. pop ds
  1172. retf 10 ; pop ExecPE parameters
  1173. assumes DS,NOTHING
  1174. cEnd nogen
  1175. endif
  1176. sEnd NRESCODE
  1177. sBegin MISCCODE
  1178. assumes cs, misccode
  1179. assumes ds, nothing
  1180. assumes es, nothing
  1181. externNP MISCMapDStoDATA
  1182. ;-----------------------------------------------------------------------;
  1183. ; ;
  1184. ; Get the Current PDB without doing a DOS call. ;
  1185. ; ;
  1186. ;-----------------------------------------------------------------------;
  1187. cProc GetCurrentPDB,<PUBLIC,FAR>
  1188. cBegin nogen
  1189. push ds
  1190. call MISCMapDStoDATA
  1191. ReSetKernelDS
  1192. mov dx,TopPDB
  1193. mov ds,curTDB
  1194. UnSetKernelDS
  1195. mov ax,ds:[TDB_PDB]
  1196. pop ds
  1197. ret
  1198. cEnd nogen
  1199. sEnd MISCCODE
  1200. end
  1201.