mirror of https://github.com/tongzx/nt5src
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
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
|