home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / SYSTEM / IDRV01.ZIP / REMDRV.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-11-19  |  14.6 KB  |  605 lines

  1. PAGE    80,132         
  2. NAME    remdrv
  3.  
  4. ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
  5. ;                                LUBLIN 24-02-1989    ;
  6. ;   remdrv (v1.03)                                    ;
  7. ;                                by JW        ;
  8. ;...............................................................................;
  9.  
  10.  
  11.  
  12.         ASSUME DS:code, SS:code ,CS:code ,ES:code
  13. code        SEGMENT    Para Public 'code'
  14.         ORG    100h
  15.  
  16. start:        jmp    starter        ; jump over data
  17.  
  18. ;.................................................................................
  19.  
  20. lf        equ    0ah        ; line feed
  21. cr        equ    0dh        ; carriage return
  22.  
  23. ZERO        equ    0
  24. TAB        equ    9
  25.  
  26. DIB_SIZE    equ    21h
  27. FIRST_DIB    equ    26h
  28. FIRST_DA    equ    3ch
  29. NUM_OF_DRV    equ    46h
  30. TOTAL_NUM    equ    47h
  31.  
  32. ;...............................................................................
  33. two        db    2        
  34. dos_dep        dw    0    ;0 - if dos 3.xx, 6 - if dos 4.xx or 5.xx
  35. dos_dep2    db    0    ;0 - if dos 3.xx, 7 - if dos 4.xx or 5.xx
  36. dos_dep3    dw    0    ;0 - if dos 3.xx, 1 - if dos 4.xx or 5.xx
  37.  
  38. flags        db    0    ;1 - device was loaded by Idrv
  39.  
  40. drv_num        db    0        ;current drive number
  41.  
  42. dos_seg        dw    0        ;IMBDOS segment
  43.  
  44. drv_beg        dw    0        ;Start of driver (must be on para boundry)
  45.  
  46. DIB_offs    dw    0        ;Address of ...
  47. DIB_seg        dw    0        ; ... driver's DIB
  48.  
  49. header_offs    dw    0
  50. header_seg    dw    0
  51.  
  52. last_offs    dw    0        ;Address of ...
  53. last_seg    dw    0        ; ... DIB to be last
  54.  
  55. xms_offs     dw    0
  56. xms_seg         dw    0
  57.  
  58. DA_flag        db    0        ;non zero if proper Drive Area found
  59. dev_flag    db    0        ;set to 1 if block device
  60. dev_count    db    0
  61.  
  62. buf        db    10 dup (0)    ;area for device driver name
  63. TXT_LEN        equ    $ - buf        
  64.  
  65. first_dev    db    0
  66.         db    ': - '
  67. last_dev    db    0
  68.         db    ':    '
  69. PATT_LEN    equ    $ - first_dev
  70.  
  71. one_dev        db    0
  72.         db    ':'
  73.         db    9 dup (' ')
  74. ONLY_ONE    equ    $ - one_dev    
  75.  
  76. signature     db    'IdrvCB '
  77. SIG_LEN        equ    $ - signature
  78.  
  79. ;......................................................................................
  80. ;...............................................................................
  81.  
  82. starter:    lea    dx,header
  83.         call    print_msg    
  84.         mov    ah,30h
  85.         int    21h            ;Get DOS version number
  86.         lea    dx,err_txt
  87.         cmp    al,3
  88.         jb    pr_txt
  89. check_ver:
  90.         je    get_list        ;DOS v3.xx
  91.         cmp    al,5            ;ver. above 5 ?
  92.         ja    pr_txt            ;yes,jump
  93.         mov    dos_dep,6        ;No,change entry length of Open Files Table 
  94.         mov    dos_dep2,7        ;Change entry length of Drive Area
  95.         mov    dos_dep3,1        ;Change entry length of Disk Info Block
  96. get_list:
  97.         mov    ah,52h
  98.         int    21h            ;Get vector for int 25H
  99.         mov    dos_seg,es
  100.         lea    dx,not_PC_Dos
  101.         cmp    word ptr es:52h,'UN'    ;NUL device ?
  102.         jne    pr_txt            ;No,jump
  103.         les    di,dword ptr es:02ah    ;get address of DOS file table
  104.         add    di,dos_dep        ;change entry length of OFT if necessary
  105.         cmp    byte ptr es:[di + 05bh],'C'    ;Entry for dev. CON ?
  106.         jne    pr_txt
  107.         cmp    word ptr es:[di + 05ch],'NO'    
  108.         je    go_on      
  109. pr_txt:
  110.         jmp    exit        ;Jump to print message and qiut
  111. go_on:        
  112.         jmp    ldrv
  113. ;...............................................................................
  114. ;...............................................................................
  115. ;    messages to display
  116.         db    'Program written by Janusz Wojcik',cr,lf
  117. err_txt        db    'IDrv: That version of DOS is not supported!',cr,lf,lf,'$'
  118. not_PC_Dos    db    'IDrv: Not PC DOS ',cr,lf,lf,'$'
  119. unlink_OK    db    cr,lf,'Device Driver uninstalled!',cr,lf,'$'
  120. unlink_err    db    cr,lf,"Can't uninstall device driver!",cr,lf,'$'
  121. unlink_quit    db    cr,lf,"Device driver not uninstalled!",cr,lf,'$'
  122. header        db    'Device Drivers Uninstaller  v1.03',cr,lf
  123.         db    '(C)  1990  by Janusz Wojcik Lublin,Poland.',cr,lf,lf,'$'
  124. intro        db    'This is device ','$'
  125. not_idrv_dev    db    cr,lf,'Not loaded by Idrv !','$'
  126. inquiry        db    cr,lf,'Delete it (y/n) ?','$'
  127. ;....................................................................................
  128. ;...............................................................................
  129.  
  130. device_header    struc
  131. next_offs    dw    ?
  132. next_seg    dw    ?
  133. dev_attr    dw    ?
  134. dev_strategy    dw    ?
  135. dev_interrupt    dw    ?
  136. name_unit    db    8 dup(?)
  137. device_header    ends
  138. ;...............................................................................
  139. ;...............................................................................
  140. ;    the program body
  141. ;..............................................................................        
  142. ldrv:  
  143.  
  144.         mov    es,dos_seg
  145.         mov    si,48h
  146.         les    si,dword ptr es:[si]    ;Address of next dev. header
  147.         call    copy_name        ;get device driver name
  148.         call    check_type        ;check whether character or block device
  149.         call    print_name        ;display driver name 
  150.         call    check_icb        ;check if Idrv Control Block precedes Device Header
  151.         lea    dx,inquiry
  152.         call    print_msg        ;ask if remove device driver
  153.         mov    ah,1
  154.         int    21h            ;get char from stdin
  155.         cmp    al,'y'            ;remove dev. driver ?
  156.         je    check_attr
  157.         lea    dx,unlink_quit
  158.         jmp    exit_OK
  159.  
  160. check_attr:        
  161.         mov    ax,es:dev_attr[si]
  162.         test    ah,80h            ;Character device ?
  163.         jnz    unlnk_dev        ;Yes,jump to unlink device headers
  164.  
  165.         mov    ax,es
  166.         mov    dx,si
  167.         mov    header_offs,dx
  168.         mov    header_seg,ax
  169.  
  170.         call    seek_DIB        ;Seek DIB pointing to ES:SI
  171.         jc    exit_err
  172.         mov    ax,DIB_offs
  173.         mov    last_offs,ax
  174.         mov    ax,DIB_seg
  175.         mov    last_seg,ax
  176. find_CDS:
  177.         mov    si,es
  178.         mov    dx,bx
  179.         mov    DA_flag,ZERO
  180.         call    seek_DA            ;Seek DA poniting to ES:BX
  181.         cmp    DA_flag,ZERO
  182.         jz    exit_err
  183.         mov    dx,header_offs
  184.         mov    ax,header_seg
  185.         
  186.         call    seek_DIB
  187.         jnc    find_CDS
  188. chain_end:
  189.         les    bx,dword ptr last_offs
  190.         mov    si,dos_dep3
  191.         mov    word ptr es:[si + bx + 18h],0ffffh    ;Mark DIB as the last DIB
  192.         mov    al,byte ptr es:[bx]
  193.         inc    al
  194.         mov    es,dos_seg
  195.         mov    byte ptr es:NUM_OF_DRV,al        ;Set real number of drives
  196.                 
  197. unlnk_dev:
  198.         call    unlink_dev        ;Link device headers
  199.         lea    dx,unlink_OK
  200.         jmp    exit_OK
  201. exit_err:
  202.         lea    dx,unlink_err
  203. exit_OK:
  204.  
  205. exit:
  206.         call    print_msg
  207.         mov    ah,4ch        ;EXIT
  208.         mov    al,1        ;Set return code
  209.         int    21h
  210. ;...............................................................................
  211. print_msg:    
  212.         mov    ah,9
  213.         int    21h
  214.         ret
  215. ;..............................................................................
  216. ; copy_name:
  217. ;    copy device driver name from Device Header into local buffer 
  218. ; INPUT:
  219. ;    ES:SI - address of Device Header for device
  220. ;..............................................................................
  221. copy_name:    push    si
  222.         push    es
  223.         push    ds
  224.  
  225.         mov    ax,es:dev_attr[si]
  226.         test    ah,80h            ;Character device ?
  227.         jnz    copy            ;Yes,skip
  228.         mov    dev_flag,1        ;Signal that block device    
  229. copy:
  230.         
  231.         mov    cx,4
  232.         mov    di,offset buf
  233.         push    es
  234.         pop    ds        ;DS = ES    
  235.         add    si,10
  236.         push    cs        
  237.         pop    es        ;ES = CS
  238.         cld
  239.         rep    movsw        ;copy device name 
  240.  
  241. quit_copy:
  242.         pop    ds
  243.         pop    es
  244.         pop    si
  245.         ret
  246. ;................................................................................
  247. ; check_type:
  248. ;    check if block device.
  249. ;    Prepare for displaying device name if so.
  250. ; INPUT:
  251. ;    ES:SI - address of Device Header for device
  252. ;................................................................................
  253. check_type:
  254.         cmp    dev_flag,1
  255.         jne    quit_check
  256.         push    es
  257.         push    si
  258.         mov    ax,es
  259.         mov    dx,si
  260.         call    seek_DIBs
  261.  
  262.         inc    first_dev
  263.         add    first_dev,40h
  264.         mov    al,first_dev
  265.         mov    last_dev,al
  266.         mov    al,dev_count
  267.         dec    al
  268.         add    last_dev,al
  269.         pop    si
  270.         pop    es
  271. quit_check:        
  272.         ret
  273. ;...............................................................................
  274. ; seek_DIBS:
  275. ;    find number of the first and the last device 
  276. ;    AX:DX - address of Device Header for device
  277. ;...............................................................................
  278. seek_DIBs    proc    near
  279.  
  280.         push    es
  281.         push    si
  282.         mov    es,dos_seg
  283.         les    bx,es:FIRST_DIB            ;Get address of first DIB
  284.         mov    si,dos_dep3        
  285. next_DIB_in_chain:    
  286.         cmp    word ptr es:[si + bx + 12h],dx
  287.         jnz    if_last_DIB
  288.         cmp    word ptr es:[si + bx + 14h],ax
  289.         jnz    if_last_DIB
  290.     
  291.         cmp    dev_count,0            ;first matched device ?
  292.         jnz    inc_count            ;No,jump
  293.         mov    cl,es:[bx]             ;get device number
  294.         mov    first_dev,cl
  295. inc_count:
  296.         inc    dev_count
  297. if_last_DIB:
  298.         cmp    word ptr es:[si + bx + 18h],0ffffh    ;The last DIB ?
  299.         jz    seek_DIBS_end                ;Yes,jump
  300.  
  301.         les    bx,dword ptr es:[si + bx + 18h]        ;Get addr. of next DIB
  302.         jmp    next_DIB_in_chain
  303.         
  304. seek_DIBs_end:  
  305.         pop    si
  306.         pop    es
  307.         clc
  308.         ret
  309. seek_DIBs    endp
  310. ;...............................................................................        
  311. ; print_name:
  312. ;    display device driver name
  313. ;...............................................................................
  314. print_name:
  315.         push    es
  316.         push    si
  317.         lea    dx,intro
  318.         call    print_msg
  319.         mov    cx,TXT_LEN
  320.         mov    dx,offset buf
  321.         cmp    dev_flag,0        ;Character device?
  322.         je    call_DOS        ;Yes,jump
  323.  
  324.         cmp    dev_count,1        ;More than one device ?
  325.         jnz    not_one_dev        ;Yes,jump
  326.         mov    cl,first_dev
  327.         mov    one_dev,cl
  328.         mov    dx,offset one_dev
  329.         mov    cx,ONLY_ONE
  330.         jmp    call_DOS
  331. not_one_dev:        
  332.         mov    dx,offset first_dev
  333.         mov    cx,PATT_LEN
  334. call_DOS:
  335.         mov    ah,40h
  336.         mov    bx,1
  337.         int    21h
  338.         pop    si
  339.         pop    es
  340.         ret
  341. ;...............................................................................        
  342. ; check_icb:
  343. ;    check if Idrv Control Block precedes Device Header
  344. ; INPUT:
  345. ;    ES:SI - address of Device Header for device
  346. ;...............................................................................
  347. check_icb:
  348.         push    es
  349.         push    si
  350.         or    flags,1
  351.         xor    di,di
  352.         mov    ax,es
  353.         dec    ax
  354.         mov    es,ax
  355.         mov    si,offset signature
  356.         mov    cx,SIG_LEN
  357.         repz    cmpsb
  358.         jz    check_icb_end
  359.         and    flags,NOT(1)
  360.         lea    dx,not_idrv_dev
  361.         call    print_msg
  362. check_icb_end:
  363.         pop    si
  364.         pop    es
  365.         ret
  366. page;..........................................................................
  367. ; unlink_dev:                               .......
  368. ;    remove Device Header from the chain of Device Headers        .......
  369. ;..............................................................................
  370.  
  371.  
  372. unlink_dev:
  373.         mov    es,dos_seg
  374.         mov    si,48h
  375.         push    es
  376.         les    si,dword ptr es:[si]    ;Address of next dev. header
  377.         mov    bx,es:dev_attr[si]
  378.         test    bl,1            ;Stdin ?
  379.         jz    dechain            ;No,jump
  380.  
  381.         push    es
  382.         push    si
  383.         call    seek_stdin
  384.         jc    quit_unlink
  385.         mov    es,dos_seg
  386.         mov    es:32h,si        ;Change pointer to ...
  387.         mov    es:34h,ax        ; ... Stdin
  388.         les    bx,es:02ah        ;Get address of DOS file table
  389.         add    bx,dos_dep        ;change entry length of OFT if necessary
  390.         mov    es:[bx + 042h],si    ;Change address of dev.header ...
  391.         mov    es:[bx + 044h],ax    ; ... in Open Files Table
  392.         pop    si
  393.         pop    es
  394. dechain:
  395.         call    free_xms
  396.         mov    ax,es:next_offs[si]
  397.         mov    bx,es:next_seg[si]
  398.         pop    es
  399.         
  400.         cli
  401.         mov    es:48h,ax
  402.         mov    es:4ah,bx        
  403.         sti
  404.         jmp    quit_unlink
  405.     
  406. test_clk:    test    bl,8            ;Is it clock device ?
  407.         jz    quit_unlink        ;No,jump
  408.         mov    es:2eh,word ptr ZERO
  409.         mov    es:30h,ax
  410.         
  411. quit_unlink:
  412.         ret        
  413.             
  414. ;...............................................................................
  415. ;  free_xms:
  416. ;    frees XMS memory allocated by device driver
  417. ;  Input:
  418. ;    ES:SI - Device Header
  419. ;...............................................................................
  420. free_xms    proc     near
  421.  
  422.         push    es
  423.         push    bx
  424.         push    si
  425.  
  426.         test    flags,1            ;ICB found ?
  427.         jz    free_xms_end        ;No,jump
  428.  
  429.         mov    ax,es
  430.         dec    ax
  431.         mov    es,ax
  432.         inc    ax
  433.  
  434.         cmp    byte ptr es:[si + 7],'X'
  435.         jne    free_xms_end
  436.         cmp    word ptr es:[si + 8],'SM'
  437.         jne    free_xms_end
  438.         mov    dx,es:[si + 0eh]           ;get xms handle to DX
  439.         les    bx,dword ptr es:[si + 0ah]
  440.         cmp    byte ptr es:[bx],0eah        ;jmp xxxx:yyyy ?
  441.         jne    free_handle
  442.         cmp    es:[bx + 3],ax            ;jump into driver's segment ?
  443.         jne    free_handle
  444.         cli
  445.         mov    word ptr es:[bx],3ebh        ;place jmp short there
  446.         mov    word ptr es:[bx + 2],9090h
  447.         mov    byte ptr es:[bx + 4],90h
  448.         sti
  449. free_handle:
  450.         mov    ax,4300h
  451.         int    2fh
  452.         cmp    al,80h
  453.         jne    free_xms_end
  454.         mov    ax,4310h
  455.         int    2fh
  456.         mov    xms_offs,bx
  457.         mov    xms_seg,es
  458.         mov    ah,0ah
  459.         call    dword ptr xms_offs
  460. free_xms_end:
  461.         pop    si
  462.         pop    bx
  463.         pop    es                
  464.         ret
  465.  
  466. free_xms    endp            
  467.     
  468. ;...............................................................................
  469. ;  seek_stdin:
  470. ;    seek Device Header of previous stdin device
  471. ;  OUTPUT:
  472. ;    AX:SI - points to Dev. Header of previous STDIN
  473. ;    Carry Flag set if not found
  474. ;...............................................................................
  475. seek_stdin    proc    near
  476.  
  477. stdin_next:    les    si,dword ptr es:[si]    ;Address of next dev. header
  478.         mov    ax,es
  479.         cmp    ax,-1
  480.         jz    stdin_err_end
  481.         mov    ax,es:dev_attr[si]
  482.         test    al,1
  483.         jz    stdin_next
  484.         mov    ax,es
  485.         clc
  486.         ret
  487.  
  488. stdin_err_end:
  489.         stc
  490.         ret
  491.  
  492. seek_stdin    endp
  493. ;...............................................................................        
  494. ; seek_DIB:
  495. ;    seek DIBs pointing at our Device Header and remove them from the
  496. ;    chain of DIBS.
  497. ; INPUT:
  498. ;    AX:DX - address of our Device Header
  499. ; OUTPUT:
  500. ;    ES:BX - last DIB
  501. ;    Carry Flag set if proper DIB not found
  502. ;...............................................................................
  503. seek_DIB    proc    near
  504.  
  505.         mov    es,dos_seg
  506.         les    bx,es:FIRST_DIB            ;Get address of first DIB
  507.         mov    si,dos_dep3        
  508. next_DIB:    
  509.         cmp    word ptr es:[si + bx + 12h],dx
  510.         jnz    if_last
  511.         cmp    word ptr es:[si + bx + 14h],ax
  512.         jz    seek_end              
  513. if_last:
  514.         cmp    word ptr es:[si + bx + 18h],0ffffh    ;The last DIB ?
  515.         jz    seek_end2                ;Yes,jump
  516.  
  517.  
  518.         mov    DIB_offs,bx
  519.         mov    DIB_seg,es
  520.         les    bx,dword ptr es:[si + bx + 18h]        ;Get addr. of next DIB
  521.         jmp    next_DIB
  522.         
  523. seek_end:  
  524.         mov    word ptr es:[si + bx + 14h],ZERO
  525.         mov    al,byte ptr es:[bx]            ;Get drive number
  526.         mov    drv_num,al
  527.         clc
  528.         ret
  529. seek_end2:        
  530.         stc
  531.         ret        
  532.         
  533. seek_DIB    endp
  534. ;...............................................................................;        
  535. ;  get_DA_addr:
  536. ;    compute address of Drive Area for drive AL
  537. ;  INPUT:
  538. ;    AL - drive number
  539. ;  OUTPUT:                                    ;
  540. ;    ES:DI - address of Drive Area for drive AL                ;
  541. ;...............................................................................;
  542. get_DA_addr    proc    near
  543.  
  544.         push     ax
  545.         push    dx
  546.  
  547.         dec    al
  548.         xor    ah,ah
  549.         mov    dl,51h                ;Set DA ...
  550.         add    dl,dos_dep2            ; ... size
  551.         mul    dl                ;Multiply by DA size
  552.         mov    es,dos_seg
  553.         les    di,dword ptr es:FIRST_DA    ;Get addr. of first DA
  554.         add    di,ax                ;So now ES:DI points to new DA
  555.  
  556.         pop    dx
  557.         pop    ax
  558.         ret
  559.         
  560. get_DA_addr    endp
  561.  
  562. ;...............................................................................
  563. ; seek_DA:
  564. ;    seek Drive Area for drv_num
  565. ; On input:
  566. ;    SI:DX - DIB address
  567. ;...............................................................................
  568. seek_DA        proc    near
  569.  
  570.         mov    es,dos_seg
  571.         mov    al,drv_num
  572.         xor    ch,ch
  573.         mov    ah,byte ptr es:TOTAL_NUM    ;Get total number of drives
  574. check_next_DA:
  575.         inc    al
  576.         cmp    al,ah
  577.         ja    check_end
  578.         call    get_DA_addr            ;Get address of DA to ES:DI
  579.         cmp    word ptr es:[di + 45h],dx    ;DA not used ?
  580.         jnz    check_next_DA            ;Yes,jump
  581.         cmp    word ptr es:[di + 47h],si    ;DA
  582.         jnz    check_next_DA
  583.  
  584.         inc    DA_flag
  585.         mov    word ptr es:[di + 43h],ZERO    ;mark DA as not used 
  586.         push    ax
  587.         add    al,40h
  588.         mov    byte ptr es:[di],al
  589.         pop    ax
  590.         mov    byte ptr es:[di + 3],ZERO
  591.         jmp    check_next_DA
  592.         ret
  593.         
  594. check_end:    
  595.         stc                    ;Signal error
  596.         ret        
  597.         
  598. seek_DA        endp
  599.  
  600.  
  601. code        ENDS
  602.         END    start
  603.  
  604.  
  605.