📄 woapmrm.asm
字号:
;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1985-1991
; * All Rights Reserved.
; */
;----------------------------------------------------------------------------;
; This file has code which is differnt for real and protected modes and has ;
; proper ifdefs. ;
; ;
; History: ;
; ;
; Fri June-15-1990. -by- Amit Chatterjee [amitc] ;
; Adapted for the Dos Task Switcher. ;
; ;
; Fri June-30-1989. -by- Amit Chatterjee [amitc] ;
; Created for Windows. (Added the History legend) ;
;----------------------------------------------------------------------------;
;----------------------------------------------------------------------------;
?win = 0
?DF = 1
.xlist
include cmacros.inc
include woasegs.inc
include macros.mac
include njmp.mac
include woaerr.inc
include woaarena.inc
.list
.286p
;----------------------------------------------------------------------------;
; define all public names of functions and variables here. ;
;----------------------------------------------------------------------------;
public GetAppXmsBase
public EmergencyExit
public SetSelectorBaseLim64
public GetSelectorBase
;----------------------------------------------------------------------------;
; declare the external function calls. ;
;----------------------------------------------------------------------------;
;----------------------------------------------------------------------------;
sBegin Data
;----------------------------------------------------------------------------;
; define the global variables defined elsewhere ;
;----------------------------------------------------------------------------;
externW WoaCsSize ;size of protected mode code seg
externW WoaDsSize ;size of winoldap data segment
externW StubSegSize ;size of real mode stub segment
externW LowMemArenaSel ;selector/seg for low heap arena
externW ArenaWalkSel ;temp selector for walkimg arena chain
externW ArenaRWSel ;temp sel for reading/writing arenas
externW WoaStubSel ;selector for stub code segment
externW XmsHeapWalkSel ;used for walking xms heap
externW LowMemParaSize ;size of low heap in paragraphs
externD XmsBankSize ;size of XMS to be allocated
externB ErrorType ;save area for error code
externW SegResizeBlock ;block to resize in real mode
externW SizeReservedArea ;size of area reserved area at heap st.
externD SwapFileOffset ;lseek offset for swap in/out
externW UsableLowHeapSel ;sel/seg for reusable part of low heap
externW LowMemSel ;sel for available mem
externB WinSaveXms ;if ff, XMS to be saved at win swap out
externW HighMemXmsHandle ;handle of the high heap XMS block
externW AppXmsBaseSel ;selector for apps XMS base.
externW AppUsesXMS ;app used XMS allocated to it or not
externB NodeToSwitchTo ;node that we want to switch to
; declare the storage for the registers needed to communicate with the stub.
externW RealMode_AX ;space for AX
externW RealMode_BX ;space for BX
externW RealMode_CS ;space for CS
externW RealMode_DS ;space for DS
externW RealMode_ES ;space for ES
externW RealMode_IP ;space for IP
;-------------------------------------------------------;
; define any locally used constants ;
;-------------------------------------------------------;
;-------------------------------------------------------;
; define any external contants. ;
;-------------------------------------------------------;
;---------------------------------------------------------------------------;
; now define the other variables that will be needed. ;
;---------------------------------------------------------------------------;
public lpXmsControl
public SegAfterReservedArea
lpStubEntry dd ? ;call gate for stub code
SegAfterReservedArea dw ? ;segment after the reserved area
SwapHandle dw ? ;temporary space
lpXmsControl dd ? ;XMS control function address
;----------------------------------------------------------------------------;
sEnd Data
;----------------------------------------------------------------------------;
; now declare the existence of the realmode stub segment and the variables ;
; that we want to reference here. ;
;----------------------------------------------------------------------------;
createSeg _WOARLMSEG,StubSeg,word,public,code
sBegin StubSeg
externB XmsStartLine ;start of XMS handler in real mode stub
sEnd StubSeg
;----------------------------------------------------------------------------;
sBegin Code
assumes cs,Code
assumes ds,Data
assumes es,nothing
;----------------------------------------------------------------------------;
; declare the external winoldap functions used here. ;
;----------------------------------------------------------------------------;
externNP ErrorManager ;(WOAERR.ASM)
externNP MoveWOA ;(WOAMGR.ASM)
externNP LoadRealModeStub ;(WOAMGR.ASM)
externNP CreateFile ;(WOAMGR.ASM)
externNP OpnFile ;(WOAFILE.ASM)
externNP ReadFile ;(WOAFILE.ASM)
externNP WriteFile ;(WOAFILE.ASM)
externNP LseekFile ;(WOAFILE.ASM)
externNP CloseFile ;(WOAFILE.ASM)
externNP DeleteFile ;(WOAPMRM.ASM)
externNP SetNormalAttributes ;(WOAFILE.ASM)
externNP SetHiddenAttributes ;(WOAFILE.ASM)
externNP GetSizeInBytes ;(WOAUTILS.ASM)
externNP RestoreSwappedGroups ;(WOAUTILS.ASM)
externNP IsEnoughDiskSpace ;(WOAUTILS.ASM)
externNP SwapOutNonZeroBlocks ;(WOAUTILS.ASM)
;----------------------------------------------------------------------------;
; SaveFirstDosBlock: ;
; ;
; This routine is invoked to copy out the first arena header to the swap ;
; file and to skip over the _DATA and _TEXT segment. ;
; If SFDBOpCode is 0 this will not write anything to disk. The size of the ;
; swap area will be returned in CX:DX and the size of the skipped part in AX.;
;----------------------------------------------------------------------------;
cProc SaveFirstDosBlock,<NEAR,PASCAL,PUBLIC>,<es>
parmW FileHandle ;handle of the swap file
parmB SFDBOpCode ;get size only or save
cBegin
cld ;do not take chances with this
mov es,LowMemArenaSel ;get the selector for the arena
; if the OpCide is for get size only, then bypass the File IO
cmp SFDBOpCode,0 ;get size only ?
jz SFDBByPassIO1 ;yes
; first swap out the arena.
xor ax,ax ;need for hiword of count and for offset
mov cx,16 ;16 bytes of arena header
save <es> ;need to save this
cCall WriteFile,<FileHandle,es,ax,ax,cx>
jc SaveFirstBlockRet ;will not continue with error
SFDBByPassIO1:
; now calculate the part that will be skipped over - the portion between
; LowMemSel and _WOARLMSEG.
mov ax,_WOARLMSEG ;start of stub segment
sub ax,LowMemSel ;start of the first block
xor cx,cx ;size written out to be in CX:DX
mov dx,16 ;we just wrote out the arena
SaveFirstBlockRet:
cEnd
;----------------------------------------------------------------------------;
; RestoreFirstDosBlock: ;
; ;
; This routine restore the arena of the first block from the swap file. ;
;----------------------------------------------------------------------------;
cProc RestoreFirstDosBlock,<NEAR,PUBLIC,PASCAL>,<es>
parmW FileHandle ;handle of the swap file
cBegin
cld ;do not take chances with this
; read in the arena header.
xor ax,ax ;nedd for hiword of count and for offset
mov es,LowMemArenaSel ;get the selector for the arena
mov cx,16 ;16 bytes of arena header
save <es> ;need to save this
cCall ReadFile,<FileHandle,es,ax,ax,cx>
cEnd
;----------------------------------------------------------------------------;
; RestoreSwap
;----------------------------------------------------------------------------;
; SaveAppXmsContext: ;
; ;
; This routine takes a file handle as a parameter and saves the apps XMS ;
; context from the current location in the file. The context is saved as a ;
; 4 byte size followed by the actual XMS block if the size is non zero. ;
;----------------------------------------------------------------------------;
cProc SaveAppXmsContext,<NEAR,PUBLIC,PASCAL>,<es,si,di>
parmW FileHandle ;handle of the dos swap file
cBegin
cld ;do not take chances with this
; irrespective of whether size is 0 or not, we need to save the size at least
mov dx,wptr [XmsBankSize] ;get low word of size
mov cx,wptr [XmsBankSize+2] ;get high word of size
; swap out the size and the XMS block to the disk if size is not zero, else
; just write the size into the swap file.
cCall RMSwapOutXmsBlock,<FileHandle,cx,dx>
SaveAppXmsContextRet:
cEnd
;----------------------------------------------------------------------------;
; RestoreAppXmsContext: ;
; ;
; Restores the apps xms context. This routine takes a file handle as a param-;
; -eter and the 4 bytes at the current position of the file is the size of ;
; the XMS memory allocated to the app. If the size is non zero, the current ;
; contents of the XMS area must be saved into the XMS swap file before ;
; restoring the apps XMS memory. ;
; ;
; A very important point to note here is that, at this point the app that we ;
; are trying to restore may not have been loaded by this instance of winoldap;
; So the value of 'XmsBankSize' that we need for restoring is not a property ;
; of the app we are trying to restore. We will reset the value of the ;
; variable from the value stored in the old apps file. ;
;----------------------------------------------------------------------------;
cProc RestoreAppXmsContext,<NEAR,PUBLIC,PASCAL>,<es,si,di>
parmW FileHandle ;handle of the swap file
localD TempBuffer ;will read in size of xms block here
localD lpSwapFile ;name of the swap file (ptr to it)
cBegin
cld ;do not take chances with this
; read in the 'AppUsesXMS' field.
mov di,DataOFFSET AppUsesXMS;will read in here directly
xor ax,ax ;hiword of count is 0
mov bx,2 ;need to read 2 bytes
cCall ReadFile,<FileHandle,ds,di,ax,bx>
jc RestoreAppXmsContextRet ;cannot procedd with error
; read in the 4 byte XMS memory size
smov es,ss ;temp buffer is in stack
lea di,TempBuffer ;es:di points to buffer
xor ax,ax ;hiword of count is 0
mov bx,4 ;need to read 4 bytes (loword of count)
cCall ReadFile,<FileHandle,es,di,ax,bx>
jc RestoreAppXmsContextRet ;cannot procedd with error
; test to see if the size of XMS memory is zero or not.
mov cx,seg_TempBuffer ;get the high word
mov dx,off_TempBuffer ;get the low word
; reset 'XmsBankSize', we will need it to be what is in cx:dx when we finally
; need to save the apps context
mov wptr [XmsBankSize+2],cx ;save the high word
mov wptr [XmsBankSize],dx ;save the low word
; test to see whether there is at all any context to restore
mov ax,cx
or ax,dx ;is the memory block size 0 ?
jz RestoreAppXmsContextRet ;yes, there is no context to restore.
; test to see if 'AppUsesXMS' is zero, if so then there will be no XMS to
; swap in.
cmp AppUsesXMS,0 ;did it use XMS ?
jz RestoreAppXmsContextRet ;no, there is no context to restore.
; now swap in the dos xms context from the dos app swap file.
xor ax,ax ;opcode = 0 => read from file
cCall RMSwapInXmsBlock,<FileHandle,TempBuffer,ax>
RestoreAppXmsContextRet:
cEnd
;----------------------------------------------------------------------------;
; RMSwapOutXmsBlock: ;
; ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -