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.

679 lines
20 KiB

  1. .xlist
  2. include kernel.inc
  3. include pdb.inc
  4. include tdb.inc
  5. include newexe.inc
  6. include eems.inc
  7. ifdef WOW
  8. include vint.inc
  9. endif
  10. .list
  11. externFP KillLibraries
  12. ifndef WOW
  13. externFP WriteOutProfiles
  14. endif
  15. DataBegin
  16. externB PhantArray
  17. externB kernel_flags
  18. externB fBreak
  19. externB fInt21
  20. ifndef WOW
  21. externB fProfileMaybeStale
  22. endif
  23. externW curTDB
  24. externW headPDB
  25. externW topPDB
  26. ife PMODE32
  27. externW hXMMHeap
  28. endif
  29. externD lpInt21
  30. externD pSftLink
  31. externD lpWinSftLink
  32. externD pSysProc
  33. externD pMouseTermProc
  34. externD pKeyboardTermProc
  35. externD pSystemTermProc
  36. externW MyCSAlias
  37. externD myInt2F
  38. if ROM
  39. externD prevInt00Proc
  40. externD prevInt21Proc
  41. externD prevInt24Proc
  42. externD prevInt2FProc
  43. externD prevInt3FProc
  44. externD prevInt67Proc
  45. externD prevInt02Proc
  46. externD prevInt04Proc
  47. externD prevInt06Proc
  48. externD prevInt07Proc
  49. externD prevInt3EProc
  50. externD prevInt75Proc
  51. externD prevInt0CProc
  52. externD prevInt0DProc
  53. externD prevIntx6Proc
  54. externD prevInt0EProc
  55. endif
  56. DataEnd
  57. sBegin CODE
  58. assumes CS,CODE
  59. assumes ds, nothing
  60. assumes es, nothing
  61. ife ROM
  62. externD prevInt00Proc
  63. externD prevInt21Proc
  64. externD prevInt24Proc
  65. externD prevInt2FProc
  66. externD prevInt3FProc
  67. externD prevInt67Proc
  68. externD prevInt02Proc
  69. externD prevInt04Proc
  70. externD prevInt06Proc
  71. externD prevInt07Proc
  72. externD prevInt3EProc
  73. externD prevInt75Proc
  74. externD prevInt0CProc
  75. externD prevInt0DProc
  76. externD prevIntx6Proc
  77. externD prevInt0EProc
  78. ifdef WOW
  79. externD prevInt01proc
  80. externD prevInt03proc
  81. externD oldInt00proc
  82. endif
  83. endif
  84. if ROM
  85. externFP PrevROMInt21Proc
  86. endif
  87. externNP real_DOS
  88. externNP Enter_gmove_stack
  89. externNP TerminatePDB
  90. ;-----------------------------------------------------------------------;
  91. ; InternalEnableDOS
  92. ;
  93. ;
  94. ; Entry:
  95. ; none
  96. ; Returns:
  97. ;
  98. ; Registers Destroyed:
  99. ;
  100. ; History:
  101. ; Thu 21-Sep-1989 20:44:48 -by- David N. Weise [davidw]
  102. ; Added this nifty comment block.
  103. ;-----------------------------------------------------------------------;
  104. SetWinVec MACRO vec
  105. externFP Int&vec&Handler
  106. mov dx, codeoffset Int&vec&Handler
  107. mov ax, 25&vec&h
  108. pushf
  109. if ROM
  110. call PrevROMInt21Proc
  111. else
  112. call prevInt21Proc
  113. endif
  114. endm
  115. assumes ds, nothing
  116. assumes es, nothing
  117. cProc InternalEnableDOS,<PUBLIC,FAR>
  118. cBegin nogen
  119. push si
  120. push ds
  121. SetKernelDS
  122. mov al,1
  123. xchg al,fInt21 ; set hook count to 1
  124. or al,al ; was it zero?
  125. jz @f
  126. jmp ena21 ; no, just leave
  127. @@:
  128. ; now link back nodes to SFT if kernel had done it before. InternalDisableDOS
  129. ; saves the link in the DWORD variable lpWinSftLink. If this variable is NULL
  130. ; then either this is the first time InternalEnableDOS is being called or
  131. ; else the SFT had not been grown.
  132. cmp lpWinSftLink.sel,0 ;was it allocated ?
  133. jz @f ;no.
  134. push ds ;save
  135. mov cx,lpWinSftLink.sel ;get the selector
  136. mov dx,lpWinSftLink.off ;get the offset
  137. lds bx,[pSftLink] ;place where we hooked new entry
  138. mov word ptr ds:[bx][0],dx ;restore offset
  139. mov word ptr ds:[bx][2],cx ;restore segment
  140. pop ds ;restore data segment
  141. @@:
  142. ; WARNING!! The ^C setting diddle MUST BE FIRST IN HERE......
  143. ; If you do some other INT 21 call before this you will have
  144. ; a "^C window", so don't do it....
  145. mov ax,3301h ; disable ^C checking
  146. mov dl,0
  147. call real_DOS
  148. mov bx,TopPDB
  149. mov ah,50h
  150. call real_DOS ; This way, or TDB_PDB gets set wrong
  151. ifndef WOW
  152. ends1: mov ah,6 ; clean out any pending keys
  153. mov dl,0FFh
  154. call real_DOS
  155. jnz ends1
  156. endif
  157. mov es,curTDB
  158. mov bx,es:[TDB_PDB]
  159. mov ah,50h
  160. int 21h
  161. push ds
  162. lds dx,myInt2F
  163. mov ax,252Fh
  164. int 21h
  165. smov ds,cs ; Pick up executable sel/seg
  166. UnSetKernelDS
  167. SetWinVec 24
  168. SetWinVec 00
  169. SetWinVec 02
  170. SetWinVec 04
  171. SetWinVec 06
  172. SetWinVec 07
  173. SetWinVec 3E
  174. SetWinVec 75
  175. pop ds
  176. ReSetKernelDS
  177. mov bx,2 ; 2 = Enable/Disable one drive logic
  178. xor ax,ax ; FALSE = Disable
  179. cCall [pSysProc],<bx,ax> ; NOTE: destroys ES if DOS < 3.20
  180. ; Set up the PhantArray by calling inquire system for each drive letter
  181. mov bx,dataOffset PhantArray + 25 ; Array index
  182. mov cx,26 ; Drive #
  183. SetPhant:
  184. dec cx
  185. push cx
  186. push bx
  187. mov dx,1 ; InquireSystem
  188. cCall [pSysProc],<dx,cx>
  189. pop bx
  190. pop cx
  191. mov byte ptr [bx],0 ; Assume not Phantom
  192. cmp ax,2
  193. jae NotPhant ; Assumption correct
  194. ; or dx,dx ; Drive just invalid?
  195. ; jz NotPhant ; Yes, assumption correct
  196. mov byte ptr [bx],dl ; Drive is phantom
  197. NotPhant:
  198. dec bx ; Next array element
  199. jcxz phant_done
  200. jmp SetPhant
  201. phant_done:
  202. lds dx,lpInt21
  203. UnSetKernelDS
  204. mov ax,2521h
  205. int 21h
  206. ena21:
  207. pop ds
  208. pop si
  209. ret
  210. cEnd nogen
  211. ;-----------------------------------------------------------------------;
  212. ; InternalDisableDOS ;
  213. ; ;
  214. ; ;
  215. ; Arguments: ;
  216. ; ;
  217. ; Returns: ;
  218. ; ;
  219. ; Error Returns: ;
  220. ; ;
  221. ; Registers Preserved: ;
  222. ; ;
  223. ; Registers Destroyed: ;
  224. ; ;
  225. ; Calls: ;
  226. ; ;
  227. ; History: ;
  228. ; ;
  229. ; Mon Oct 16, 1989 11:04:50 -by- Amit Chatterjee [amitc] ;
  230. ; InternalDisableDOS now takes away any nodes that kernel would have ;
  231. ; added to the SFT. InternalEnableDOS puts the nodes backs. Previously ;
  232. ; the delinking was done by DisableKernel, but no one linked it back! ;
  233. ; ;
  234. ; Sat May 09, 1987 02:00:52p -by- David N. Weise [davidw] ;
  235. ; Added this nifty comment block. ;
  236. ; ;
  237. ; Thu Apr 16, 1987 11:32:00p -by- Raymond E. Ozzie [-iris-] ;
  238. ; Changed InternalDisableDOS to use real dos for 52h function, since ;
  239. ; DosTrap3 doesn't have 52h defined and PassOnThrough will croak if the ;
  240. ; current TDB's signature is 0, as it is during exit after the last ;
  241. ; task has been deleted. ;
  242. ;-----------------------------------------------------------------------;
  243. ReSetDOSVec MACRO vec
  244. lds dx,PrevInt&vec&proc
  245. mov ax,25&vec&h
  246. int 21h
  247. endm
  248. assumes ds, nothing
  249. assumes es, nothing
  250. cProc InternalDisableDOS,<PUBLIC,FAR>
  251. cBegin
  252. SetKernelDS es
  253. xor ax,ax
  254. xchg al,fInt21 ; set hook count to zero
  255. or al,al ; was it non zero?
  256. jnz @F
  257. jmp dis21 ; no, just leave
  258. @@:
  259. mov bx,2 ; 2 = Enable/Disable one drive logic
  260. mov ax,1 ; TRUE = Enable
  261. push es
  262. cCall pSysProc,<bx,ax>
  263. pop es
  264. mov ax,3301h ; disable ^C checking
  265. mov dl,0
  266. pushf
  267. ife PMODE32
  268. FCLI
  269. endif
  270. call [prevInt21Proc]
  271. mov ax,2521h
  272. lds dx,prevInt21Proc
  273. pushf
  274. ife PMODE32
  275. FCLI
  276. endif
  277. call [prevInt21Proc]
  278. push es
  279. mov ax,352Fh
  280. int 21h
  281. mov ax,es
  282. pop es
  283. mov myInt2F.sel,ax
  284. mov myInt2F.off,bx
  285. ReSetDOSVec 00 ; as a favor in win2 we restored this
  286. ReSetDOSVec 24
  287. ReSetDOSVec 2F
  288. ReSetDOSVec 02
  289. ReSetDOSVec 04
  290. ReSetDOSVec 06
  291. ReSetDOSVec 07
  292. ReSetDOSVec 3E
  293. ReSetDOSVec 75
  294. mov dl,fBreak ; return state of ^C checking
  295. mov ax,3301h
  296. int 21h
  297. dis21:
  298. cEnd
  299. ;------------------------------------------------------------------
  300. ;
  301. ; Ancient WinOldAp hook.
  302. ;
  303. ;------------------------------------------------------------------
  304. public EnableDOS
  305. EnableDOS Label Byte
  306. if kdebug
  307. krDebugOut DEB_WARN, "Don't call EnableDOS"
  308. endif
  309. retf
  310. ;------------------------------------------------------------------
  311. ;
  312. ; Ancient WinOldAp hook.
  313. ;
  314. ;------------------------------------------------------------------
  315. public DisableDOS
  316. DisableDOS Label Byte
  317. if kdebug
  318. krDebugOut DEB_WARN, "Don't call DisableDOS"
  319. endif
  320. retf
  321. ;------------------------------------------------------------------
  322. ;
  323. ; Ancient WinOldAp hook.
  324. ;
  325. ;------------------------------------------------------------------
  326. public EnableKernel
  327. EnableKernel Label Byte
  328. if kdebug
  329. krDebugOut DEB_WARN, "Don't call EnableKernel"
  330. endif
  331. retf
  332. ;-----------------------------------------------------------------------;
  333. ; DisableKernel ;
  334. ; ;
  335. ; This call is provided as a Kernel service to applications that ;
  336. ; wish to totally unhook Windows in order to do something radical ;
  337. ; such as save the state of the world and restore it at a later ;
  338. ; time. This is similar in many ways to the way OLDAPP support ;
  339. ; works, with the addition that it also unhooks the kernel. ;
  340. ; ;
  341. ; Arguments: ;
  342. ; ;
  343. ; Returns: ;
  344. ; ;
  345. ; Error Returns: ;
  346. ; ;
  347. ; Registers Preserved: ;
  348. ; DI,SI,DS ;
  349. ; ;
  350. ; Registers Destroyed: ;
  351. ; ;
  352. ; Calls: ;
  353. ; ;
  354. ; History: ;
  355. ; ;
  356. ; Sat May 09, 1987 02:34:35p -by- David N. Weise [davidw] ;
  357. ; Merged changes in. Most of this came from ExitKernel. ;
  358. ; ;
  359. ; Tue Apr 28, 1987 11:12:00a -by- R.E.O. SpeedWagon [-????-] ;
  360. ; Changed to indirect thru PDB to get JFN under DOS 3.x. ;
  361. ; ;
  362. ; Mon Apr 20, 1987 11:34:00p -by- R.E.O. SpeedWagon [-????-] ;
  363. ; Set PDB to topPDB before final int 21/4C; we were sometimes exiting ;
  364. ; with a task's PDB, and thus we came back to ExitCall2 instead of ;
  365. ; going back to DOS! ;
  366. ;-----------------------------------------------------------------------;
  367. assumes ds, nothing
  368. assumes es, nothing
  369. cProc DisableKernel,<PUBLIC,FAR>,<si,di>
  370. cBegin
  371. SetKernelDS
  372. or Kernel_flags[2],KF2_WIN_EXIT ; prevent int 24h dialogs
  373. cmp prevInt21Proc.sel,0
  374. je nodisable
  375. call InternalDisableDOS
  376. nodisable:
  377. SetKernelDS
  378. mov ax,0203h ; Reset not present fault.
  379. mov bl,0Bh
  380. mov cx,prevInt3Fproc.sel
  381. mov dx,prevInt3Fproc.off
  382. int 31h
  383. mov ax,0203h ; Reset stack fault.
  384. mov bl,0Ch
  385. mov cx,prevInt0Cproc.sel
  386. mov dx,prevInt0Cproc.off
  387. int 31h
  388. mov ax,0203h ; Reset GP fault.
  389. mov bl,0Dh
  390. mov cx,prevInt0Dproc.sel
  391. mov dx,prevInt0Dproc.off
  392. int 31h
  393. mov ax,0203h ; Reset invalid op-code exception.
  394. mov bl,06h
  395. mov cx,prevIntx6proc.sel
  396. mov dx,prevIntx6proc.off
  397. int 31h
  398. mov ax,0203h ; Reset page fault.
  399. mov bl,0Eh
  400. mov cx,prevInt0Eproc.sel
  401. mov dx,prevInt0Eproc.off
  402. int 31h
  403. ifdef WOW
  404. mov ax,0203h ; Reset divide overflow traps
  405. mov bl,00h
  406. mov cx,oldInt00proc.sel
  407. mov dx,oldInt00proc.off
  408. int 31h
  409. mov ax,0203h ; Reset single step traps
  410. mov bl,01h
  411. mov cx,prevInt01proc.sel
  412. mov dx,prevInt01proc.off
  413. int 31h
  414. mov ax,0203h ; Reset breakpoint traps
  415. mov bl,03h
  416. mov cx,prevInt03proc.sel
  417. mov dx,prevInt03proc.off
  418. int 31h
  419. endif
  420. mov dx, [HeadPDB]
  421. SetKernelDS es
  422. UnSetKernelDS
  423. exk1:
  424. mov ds,dx
  425. cmp dx, [topPDB] ; Skip KERNEL, he is about to get
  426. je exk3 ; a 4C stuffed down his throat
  427. push ds
  428. call TerminatePDB
  429. pop ds
  430. exk3:
  431. mov dx,ds:[PDB_Chain] ; move to next PDB in chain
  432. or dx,dx
  433. jnz exk1
  434. mov bx,[topPDB] ; set to initial DOS task PDB
  435. mov ah,50h ; set PDB function
  436. int 21h
  437. and Kernel_flags[2],NOT KF2_WIN_EXIT ; prevent int 24h dialogs
  438. ;
  439. ; Close all files on Kernel's PSP, 'cause we're gonna shrink the SFT and
  440. ; quit ourselves afterwards.
  441. ;
  442. mov ds,[topPDB]
  443. mov cx,ds:[PDB_JFN_Length]
  444. exk4: mov bx,cx ; close all file handles
  445. dec bx
  446. cmp bx,5 ; console-related handle?
  447. jb exk5 ; yup, don't close it (AUX, etc.)
  448. mov ah,3eh
  449. int 21h
  450. exk5: loop exk4
  451. ; kernel could have added some nodes to the SFT. Delink them by removing
  452. ; the link from the last DOS link in the chain. We need to remember the
  453. ; current pointer there so that InternalEnableDOS can put it back.
  454. lds bx,[pSftLink] ;place where we hooked new entry
  455. assumes ds,nothing
  456. mov cx,ds ;this could have been unitialized too
  457. jcxz exk6 ;if unitialized, nothing to do
  458. mov dx,ds:[bx].off ;get the current offset
  459. mov cx,ds:[bx].sel ;get the current segment
  460. mov ds:[bx].off,-1 ;remove windows SFT link
  461. mov ds:[bx].sel, 0 ;remove windows SFT link
  462. mov lpWinSftLink.off,dx ;save the offset
  463. mov lpWinSftLink.sel,cx ;save the segment
  464. exk6:
  465. UnSetKernelDS es
  466. cEnd
  467. ;------------------------------------------------------------------
  468. ;
  469. ; ExitKernel -- Bye, bye.
  470. ;
  471. ;------------------------------------------------------------------
  472. ifndef WOW ; If we are closing down WOW then we don't want to go back to the DOS Prompt
  473. ; We want to kill the NTVDM WOW Process - so we don't need/want this code.
  474. assumes ds, nothing
  475. assumes es, nothing
  476. cProc ExitKernel,<PUBLIC,FAR>
  477. ; parmW exitcode
  478. cBegin nogen
  479. SetKernelDS
  480. or Kernel_flags[2],KF2_WIN_EXIT ; prevent int 24h dialogs
  481. call KillLibraries ; Tell DLLs that the system is exiting
  482. mov si,sp
  483. mov si,ss:[si+4] ; get exit code
  484. ; Call driver termination procs, just to make sure that they have removed
  485. ; their interrupt vectors.
  486. push si
  487. mov ax,word ptr [pMouseTermProc]
  488. or ax,word ptr [pMouseTermProc+2]
  489. jz trm0
  490. call [pMouseTermProc]
  491. CheckKernelDS
  492. trm0: mov ax,word ptr [pKeyboardTermProc]
  493. or ax,word ptr [pKeyboardTermProc+2]
  494. jz trm1
  495. call [pKeyboardTermProc]
  496. CheckKernelDS
  497. trm1: mov ax,word ptr [pSystemTermProc]
  498. or ax,word ptr [pSystemTermProc+2]
  499. jz trm2
  500. call [pSystemTermProc]
  501. CheckKernelDS
  502. trm2: pop si
  503. call WriteOutProfiles
  504. mov fProfileMaybeStale,1 ; Make sure we check the
  505. ; INI file next time around
  506. ;;; cCall CloseCachedFiles,<topPDB>
  507. ; Close open files and unhook kernel hooks
  508. ; get on a stack that's not in EMS land
  509. call Enter_gmove_stack
  510. cCall DisableKernel
  511. CheckKernelDS
  512. cmp si,EW_REBOOTSYSTEM ; Reboot windows?
  513. jnz exitToDos
  514. ifndef WOW
  515. if PMODE32
  516. mov ax,1600h
  517. int 2Fh
  518. test al,7Fh
  519. jz NotRunningEnhancedMode
  520. cmp al,1
  521. je exitToDos ;RunningWindows3862x
  522. cmp al,-1
  523. je exitToDos ;RunningWindows3862x
  524. xor di,di ; Zero return regs
  525. mov es,di
  526. mov bx,0009h ; Reboot device ID
  527. mov ax,1684h ; Get device API entry point
  528. int 2Fh
  529. mov ax,es
  530. or ax,di
  531. jz exitToDos ; Reboot vxd not loaded. Exit to dos
  532. ; Call the reboot function
  533. mov ax,0100h
  534. push es
  535. push di
  536. mov bx,sp
  537. call DWORD PTR ss:[bx]
  538. jmp short exitToDos ; Reboot didn't work just exit to dos
  539. NotRunningEnhancedMode:
  540. endif
  541. endif ; WOW
  542. mov ah, 0Dh ; Disk Reset so that Smartdrv etc buffers
  543. int 21h ; are written to disk
  544. mov ax, 0FE03h ; Flush Norton NCache
  545. mov si, "CF"
  546. mov di, "NU"
  547. stc ; Yes! Really set carry too!
  548. int 2Fh
  549. ifdef NEC_98
  550. mov al,92h
  551. out 37h,al
  552. mov al,07h
  553. out 37h,al
  554. mov al,0bh
  555. out 37h,al
  556. mov al,0fh
  557. out 37h,al
  558. mov al,08h
  559. out 37h,al
  560. out 50h,al
  561. mov al,05h
  562. out 0a2h,al ; graph off
  563. out 62h,al ; text off
  564. xor cx, cx
  565. loop $
  566. loop $
  567. loop $
  568. loop $
  569. mov al, 00h
  570. out 0f0h, al ; CPU Reset
  571. jmp $
  572. else ; NEC_98
  573. int 19h ; Reboot via int 19h
  574. endif ; NEC_98
  575. exitToDos:
  576. mov ax,si
  577. mov ah,4Ch ; Leave Windows.
  578. int 21h
  579. cEnd nogen
  580. endif ; NOT WOW
  581. sEnd CODE
  582. end