windows-nt/Source/XPSP1/NT/base/mvdm/wow16/kernel31/enable.asm
2020-09-26 16:20:57 +08:00

680 lines
20 KiB
NASM

.xlist
include kernel.inc
include pdb.inc
include tdb.inc
include newexe.inc
include eems.inc
ifdef WOW
include vint.inc
endif
.list
externFP KillLibraries
ifndef WOW
externFP WriteOutProfiles
endif
DataBegin
externB PhantArray
externB kernel_flags
externB fBreak
externB fInt21
ifndef WOW
externB fProfileMaybeStale
endif
externW curTDB
externW headPDB
externW topPDB
ife PMODE32
externW hXMMHeap
endif
externD lpInt21
externD pSftLink
externD lpWinSftLink
externD pSysProc
externD pMouseTermProc
externD pKeyboardTermProc
externD pSystemTermProc
externW MyCSAlias
externD myInt2F
if ROM
externD prevInt00Proc
externD prevInt21Proc
externD prevInt24Proc
externD prevInt2FProc
externD prevInt3FProc
externD prevInt67Proc
externD prevInt02Proc
externD prevInt04Proc
externD prevInt06Proc
externD prevInt07Proc
externD prevInt3EProc
externD prevInt75Proc
externD prevInt0CProc
externD prevInt0DProc
externD prevIntx6Proc
externD prevInt0EProc
endif
DataEnd
sBegin CODE
assumes CS,CODE
assumes ds, nothing
assumes es, nothing
ife ROM
externD prevInt00Proc
externD prevInt21Proc
externD prevInt24Proc
externD prevInt2FProc
externD prevInt3FProc
externD prevInt67Proc
externD prevInt02Proc
externD prevInt04Proc
externD prevInt06Proc
externD prevInt07Proc
externD prevInt3EProc
externD prevInt75Proc
externD prevInt0CProc
externD prevInt0DProc
externD prevIntx6Proc
externD prevInt0EProc
ifdef WOW
externD prevInt01proc
externD prevInt03proc
externD oldInt00proc
endif
endif
if ROM
externFP PrevROMInt21Proc
endif
externNP real_DOS
externNP Enter_gmove_stack
externNP TerminatePDB
;-----------------------------------------------------------------------;
; InternalEnableDOS
;
;
; Entry:
; none
; Returns:
;
; Registers Destroyed:
;
; History:
; Thu 21-Sep-1989 20:44:48 -by- David N. Weise [davidw]
; Added this nifty comment block.
;-----------------------------------------------------------------------;
SetWinVec MACRO vec
externFP Int&vec&Handler
mov dx, codeoffset Int&vec&Handler
mov ax, 25&vec&h
pushf
if ROM
call PrevROMInt21Proc
else
call prevInt21Proc
endif
endm
assumes ds, nothing
assumes es, nothing
cProc InternalEnableDOS,<PUBLIC,FAR>
cBegin nogen
push si
push ds
SetKernelDS
mov al,1
xchg al,fInt21 ; set hook count to 1
or al,al ; was it zero?
jz @f
jmp ena21 ; no, just leave
@@:
; now link back nodes to SFT if kernel had done it before. InternalDisableDOS
; saves the link in the DWORD variable lpWinSftLink. If this variable is NULL
; then either this is the first time InternalEnableDOS is being called or
; else the SFT had not been grown.
cmp lpWinSftLink.sel,0 ;was it allocated ?
jz @f ;no.
push ds ;save
mov cx,lpWinSftLink.sel ;get the selector
mov dx,lpWinSftLink.off ;get the offset
lds bx,[pSftLink] ;place where we hooked new entry
mov word ptr ds:[bx][0],dx ;restore offset
mov word ptr ds:[bx][2],cx ;restore segment
pop ds ;restore data segment
@@:
; WARNING!! The ^C setting diddle MUST BE FIRST IN HERE......
; If you do some other INT 21 call before this you will have
; a "^C window", so don't do it....
mov ax,3301h ; disable ^C checking
mov dl,0
call real_DOS
mov bx,TopPDB
mov ah,50h
call real_DOS ; This way, or TDB_PDB gets set wrong
ifndef WOW
ends1: mov ah,6 ; clean out any pending keys
mov dl,0FFh
call real_DOS
jnz ends1
endif
mov es,curTDB
mov bx,es:[TDB_PDB]
mov ah,50h
int 21h
push ds
lds dx,myInt2F
mov ax,252Fh
int 21h
smov ds,cs ; Pick up executable sel/seg
UnSetKernelDS
SetWinVec 24
SetWinVec 00
SetWinVec 02
SetWinVec 04
SetWinVec 06
SetWinVec 07
SetWinVec 3E
SetWinVec 75
pop ds
ReSetKernelDS
mov bx,2 ; 2 = Enable/Disable one drive logic
xor ax,ax ; FALSE = Disable
cCall [pSysProc],<bx,ax> ; NOTE: destroys ES if DOS < 3.20
; Set up the PhantArray by calling inquire system for each drive letter
mov bx,dataOffset PhantArray + 25 ; Array index
mov cx,26 ; Drive #
SetPhant:
dec cx
push cx
push bx
mov dx,1 ; InquireSystem
cCall [pSysProc],<dx,cx>
pop bx
pop cx
mov byte ptr [bx],0 ; Assume not Phantom
cmp ax,2
jae NotPhant ; Assumption correct
; or dx,dx ; Drive just invalid?
; jz NotPhant ; Yes, assumption correct
mov byte ptr [bx],dl ; Drive is phantom
NotPhant:
dec bx ; Next array element
jcxz phant_done
jmp SetPhant
phant_done:
lds dx,lpInt21
UnSetKernelDS
mov ax,2521h
int 21h
ena21:
pop ds
pop si
ret
cEnd nogen
;-----------------------------------------------------------------------;
; InternalDisableDOS ;
; ;
; ;
; Arguments: ;
; ;
; Returns: ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; ;
; Registers Destroyed: ;
; ;
; Calls: ;
; ;
; History: ;
; ;
; Mon Oct 16, 1989 11:04:50 -by- Amit Chatterjee [amitc] ;
; InternalDisableDOS now takes away any nodes that kernel would have ;
; added to the SFT. InternalEnableDOS puts the nodes backs. Previously ;
; the delinking was done by DisableKernel, but no one linked it back! ;
; ;
; Sat May 09, 1987 02:00:52p -by- David N. Weise [davidw] ;
; Added this nifty comment block. ;
; ;
; Thu Apr 16, 1987 11:32:00p -by- Raymond E. Ozzie [-iris-] ;
; Changed InternalDisableDOS to use real dos for 52h function, since ;
; DosTrap3 doesn't have 52h defined and PassOnThrough will croak if the ;
; current TDB's signature is 0, as it is during exit after the last ;
; task has been deleted. ;
;-----------------------------------------------------------------------;
ReSetDOSVec MACRO vec
lds dx,PrevInt&vec&proc
mov ax,25&vec&h
int 21h
endm
assumes ds, nothing
assumes es, nothing
cProc InternalDisableDOS,<PUBLIC,FAR>
cBegin
SetKernelDS es
xor ax,ax
xchg al,fInt21 ; set hook count to zero
or al,al ; was it non zero?
jnz @F
jmp dis21 ; no, just leave
@@:
mov bx,2 ; 2 = Enable/Disable one drive logic
mov ax,1 ; TRUE = Enable
push es
cCall pSysProc,<bx,ax>
pop es
mov ax,3301h ; disable ^C checking
mov dl,0
pushf
ife PMODE32
FCLI
endif
call [prevInt21Proc]
mov ax,2521h
lds dx,prevInt21Proc
pushf
ife PMODE32
FCLI
endif
call [prevInt21Proc]
push es
mov ax,352Fh
int 21h
mov ax,es
pop es
mov myInt2F.sel,ax
mov myInt2F.off,bx
ReSetDOSVec 00 ; as a favor in win2 we restored this
ReSetDOSVec 24
ReSetDOSVec 2F
ReSetDOSVec 02
ReSetDOSVec 04
ReSetDOSVec 06
ReSetDOSVec 07
ReSetDOSVec 3E
ReSetDOSVec 75
mov dl,fBreak ; return state of ^C checking
mov ax,3301h
int 21h
dis21:
cEnd
;------------------------------------------------------------------
;
; Ancient WinOldAp hook.
;
;------------------------------------------------------------------
public EnableDOS
EnableDOS Label Byte
if kdebug
krDebugOut DEB_WARN, "Don't call EnableDOS"
endif
retf
;------------------------------------------------------------------
;
; Ancient WinOldAp hook.
;
;------------------------------------------------------------------
public DisableDOS
DisableDOS Label Byte
if kdebug
krDebugOut DEB_WARN, "Don't call DisableDOS"
endif
retf
;------------------------------------------------------------------
;
; Ancient WinOldAp hook.
;
;------------------------------------------------------------------
public EnableKernel
EnableKernel Label Byte
if kdebug
krDebugOut DEB_WARN, "Don't call EnableKernel"
endif
retf
;-----------------------------------------------------------------------;
; DisableKernel ;
; ;
; This call is provided as a Kernel service to applications that ;
; wish to totally unhook Windows in order to do something radical ;
; such as save the state of the world and restore it at a later ;
; time. This is similar in many ways to the way OLDAPP support ;
; works, with the addition that it also unhooks the kernel. ;
; ;
; Arguments: ;
; ;
; Returns: ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; DI,SI,DS ;
; ;
; Registers Destroyed: ;
; ;
; Calls: ;
; ;
; History: ;
; ;
; Sat May 09, 1987 02:34:35p -by- David N. Weise [davidw] ;
; Merged changes in. Most of this came from ExitKernel. ;
; ;
; Tue Apr 28, 1987 11:12:00a -by- R.E.O. SpeedWagon [-????-] ;
; Changed to indirect thru PDB to get JFN under DOS 3.x. ;
; ;
; Mon Apr 20, 1987 11:34:00p -by- R.E.O. SpeedWagon [-????-] ;
; Set PDB to topPDB before final int 21/4C; we were sometimes exiting ;
; with a task's PDB, and thus we came back to ExitCall2 instead of ;
; going back to DOS! ;
;-----------------------------------------------------------------------;
assumes ds, nothing
assumes es, nothing
cProc DisableKernel,<PUBLIC,FAR>,<si,di>
cBegin
SetKernelDS
or Kernel_flags[2],KF2_WIN_EXIT ; prevent int 24h dialogs
cmp prevInt21Proc.sel,0
je nodisable
call InternalDisableDOS
nodisable:
SetKernelDS
mov ax,0203h ; Reset not present fault.
mov bl,0Bh
mov cx,prevInt3Fproc.sel
mov dx,prevInt3Fproc.off
int 31h
mov ax,0203h ; Reset stack fault.
mov bl,0Ch
mov cx,prevInt0Cproc.sel
mov dx,prevInt0Cproc.off
int 31h
mov ax,0203h ; Reset GP fault.
mov bl,0Dh
mov cx,prevInt0Dproc.sel
mov dx,prevInt0Dproc.off
int 31h
mov ax,0203h ; Reset invalid op-code exception.
mov bl,06h
mov cx,prevIntx6proc.sel
mov dx,prevIntx6proc.off
int 31h
mov ax,0203h ; Reset page fault.
mov bl,0Eh
mov cx,prevInt0Eproc.sel
mov dx,prevInt0Eproc.off
int 31h
ifdef WOW
mov ax,0203h ; Reset divide overflow traps
mov bl,00h
mov cx,oldInt00proc.sel
mov dx,oldInt00proc.off
int 31h
mov ax,0203h ; Reset single step traps
mov bl,01h
mov cx,prevInt01proc.sel
mov dx,prevInt01proc.off
int 31h
mov ax,0203h ; Reset breakpoint traps
mov bl,03h
mov cx,prevInt03proc.sel
mov dx,prevInt03proc.off
int 31h
endif
mov dx, [HeadPDB]
SetKernelDS es
UnSetKernelDS
exk1:
mov ds,dx
cmp dx, [topPDB] ; Skip KERNEL, he is about to get
je exk3 ; a 4C stuffed down his throat
push ds
call TerminatePDB
pop ds
exk3:
mov dx,ds:[PDB_Chain] ; move to next PDB in chain
or dx,dx
jnz exk1
mov bx,[topPDB] ; set to initial DOS task PDB
mov ah,50h ; set PDB function
int 21h
and Kernel_flags[2],NOT KF2_WIN_EXIT ; prevent int 24h dialogs
;
; Close all files on Kernel's PSP, 'cause we're gonna shrink the SFT and
; quit ourselves afterwards.
;
mov ds,[topPDB]
mov cx,ds:[PDB_JFN_Length]
exk4: mov bx,cx ; close all file handles
dec bx
cmp bx,5 ; console-related handle?
jb exk5 ; yup, don't close it (AUX, etc.)
mov ah,3eh
int 21h
exk5: loop exk4
; kernel could have added some nodes to the SFT. Delink them by removing
; the link from the last DOS link in the chain. We need to remember the
; current pointer there so that InternalEnableDOS can put it back.
lds bx,[pSftLink] ;place where we hooked new entry
assumes ds,nothing
mov cx,ds ;this could have been unitialized too
jcxz exk6 ;if unitialized, nothing to do
mov dx,ds:[bx].off ;get the current offset
mov cx,ds:[bx].sel ;get the current segment
mov ds:[bx].off,-1 ;remove windows SFT link
mov ds:[bx].sel, 0 ;remove windows SFT link
mov lpWinSftLink.off,dx ;save the offset
mov lpWinSftLink.sel,cx ;save the segment
exk6:
UnSetKernelDS es
cEnd
;------------------------------------------------------------------
;
; ExitKernel -- Bye, bye.
;
;------------------------------------------------------------------
ifndef WOW ; If we are closing down WOW then we don't want to go back to the DOS Prompt
; We want to kill the NTVDM WOW Process - so we don't need/want this code.
assumes ds, nothing
assumes es, nothing
cProc ExitKernel,<PUBLIC,FAR>
; parmW exitcode
cBegin nogen
SetKernelDS
or Kernel_flags[2],KF2_WIN_EXIT ; prevent int 24h dialogs
call KillLibraries ; Tell DLLs that the system is exiting
mov si,sp
mov si,ss:[si+4] ; get exit code
; Call driver termination procs, just to make sure that they have removed
; their interrupt vectors.
push si
mov ax,word ptr [pMouseTermProc]
or ax,word ptr [pMouseTermProc+2]
jz trm0
call [pMouseTermProc]
CheckKernelDS
trm0: mov ax,word ptr [pKeyboardTermProc]
or ax,word ptr [pKeyboardTermProc+2]
jz trm1
call [pKeyboardTermProc]
CheckKernelDS
trm1: mov ax,word ptr [pSystemTermProc]
or ax,word ptr [pSystemTermProc+2]
jz trm2
call [pSystemTermProc]
CheckKernelDS
trm2: pop si
call WriteOutProfiles
mov fProfileMaybeStale,1 ; Make sure we check the
; INI file next time around
;;; cCall CloseCachedFiles,<topPDB>
; Close open files and unhook kernel hooks
; get on a stack that's not in EMS land
call Enter_gmove_stack
cCall DisableKernel
CheckKernelDS
cmp si,EW_REBOOTSYSTEM ; Reboot windows?
jnz exitToDos
ifndef WOW
if PMODE32
mov ax,1600h
int 2Fh
test al,7Fh
jz NotRunningEnhancedMode
cmp al,1
je exitToDos ;RunningWindows3862x
cmp al,-1
je exitToDos ;RunningWindows3862x
xor di,di ; Zero return regs
mov es,di
mov bx,0009h ; Reboot device ID
mov ax,1684h ; Get device API entry point
int 2Fh
mov ax,es
or ax,di
jz exitToDos ; Reboot vxd not loaded. Exit to dos
; Call the reboot function
mov ax,0100h
push es
push di
mov bx,sp
call DWORD PTR ss:[bx]
jmp short exitToDos ; Reboot didn't work just exit to dos
NotRunningEnhancedMode:
endif
endif ; WOW
mov ah, 0Dh ; Disk Reset so that Smartdrv etc buffers
int 21h ; are written to disk
mov ax, 0FE03h ; Flush Norton NCache
mov si, "CF"
mov di, "NU"
stc ; Yes! Really set carry too!
int 2Fh
ifdef NEC_98
mov al,92h
out 37h,al
mov al,07h
out 37h,al
mov al,0bh
out 37h,al
mov al,0fh
out 37h,al
mov al,08h
out 37h,al
out 50h,al
mov al,05h
out 0a2h,al ; graph off
out 62h,al ; text off
xor cx, cx
loop $
loop $
loop $
loop $
mov al, 00h
out 0f0h, al ; CPU Reset
jmp $
else ; NEC_98
int 19h ; Reboot via int 19h
endif ; NEC_98
exitToDos:
mov ax,si
mov ah,4Ch ; Leave Windows.
int 21h
cEnd nogen
endif ; NOT WOW
sEnd CODE
end