home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c004 / 4.ddi / NETBIOS / CTSRVX.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-04-18  |  26.0 KB  |  1,122 lines

  1.     page ,132
  2.  
  3. comment !
  4.  *    server extension version of c-tree server
  5.  *    terminate/stay resident asm lang support
  6.  *
  7.  *    This program is the CONFIDENTIAL and PROPRIETARY property 
  8.  *    of FairCom(R) Corporation. Any unauthorized use, reproduction or
  9.  *    transfer of this program is strictly prohibited.
  10.  *
  11.  *      Copyright (c) 1987, 1988, 1989 FairCom Corporation
  12.  *    (Subject to limited distribution and
  13.  *     restricted disclosure only.)
  14.  *    *** ALL RIGHTS RESERVED ***
  15.  *
  16.  *    4006 West Broadway
  17.  *    Columbia, MO 65203
  18.  *
  19.  *
  20.  *    c-tree(R)    Version 4.3
  21.  *            Release C
  22.  *            February 7, 1989 17:30
  23.  *
  24. !
  25.  
  26.  
  27.     include    asm.inc
  28.  
  29. ;--------------------------------------------------------------------
  30. ;configuration control
  31. ;--------------------------------------------------------------------
  32. ;note: the same source module can be used for any C memory module
  33. ;(with appropiate 'far' modifiers). however it is recommended to
  34. ;assemble with a define (/D on the masm line) of one of the
  35. ;following:  SMALL or COMPACT or MEDIUM or LARGE
  36. ;example:  masm ctstsr /ml /DCOMPACT;
  37. ;--------------------------------------------------------------------
  38.  
  39.  
  40. ;comment out next to use dos default of 20 file max
  41. FID_TABLE_SZ = 255        ;up to 255 files open
  42.  
  43.  
  44.  
  45.  
  46. ;--------------------------------------------------------------------
  47. ; SMB (Server Message Block)
  48. ;--------------------------------------------------------------------
  49. ; sm_res is the field used to hold the server extension name (8 chars)
  50. ;  this verifies that the SMB is actually for this extension
  51. ; the values above are recommended. To include data in the packet:
  52. ; starting at sm_vwv:
  53. ;    dw len_of_data + 3    ; length of byte area
  54. ;    db 5            ; gen purpose byte data follows
  55. ;    dw len_of_data        ; len of gen purpose byte data
  56. ;    db len_of_data dup (?)    ; the actual data
  57. ;
  58. ; that last area contains params used by srvx process.  This includes
  59. ; command code etc.  Srvx will put its result here, subject to
  60. ; maximum len restriction (srvx_smbmax)  Srvx should also put a
  61. ; 0 in smb_err and smb_errclass.  Any real errors should be in a field
  62. ; inside the gen purpose byte data.  If a user sends request to server
  63. ; where srvx is not installed, server will return smb_errclass = 0xff.
  64. ;--------------------------------------------------------------------
  65.  
  66. SMB struc
  67.   sm_id        db 0ffh,'SMB'    ; 00 verification string
  68.   sm_cmd    db 0ffh        ; 04 command code
  69.   sm_errclass    db 0        ; 05 error class (DOS, Server, Hardware)
  70.   sm_err24type    db 0ffh        ; 06 int 24 AH code
  71.   sm_err    dw 0        ; 07 error code
  72.   sm_reb    db 0        ; 09 nu
  73.   sm_res    dw 7 dup (?)    ; 0a nu (*** SEE NOTE)
  74.   sm_tid    dw 0        ; 18 tree ID
  75.   sm_pid    dw 0 ;(or psp)    ; 1a process ID (psp)
  76.   sm_uid    dw 0         ; 1c user ID
  77.   sm_mid    dw 0        ; 1e mux ID
  78.   sm_wct    db 0        ; 20 word parameter count
  79.   sm_vwv    dw ? ;see note    ; 21 1st word param or begin of byte area
  80. SMB ends
  81.  
  82.  
  83. ;--------------------------------------------------------------------
  84. ; program segment prefix
  85. ;--------------------------------------------------------------------
  86. ;--------------------------------------------------------------------
  87.  
  88. PSP struc
  89.   pp_int20    dw ?        ;+00 exit instruction
  90.   pp_mtop    dw ?        ; 02 paragraph past end of mem
  91.   pp_4        db ?        ; 04
  92.   pp_cpmcall    db ?        ; 05 long call opcode
  93.   pp_cpmmtop    dw ?        ; 06 long call oprand adj to look like mtop
  94.   pp_cpmcallseg    dw ?        ; 08 rest of long call
  95.   pp_i22term    dd ?        ; 0a exit to parent addr
  96.   pp_i23ctlcp    dd ?        ; 0e ctl-c trap of parent
  97.   pp_i24cerrp    dd ?        ; 12 critical err trap of parent
  98.   pp_parent    dw ?        ; 16 psp of parent
  99.   pp_fidtbl    db 20 dup (?)    ; 18 file id table
  100.   pp_envseg    dw ?        ; 2c seg of environment
  101.   pp_spsave    dw ?        ; 2e sp save while in dos or execing child
  102.   pp_sssave    dw ?        ; 30 ss save "
  103.   pp_fidtbllen    dw ?        ; 32 length of fidtbl
  104.   pp_fidtblptr    dd ?        ; 34 ptr to fidtbl
  105.   pp_shr0    dw ?        ; 38 set to ffff (used by share.exe)
  106.   pp_shr1    dw ?        ; 3a set  to ffff (used by share.exe)
  107.         db 14h dup (?)    ; 3c
  108.   pp_call50    dw ?        ; 50 old convention dos entry
  109.   pp_call50ret    db ?        ; 52
  110.         db 09h dup (?)    ; 53
  111.   pp_fcb0    db 16 dup (?)    ; 5c
  112.   pp_fcb1    db 16 dup (?)    ; 6c
  113.         db 4 dup (?)    ; 7c
  114.   pp_cmdtail    db 128 dup (?)    ; 80
  115. PSP ends
  116.  
  117. ;--------------------------------------------------------------------
  118. ;DOSSTATE structure
  119. ;--------------------------------------------------------------------
  120. ; msdos 3.x user context area - everything except current directorys
  121. ; the address of this table is obtained with DOS 5d06h call:
  122. ;        in:    ax = 5d06h
  123. ;        out:    ds:si = addr of context data
  124. ;            dx = len of context data when in_dos flag clear
  125. ;            cx = len of context data when in_dos flag set
  126. ;                 (struc of this small context is shown below)
  127. ;--------------------------------------------------------------------
  128.  
  129. DOSSTATE struc
  130.   dst_in_i24        db ?    ;00 dos is in int 24 counting flag
  131.   dst_in_dos        db ?    ;01 dos is in use counting flag
  132.   dst_wpe_drv        db ?    ;02 drive number of write prot error
  133.   dst_errloc        db ?    ;03 extended error locus
  134.   dst_err        dw ?    ;04 extended error
  135.   dst_erract        db ?    ;06 extended error suggested action
  136.   dst_errclass        db ?    ;07 extended error class
  137.   dst_errvol        dd ?    ;08 extended error volume label ptr
  138.   dst_dta        dd ?    ;0c data transfer address
  139.   dst_psp        dw ?    ;10 program segment prefix
  140.   dst_i23_sp        dw ?    ;12 sp save during int 23
  141.   dst_retcode        dw ?    ;14 dos return code
  142.   dst_defdrv        db ?    ;16 default drive
  143.   dst_breakon        db ?    ;17 check for ctl-break on/off flag
  144.                 ;18h sizeof dosstate
  145. DOSSTATE ends
  146.  
  147.  
  148. ;---------------------------------------------------------------------
  149. ;                              DATA
  150. ;---------------------------------------------------------------------
  151. ;
  152.     DSEG
  153.     extrn __aintdiv:dword    ;dos's div exception vector ptr that
  154.                 ;was saved by c-runtime init code
  155.  
  156. MAXSEG = 20            ;size of _abrktb
  157.     extrn __abrktb:word    ;crt (c runtime) table of blocks
  158.                 ;alloc'd from dos
  159.     extrn __asegds:word    ;crt heaprec for malloc in DGROUP
  160.     extrn __asizds:word    ;crt size of DGROUP
  161.     extrn __psp:word    ;crt addr of program seg prefix
  162.  
  163.  
  164.  
  165. SXEVinit  = 1
  166. SXEVlusmb = 2
  167. SXEVrusmb = 3
  168. SXEVludis = 4
  169. SXEVrudis = 5
  170.  
  171.     public    _srvx_smb, _srvx_ncb, _srvx_ses, _srvx_smbmax
  172.     public    _srvx_eventcode
  173.  
  174.     even
  175. _srvx_smb        dd ?    ;ptr to smb, ref'd by main code
  176. _srvx_ncb        dd ?    ;ptr to ncb
  177. _srvx_ses        dw ?    ;session number (0 if local user)
  178. _srvx_smbmax        dw ?    ;max len of response smb
  179. _srvx_eventcode        dw SXEVinit
  180.  
  181.  
  182.     CSEG
  183.     assume    ds:nothing
  184.  
  185. ;    NOTE: all data beyond this point is in code segment
  186.  
  187. ;this is the layout of context data saved for both the user and the
  188. ;srvx programs.
  189.  
  190. CONTEXT struc
  191.   cx_i1b        dd ?    ;int 1b vector (kbd break)
  192.   cx_i23        dd ?    ;int 23 vector (dos ^C)
  193.   cx_i24        dd ?    ;int 24 vector (dos critical error)
  194.   cx_dost db (size DOSSTATE) dup (?) ;dos variables
  195.   cx_spare db 20 dup (?)    ;
  196. CONTEXT ends
  197.  
  198. ifdef DEBUG
  199.  public u_ctxt, x_ctxt
  200. endif
  201.  
  202.     even
  203. u_ctxt        CONTEXT <>    ;save area for user context
  204.     even
  205. x_ctxt        CONTEXT <>    ;          for our context
  206.  
  207. ;the program name is set in srvx_init().  It is compared against
  208. ;signature in SMB blocks.
  209.  
  210. ifdef DEBUG
  211.  public srvx_name
  212. endif
  213.  
  214. srvx_name    db 8 dup (' ')        ;name of srvx process
  215.  
  216. ;fixed up user's stack for first call to srvx_wait()
  217. ;this will go to code that does an int 21 with ax = term, stay resident
  218.  
  219. ifdef DEBUG
  220.  public init_ustk, task_memsize
  221. endif
  222.  
  223.     even
  224.         dw 64 dup (?)        ;slack
  225. init_ustk    dw 0            ;bx
  226.         dw 0            ;cx
  227. task_memsize    dw ?            ;dx
  228.         dw 0            ;si
  229.         dw 0            ;di
  230.         dw 0            ;bp
  231.         dw seg _TEXT        ;ds
  232.         dw seg _TEXT        ;es
  233.         dw OTX go_tsr        ;ret
  234.  
  235. ;end of stack
  236.  
  237.  
  238. ;original vectors for interrupts we patch
  239.  
  240. ifdef DEBUG
  241.  public i2f_passon, upost_passon, i21_passon
  242. endif
  243.  
  244.  
  245.     even
  246. i2f_passon    dd ?        ;continue for mux int intercept
  247. upost_passon    dd ?        ;server extension intercept
  248. i21_passon    dd ?        ;continue for int 21 intercept
  249.  
  250. ;sp saves for context switches
  251.  
  252. ifdef DEBUG
  253.  public u_sp,u_ss,x_sp,x_ss;for debug
  254. endif
  255.  
  256.     even
  257. u_sp        dw OTX init_ustk ;user sp save when in srvx context
  258. u_ss        dw seg _TEXT
  259. x_sp        dw ?        ;sp save when in user context
  260. x_ss        dw ?
  261.  
  262.  
  263. ifdef DEBUG
  264.  public srvx_waiting, srvx_lock, srvx_mid, srvx_killed
  265. endif
  266.  
  267. srvx_waiting    db 0        ;flags blocked thread pending
  268. srvx_lock    db 0        ;0-not in srvx, 1-in srvx, called by
  269.                 ; server, 2-in srvx, called by local
  270.                 ; user (via int 2f)
  271. srvx_mid    db 0        ;mux id (int 2f, ah value noticed by us)
  272. srvx_killed    db 0        ;set if server terminates
  273.  
  274.  
  275. ifdef DEBUG
  276.  public dos_state, dctx_szsmall, dctx_szlarge
  277. endif
  278.  
  279.     even
  280. dos_state    dd ?        ;pointer to dos variables
  281. dctx_szsmall    dw ?        ;size of dos variables for context sw.
  282. dctx_szlarge    dw ?        ;size of dos variables for context sw.
  283.                 ;  typically some 2k bytes (not used)
  284.  
  285. ;
  286. ;replacement file-id so dos can open more than 20 files
  287. ;
  288.  
  289. ifdef FID_TABLE_SZ
  290.   ifdef DEBUG
  291.    public fid_table
  292.   endif
  293.     even
  294. fid_table    db FID_TABLE_SZ dup (0ffh)
  295. endif
  296.  
  297.  
  298. ;debug vars
  299.  
  300. ifdef DEBUG
  301.  
  302.     public blocked
  303. blocked        dw 0        ;
  304.  
  305. endif
  306.  
  307.     
  308.  
  309. ;--------------------------------------------------------------------
  310. ;int 21 trap
  311. ;--------------------------------------------------------------------
  312. ;trap is in effect only during srvx context:
  313. ;  trapped to (1) force error on mem alloc's (2) clean up if task
  314. ;  terminates
  315. ;--------------------------------------------------------------------
  316.  
  317.  
  318. ifdef DEBUG
  319.   public i21_trap
  320. endif
  321.  
  322. i21_trap:
  323.  
  324.     push    ax        ;check for user interrupted our thread
  325.     mov    ax,ss
  326.     cmp    ax,DGROUP
  327.     pop    ax
  328.     jnz    dtr2
  329.  
  330.     cmp    ah,4ch            ;terminate?
  331.     jz    killtask
  332.     cmp    ah,48h            ;alloc?
  333.     jz    dtr1
  334.     cmp    ah,4ah            ;mod alloc?
  335.     jnz    dtr2
  336. dtr1:    mov    ax,8            ;no mem dos err
  337.     xor    bx,bx
  338.     stc
  339.     sti
  340.     retf    2
  341. dtr2:    jmp    cs:i21_passon
  342.  
  343. ;--------------------------------------------------------------------
  344. ;killtask
  345. ;--------------------------------------------------------------------
  346. ;entered from i21_trap if server task issued dos terminate call
  347. ;unhook from traps, release all memory disappear
  348. ;
  349. ;NOTE: if this is to be used with other tsr's, then they should
  350. ;be removed first if they are loaded after this.
  351. ;--------------------------------------------------------------------
  352. ifdef DEBUG
  353.  public killtask, clsall
  354. endif
  355.  
  356. killtask:
  357.  
  358.     mov    ax,DGROUP
  359.     mov    ds,ax
  360.  
  361.     assume    ds:DGROUP
  362.  
  363.     push    ds
  364.     assume    ds:nothing
  365.     ;unlink int traps
  366.  
  367.     les    bx,cs:upost_passon
  368.     mov    ax,0b804h
  369.     int    2fh
  370.  
  371.     lds    dx,cs:i2f_passon
  372.     DOS    252fh
  373.  
  374.     pop    ds
  375.     assume    ds:DGROUP
  376.  
  377.  
  378.     ;close all open files
  379.  
  380.     mov    es,__psp
  381.     push    ds
  382.     lds    si,es:[0].pp_fidtblptr
  383.     mov    cx,es:[0].pp_fidtbllen
  384.     xor    bx,bx
  385. clsall:    cmp    BY [si+bx],0ffh
  386.     jz    cla1
  387.     DOS    3eh
  388. cla1:    inc    bx
  389.     loop    clsall
  390.     pop    ds
  391.  
  392.     ;free all memory associated with task
  393.     mov    es,__psp
  394.     mov    ax,es:[0].pp_envseg    ;env ptr
  395.     mov    es,ax
  396.     or    ax,ax
  397.     jz    kt1
  398.     DOS    49h            ;free env
  399. kt1:
  400.     lea    si,__abrktb+4        ;free all far segs
  401.     mov    cx,MAXSEG-1
  402. kt2:    mov    ax,[si+2]
  403.     or    ax,ax
  404.     jz    kt3
  405.     mov    es,ax
  406.     DOS    49h
  407.     add    si,4
  408.     loop    kt2
  409. kt3:    mov    es,__psp        ;free the main seg
  410.     DOS    49h
  411.  
  412.     ;flag killed
  413.     mov    cs:srvx_killed,1
  414.  
  415.     ;return to interrupted thread
  416.  
  417.     call    far ptr _srvx_wait        ;won't return
  418.  
  419.     assume    ds:nothing
  420.  
  421. ;--------------------------------------------------------------------
  422. ; srvx_trap
  423. ;--------------------------------------------------------------------
  424. ;
  425. ;This is the linkage to the resident file server.
  426. ;When the server receives a message from a workstation, we get to
  427. ;take a look at it and process it if we want to.
  428. ;
  429. ;The linkage was set up with int 2f, ax=b803 (get current post address)
  430. ;and int 2f, ax=b804 (set new post address).
  431. ;
  432. ;On entry:
  433. ;    if ax == 0010h then
  434. ;        /* smb request from user */
  435. ;        ds:di points to the SMB message
  436. ;        cx has max length for response smb.
  437. ;        es:bx ptr to NCB
  438. ;        dx has net bios session number
  439. ;    if ax == 0106h then
  440. ;        /* user has 'called' via netbios */
  441. ;        es:bx ptr to NCB
  442. ;        dx has net bios session number
  443. ;    if ax == 0105h then
  444. ;        /* user has 'hung-up' via netbios */
  445. ;        es:bx ptr to NCB
  446. ;        dx has net bios session number
  447. ;
  448. ;
  449. ;On exit: if we processed the message, iret with ax = 0 (actually jmps
  450. ;to got_request to resume our main code).  If we don't process the
  451. ;message, then jmp to the next server extension (via address obtained
  452. ;on int 2f, ax=b803)
  453. ;
  454. ;No registers other than ax are changed.  If we process SMB, then
  455. ;ax is set to 0.
  456. ;--------------------------------------------------------------------
  457.  
  458. ifdef DEBUG
  459.  public srvx_trap
  460. endif
  461.  
  462. srvx_trap:
  463.     cmp    ax,105h            ;disconnect code?
  464.     jnz    sxt2
  465.     push    ax
  466.     mov    ax,SXEVrudis
  467.     call    got_req
  468.     pop    ax
  469.     jmp    short sxt3
  470. sxt2:    cmp    ax,10h            ;is it SMB type?
  471.     jz    sxt4            ;keep checking if so
  472. sxt3:    jmp    cs:upost_passon        ;pass to next extension
  473.  
  474. sxt4:    cmp    [di].sm_cmd,0ffh    ;is SMB command code an 'escape'
  475.     jnz    sxt3            ;if not, pass to next
  476.     cld                ;
  477.     push    es            ;save regs needed for signature
  478.     push    ds            ; compare
  479.     push    cx
  480.     push    di
  481.     push    si
  482.     mov    si,di            ;ds:si -> smb
  483.     add    si,sm_res        ;-> smb signature field
  484.     push    cs
  485.     pop    es
  486.     mov    di,OTX srvx_name    ;name of our server extension
  487.     mov    cx,8/2
  488.     repz    cmpsw            ;will match if user made this SMB
  489.     pop    si            ; with us in mind
  490.     pop    di
  491.     pop    cx
  492.     pop    ds
  493.     pop    es
  494.     jnz    sxt3            ;jmp if not for us
  495.     mov    ax,0
  496.     push    ax            ;ax = 0 to indicate msg processed
  497.     mov    ax,SXEVrusmb
  498.     call    got_req            ;get back to waiting main program
  499.     pop    ax
  500.     jnc    sxt1            ;if not killed while in prog
  501.     mov    ax,10h
  502.     jmp    sxt3
  503. sxt1:    iret
  504.  
  505. ;--------------------------------------------------------------------
  506. ; i2f_trap
  507. ;--------------------------------------------------------------------
  508. ;
  509. ;Monitors int 2f for our multiplex ID assigned at startup time.
  510. ; int 2f, ah=id, al=0  is used for an install check.
  511. ; int 2f, ah=id, al!=1 is mechanism for local user (foreground process)
  512. ;                      to issue a request to us.  In this case, user
  513. ;                      passes an SMB-like data structure in ds:di to us
  514. ;               and cx has smb max len
  515. ;
  516. ;only AX is changed
  517. ;--------------------------------------------------------------------
  518.  
  519. ifdef DEBUG
  520.  public i2f_trap
  521. endif
  522.  
  523. i2f_trap:
  524.     cmp    ah,cs:srvx_mid        ;make sure our mux ID
  525.     jz    muxus
  526.     jmp    cs:i2f_passon        ;pass to next int 2f handler
  527. muxus:    or    al,al
  528.     jnz    mux1            ;jmp if not install check
  529.     inc    al            ;return 'is installed'
  530. mux0:    iret
  531. mux1:
  532.     cld                ;alway fwd dir
  533.     cmp    al,1
  534.     jz    mux2
  535.     mov    ax,0
  536.     push    ax
  537.     mov    ax,SXEVludis
  538.     jmp    short mux3
  539. mux2:    mov    ax,0
  540.     push    ax
  541.     mov    ax,SXEVlusmb        ;flag that request is from local proc
  542. mux3:    call    got_req            ;get to waiting main program
  543.     pop    ax
  544.     jnc    mux4            ;if not killed while in prog
  545.     mov    al,1            ;flag killed to user
  546. mux4:    iret
  547.  
  548. ;--------------------------------------------------------------------
  549. ; far srvx_wait();
  550. ;--------------------------------------------------------------------
  551. ;
  552. ;Main code calls this to wait on next user request.  At the same time,
  553. ;the reply for the just-completed request is returned to the user (except
  554. ;the first time).
  555. ;
  556. ;The first time called, we will end up doing a DOS 'terminate stay resident'.
  557. ;The saved stack info was set up in init to cause a return to the TSR code.
  558. ;
  559. ;input: none
  560. ;output: (SMB far *) srvx_smb is pointer to the SMB associated with request
  561. ;        We build response in this smb also.
  562. ;        (unsigned) srvx_smbmax specifies maximum size of smb for response.
  563. ;     returns 1 if request came from user via server, else 2 if request
  564. ;        was via int 2f (local user)
  565. ;--------------------------------------------------------------------
  566.  
  567.     public    _srvx_wait
  568.  
  569. _srvx_wait proc far
  570. _srvx_wait endp
  571.     PUSHM    <bp,di,si,ds>
  572.  
  573.     mov    cs:x_sp,sp        ;save our sp
  574.     mov    cs:x_ss,ss
  575.  
  576.  
  577.     mov    di,OTX x_ctxt        ;save our context
  578.     call    save_context
  579.     ;remove the int 21 trap
  580.     lds    dx,cs:i21_passon
  581.     DOS    2521h
  582.     mov    si,OTX u_ctxt        ;restore user's context
  583.     call    restore_context
  584.  
  585.     cli
  586.     mov    ss,cs:u_ss        ;user's sp restored
  587.     mov    sp,cs:u_sp
  588.     sti
  589.  
  590.     POPM    <bx,cx,dx,si,di,bp,ds,es>
  591.     mov    al,0
  592.     cli
  593.     xchg    al,cs:srvx_lock
  594.     cmp    al,SXEVlusmb
  595.     jnz    sxw1
  596.     cmp    cs:srvx_waiting,0
  597.     jz    sxw1
  598.     sti
  599.     mov    ah,84h
  600.     int    2ah
  601. sxw1:    xor    ax,ax            ;cf clear to indicate not killed
  602.     ret                ;return to (1) server or (2) local
  603.                     ;user that did an int 2f
  604.  
  605. ;--------------------------------------------------------------------
  606. ; got_req
  607. ;--------------------------------------------------------------------
  608. ;
  609. ;This can be viewed as a continuation of respond_wait. Gets control when
  610. ;there is another (SMB) request to be processed
  611. ;
  612. ;in: al = 1 if from server, 2 if from local user
  613. ;
  614. ;It is possible for server and local user to make requests asynchronously.
  615. ;However, mutual exclusion lock is done here so that higher level has
  616. ;to worry about only 1 request at a time.  Undoc'd DOS 3.x   int 2a, ah=84
  617. ;function is used to sleep when it is found that other thread is using
  618. ;our code.
  619. ;--------------------------------------------------------------------
  620.  
  621. ifdef DEBUG
  622.  public got_req
  623. endif
  624.  
  625. got_req:
  626. gr1:
  627.     cli                ;ints off for lock'd test
  628.     cmp    cs:srvx_lock,0
  629.     jz    gr2            ;jmp if not locked
  630.     mov    cs:srvx_waiting,al
  631.     sti
  632.  
  633.     ifdef    DEBUG
  634.     inc    cs:blocked
  635.     endif
  636.  
  637.     push    ax
  638.     mov    ah,84h            ;sleep till tick or other event
  639.     int    2ah
  640.     pop    ax
  641.     jmp    gr1
  642.  
  643. gr2:    mov    cs:srvx_waiting,0
  644.     cmp    cs:srvx_killed,0
  645.     jz    gr3
  646.     stc
  647.     ret
  648. gr3:    mov    cs:cs:srvx_lock,al    ;no locked so lock for us
  649.     sti
  650.     PUSHM    <es,ds,bp,di,si,dx,cx,bx>
  651.     push    ds
  652.     push    ax
  653.     mov    ax,seg DGROUP
  654.     mov    ds,ax
  655.     assume    ds:DGROUP
  656.     pop    _srvx_eventcode        ;what caused wakeup
  657.     pop    WO _srvx_smb+2
  658.     mov    WO _srvx_smb,di        ;save smb ptr in global var
  659.     mov    _srvx_smbmax,cx        ;save smb max len in global
  660.     mov    WO _srvx_ncb,bx
  661.     mov    WO _srvx_ncb+2,es
  662.     mov    _srvx_ses,dx
  663.  
  664.     assume    ds:nothing
  665.  
  666.     mov    u_sp,sp            ;save user sp
  667.     mov    u_ss,ss
  668.     cli
  669.     mov    ss,x_ss            ;restore srvx's stack
  670.     mov    sp,x_sp
  671.     sti
  672.  
  673.     mov    di,OTX u_ctxt        ;save user's context
  674.     call    save_context
  675.     mov    si,OTX x_ctxt        ;restore srvx's context
  676.     call    restore_context
  677.  
  678.     ;set up a trap on server's int 21 functions
  679.     DOS    3521h
  680.     mov    WO cs:i21_passon,bx
  681.     mov    WO cs:i21_passon+2,es
  682.     mov    dx,OTX i21_trap
  683.     mov    ax,cs
  684.     mov    ds,ax
  685.     DOS    2521h
  686.  
  687.  
  688.     POPM    <ds,si,di,bp>        ;restore C regs
  689.     retf
  690.  
  691.  
  692. ;--------------------------------------------------------------------
  693. ;save_context
  694. ;--------------------------------------------------------------------
  695. ;utility used to save current context
  696. ;in:
  697. ;    cs:di = save area
  698. ;out:
  699. ;    ax,di,si,ds,es destroyed
  700. ;
  701. ;--------------------------------------------------------------------
  702.  
  703. ifdef DEBUG
  704.   public save_context
  705. endif
  706.  
  707. save_context:
  708.     cld
  709.     mov    cx,cs
  710.     mov    es,cx            ;es:di -> save
  711.     xor    cx,cx
  712.     mov    ds,cx
  713.     mov    si,1bh*4        ;get int 1b vect
  714.     cld
  715.     movsw
  716.     movsw
  717.     mov    si,23h*4        ;get ints 23,24 vects
  718.     movsw
  719.     movsw
  720.     movsw
  721.     movsw
  722.  
  723.     lds    si,cs:dos_state
  724.     mov    cx,cs:dctx_szsmall
  725.     shr    cx,1
  726.     rep    movsw
  727.     jnc    sst1
  728.     movsb
  729. sst1:
  730.     ret
  731.  
  732. ;--------------------------------------------------------------------
  733. ;restore_context
  734. ;--------------------------------------------------------------------
  735. ;utility used to save current context
  736. ;in:
  737. ;    cs:si = save area
  738. ;out:
  739. ;    cx,di,si,es,ds destroyed
  740. ;
  741. ;--------------------------------------------------------------------
  742.  
  743. ifdef DEBUG
  744.   public restore_context
  745. endif
  746.  
  747. restore_context:
  748.     cld
  749.     mov    ax,cs
  750.     mov    ds,ax            ;ds:si -> save area
  751.     xor    ax,ax
  752.     mov    es,cx
  753.     mov    di,1bh*4        ;set int 1b vect
  754.     cli
  755.     movsw
  756.     movsw
  757.     mov    di,23h*4        ;get ints 23,24 vects
  758.     movsw
  759.     movsw
  760.     movsw
  761.     movsw
  762.     sti
  763.     les    di,cs:dos_state
  764.     mov    cx,cs:dctx_szsmall
  765.     shr    cx,1
  766.     rep    movsw
  767.     jnc    rst1
  768.     movsb
  769. rst1:
  770.     ret
  771.  
  772.  
  773.  
  774. ;--------------------------------------------------------------------
  775. ;misc dos traps
  776. ;--------------------------------------------------------------------
  777. ;these are set during task (server) context
  778. ;i24 (critical err) just causes dos call to fail
  779. ;i23 (ctl-brk dos) don't let user trap get control
  780. ;i1b (ctl-brk bios) "    "   "    "    "    "
  781. ;
  782. ;note: during heavy server activity ctl-brks may get lost.
  783. ;--------------------------------------------------------------------
  784.  
  785. ;misc default traps for task context
  786.  
  787. ifdef DEBUG
  788.   public i24_trap,i1b_trap,i23_trap
  789. endif
  790.  
  791. i24_trap:
  792.     mov    al,3            ;fail the call
  793. i1b_trap:
  794. i23_trap:
  795.     iret
  796.  
  797.  
  798. ;--------------------------------------------------------------------
  799. ; srvx_init
  800. ;--------------------------------------------------------------------
  801. ;
  802. ;srvx_init(name, mid)
  803. ; char far *name;   /* name of srvx process, 8 chars long */
  804. ; int mid;      /* our ID on mux (int 2fh) chain
  805. ;
  806. ;
  807. ;assumes srvx_preinit() has been called to verify system ready
  808. ;called from ctsmsg to divide the system into two processes -- the
  809. ;user and the server task.  When it returns, the server task is
  810. ;running and the user is suspended.  When the server suspends, the
  811. ;user will resume at a go term/stay resident instruction, which will
  812. ;return to the shell, leaving the server in memory (the user has its
  813. ;own little stack for this exit process)
  814. ;
  815. ;for the C small and medium models, this cuts off the heap at its
  816. ;first free space.  for other models, the thing to do is link
  817. ;with /CP:1 as noted in MS C users guide
  818. ;
  819. ;the dos internal handle table is moved to a bigger area so more
  820. ;files can be opened by the server task.
  821. ;--------------------------------------------------------------------
  822.  
  823.     ;this routine gets control on first call to srvx_wait().  It
  824.     ;sets up this code as a resident program.
  825.  
  826. ifdef DEBUG
  827.  public got_req
  828. endif
  829.  
  830. go_tsr:
  831.     cli
  832.     DOS    3100h
  833.  
  834. __name = 6
  835. __mid = 10
  836.  
  837.     public _srvx_init
  838. _srvx_init proc far
  839.     push    bp
  840.     mov    bp,sp
  841.     push    di
  842.     push    si
  843.  
  844.     assume    ds:DGROUP
  845.  
  846.     ;cut off mem alloc
  847.     call    fxalloc
  848.  
  849.  
  850.     push    ds
  851.  
  852.  
  853.  
  854.     ifdef FID_TABLE_SZ
  855. ; set bigger file id table for dos
  856.     mov    es,__psp
  857.     lds    si,es:[0].pp_fidtblptr
  858.  
  859.     assume    ds:nothing
  860.  
  861.     mov    cx,es:[0].pp_fidtbllen
  862.     cmp    cx,FID_TABLE_SZ
  863.     jae    iti2
  864.     mov    di,OTX fid_table
  865.     mov    WO es:[0].pp_fidtblptr,di
  866.     mov    WO es:[0].pp_fidtblptr+2,cs
  867.     mov    es:[0].pp_fidtbllen,FID_TABLE_SZ
  868.     push    cs
  869.     pop    es
  870.     rep    movsb            ;copy already open file ids
  871. iti2:
  872.     endif
  873.  
  874.     assume ds:nothing
  875.  
  876.     ;copy name to static buffer
  877.  
  878.  
  879.     push    cs
  880.     pop    es
  881.     mov    di,OTX srvx_name
  882.     lds    si,DWO [bp+__name]
  883.     cld
  884.     mov    cx,8/2
  885.     rep    movsw
  886.  
  887.  
  888. ; copy current context to user context save
  889. ; (the first "user" is us, going tsr on first call to srvx_wait())
  890.  
  891.     mov    di,OTX u_ctxt
  892.     call    save_context
  893.  
  894.     push    cs
  895.     pop    ds
  896.  
  897. ; turn off break checking
  898.  
  899.     mov    dl,0
  900.     DOS    3301h
  901.  
  902.  
  903. ;set up error traps
  904.  
  905.     mov    dx,OTX i1b_trap
  906.     DOS    251bh
  907.     mov    dx,OTX i23_trap
  908.     DOS    2523h
  909.     mov    dx,OTX i24_trap
  910.     DOS    2524h
  911.  
  912.     ;set up a trap on server's int 21 functions
  913.     DOS    3521h
  914.     mov    WO cs:i21_passon,bx
  915.     mov    WO cs:i21_passon+2,es
  916.     mov    dx,OTX i21_trap
  917.     mov    ax,cs
  918.     mov    ds,ax
  919.     DOS    2521h
  920.  
  921. ; set mux int trap
  922.  
  923.     mov    ax,[bp+__mid]
  924.     mov    cs:srvx_mid,al
  925.  
  926.     DOS    352fh
  927.     mov    WO cs:i2f_passon,bx
  928.     mov    WO cs:i2f_passon+2,es
  929.     mov    dx,OTX i2f_trap
  930.     DOS    252fh
  931.  
  932. ; set server extension trap
  933.     mov    ax,0b803h
  934.     int    2fh
  935.     mov    WO cs:upost_passon,bx
  936.     mov    WO cs:upost_passon+2,es
  937.     push    cs
  938.     pop    es
  939.     mov    bx,OTX srvx_trap
  940.     mov    ax,0b804h
  941.     int    2fh
  942.  
  943. ; restore dos's div by 0 trap
  944.     mov    ax,seg DGROUP
  945.     mov    ds,ax
  946.     assume    ds:DGROUP
  947.     lds    dx,__aintdiv
  948.     assume    ds:nothing
  949.     DOS    2500h
  950.     xor    ax,ax
  951.  
  952.     pop    ds
  953.     assume    ds:nothing
  954. itxit:
  955.     pop    si
  956.     pop    di
  957.     pop    bp
  958.     ret
  959. _srvx_init endp
  960.  
  961.  
  962. ;--------------------------------------------------------------------
  963. ;UCOUNT srvx_preinit(muxid)
  964. ;--------------------------------------------------------------------
  965. ;--------------------------------------------------------------------
  966.  
  967. __midi = 6
  968.  
  969.     public _srvx_preinit
  970. _srvx_preinit proc far
  971.     push    bp
  972.     mov    bp,sp
  973.     push    di
  974.     push    si
  975. ; check dos version
  976.  
  977.     DOS    30h
  978.     cmp    al,3
  979.     jz    tpi1
  980.     mov    ax,1        ;return 1 for bad dos ver
  981.     jmp    tpi2
  982. tpi1:
  983.     mov    ax,0b800h    ;test for server installed
  984.     int    2fh
  985.     or    al,al
  986.     mov    ax,2
  987.     jz    tpi2        ;ret 2 if not installed
  988.     test    bx,40h
  989.     mov    ax,3
  990.     jz    tpi2        ;ret 3 if not server
  991.     mov    ax,[bp+__midi]
  992.     mov    ah,al
  993.     mov    al,0
  994.     int    2fh
  995.     or    al,al
  996.     mov    ax,4
  997.     jnz    tpi2        ;ret 4 if srvx already installed
  998.  
  999.     ;get addr and size of DOS data for context sw
  1000.     push    ds
  1001.     DOS    5d06h        ;see notes in struc section
  1002.     mov    ax,ds
  1003.     pop    ds
  1004.     mov    WO cs:dos_state,si
  1005.     mov    WO cs:dos_state+2,ax
  1006.     mov    cs:dctx_szsmall,dx
  1007.     mov    cs:dctx_szlarge,cx    ;(this not used)
  1008.  
  1009.     xor    ax,ax        ;ret 0 if all ok
  1010.  
  1011. tpi2:    pop    si
  1012.     pop    di
  1013.     pop    bp
  1014.     ret
  1015. _srvx_preinit endp
  1016.  
  1017. ;--------------------------------------------------------------------
  1018. ;fxalloc
  1019. ;--------------------------------------------------------------------
  1020. ;if no _fmallocs have been done, this cuts off the main data seg
  1021. ;just past last used heap space.  This works for MSC 3 and 4, and
  1022. ;probably for 5 too.
  1023. ;
  1024. ;the size of the main segment (psp to end of data seg) is saved
  1025. ;for the TSR parameter
  1026. ;--------------------------------------------------------------------
  1027.  
  1028. ifdef DEBUG
  1029.  public fxalloc
  1030. endif
  1031.     assume    ds:DGROUP
  1032. fxalloc:
  1033.     cmp    __abrktb+6,0    ;_abrktb[1].sg
  1034.     jnz    fx6
  1035.     mov    si,__asegds+0    ;_asegds.bottom
  1036.     or    si,si
  1037.     jnz    fx1
  1038.     mov    di,__abrktb    ;__abrktb[0].sz
  1039.     jmp    fx5a        ;make di end of dseg
  1040. fx1:    mov    __asegds+2,si    ;_asegds.roveroff
  1041.     xor    di,di
  1042. fx2:    mov    ax,[si]
  1043.     cmp    ax,0fffeh
  1044.     jz    fx4
  1045.     test    ax,1
  1046.     jnz    fx3
  1047.     mov    di,si        ;last alloc'd block found
  1048. fx3:    and    ax,not 1
  1049.     add    si,ax
  1050.     add    si,2
  1051.     jmp    fx2
  1052. fx4:    or    di,di
  1053.     jnz    fx5
  1054.     mov    di,__abrktb
  1055.     mov    WO [di],1    ;dummy free block
  1056. fx5:    mov    ax,[di]
  1057.     and    ax,not 1
  1058.     add    di,ax
  1059.     add    di,2
  1060.     mov    WO [di],0fffeh
  1061.     add    di,2
  1062.  
  1063.     mov    __asegds+6,di    ;_asegds.top
  1064.     mov    __abrktb,di    ;_abrktb[0].sz
  1065. fx5a:
  1066.     mov    __asizds,di
  1067.  
  1068.     mov    ax,di
  1069.     add    ax,15
  1070.     rcr    ax,1
  1071.     mov    cl,3
  1072.     shr    ax,cl
  1073.     mov    es,__psp
  1074.     mov    bx,ds
  1075.     add    ax,bx
  1076.     mov    es:[0].pp_mtop,ax
  1077.     DOS    4ah
  1078.  
  1079. fx6:    mov    bx,__psp
  1080.     mov    es,bx
  1081.     mov    ax,es:[0].pp_mtop    ;get main seg size
  1082.     sub    ax,bx
  1083.     mov    cs:task_memsize,ax
  1084.     ret
  1085.     assume    ds:nothing
  1086.  
  1087. ;--------------------------------------------------------------------
  1088. ;farcpybuf(far *dest, far * src, count)
  1089. ;--------------------------------------------------------------------
  1090. ;so that c code can be any model
  1091. ;--------------------------------------------------------------------
  1092.     public    _farcpybuf
  1093. _farcpybuf proc far
  1094.     push    bp
  1095.     mov    bp,sp
  1096.     PUSHM    <si,di,ds>
  1097.     les    di,DWO [bp+6]
  1098.     lds    si,DWO [bp+10]
  1099.     mov    cx,[bp+14]
  1100.     shr    cx,1
  1101.     jz    fcp1
  1102.     rep    movsw
  1103. fcp1:    jnc    fcp2
  1104.     movsb
  1105. fcp2:    POPM    <ds,di,si>
  1106.     pop    bp
  1107.     ret
  1108. _farcpybuf endp
  1109.  
  1110.     END_MOD
  1111.     end
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.