home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PASCAL / TSRUTILS.ZIP / WATCH.ASM < prev    next >
Assembly Source File  |  1989-05-04  |  14KB  |  422 lines

  1. ;WATCH.ASM
  2. ;resident routine watches programs going resident
  3. ;and keeps a list of changes in interrupt vectors to an internal data structure
  4. ;==============================================================================
  5. ; written for MASM (version 4 or later) or TASM
  6. ; by Kim Kokkonen, TurboPower Software
  7. ; telephone: 408-438-8608, Compuserve 72457,2131
  8. ;==============================================================================
  9. ; VERSION 2.2  3/4/87
  10. ;   First release, version to be consistent with MAPMEM.PAS
  11. ; VERSION 2.3  5/1/87
  12. ;   Sets up a separate stack for the interrupt handlers
  13. ;     to solve problem first noticed with EMMCACHE and WATCH
  14. ;   Changes approach - store all vector information in RAM buffers
  15. ;   No disk access at all by WATCH
  16. ;   Better check for multiple installation
  17. ;   Changed to use MASM
  18. ; VERSION 2.4  5/17/87
  19. ;   for consistency with RELEASE
  20. ; VERSION 2.5  5/28/87
  21. ;   save flags in int21 handler
  22. ; VERSION 2.6  1/15/89
  23. ;   for consistency with MARK
  24. ; VERSION 2.7
  25. ;   skipped
  26. ; VERSION 2.8
  27. ;   for consistency with MARKNET/RELNET
  28. ; VERSION 2.9
  29. ;   for consistency with MARKNET/RELNET
  30.  
  31. Cseg      segment public para
  32.           assume  cs:Cseg, ds:nothing, es:nothing, ss:nothing
  33.  
  34.           org     080H
  35. cmdline   label   byte                 ;pointer to command line
  36.  
  37.           org     100H
  38. comentry: jmp     init
  39.  
  40. ;******************************************************************************
  41. ;resident data section follows
  42. ;******************************************************************************
  43.  
  44. ;put the following in the MAP file
  45. public bmesg,origv,prevv,vpos,vchg
  46.  
  47. ;resident data structures not part of COM file
  48. vchg           equ     220H            ;location of data area (>= offset bmesg)
  49. vrecsize       equ     8               ;number of bytes per vector change record
  50. vsize          equ     80H*vrecsize    ;size of vector change area in bytes
  51.                                        ;space for 128 changes of vector here
  52.  
  53. ;vector table buffers
  54. origv          equ     vchg+vsize      ;location of original vector table
  55. veclen         equ     400H            ;size of vector table in bytes
  56. prevv          equ     origv+veclen    ;location of current vector table
  57. newstackpos    equ     prevv+veclen    ;location of newstack
  58. ssize          equ     0080H           ;number of bytes in temporary stack
  59. newloc         equ     newstackpos+ssize ;location for relocated installation code
  60.  
  61.                even
  62. vpos           dw      0               ;next position to write in data area
  63.  
  64. ;temporary stack used by interrupt handler
  65. newss          dw      0               ;segment of our temporary stack
  66. newsp          dw      0               ;initial stack pointer
  67.  
  68. ;information saved about the calling program
  69. oldss          dw      ?               ;stack segment
  70. oldsp          dw      ?               ;stack pointer
  71. curpsp         dw      ?               ;program segment
  72.  
  73. ;id code for a PSP data block
  74. pspid          equ     0FFFFH          ;id used to indicate a PSP block
  75. ;int16H function call for id check
  76. getid          equ     'wa'            ;function code for int16
  77. chkid          equ     'WA'            ;returned by int16 getid check
  78.  
  79. ;previous interrupt handlers
  80. kbd_int        label dword
  81. old16          dw 2 dup (?)            ;old int16 vector
  82. dos_int        label dword
  83. old21          dw 2 dup (?)            ;old int21 vector
  84. tsr_int        label dword
  85. old27          dw 2 dup (?)            ;old int27 vector
  86.  
  87. ;***********************************************************************
  88. ;interrupt handler for int16
  89. ;used only to avoid reinstallation
  90. newint16 proc  near
  91.          assume ds:nothing
  92.          pushf                  ;save application flags
  93.          sti
  94.          cmp    ax,getid        ;see if our id function
  95.          jne    ex16            ;no, pass on to previous int16
  96.  
  97.          mov    ax,chkid        ;return id code
  98.          popf
  99.          iret                   ;back to caller
  100.  
  101. ex16:    popf
  102.          jmp    kbd_int         ;transfer control to the previous int16
  103. newint16 endp
  104.  
  105. ;***********************************************************************
  106. ;interrupt handler for int21
  107. newint21 proc  near
  108.          assume ds:nothing
  109.          pushf                  ;save flags
  110.          cmp    ah,31H
  111.          jne    ex21
  112.          call   checkvec        ;call routine to check vector table
  113. ex21:    popf
  114.          jmp    dos_int         ;transfer control to the previous int21 vector
  115. newint21 endp
  116.  
  117. ;***********************************************************************
  118. ;interrupt handler for int27
  119. newint27 proc  near
  120.          assume ds:nothing
  121.          call   checkvec
  122. ex27:    jmp    tsr_int         ;transfer control to the previous int27 vector
  123. newint27 endp
  124.  
  125. ;***********************************************************************
  126. ;procedure checkvec
  127. ;  compares vectors to previous installation
  128. ;  stores a new vector buffer
  129. ;  writes information to wfile
  130.  
  131. checkvec proc  near
  132.        assume ds:nothing
  133.  
  134. ;save current stack
  135.        mov     oldss,ss
  136.        mov     oldsp,sp
  137.  
  138. ;switch to our stack
  139.        cli
  140.        mov     ss,newss
  141.        mov     sp,newsp
  142.        sti
  143.  
  144. ;store registers
  145.        push    ax
  146.        push    bx
  147.        push    cx
  148.        push    dx
  149.        push    si
  150.        push    di
  151.        push    ds
  152.        push    es
  153.  
  154. ;get DS set up as CS
  155.        mov     ax,cs
  156.        mov     ds,ax
  157.        assume  ds:cseg
  158.  
  159.        mov     ah,51H           ;get current PSP
  160.        pushf
  161.        call    dos_int          ;bx returns PSP
  162.  
  163.        call    vechdr           ;store the PSP segment of the program going resident
  164.        call    cmpvec           ;scan the vector table looking for changes from our buffer
  165.        mov     di,prevv         ;save the new version of the vector table
  166.        call    savevec
  167.  
  168. ;restore registers
  169.        pop     es
  170.        pop     ds
  171.        assume  ds:nothing
  172.        pop     di
  173.        pop     si
  174.        pop     dx
  175.        pop     cx
  176.        pop     bx
  177.        pop     ax
  178.  
  179. ;restore stack
  180.        cli
  181.        mov     ss,oldss
  182.        mov     sp,oldsp
  183.        sti
  184.  
  185.        ret
  186. checkvec endp
  187.  
  188. ;**************************************************************************
  189. ;procedure vechdr
  190. ;  writes a header to the vector data area for this new TSR
  191. ;  on entry:
  192. ;    bx has PSP of the new TSR
  193. ;
  194. vechdr proc near
  195.        assume ds:cseg
  196.        cmp      vpos,vsize-vrecsize       ;assure room for next record
  197.        ja       vecex                     ;ignore if no room
  198.  
  199.        push     di
  200.        mov      di,vpos                   ;index into vchg array
  201.        mov      word ptr [di+vchg],pspid  ;store id word
  202.        mov      word ptr [di+vchg+2],bx   ;store PSP value
  203.                                           ;two words in record left unitialized
  204.        add      vpos,vrecsize             ;move to next data element
  205.        pop      di
  206.  
  207. vecex: ret
  208. vechdr endp
  209.  
  210. ;**************************************************************************
  211. ;procedure wrchg
  212. ;  writes information about changed vectors to the data area
  213. ;  on entry
  214. ;    ax has changed vector number
  215. ;    ds points to segment 0
  216. ;  on exit:
  217. ;    flags changed
  218. ;
  219. wrchg  proc     near
  220.        assume   ds:nothing, es:nothing
  221.        cmp      vpos,vsize-vrecsize ;assure room for next record
  222.        ja       wrcex
  223.  
  224.        push     ax
  225.        push     si
  226.        push     di
  227.  
  228.        mov      di,vpos             ;index into vchg array
  229.        mov      cs:[di+vchg],ax     ;store interrupt vector number
  230.  
  231.        mov      si,ax
  232.        shl      si,1
  233.        shl      si,1                ;get address of vector
  234.        mov      ax,[si]             ;get offset of vector
  235.        mov      cs:[di+vchg+2],ax   ;store vector offset
  236.        mov      ax,[si+2]           ;get segment
  237.        mov      cs:[di+vchg+4],ax   ;store segment
  238.                                     ;one word in record left unused
  239.        add      vpos,vrecsize       ;move to next data element
  240.  
  241.        pop      di
  242.        pop      si
  243.        pop      ax
  244.  
  245. wrcex: ret
  246. wrchg  endp
  247.  
  248. ;**************************************************************************
  249. ;procedure cmpvec
  250. ;  compares vectors in buffer to those in use
  251. ;  writes numbers of those different to data area
  252. ;  on exit:
  253. ;    ax,si,di destroyed
  254. ;    flags changed
  255. ;
  256. cmpvec  proc   near
  257.         assume ds:nothing, es:nothing
  258.         push    ds
  259.         push    es
  260.  
  261.         xor     si,si           ;source offset 0
  262.         mov     ds,si           ;source address segment 0
  263.         mov     ax,cs
  264.         mov     es,ax
  265.         xor     ax,ax           ;vector counter
  266.         mov     di,prevv        ;destination offset
  267.         cld                     ;upward direction
  268.  
  269. nexvec: cmpsw                   ;compare offsets
  270.         je      cmpseg          ;compare segments if offsets equal
  271.         call    wrchg           ;write changed vector
  272.         cmpsw                   ;compare next word, ignore result
  273.         jmp short vecinc
  274.  
  275. cmpseg: cmpsw                   ;compare segments
  276.         je      vecinc
  277.         call    wrchg           ;write changed vector
  278.  
  279. vecinc: inc     ax              ;next vector number
  280.         cmp     ax,00FFH
  281.         jbe     nexvec          ;continue until 256 vectors checked
  282.  
  283.         pop     es
  284.         pop     ds
  285.         ret
  286. cmpvec  endp
  287.  
  288. ;**************************************************************************
  289. ;procedure savevec
  290. ;  saves image of interrupt vectors
  291. ;  on entry:
  292. ;    di has destination offset
  293. ;  on exit:
  294. ;    ax,cx,si,di destroyed
  295. ;    flags changed
  296. ;
  297. savevec proc   near
  298.         assume ds:nothing, es:nothing
  299.         push    ds
  300.         push    es
  301.         xor     si,si           ;offset 0
  302.         mov     ds,si           ;source address segment 0
  303.         mov     ax,cs
  304.         mov     es,ax           ;destination always in this code segment
  305.         mov     cx,200H         ;512 integers to store
  306.         cld                     ;copy up
  307.         rep     movsw           ;copy vectors to our table
  308.         pop     es
  309.         pop     ds
  310.         ret
  311. savevec endp                    ;of proc savevec
  312.  
  313.  
  314. ;**************************************************************************
  315. ;resident portion above, temporary portion below
  316. ;**************************************************************************
  317.  
  318. ;temporary strings
  319.                even
  320. bmesg   db     13,10,'Cannot install WATCH more than once....',13,10,36
  321. mesg    db     13,10,'WATCH 2.9 successfully installed',13,10,36
  322. pname   db     'TSR WATCHER'
  323. plen    equ    $-pname             ;length of string
  324.  
  325. ;**************************************************************************
  326. ;install new handlers for DOS go-resident services
  327. init    proc   near
  328.         assume ds:cseg
  329.  
  330. ;use int 16h test to check for previous installation
  331.         mov     ax,getid        ;int16h diagnostic request
  332.         int     16h             ;now, ax=chkid if installed
  333.         cmp     ax,chkid        ;TSR already installed?
  334.         jne     success         ;no - jump if not installed
  335.  
  336. ;error exit
  337.         mov    dx,offset bmesg  ;error message
  338.         mov    ah,09H
  339.         int    21H              ;DOS print string
  340.         mov    ax,4C01H         ;exit with error
  341.         int    21H
  342.  
  343. ;print a success message
  344. success: mov    dx,offset mesg  ;start of message to write
  345.          mov    ah,09H
  346.          int    21H             ;DOS print string
  347.  
  348. ;relocate ourselves out of the way of the vector tables
  349.         mov     ax,cs
  350.         mov     es,ax
  351.         mov     di,newloc+10H
  352.         push    di                    ;will act as a return address
  353.         mov     si,offset newstk
  354.         mov     cx,lastcode-newstk
  355.         rep     movsb                 ;move code
  356.         ret                           ;"return" to the relocated code
  357.  
  358. ;initialize location of WATCH stack
  359. newstk: mov     newsp,newstackpos+ssize
  360.         mov     newss,cs        ;stack seg is code seg
  361.  
  362. ;get int 16H vector
  363.         mov    ax,3516H         ;GetVector DOS function call
  364.         int    21H
  365.         mov    old16,bx         ;store first word of old21
  366.         mov    old16[2],es      ;store second word
  367.  
  368. ;get int 21H vector
  369.         mov    ax,3521H         ;GetVector DOS function call
  370.         int    21H
  371.         mov    old21,bx         ;store first word of old21
  372.         mov    old21[2],es      ;store second word
  373.  
  374. ;get int 27H vector
  375.         mov    ax,3527H         ;GetVector DOS function call
  376.         int    21H
  377.         mov    old27,bx         ;store first word of old27 (offset)
  378.         mov    old27[2],es      ;store second word (segment)
  379.  
  380. ;put an id label at offset 80H to allow other programs to recognize WATCH
  381.         mov    ax,cs
  382.         mov    es,ax
  383.         mov    cx,plen          ;length of name string
  384.         mov    si,offset pname  ;offset of name string
  385.         mov    di,offset cmdline ;offset of DOS command line
  386.         cld                     ;transfer in forward direction
  387.         mov    al,cl
  388.         stosb                   ;store length byte first
  389.         rep    movsb            ;transfer characters
  390.  
  391. ;store image of original vector table (overwrites messages)
  392.         mov    di,origv
  393.         mov    ax,offset savevec
  394.         call   ax               ;absolute call works as code is moved
  395.  
  396. ;store it again into the current vector table
  397.         mov    di,prevv
  398.         mov    ax,offset savevec
  399.         call   ax               ;absolute call works as code is moved
  400.  
  401. ;install the new vectors
  402.         mov    ax,2516H
  403.         mov    dx,offset newint16
  404.         int    21H
  405.         mov    ax,2521H
  406.         mov    dx,offset newint21
  407.         int    21H
  408.         mov    ax,2527H
  409.         mov    dx,offset newint27
  410.         int    21H
  411.  
  412. ;terminate and stay resident
  413.         mov    dx,(newloc+15) shr 4
  414.         mov    ax,3100H        ;return success code
  415.         int    21H
  416.  
  417. lastcode:
  418. init    endp
  419.  
  420. Cseg    ends
  421.         end     ComEntry
  422.