⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 woaswapi.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;/*
; *                      Microsoft Confidential
; *                      Copyright (C) Microsoft Corporation 1985-1991
; *                      All Rights Reserved.
; */

  
;----------------------------------------------------------------------------;
; This file implements all the switch API functions.			     ;
;									     ;
; History:								     ;
;									     ;
;	 Tue Nov-13-1990.	-by-  Amit Chatterjee [amitc]		     ;
;	 'SwitchAPICallIn' returns with carry set for unsupported call-ins.  ;
;									     ;
;        Thu Aug-23-1990.  	-by-  Amit Chatterjee [amitc]		     ;
;        Created for Switcher. (Added the History legend)    		     ;
;----------------------------------------------------------------------------;


	?win = 0

	?DF = 1
	.xlist
	include cmacros.inc
	include woasegs.inc
	include macros.mac
	include njmp.mac
	include woaswapi.inc
	include woakeys.inc
	.list

	.8086

;----------------------------------------------------------------------------;
; define any public labels or eqautes here.				     ;
;----------------------------------------------------------------------------;

;----------------------------------------------------------------------------;

createSeg   _WOARLMSEG,StubSeg,word,public,code
sBegin	StubSeg

	assumes	cs,StubSeg
	assumes	ds,StubSeg

;----------------------------------------------------------------------------;
; declare public labe and names.					     ;
;----------------------------------------------------------------------------;

			public	SwitchAPICallIn

;----------------------------------------------------------------------------;
; declare variables defined in other files.				     ;
;----------------------------------------------------------------------------;

externW		WoahApp			;App's ID
externB		SwitcherName		;name of the switcher
externW		SwitcherDisabled	;code why switcher is disabled
externB		WoaSwitcherID		;ID of this switcher
externB		WoaHotKeyState		;type of hot key pressed
externW		WoaNodeToSwitchTo	;next node that we want to switch to
externB		WoaNetAsyncSwitching	;Network to be monitored or not
externB		AsyncNetPending		;asynchronous requests seen or not
externW		WoaSwapAreaParaSize	;size of the swap area

;----------------------------------------------------------------------------;
; define data areas that we need in this file.				     ;
;----------------------------------------------------------------------------;

Our_Ver_Struc  	Switcher_Ver_Struc <>	;our version information
Our_NB_API_Info	API_Info_Struc	<>	;our NetBios handler details.

lpCallBackChain		dd	?	;address of the call back SCBI list
CallBackAddrValid 	db	0	;above addr valid or not (not by default)

;----------------------------------------------------------------------------;
; declare external constants.						     ;
;----------------------------------------------------------------------------;

;----------------------------------------------------------------------------;
; define local constants.						     ;
;----------------------------------------------------------------------------;

SD_SWAPI_DISABLE  equ	04h		;disabled by another switcher

;----------------------------------------------------------------------------;
; define the call-in jump table.				             ;
;----------------------------------------------------------------------------;

SwitchAPICallInTable label word

	dw	GetVersion		;AX=0
	dw	TestMemoryRegion	;AX=1
	dw	SuspendSwitcher		;AX=2
	dw	ResumeSwitcher		;AX=3
	dw	HookCallOut		;AX=4
	dw	UnHookCallOut		;AX=5
	dw	QueryAPISupport		;AX=6


SWAPI_MAX_CALL_IN equ 6			;highest call number
;----------------------------------------------------------------------------;
; InitSwitcherAPI:							     ;
;									     ;
; This routine should do whatever is needed to initialize our Switcher API   ;
; support. At this momemnt it does the following:			     ;
;									     ;
;	. prepares the GetVersion return information buffer		     ;
;	. prepare a API_Info_Struc buffer for our NetBios handling details   ;
;       . finds out who is the best API handler for NetBios and if there is  ;
;	  one who is better, it sets the 'WoaNetAsyncSwitching' flag so that ;
;	  we will not mess with NetBios calls.				     ;
;									     ;
; Entry:								     ;
;       None.								     ;
; Exit:									     ;
;	None.								     ;
; Uses:									     ;
;	AX,Flags.							     ;
;----------------------------------------------------------------------------;
cProc	InitSwitcherAPI,<NEAR,PUBLIC,PASCAL>,<es,di,bx,si>

	localD	lp_ISAPI_Call		;to build a call address
cBegin

