home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / v / vol12n06.zip / BOOTPW.ZIP / BOOTPW.ASM < prev    next >
Assembly Source File  |  1993-03-02  |  25KB  |  893 lines

  1.         page    66,132
  2. ;====================================================================
  3. ;
  4. ; BOOTPW - A program to password protect a disk
  5. ;
  6. ; Copyright (c) 1993 Douglas Boling
  7. ;
  8. ;====================================================================
  9.         code    segment
  10.         assume    cs:code
  11.  
  12.         org    100h
  13. ;====================================================================
  14. ;BOOTPW Boot record
  15. ;
  16. ; Entry:     
  17. ;   CS:IP - 0:7C00h
  18. ;      DL - boot drive
  19. ;   ES:SI - Ptr to partition table boot entry (if hard disk.)
  20. ;   All other registers undefined
  21. ;====================================================================
  22.  
  23. root_offset    equ    500h
  24. boot_buffer    equ    offset end_of_code + 512
  25. pw_nonres    equ    offset password_size - offset entry
  26.  
  27.  
  28. data_startl     equ     word ptr [bp]
  29. data_starth     equ     word ptr [bp+2]
  30. boot_disk       equ     byte ptr [bp+4]
  31.  
  32. bytes_per_sec   equ     word ptr [bp+0bh]
  33. sec_per_cluster equ     byte ptr [bp+0dh]
  34. reserved_sec    equ     word ptr [bp+0eh]
  35. number_of_fats  equ     byte ptr [bp+10h]
  36. root_size       equ     word ptr [bp+11h]
  37. total_sec       equ     word ptr [bp+13h]
  38. media_des_byte  equ     byte ptr [bp+15h]
  39. sec_per_fat     equ     word ptr [bp+16h]
  40. sec_per_track   equ     word ptr [bp+18h]
  41. number_of_heads equ     word ptr [bp+1ah]
  42. num_hidden_sec  equ     word ptr [bp+1ch]
  43. boot_flag    equ    word ptr [bp+3feh]
  44.  
  45. oldboot_name    equ    7c00h + offset oldboot_nameo - offset entry
  46. boot_initmsg    equ    7c00h + offset program - offset entry
  47. boot_pwmsg    equ    7c00h + offset pw_msg - offset entry
  48. boot_perrmsg     equ    7c00h + offset pwerror_msg - offset entry
  49. boot_rerrmsg     equ    7c00h + offset readerr_msg - offset entry
  50. boot_ferrmsg    equ    7c00h + offset finderr_msg - offset entry
  51. boot_pw        equ    7c00h + offset password - offset entry
  52. boot_pwsize    equ    7c00h + offset password_size - offset entry
  53.  
  54. ;--------------------------------------------------------------------
  55. ;Boot sector code
  56. ;--------------------------------------------------------------------
  57. entry:        jmp    initialize
  58. oem_field    db    "BootPW10"
  59. bpb_data    db    24 dup (0)        ;Leave room for rest of BPB
  60. bpb_dataend    =    $
  61. boot_1:
  62.             cli                ;Disable interrupts
  63.             cld                             ;Set direction UP.
  64.             mov     ax,7c00h
  65.             xor     bx,bx
  66.             mov     ss,bx                   ;SS:SP = 790:0
  67.             mov     sp,ax
  68.             sti                ;Interrupts OK
  69.         mov    ds,bx
  70.         mov    es,bx
  71.         push    si            ;Save Part table ptr
  72.         push    bp
  73.         mov    bp,ax
  74.         mov    boot_disk,dl
  75.  
  76.         mov     al,number_of_fats       ;Compute the sector of the
  77.         cbw                ;  roor directory.
  78.             mul     sec_per_fat
  79.             mov     cx,reserved_sec
  80.             add     cx,num_hidden_sec
  81.             adc     dx,num_hidden_sec[2]
  82.             add     cx,ax
  83.             adc     dx,bx                   ;BX = 0
  84.         push    cx            ;Save root sector low
  85.         push    dx            ;Save root sector high
  86.             mov     data_startl,cx
  87.             mov     data_starth,dx
  88.  
  89.             mov     ax,32                   ;Get length of dir entry
  90.             mul     root_size               ;Compute the size -in sectors-
  91.             mov     si,bytes_per_sec        ;  of the Root Directory.
  92.             add     ax,si
  93.             dec     ax
  94.             div     si
  95.             add     data_startl,ax
  96.             adc     data_starth,bx
  97.         push    ax
  98.         pop    cx
  99.  
  100.         pop    dx            ;Get root directory 
  101.         pop    ax            ;  starting sector
  102.         mov    bx,root_offset        ;Read the root dir
  103.         push    bx            ;Save ptr to Root dir
  104. boot_3:
  105.         push    cx
  106.         push    ax
  107.         push    dx
  108.         call    boot_read_disk        ;Loop on read_disk to
  109.         pop    dx            ;  read in all sectors
  110.         pop    ax            ;  of the root dir
  111.         pop    cx
  112.         jc    boot_error
  113.         add    bx,bytes_per_sec
  114.         add    ax,1
  115.         adc    dx,0
  116.         loop    boot_3
  117.  
  118.             mov     si,boot_initmsg        ;Identify ourselves 
  119.         call    bootprint_msg
  120.             mov     si,boot_pwmsg        ;Prompt for PW
  121.         call    bootprint_msg
  122.         mov    di,7c00h
  123.         call    read_line        ;Get password
  124.         mov    si,boot_pwsize
  125.         lodsb
  126.         cmp    cl,al
  127.         jne    boot_badpw
  128.         rep    cmpsb
  129.         jne    boot_badpw
  130.         
  131.         pop    si            ;Get back Root ptr
  132.         mov    bx,root_size
  133. boot_4:
  134.         mov    di,oldboot_name        ;Find old boot record
  135.         mov    cx,8            ;  in root directory
  136.         push    si
  137.         repe    cmpsb
  138.         pop    si
  139.         je    boot_5
  140.         add    si,32
  141.         dec    bx
  142.         jne    boot_4
  143.             mov     si,boot_ferrmsg
  144.         jmp    short boot_error
  145. boot_5:
  146.         mov    cx,word ptr [si+1ah]     ;Get start clust
  147.             dec     cx            ;Compensate for 1st to FAT
  148.             dec     cx            ;  entries not being used.
  149.             mov     al,sec_per_cluster    ;Get sectors per cluster
  150.         cbw
  151.             mul     cx
  152.             add     ax,data_startl        
  153.             adc     dx,data_starth
  154.         
  155.         mov    bx,7e00h        ;To address 0:7E00
  156.         call    boot_read_disk
  157.         jc    boot_error
  158.         xor    ax,ax
  159.         cwd
  160.         call    boot_write_disk
  161.         pop    bp
  162.         pop    si
  163.         int    19h            ;Reboot
  164. boot_badpw:
  165.         mov    si,boot_perrmsg
  166. boot_error:
  167.         call    bootprint_msg
  168. boot_halt:
  169.         jmp    boot_halt
  170.  
  171. ;-----------------------------------------------------------------------
  172. ; Write/Read disk - Writes or reads one sector from the disk
  173. ; Entry: DX,AX - Absolute sector to write/read
  174. ;        BX - address of buffer.
  175. ; Exit:  CF - Clear if read successful.
  176. ;-----------------------------------------------------------------------
  177. boot_write_disk    proc    near
  178.         mov    cx,0301h
  179.         jmp    short read_1
  180. boot_read_disk    proc    near
  181.         mov    cx,0201h
  182. read_1:
  183.         push    cx
  184.         push    bx
  185.         div    sec_per_track        ;Get sectors per track
  186.             inc     dx
  187. read_2:
  188.         mov    bx,dx            ;Save sector
  189.             cwd
  190.             div     number_of_heads         ;Compute head and cylinder
  191.             xchg    ah,al                   ;Swap cyl low and high bytes
  192.             mov     cl,6
  193.             shl     al,cl                   ;Shift high cyl bits
  194.             xchg    cx,ax                   ;Copy cyl into CX
  195.             or      cl,bl                   ;Combine cyl with sector
  196.             mov     dh,dl                   ;Move head number
  197.             mov     si,5                    ;Try to read 5 times.
  198.             pop     bx            ;Get dest buff offset
  199.         pop    ax            ;Get Read/Write cmd
  200. read_3:
  201.             mov     dl,boot_disk            ;Get disk to read
  202.         push    ax
  203.             int     13h                     ;Read/Write disk.
  204.         pop    ax
  205.             jnc     read_exit               ;No error, exit
  206.             xor     ax,ax                   ;Reset disk before reading
  207.             int     13h
  208.         dec    si
  209.         jnz    read_3
  210.             mov     si,boot_rerrmsg
  211.         stc
  212. read_exit:                                
  213.             ret
  214. boot_read_disk    endp
  215. boot_write_disk    endp
  216.  
  217. ;--------------------------------------------------------------------
  218. ; Print Msg - Prints a message to the screen
  219. ; Entry: DS:SI - Points to ASCIIZ message
  220. ;--------------------------------------------------------------------
  221. bootprint_msg    proc    near
  222.         push    bx
  223.         push    bp
  224. bprint_msg1:
  225.         lodsb
  226.         or    al,al
  227.         je    bprint_exit
  228.         mov    ah,0eh
  229.         mov    bx,7h
  230.         push    si
  231.         int    10h
  232.         pop    si
  233.         jmp    short bprint_msg1
  234. bprint_exit:
  235.         mov    ax,0e0dh        ;Append CR - LF
  236.         int    10h
  237.         mov    ax,0e0ah
  238.         int    10h
  239.         pop    bp
  240.         pop    bx
  241.         ret
  242. bootprint_msg    endp
  243. password_size    db    0
  244. password    db    4eh,75h,0f0h,0beh,7dh,0b4h,0f9h,0c3h
  245. ;--------------------------------------------------------------------
  246. ; Read Line - Reads upto 8 charagers from the keyboard - No echo
  247. ; Entry: DS:DI - Points to buffer
  248. ; Exit:     CX - Number of characters in buffer
  249. ;--------------------------------------------------------------------
  250. read_line    proc    near
  251.         push    di
  252.         mov    cx,8
  253. readl_1:
  254.         xor    ax,ax            ;Get key
  255.         int    16h
  256.         cmp    al,13
  257.         je    readl_exit
  258.         cmp    al,8
  259.         je    readl_2
  260.         not    al
  261.         stosb
  262.         loop    readl_1
  263. readl_exit:
  264.         sub    cx,8
  265.         neg    cx
  266.         pop    di
  267.         ret
  268. readl_2:
  269.         cmp    cx,8
  270.         je    readl_1
  271.         dec    di
  272.         inc    cx
  273.         jmp    short readl_1
  274. read_line    endp
  275. program        db    13,10,"BOOTPW 1.0 "
  276.         db    "Copyright 1993 Douglas Boling",0
  277. pw_msg        db    13,10,10,"Enter Password",0
  278. pwerror_msg    db    "Wrong password",0
  279. readerr_msg    db    "Read Error",0
  280. finderr_msg    db    "Can",39,"t find "
  281. oldboot_nameo    db    "OLDBOOT BIN",0
  282.  
  283. bootcode_end    =    $
  284.         org    2feh
  285.         dw    0AA55h            ;Boot signature
  286. boot_end    =    $
  287. ;====================================================================
  288. ;Start of nonresident install code
  289. ;====================================================================
  290. program1        db      "First published in PC Magazine, "
  291.         db    "March 30, 1993",13,10,10,0
  292.  
  293. infomsg1    db    "USAGE: BOOTPW d:",13,10
  294.         db    "d: is the target diskette to "
  295.         db    "password protect",0
  296.  
  297. infomsg3    db    "Please enter password, up to 8 characters",0
  298. infomsg4    db    "Please reenter password for verification",0
  299. infomsg5    db    13,10,"Disk "
  300. infomsg5_dsk    db    " : Password protected.",0
  301. infomsg6    db    13,10,"Password removed",0
  302. infomsg7    db    "Disk password protected",0
  303. infomsg8           db    13,10,"Please remove the disk from the drive "
  304.         db    "and press <Enter>",13,10
  305.             db    "or if the disk is a hard drive, turn off the system.",0
  306.  
  307. errmsg0        db    "This program requires DOS 2.0 or greater",0
  308. errmsg1        db    "Target drive letter not specified",0
  309. errmsg2      db    "Target diskette not a DOS formatted "
  310.         db    "disk",0
  311. errmsg3     db    "Unable to fit BOOTPW code on "
  312.         db    "target disk",0
  313. errmsg4        db    "Passwords do not match",0
  314. errmsg5        db    "No password entered, disk not modified",0
  315. errmsg6        db    "The password doesn't match the disk "
  316.         db    "password",0
  317. errmsg7        db    "Unable to find old DOS boot record",0
  318.  
  319. dos_version    dw    0
  320. crit_vec    dd    0            ;Critical err vector
  321. targ_disk    db    0            ;Disk to modify
  322.  
  323. oldboot_fname    db    "C:\OLDBOOT.BIN",0
  324.  
  325. doserr_tbl    dw    offset    doserr_00
  326.          dw    offset    doserr_01
  327.         dw    offset    doserr_02
  328.         dw    offset    doserr_03
  329.         dw    offset    doserr_04
  330.         dw    offset    doserr_05
  331.         dw    offset    doserr_06
  332.         dw    offset    doserr_07
  333.         dw    offset    doserr_08
  334.         dw    offset    doserr_09
  335.         dw    offset    doserr_10
  336.         dw    offset    doserr_11
  337.         dw    offset    doserr_12
  338.         dw    offset    doserr_unk
  339. doserr_tblend    =    $
  340.  
  341. doserr_00    db    "Disk Write Protected",0
  342. doserr_01    db    "Unknown Unit",0
  343. doserr_02    db    "Drive not ready",0
  344. doserr_03    db    "Unknown Command",0
  345. doserr_04    db    "CRC Data Error",0
  346. doserr_05    db    "Bad request structure",0
  347. doserr_06    db    "Disk Seek error",0
  348. doserr_07    db    "Not a DOS disk",0
  349. doserr_08    db    "Sector not found",0
  350. doserr_09    db    "Printer out of paper",0
  351. doserr_10    db    "Disk Write fault",0
  352. doserr_11    db    "Disk Read fault",0
  353. doserr_12    db    "General failure",0
  354. doserr_unk    db    "Unknown DOS error",0
  355.  
  356. ;--------------------------------------------------------------------
  357. ; INITIALIZE - Entry point of nonresident code
  358. ;--------------------------------------------------------------------
  359. initialize:
  360.         cld                ;String ops UP
  361.         mov    ah,30h            ;Get DOS version
  362.         int    21h
  363.         xchg    al,ah
  364.         mov    si,offset errmsg0
  365.         cmp    ax,200h
  366.         jb      init_jmperror
  367.         mov    dos_version,ax
  368.         mov    si,offset program    ;Print copyright msg    
  369.         call    print_msg
  370.         mov    si,offset program1
  371.         call    print_msg
  372.         call    set_crit_vec        ;Set crit vec to int routine
  373.  
  374.         mov    si,offset infomsg1         ;Syntax msg text
  375.         cmp    byte ptr ds:[80h],0
  376.         je    init_jmperror
  377.         mov    si,offset 81h
  378.         call    get_drive        ;Get target disk
  379.         jc    init_jmperror
  380.         mov    targ_disk,al        ;Save drive number
  381.         mov    oldboot_fname,ah    ;Save drive letter
  382.  
  383.         mov    bx,boot_buffer
  384.         call    read_boot        ;Read current boot record
  385.         jc    init_jmperror
  386.  
  387.         call    check4bpw        ;See if BOOTPW protected
  388.         jnz    init_3
  389.  
  390.         mov    si,offset infomsg7    ;Tell user disk protected
  391.         call    print_msg
  392.         mov    si,offset infomsg3    ;Password prompt
  393.         call    print_msg
  394.         mov    di,offset end_of_code
  395.         call    read_line
  396.         mov    si,boot_buffer
  397.         add    si,pw_nonres
  398.         lodsb    
  399.         cmp    al,cl
  400.         jne    init_1            ;PW lengths don't match
  401.         rep    cmpsb         
  402.         jne    init_1            ;PWs don't match
  403.         call    uninstall
  404.         jc    init_error
  405.         jmp    short init_exit
  406. init_1:
  407.         mov    si,offset errmsg6    ;Bad password
  408. init_jmperror:
  409.         jmp    short init_error
  410. init_3:
  411.         mov    si,offset infomsg3    ;Password prompt
  412.         call    print_msg
  413.         mov    di,offset end_of_code
  414.         call    read_line
  415.         mov    si,offset errmsg5    ;Password not entered
  416.         jcxz    init_error
  417.         push    cx
  418.         mov    si,offset infomsg4    ;Password verify prompt
  419.         call    print_msg
  420.         mov    di,offset end_of_code+16
  421.         call    read_line
  422.         mov    si,offset errmsg4    ;Passwords don't match
  423.         pop    bx
  424.         cmp    cx,bx
  425.         jne    init_error
  426.         mov    si,offset end_of_code
  427.         mov    di,offset end_of_code+16
  428.         push    cx
  429.         rep    cmpsb
  430.         pop    cx
  431.         mov    si,offset errmsg4    ;Passwords don't match
  432.         jne    init_error
  433.         mov    si,offset end_of_code
  434.         mov    di,offset password
  435.         mov    password_size,cl
  436.         rep    movsb            ;Copy password
  437.  
  438.         call    install
  439. init_4:        
  440.         mov    si,offset infomsg8    ;Make user remove the disk
  441.         call    print_msg
  442.         
  443.         mov    ah,7            ;DOS read key
  444.         int    21h
  445.         or    al,al
  446.         jne    init_5
  447.         mov    ah,7
  448.         int    21h
  449. init_5:
  450.         cmp    al,27
  451.         je    init_6
  452.         mov    ah,1ch            ;Get allocation info
  453.         mov    dl,targ_disk
  454.         inc    dl
  455.         int    21h
  456.         jnc    init_4
  457. init_6:        
  458.         xor    ax,ax            ;Clear return code
  459. init_exit:
  460.         push    ax
  461.             call    reset_crit_vec        ;Restore critical error vec
  462.         pop    ax
  463.         mov    ah,4ch
  464.         int    21h
  465. init_error:
  466.         call    print_msg
  467.         mov    al,1
  468.         jmp    short init_exit
  469.  
  470. ;--------------------------------------------------------------------
  471. ;GET DRIVE - Returns a disk number for a letter on the command line
  472. ; Entry: SI - Ptr to command line
  473. ; Exit:  AL - Drive number
  474. ;        AH - Drvie letter
  475. ;        SI - Points to character after :
  476. ;        CF - Set if error
  477. ;        DX - Offset of error message if CF set
  478. ;--------------------------------------------------------------------
  479. get_drive    proc    near
  480.         lodsb
  481.         cmp    al,13            ;See if end of line
  482.         je    getdisk_err
  483.         cmp    al,20h            ;If space, keep looking
  484.         jbe    get_drive
  485.         mov    ah,al            ;Save letter in AH
  486.         and    ah,0dfh            ;Convert to upper case
  487.         or    al,20h            ;Convert to lower case
  488.         sub    al,'a'            ;See if between a - z
  489.         jb    getdisk_err
  490.         cmp    al,25
  491.         ja    getdisk_err
  492.         mov    bl,al
  493.         lodsb                ;See if trailing :
  494.         cmp    al,":"            ;  present.
  495.         jne    getdisk_err
  496.         mov    al,bl            ;Get back drv letter
  497.         cmp    al,2
  498.         jb    getdisk_1
  499.         mov    al,80h
  500. getdisk_1:
  501.         clc
  502. getdisk_exit:
  503.         ret
  504. getdisk_err:
  505.         mov    si,offset errmsg1
  506.         stc
  507.         jmp    short getdisk_exit
  508. get_drive    endp
  509.  
  510. ;--------------------------------------------------------------------
  511. ;INSTALL - Installs the BOOTPW boot record on the target diskette
  512. ; Exit:  CF - Set if error
  513. ;        DX - Offset of error message if CF set
  514. ;--------------------------------------------------------------------
  515. install        proc    near
  516.         mov    di,offset entry
  517.         mov    ax,0eb90h        ;NOP + JMP short opcode
  518.          stosw
  519.          mov    ax,offset boot_1 - offset bpb_data
  520.          stosb
  521.  
  522.         mov    si,boot_buffer        ;Get ptr to boot rec
  523.         lodsb
  524.         mov    bl,al            ;Get opcode
  525.         lodsw
  526.         cmp    bl,0ebh            ;See if short JMP opcode
  527.         jne    install_1
  528.             
  529.         xor    ah,ah            ;If short JMP, clear 
  530.         jmp    install_2        ;  high byte
  531. install_1:
  532.         mov    si,offset errmsg2
  533.         cmp    bl,0e9h            ;Check for long JMP
  534.         jne    install_error
  535. install_2:
  536.         mov    si,boot_buffer+11
  537.         mov    di,offset bpb_data    ;Copy BIOS Param Blk
  538.         mov    cx,offset bpb_dataend - offset bpb_data - 8
  539.         rep    movsb
  540.  
  541.         mov    ah,3ch            ;Create file
  542.         mov    cx,2            ;Make hidden
  543.         mov    dx,offset oldboot_fname
  544.         push    ds
  545.         int    21h
  546.         pop    ds
  547.         mov    si,offset errmsg3
  548.         jc    install_exit
  549.         mov    bx,ax            ;Copy file handle
  550.         mov    ah,40h
  551.         mov    cx,512            ;Write 512 bytes
  552.         mov    dx,boot_buffer
  553.         int    21h
  554.         mov    si,offset errmsg3
  555.         jc    install_exit
  556.         mov    ah,3eh            ;Close file
  557.         int    21h
  558.         mov    si,offset errmsg3
  559.         jc    install_exit
  560.  
  561.         mov    al,targ_disk        ;Get target disk
  562.         mov    bx,offset entry        ;Point to BootPW rec
  563.         call    write_boot        ;Write new boot rec
  564.         jc    install_exit
  565.  
  566.         mov    al,oldboot_fname
  567.         mov    infomsg5_dsk,al
  568.         mov    si,offset infomsg5    ;Indicate installed 
  569.         call    print_msg
  570.         clc
  571. install_exit:
  572.         ret
  573. install_error:
  574.         stc
  575.         jmp    short install_exit
  576. install        endp
  577.  
  578. ;--------------------------------------------------------------------
  579. ;UNINSTALL - Uninstalls BOOTPW from the target disk
  580. ; Exit:  CF - Set if error
  581. ;        DX - Offset of error message if CF set
  582. ;--------------------------------------------------------------------
  583. uninstall    proc    near
  584.  
  585.         mov    di,boot_buffer
  586.         mov    al,0ebh            ;JMP short opcode
  587.          stosb
  588.          mov    al,offset boot_1 - offset bpb_data + 1
  589.          stosb
  590.         mov    al,90h
  591.          stosb
  592.  
  593.         mov    al,targ_disk        ;Get target disk
  594.         mov    bx,boot_buffer        ;Point to BootPW rec
  595.         call    write_boot        ;Write new boot rec
  596.         jc    uninstall_error
  597.  
  598.         mov    ah,0dh            ;Reset disks
  599.         int    21h
  600.  
  601.         mov    ax,3d00h        ;Open file
  602.         mov    dx,offset oldboot_fname    ;Open file that has
  603.         int    21h            ;  old boot rec
  604.         mov    si,offset errmsg7
  605.         jc    uninstall_exit
  606.         mov    bx,ax            ;Copy file handle
  607.         mov    ah,3fh
  608.         mov    cx,512            ;Read 512 bytes
  609.         mov    dx,boot_buffer
  610.         int    21h
  611.         mov    si,offset errmsg7
  612.         jc    uninstall_exit
  613.         mov    ah,3eh            ;Close file
  614.         int    21h
  615.         mov    si,offset errmsg7
  616.         jc    uninstall_exit
  617.  
  618.         mov    al,targ_disk        ;Get target disk
  619.         mov    bx,boot_buffer        ;Point to DOS rec
  620.         call    write_boot        ;Write DOS boot rec
  621.         jc    uninstall_exit
  622.         mov    si,offset infomsg6    ;Tell user, disk 
  623.         call    print_msg        ;  unprotected.
  624. uninstall_exit:
  625.         ret
  626. uninstall_error:
  627.         stc
  628.         jmp    short uninstall_exit
  629. uninstall    endp
  630.  
  631. ;--------------------------------------------------------------------
  632. ; CHECK4BPW - Check boot record to see if it is a BootPW boot rec
  633. ; Exit:  ZF - Set if BootPW record
  634. ;--------------------------------------------------------------------
  635. check4bpw    proc    near
  636.         mov    si,boot_buffer
  637.         add    si,3
  638.         mov    di,offset oem_field
  639.         mov    cx,8
  640.         rep    cmpsb
  641.         ret
  642. check4bpw    endp
  643.  
  644. ;--------------------------------------------------------------------
  645. ; READ BOOT - Reads the boot sector of a disk
  646. ; Entry: AL - Disk number (0=A, 1=B,...)
  647. ;        BX - Points to buffer
  648. ; Exit:  CF - Set if error
  649. ;        DX - Points to error message
  650. ;--------------------------------------------------------------------
  651. read_boot    proc    near
  652.         mov    al,targ_disk        ;Get target disk
  653.  
  654.         mov     cx,1            ;read 1 sector
  655.         mov    dx,0            ;Sector 0
  656.         call    read_absolute        ;Read current boot rec
  657.         ret
  658. read_boot    endp
  659.  
  660. ;--------------------------------------------------------------------
  661. ; WRITE BOOT - Wrotes the boot sector of a disk
  662. ; Entry: AL - Disk number (0=A, 1=B,...)
  663. ;        BX - Points to buffer
  664. ; Exit:  CF - Set if error
  665. ;        DX - Points to error message
  666. ;--------------------------------------------------------------------
  667. write_boot    proc    near
  668.         mov    al,targ_disk        ;Get target disk
  669.         mov     cx,1            ;read 1 sector
  670.         mov    dx,0            ;Sector 0
  671.         call    write_absolute        ;Read current boot rec
  672.         ret
  673. write_boot    endp
  674.  
  675. ;--------------------------------------------------------------------
  676. ; READ ABSOLUTE - Reads sectors from the disk.
  677. ; Entry:   AL - Letter of drive to read
  678. ;          CX - Number of sectors to read.  
  679. ;       SI,DX - Sector to start read (SI only used on huge disks)
  680. ;       DS:BX - Pointer to data buffer. 
  681. ;--------------------------------------------------------------------
  682. read_abs_hstruc    =    $            ;Needed for >32M disks
  683. read_abs_start    dd    0            ;Starting sector
  684. read_abs_cnt    dw    0            ;Number of sectors to read
  685. read_abs_dbp    dd    0            ;Data buffer ptr
  686.  
  687. read_absolute   proc    near
  688.         push    bx
  689.         push    cx
  690.         push    ds
  691.         call    huge_disk_check
  692.         jc    read_abs_2
  693.         je    read_abs_1
  694.         push    ds            ;Save ptr to data buffer
  695.         push    bx
  696.         push    cs
  697.         pop    ds
  698.         mov    bx,offset read_abs_hstruc
  699.         mov    [bx],dx            ;More than 64K sectors
  700.         mov    [bx+2],si        ;  -> huge disk uses a
  701.         mov    [bx+4],cx        ;  different format
  702.         pop    [bx+6]            ;  than std int 25h.    
  703.         pop    [bx+8]
  704.         mov    cx,-1
  705. read_abs_1:
  706.             int     25h                     ;DOS Absolute Disk Read
  707.             pop     bx                      ;Clean off old flags
  708.         call    seterrmsg
  709.             cld
  710. read_abs_2:
  711.         pop    ds
  712.         pop    cx
  713.         pop    bx
  714.             ret
  715. read_absolute   endp
  716.  
  717. ;--------------------------------------------------------------------
  718. ; WRITE ABSOLUTE - Writes sectors to the disk.
  719. ; Entry:   AL - Letter of drive to write
  720. ;          CX - Number of sectors to write  
  721. ;       SI,DX - Sector to start write (SI only used on huge disks)
  722. ;       DS:BX - Pointer to data buffer. 
  723. ;--------------------------------------------------------------------
  724. write_absolute  proc    near
  725.         push    bx
  726.         push    cx
  727.         push    ds
  728.         call    huge_disk_check
  729.         jc    write_abs_2    
  730.         je    write_abs_1
  731.         push    ds            ;Save data buffer pointer
  732.         push    bx
  733.         push    cs
  734.         pop    ds
  735.         mov    bx,offset read_abs_hstruc
  736.         mov    [bx],dx            ;More than 64K sectors
  737.         mov    [bx+2],si        ;  -> huge disk uses a
  738.         mov    [bx+4],cx        ;  different format
  739.         pop    [bx+6]            ;  than std int 26h.    
  740.         pop    [bx+8]
  741.         mov    cx,-1                
  742. write_abs_1:
  743.             int     26h                     ;DOS Absolute Disk Write
  744.             pop     bx                      ;Clean off old flags
  745.         call    seterrmsg
  746.             cld
  747. write_abs_2:
  748.         pop    ds
  749.         pop    cx
  750.         pop    bx
  751.             ret
  752. write_absolute  endp
  753.  
  754. ;--------------------------------------------------------------------
  755. ; HUGE DISK CHECK - Checks if disk is greater than 32 Meg
  756. ; Entry: AL - Disk to check
  757. ; Exit:  ZF - Clear if > 32 Meg disk
  758. ;        CF - Set if error
  759. ;        DI - Sectors per cluster
  760. ;--------------------------------------------------------------------
  761. last_disk_read    db    -1
  762. last_disk_huge    db    0
  763. last_disk_spc     dw    0
  764. huge_disk_check    proc    near
  765.         push    ax
  766.         push    bx
  767.         push    cx
  768.         push    dx
  769.         cmp    al,last_disk_read    ;Save last disk checked, if
  770.         jne    huge_disk_check_1    ;  same as last disk, just
  771.         mov    di,last_disk_spc    ;  get saved answer.
  772.         cmp    last_disk_huge,0    
  773.         jmp    short huge_disk_check_3
  774. huge_disk_check_1:
  775.         mov    last_disk_read,al
  776.         mov    last_disk_huge,0
  777.         mov    dl,al            ;Copy disk number
  778.         inc    dl
  779.         mov    ah,36h            ;DOS Get Free disk space
  780.         int    21h        
  781.         cmp    ax,-1
  782.         jne    huge_disk_check_2
  783.         mov    last_disk_read,-1
  784.         jmp    short huge_disk_check_4
  785. huge_disk_check_2:
  786.         mov    di,ax            ;Save sectors per cluster
  787.         mov    last_disk_spc,di
  788.         mul    dx
  789.         or    dx,dx            ;See if more than 64K sectors
  790.         je    huge_disk_check_3
  791.         mov    last_disk_huge,1
  792. huge_disk_check_3:
  793.         clc
  794. huge_disk_check_4:
  795.         pop    dx
  796.         pop    cx
  797.         pop    bx
  798.         pop    ax
  799.         ret
  800. huge_disk_check    endp
  801.  
  802. ;--------------------------------------------------------------------
  803. ; SET CRIT VEC - Sets the critical error vector to an internal routine
  804. ;                to avoid the abort, retry, ignore message.
  805. ;--------------------------------------------------------------------
  806. set_crit_vec    proc    near
  807.         push    es
  808.             mov     ax,3524h                ;Get crititcal error vector
  809.             int     21h                      
  810.             mov     word ptr crit_vec,bx    ;Save vector
  811.         mov    word ptr crit_vec[2],es
  812.             mov     dx,offset crit_error    ;Set to internal routine.
  813.             mov     ax,2524h                
  814.             int     21h
  815.         pop    es
  816.         ret
  817. set_crit_vec    endp
  818.  
  819. ;--------------------------------------------------------------------
  820. ; RESET CRIT VEC - Resets the critical error vector to its original
  821. ;                  state.
  822. ;--------------------------------------------------------------------
  823. reset_crit_vec    proc    near
  824.         push    ds
  825.             lds     dx,crit_vec             ;Get old vector
  826.             mov     ax,2524h                ;Set vector
  827.             int     21h
  828.         pop    ds
  829.         ret
  830. reset_crit_vec    endp
  831.  
  832. ;--------------------------------------------------------------------
  833. ; SETERRMSG - Assigns a DOS error message to the value in AL
  834. ; Entry: AL - Error code
  835. ;        CF - Set if error
  836. ; Exit:  SI - Points to error message
  837. ;--------------------------------------------------------------------
  838. seterrmsg    proc    near
  839.         push    bx
  840.         pushf
  841.         jnc    seterrmsg_exit
  842.         mov    bx,ax
  843.         xor    bh,bh
  844.         shl    bx,1
  845.         cmp    bx,offset doserr_tblend - offset doserr_tbl
  846.         jbe    seterrmsg_1
  847.         mov    bx,26
  848. seterrmsg_1:
  849.         mov    si,[bx+doserr_tbl]
  850. seterrmsg_exit:
  851.         popf
  852.         pop    bx
  853.         ret
  854. seterrmsg    endp
  855.  
  856. ;--------------------------------------------------------------------
  857. ; Print Msg - Prints a message to the screen
  858. ; Entry: DS:SI - Points to ASCIIZ message
  859. ;--------------------------------------------------------------------
  860. crlf_msg    db    13,10,"$"
  861. print_msg    proc    near
  862. print_msg1:
  863.         lodsb
  864.         or    al,al
  865.         je    print_exit
  866.         mov    dl,al
  867.         mov    ah,02
  868.         int    21h
  869.         jmp    short print_msg1
  870. print_exit:
  871.         mov    dx,offset crlf_msg
  872.         mov    ah,9
  873.         int    21h
  874.         ret
  875. print_msg    endp
  876.  
  877. ;-----------------------------------------------------------------------------
  878. ; Prevent Abort,Retry,Ignore error msg with this dummy crit. error routine
  879. ;-----------------------------------------------------------------------------
  880. crit_error      proc    far
  881.             mov     al,0                    ;Ignore critical error.
  882.             cmp    cs:dos_version,300h
  883.             jb    crit_1
  884.         mov    al,3
  885. crit_1:                    
  886.             iret
  887. crit_error      endp
  888.  
  889.         even    
  890. end_of_code    =    $
  891. code        ends
  892. end        entry
  893.