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