summaryrefslogtreecommitdiffstats
path: root/private/nw/nw16/tsr/nw16.asm
diff options
context:
space:
mode:
Diffstat (limited to 'private/nw/nw16/tsr/nw16.asm')
-rw-r--r--private/nw/nw16/tsr/nw16.asm517
1 files changed, 517 insertions, 0 deletions
diff --git a/private/nw/nw16/tsr/nw16.asm b/private/nw/nw16/tsr/nw16.asm
new file mode 100644
index 000000000..ac19beed8
--- /dev/null
+++ b/private/nw/nw16/tsr/nw16.asm
@@ -0,0 +1,517 @@
+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 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