home *** CD-ROM | disk | FTP | other *** search
- ; Netmgr.Asm written 1999 by Tobias Ernst.
- ;
- ; This file installs interrupt service handlers that are needed by the
- ; patched NetMgr executable and then spawns the patched Netmgr executable,
- ; and afterwards deinstalls the interrupt service handlers. The patched
- ; Netmgr executable is expected to have the name "netmgr.ovl" and reside
- ; in the same directory as the netmgr.com file that is assembled from
- ; netmgr.asm.
- ;
- ; This file is written for Borland TASM, but should also work with
- ; microsoft MASM and compatible assemblers, though I didn't test it.
- ; Assemble as follows:
- ;
- ; tasm netmgr.asm
- ; tlink netmgr /t
- ;
- ; If you use another linker, assure that a .COM file is generated, or
- ; convert the EXE file with EXE2BIN. It is important that the file is
- ; a .COM file!
-
- DGROUP group _TEXT, _DATA
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS: DGROUP, DS:DGROUP, SS:DGROUP
-
- org 0100h
- start: jmp main
-
-
- ; Symbolic contants for the interrupt vectors to use
-
- vector1 equ 04Bh
- vector2 equ 04Ch
- vector3 equ 04Dh
- vector4 equ 04Eh
-
-
- ; Interrupt Service Routine #1
- ; Function: - Get a two digit year number from [bp-10h] to AX
- ; - Convert AX to a "tm.tm_year" compatible year number, that
- ; is, the number of years that have passed since 1900.
- ; Purpose: This routine is called when reading in a message from the
- ; Hudson Message Base. HMB only has a two digit year field,
- ; so we have to interpret a two digit year number somehow.
- ; Here, we assume that a year number of 00..79 is in 20xx,
- ; while a year number of 80..99 is in 19xx. This makes HMB
- ; save until 12/31/2079.
- service1:
-
- mov ax, word ptr [bp-10h]
- cmp ax, 80d ; is ax >= 80
- jae twc2 ; if so -> 19xx
- add ax, 100d ; otherwise: 20xx, add 100 dec
- twc2: iret
-
-
- ; Interrupt Service Routines #2
- ; Function: Get a year number in tm.tm_year format from [si+0a],
- ; and push the modulo of the division of this number by 100
- ; to the stack.
- ; Notes: As an interrupt normally does not leave anything on the
- ; stack, this code looks a bit unconventional
- ; Purpose: This routine is called when writing a FTSC date stamp into
- ; a PKT file, or when creating a textual header represenatation
- ; (in boundes, forwards, etc) and prevents the 2 digit date
- ; field from spilling (without the modulo 100 operation, "100"
- ; would be written there in the year 2000 instead of 00).
-
- service2: mov cs:[tmpax],ax ;save AX
-
- pop ax ;get the return address from stack
- mov cs:[retadd1],ax
- pop ax
- mov cs:[retadd2],ax
- pop ax
- mov cs:[retadd3],ax
-
- mov ax, word ptr[si+0ah]
- push cx
- mov cl, 064h ; only pass the modulo 100 value
- idiv cl ; to sprintf
- pop cx
- mov al,ah
- xor ah,ah
- push ax
-
- push cs:[retadd3] ;Now jump back
- push cs:[retadd2]
- push cs:[retadd1]
- mov ax,cs:[tmpax]
- iret
-
- tmpax dw 0
- retadd1 dw 0
- retadd2 dw 0
- retadd3 dw 0
-
- ; Interrupt Service Routines #3
- ; Function: Get a year number in tm.tm_year format from [bx+0a],
- ; and push the modulo of the division of this number by 100
- ; to the stack.
- ; Notes: As an interrupt normally does not leave anything on the
- ; stack, this code looks a bit unconventional
- ; Purpose: This routine is called when writing a FTSC date stamp
- ; into a *.squish or *.msg base, and when writing a hudson
- ; time stamp. It prevents the 2 digit date field from spilling
- ; (without the modulo 100 operation, "100" would be written
- ; there in the year 2000 instead of 00).
-
- service3: mov cs:[tmp2ax],ax ;save AX
-
- pop ax ;get the return address from stack
- mov cs:[ret2add1],ax
- pop ax
- mov cs:[ret2add2],ax
- pop ax
- mov cs:[ret2add3],ax
-
- mov ax, word ptr[bx+0ah]
- push cx
- mov cl, 064h ; only pass the modulo 100 value
- idiv cl ; to sprintf
- pop cx
- mov al,ah
- xor ah,ah
- push ax
-
- push cs:[ret2add3] ;Now jump back
- push cs:[ret2add2]
- push cs:[ret2add1]
- mov ax,cs:[tmp2ax]
- iret
-
- tmp2ax dw 0
- ret2add1 dw 0
- ret2add2 dw 0
- ret2add3 dw 0
-
- ; Interrupt Service Routines #4
- ; Function: Get a year number in tm.tm_year format from [bx+0a],
- ; and push the modulo of the division of this number by 100
- ; to the stack.
- ; Notes: As an interrupt normally does not leave anything on the
- ; stack, this code looks a bit unconventional
- ; Purpose: This routine is called when writing a FTSC date stamp
- ; into a *.squish or *.msg base, and when writing a hudson
- ; time stamp. It prevents the 2 digit date field from spilling
- ; (without the modulo 100 operation, "100" would be written
- ; there in the year 2000 instead of 00).
-
- service4: mov cs:[tmp3ax],ax ;save AX
-
- pop ax ;get the return address from stack
- mov cs:[ret3add1],ax
- pop ax
- mov cs:[ret3add2],ax
- pop ax
- mov cs:[ret3add3],ax
-
- mov ax, word ptr[bx+0ah] ;get tm->tm_year
- add ax, 1900d ;convert to 4 digit year
- push ax
-
- push cs:[ret3add3] ;Now jump back
- push cs:[ret3add2]
- push cs:[ret3add1]
- mov ax,cs:[tmp3ax]
- iret
-
- tmp3ax dw 0
- ret3add1 dw 0
- ret3add2 dw 0
- ret3add3 dw 0
-
-
-
-
-
- ; The main program. These routines install the correct interrupt handlers,
- ; execute timed.ovl, and restore the original interrupt handlers. This code
- ; is fairly uninteresting.
-
- main:
- mov ax, cs ; set up the segment registers and stack
- mov ds, ax
- mov ss, ax
- mov es, ax
- mov ax, offset DGROUP:stack_high
- mov sp, ax
-
- ; free unneeded memory
- mov bx, offset DGROUP:highwater
- shr bx, 4
- inc bx
- mov ah, 4Ah
- int 21h
-
- ; store the old interrupt vectors
- mov ah, 35h
- mov al, vector1
- int 21h
- mov [oldofs1],bx
- mov [oldseg1],es
-
- mov ah, 35h
- mov al, vector2
- int 21h
- mov [oldofs2],bx
- mov [oldseg2],es
-
- mov ah, 35h
- mov al, vector3
- int 21h
- mov [oldofs3],bx
- mov [oldseg3],es
-
- mov ah, 35h
- mov al, vector4
- int 21h
- mov [oldofs4],bx
- mov [oldseg4],es
-
-
- ; set the new interrupt vectors
- mov ah,25h
- mov al, vector1
- mov dx, offset DGROUP:service1
- int 21h
-
- mov ah,25h
- mov al, vector2
- mov dx, offset DGROUP:service2
- int 21h
-
- mov ah,25h
- mov al, vector3
- mov dx, offset DGROUP:service3
- int 21h
-
- mov ah,25h
- mov al, vector4
- mov dx, offset DGROUP:service4
- int 21h
-
- ; prepare the call to stringops
- push ds
- mov ax, offset DGROUP:paramoff
- push ax
- push ds
- mov ax, offset DGROUP:paramseg
- push ax
- push ds
- mov ax, offset DGROUP:prognameoff
- push ax
- push ds
- mov ax, offset DGROUP:prognameseg
- push ax
-
- mov ah,062h ; get PSP
- int 21h
- push bx
- xor ax,ax
- push ax
-
- call _stringops ; fill in the various structures
- add sp, 014h
-
-
- mov ax, [paramseg] ; call the DOS EXEC function
- mov es, ax
- mov bx, [paramoff]
- mov dx, [prognameoff]
- mov ax, [prognameseg]
- mov ds, ax
- mov ax, 04B00h
- int 21h
-
- mov ax, cs ; restore the registers
- mov ds, ax
- mov ss, ax
- mov ax, offset DGROUP:stack_high
- mov sp, ax
-
-
- ; restore the interrupt vectors
- mov bx, ds
- mov ah, 25h
- mov al, vector1
- mov dx, [oldofs1]
- mov cx, [oldseg1]
- mov ds, cx
- int 21h
- mov ds, bx
-
- mov bx, ds
- mov ah, 25h
- mov al, vector2
- mov dx, [oldofs2]
- mov cx, [oldseg2]
- mov ds, cx
- int 21h
- mov ds, bx
-
- mov bx, ds
- mov ah, 25h
- mov al, vector3
- mov dx, [oldofs3]
- mov cx, [oldseg3]
- mov ds, cx
- int 21h
- mov ds, bx
-
- mov bx, ds
- mov ah, 25h
- mov al, vector4
- mov dx, [oldofs4]
- mov cx, [oldseg4]
- mov ds, cx
- int 21h
- mov ds, bx
-
-
- mov ah, 04dh ; query return code of the .OVL module
- int 21h
- mov ax, 04ch ; terminate program
- int 21h
-
-
- ; _stringops
- ; This function fills in the huge bunch of tables that is required for the
- ; DOS exec function. It looks a bit weired, because it has originally been
- ; created by a C compiler.
-
- _stringops proc near
- push bp
- mov bp,sp
- sub sp,12
- push si
- push di
-
-
- ; /* pass the command line on as is */
- les bx,dword ptr [bp+4]
- mov al,byte ptr es:[bx+128]
- mov byte ptr DGROUP:_cmdlin,al
- cmp byte ptr DGROUP:_cmdlin,126
- jle short @1@534
- mov byte ptr DGROUP:_cmdlin,126
- @1@534:
- xor si,si
- jmp short @1@618
- @1@562:
- les bx,dword ptr [bp+4]
- add bx,si
- mov al,byte ptr es:[bx+129]
- mov byte ptr DGROUP:_cmdlin[si+1],al
- inc si
- @1@618:
- mov al,byte ptr DGROUP:_cmdlin
- cbw
- cmp ax,si
- jg short @1@562
- mov byte ptr DGROUP:_cmdlin[si+1],13
-
- ; /* adjust the name of the file to be spawned in the env_block */
- les bx,dword ptr [bp+4]
- mov ax,word ptr es:[bx+44]
- mov word ptr [bp-2],ax
- mov word ptr [bp-4],0
- mov ax,word ptr [bp-2]
- mov dx,word ptr [bp-4]
- mov word ptr [bp-6],ax
- mov word ptr [bp-8],dx
- jmp short @1@702
- @1@674:
- inc word ptr [bp-8]
- @1@702:
- les bx,dword ptr [bp-8]
- cmp byte ptr es:[bx],1
- jne short @1@674
- les bx,dword ptr [bp-8]
- cmp byte ptr es:[bx+1],0
- jne short @1@674
-
- mov ax,word ptr [bp-6]
- mov dx,word ptr [bp-8]
- add dx,2
- mov word ptr [bp-10],ax
- mov word ptr [bp-12],dx
- mov word ptr [bp-6],ax
- mov word ptr [bp-8],dx
- jmp short @1@814
- @1@786:
- inc word ptr [bp-8]
- @1@814:
- les bx,dword ptr [bp-8]
- cmp byte ptr es:[bx],0
- jne short @1@786
- les bx,dword ptr [bp-8]
- mov byte ptr es:[bx-3],79
- les bx,dword ptr [bp-8]
- mov byte ptr es:[bx-2],86
- les bx,dword ptr [bp-8]
- mov byte ptr es:[bx-1],76
- ; /* fill in the parameter block */
- mov ax,word ptr [bp-2]
- mov word ptr DGROUP:_paramblock,ax
- mov word ptr DGROUP:_paramblock+2,offset DGROUP:_cmdlin
- mov word ptr DGROUP:_paramblock+4,ds
- mov word ptr DGROUP:_paramblock+6,offset DGROUP:_fcb2
- mov word ptr DGROUP:_paramblock+8,ds
- mov word ptr DGROUP:_paramblock+10,offset DGROUP:_fcb2
- mov word ptr DGROUP:_paramblock+12,ds
- les bx,dword ptr [bp+16]
- mov word ptr es:[bx],ds
- les bx,dword ptr [bp+20]
- mov word ptr es:[bx],offset DGROUP:_paramblock
- les bx,dword ptr [bp+8]
- mov ax,word ptr [bp-10]
- mov word ptr es:[bx],ax
- les bx,dword ptr [bp+12]
- mov ax,word ptr [bp-12]
- mov word ptr es:[bx],ax
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
- _stringops endp
-
-
- _TEXT ENDS
-
- _DATA SEGMENT WORD PUBLIC 'DATA'
-
-
- ; These variables store the old interrupt vectors
- oldseg1 dw ?
- oldofs1 dw ?
- oldseg2 dw ?
- oldofs2 dw ?
- oldseg3 dw ?
- oldofs3 dw ?
- oldseg4 dw ?
- oldofs4 dw ?
-
-
- ; These variables are used to exchange data between the main program
- ; and the _stringops subroutine
- paramoff dw 1
- paramseg dw 2
- prognameoff dw 3
- prognameseg dw 4
-
- ; We do need a little bit of stack for our own ...
- stack_low dw 128 dup (10)
- stack_high dw 0
-
-
- ; These structures are filled in and passed to the DOS EXEC function
- _cmdlin label byte
- db 128 dup (0)
- _paramblock label word
- db 16 dup (0)
- _fcb2 label word
- db 35 dup (0)
- _fcb1 label word
- db 35 dup (0)
-
- ; This variable marks the last address in the file, so that the rest
- ; of the memory can be freed.
- highwater db 0
-
- _DATA ENDS
-
- END start
-
-