; prepare the invaliant part of the information buffer.

	smov	es,cs			;es:di -> the buffer to fill.
	mov	di,StubSegOFFSET Our_Ver_Struc
	mov	ax,OUR_API_MAJOR	;save major version of our API spec
	mov	es:[di.SVS_API_Major],ax
	mov	ax,OUR_API_MINOR	;save minor version of our API spec
	mov	es:[di.SVS_API_Minor],ax
	mov	ax,OUR_PRODUCT_MAJOR	;save major version of the switcher
	mov	es:[di.SVS_Product_Major],ax
	mov	ax,OUR_PRODUCT_MINOR	;save minor version of the switcher
	mov	es:[di.SVS_Product_Minor],ax
	xor	ah,ah			
	mov	al,WoaSwitcherID	;save the ID
	mov	es:[di.SVS_Switcher_ID],ax
	mov	ax,SwitcherDisabled	;save the state
	and	ax,SD_SWAPI_DISABLE	;isolate the disabled/enabled flag
	shiftr	ax,2			;bring it to LSB
	.errnz	SD_SWAPI_DISABLE - 4
	mov	es:[di.SVS_Flags],ax	
	mov	ax,StubSegOFFSET SwitcherName  ;get the offset of ID
	mov	wptr es:[di.SVS_Name_Ptr],ax   ;save offset 
	mov	ax,cs			       ;get the segment of name
	mov	wptr es:[di.SVS_Name_Ptr.2],ax ;save segment

; check to see if there is another switcher.

	pushem	es,di			;save
	mov	ax,SWAPI_DETECT_SWITCHER;detect switcher code
	xor	di,di			;need lots of zeros
	mov	es,di			;ES:DI = 0
	mov	bx,di			;BX = 0
	int	2fh			;make the call
	mov	ax,es			;is there another switcher ?
	or	ax,di
	jz	ISAPI_NoOther		;no.

; get the address of the previous switcher's version structure.

	mov	seg_lp_ISAPI_Call,es	;save segment of call address
	mov	off_lp_ISAPI_Call,di	;save offset of call address
	mov	ax,SWAPI_GETVERSION	;need to do a get version call
	pushf				;save interrupt flags
	cli				;interrupts disabled for call
	call	lp_ISAPI_Call		;get the address of the structure
	popf				;restore interrupt state
	mov	di,bx			;ES:DI has the address.

ISAPI_NoOther:

	mov	ax,di			;get offset of the structure
	mov	bx,es			;get the segment of the structure
	popem	es,di			;restore pointer to our structure
	mov	wptr es:[di.SVS_Prev_Switcher],ax   ;save offset 
	mov	wptr es:[di.SVS_Prev_Switcher.2],bx ;save segment

; the version structure has been prepared, prepare a buffer having details 
; about the level of our NetBios handler.

	smov	es,cs			;es:di -> the buffer to fill.
	mov	di,StubSegOFFSET Our_NB_API_Info
	mov	ax,SIZE API_Info_Struc  ;save size of the node
	mov	es:[di.AIS_Length],ax	
	mov	ax,API_NETBIOS		;save API code
	mov	es:[di.AIS_API],ax	
	mov	ax,OUR_NB_MAJOR_VER	;save major version of our support
	mov	es:[di.AIS_MAJOR_VER],ax
	mov	ax,OUR_NB_MINOR_VER	;save minor version of our support
	mov	es:[di.AIS_MINOR_VER],ax
	mov	ax,API_SL_MINIMAL	;save support level
	mov	es:[di.AIS_Support_Level],ax

; Now get the information about the best NetBios handler in the system. 
; If 'WoaNetAsyncSwitching' is 0 we will not do any checks at all since 
; we will not be handling NetBios calls then

	cmp	WoaNetAsyncSwitching,0	;No NetBios support ?
	jnz	ISAPI_Ret		;that right.
	mov	ax,SWAPI_QUERY_API_SUPPORT
	mov	bx,API_NETBIOS		;we are interested in NetBios alone
	call	QueryAPISupport		;a call in function supported by us

; compare to see if ours is the best or not. If they are equal we would still
; enforce ours since what is returned could be information about ourselves.

	mov	ax,es			;get the segment
	mov	di,cs			;get our cs
	cmp	ax,di			;is it in our segment ?
	jnz	ISAPI_NoNBSupport	;no, we will turn off NB support
	cmp	bx,StubSegOFFSET Our_NB_API_Info
	jz	ISAPI_Ret		;our's is the best, we will do NetBios

ISAPI_NoNBSupport:

