home *** CD-ROM | disk | FTP | other *** search
/ Troubleshooting Netware Systems / CSTRIAL0196.BIN / attach / pcc / v08n03 / netwrk.exe / DOSRIFS.ZIP / RIFSSRC.ZIP / SVR0.ASM < prev    next >
Assembly Source File  |  1994-06-10  |  14KB  |  572 lines

  1. ;----------------------------------------------------------------------
  2. ;----------------------------------------------------------------------
  3. ;
  4. ; this is the server - specific assembly code. 
  5. ; some notes:
  6. ;   in thought i could interrupt DOS any time outside of a DOS
  7. ;   critical area (flagged through int 2a/80 2a/81 2a/82) by simply
  8. ;   swapping the SDA. surprise! i have used this technique many times
  9. ;   in the past, but it seems that if both a background and foreground
  10. ;   process are doing directory searches, they interfere with each
  11. ;   other. that's what some of the more bizarre looking checks
  12. ;   are all about.
  13. ;
  14. ;----------------------------------------------------------------------
  15. ;----------------------------------------------------------------------
  16.  
  17. SVR0_TEXT    segment    byte public 'CODE'
  18. DGROUP    group    _DATA,_BSS
  19.     assume    cs:SVR0_TEXT,ds:DGROUP
  20. SVR0_TEXT    ends
  21.  
  22. _DATA    segment word public 'DATA'
  23. d@    label    byte
  24. d@w    label    word
  25.  
  26. STK1LEN    equ    512             ; stack while servicing any
  27. stk1    db    STK1LEN dup (0)        ; interrupt
  28. stk1end    equ    $
  29. stk1sav    dd    0
  30.  
  31. userintno    db    ?        ; communications int #
  32.  
  33. _DATA    ends
  34.  
  35. _BSS    segment word public 'BSS'
  36. b@    label    byte
  37. b@w    label    word
  38. _BSS    ends
  39.  
  40. extrn   _ServerDispatch : far
  41. extrn    _UserInt    : far
  42. extrn   _background     : byte
  43. extrn    _SDA        : far ptr
  44. extrn   _SDA_DOSBUSY    : far ptr
  45. extrn    _lcl_SDA    : far ptr
  46. extrn    _CDS_base    : far ptr
  47. extrn    _lcl_CDS    : far ptr
  48. extrn    _SDA_maxsize    : word
  49. extrn    _SDA_minsize    : word
  50. extrn    _CDS_TotalSize    : word
  51. extrn    __Recieve    : far
  52.  
  53. public  _svr0_init
  54. public  _svr0_shutdown
  55. public    _svr0_GetSemaphores
  56. public  _svr0_SetDispatchFlag
  57. public  _svr0_ResetDispatchFlag
  58. public  _svr0_GetStackUsed
  59. public    _svr0_int1b
  60. public    _svr0_int23
  61. public    _svr0_int24
  62. public    _SwapDOS
  63.  
  64. SVR0_TEXT    segment    byte public 'CODE'
  65.  
  66. ;
  67. ; these are easiest to keep in the code segment. bad
  68. ; practice though :)
  69. ;
  70. semflag        db    0        ; BIOS semaphore flags
  71. doscrit        db    0        ; DOS critical flag
  72. callsvr        db    0        ; call server pending
  73.  
  74. ;
  75. ; swap two memory regious
  76. ;   es:di --> src 1
  77. ;   ds:si --> src 2
  78. ;   cx    =   length
  79. ; exit:
  80. ;   ax = ?
  81. ;   cx = 0
  82. ;   si/di are incremented [cx] bytes
  83. ;   all others unchanged
  84. ; notes:
  85. ;   i don't check that either di or si (or both) are at even addresses.
  86. ;   this routine slows considerably if that is not the case!
  87. ;
  88. swap        proc    near
  89.         pushf
  90.         cld            ; want increment on string cmds
  91.         shr    cx,1        ; cx /= 2 (holds # of words to move)
  92.         jz    @@m1        ; if zero, skip
  93.         pushf            ; save carry flag
  94. @@ms:
  95.         mov    bx,es:[di]    ; swap 1 word at a time
  96.         movsw
  97.         mov    [si-2],bx
  98.         loop    @@ms
  99.         popf            ; get carry back
  100. @@m1:
  101.         jnc    @@mr        ; skip on no carry
  102.         mov    ah,es:[di]    ; otherwise move odd byte
  103.         movsb
  104.         mov    [si-1],ah
  105. @@mr:
  106.         popf
  107.         ret
  108. swap        endp
  109.  
  110. _SwapDOS    proc    far
  111.         push    ax
  112.         push    cx
  113.         push    di
  114.         push    si
  115.         push    es
  116.         
  117.         push    ds            ; swap SDA
  118.         mov    cx,[_SDA_maxsize]
  119.         les    di,[_SDA]
  120.         lds    si,[_lcl_SDA]
  121.         call    swap
  122.         pop    ds
  123.  
  124.         push    ds            ; swap CDS
  125.         mov    cx,[_CDS_TotalSize]
  126.         les    di,[_CDS_base]
  127.         lds    si,[_lcl_CDS]
  128.         call    swap
  129.         pop    ds
  130.         pop    es
  131.         pop    si
  132.         pop    di
  133.         pop    cx
  134.         pop    ax
  135.         ret
  136. _SwapDOS    endp
  137.  
  138. ;----------------------------------------------------------------------
  139. ; test to see if the server needs to be called (or can be called)
  140. ; and do all of the necessary prep work.
  141. ;----------------------------------------------------------------------
  142. svrhere        db    0        ; local semaphore
  143. _svr0_TestCallSvr    proc    far
  144.         pushf            ; save things as i go along...
  145.         push    ds
  146.         push    bp
  147.  
  148.         mov    bp,DGROUP
  149.         mov    ds,bp
  150.         
  151.                 cmp     DGROUP:[_background],0    ; are we a background task?
  152.                 jz      @@__svr0a        ; no, skip!
  153.         
  154.         ;
  155.         ; everything from this test until we either
  156.         ; set the flag or exit must not be interrupted!
  157.         ;
  158.         cli
  159.         cmp    cs:[svrhere],0        ; are we here?
  160.         jnz    @@__svr0a        ; yes, exit!
  161.         
  162.         cmp     cs:[semflag], 0        ; any BIOS locks?
  163.         jnz    @@__svr0a        ; yes, exit!
  164.         
  165.         cmp    cs:[doscrit],0        ; DOS in critical area?
  166.         jnz    @@__svr0a        ; yes, exit!
  167.         
  168.         push    di            ; finally, check DOS busy
  169.         push    es
  170.         les    di,[_SDA_DOSBUSY]
  171.         cmp byte ptr es:[di],0        ; if DOS not busy, OK
  172.         jz    @@_svr0_OK
  173.         cmp byte ptr es:[di],1        ; if DOS ct > 1, BAD
  174.         jnz    @@_svr0_OK
  175.         cmp    [int28here],1        ; if DOS ct IS 1
  176.                         ;   and we're at int 28
  177.                         ;   OK!
  178. @@_svr0_OK:        
  179.         pop    es
  180.         pop    di
  181.         jz    @@__svr1        ; DOS not busy, continue
  182. @@__svr0a:    
  183.         jmp    @@TestCallSvrR
  184. @@__svr1:        
  185.         mov    cs:[svrhere],1        ; set semaphore
  186.                         ; save stack
  187.         mov word ptr DGROUP:[stk1sav],sp    
  188.         mov word ptr DGROUP:[stk1sav+2],ss
  189.  
  190.         cli                ; set local stack
  191.         mov    sp, offset stk1end
  192.         mov    bp,ds
  193.         mov    ss,bp
  194.         sti
  195.         
  196.         push    ax            ; save remaining regs
  197.         push    bx
  198.         push    cx
  199.         push    dx
  200.         push    di
  201.         push    si
  202.         push    es
  203.  
  204.         call    __Recieve        ; check for recieve
  205.         cmp    cs:[callsvr],0        ; ready to call server?
  206.         jz    @@__svr0_rcv        ; no, done!
  207.         
  208.         call    _SwapDOS
  209.         call    _ServerDispatch        ; dispatch command
  210.         call    _SwapDOS
  211. @@__svr0_rcv:
  212.         pop    es
  213.         pop    si
  214.         pop    di
  215.         pop    dx
  216.         pop    cx
  217.         pop    bx
  218.         pop    ax
  219.         
  220.         cli
  221.         mov    sp,word ptr DGROUP:[stk1sav]
  222.         mov    ss,word ptr DGROUP:[stk1sav+2]
  223.         sti
  224.         mov    cs:[svrhere],0        ; reset semaphore
  225. @@TestCallSvrR:
  226.         pop    bp
  227.         pop    ds
  228.         popf
  229.         ret
  230. _svr0_TestCallSvr endp
  231.  
  232. ;----------------------------------------------------------------------
  233. ; my int 9 control-break handler (ignore)
  234. ;----------------------------------------------------------------------
  235. _svr0_int1b    proc    far
  236.         iret
  237. _svr0_int1b    endp
  238.  
  239. ;----------------------------------------------------------------------
  240. ; here is my control-break handler (ignore)
  241. ;----------------------------------------------------------------------
  242. _svr0_int23    proc    far
  243.         iret
  244. _svr0_int23    endp
  245.  
  246. ;----------------------------------------------------------------------
  247. ; my critical error handler (always return FAIL)
  248. ;----------------------------------------------------------------------
  249. _svr0_int24    proc    far
  250.         mov    al,03h
  251.         iret
  252. _svr0_int24    endp
  253.  
  254. ;----------------------------------------------------------------------
  255. ; clock int
  256. ;   we could only be here if the server was called during the last
  257. ;   timer tick, but better safe than sorry.
  258. ;----------------------------------------------------------------------
  259. int08here    db    0
  260. oldint08    dd    0
  261. semint08    proc    far
  262.         pushf                ; emulate an INT 08
  263.         call    cs:[oldint08]
  264.         cli
  265.         cmp    cs:[int08here],0    ; check semaphore
  266.         jnz    @@semint08R        ; skip if here
  267.         inc    cs:[int08here]
  268.         call    _svr0_TestCallSvr    ; try me
  269.         dec    cs:[int08here]
  270. @@semint08R:        
  271.         iret                ; finished
  272. semint08    endp
  273.  
  274. ;----------------------------------------------------------------------
  275. ; don't interrupt a disk action
  276. ;----------------------------------------------------------------------
  277. oldint13    dd    0
  278. semint13    proc    far
  279.         inc    cs:[semflag]
  280.         pushf
  281.         call     cs:[oldint13]
  282.         pushf
  283.         dec    cs:[semflag]
  284.         jnz    @@__int13a
  285.         call    _svr0_TestCallSvr
  286. @@__int13a:        
  287.         popf
  288.         retf    2            ; pop old flags
  289. semint13    endp
  290.  
  291. ;----------------------------------------------------------------------
  292. ; forward call calls to DOS, then try calling test server
  293. ; this assures that if a call to the server could not be put through
  294. ;   due to DOS busy, it will be processed immediatly
  295. ;----------------------------------------------------------------------
  296. oldint21    dd    0
  297. semint21    proc    far
  298.         call    _svr0_TestCallSvr
  299.         jmp    cs:[oldint21]
  300. semint21    endp
  301.         
  302. ;----------------------------------------------------------------------
  303. ; if in INT 0x28, we can interrupt DOS if 0 <= SDA_DOSBUSY  <= 1
  304. ;----------------------------------------------------------------------
  305. int28here    db    0
  306. oldint28    dd    0
  307. semint28    proc    far
  308.         inc    cs:[int28here]
  309.         pushf
  310.         call    cs:[oldint28]
  311.         call    _svr0_TestCallSvr
  312.         dec    cs:[int28here]
  313.         iret
  314. semint28    endp
  315.         
  316. ;----------------------------------------------------------------------
  317. ; dos set critical interrupt
  318. ;----------------------------------------------------------------------
  319. oldint2a    dd    0
  320. semint2a    proc    far
  321.         pushf
  322.         cmp    ah,80h        ; entering DOS critical area?
  323.         jnz    @@sem1        ; no, skip
  324.         inc    cs:[doscrit]    ; else inc. counter
  325.         jmp     @@semrr
  326. @@sem1:        cmp    ah,81h        ; leaving DOS critical area?
  327.         jz    @@sem2
  328.         cmp    ah,82h
  329.         jnz    @@semrr        ; no, skip
  330. @@sem2:        
  331.         cmp    cs:[doscrit],0    ; counter at 0?
  332.         jz    @@semrdr    ; yes, no action
  333.         dec    cs:[doscrit]    ; else decrmentS
  334.         jnz    @@semrdr    ; if not zero, skip
  335.         call    _svr0_TestCallSvr    ; else test server
  336. @@semrdr:
  337. @@semrr:
  338.         popf
  339.         jmp    cs:[oldint2a]    ; chain
  340. semint2a    endp
  341.  
  342. ;----------------------------------------------------------------------
  343. ; void far svr0_init(unsigned itr)
  344. ;   initialize the various interrupts used in this section
  345. ;----------------------------------------------------------------------
  346. _svr0_init    proc    far
  347.         push    bp
  348.         mov    bp,sp
  349.         mov    ax,[bp+6]
  350.         mov    [userintno],al
  351.  
  352.         mov    ah,35h                ; get user int
  353.         int    21h
  354.         mov word ptr cs:[olduser], bx
  355.         mov word ptr cs:[olduser+2], es
  356.  
  357.                 cmp     [_background],0        ; if this is not to run in the
  358.                 jz      @@svr0_init0        ; background, we're done!
  359.                 
  360.         mov    al,[userintno]
  361.         mov    ah,25h
  362.         push    ds
  363.         push    cs
  364.         pop    ds
  365.         mov    dx,offset _svr0_user
  366.         int    21h
  367.         pop    ds
  368.  
  369.         push    ds
  370.         push    cs
  371.         pop    ds
  372.         assume    ds:SVR0_TEXT
  373.         
  374.         ;
  375.         ; grab timer int
  376.         ;
  377.         mov    ax,3508h
  378.         int    21h
  379.         mov word ptr [oldint08],bx
  380.         mov word ptr [oldint08+2],es
  381.         mov    dx,offset semint08
  382.         mov    ax,2508h
  383.         int    21h
  384.         
  385.         ;
  386.         ; grab disk i/o int
  387.         ;
  388.         mov    ax,3513h
  389.         int    21h
  390.         mov word ptr [oldint13],bx
  391.         mov word ptr [oldint13+2],es
  392.         mov    dx,offset semint13
  393.         mov    ax,2513h
  394.         int    21h
  395.  
  396.         ;
  397.         ; grab DOS call
  398.         ;
  399.         mov    ax,3521h
  400.         int    21h
  401.         mov word ptr [oldint21],bx
  402.         mov word ptr [oldint21+2],es
  403.         mov    dx,offset semint21
  404.         mov    ax,2521h
  405.         int    21h
  406.  
  407.         ;
  408.         ; grab DOS waiting
  409.         ;
  410.         mov    ax,3528h
  411.         int    21h
  412.         mov word ptr [oldint28],bx
  413.         mov word ptr [oldint28+2],es
  414.         mov    dx,offset semint28
  415.         mov    ax,2528h
  416.         int    21h
  417.         
  418.         ;
  419.         ; grab dos critical int
  420.         ;
  421.         mov    ax,352ah
  422.         int    21h
  423.         mov word ptr [oldint2a],bx
  424.         mov word ptr [oldint2a+2],es
  425.         mov    dx,offset semint2a
  426.         mov    ax,252ah
  427.         int    21h
  428.  
  429.         pop    ds
  430. @@svr0_init0:
  431.         pop    bp
  432.         ret
  433. _svr0_init    endp
  434.  
  435. ;----------------------------------------------------------------------
  436. ; void far svr0_shutdown(void)
  437. ;   reset everything to startup values. no checking is done
  438. ;   so if this is called before svr0_initialize the machine will
  439. ;   go balistic!
  440. ;----------------------------------------------------------------------
  441. _svr0_shutdown    proc    far
  442.         assume  ds:DGROUP
  443.                 cmp     [_background],0
  444.                 jz      @@svr0_shut0
  445.                 
  446.         mov    al,[userintno]
  447.         push    ds
  448.  
  449.         lds    dx,cs:[olduser]
  450.         mov    ah,25h
  451.         int    21h
  452.  
  453.                 pop     ds
  454.  
  455.                 push    ds
  456.                 lds    dx,cs:[oldint08]
  457.                 mov    ax,2508h
  458.                 int    21h
  459.                 
  460.         lds    dx,cs:[oldint13]
  461.         mov    ax,2513h
  462.         int    21h
  463.  
  464.         lds    dx,cs:[oldint21]
  465.         mov    ax,2521h
  466.         int    21h
  467.  
  468.         lds    dx,cs:[oldint28]
  469.         mov    ax,2528h
  470.         int    21h
  471.         
  472.         lds    dx,cs:[oldint2a]
  473.         mov    ax,252ah
  474.         int    21h
  475.         pop    ds
  476. @@svr0_shut0:
  477.         ret
  478. _svr0_shutdown    endp
  479.  
  480. ;----------------------------------------------------------------------
  481. ; unsigned far svr0_GetSemaphores(void)
  482. ;   return the semaphore values
  483. ;      MSB = dos critical flag
  484. ;      LSB = bios critical flag
  485. ;----------------------------------------------------------------------
  486. _svr0_GetSemaphores proc far
  487.         mov    ax,word ptr cs:[semflag]
  488.         ret
  489. _svr0_GetSemaphores endp
  490.  
  491. ;----------------------------------------------------------------------
  492. ; void far svr0_SetDispatchFlag(void)
  493. ;   set the Dispatch flag to TRUE, so the next srv0_TestCallSvr
  494. ;   will trigger a dispatch function
  495. ;----------------------------------------------------------------------
  496. _svr0_SetDispatchFlag proc far
  497.         mov    cs:[callsvr],1
  498.         ret
  499. _svr0_SetDispatchFlag endp
  500.  
  501. ;----------------------------------------------------------------------
  502. ; void far svr0_ResetDispatchFlag(void)
  503. ;   reset the Dispatch flag
  504. ;----------------------------------------------------------------------
  505. _svr0_ResetDispatchFlag proc far
  506.         mov    cs:[callsvr],0
  507.         ret
  508. _svr0_ResetDispatchFlag endp
  509.  
  510.  
  511. ;----------------------------------------------------------------------
  512. ; unsigned far svr0_GetStackUsed(void)
  513. ;   return the maximum number of local stack bytes used. this was
  514. ;   mostly for debugging.
  515. ;----------------------------------------------------------------------
  516. _svr0_GetStackUsed proc far
  517.         push    di
  518.         mov     di,offset stk1
  519.         mov    cx,STK1LEN
  520.         push    ds
  521.         pop    es
  522.         mov    al,0
  523.         cld
  524. repz        scasb        
  525.         sub    di,offset stk1
  526.         mov    ax,STK1LEN
  527.         sub    ax,di
  528.         pop    di
  529.         ret
  530. _svr0_GetStackUsed endp
  531.  
  532. ;----------------------------------------------------------------------
  533. ; this is how we communicate. 
  534. ; it is user selectable. the RIFS at the beginning is how we
  535. ; find ourselves.
  536. ;----------------------------------------------------------------------
  537. olduser        dd    0
  538.         db    'RIFS'
  539. _svr0_user    proc    far
  540.         push    ax        ; save all regs
  541.         push    bx
  542.         push    cx
  543.         push    dx
  544.         push    di
  545.         push    si
  546.         push    ds
  547.         push    es
  548.         push    bp
  549.         mov    bp,DGROUP    ; init DS
  550.         mov    ds,bp
  551.         mov    bp,sp
  552.         mov    cs:[svrhere],1
  553.         push    ss        ; push INTREGS *
  554.         push    bp
  555.         call    _UserInt    ; execute user interrupt
  556.         add    sp,4        ; and return
  557.         mov    cs:[svrhere],0
  558.         pop    bp
  559.         pop    es
  560.         pop    ds
  561.         pop    si
  562.         pop    di
  563.         pop    dx
  564.         pop    cx
  565.         pop    bx
  566.         pop    ax
  567.         iret
  568. _svr0_user    endp
  569. SVR0_TEXT    ends
  570.         end
  571.         
  572.