home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / SHSUCD11.ZIP / SHSUCDHD.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-12-07  |  33.0 KB  |  1,072 lines

  1. ;************************************************************************
  2. ;
  3. ;  SHSUCDHD.ASM
  4. ;
  5. ;    makes cached CD image appear as unit 0 on shsu-cdh
  6. ;
  7. ;  Use:  CDHD [/F:imagepathname1 [/F:imagepathname2 ...]] [/U] [/?]
  8. ;
  9. ;  Assemble using MASM 6.0 and link as an .exe file.
  10. ;
  11. ;  SHSUCDHD is a copyright reserved, free use program.  Use at your own risk.
  12. ;
  13. ;  (c)John H. McCoy, 1995, Sam Houston St. Univ., TX 77341-2206
  14. ;************************************************************************
  15.  
  16. .model small, os_dos
  17.  
  18. option nokeyword:<length name>
  19. option expr16
  20.  
  21. fptr  typedef  far ptr word
  22. nptr  typedef  near ptr word
  23.  
  24.  
  25. devHdr  struct
  26.   NextDriver   dword     -1
  27.   Attributes   word      0C800h        ; for a cdrom
  28.   Strategy     nptr      ?
  29.   Interrupt    nptr      ?
  30.   DeviceName   byte      '        '    ; 8 bytes
  31.                word      0             ; CDROM reserved
  32.                byte      0             ; CDROM drive letter
  33.   Units        byte      1             ; number of CD drives on this device
  34. devHdr ends
  35.  
  36. rh    struc
  37.    Length      byte ?          ; header size in bytes
  38.    Unit        byte ?          ; cd drive unit
  39.    Command     byte ?          ; device command code
  40.    Status      word ?          ; device command status
  41.    Reserved    byte 8 dup(?)
  42. rh    ends
  43.  
  44. rhIOCTL   struc
  45.                      byte size rh dup(?) ;rh common
  46.    MediaDesc         byte ?
  47.    CBPtr             fptr ?
  48.    BytesToTransfer   word ?
  49.    StartSector       word ?
  50.    VolIdPtr          fptr ?
  51. rhIOCTL   ends
  52.  
  53. rhTransfer  struc
  54.                      byte size rh dup(?) ;rh common
  55.                      byte   ?
  56.    DtaPtr            fptr   ?
  57.    SectorCount       word   ?
  58.    StartSector       dword  ?
  59.    ReadMode          byte   ?     ; we support cooked mode only
  60.                      byte   ?
  61.                      byte   ?
  62. rhTransfer ends
  63.  
  64. rhcmdIOCTL_In          equ 3
  65. rhcmdOpen              equ 0Dh
  66. rhcmdClose             equ 0Eh
  67. rhcmdPreFetch          equ 82h
  68. rhcmdReadLong          equ 80h
  69.  
  70. IOCtl_In_RDHACmd          equ  0
  71. IOCtl_ReadDriveBytes      equ  5
  72. IOCtl_DevStatCmd          equ  6
  73. IOCtl_ReturnSectorSize    equ  7
  74. IOCtl_ReturnVolumeSize    equ  8    ; total sectors on disk
  75. IOCtl_MediaChangedCmd     equ  9
  76.  
  77. IoCB_RDHA     struc
  78.    IoctlCommand           byte IOCtl_In_RDHACmd
  79.    DeviceHeaderAddress    fptr ?
  80. IoCB_RDHA ends
  81.  
  82. DeviceError            equ  8000h
  83. DeviceDone             equ  0100h
  84. DE_UnknownUnit         equ    01h   ; OR these with DeviceError
  85. DE_DeviceNotReady      equ    02h
  86. DE_UnknownCommand      equ    03h
  87. DE_SectorNoFound       equ    08h
  88. DE_ReadError           equ    0Bh
  89. DE_GeneralFailure      equ    0Ch
  90.  
  91. MediaChanged_No           equ   00
  92. MediaChanged_Yes          equ   0ffh
  93. MediaChanged_DontKnow     equ   01
  94. DriveNormalReady          equ   0
  95. DriveDoorOpen             equ   01h      ; bit is zero if closed
  96. DriveDoorUnlocked         equ   02h      ; bit is zero if locked
  97. DriveDataAndAudio         equ   10h      ; bit is zero if data only
  98. DrivePrefetching          equ   80h      ; bit is zero if no prefetch
  99. DriveRedBookAddressing    equ   200h     ; bit is zero if HSG only
  100. DriveEmpty                equ   800h     ; bit is zero if loaded
  101.                                          ; best guess observation
  102.  
  103. DriveEntry      struct
  104.    MediaChange     byte   MediaChanged_No
  105.    Status          dword  DriveEmpty
  106.    ImageFile       byte   33 dup (0)
  107. DriveEntry      ends
  108.  
  109. AsciiNul                equ     0
  110. cr                      equ     13
  111. lf                      equ     10
  112. ht                      equ     09
  113. QMark                   equ     '?'
  114. T                       equ     0
  115. F                       equ     -1
  116.  
  117. ReadImage         proto near C
  118. StringEq?         proto near C S1:fptr, S2:fptr
  119. ToHex             proto near C Num:word
  120. MsgOut            proto near C msg:nptr
  121. .code
  122.  
  123.    assume cs:@code,  ds:@code
  124.  
  125. ;  dos device header with CDROM extension fields
  126. ;  DO NOT MAKE THE DEVICE DRIVER NAME THE SAME AS THE FILE NAME
  127.  
  128. MaxDrives      equ     5
  129.  
  130. CDHDHdr  devHdr  {-1,0C800h,Strategy,Interrupt,'SHSU-CDH',0,0,0}
  131.  
  132. Author          byte     "Copyright 1995, John H. McCoy"
  133.  
  134. Drive          DriveEntry  MaxDrives dup(<>)
  135.  
  136. DriveUnit      byte    0
  137. DriveOffset    word    0             ; re-calculated on entry
  138.  
  139. InDOS           byte ?
  140. InDOSp          fptr ?
  141.  
  142. rhAddr        label far ptr
  143.   rhOffset      word       ?
  144.   rhSegment     word       ?
  145.  
  146. ImageHandle    word     ?
  147. PSP            word     ?
  148. _SS            word     ?
  149. _SP            word     ?
  150. DOS_SS         word     ?
  151. DOS_SP         word     ?
  152.  
  153. _ds             word     ?
  154.  
  155. SectorSize     equ     800h      ;make it an equ so we don't change it
  156. StartSector    Dword    ?
  157. StartOffset    word     ?
  158. StartPosition  Dword    ?
  159. BytesToRead    word     ?
  160.  
  161. DTAp              fptr    ?
  162. kount             word    0
  163. MySDAp            fptr    ?
  164. MySDASize         word    ?
  165. MySDASave         byte    800h dup ("v")
  166. MyReadBuffer      byte    96 dup ("r")
  167. HS                byte    "CDROM"      ; PVD 10-14
  168. ISO               byte    "CD001"      ; PVD 2-6
  169.  
  170. ;************************************************************************
  171. ;  Driver Strategy routine
  172. ;************************************************************************
  173.  
  174. Strategy    proc  far
  175.  
  176.    ;  es:bx contains request header pointer.  save it.
  177.       mov    cs:rhOffset, bx
  178.       mov    cs:rhSegment, es
  179.       ret
  180.  
  181. Strategy    endp
  182.  
  183. ;************************************************************************
  184. ;  Driver Interrupt routine
  185. ;************************************************************************
  186.  
  187. Interrupt    proc  far  uses bx cx dx di si es bp ds
  188.    ;  process command
  189.       les      bx, cs:rhAddr                ; make sure we have rh addr
  190.       mov      al, es:[bx].rh.Unit
  191.       .if   (al >= MaxDrives)
  192.             mov   ax,(DeviceDone OR DeviceError OR DE_UnknownUnit)
  193.             mov   es:[bx].rh.Status, ax
  194.             ret
  195.       .endif
  196.    ;  save  ds and setup ds addressing
  197.       push   cs
  198.       pop    ds
  199.       mov    _ds, ds
  200.  
  201.       mov    DriveUnit, al
  202.       sub    ah, ah
  203.       mov    cx, sizeof DriveEntry
  204.       mul    cx
  205.       mov    DriveOffset, ax
  206.       mov    al, es:[bx].rh.command
  207.       .if  (al == rhcmdIOCTL_In)
  208.         les      bx, es:[bx].rhIOCTL.CBPtr
  209.         mov      al, byte ptr es:[bx]         ; 1st byte of dta is subcommand
  210.         .if      al == IOCtl_In_RDHACmd
  211.            lea   ax, CDHDHdr
  212.            mov   word ptr es:[bx].IoCB_RDHA.DeviceHeaderAddress, ax
  213.            mov   ax, ds
  214.            mov   word ptr es:[bx].IoCB_RDHA.DeviceHeaderAddress+2, ax
  215.            mov   ax, DeviceDone
  216.         .elseif   al == IOCtl_ReadDriveBytes
  217.            mov   ax, 0
  218.            mov   word ptr es:[bx+1], ax
  219.            mov   ax, DeviceDone
  220.         .elseif   al == IOCtl_DevStatCmd
  221.            mov   si, DriveOffset
  222.            mov   ax, word ptr Drive[si].Status
  223.            mov   word ptr es:[bx+1], ax
  224.            mov   ax, word ptr Drive[si+2].Status
  225.            mov   word ptr es:[bx+3], ax
  226.            mov   ax, DeviceDone
  227.         .elseif   al == IOCtl_ReturnSectorSize
  228.            mov   ax, 0
  229.            mov   word ptr es:[bx+1], ax
  230.            mov   ax, 2048
  231.            mov   word ptr es:[bx+2], ax
  232.            mov   ax, DeviceDone
  233.         .elseif   al == IOCtl_ReturnVolumeSize
  234.            ; could avoid read and worry about cd type by
  235.            ;   seeking to end of the file and calculating next sector
  236.            mov   ax, 10h
  237.            mov   word ptr StartSector, ax
  238.            mov   word ptr StartSector+2, 0
  239.            mov   ax, offset MyReadBuffer
  240.            mov   word ptr DTAp, ax
  241.            mov   ax, ds
  242.            mov   word ptr DTAp+2, ax
  243.            mov   StartOffset, 0
  244.            mov   BytesToRead, sizeof MyReadBuffer
  245.            invoke ReadImage
  246.            ;    if buffer 2-6 = "CD001" size offset 80-83
  247.            mov  cx, sizeof ISO
  248.            invoke StringEq?,addr ISO,addr MyReadBuffer[1] ;eq if cx=0 on ret
  249.            cmp  cx,0
  250.            jne  NotISO
  251.            mov   ax, word ptr MyReadBuffer[80]
  252.            mov   word ptr es:[bx+1], ax
  253.            mov   ax, word ptr MyReadBuffer[82]
  254.            mov   word ptr es:[bx+3], ax
  255.            jmp   VolSizeXit
  256.          NotISO:
  257.            ;    if buffer 10-14= "CDROM" size offset 88-91
  258.            mov  cx, sizeof HS
  259.            invoke StringEq?,addr HS,addr MyReadBuffer[9] ;eq if cx=0 on ret
  260.            cmp  cx,0
  261.            jne  NotHS
  262.            mov   ax, word ptr MyReadBuffer[88]
  263.            mov   word ptr es:[bx+1], ax
  264.            mov   ax, word ptr MyReadBuffer[91]
  265.            mov   word ptr es:[bx+3], ax
  266.            jmp   VolSizeXit
  267.           NotHS:
  268.            mov   word ptr es:[bx+1], 0
  269.            mov   word ptr es:[bx+3], 0
  270.            jmp   @f
  271.           VolSizeXit:
  272.            add   word ptr es:[bx+1], 10h  ; add 1st 16 sectors to get
  273.            jnc   @f                       ; 1st sector after vol area
  274.            add   word ptr es:[bx+3], 1
  275.          @@:
  276.            mov   ax, DeviceDone
  277.         .elseif   al == IOCtl_MediaChangedCmd
  278.            mov   byte ptr es:[bx+1], 1    ; report don't know
  279.            mov   ax, DeviceDone           ; 1 - no change; 0ffh changed
  280.         .else   ; all other ioctlin sub commands
  281.            mov   ax,(DeviceDone OR DeviceError OR DE_UnknownCommand)
  282.         .endif
  283.       .elseif   ((al == rhcmdOpen)||(al ==rhcmdClose))
  284.           mov   ax, DeviceDone
  285.       .elseif   (al == rhcmdReadLong)
  286.           les   bx, cs:rhaddr
  287.           mov   ax,word ptr es:[bx].rhTransfer.StartSector
  288.           mov   word ptr StartSector, ax
  289.           mov   ax,word ptr es:[bx].rhTransfer.StartSector+2
  290.           mov   word ptr StartSector+2, ax
  291.           mov   ax, word ptr es:[bx].rhTransfer.DtaPtr
  292.           mov   word ptr DTAp, ax
  293.           mov   ax, word ptr es:[bx].rhTransfer.DtaPtr+2
  294.           mov   word ptr DTAp+2, ax
  295.           mov   StartOffset, 0
  296.        @@:
  297.           mov   ax, SectorSize
  298.           mul   es:[bx].rhTransfer.SectorCount
  299.           cmp   dx,0
  300.           je    @f
  301.           sub   es:[bx].rhTransfer.SectorCount,1
  302.           jmp   @b
  303.         @@:
  304.           mov   BytesToRead, ax
  305.           Invoke ReadImage
  306.           .if  (ax!=0)
  307.              mov   es:[bx].rhTransfer.SectorCount,0
  308.           .endif
  309.           or   ax,(DeviceDone)
  310.       .elseif   (al == rhcmdPreFetch)
  311.           mov   ax,(DeviceDone OR DeviceError OR DE_UnknownCommand)
  312.       .else
  313.           mov   ax,(DeviceDone OR DeviceError OR DE_UnknownCommand)
  314.       .endif
  315.  
  316. Xit:
  317.        les   bx, cs:rhAddr                   ; restore rh ptr
  318.        mov   es:[bx].rh.Status, ax
  319.        ret
  320.  
  321. Interrupt   endp
  322.  
  323. ReadImage  proc near C uses BX ES
  324.  
  325.    .if (BytesToRead == 0)
  326.       xor  ax, ax
  327.       ret
  328.    .endif
  329.  
  330.    mov   es, _ds
  331.    mov   cx, MySDASize
  332.    mov   di, offset MySDASave
  333.    lds   si, MySDAp
  334.    cld
  335.    rep   movsb                    ; save the SDA
  336.                                   ; ds:si=>es:di
  337.    mov   ds, cs:_ds
  338.    ; get InDOS flag
  339.    les   bx, InDOSp
  340.    mov   ah, byte ptr es:[bx]
  341.    mov   byte ptr InDOS, ah
  342.  
  343. .if inDOS
  344.    ;change to DOS's stack
  345.    mov   _SP, sp
  346.    mov   _SS, ss
  347.  
  348.    mov   ss, DOS_SS
  349.    mov   sp, DOS_SP
  350.  
  351.  
  352.    ;open the image file
  353.    mov   cl,40h
  354.    mov   dx, offset Drive.ImageFile
  355.    add   dx, DriveOffset
  356.    mov   ax, 1226h
  357.    int   2fh               ; handle returned in ax if carry not set
  358.    jnc   @f
  359.    mov   ax, (DeviceError OR DE_DeviceNotReady)
  360.    ; restore incoming stack since we are terminating
  361.    mov   ss, cs:_SS
  362.    mov   sp, cs:_SP
  363.    jmp restore
  364.  @@:
  365. .else    ; not in DOS
  366.    ;open the  image file
  367.    mov   dx, offset Drive.ImageFile
  368.    add   dx, DriveOffset
  369.    mov   ax, 3d00h
  370.    int   21h              ; handle returned in ax if carry not set
  371.    jnc   @f
  372.    mov   ax, (DeviceError OR DE_DeviceNotReady)
  373.    jmp   restore
  374.   @@:
  375. .endif
  376.  
  377.    mov   ds, cs:_ds
  378.    mov   ImageHandle, ax
  379.  
  380.    ; calc file pointer position
  381.    mov   ax, SectorSize
  382.    mov   dx, word ptr StartSector
  383.    dec   dx
  384.    mul   dx
  385.    push  ax                  ; low order word
  386.    mov   cx, dx              ; hi order word
  387.    mov   dx, word ptr StartSector+2
  388.    jz    @F
  389.    mov   ax, SectorSize
  390.    mul   dx
  391.    add   cx, ax               ; high order word in cx for set
  392.  @@:
  393.    pop   dx                   ;low order word goes in dx for set
  394.    add   dx, StartOffset
  395.  
  396. .if cs:inDOS
  397.    ;set file pointer position
  398.    mov   bp, 4200h
  399.    mov   bx, ImageHandle
  400.    mov   ax, 1228h
  401.    int   2fh
  402.    jnc   @f
  403.    mov   cx, (DeviceError OR DE_SectorNoFound)
  404.    jmp   InDOSXit
  405.  @@:
  406.    mov   ds, cs:_ds
  407.    ; read cd sector
  408.    mov   bx, ImageHandle
  409.    mov   cx, BytesToRead
  410.    lds   dx, DTAp
  411.    mov   ax, 1229h
  412.    int   2fh
  413.    jnc   @F
  414.     mov   cx, (DeviceError OR DE_ReadError)
  415.    jmp   InDOSXit
  416.  @@:
  417.    xor cx,cx        ; no error
  418.    ;  close file
  419.  InDOSXit:
  420.    mov   bx, cs:ImageHandle
  421.    mov   ax, 1227h
  422.    int   2fh
  423.    mov   ax, cx
  424.    ; restore incoming stack
  425.    mov   ss, cs:_SS
  426.    mov   sp, cs:_SP
  427.  
  428. .else    ; not in DOS
  429.  
  430.    ;set file pointer position
  431.    mov   bx, ImageHandle
  432.    mov   ax, 4200h
  433.    int   21h
  434.    jnc   @f
  435.    mov   cx, (DeviceError OR DE_SectorNoFound)
  436.    jmp   NotInDOSXit
  437.  @@:
  438.    mov   ds, cs:_ds
  439.    ;read cd sector
  440.    mov   bx, ImageHandle
  441.    mov   cx, BytesToRead
  442.    lds   dx, DTAp
  443.    mov   ax, 3f00h
  444.    int   21h
  445.    jnc   @f
  446.    mov   ah, 0ffh
  447.    mov   cx, (DeviceError OR DE_ReadError)
  448.    jmp   NotInDOSXit
  449.  @@:
  450.    xor cx, cx        ; no error
  451.    ;  close the file
  452.  NotInDOSXit:
  453.    mov   bx, cs:ImageHandle
  454.    mov   ax, 3e00h
  455.    int   21h
  456.    mov   ax, cx
  457.  
  458. .endif
  459.  
  460. restore:                   ; ax has return status
  461.    mov ds, cs:_ds
  462.    les di, MySDAp
  463.    mov CX, MySDASize
  464.    mov si, offset MySDASave
  465.    cld
  466.    rep movsb                   ; ds:si=>es:di
  467.  
  468.    ret
  469.  
  470. ReadImage  endp
  471.  
  472. ToHex proc near C public uses ax bx cx dx, Num:word
  473.       mov   cl, 4
  474.       mov   ch, 4
  475.       mov   ah, 02h
  476.       mov   dx, Num
  477.       .while ch > 0
  478.           rol   dx, cl
  479.           mov   bx, dx
  480.           and   dx, 0fh
  481.           .if dl < 0Ah
  482.               add  dl, '0'
  483.           .else
  484.               add  dl, 'A' - 0Ah
  485.           .endif
  486.           int   21h
  487.           mov   dx, bx
  488.           dec   ch
  489.       .endw
  490.       ret
  491. ToHex    endp
  492.  
  493. StringEq? proc near C uses  ds es di si, S1:fptr,S2:fptr
  494.     ; cx is string length on entry
  495.     mov   ax, word ptr S1
  496.     mov   si, ax
  497.     mov   ax, word ptr S1+2
  498.     mov   ds, ax
  499.     mov   ax, word ptr S2
  500.     mov   di, ax
  501.     mov   ax, word ptr S2+2
  502.     mov   es, ax
  503.     repe  cmpsb
  504.     ret
  505.     ; returns with cx = 0 if strings match
  506. StringEq? endp
  507.  
  508. MovString proc near C uses   ds es di si, S1:fptr,S2:fptr
  509.     ; cl has number of chars to move
  510.     mov   ax, word ptr S1
  511.     mov   si, ax
  512.     mov   ax, word ptr S1+2
  513.     mov   ds, ax
  514.     mov   ax, word ptr S2
  515.     mov   di, ax
  516.     mov   ax, word ptr S2+2
  517.     mov   es, ax
  518.     cld
  519.     rep movsb                   ; ds:si=>es:di
  520.     ret
  521. MovString endp
  522.  
  523. MsgOut    proc  near C public uses ax bx dx, msg:nptr
  524.       mov      ah, 02h       ; display ch function
  525.       mov      bx, msg
  526.       mov      dl, ds:[bx]
  527.       .while (dl != '$' && dl != 0)
  528.          int      21h
  529.          inc      bx
  530.          mov      dl, ds:[bx]
  531.       .endw
  532.       ret
  533. MsgOut    endp
  534.  
  535.  
  536.      byte "End of CDHD"
  537.  
  538. LastByte               label byte
  539. ;============================================================================
  540. ;  everything below this line is discarded after installing the driver
  541.  
  542. ArgumentNotFound        EQU     2       ; Unrecognized argument
  543. NoArgumentsFound        EQU     1       ; No argument in command line
  544. ArgumentFound           EQU     0       ; Ok argument in command line
  545.  
  546. IOCtlInBuf       byte     5 dup(?)
  547.  
  548. FName            byte     sizeof DriveEntry.ImageFile dup (0)
  549.                  byte     128 dup(0)
  550. DOffset          word     0
  551.  
  552. DontInstall             equ     1
  553. Install                 equ     0
  554. InstallFlag             byte    DontInstall
  555.  
  556. InstallMsg  db cr,lf,"Copyright 1995, John H. McCoy."
  557.             db cr,lf,"SHSU-CDH CD HardDisk cache driver version 1.0 Installed."
  558.             db cr,lf, "$"
  559. UnInstallMsg       db " SHSUCDHD Uninstalled and memory freed",cr,lf,"$"
  560. CouldNotRemoveMsg  db "Can't un-install SHSUCDHD.",cr,lf,"$"
  561. NotInstalledMsg db "SHSUCDHD not installed.",cr,lf,"$"
  562. FileNotFoundMsg db "Can't open any cache image file.",cr,lf,"$"
  563. InvalidImageFileMsg db "Image File Name invalid or doesn't exist",cr,lf,"$"
  564. HelpMsg db  cr,lf,"Usage:  SHSUCDHD /F:imagefilename  [/U] [/?]"
  565.         db  cr,lf,"Installs as SHSU-CDH.  Use with SHSUCDX."
  566.         db  cr,lf,"Attempting to use MSCDEX will crash your system.","$"
  567. NewLine db  cr,lf,"$"
  568. Init  proc far
  569.  
  570. local _cx,_di,_es : word
  571.  
  572.       mov      cs:PSP, ds            ; save PSP
  573.       mov      ax, cs                ; now set DS to CS
  574.       mov      ds, ax
  575.  
  576.    ;* If driver is loaded from config.sys using device=drivername parms
  577.    ;* then rhINIT points to the first character following the drivername
  578.    ;* and a CR follows the last parm.  When loaded by executing, the
  579.    ;* command line is available in the PSP.(len +80h, 1st ch +81h, no CR)
  580.  
  581.    ; check for uninstall
  582.       sub      ch, ch
  583.       mov      di, 80h            ; command line length psp +80h
  584.       mov      cl, es:[di]
  585.       mov      al, 'U'            ; /U unInstall driver
  586.       call     GetParm
  587.       .if ax == ArgumentFound
  588.           call UnInstallCDHD
  589.           jmp   Xit
  590.       .elseif ax == NoArgumentsFound
  591.           jmp   Dont
  592.       .endif
  593.     ; check for use help
  594.       sub      ch, ch
  595.       mov      di, 80h            ; command line length psp +80h
  596.       mov      cl, es:[di]
  597.       mov      al, '?'            ; /? help
  598.       call     GetParm
  599.       .if ax == ArgumentFound
  600.           invoke MsgOut, addr HelpMsg
  601.           jmp   Xit
  602.       .endif
  603.  
  604.       mov      di, 80h                ; command line length at psp +80h
  605.       sub      ch, ch
  606.       mov      cl, es:[di]
  607.       mov      al, 'F'            ; /F:filename
  608.       call     FindParm
  609.      .if   ax == ArgumentFound
  610.          call    MoveName
  611.          mov    _cx, cx
  612.          mov    _di, di
  613.          mov    _es, es
  614.  
  615.           ; canonicalize filename
  616.           mov   ax, cs
  617.           mov   es, ax
  618.           mov   di, offset FName
  619.           mov   si, offset FName
  620.           mov   ah, 60h
  621.           int   21h
  622.  
  623.          ;open the file  see if it exists
  624.           mov   dx, offset FName
  625.           mov   ax, 3d00h
  626.           int   21h
  627.           jc    @f          ; file didn't open
  628.           ; close the file
  629.           mov   bx, ax
  630.           mov   ax,3e00h
  631.           int   21h
  632.           invoke msgout,addr FName
  633.           invoke msgout,addr NewLine
  634.           mov cl,sizeof Drive.ImageFile
  635.           invoke MovString,addr FName, addr Drive.ImageFile
  636.           mov   ax, DriveNormalReady
  637.           mov   word ptr Drive.Status, ax
  638.           add   DOffset, sizeof DriveEntry
  639.           inc   byte ptr CDHDHdr.Units
  640.         @@:
  641.           mov   cx, _cx
  642.           mov   di, _di
  643.           mov   es, _es
  644.  
  645.           mov   al, 'F'            ; /F:filename
  646.           call  FindParm
  647.           .if  ax==ArgumentFound
  648.              call    MoveName
  649.              mov    _cx, cx
  650.              mov    _di, di
  651.              mov    _es, es
  652.  
  653.             ; canonicalize filename
  654.              mov   ax, cs
  655.              mov   es, ax
  656.              mov   di, offset FName
  657.              mov   si, offset FName
  658.              mov   ah, 60h
  659.              sub   al, al
  660.              int   21h
  661.             ;open the file  see if it exists
  662.              mov   dx, offset FName
  663.              mov   ax, 3d00h
  664.              int   21h
  665.              jc    @f      ; file not found
  666.              ; close the file
  667.              mov   bx, ax
  668.              mov   ax,3e00h
  669.              int   21h
  670.              invoke msgout,addr FName
  671.              invoke msgout,addr NewLine
  672.              mov cl,sizeof Drive.ImageFile
  673.              mov   bx, DOffset
  674.              invoke MovString,addr FName, addr Drive[bx].ImageFile
  675.              mov   ax, DriveNormalReady
  676.              mov   word ptr Drive[bx].Status, ax
  677.              add   DOffset, sizeof DriveEntry
  678.              inc   byte ptr CDHDHDR.Units
  679.            @@:
  680.           mov   cx, _cx
  681.           mov   di, _di
  682.           mov   es, _es
  683.           mov   al, 'F'            ; /F:filename
  684.           call  FindParm
  685.           .if  ax==ArgumentFound
  686.              call    MoveName
  687.              mov    _cx, cx
  688.              mov    _di, di
  689.              mov    _es, es
  690.  
  691.             ; canonicalize filename
  692.              mov   ax, cs
  693.              mov   es, ax
  694.              mov   di, offset FName
  695.              mov   si, offset FName
  696.              mov   ah, 60h
  697.              sub   al, al
  698.              int   21h
  699.             ;open the file  see if it exists
  700.              mov   dx, offset FName
  701.              mov   ax, 3d00h
  702.              int   21h
  703.              jc    @f      ; file not found
  704.              ; close the file
  705.              mov   bx, ax
  706.              mov   ax,3e00h
  707.              int   21h
  708.              invoke msgout,addr FName
  709.              invoke msgout,addr NewLine
  710.              mov cl,sizeof Drive.ImageFile
  711.              mov   bx, DOffset
  712.              invoke MovString,addr FName, addr Drive[bx].ImageFile
  713.              mov   ax, DriveNormalReady
  714.              mov   word ptr Drive[bx].Status, ax
  715.              add   DOffset, sizeof DriveEntry
  716.              inc   byte ptr CDHDHDR.Units
  717.            @@:
  718.           mov   cx, _cx
  719.           mov   di, _di
  720.           mov   es, _es
  721.           mov   al, 'F'            ; /F:filename
  722.           call  FindParm
  723.           .if  ax==ArgumentFound
  724.              call    MoveName
  725.              mov    _cx, cx
  726.              mov    _di, di
  727.              mov    _es, es
  728.  
  729.             ; canonicalize filename
  730.              mov   ax, cs
  731.              mov   es, ax
  732.              mov   di, offset FName
  733.              mov   si, offset FName
  734.              mov   ah, 60h
  735.              sub   al, al
  736.              int   21h
  737.             ;open the file  see if it exists
  738.              mov   dx, offset FName
  739.              mov   ax, 3d00h
  740.              int   21h
  741.              jc    @f      ; file not found
  742.              ; close the file
  743.              mov   bx, ax
  744.              mov   ax,3e00h
  745.              int   21h
  746.              invoke msgout,addr FName
  747.              invoke msgout,addr NewLine
  748.              mov cl,sizeof Drive.ImageFile
  749.              mov   bx, DOffset
  750.              invoke MovString,addr FName, addr Drive[bx].ImageFile
  751.              mov   ax, DriveNormalReady
  752.              mov   word ptr Drive[bx].Status, ax
  753.              add   DOffset, sizeof DriveEntry
  754.              inc   byte ptr CDHDHDR.Units
  755.            @@:
  756.           mov   cx, _cx
  757.           mov   di, _di
  758.           mov   es, _es
  759.           mov   al, 'F'            ; /F:filename
  760.           call  FindParm
  761.           .if  ax==ArgumentFound
  762.              call    MoveName
  763.              mov    _cx, cx
  764.              mov    _di, di
  765.              mov    _es, es
  766.  
  767.             ; canonicalize filename
  768.              mov   ax, cs
  769.              mov   es, ax
  770.              mov   di, offset FName
  771.              mov   si, offset FName
  772.              mov   ah, 60h
  773.              sub   al, al
  774.              int   21h
  775.             ;open the file  see if it exists
  776.              mov   dx, offset FName
  777.              mov   ax, 3d00h
  778.              int   21h
  779.              jc    @f      ; file not found
  780.              ; close the file
  781.              mov   bx, ax
  782.              mov   ax,3e00h
  783.              int   21h
  784.              invoke msgout,addr FName
  785.              invoke msgout,addr NewLine
  786.              mov cl,sizeof Drive.ImageFile
  787.              mov   bx, DOffset
  788.              invoke MovString,addr FName, addr Drive[bx].ImageFile
  789.              mov   ax, DriveNormalReady
  790.              mov   word ptr Drive[bx].Status, ax
  791.              add   DOffset, sizeof DriveEntry
  792.              inc   byte ptr CDHDHDR.Units
  793.            @@:
  794.           .endif
  795.           .endif
  796.           .endif
  797.           .endif
  798.  
  799.          .if CDHDHDR.Units==0
  800.             jmp FileNotFound
  801.          .endif
  802.          ;get the SDA ptr and setup some other ptrs
  803.           mov   ax, 5d06h
  804.           int   21h
  805.           mov   ax, ds
  806.           push  cs
  807.           pop   ds
  808.           mov   MySDASize,cx
  809.           mov   word ptr MySDAp+2, ax ; segment is SDA seg
  810.           mov   DOS_SS, ax            ; segment is DOS's seg
  811.           mov   word ptr InDOSp+2, ax ; InDOS flag seg
  812.           mov   word ptr InDOSp, si
  813.           inc   word ptr InDOSp       ; InDos flag +1
  814.           mov word ptr MySDAp, si
  815.           .if (si== 02ceh)          ;if SDA is @ 2ceh then its DOS 3.3+
  816.               add si,  5B8h
  817.           .else                     ; else assume DOS 4 or later
  818.               add si,  600h
  819.           .endif
  820.           mov DOS_SP, si            ; set top of disk stack in SDA
  821.  
  822.           mov    InstallFlag, DontInstall
  823.              call Link
  824.           .if (InstallFlag == DontInstall)
  825.              jmp Dont
  826.           .endif
  827.  
  828.           invoke MsgOut, addr InstallMsg
  829.  
  830.           mov    ax, PSP
  831.           mov    ds, ax
  832.           mov    ax, ds:[2Ch]           ; find environment and release it
  833.           mov    es, ax
  834.           mov    ah, 49h
  835.           int    21h
  836.           sub    ax, ax
  837.           mov    ds:[2Ch], ax           ; zero the evironment ptr
  838.  
  839.           if  (LastByte-CDHDHdr+1) mod 16
  840.               roundup = 1
  841.           else
  842.               roundup = 0
  843.           endif
  844.  
  845.           mov     dx,((LastByte-CDHDHdr)+1+100h)/16+roundup; para to keep
  846.           mov     ah,31h        ; stay resident and
  847.           int     21h             ; exit
  848.       .else
  849.           jmp   FileNotFound
  850.       .endif
  851.  
  852.    FileNotFound:
  853.       invoke MsgOut, addr Drive.ImageFile
  854.       invoke MsgOut, addr  FileNotFoundMsg
  855.    Dont:
  856.       invoke MsgOut, addr  NotInstalledMsg
  857.    XIT:
  858.       .exit
  859.  
  860. Init endp
  861.  
  862. Link   proc near uses es
  863.       mov      ax, 5200h               ; get list of list
  864.       int      21h                     ; we assume DOS 3.1 or later
  865.       add      bx, 22h                 ; es:bx[22] is NUL device header
  866.       mov      ax, es:[bx]               ; put NUL.next in our header
  867.       mov      word ptr CDHDHdr.NextDriver, ax
  868.       mov      ax, es:[bx+2]
  869.       mov      word ptr CDHDHdr.NextDriver+2, ax
  870.       mov      ax, 0                   ; then point NUL header at us
  871.       mov      es:[bx], ax
  872.       mov      es:[bx+2], cs
  873.       mov      InstallFlag, Install
  874.       ret
  875. Link   endp
  876.  
  877. UnInstallCDHD proc near
  878.  
  879.    local _bx,_es:word
  880.  
  881.       push     es                      ; save our psp address
  882.       mov      ax, 5200h               ; get list of list
  883.       int      21h                     ; we assume DOS 3.1 or later
  884.       add      bx, 22h                 ; es:bx[22] is NUL (1st) device header
  885.                                        ; es:bx now pointing at NUL header
  886.    TryNext:
  887.       cld
  888.       mov      _bx, bx                 ; save current header addr
  889.       mov      _es, es
  890.       les      bx, es:[bx]             ; load next header addr into es:bx
  891.       mov      ax, es
  892.       cmp      bx, 0FFFFh              ; end of drivers?
  893.       je       DriverNotFound
  894.       mov      cx, 8
  895.       lea      di, devHdr.DeviceName[bx]       ; es:di is chained device name
  896.       mov      si, offset CDHDHdr.DeviceName   ; ds:si is our device name
  897.       repe     cmpsb                   ; if equ its the one we are looking for
  898.       jne      TryNext
  899.       push     ds
  900.       mov      ax, es                  ; es:bx is addr of driver being removed
  901.       mov      ds, ax                  ; put it into ds:si
  902.       mov      si, bx                  ;
  903.       mov      cx, 4                   ;
  904.       mov      es, _es                 ;
  905.       mov      di, _bx                 ; previous header now in es:di
  906.       rep      movsb                   ; move address ds:si -> es:di
  907.       mov      es, ax                  ; es now points at unlinked driver
  908.       pop      ds                      ; cs=ds=@code
  909.       mov      ax, es                   ; locate the
  910.       sub      ax, 10h                  ; psp of installed driver
  911.       mov      es, ax                   ;
  912.       mov      bx, 16h                  ; installed drivers parent psp pointer
  913.       pop      ax                       ; our psp address(pushed es above)
  914.       mov      es:[bx],ax               ; make us parent of TSR
  915.       lea      ax, UnInstallExit        ; set TSRs
  916.       mov      bx, 0Ah                  ; terminate address
  917.       mov      es:[bx], ax              ; to come back to
  918.       mov      ax, cs
  919.       mov      es:[bx]+2, ax            ; us
  920.       mov      bx, es                   ; now make TSRs psp the
  921.       mov      ah, 50h                  ; current psp
  922.       int      21h
  923.  
  924.       push     bp
  925.       mov      _SS, ss                  ; save stack info
  926.       mov      _SP, sp
  927.       mov      ah, 4Ch                  ; terminate TSR and
  928.       int      21h                      ; come back to next
  929.  
  930.     UnInstallExit:
  931.       mov      ax, cs
  932.       mov      ds, ax                   ; reestablish addressing
  933.       mov      sp, _SP                  ; and stack info
  934.       mov      ss, _SS
  935.       pop      bp
  936.  
  937.       invoke MsgOut, addr UnInstallMsg
  938.       ret
  939.  
  940.   DriverNotFound:
  941.       pop es
  942.       invoke MsgOut, addr  CouldNotRemoveMsg
  943.       invoke MsgOut, addr  NotInstalledMsg
  944.       ret
  945.  
  946. UnInstallCDHD endp
  947.  
  948. MoveName proc near
  949.       mov     dx, sizeof FName
  950.       xor  si,si                                   ; es:di points to 1st char
  951.       .repeat                                      ; cx chars left on cmd line
  952.           mov al, es:[di]
  953.           .if ((al==' ') || (al==0) ||(al=='/')||(cx==0))
  954.               .if cx!= 0
  955.                  dec cx
  956.               .endif
  957.               mov   al, 0
  958.               .repeat
  959.                  mov    byte ptr FName[si], al
  960.                  inc    si
  961.               .until (si==dx)
  962.           .else
  963.              .if (al >= 'a' && al <= 'z')
  964.                  and    al, 11011111y           ; upper case it
  965.               .endif
  966.               mov    byte ptr FName[si], al
  967.               inc    di
  968.               dec    cx
  969.               inc    si
  970.           .endif
  971.       .until (si==dx)
  972.       ret
  973. MoveName endp
  974.  
  975. FindParm proc near
  976.  
  977.    ; al      parm code we are to find       /X: or -X:
  978.    ; es:di   first char on command line -1
  979.    ; cx      number of characters left on command line
  980.  
  981.  GetNext:                             ; this code allows us to handle names
  982.       call     GetParm                ; like   -C:NET-CD
  983.       cmp      ax, ArgumentFound
  984.       jne      NotFound
  985.       inc      di                     ; found /X or -X, is next char a ':' ?
  986.       dec      cl
  987.       mov      al, es:[di]
  988.       cmp      al, ':'
  989.       je       FoundIt
  990.       loop     GetNext
  991.       mov      ax, ArgumentNotFound
  992.       ret
  993.  
  994.   FoundIt:
  995.       inc   di                           ; /X:name  make di point @ name
  996.       dec   cl
  997.       mov   ax, ArgumentFound
  998.   NotFound:
  999.    ret
  1000.  
  1001. FindParm endp
  1002.  
  1003. ;* GetParm - Scans command line for argument of form /X or -X  where
  1004. ;* X = specified ASCII character. Presumes that argument is preceded
  1005. ;* by a '/' or a '-'. Comparisons are case insensitive.
  1006. ;*
  1007. ;* Params: ES:DI = Address of CommandLine -1
  1008. ;*         AL    = Paramater character to scan for
  1009. ;*         CX    = command line length
  1010. ;*
  1011. ;* Return: AX    = One of the following codes:
  1012. ;*                 NoArgumentsFound  if empty command line
  1013. ;*                 ArgumentFound  if argument found
  1014. ;*                 ArgumentNotFound if argument not as specified
  1015. ;*         ES:DI = Pointer to found argument
  1016. ;*         CX    = chars left on command line including arg or 0
  1017.  
  1018. GetParm PROC NEAR
  1019.  
  1020.         mov     ah, NoArgumentsFound    ; assume no /X style arguments
  1021.         jcxz    exit
  1022.         .if (al >= 'a' && al <= 'z')
  1023.             and    al, 11011111y           ; Make character upper case
  1024.         .endif
  1025.  
  1026. ; Find start of argument
  1027.  
  1028. loop1:
  1029.         inc     di                      ;
  1030.         mov     dl, es:[di]             ; Get character from argument list
  1031.         cmp     dl, '/'                 ; Find option prefix '/'
  1032.         je      analyze
  1033.         cmp     dl, '-'                 ;   or option prefix '-'
  1034.         je      analyze
  1035.  
  1036.         loop    loop1
  1037.  
  1038.         jmp     exit
  1039.  
  1040. ; '/' or '-' prefix found. Compare command-line character
  1041. ; with character specified in AL.
  1042. analyze:
  1043.         inc     di
  1044.         dec     cl
  1045.         jcxz    exit
  1046.         mov     ah, ArgumentFound         ; Assume argument is okay
  1047.         mov     dl, es:[di]
  1048.         .if (dl >= 'a' && dl <= 'z')
  1049.             and    dl, 11011111y           ; Make character upper case
  1050.         .endif
  1051.         cmp     dl, al
  1052.         je      exit                    ; specified char
  1053.         mov     ah, ArgumentNotFound    ; Else signal bad argument,
  1054.         loop    loop1             ;   continue scan
  1055.  
  1056. exit:
  1057.         mov     al, ah
  1058.         cbw                             ; AX = return code
  1059.         ret
  1060.  
  1061. GetParm ENDP
  1062.  
  1063.  
  1064. .stack
  1065.         byte 80 dup(?)
  1066.         byte "This is here to keep loadhigh happy if NETX is loaded."
  1067.  
  1068.  
  1069.         end  Init
  1070.  
  1071.  
  1072.