; there is a better NetBios handler in the system than us. We will not handle
; any NetBios calls, that is, we will set WoaNetAsyncSwitching.

	mov	WoaNetAsyncSwitching,-1 ;no NetBios support

ISAPI_Ret:

cEnd
;----------------------------------------------------------------------------;
; BuildCallBackChain:							     ;
;									     ;
; This routine builds the chain of call back nodes.			     ;
;									     ;
; Entry: 								     ;
;	 None.							             ;
; Exit:									     ;
;       ES:BX	-- Call Back Chain.					     ;
;----------------------------------------------------------------------------;
cProc	BuildCallBackChain,<NEAR,PUBLIC,PASCAL>,<ax,cx,dx>

cBegin	

	pushf				;save interrupt state
	mov	ax,SWAPI_BUILD_CHAIN

; load ES:BX to be 0:0

	xor	bx,bx			;es:bx should be 0 at call time
	mov	es,bx

; load the call in finction address in CX:DX

	mov	dx,StubSegOFFSET SwitchAPICallIn
	mov	cx,cs

; make the INT 2FH call to build the chain of call back nodes.

	int	2fh
	popf				;restore interrupt state

cEnd
;----------------------------------------------------------------------------;
; OkToSuspend?:								     ;
;									     ;
; This call checks to see if it is ok to syspend the current app. The        ;
; following actions are done:						     ;
;									     ;
;	(1) A QuerySuspend call is done. If any one fails this call we do    ;
;	    a SessionActive call to all respondents and abort the switch     ;
;	    attempt. Else,						     ;
;	(2) We check to see whether our NetBios handler says it's OK to      ;
;	    switch or not (based on whether asynchronous calls have gone     ;
;	    through or not). If all's fine we move to step 3, else we        ;
;	    check to see if there is a better NetBios handler than us or not.;
;	    If there are none, we do a SessionActive call abd bort the       ;
;	    switch attempt. Else,					     ;
;	(3) We do a SuspendSession call. If this call is failed we abort     ;
;           our switch attempt as mentioned above, else this routine sets the;
;	    zero flag and returns, meaning thereby, it is ok to switch.	     ;
;									     ;
; Entry:								     ;
;	 None.								     ;
; Exit:									     ;
;        ZERO SET    - If the app can be suspended. Also Interrupts are      ;
;		       disabled in this case.				     ;
;      ZERO CLEAR    - If app cannot be suspended.			     ;
;----------------------------------------------------------------------------;
cProc	OkToSuspend?,<NEAR,PUBLIC,PASCAL>,<ax,bx,dx,es>

cBegin

	mov	ax,SWAPI_QUERY_SUSPEND	;code for QuerySuspend
	mov	dx,0ffffh		;call expects a return code
	sti				;interrupts on for this call
	call	MakeSwitchAPICall	;make the Switch API call
	jnz	SuspendFails		;some node failed the call
	cli				;shut off interrupts.

; have we seen any asynchronous NetBios requests go by ?

	cmp	cs:[AsyncNetPending],0	;any asynchronous net requests ?
	jz	OKTS_Step3		;next step.

; get a ptr to the API info structure block of the best handler of the 
; NetBios API.

	mov	ax,SWAPI_QUERY_API_SUPPORT
	mov	bx,API_NETBIOS		;we are interested in NetBios alone
	call	QueryAPISupport		;a call in function supported by us

; compare to see if ours is the best or not. If it is then we will make the
; decisions and since rquests have been oustanding we will fail the call.

	mov	ax,es			;get the segment
	mov	dx,cs			;get our cs
	cmp	ax,dx			;is it in our segment ?
	jnz	OKTS_Step3		;no, goto step 3
	cmp	bx,StubSegOFFSET Our_NB_API_Info
	jz	SuspendFails		;fail the switch.

OKTS_Step3:

; do the actual suspend call now. Interrupts should be disabled for this call

	mov	ax,SWAPI_SUSPEND	;code for QuerySuspend
	mov	dx,0ffffh		;call expects a return code
	cli				;interrupts off for this call
	call	MakeSwitchAPICall	;make the Switch API call
	jz	OkToSuspendRet		;suspend succeeded

SuspendFails:

; we got to make a SessionActive call into all the nodes

	mov	ax,SWAPI_SESSION_ACTIVE	;code for SessionActive
	xor	dx,dx			;call expects no return code
	push	cx			;save cx
	xor	cx,cx			;not the first SessionActive call
	sti				;interrupts on for this call
	call	MakeSwitchAPICall	;make the Switch API call
	pop	cx			;recover cx, ax != 0
	or	ax,ax			;ZERO not set -> failure

