Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

517 lines
12 KiB

page ,132
if 0
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
nw16.asm
Abstract:
This module contains the stub redir TSR code for NT VDM net support
Author:
Richard L Firth (rfirth) 05-Sep-1991
Colin Watson (colinw) 30-Jun-1993
Environment:
Dos mode only
Revision History:
05-Sep-1991 rfirth
Created
30-Jun-1993 colinw
ported to NetWare
--*/
endif
;
; DOS include files
;
.xlist
.xcref
include ..\..\..\..\public\sdk\inc\isvbop.inc ; NTVDM BOP mechanism
include dossym.inc ; includes MS-DOS version etc
include pdb.inc ; PSP defines
include syscall.inc ; AssignOper
include segorder.inc ; load order of 'redir' segments
include debugmac.inc ; debug display macros
include asmmacro.inc ; jumps which may be short or near
include messages.inc
include nwdos.inc ; NetWare structures and nwapi32 interface
.cref
.list
;
; Define externals in resident code and data
;
ResidentCodeStart
extrn Old21Handler:dword
extrn NwInt21:near
extrn hVDD:dword
extrn quick_jump_to_dos:byte
extrn for_dos_proper:byte
extrn chain_previous_int21:byte
extrn ConnectionIdTable:byte
extrn not_exclusive:byte
ResidentCodeEnd
InitStack segment stack para 'stack'
dw 256 dup (?)
InitStack ends
InitDataStart
bad_ver_msg db NLS_MSG_001,c_CR,c_LF
BAD_VER_MSG_LEN equ $-bad_ver_msg
db '$' ; for INT 21/09 display string
already_loaded_msg db NLS_MSG_004,c_CR,c_LF
ALREADY_LOADED_MSG_LEN equ $-already_loaded_msg
cannot_load_msg db NLS_MSG_005,c_CR, c_LF
CANNOT_LOAD_MSG_LEN equ $-cannot_load_msg
InitDataEnd
InitCodeStart
assume cs:InitCode
assume ds:nothing
assume es:nothing
assume ss:nothing
public DllName
DllName db "NWAPI16.DLL",0
public InitFunc
InitFunc db "Nw16Register",0
public DispFunc
DispFunc db "Nw16Handler",0
public start
start proc near
;
; when we start up we could be on any old PC - even an original, so don't
; assume anything other than a model-T processor
;
.8086
;
; Set the data segment while we're at it - all paths set it sooner
; or later. NOTE: es will point to the PSP until we change it!
;
mov dx,InitData
mov ds,dx
assume ds:InitData
;
; first off, get the DOS version. If we're not running on NT (VDM) then this
; TSR's not going to do much, so exit. Exit using various methods, depending
; on the DOS version (don't you hate compatibility?)
;
mov ah,30h
int 21h
jc ancient_version ; version not even supported
;
; version is 2.0 or higher. Check it out. al = major#, ah = minor#
;
cmp al,major_version
jne invalid_version
;
; what do you know? We're actually running on NT (unless some evil programmer
; has pinched int 21h/30h and broken it!). Enable minimum instruction set
; for NTVDM (286 on RISC).
;
.286c
;
; perform an installation check by calling one of our entry points
; (GetFileServerNameTable). If this returns a table pointer in ES:DI then we
; know this TSR is already active, in which case we bail out now
;
push es
push di
xor di,di
mov es,di
mov ax,0ef03h
int 21h
mov ax,es
or ax,di
pop di
pop es
jnz already_here
;
; OK, the NetWare redir is not already loaded - we're in business.
; Find entrypoints to nwapi16.dll Get and set the various interrupt
; vectors, Calculate the amount of space we want to keep,
; free up any unused space (like the environment segment), display a message
; in the DEBUG version, then terminate and stay resident. Remember: at this
; point we expect ES to point at the PSP
;
call PullInDll
jc already_here ; failed to load
call InstallInterruptHandlers
assume es:nothing
push es
pop ds
call is_c_on_command_line
jz @f
mov dx,ResidentCode
mov ds,dx
assume ds:ResidentCode
mov not_exclusive, 1
assume ds:nothing
@@:
;
; free the environment segment
;
mov es,es:[PDB_environ]
mov ah,49h
int 21h ; free environment segment
;if DEBUG
;ifdef VERBOSE
; DbgPrintString <"NetWare Redir successfully loaded",13,10>
;endif
;endif
;
; finally terminate and stay resident
;
mov dx,ResidentEnd
sub dx,ResidentStart ; number of paragraphs in resident code
add dx,10h ; additional for PSP (PDB)
;if DEBUG
;ifdef VERBOSE
; DbgPrintString "Staying resident with "
; DbgPrintHexWord dx
; DbgPrintString " paragraphs. Load seg is ",NOBANNER
; mov ah,62h
; int 21h
; DbgPrintHexWord bx
; DbgPrintString " current seg is ",NOBANNER
; DbgPrintHexWord cs
; DbgCrLf
;endif
;endif
mov ax,3100h
int 21h ; terminate and stay resident
;
; here if the MS-DOS version check (Ah=30h) call is not supported
;
ancient_version:
mov dx,InitData
mov ds,dx
assume ds:InitData
mov dx,offset bad_ver_msg
mov ah,9 ; cp/m-style write to output
int 21h
;
; safe exit: what we really want to do here is INT 20H, but when you do this,
; CS must be the segment of the PSP of this program. Knowing that CD 20 is
; embedded at the start of the PSP, the most foolproof way of doing this is
; to jump (using far return) to the start of the PSP
;
push es
xor ax,ax
push ax
retf ; terminate
;
; we are running on a version of DOS >= 2.00, but its not NT, so we still can't
; help. Display the familiar message and exit, but using a less programmer-
; hostile mechanism
;
invalid_version:
mov dx,offset bad_ver_msg
mov cx,BAD_VER_MSG_LEN
jmps print_error_message_and_exit
;
; if we cannot initialize 32-bit support (because we can't find/load the DLL)
; then put back the hooked interrupt vectors as they were when this TSR started,
; display a message and fail to load the redir TSR
;
initialization_error:
call RestoreInterruptHandlers
mov dx,offset cannot_load_msg
mov cx,CANNOT_LOAD_MSG_LEN
jmps print_error_message_and_exit
;
; The DOS version's OK, but this TSR is already loaded
;
already_here:
mov dx,offset already_loaded_msg
mov cx,ALREADY_LOADED_MSG_LEN
print_error_message_and_exit:
mov bx,1 ; bx = stdout handle
mov ah,40h ; write to handle
int 21h ; write (cx) bytes @ (ds:dx) to stdout
mov ax,4c01h ; terminate program
int 21h ; au revoir, cruel environment
start endp
;*******************************************************************************
;*
;* InstallInterruptHandlers
;*
;* Sets the interrupt handlers for all the ints we use - 21
;*
;* ENTRY es = PSP segment
;* ds =
;*
;* EXIT Old21Handler contains the original interrupt 21 vector
;*
;* RETURNS nothing
;*
;* ASSUMES
;*
;*******************************************************************************
InstallInterruptHandlers proc
push es ; PSP segment - destroyed by INT 21/35h
push ds
;
; note: if we use ResidentCode here, explicitly, instead of seg OldMultHandler,
; then we can leave out an extraneous load of ds for the ISR address
;
mov dx,ResidentCode
mov ds,dx
assume ds:ResidentCode
;
; Add ourselves to the int 21 chain
;
mov ax,3521h
int 21h
mov word ptr Old21Handler,bx
mov word ptr Old21Handler+2,es
mov word ptr quick_jump_to_dos+1,bx
mov word ptr quick_jump_to_dos+3,es
mov word ptr for_dos_proper+1,bx
mov word ptr for_dos_proper+3,es
mov word ptr chain_previous_int21+1,bx
mov word ptr chain_previous_int21+3,es
mov dx,offset ResidentCode:NwInt21
mov ax,2521h
int 21h
pop ds ; restore segment registers
pop es
ret
InstallInterruptHandlers endp
;*******************************************************************************
;*
;* RestoreInterruptHandlers
;*
;* Resets the interrupt handlers for all the ints we use - 21
;*
;* ENTRY Old21Handler
;* contain the interrupt vectors from before nw16.sys was loaded
;*
;* EXIT Original interrupt vectors are restored
;*
;* RETURNS nothing
;*
;* ASSUMES
;*
;*******************************************************************************
RestoreInterruptHandlers proc
push ds
assume ds:nothing
push es
mov dx,ResidentCode
mov es,dx
assume es:ResidentCode
lds dx,Old21Handler
mov ax,2521h
int 21h
pop es
pop ds
ret
RestoreInterruptHandlers endp
;*******************************************************************************
;*
;* PullInDll
;*
;* Does a RegisterModule to load NWAPI32.DLL into our NTVDM.EXE
;*
;* ENTRY nothing
;*
;* EXIT nothing
;*
;* RETURNS cf if fails.
;*
;* ASSUMES Earth moves round Sun
;*
;******************************************************************************/
PullInDll proc near
pusha ; dispatch code
push dx ; save callers dx,ds,es,ax
push ds
push es
push ax
mov dx,InitCode
mov ds,dx
assume ds:InitCode
push ds
pop es
assume es:InitCode
mov si,offset DllName ; ds:si = nwapi32.dll
mov di,offset InitFunc ; es:di = init routine
mov bx,offset DispFunc ; ds:bx = dispatch routine
mov ax,ResidentCode
mov dx,offset ConnectionIdTable
; ax:dx = shared datastructure
RegisterModule
jc @f
mov dx,ResidentCode
mov ds,dx
assume ds:ResidentCode
mov word ptr hVDD,ax
@@: pop ax ; callers ax
pop es ; callers es
pop ds ; callers ds
pop dx ; callers dx
assume ds:nothing
assume es:nothing
popa ; dispatch code
ret
PullInDll endp
;*******************************************************************************
;*
;* is_c_on_command_line
;*
;* -C or /C means we should open compatiblity mode createfiles as shared
;* instead of exclusive
;*
;* ENTRY ds points to PDB
;*
;* EXIT nothing
;*
;* RETURNS zero if not found.
;*
;* ASSUMES ds points at PSP
;*
;******************************************************************************/
is_c_on_command_line proc near
mov si,80h
lodsb
cbw
mov cx,ax
next: jcxz quit
dec cx
lodsb
check_next:
cmp al,'-'
je check_c
cmp al,'/'
je check_c
cmp al,' '
je next
cmp al,9
je next
find_ws:jcxz quit
dec cx
lodsb
cmp al,' '
je next
cmp al,9
je next
jmp short find_ws
check_c:jcxz quit
dec cx
lodsb
or al,20h
cmp al,'c'
jne find_ws
or cx,ax
quit: or cx,cx
ret
is_c_on_command_line endp
InitCodeEnd
end start