home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
packetdrivers.tar.gz
/
pd.tar
/
src
/
vpkt.asm
< prev
next >
Wrap
Assembly Source File
|
1992-02-10
|
15KB
|
650 lines
include defs.asm
; Copyright, 1988-9, 1990, Russell Nelson
; Copyright, 1991, Roger F. James
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, version 1.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
code segment word public
assume cs:code, ds:code
org 2ch
phd_environ dw ?
org 80h
phd_dioa label byte
org 100h
start:
jmp start_1
even
;Debugging stuff
;total_pkts dw 0
;gvm_pkts dw 0
;bvm_pkts dw 0
npacket_int_no db ?,?,?,? ; interrupt to communicate.
per_handle struc
in_use db 0 ;non-zero if this handle is in use.
their_handle dw 0 ;lower layer handle
recv_handler dd 0 ;receiver upcall.
vm_id dw 0 ;VM_ID for this handler
per_handle ends
handles per_handle MAX_HANDLE dup(<>)
end_handles label byte
regs struc ; stack offsets of incoming regs
_ES dw ?
_DS dw ?
_BP dw ?
_DI dw ?
_SI dw ?
_DX dw ?
_CX dw ?
_BX dw ?
_AX dw ?
_IP dw ?
_CS dw ?
_F dw ? ; flags, Carry flag is bit 0
regs ends
CY equ 0001h
EI equ 0200h
bytes struc ; stack offsets of incoming regs
dw ? ; es, ds, bp, di, si are 16 bits
dw ?
dw ?
dw ?
dw ?
_DL db ?
_DH db ?
_CL db ?
_CH db ?
_BL db ?
_BH db ?
_AL db ?
_AH db ?
bytes ends
their_isr dd 0 ; original owner of pkt driver int
old_isr dd 0 ; old pkt driver int
their_2f_isr dd 0 ; original int 2f ISR
; The following are globals that assume that the code that access them
; single threads.
MAX_BUFFER_LEN equ 1520
our_buffer db MAX_BUFFER_LEN dup (0)
buffer_flag db 0
buffer_len dw 0
their_handler dd 0 ; Recv handler to call
their_bx dw 0
;
;
vmm_running db 0 ; The 386 virtual machine manager is
; running
our_handle dw 0 ; Current top level handle
our_isr:
jmp our_isr_0 ;the required signature.
db 'PKT DRVR',0
our_isr_0:
assume ds:nothing
cmp ah,2 ;Check if it one of the calls we
je our_isr_2 ;want to intercept.
cmp ah,3
je our_isr_2
cmp ah,5
je our_isr_2
cmp ah,8
je our_isr_2
our_isr_1:
jmp old_isr ;Just chain onto the original driver.
our_isr_2:
push ax ;We are interested in this one
push bx ;so save some registers and off we go.
push cx
push dx
push si
push di
push bp
push ds
push es
cld
mov bx,cs ;set up ds.
mov ds,bx
assume ds:code
mov bp,sp ;we use bp to access the original regs.
and _F[bp],not CY ;start by clearing the carry flag.
cmp ah,2 ;Jump to the function requested.
jne our_isr_3
jmp f_access_type
our_isr_3:
cmp ah,3
jne our_isr_4
jmp f_release_type
our_isr_4:
cmp ah,5
jne our_isr_5
jmp f_terminate
our_isr_5:
jmp f_stop ;Must be this one!
our_isr_error:
mov _DH[bp],dh
or _F[bp],CY ;return their carry flag.
our_isr_return:
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
our_2f_isr:
assume ds:nothing
cmp ax,1608h
jne our_2f_1
mov vmm_running,1 ;Windows has started.
jmp their_2f_isr ;Pass it on down the chain.
our_2f_1:
cmp ax,1609h
jne our_2f_2
mov vmm_running,0 ;Windows has stopped.
our_2f_2:
jmp their_2f_isr ;Pass it on down the chain.
our_handler:
cmp ax,1
je our_handler_2 ;Second upcall
;Must be first upcall
;So check if our buffer is free
cmp buffer_flag,1
je our_handler_1 ;Our buffer is busy
cmp cx,MAX_BUFFER_LEN
jg our_handler_1 ;Frame to big for our buffer
mov buffer_flag,1 ;Mark our buffer busy
mov buffer_len,cx ;Store frame length for later use
mov ax,cs
mov es,ax ;Segment of our buffer
mov di,offset our_buffer
retf
our_handler_1:
mov ax,0 ;Tell the driver we dont want the frame
mov es,ax
mov di,0
retf
our_handler_2: ;Second upcall
mov their_bx,bx ;Save their registers
mov dx,bx
mov bx,cs ;Get our data segment
mov ds,bx
assume ds:code
mov bx,offset handles
our_handler_3:
cmp [bx].their_handle,dx
je our_handler_4 ;Found their handle.
add bx,(size per_handle) ;go to the next handle.
cmp bx,offset end_handles ;examined all handles?
jb our_handler_3 ;no, continue.
;Fall through if we cannot find it.
mov buffer_flag,0 ;Mark our buffer free
retf
our_handler_4: ;Found the handle.
; inc total_pkts
mov ax,[bx].recv_handler.segm
mov their_handler.segm,ax
mov ax,[bx].recv_handler.offs
mov their_handler.offs,ax
push bx
mov ax,1683h ;Check current VM_ID
int 2fh
mov ax,bx
pop bx
cmp ax,[bx].vm_id
je our_handler_5 ;Correct VM is running
jmp our_handler_7 ;Wrong VM running so switch it
our_handler_5:
; inc gvm_pkts
call pass_to_app
retf
pass_to_app:
mov ax,0 ;Set up registers for first upcall
;to application
mov bx,their_bx
mov cx,buffer_len
push ds
call their_handler
pop ds
mov ax,es
cmp ax,0
jne pass_to_app_1
cmp di,0
jne pass_to_app_1
mov buffer_flag,0 ;They dont want the frame
ret
pass_to_app_1:
push di
mov cx,buffer_len
mov si,offset our_buffer
rep movsb ;Copy frame into apps buffer
mov ax,1 ;Set up regs for second upcall
mov bx,their_bx
mov cx,buffer_len
pop si
mov dx,es
push ds
mov ds,dx
assume ds:nothing
call their_handler
pop ds
assume ds:code
mov buffer_flag,0
ret
our_handler_7:
; inc bvm_pkts
mov ax,1685h ;Request switch VMs and callback
mov bx,[bx].vm_id
mov cx,0
mov dx,40h
mov si,0
push cs
pop es
mov di,offset our_callback
int 2fh
retf
assume ds:nothing
our_callback:
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp
mov ax,cs
mov ds,ax ;Set up our ds
assume ds:code
call pass_to_app
pop bp
pop es
pop ds
assume ds:nothing
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
assume ds:code
;register caller of pkt TYPE
f_access_type:
mov bx,offset handles
access_type_1:
cmp [bx].in_use,0 ;is this handle in use?
je access_type_2 ;found free one
add bx,(size per_handle) ;go to the next handle.
cmp bx,offset end_handles ;examined all handles?
jb access_type_1 ;no, continue.
jmp access_type_space ;no - return error.
access_type_2:
mov our_handle,bx ;save our handle
mov [bx].in_use,1 ;remember that we're using it.
cmp vmm_running,0 ;Is VMM running
je access_type_3 ;No, so dont bother to redirect
mov [bx].recv_handler.segm,es
mov [bx].recv_handler.offs,di
mov bx,cs
mov es,bx
mov di,offset our_handler
access_type_3:
push ds
mov bx,_DS[bp]
mov ds,bx
assume ds:nothing
mov bx,_BX[bp] ;restore callers registers
pushf
call old_isr
pop ds
assume ds:code
mov bx,our_handle
jnc access_type_4 ;it worked
mov [bx].in_use,0 ;it failed free our handle
jmp our_isr_error
access_type_4:
mov [bx].their_handle,ax
mov _AX[bp],ax ;save return handle
cmp vmm_running,0
je access_type_5 ;Dont bother if VMM not running
push bx
mov ax,1683h
int 2fh ;get current VM_ID
mov ax,bx
pop bx
mov [bx].vm_id,ax
access_type_5:
jmp our_isr_return
access_type_space:
mov dh,NO_SPACE
jmp our_isr_error
f_release_type:
mov bx,_BX[bp] ;restore callers registers
pushf
call old_isr
jnc release_type_1 ;it worked
jmp our_isr_error
release_type_1:
mov ax,_BX[bp] ;just in case
mov bx,offset handles
release_type_2:
cmp [bx].their_handle,ax ;compare handles
je release_type_3 ;found a match
add bx,(size per_handle) ;go to the next handle.
cmp bx,offset end_handles ;examined all handles?
jb release_type_2 ;no, continue.
jmp err_bad_handle ;no - return error.
release_type_3:
mov [bx].in_use,0
jmp our_isr_return
err_bad_handle:
mov dh,BAD_HANDLE
jmp our_isr_error
f_terminate:
mov bx,_BX[bp] ;restore callers registers
pushf
call old_isr
jnc terminate_1 ;it worked
jmp our_isr_error
terminate_1:
mov ax,_BX[bp] ;just in case
mov bx,offset handles
terminate_2:
cmp [bx].their_handle,ax ;compare handles
je terminate_3 ;found a match
add bx,(size per_handle) ;go to the next handle.
cmp bx,offset end_handles ;examined all handles?
jb terminate_2 ;no, continue.
jmp err_bad_handle ;no - return error.
terminate_3:
mov [bx].in_use,0 ; mark handle as free
mov bx,offset handles ; check that all handles are free
terminate_4:
cmp [bx].in_use,0 ; is this handle free?
jne terminate_5 ; ne = no, so can't exit completely
add bx,(size per_handle) ; next handle
cmp bx,offset end_handles ; examined all handles?
jb terminate_4 ; b = no, continue examination
mov al,npacket_int_no ;release our_isr.
mov ah,25h
push ds
lds dx,their_isr
int 21h
pop ds
mov al,2fh ;Restore 2f int
mov ah,25h ;Just hope nobody has
push ds ;chained on top of us.
lds dx,their_2f_isr
int 21h
pop ds
;
; Now free our memory
;
push cs
pop es
mov ah,49h
int 21h
jmp our_isr_return
terminate_5:
mov dh, CANT_TERMINATE
jmp our_isr_error
; Stop the packet driver doing upcalls. Also a following terminate will
; always succed (no in use handles any longer).
f_stop:
mov bx,_BX[bp] ;restore callers registers
pushf
call old_isr
mov bx,offset handles
f_stop_2:
mov [bx].in_use,0
add bx,(size per_handle) ; next handle
cmp bx,offset end_handles
jb f_stop_2
clc
ret
end_resident label byte
include printnum.asm
include decout.asm
include digout.asm
include chrout.asm
;usage_msg is of the form "usage: driver [-d -n] <packet_int_no> <args>"
usage_msg label byte
db "usage:vpkt <new_packet_int_no> <old_packet_int_no>",CR,LF,'$'
;copyright_msg is of the form:
;"Packet driver for the foobar",CR,LF
;"Portions Copyright 19xx, J. Random Hacker".
copyright_msg label byte
db "Virtual packet driver for Windows 3",CR,LF
db "Portions Copyright 1991 Roger F. James",CR,LF,'$'
copyleft_msg label byte
db "Packet driver skeleton copyright 1988-90, Russell Nelson.",CR,LF
db "This program is free software; see the file COPYING for details.",CR,LF
db "NO WARRANTY; see the file COPYING for details.",CR,LF
db CR,LF
crlf_msg db CR,LF,'$'
location_msg db "Packet driver is at segment ",'$'
packet_int_no db ?
opacket_int_no db ?,?,?,?
already_msg db CR,LF,"There is already a packet driver at ",'$'
not_found_msg db CR,LF,"There is no packet driver at ",'$'
new_int_msg db CR,LF,"Virtual packet driver installed on new interrupt ",'$'
old_int_msg db "Using old interrupt ",'$'
not_found_error:
mov dx,offset not_found_msg
mov di,offset opacket_int_no
call print_number
mov ax,4c05h
int 21h
already_error:
mov dx,offset already_msg
mov di,offset npacket_int_no
call print_number
mov ax,4c05h ; give errorlevel 5
int 21h
usage_error:
mov dx,offset usage_msg
error:
mov ah,9
int 21h
mov ax,4c0ah ; give errorlevel 10
int 21h
start_1:
cld
mov dx,offset copyright_msg
mov ah,9
int 21h
mov dx,offset copyleft_msg
mov ah,9
int 21h
mov si,offset phd_dioa+1
call skip_blanks ;end of line?
cmp al,CR
je usage_error
;print the location we were loaded at.
mov dx,offset location_msg
mov ah,9
int 21h
mov ax,cs ;print cs as a word.
call wordout
mov dx,offset crlf_msg
mov ah,9
int 21h
chk_options:
call skip_blanks
cmp al,'-' ; any options?
jne no_more_opt
usage_error_j_1:
jmp usage_error
no_more_opt:
mov di,offset npacket_int_no
call get_number
call skip_blanks
cmp al,CR
je usage_error
mov di,offset opacket_int_no
call get_number
call skip_blanks ;end of line?
cmp al,CR
jne usage_error
mov al,npacket_int_no
mov packet_int_no,al
call verify_packet_int
jnc packet_int_ok
jmp error
packet_int_ok:
jne packet_int_unused
jmp already_error ;give an error if there's one there.
packet_int_unused:
mov al,opacket_int_no
mov packet_int_no,al
call verify_packet_int
jnc packet_int_ok_1
jmp error
packet_int_ok_1:
je packet_int_used
jmp not_found_error
packet_int_used:
mov ah,35h ;remember their packet interrupt.
mov al,opacket_int_no
int 21h
mov old_isr.offs,bx
mov old_isr.segm,es
mov ah,35h ;remember their 2f interrupt.
mov al,2fh
int 21h
mov their_2f_isr.offs,bx
mov their_2f_isr.segm,es
mov ah,25h ;install our 2f interrupt
mov dx,offset our_2f_isr
int 21h
mov dx,offset new_int_msg
mov di,offset npacket_int_no
call print_number
mov dx,offset old_int_msg
mov di,offset opacket_int_no
call print_number
call take_packet_int
mov ah,49h ;free our environment, because
mov es,phd_environ ; we won't need it.
int 21h
mov bx,1 ;get the stdout handle.
mov ah,3eh ;close it in case they redirected it.
int 21h
mov dx, offset end_resident
add dx,0fh ;round up to next highest paragraph.
mov cl,4
shr dx,cl
mov ah,31h ;terminate, stay resident.
mov al,0
int 21h
take_packet_int:
mov ah,35h ;remember their packet interrupt.
mov al,npacket_int_no
int 21h
mov their_isr.offs,bx
mov their_isr.segm,es
mov ah,25h ;install our packet interrupt
mov dx,offset our_isr
int 21h
ret
include verifypi.asm
include getnum.asm
include getdig.asm
include skipblk.asm
include printea.asm
code ends
end start