OkToSuspendRet:

; invalidate the call back address.

	mov	cs:[CallBackAddrValid],0;the address is invalid

cEnd
;----------------------------------------------------------------------------;
; MakeSwitchAPICall:							     ;
;									     ;
; This routine walks build the Switch API call back structure and calls the  ;
; the entry points in the chain with the function code in AX till all nodes  ;
; have been called or some node returns a non zero value in AX.		     ;
;									     ;
; Entry:								     ;
;	 AX     -    Switch API function code.				     ;
;	 DX	-    0 if return code not significant, -1 if it is.	     ;
;     Flags	-    Interrupts enabled/disabled as appropriate for the call ;
;								             ;
; Exit:									     ;
;    ZeroSet	-    If all the nodes returned success.			     ;
;									     ;
; Note: When this routine is called, DS will not always be our segment.      ;
;----------------------------------------------------------------------------;

cProc	MakeSwitchAPICall,<NEAR,PUBLIC,PASCAL>,<es,di,ax,bx,cx,dx>

	localD	OTS_Call_Ptr		;needed to call through a DWORD

cBegin

	cCall	BuildCallBackChain	;ES:BX points to start of chain

; we should save the address of the call back chain so that all call ins to 
; us from within the call outs do not have to regenerate the chain. This addr
; will however be invalidated at the end of this call.

	mov	wptr cs:[lpCallBackChain],bx ;save address of call back chain.
	mov	wptr cs:[lpCallBackChain+2],es
	mov	cs:[CallBackAddrValid],-1	;the address is valid
	
WalkChainLoop:

	push	ax			;save
	mov	ax,es			;is es:bx 0 ?
	or	ax,bx			;end of chain ?
	pop	ax			;restore
	jz	MakeSwitchAPICallRet	;yes, call was successful

; call down the chain.

	pushem	es,bx,ax,cx		;save in case the call destroys this
	push	dx			;save return code mask
	les	bx,es:[bx.SCBI_Entry_Pt];get the entry point
	mov	seg_OTS_Call_Ptr,es
	mov	off_OTS_Call_Ptr,bx	;save the address we want to call
	mov	bx,cs:[WoahApp]		;ID of app
	smov	es,cs			;es = cs
	mov	di,StubSegOFFSET SwitchAPICallIn
	call	OTS_Call_Ptr		;make the call
	pop	dx			;get back return code mask
	and	ax,dx			;mask the code
	or	ax,ax			;call returned success ?
	popem	es,bx,ax,cx		;restore pointer to current node & code
	jnz	MakeSwitchAPICallRet    ;this call was failed
	les	bx,es:[bx.SCBI_Next]	;load the pointer to the next node.
	jmp	short WalkChainLoop	;continue checking.

MakeSwitchAPICallRet:

cEnd
;----------------------------------------------------------------------------;
; SwitchAPICallIn:							     ;
;									     ;
; This is the Switch API call in function. This routine checks to see whether;
; the entry code is in range and if it is then the appropriate handler is    ;
; called. Carry is set for unsupported call-ins.			     ;
;----------------------------------------------------------------------------;
SwitchAPICallIn	 proc far

	cmp	ax,SWAPI_MAX_CALL_IN	;in range ?
	ja	SwitchAPICallInErr	;no. Return with carry set
	push	bx			;save
	mov	bx,ax			;get the entry code
	shl	bx,1			;for indexing into jump table
	add	bx,StubSegOFFSET SwitchAPICallInTable
	mov	ax,cs:[bx] 		;get the call address
	pop	bx			;restore
	call	ax			;call the routine

SwitchAPICallInRet:

	ret    

SwitchAPICallInErr:

	stc				;unsupported call-in
	ret

SwitchAPICallIn endp
;----------------------------------------------------------------------------;
; GetVersion:   							     ;
;                Entry:							     ;
;			AX = 0						     ;
;		        Interrupts are disabled and may not be enabled.      ;
;			DOS calls may NOT be made.			     ;
;		 Exit:							     ;
;		        carry flag clear				     ;
;			AX = 0 for future extensibility.		     ;
;		     ES:BX = address of current switcher ver structures.     ;
;									     ;
;----------------------------------------------------------------------------;
GetVersion proc near

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -