📄 woainit.asm
字号:
; We should not try to delete grabber files if the SwitcherID is not 1 or if
; Windows 3.0 winoldap is active.
cmp cx,2 ;trying to delete grabber files ?
jnz DTF_OkToDeleteChain ;no.
cmp SwitcherID,1 ;first instance of switcher ?
jnz DTF_SkipThisChain ;no, do not delete grabber files
; check to see if another winoldap is active as a real mode stub.
mov ax,IS_WINOLDAP_ACTIVE ;woa traps this in real mode
int 2fh ;see if woa is in chain
or ax,ax ;is woa active as a stub ?
jz DTF_SkipThisChain ;yes, donot delete any files
DTF_OkToDeleteChain:
call GetTempFileTemplate ;ds:dx has the file name template
push cx ;save
mov cx,3 ;include hidden and read-only files
mov ah,4eh ;find first call
int 21h ;get the first in chain
jc DoNextChain ;no such file
DeleteTheFile:
; recreate the complete path-file name from the file name that we just found
pop cx ;restore loop index
push cx ;save it back
call CopyBasicTempPrefix ;get the basic temp prefix
sub di,4 ;back over '~DOS'
lea si,NewDta+1eh ;file name here
push ds ;save
smov ds,ss ;ds:dx has the file to delete
; now copy the file name over to complete the path file name
@@:
lodsb ;get the next character of file name
stosb ;copy it
or al,al ;are we done ?
jnz @b ;no.
; now delete the file after setting normal attributes.
pop ds ;restore ds
mov ax,4301h ;set file attributes
xor cx,cx ;normal attributes
int 21h ;normal attributes set
mov ah,41h ;delete file code
int 21h ;one file deleteted
mov ah,4fh ;find next file in chain
int 21h ;did we get another
jc DoNextChain ;no.
jmp short DeleteTheFile ;delete this and look for more
DoNextChain:
pop cx ;get back count
DTF_SkipThisChain:
loop DeleteAChain ;delete this chain too.
; now set back the original DTA address and go back.
push ds ;save
mov dx,off_CurrentDta ;old dta offset
mov ds,seg_CurrentDta ;old dta segment
mov ah,1ah ;set DTA code
int 21h ;DTA address restored
pop ds ;restore data segment
DeleteTempFilesRet:
cEnd
;------------------------------------------;
; get template for temp files based on the ;
; value of CX. ;
; CX = 3 => woa temp files in swap path2 ;
; CX = 2 => grb temp files in swap path2 ;
; CX = 1 => woa temp files in swap path1 ;
;------------------------------------------;
GetTempFileTemplate proc near
call CopyBasicTempPrefix ;get the basic path prefix
cmp cx,2 ;grabber template ?
jz GetGrbTemplate ;get grabbers file template
; now append a nibble for the switcher ID.
mov al,SwitcherID ;get the ID
and al,0fh ;only a nibble of ID
add al,30h ;convert numbers to ascii
cmp al,'9' ;did we go above 9 ?
jbe GTFT_ALHasAscii ;no, we are ok.
add al,7h ;convert to (A-F)
GTFT_ALHasAscii:
stosb ;save it
mov ax,'.*' ;follow it up with '*.*'
stosw ;save it
mov ax,'*' ;ah will have terminating NULL
stosw ;template created
mov dx,DataOFFSET FileTemplate
ret
GetGrbTemplate:
sub di,3 ;step back over 'DOS'
mov ax,'RG' ;nedd to have 'GRB' instead
stosw ;'GR' saved
mov al,'B' ;last part of 'GRB'
stosb ;initial part done.
mov ax,'.*' ;follow it up with '*.*'
stosw ;save it
mov ax,'*' ;ah will have terminating NULL
stosw ;template created
mov dx,DataOFFSET FileTemplate
ret
GetTempFileTemplate endp
;--------------------------------------------;
; gets the basic swap path prefix based on ;
; the value of cx. CX = 2 or 3 implies use ;
; swap path 2, CX = 1 implies use path 1 ;
;--------------------------------------------;
CopyBasicTempPrefix proc near
mov di,DataOFFSET FileTemplate
test cx,2 ;2 or 3
jnz @f ;yes.
call FarCopyBasicSwap1FileName;get prefix for path 1
ret
@@:
call FarCopyBasicSwap2FileName;get prefix for path 2
ret
CopyBasicTempPrefix endp
;----------------------------------------------------------------------------;
; GetSwitcherInfo: ;
; ;
; Gets info from the global switch structure. ;
;----------------------------------------------------------------------------;
cProc GetSwitcherInfo,<FAR,PUBLIC,PASCAL>,<es>
localD OtherSwitcherAddr ;call in address of the 'other' switcher
cBegin
; get a pointer to the global block.
mov ax,4a05h ;opcode
mov si,CGET_GLOBAL_SWITCH_DATA
int 2fh ;dx:ax has the long pointer
mov es,dx ;load it into es
mov di,ax ;es:di -> info structure
; scan through the list and if all ProgramID's are zero, then reset the
; Id_Serial field.
lea si,[di].Program_List ;es:si points to the first program entry
mov cx,MAX_NUM_PROGRAMS ;get the max number of entries
xor ax,ax ;will build a count here
LoopAllEntries:
test es:[si].Program_Flags,F_FREE
jnz ContinueLoop ;this is a free entry
cmp es:[si].Program_Id,0 ;has this been run before ?
jnz OutOfLoop ;yes, break out of loop
ContinueLoop:
add si, SIZE Switch_Entry ;es:si -> next program
inc ax ;one more fresh entry obtained
loop LoopAllEntries ;continue lloking
OutOfLoop:
cmp ax,MAX_NUM_PROGRAMS ;all entries fresh ?
jb @f ;no.
mov es:[di].Id_Serial,0 ;reset this.
@@:
; copy the SwitcherId from the global structure.
mov al,es:[di].Switcher_Id ;ID allocated to this swicher
mov SwitcherID,al ;save it.
; get a pointer to the first program in the list.
lea si,[di].Program_List ;start of array
xor ah,ah ;clear out high byte
mov al,es:[di].First_In_List;get index of first entry
mov bl,SIZE Switch_Entry ;size of each entry
mul bl ;ax has start offset
add si,ax ;es:si -> first program in list.
; copy program related variables.
mov ax,es:[si].Conv_Req ;get conventional memory requirements
mov AppMinMem,ax ;save minimum memory required
mov ax,es:[si].XMS_Req ;amount of xms required
mov AppMinXmsK,ax ;save as min xms requirement
mov ax,es:[si].XMS_Want ;xms desired
mov AppMaxXmsK,ax ;save it
; if AppMaxXmsK is < AppMinXmsK, set it to AppMinXmsK.
cmp ax,AppMinXmsK ;ax could be -1 too.
jae @f ;all is fine
mov ax,AppMinXmsK ;minimum
mov AppMaxXmsK,ax ;save it
@@:
; copy global variables and flags from the switch_info structure.
xor ah,ah ;reset
mov al,es:[di].Num_Lines ;start up no of screen lines
; if the screen lines is zero, we must get it from the BIOS area
or al,al ;uninitialized ?
jnz @f ;no.
push es ;save
mov bx,40h ;bios data area
mov es,bx ;es points to BIOS data segment
mov bx,84h ;location where screen lines saved
mov al,es:[bx] ;get the no of screen lines
inc ax ;actually it is one more
pop es ;restore
@@:
mov cs:[WoaStartScreenLines],ax;save it
mov StartScreenLines,ax ;save a local copy too.
mov al,es:[di].Screen_Back ;back ground screen color
mov [SwitcherColors],al ;save it
mov al,es:[di].Title_Back ;title back ground color
mov [SwitcherColors+1],al ;save it
mov al,es:[di].Title_Fore ;title text color
mov [SwitcherColors+2],al ;save it
mov ax,es:[di].CPU_Type ;get the CPU type
mov cs:[WoaCpuType],ax ;save it
mov ax,es:[di].SFT_Size ;get the file entry size
mov cs:[WoaFileEntrySize],ax;save it
; set the global flags
mov al,es:[di].Global_Flags ;get the global flags
mov cs:[Woa6fValue],0 ;assume int 6f not to be done
test al,GF_INT_6F_TOBE_DONE ;int 6f to be done ?
jz @f ;no.
mov cs:[Woa6fValue],0ffh ;int 6f to be done.
@@:
mov cs:[WoaIrq9Global],0 ;assume IRQ 9 to be handled globally
test al,GF_IRQ9_GLOBAL ;is IRQ 9 global ?
jnz @f ;yes
mov cs:[WoaIrq9Global],0ffh ;don't handle IRQ 9
@@:
mov cs:[WoaNetAsyncSwitching],0 ;assume cannot switch out on async net
test al,GF_NET_ASYNC_SWITCH_OK;is it ok to switch out ?
jz @f ;no
mov cs:[WoaNetAsyncSwitching],0ffh ;ok to switch out
@@:
; copy various behaviour bits and hot key states.
mov cs:[WoaBehavior],0 ;initialize
mov cs:[WoaHotKeys],0 ;initialize
mov ax,es:[si].Program_Flags
and al,F_NO_SWITCH+F_GRAPHICS+F_NO_PAUSE
mov cs:[WoaBehavior],al ;save it
and ax,F_NO_ALT_TAB+F_NO_ALT_ESC+F_NO_CTRL_ESC
mov cs:[WoaHotkeys],ah ;save
; also set bytes in the local hot key list for keys that are disabled.
test ax,F_NO_ALT_TAB ;ALT+TAB disabled ?
jz @f ;no.
mov cs:[WoaAltTabDisabled],0ffh
mov cs:[WoaShftAltTabDisabled],0ffh
@@:
test ax,F_NO_ALT_ESC ;ALT+ESC disabled ?
jz @f ;no.
mov cs:[WoaAltEscDisabled],0ffh
mov cs:[WoaShftAltEscDisabled],0ffh
@@:
test ax,F_NO_CTRL_ESC ;ALT+ESC disabled ?
jz @f ;no.
mov cs:[WoaCtrlEscDisabled],0ffh
@@:
; copy the swither ID.
mov al,SwitcherID ;get the ID
mov cs:[WoaSwitcherID],al ;pass it on
; now copy the program name.
push di ;save
push si ;save program entry pointer
mov di,StubSegOFFSET WoaPath;save program name here.
lea si,[si].Program_Name ;es:si -> program name
call CopyEsSiToCsDi ;copy the name .
pop si ;get back start of entry
pop di ;restore.
; now copy the parameters
push di ;save
push si ;save program entry pointer
lea si,[di].Parameters ;es:si -> parametsrs
mov di,StubSegOFFSET WoaParams;command parameters
call CopyEsSiToCsDi ;copy the name .
pop si ;get back start of entry
pop di ;restore.
; get the program ID and the path ID.
mov al,es:[si].Path_Id ;get the path ID
mov CurrentPathId,al ;save it
mov ax,es:[si].Program_Id ;id for the app
mov hApp,ax ;save it.
mov StartRestartId,al ;start if 0 else restart
or ax,ax ;is it a fresh start ?
jnz @f ;no.
; build the DosAppNumber.
mov ax,es:[di].Id_Serial ;get the serial id
mov DosAppNumber,ax ;save it.
inc ax ;increment it
mov es:[di].Id_Serial,ax ;update it.
; build the hApp id. This is basically the slot in the global structure where
; the program details have been built. Or in otherwords, it is First_In_List.
; we also need to combine the SwitcherID with it.
mov ah,SwitcherID ;get the ID
shiftl ah,4 ;only four 4 bits are significant
mov al,es:[di].First_In_List;rest of the task id
mov hApp,ax ;app's id
mov es:[si].Program_Id,ax ;save it
@@:
; get the grabber file name.
mov si,di ;es:si -> SwitchInfo structure
push si ;save
lea si,es:[si].Grabber_Name ;es:si -> points to the grabber name
mov di,StubSegOFFSET WoaGrabberName;will copy grabber name here
call CopyEsSiToCsDi ;copy the name .
pop si ;es:si -> SwitchInfo
; copy the two swap file paths.
push si ;save
lea si,es:[si].Swap_Path1 ;es:si -> points to the swap path
mov di,DataOFFSET WoaSwap1Path;will copy path here
call CopyEsSiToDsDi ;copy the name .
pop si ;restore pointer to entry
push si ;save
lea si,es:[si].Swap_Path2 ;es:si -> points to the swap path
mov di,DataOFFSET WoaSwap2Path;will copy path here
call CopyEsSiToDsDi ;copy the name .
pop si ;restore pointer to entry
; load the minimum space information for the two swap paths.
mov ax,es:[si].Min_Path1 ;min space for path 1
mov Swap1MinK,ax ;save it
mov ax,es:[si].Min_Path2 ;min space for path 2
mov Swap2MinK,ax ;save it
; get information about swap file.
call GetSwapFileInformation
; If DosAppNumber is 0 and this is not a restart, we must delete all
; temporary files
cmp DosAppNumber,0 ;first app ?
jnz @f ;no.
cmp StartRestartID,0 ;if tart
jnz @f ;delete files.
cCall DeleteTempFiles ;delete all temporary files.
@@:
clc ;successful completion of routine
jmp short GetSwitcherInfoRet
GetSwitcherInfoErr:
stc ;error, cannot proceed
GetSwitcherInfoRet:
cEnd
;----------------------------------------------------------------------------;
; CopyEsSiToDsDi: ;
; ;
; Copies a NULL terminated string from es:si to ds:si. ;
;----------------------------------------------------------------------------;
CopyEsSiToDsDi proc near
mov al,es:[si] ;load a byte
mov ds:[di],al ;save it
inc si ;bump src ptr
inc di ;bump target ptr
or al,al ;NULL copied ?
jnz CopyEsSiToDsDi ;continue
ret ;done
CopyEsSiToDsDi endp
;----------------------------------------------------------------------------;
; CopyEsSiToCsDi: ;
; ;
; Copies a NULL terminated string from es:si to cs:si. ;
;----------------------------------------------------------------------------;
CopyEsSiToCsDi proc near
mov al,es:[si] ;load a byte
mov cs:[di],al ;save it
inc si ;bump src ptr
inc di ;bump target ptr
or al,al ;NULL copied ?
jnz CopyEsSiToCsDi ;continue
ret ;done
CopyEsSiToCsDi endp
;----------------------------------------------------------------------------;
; NearErrorHanlder: ;
; ;
; From here we jump into the main code segment error handler. ;
;----------------------------------------------------------------------------;
NearErrorHandler:
jmp ErrorHandler ;hApp jump into _TEXT segment
;----------------------------------------------------------------------------;
sEnd StubSeg
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -