mirror of https://github.com/lianthony/NT4.0
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.
993 lines
25 KiB
993 lines
25 KiB
;*****************************************************************;
|
|
;** Copyright(c) Microsoft Corp., 1988-1993 **;
|
|
;*****************************************************************;
|
|
;:ts=8
|
|
TITLE VNBT - Netbios on TCP/IP vxd
|
|
.XLIST
|
|
;*** VNBT -- NetBios on TCP/IP VxD
|
|
;
|
|
; This module contains the device header for the NBT VxD driver.
|
|
;
|
|
.386p
|
|
include vmm.inc
|
|
ifdef CHICAGO
|
|
include ndis.inc
|
|
endif ;; CHICAGO
|
|
include dosmgr.inc
|
|
include netvxd.inc
|
|
IFDEF CHICAGO
|
|
include configmg.inc
|
|
ENDIF
|
|
include vwin32.inc
|
|
include vdhcp.inc
|
|
include debug.inc
|
|
include vtdi.inc
|
|
|
|
Create_VNBT_Service_Table EQU True
|
|
ifdef CHICAGO
|
|
include vnbt.inc
|
|
else ;; CHICAGO
|
|
include vnbtd.inc
|
|
endif ;; CHICAGO
|
|
include vnetbios.inc
|
|
|
|
include pageable.inc
|
|
.LIST
|
|
|
|
Declare_Virtual_Device VNBT,3,0,VNBT_Control,VNBT_Device_ID, \
|
|
VNBT_Init_Order,VNBT_Api_Handler,VNBT_Api_Handler
|
|
|
|
|
|
VxD_DATA_SEG
|
|
VxD_DATA_ENDS
|
|
|
|
EXTRN __VxdMapSegmentOffsetToFlat:near ; from client.asm
|
|
ifndef CHICAGO
|
|
EXTRN _BSSBegin:DWORD
|
|
EXTRN _BSSDataEnd:DWORD
|
|
endif ;; CHICAGO
|
|
EXTRN _TdiDispatch:DWORD
|
|
|
|
EXTRN _PostInit_Proc:NEAR
|
|
EXTRN _VxdApiWorker:NEAR
|
|
|
|
ifndef CHICAGO
|
|
EXTRN _VNBT_NCB_X@20:NEAR
|
|
endif ;; CHICAGO
|
|
|
|
EXTRN _GetDhcpOption:NEAR
|
|
|
|
|
|
VxD_ICODE_SEG
|
|
|
|
EXTRN _Init:NEAR
|
|
|
|
MSTCP db 'MSTCP',0 ; Protocol this driver sits on (this will have
|
|
; to be changed to get it from an .ini file)
|
|
IFDEF CHICAGO
|
|
bInitialized db 0 ; 0 means not initialized, 1 means we've entered
|
|
; the initialization, and 2 means we've left init
|
|
bSuccessInit db 0 ; 0 means initialization failed and all subsequent
|
|
; initializations should fail
|
|
ENDIF
|
|
|
|
NBTSectionName db 'NBT',0 ; Section where parameters are stored
|
|
|
|
;****************************************************************************
|
|
;** VNBT_Device_Init - VNBT device initialization service.
|
|
;
|
|
; The VNBT device initialization routine. Before calling anything
|
|
; we need to zero out the BSS data area.
|
|
;
|
|
;
|
|
; Entry: (EBX) - System VM Handle
|
|
; (EBP) - System Client Regs structure.
|
|
;
|
|
; Exit: 'CY' clear if we init. successfully.
|
|
; 'CY' set if we've failed.
|
|
;
|
|
BeginProc VNBT_Device_Init
|
|
|
|
IFDEF CHICAGO
|
|
;
|
|
; Chicago calls us at both dynamic and static init, so only process
|
|
; once
|
|
;
|
|
cmp bInitialized, 2 ; 2 means we've already completed initialization
|
|
jne Init_Continue
|
|
clc ; Assume success (is checked below)
|
|
jmp Init_Exit
|
|
|
|
Init_Continue:
|
|
mov bInitialized, 1
|
|
ENDIF
|
|
|
|
ifndef CHICAGO
|
|
mov edi, OFFSET32 _BSSBegin
|
|
mov ecx, OFFSET32 _BSSDataEnd
|
|
sub ecx, edi
|
|
shr ecx, 2
|
|
sub eax, eax
|
|
cld
|
|
rep stosd
|
|
endif ;; CHICAGO
|
|
|
|
VxDcall VTDI_Get_Version
|
|
jc Init_Exit ; Get out if VTDI is not installed
|
|
|
|
;
|
|
; Get the TDI Vxd dispatch table for "MSTCP" to initialize the TDI
|
|
; dispatch table (which will be needed by some of our
|
|
; initialization stuff)
|
|
;
|
|
mov eax, OFFSET32 MSTCP
|
|
push eax
|
|
VxDcall VTDI_Get_Info
|
|
add esp, 4
|
|
cmp eax, 0 ; eax contains NULL or the pointer to the table
|
|
jne NoError
|
|
|
|
Debug_Out "VNBT_Device_Init - VTDI_Get_Info failed!"
|
|
stc ; Set the carry
|
|
jmp Init_Exit
|
|
|
|
NoError:
|
|
mov _TdiDispatch, eax
|
|
|
|
;
|
|
; Initialize the rest of the driver
|
|
;
|
|
call _Init
|
|
cmp eax, 1 ; Set 'CY' appropriately.
|
|
|
|
Init_Exit:
|
|
|
|
IFDEF CHICAGO
|
|
jc Exit2 ; Failed init, leave bSuccessInit 0
|
|
|
|
;
|
|
; If first time through and success, indicate successful initialization
|
|
;
|
|
cmp bInitialized, 1
|
|
je SetInitFlag
|
|
|
|
;
|
|
; We've already been initialized once, was it successful?
|
|
;
|
|
cmp bSuccessInit, 1
|
|
clc ; test clears the carry so assume success
|
|
je Exit2
|
|
|
|
stc ; Set the carry since we failed init. last time
|
|
jmp Exit2
|
|
|
|
SetInitFlag:
|
|
clc
|
|
mov bSuccessInit, 1
|
|
|
|
Exit2:
|
|
mov bInitialized, 2
|
|
ENDIF
|
|
ret
|
|
|
|
|
|
|
|
|
|
EndProc VNBT_Device_Init
|
|
|
|
|
|
VxD_ICODE_ENDS
|
|
|
|
NBT_PAGEABLE_CODE_SEG
|
|
|
|
ifdef CHICAGO
|
|
_NdisOpenProtocolConfiguration@12 PROC NEAR PUBLIC
|
|
VxDJmp NdisOpenProtocolConfiguration
|
|
_NdisOpenProtocolConfiguration@12 ENDP
|
|
|
|
_NdisCloseConfiguration@4 PROC NEAR PUBLIC
|
|
VxDJmp NdisCloseConfiguration
|
|
_NdisCloseConfiguration@4 ENDP
|
|
|
|
_NdisReadConfiguration@20 PROC NEAR PUBLIC
|
|
VxDJmp NdisReadConfiguration
|
|
_NdisReadConfiguration@20 ENDP
|
|
endif ;; CHICAGO
|
|
|
|
NBT_PAGEABLE_CODE_ENDS
|
|
|
|
VxD_CODE_SEG
|
|
;****************************************************************************
|
|
;* NCB_Handler
|
|
;
|
|
; Called by VNetBios when NCBs need to be submitted to this driver
|
|
;
|
|
; ENTRY:
|
|
; EBX = NCB being submitted
|
|
;
|
|
; EXIT:
|
|
; AL - return code
|
|
;
|
|
BeginProc NCB_Handler
|
|
|
|
;
|
|
; In the master portion of the mif tests, after hitting ctrl-c during
|
|
; the attempt to synchronize, a wait add group name NCB is
|
|
; submitted with interrupts disabled. The CTE timer event handler
|
|
; checks this and schedules an event for when they are re-enabled,
|
|
; however since it's a wait NCB, we deadlock in VNBT_NCB_X's block.
|
|
;
|
|
; Make sure interrupts are enabled.
|
|
; BUGBUG - Why were we called with ints disabled?
|
|
;
|
|
;VMMcall Enable_VM_Ints
|
|
|
|
xor eax, eax ; second parm of VNBT_NCB_X is unused when
|
|
|
|
ifndef CHICAGO
|
|
|
|
push eax
|
|
push eax
|
|
push eax ; called from here, but is used (e.g.nbtstat)
|
|
push eax
|
|
push ebx
|
|
call _VNBT_NCB_X@20 ; when VNBT_NCB_X is called directly
|
|
|
|
else ;; CHICAGO
|
|
if 0
|
|
;
|
|
; As of 08-Feb-1996 there is a bug in "vmm.h" where this doesn't
|
|
; work properly, with the result being a misaligned stack pointer.
|
|
;
|
|
VxDCall VNBT_NCB_X, <ebx, eax, eax, eax, eax>
|
|
else ;; 0
|
|
push eax
|
|
push eax
|
|
push eax
|
|
push eax
|
|
push ebx
|
|
VxDCall VNBT_NCB_X
|
|
endif ;; 0
|
|
endif ;; CHICAGO
|
|
|
|
ret
|
|
EndProc NCB_Handler
|
|
|
|
;****************************************************************************
|
|
;** _DhcpQueryOption - Queries a DHCP option
|
|
;
|
|
; Stub callout to the Dhcp driver
|
|
;
|
|
; Entry: [ESP+4] - IP Address of interest
|
|
; [ESP+8] - DHCP Option number
|
|
; [ESP+12]- Pointer to buffer
|
|
; [ESP+16]- Pointer to buffer size
|
|
;
|
|
;
|
|
|
|
BeginProc _DhcpQueryOption
|
|
|
|
VxdCall VDHCP_Get_Version
|
|
jnc DQI_Installed
|
|
|
|
mov eax, 26 ; DHCP not installed, return invalid param
|
|
ret
|
|
|
|
DQI_Installed:
|
|
push ebp
|
|
mov ebp,esp
|
|
|
|
mov eax, [ebp+20] ; Buff size
|
|
push eax
|
|
mov eax, [ebp+16] ; Buff
|
|
push eax
|
|
mov eax, [ebp+12] ; Option
|
|
push eax
|
|
mov eax, [ebp+8] ; IP Address
|
|
push eax
|
|
|
|
VxdCall VDHCP_Query_Option
|
|
|
|
add esp, 16
|
|
|
|
pop ebp
|
|
ret
|
|
|
|
EndProc _DhcpQueryOption
|
|
|
|
;****************************************************************************
|
|
;** VNBT_Get_Version - VNBT get version service
|
|
;
|
|
; Called by using devices to make sure the VNBT driver
|
|
; is present. Also returns the version of the VNBT driver.
|
|
;
|
|
; Entry: Nothing
|
|
;
|
|
; Exit: On success, 'CY' is clear, and
|
|
; AH - Major version # of driver.
|
|
; AL - Minor version #
|
|
;
|
|
; On failure, 'CY' is set.
|
|
;
|
|
; Uses: AX
|
|
;
|
|
BeginProc VNBT_Get_Version, SERVICE
|
|
|
|
mov ax, VNBT_VERSION
|
|
clc
|
|
ret
|
|
|
|
EndProc VNBT_Get_Version
|
|
|
|
VxD_CODE_ENDS
|
|
NBT_PAGEABLE_CODE_SEG
|
|
|
|
;****************************************************************************
|
|
;** VNBT_Device_PostProc - do postprocessing
|
|
;
|
|
; Called by the sytem when all the other stuff (in our case, rdr) is
|
|
; loaded. At this we read the lmhosts file, so that any #INCLUDE with
|
|
; UNC names in it will work.
|
|
; This routine can also be used for other stuff, but for now only lmhosts
|
|
; stuff.
|
|
;
|
|
BeginProc VNBT_Device_PostProc
|
|
|
|
call _PostInit_Proc
|
|
clc
|
|
ret
|
|
|
|
EndProc VNBT_Device_PostProc
|
|
|
|
NBT_PAGEABLE_CODE_ENDS
|
|
VxD_CODE_SEG
|
|
|
|
;****************************************************************************
|
|
;** VNBT_Control - VNBT device control procedure
|
|
;
|
|
; This procedure dispatches VxD messages to the appropriate handler.
|
|
;
|
|
; Entry: EBX - VM handle
|
|
; (EBP) - Client reg structure
|
|
;
|
|
; Exit: 'NC' is success, 'CY' on failure
|
|
;
|
|
; Uses: All
|
|
;
|
|
BeginProc VNBT_Control
|
|
|
|
Control_Dispatch Device_Init, VNBT_Device_Init
|
|
Control_Dispatch Sys_Dynamic_Device_Init, VNBT_Device_Init
|
|
Control_Dispatch Sys_Vm_Init, VNBT_Device_PostProc
|
|
IFDEF CHICAGO
|
|
Control_Dispatch W32_DEVICEIOCONTROL, VNBT_DeviceIoControl
|
|
ENDIF
|
|
|
|
clc
|
|
ret
|
|
|
|
EndProc VNBT_Control
|
|
|
|
IFDEF CHICAGO
|
|
;*******************************************************************
|
|
;** VNBT_DeviceIoControl
|
|
;
|
|
; Dispatch routine for VxD services invoked via the Win32
|
|
; DeviceIoControl API.
|
|
;
|
|
; Entry: (ESI) - Points to DIOCParams structure (see VWIN32.H).
|
|
;
|
|
; Exit: (EAX) - Win32 status code, -1 for asynchronous
|
|
; completion.
|
|
; HISTORY:
|
|
; Koti 10-Nov-1994 Created (Modified from wsock version)
|
|
;
|
|
;********************************************************************
|
|
BeginProc VNBT_DeviceIoControl
|
|
|
|
;;;
|
|
;;; Setup stack frame.
|
|
;;;
|
|
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
mov eax, [esi.dwIoControlCode]
|
|
cmp ecx, DIOC_GETVERSION
|
|
je vdic_doNothing
|
|
cmp ecx, DIOC_CLOSEHANDLE
|
|
jne vdic_doSomething
|
|
|
|
;;;
|
|
;;; For devioctl calls resulting from CreateFile and CloseFile, we don't do
|
|
;;; anything other than return success.
|
|
;;;
|
|
|
|
vdic_doNothing:
|
|
xor eax, eax
|
|
jmp vdic_CommonExit
|
|
|
|
;;;
|
|
;;; This is an ioctl requiring some work: call our api worker (VxdApiWorker)
|
|
;;;
|
|
|
|
vdic_doSomething:
|
|
|
|
;;; Lock the in-buffer.
|
|
|
|
mov eax, [esi.lpvInBuffer]
|
|
or eax, eax
|
|
jz vdic_outbuf
|
|
|
|
cCall __VxdLockBuffer, <eax, [esi.cbInBuffer]>
|
|
or eax, eax
|
|
jz vdic_LockFailure
|
|
mov [esi.lpvInBuffer], eax
|
|
|
|
vdic_outbuf:
|
|
|
|
;;; Lock the out-buffer.
|
|
|
|
mov eax, [esi.lpvOutBuffer]
|
|
or eax, eax
|
|
jz vdic_callApi
|
|
|
|
cCall __VxdLockBuffer, <eax, [esi.cbOutBuffer]>
|
|
or eax, eax
|
|
jz vdic_LockFailure
|
|
mov [esi.lpvOutBuffer], eax
|
|
|
|
vdic_callApi:
|
|
|
|
mov eax, 0 ; VxdApiWorker won't trash input buffer
|
|
push eax
|
|
mov eax, [esi.cbInBuffer]
|
|
push eax
|
|
mov eax, [esi.lpvInBuffer]
|
|
push eax
|
|
mov eax, [esi.cbOutBuffer]
|
|
push eax
|
|
mov eax, [esi.lpvOutBuffer]
|
|
push eax
|
|
mov eax, [esi.dwIoControlCode]
|
|
push eax
|
|
|
|
call _VxdApiWorker
|
|
add esp, 24
|
|
|
|
|
|
;;; Unlock the in-buffer.
|
|
|
|
push eax ; save the return code from VxdApiWorker
|
|
cCall __VxdUnlockBuffer, <[esi.lpvInBuffer], [esi.cbInBuffer]>
|
|
pop eax
|
|
|
|
;;; Unlock the out-buffer.
|
|
|
|
push eax ; save the return code from VxdApiWorker
|
|
cCall __VxdUnlockBuffer, <[esi.lpvOutBuffer], [esi.cbOutBuffer]>
|
|
pop eax
|
|
|
|
vdic_CommonExit:
|
|
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
|
|
ret
|
|
|
|
;;;
|
|
;;; Failed to lock parameter structure.
|
|
;;;
|
|
|
|
vdic_LockFailure:
|
|
|
|
Debug_Out "VNBT_DeviceIoControl: cannot lock parameters"
|
|
|
|
mov eax, 1784 ; ERROR_INVALID_USER_BUFFER
|
|
jmp vdic_CommonExit
|
|
|
|
EndProc VNBT_DeviceIoControl
|
|
|
|
;*******************************************************************
|
|
;** _ReconfigureDevnode
|
|
;
|
|
; This routine schedules an AppyTime call for the ConfigMgr to
|
|
; call us back when it's ready. It calls our routine VNBT_ConfigCalls
|
|
;
|
|
; Entry: ESP+4 our devnode on the stack
|
|
;
|
|
; Exit: (EAX) - 0 if everything goes well
|
|
; 1 if something goes wrong
|
|
;
|
|
; HISTORY:
|
|
; Koti 15-Dec-1994 Created
|
|
;
|
|
;********************************************************************
|
|
|
|
BeginProc _ReconfigureDevnode
|
|
|
|
push ebp
|
|
mov ebp, esp
|
|
|
|
xor eax, eax
|
|
push eax ; the flags
|
|
mov eax, [ebp+8] ; our devnode
|
|
push eax ; this is our RefData
|
|
lea eax, VNBT_ConfigCalls ; call back routine
|
|
push eax
|
|
VxdCall _CONFIGMG_Call_At_Appy_Time
|
|
add esp, 12
|
|
cmp eax, CR_SUCCESS
|
|
je ReconfigureDevnode_PASS
|
|
mov eax, 1
|
|
jmp ReconfigureDevnode_Exit
|
|
|
|
ReconfigureDevnode_PASS:
|
|
xor eax, eax
|
|
|
|
ReconfigureDevnode_Exit:
|
|
IFDEF DBG
|
|
or eax, eax
|
|
jz ReconfigureDevnode_GoodJob
|
|
int 3
|
|
ReconfigureDevnode_GoodJob:
|
|
ENDIF
|
|
pop ebp
|
|
ret
|
|
EndProc _ReconfigureDevnode
|
|
|
|
VxD_CODE_ENDS
|
|
|
|
NBT_PAGEABLE_CODE_SEG
|
|
|
|
;*******************************************************************
|
|
;** VNBT_ConfigCalls
|
|
;
|
|
; This routine makes all the calls to the Config Mgr so that our
|
|
; devnode is reconfigured. We first get vredir's devnode, kill it
|
|
; and then reenumerate all the children again. This way vredir
|
|
; gets the msg from ConfigMgr to do whatever it does with a new devnode.
|
|
;
|
|
; If dhcp lease expires and then comes back in, vredir had no way
|
|
; of knowing that lana is usable again: hence this convoluted way.
|
|
;
|
|
; IMPORTANT: if chicago ever changes to add more children to tcp's
|
|
; devnode, this function needs to be modified to enumerate
|
|
; rest of the children and kill them!
|
|
;
|
|
; Entry: (EDX) - our devnode
|
|
;
|
|
; Exit: (EAX) - 0 if everything goes well
|
|
; 1 if something goes wrong
|
|
;
|
|
; HISTORY:
|
|
; Koti 15-Dec-1994 Created
|
|
;
|
|
;********************************************************************
|
|
|
|
VnbtScratch dd 0
|
|
|
|
BeginProc VNBT_ConfigCalls
|
|
|
|
push ebp
|
|
mov ebp, esp
|
|
push esi
|
|
push edi
|
|
push ecx
|
|
|
|
;;; First get the first child
|
|
xor eax, eax
|
|
push eax ; the flags
|
|
mov eax, [ebp+8]
|
|
push eax ; our devnode
|
|
lea eax, VnbtScratch ; this is where we will receive child node
|
|
push eax
|
|
VxdCall _CONFIGMG_Get_Child
|
|
add esp, 12
|
|
mov esi, dword ptr [VnbtScratch] ;save the first child in esi
|
|
mov edi, 0 ; for now, make esi,edi different
|
|
cmp eax, CR_SUCCESS
|
|
je ConfigCalls_Label2
|
|
mov ecx, 1
|
|
jmp ConfigCalls_Exit
|
|
|
|
;;; Get a sibling of this child
|
|
ConfigCalls_Label2:
|
|
cmp edi, esi ; did we just kill the first child
|
|
je ConfigCalls_Label6 ; yes: we are done with all the killings
|
|
xor eax, eax
|
|
push eax ; the flags
|
|
push esi ; the first child
|
|
lea eax, VnbtScratch ; this is where we will receive sibling
|
|
push eax
|
|
VxdCall _CONFIGMG_Get_Sibling
|
|
add esp, 12
|
|
mov edi, dword ptr [VnbtScratch] ;edi contains sibling
|
|
cmp eax, CR_SUCCESS ; found a sibling?
|
|
je ConfigCalls_Label4 ; yes, go kill it
|
|
cmp eax, CR_NO_SUCH_DEVNODE ; done with all siblings?
|
|
je ConfigCalls_Label3 ; yes, go kill the first child
|
|
mov ecx, 2 ; hmmm: something went wrong
|
|
jmp ConfigCalls_Exit
|
|
|
|
;;; Done with all the siblings: now kill the first child
|
|
ConfigCalls_Label3:
|
|
mov edi, esi ; esi=first child, edi=child to kill
|
|
|
|
ConfigCalls_Label4:
|
|
;;; Now, ask ConfigMgr if it's ok to kill our child
|
|
xor eax, eax
|
|
push eax ; the flags
|
|
push edi ; sibling's devnode
|
|
VxdCall _CONFIGMG_Query_Remove_SubTree
|
|
add esp, 8
|
|
cmp eax, CR_SUCCESS ; ok to kill?
|
|
je ConfigCalls_Label5 ; nope!
|
|
mov ecx, 4
|
|
jmp ConfigCalls_Exit
|
|
|
|
ConfigCalls_Label5:
|
|
;;; Now that ConfigMgr approved, kill the child
|
|
xor eax, eax
|
|
push eax ; the flags
|
|
push edi ; sibling's devnode
|
|
VxdCall _CONFIGMG_Remove_SubTree
|
|
add esp, 8
|
|
cmp eax, CR_SUCCESS ; did it die?
|
|
je ConfigCalls_Label2 ; yes, it did: go kill other siblings
|
|
mov ecx, 5 ; nope!
|
|
jmp ConfigCalls_Exit
|
|
|
|
ConfigCalls_Label6:
|
|
;;; Ok, reenumerate our devnode so our children come back to life
|
|
xor eax, eax
|
|
push eax ; the flags
|
|
mov eax, [ebp+8]
|
|
push eax ; our devnode
|
|
VxdCall _CONFIGMG_Reenumerate_DevNode
|
|
add esp, 8
|
|
cmp eax, CR_SUCCESS ; did it die?
|
|
je ConfigCalls_Label7 ; nope!
|
|
mov ecx, 6
|
|
jmp ConfigCalls_Exit
|
|
|
|
ConfigCalls_Label7:
|
|
xor eax, eax
|
|
|
|
ConfigCalls_Exit:
|
|
IFDEF DBG
|
|
or eax, eax
|
|
jz ConfigCalls_GoodJob
|
|
int 3
|
|
ConfigCalls_GoodJob:
|
|
ENDIF
|
|
pop ecx
|
|
pop edi
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
EndProc VNBT_ConfigCalls
|
|
|
|
ENDIF
|
|
|
|
NBT_PAGEABLE_CODE_ENDS
|
|
|
|
VxD_CODE_SEG
|
|
|
|
;****************************************************************************
|
|
;** _GetInDosFlag - Retrieves the InDos flag
|
|
;
|
|
;
|
|
; Note: This routine cannot be called at init time (vdosmgr complains
|
|
; the variable not initialized yet)
|
|
;
|
|
; Returns the flag in ax
|
|
;
|
|
|
|
BeginProc _GetInDosFlag
|
|
|
|
push ebx
|
|
|
|
VxdCall DOSMGR_Get_IndosPtr
|
|
|
|
;
|
|
; Add CB_High_Linear if we are in V86 mode
|
|
;
|
|
|
|
VMMcall Get_Cur_VM_Handle
|
|
|
|
test [ebx.CB_VM_Status], VMStat_PM_Exec
|
|
jnz GIF_Exit
|
|
|
|
add eax, [ebx.CB_High_Linear]
|
|
|
|
GIF_Exit:
|
|
movzx eax, word ptr [eax]
|
|
|
|
pop ebx
|
|
ret
|
|
EndProc _GetInDosFlag
|
|
|
|
;****************************************************************************
|
|
;
|
|
; ULONG
|
|
; RtlCompareMemory (
|
|
; IN PVOID Source1,
|
|
; IN PVOID Source2,
|
|
; IN ULONG Length
|
|
; )
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; This function compares two blocks of memory and returns the number
|
|
; of bytes that compared equal.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; Source1 (ebp+8) - Supplies a pointer to the first block of memory to
|
|
; compare.
|
|
;
|
|
; Source2 (ebp+12) - Supplies a pointer to the second block of memory to
|
|
; compare.
|
|
;
|
|
; Length (ebp+16) - Supplies the Length, in bytes, of the memory to be
|
|
; compared.
|
|
;
|
|
; Return Value:
|
|
;
|
|
; The number of bytes that compared equal is returned as the function
|
|
; value. If all bytes compared equal, then the length of the orginal
|
|
; block of memory is returned.
|
|
;
|
|
;--
|
|
|
|
RcmSource1 equ [ebp+8]
|
|
RcmSource2 equ [ebp+12]
|
|
RcmLength equ [ebp+16]
|
|
|
|
public _VxdRtlCompareMemory
|
|
BeginProc _VxdRtlCompareMemory
|
|
|
|
push ebp
|
|
mov ebp,esp
|
|
push esi
|
|
push edi
|
|
cld
|
|
|
|
mov esi,RcmSource1 ; (esi) -> first block to compare
|
|
mov edi,RcmSource2 ; (edi) -> second block to compare
|
|
mov ecx,RcmLength ; (ecx) = length in bytes
|
|
and ecx,3 ; (ecx) = length mod 4
|
|
jz rcm10 ; 0 odd bytes, go do dwords
|
|
|
|
;
|
|
; Compare "odd" bytes.
|
|
;
|
|
|
|
repe cmpsb ; compare odd bytes
|
|
jnz rcm40 ; mismatch, go report how far we got
|
|
|
|
;
|
|
; Compare dwords.
|
|
;
|
|
|
|
rcm10: mov ecx,RcmLength ; (ecx) = length in bytes
|
|
shr ecx,2 ; (ecx) = length in dwords
|
|
jz rcm20 ; no dwords, go exit
|
|
|
|
repe cmpsd ; compare dwords
|
|
jnz rcm30 ; mismatch, go find byte
|
|
|
|
;
|
|
; When we come to rcm20, we matched all the way to the end. Esi
|
|
; points to the byte after the last byte in the block, so Esi - RcmSource1
|
|
; equals the number of bytes that matched
|
|
;
|
|
|
|
rcm20: sub esi,RcmSource1
|
|
mov eax,esi
|
|
pop edi
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
|
|
;
|
|
; When we come to rcm30, esi (and edi) points to the dword after the
|
|
; one which caused the mismatch. Back up 1 dword and find the byte.
|
|
; Since we know the dword didn't match, we can assume one byte won't.
|
|
;
|
|
|
|
rcm30: sub esi,4 ; back up
|
|
sub edi,4 ; back up
|
|
mov ecx,5 ; ensure that ecx doesn't count out
|
|
repe cmpsb ; find mismatch byte
|
|
|
|
;
|
|
; When we come to rcm40, esi points to the byte after the one that
|
|
; did not match, which is TWO after the last byte that did match.
|
|
;
|
|
|
|
rcm40: dec esi
|
|
sub esi,RcmSource1
|
|
mov eax,esi
|
|
pop edi
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
|
|
EndProc _VxdRtlCompareMemory
|
|
|
|
;****************************************************************************
|
|
;** VNBT_Api_Handler - handles all request from other vxd's, v86-mode apps
|
|
;
|
|
; This procedure does all the address translations, memory locking etc.
|
|
; and calls the C routine VxdApiWorker() to do the actual work
|
|
;
|
|
; Entry: EBX - VM handle
|
|
; (EBP) - Client reg structure
|
|
;
|
|
; Exit: 'NC' is success, 'CY' on failure
|
|
;
|
|
; Uses: All
|
|
;
|
|
; HISTORY:
|
|
; Koti 16-Jun-1994 Created (Modified from dhcp's version)
|
|
;
|
|
;********************************************************************
|
|
BeginProc VNBT_Api_Handler
|
|
|
|
|
|
push ebp
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
push edx
|
|
push ecx
|
|
|
|
;;; get function op code
|
|
|
|
movzx edi, [ebp.Client_CX]
|
|
|
|
;;;
|
|
;;; Convert the parameter buffer pointers from segmented to flat.
|
|
;;;
|
|
|
|
;;; first, the output buffer
|
|
|
|
movzx eax, [ebp.Client_BX]
|
|
push eax
|
|
movzx eax, [ebp.Client_ES]
|
|
push eax
|
|
push ebx
|
|
call __VxdMapSegmentOffsetToFlat
|
|
add esp, 12
|
|
|
|
cmp eax, 0FFFFFFFFh
|
|
je vnbt_Fault
|
|
|
|
;;;
|
|
;;; Lock the output buffer.
|
|
;;;
|
|
|
|
or eax, eax
|
|
jz vnbt_DontLock_OutBuf
|
|
|
|
movzx ecx, [ebp.Client_DI]
|
|
cCall __VxdLockBuffer, <eax, ecx>
|
|
|
|
or eax, eax
|
|
jz vnbt_Fault
|
|
|
|
vnbt_DontLock_OutBuf:
|
|
|
|
mov esi, eax
|
|
|
|
;;; now, convert and lock the input buffer
|
|
|
|
movzx eax, [ebp.Client_AX]
|
|
push eax
|
|
movzx eax, [ebp.Client_DX]
|
|
push eax
|
|
push ebx
|
|
call __VxdMapSegmentOffsetToFlat
|
|
add esp, 12
|
|
|
|
cmp eax, 0FFFFFFFFh
|
|
je vnbt_Fault
|
|
|
|
or eax, eax
|
|
jz vnbt_DontLock
|
|
|
|
movzx ebx, [ebp.Client_SI]
|
|
cCall __VxdLockBuffer, <eax, ebx> ; this preserves esi
|
|
|
|
or eax, eax
|
|
jz vnbt_Fault
|
|
|
|
vnbt_DontLock:
|
|
|
|
mov edx, eax
|
|
|
|
;;; call worker routine
|
|
;;; edi - opcode
|
|
;;; esi - OutBuffer pointer
|
|
;;; ecx - OutBuffer length
|
|
;;; edx - InBuffer pointer
|
|
;;; ebx - InBuffer length
|
|
|
|
;
|
|
; RLF 05/30/94 - __VxdLockBuffer destroys contents of cx - reload
|
|
;
|
|
|
|
push esi ; save OutBuffer addr
|
|
push edx ; save InBuffer addr
|
|
|
|
mov eax, 1 ; VxdApiWorker will trash input buffer
|
|
push eax
|
|
movzx ecx, [ebp.Client_DI]
|
|
movzx ebx, [ebp.Client_SI]
|
|
push ebx
|
|
push edx
|
|
push ecx
|
|
push esi
|
|
push edi
|
|
|
|
call _VxdApiWorker
|
|
add esp, 24
|
|
|
|
pop edx ; restore InBuffer addr
|
|
pop esi ; restore OutBuffer addr
|
|
|
|
mov [ebp.Client_AX], ax
|
|
|
|
;;;
|
|
;;; Unlock the parameter buffer.
|
|
;;;
|
|
|
|
or esi, esi
|
|
jz vnbt_DontUnLock_OutBuf
|
|
|
|
push edx ; save InBuffer addr
|
|
movzx ecx, [ebp.Client_DI]
|
|
cCall __VxdUnlockBuffer <esi, ecx>
|
|
pop edx ; restore InBuffer addr
|
|
vnbt_DontUnLock_OutBuf:
|
|
|
|
or edx, edx
|
|
jz vnbt_DontUnLock
|
|
|
|
movzx ebx, [ebp.Client_SI]
|
|
cCall __VxdUnlockBuffer <edx, ebx>
|
|
|
|
vnbt_DontUnLock:
|
|
|
|
vnbt_CommonExit:
|
|
|
|
;;; Restore stack fame
|
|
pop ecx
|
|
pop edx
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
pop ebp
|
|
ret
|
|
|
|
;;;
|
|
;;; Either failed to map a segmented pointer to flat or failed
|
|
;;; to lock the parameter buffer.
|
|
;;;
|
|
|
|
vnbt_Fault:
|
|
|
|
cmp eax, 0FFFFFFFFh
|
|
mov [ebp.Client_AX], ax
|
|
jmp vnbt_CommonExit
|
|
|
|
|
|
EndProc VNBT_Api_Handler
|
|
|
|
VxD_CODE_ENDS
|
|
END
|
|
|