home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / ARTFIX09.ZIP / NETMGR / NETMGR.ASM < prev    next >
Assembly Source File  |  2000-01-01  |  16KB  |  518 lines

  1. ; Netmgr.Asm written 1999 by Tobias Ernst.
  2. ;
  3. ; This file installs interrupt service handlers that are needed by the
  4. ; patched NetMgr executable and then spawns the patched Netmgr executable,
  5. ; and afterwards deinstalls the interrupt service handlers. The patched
  6. ; Netmgr executable is expected to have the name "netmgr.ovl" and reside
  7. ; in the same directory as the netmgr.com file that is assembled from
  8. ; netmgr.asm.
  9. ;
  10. ; This file is written for Borland TASM, but should also work with
  11. ; microsoft MASM and compatible assemblers, though I didn't test it.
  12. ; Assemble as follows:
  13. ;
  14. ; tasm netmgr.asm
  15. ; tlink netmgr /t
  16. ;
  17. ; If you use another linker, assure that a .COM file is generated, or
  18. ; convert the EXE file with EXE2BIN. It is important that the file is
  19. ; a .COM file!
  20.  
  21. DGROUP group  _TEXT, _DATA
  22.  
  23. _TEXT        SEGMENT BYTE PUBLIC 'CODE'
  24.         ASSUME CS: DGROUP, DS:DGROUP, SS:DGROUP
  25.  
  26. org             0100h
  27. start:          jmp main
  28.  
  29.  
  30. ; Symbolic contants for the interrupt vectors to use
  31.  
  32. vector1         equ 08Bh
  33. vector2         equ 08Ch
  34. vector3         equ 08Dh
  35. vector4         equ 08Eh
  36. vector5         equ 08Fh
  37.  
  38. ;  Interrupt Service Routine #1
  39. ;  Function: - Get a two digit year number from [bp-10h] to AX
  40. ;            - Convert AX to a "tm.tm_year" compatible year number, that
  41. ;              is, the number of years that have passed since 1900.
  42. ;  Purpose:  This routine is called when reading in a message from the
  43. ;            Hudson Message Base. HMB only has a two digit year field,
  44. ;            so we have to interpret a two digit year number somehow.
  45. ;            Here, we assume that a year number of 00..79 is in 20xx,
  46. ;            while a year number of 80..99 is in 19xx. This makes HMB
  47. ;            save until 12/31/2079.
  48. service1:
  49.  
  50.        mov ax, word ptr [bp-10h]
  51.        cmp ax, 80d    ; is ax >= 80
  52.        jae twc2       ; if so ->   19xx
  53.        add ax, 100d   ; otherwise: 20xx, add 100 dec
  54. twc2:  iret
  55.  
  56.  
  57. ;  Interrupt Service Routines #2
  58. ;  Function:  Get a year number in tm.tm_year format from [si+0a],
  59. ;             and push the modulo of the division of this number by 100
  60. ;             to the stack.
  61. ;  Notes:     As an interrupt normally does not leave anything on the
  62. ;             stack, this code looks a bit unconventional
  63. ;  Purpose:   This routine is called when writing a FTSC date stamp into
  64. ;             a PKT file, or when creating a textual header represenatation
  65. ;             (in boundes, forwards, etc) and prevents the 2 digit date
  66. ;             field from spilling  (without the modulo 100 operation, "100"
  67. ;             would be written there in the year 2000 instead of 00).
  68.  
  69. service2:       mov cs:[tmpax],ax      ;save AX
  70.  
  71.                 pop ax                 ;get the return address from stack
  72.                 mov cs:[retadd1],ax
  73.                 pop ax
  74.                 mov cs:[retadd2],ax
  75.                 pop ax
  76.                 mov cs:[retadd3],ax
  77.  
  78.                 mov ax, word ptr[si+0ah]
  79.                 push cx
  80.                 mov cl, 064h          ; only pass the modulo 100 value
  81.                 idiv cl               ; to sprintf
  82.                 pop cx
  83.                 mov al,ah
  84.                 xor ah,ah
  85.                 push ax
  86.  
  87.                 push cs:[retadd3]      ;Now jump back
  88.                 push cs:[retadd2]
  89.                 push cs:[retadd1]
  90.                 mov ax,cs:[tmpax]
  91.                 iret
  92.  
  93. tmpax           dw 0
  94. retadd1         dw 0
  95. retadd2         dw 0
  96. retadd3         dw 0
  97.  
  98. ;  Interrupt Service Routines #3
  99. ;  Function:  Get a year number in tm.tm_year format from [bx+0a],
  100. ;             and push the modulo of the division of this number by 100
  101. ;             to the stack.
  102. ;  Notes:     As an interrupt normally does not leave anything on the
  103. ;             stack, this code looks a bit unconventional
  104. ;  Purpose:   This routine is called when writing a FTSC date stamp
  105. ;             into a *.squish or *.msg base, and when writing a hudson
  106. ;             time stamp. It prevents the 2 digit date field from spilling
  107. ;             (without the modulo 100 operation, "100" would be written
  108. ;             there in the year 2000 instead of 00).
  109.  
  110. service3:       mov cs:[tmp2ax],ax      ;save AX
  111.  
  112.                 pop ax                 ;get the return address from stack
  113.                 mov cs:[ret2add1],ax
  114.                 pop ax
  115.                 mov cs:[ret2add2],ax
  116.                 pop ax
  117.                 mov cs:[ret2add3],ax
  118.  
  119.                 mov ax, word ptr[bx+0ah]
  120.                 push cx
  121.                 mov cl, 064h          ; only pass the modulo 100 value
  122.                 idiv cl               ; to sprintf
  123.                 pop cx
  124.                 mov al,ah
  125.                 xor ah,ah
  126.                 push ax
  127.  
  128.                 push cs:[ret2add3]      ;Now jump back
  129.                 push cs:[ret2add2]
  130.                 push cs:[ret2add1]
  131.                 mov ax,cs:[tmp2ax]
  132.                 iret
  133.  
  134. tmp2ax           dw 0
  135. ret2add1         dw 0
  136. ret2add2         dw 0
  137. ret2add3         dw 0
  138.  
  139. ;  Interrupt Service Routines #4
  140. ;  Function:  Get a year number in tm.tm_year format from [bx+0a],
  141. ;             and push the modulo of the division of this number by 100
  142. ;             to the stack.
  143. ;  Notes:     As an interrupt normally does not leave anything on the
  144. ;             stack, this code looks a bit unconventional
  145. ;  Purpose:   This routine is called when writing a FTSC date stamp
  146. ;             into a *.squish or *.msg base, and when writing a hudson
  147. ;             time stamp. It prevents the 2 digit date field from spilling
  148. ;             (without the modulo 100 operation, "100" would be written
  149. ;             there in the year 2000 instead of 00).
  150.  
  151. service4:       mov cs:[tmp3ax],ax       ;save AX
  152.  
  153.                 pop ax                   ;get the return address from stack
  154.                 mov cs:[ret3add1],ax
  155.                 pop ax
  156.                 mov cs:[ret3add2],ax
  157.                 pop ax
  158.                 mov cs:[ret3add3],ax
  159.  
  160.                 mov ax, word ptr[bx+0ah] ;get tm->tm_year
  161.                 add ax, 1900d            ;convert to 4 digit year
  162.                 push ax
  163.  
  164.                 push cs:[ret3add3]       ;Now jump back
  165.                 push cs:[ret3add2]
  166.                 push cs:[ret3add1]
  167.                 mov ax,cs:[tmp3ax]
  168.                 iret
  169.  
  170. tmp3ax           dw 0
  171. ret3add1         dw 0
  172. ret3add2         dw 0
  173. ret3add3         dw 0
  174.  
  175. ;  Interrupt Service Routines #5
  176. ;  Function:  Get a two digit year number from ax and convert it to a
  177. ;             FAT-style timestamp (years since 1980). Works until 2080.
  178. ;  Purpose:   This routine is called when Netmgr reads a message from a
  179. ;             *.MSG area and the Opus Written or Opus Arrived date are
  180. ;             not set (this is allowed behaviour, only the FTSC date
  181. ;             field is mandatory). In this case, Netmgr wants to derive
  182. ;             valid dates for the Opus date stamps from the FTSC date,
  183. ;             which only has the date in two digits. This previously failed
  184. ;             in 2000, because 00 - 80 < 0.
  185.  
  186. service5:       cmp ax, 80d
  187.                 jae rudolph
  188.                 add ax,20d
  189.                 iret
  190. rudolph:        sub ax, 80d   ; the red nosed reindeer
  191.                 iret
  192.  
  193.  
  194. ; The main program. These routines install the correct interrupt handlers,
  195. ; execute timed.ovl, and restore the original interrupt handlers. This code
  196. ; is fairly uninteresting.
  197.  
  198. main:
  199.                 mov ax, cs         ; set up the segment registers and stack
  200.                 mov ds, ax
  201.                 mov ss, ax
  202.                 mov es, ax
  203.                 mov ax, offset DGROUP:stack_high
  204.                 mov sp, ax
  205.  
  206.                                    ; free unneeded memory
  207.                 mov bx, offset DGROUP:highwater
  208.                 shr bx, 4
  209.                 inc bx
  210.                 mov ah, 4Ah
  211.                 int 21h
  212.  
  213.                                    ; store the old interrupt vectors
  214.                 mov ah, 35h
  215.                 mov al, vector1
  216.                 int 21h
  217.                 mov [oldofs1],bx
  218.                 mov [oldseg1],es
  219.  
  220.                 mov ah, 35h
  221.                 mov al, vector2
  222.                 int 21h
  223.                 mov [oldofs2],bx
  224.                 mov [oldseg2],es
  225.  
  226.                 mov ah, 35h
  227.                 mov al, vector3
  228.                 int 21h
  229.                 mov [oldofs3],bx
  230.                 mov [oldseg3],es
  231.  
  232.                 mov ah, 35h
  233.                 mov al, vector4
  234.                 int 21h
  235.                 mov [oldofs4],bx
  236.                 mov [oldseg4],es
  237.  
  238.                 mov ah, 35h
  239.                 mov al, vector5
  240.                 int 21h
  241.                 mov [oldofs5],bx
  242.                 mov [oldseg5],es
  243.  
  244.  
  245.  
  246.                                   ; set the new interrupt vectors
  247.                 mov ah,25h
  248.                 mov al, vector1
  249.                 mov dx, offset DGROUP:service1
  250.                 int 21h
  251.  
  252.                 mov ah,25h
  253.                 mov al, vector2
  254.                 mov dx, offset DGROUP:service2
  255.                 int 21h
  256.  
  257.                 mov ah,25h
  258.                 mov al, vector3
  259.                 mov dx, offset DGROUP:service3
  260.                 int 21h
  261.  
  262.                 mov ah,25h
  263.                 mov al, vector4
  264.                 mov dx, offset DGROUP:service4
  265.                 int 21h
  266.  
  267.                 mov ah,25h
  268.                 mov al, vector5
  269.                 mov dx, offset DGROUP:service5
  270.                 int 21h
  271.  
  272.  
  273.                                    ; prepare the call to stringops
  274.                 push ds
  275.                 mov ax, offset DGROUP:paramoff
  276.                 push ax
  277.                 push ds
  278.                 mov ax, offset DGROUP:paramseg
  279.                 push ax
  280.                 push ds
  281.                 mov ax, offset DGROUP:prognameoff
  282.                 push ax
  283.                 push ds
  284.                 mov ax, offset DGROUP:prognameseg
  285.                 push ax
  286.  
  287.                 mov ah,062h        ; get PSP
  288.                 int 21h
  289.                 push bx
  290.                 xor  ax,ax
  291.                 push ax
  292.  
  293.                 call _stringops    ; fill in the various structures
  294.                 add sp, 014h
  295.  
  296.  
  297.                 mov ax, [paramseg] ; call the DOS EXEC function
  298.                 mov es, ax
  299.                 mov bx, [paramoff]
  300.                 mov dx, [prognameoff]
  301.                 mov ax, [prognameseg]
  302.                 mov ds, ax
  303.                 mov ax, 04B00h
  304.                 int 21h
  305.  
  306.                 mov ax, cs         ; restore the registers
  307.                 mov ds, ax
  308.                 mov ss, ax
  309.                 mov ax, offset DGROUP:stack_high
  310.                 mov sp, ax
  311.  
  312.  
  313.                                         ; restore the interrupt vectors
  314.                 mov bx, ds
  315.                 mov ah, 25h
  316.                 mov al, vector1
  317.                 mov dx, [oldofs1]
  318.                 mov cx, [oldseg1]
  319.                 mov ds, cx
  320.                 int 21h
  321.                 mov ds, bx
  322.  
  323.                 mov bx, ds
  324.                 mov ah, 25h
  325.                 mov al, vector2
  326.                 mov dx, [oldofs2]
  327.                 mov cx, [oldseg2]
  328.                 mov ds, cx
  329.                 int 21h
  330.                 mov ds, bx
  331.  
  332.                 mov bx, ds
  333.                 mov ah, 25h
  334.                 mov al, vector3
  335.                 mov dx, [oldofs3]
  336.                 mov cx, [oldseg3]
  337.                 mov ds, cx
  338.                 int 21h
  339.                 mov ds, bx
  340.  
  341.                 mov bx, ds
  342.                 mov ah, 25h
  343.                 mov al, vector4
  344.                 mov dx, [oldofs4]
  345.                 mov cx, [oldseg4]
  346.                 mov ds, cx
  347.                 int 21h
  348.                 mov ds, bx
  349.  
  350.                 mov bx, ds
  351.                 mov ah, 25h
  352.                 mov al, vector5
  353.                 mov dx, [oldofs5]
  354.                 mov cx, [oldseg5]
  355.                 mov ds, cx
  356.                 int 21h
  357.                 mov ds, bx
  358.  
  359.  
  360.  
  361.                 mov ah, 04dh     ; query return code of the .OVL module
  362.                 int 21h
  363.                 mov ah, 04ch     ; terminate program
  364.                 int 21h
  365.  
  366.  
  367. ; _stringops
  368. ; This function fills in the huge bunch of tables that is required for the
  369. ; DOS exec function. It looks a bit weired, because it has originally been
  370. ; created by a C compiler.
  371.  
  372. _stringops    proc    near
  373.     push    bp
  374.     mov    bp,sp
  375.     sub    sp,12
  376.     push    si
  377.     push    di
  378.  
  379.  
  380.    ;        /* pass the command line on as is */
  381.     les    bx,dword ptr [bp+4]
  382.     mov    al,byte ptr es:[bx+128]
  383.     mov    byte ptr DGROUP:_cmdlin,al
  384.     cmp    byte ptr DGROUP:_cmdlin,126
  385.     jle    short @1@534
  386.     mov    byte ptr DGROUP:_cmdlin,126
  387. @1@534:
  388.     xor    si,si
  389.     jmp    short @1@618
  390. @1@562:
  391.     les    bx,dword ptr [bp+4]
  392.     add    bx,si
  393.     mov    al,byte ptr es:[bx+129]
  394.     mov    byte ptr DGROUP:_cmdlin[si+1],al
  395.     inc    si
  396. @1@618:
  397.     mov    al,byte ptr DGROUP:_cmdlin
  398.     cbw
  399.     cmp    ax,si
  400.     jg    short @1@562
  401.     mov    byte ptr DGROUP:_cmdlin[si+1],13
  402.  
  403.    ;        /* adjust the name of the file to be spawned in the env_block */
  404.     les    bx,dword ptr [bp+4]
  405.     mov    ax,word ptr es:[bx+44]
  406.     mov    word ptr [bp-2],ax
  407.     mov    word ptr [bp-4],0
  408.     mov    ax,word ptr [bp-2]
  409.     mov    dx,word ptr [bp-4]
  410.     mov    word ptr [bp-6],ax
  411.     mov    word ptr [bp-8],dx
  412.     jmp    short @1@702
  413. @1@674:
  414.     inc    word ptr [bp-8]
  415. @1@702:
  416.     les    bx,dword ptr [bp-8]
  417.     cmp    byte ptr es:[bx],1
  418.     jne    short @1@674
  419.     les    bx,dword ptr [bp-8]
  420.     cmp    byte ptr es:[bx+1],0
  421.     jne    short @1@674
  422.  
  423.     mov    ax,word ptr [bp-6]
  424.     mov    dx,word ptr [bp-8]
  425.     add    dx,2
  426.     mov    word ptr [bp-10],ax
  427.     mov    word ptr [bp-12],dx
  428.     mov    word ptr [bp-6],ax
  429.     mov    word ptr [bp-8],dx
  430.     jmp    short @1@814
  431. @1@786:
  432.     inc    word ptr [bp-8]
  433. @1@814:
  434.     les    bx,dword ptr [bp-8]
  435.     cmp    byte ptr es:[bx],0
  436.     jne    short @1@786
  437.     les    bx,dword ptr [bp-8]
  438.     mov    byte ptr es:[bx-3],79
  439.     les    bx,dword ptr [bp-8]
  440.     mov    byte ptr es:[bx-2],86
  441.     les    bx,dword ptr [bp-8]
  442.     mov    byte ptr es:[bx-1],76
  443.    ;        /* fill in the parameter block */
  444.     mov    ax,word ptr [bp-2]
  445.     mov    word ptr DGROUP:_paramblock,ax
  446.     mov    word ptr DGROUP:_paramblock+2,offset DGROUP:_cmdlin
  447.     mov    word ptr DGROUP:_paramblock+4,ds
  448.     mov    word ptr DGROUP:_paramblock+6,offset DGROUP:_fcb2
  449.     mov    word ptr DGROUP:_paramblock+8,ds
  450.     mov    word ptr DGROUP:_paramblock+10,offset DGROUP:_fcb2
  451.          mov    word ptr DGROUP:_paramblock+12,ds
  452.     les    bx,dword ptr [bp+16]
  453.     mov    word ptr es:[bx],ds
  454.     les    bx,dword ptr [bp+20]
  455.     mov    word ptr es:[bx],offset DGROUP:_paramblock
  456.     les    bx,dword ptr [bp+8]
  457.     mov    ax,word ptr [bp-10]
  458.     mov    word ptr es:[bx],ax
  459.     les    bx,dword ptr [bp+12]
  460.     mov    ax,word ptr [bp-12]
  461.     mov    word ptr es:[bx],ax
  462.     pop    di
  463.     pop    si
  464.     mov    sp,bp
  465.     pop    bp
  466.     ret
  467. _stringops    endp
  468.  
  469.  
  470. _TEXT ENDS
  471.  
  472. _DATA        SEGMENT WORD PUBLIC 'DATA'
  473.  
  474.  
  475. ; These variables store the old interrupt vectors
  476. oldseg1      dw ?
  477. oldofs1      dw ?
  478. oldseg2      dw ?
  479. oldofs2      dw ?
  480. oldseg3      dw ?
  481. oldofs3      dw ?
  482. oldseg4      dw ?
  483. oldofs4      dw ?
  484. oldseg5      dw ?
  485. oldofs5      dw ?
  486.  
  487.  
  488. ; These variables are used to exchange data between the main program
  489. ; and the _stringops subroutine
  490. paramoff    dw 1
  491. paramseg    dw 2
  492. prognameoff dw 3
  493. prognameseg dw 4
  494.  
  495. ; We do need a little bit of stack for our own ...
  496. stack_low       dw 128 dup (10)
  497. stack_high      dw 0
  498.  
  499.  
  500. ; These structures are filled in and passed to the DOS EXEC function
  501. _cmdlin    label    byte
  502.     db    128 dup (0)
  503. _paramblock    label    word
  504.     db    16 dup (0)
  505. _fcb2    label    word
  506.     db    35 dup (0)
  507. _fcb1    label    word
  508.     db    35 dup (0)
  509.  
  510. ; This variable marks the last address in the file, so that the rest
  511. ; of the memory can be freed.
  512. highwater db 0
  513.  
  514. _DATA ENDS
  515.  
  516. END start
  517.  
  518.