×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

QBasic FAQ

Low-level disk access with QB45 by Alt255
Posted: 30 May 00

The following examples show how to manipulate the boot record of a floppy:
 1) Set the disk serial number.
 2) Customize the boot message.
 3) Set a volume label that can contain any character (even * and ?).
 Everything must be entered EXACTLY as shown, except the contents of
"Message$" (it still must be exactly 135 bytes in length), and "NLabel$" (which must be exactly 11 bytes in length).
 Don't experiment with the register values unless you know what you are doing. You could easily trash your hard drive!

DEFINT A-Z

' First, declare the registers.
TYPE RegTypeX
    AX        AS INTEGER
    BX        AS INTEGER
    CX        AS INTEGER
    DX        AS INTEGER
    bp        AS INTEGER
    si        AS INTEGER
    di        AS INTEGER
    FLAGS     AS INTEGER
    DS        AS INTEGER
    ES        AS INTEGER
END TYPE
DIM inregs AS RegTypeX, outregs AS RegTypeX

' Set up a buffer large enough to hold one disk sector (512 bytes).
Sbuffer$ = STRING$(512, " ")

' Read the floppy boot record, repeating the read four times to allow the
' floppy time to spin up to speed.
FOR Re = 1 TO 4
    inregs.DX = 0   'drive 0 (A:)
    inregs.AX = 0   'function 0
    CALL INTERRUPTX(&H13, inregs, outregs)

        'Interrupt 13, function 0 - reset disk system
    inregs.ES = VARSEG(Sbuffer$)

'ES and BX point to address of disk buffer
    inregs.BX = SADD(Sbuffer$)
    inregs.AX = &H201
'function 2, read 1 sector
    inregs.CX = &H1   
'sector #1, the boot record
    CALL INTERRUPTX(&H13, inregs, outregs)
NEXT

' Let's set the disk serial number to "12345678".
' ABCDEF0123456789 are all valid but the string must be eight bytes long.
SerialNo$ = "12345678"
NewSerial& = VAL("&H" + SerialNo$)
SerialNo$ = MKL$(NewSerial&)

' The disk serial number starts at the 40th byte in the boot record and
' lasts for 4 bytes.
MID$(Sbuffer$, 40, 4) = SerialNo$

'===========================================================
''' A more direct way to set the serial number would be to...
''InfoBuffer$ = STRING$(25, 0)

''' Get current info for a disk
''' (BX=1 points to the A: drive)
''' and place it in a buffer.
''InRegs.Ds = VARSEG(InfoBuffer$)
''InRegs.DX = SADD(InfoBuffer$)
''InRegs.AX = &H6900
''InRegs.BX = &H1
''CALL INTERRUPTX(&H21, InRegs, OutRegs)

''' Set a new serial number in the buffer
''' and write it to the disk.
''MID$(InfoBuffer$, 3, 4) = MKL$(NewSerial&)
''InRegs.Ds = VARSEG(InfoBuffer$)
''InRegs.DX = SADD(InfoBuffer$)
''InRegs.AX = &H6901
''InRegs.BX = &H1
''CALL INTERRUPTX(&H21, InRegs, OutRegs)

'''..... but we were only interested in fiddling with the boot record.
'===========================================================
' Lets change the boot message.
' This is the text one reads when rebooting with a floopy in the A: drive.
CrLf$ = CHR$(13) + CHR$(10)
Message$ = " This floppy belongs Joe Cool Programmer. What a guy!! "
Message$ = Message$ + CrLf$ + CrLf$ + CrLf$
Message$ = Message$ + "The floppy is not bootable. "
Message$ = Message$ + CrLf$ + CrLf$ + CrLf$ + CrLf$
Message$ = Message$ + " Remove the floppy and reboot system. "
MID$(Sbuffer$, 180, 135) = Message$

' Now let's give the floppy an "illegal" volume label.
' First, give it legal label using the DOS LABEL command. We'll use
' that value to search the floppy's root directory entries.
LBL$ ="QWERTYUIOPA"
SHL$ ="LABEL A: " + LBL$
SHELL SHL$

' Create a buffer large enough to hold 14 disk sectors
RootBuffer$ = STRING$(7168, 0)

'' get the root directory entries
FOR Re = 1 TO 4
    inregs.DX = 0: inregs.AX = 0
    CALL INTERRUPTX(&H13, inregs, outregs)
    inregs.DX = &H100   
'side 1, drive 0
    inregs.ES = VARSEG(RootBuffer$)
    inregs.BX = SADD(RootBuffer$)
    inregs.AX = &H20E
'function 2, read 14 sectors
    inregs.CX = 2
'starting at sector #2
    CALL INTERRUPTX(&H13, inregs, outregs)
NEXT
      
' Set the volume label to something strange.
NLabel$ = "Tek-Tips?!?"
MID$(RootBuffer$, INSTR(UCASE$(RootBuffer$), LBL$), 11) = NLabel$

' Set the volume label in the boot sector, too.
MID$(Sbuffer$, 44, 11) = NLabel$

' Let's write those changes to the floppy boot record.
FOR Re = 1 TO 4
    inregs.DX = 0
    inregs.AX = 0
    CALL INTERRUPTX(&H13, inregs, outregs)
    inregs.ES = VARSEG(Sbuffer$)
    inregs.BX = SADD(Sbuffer$)
    inregs.AX = &H301 'function 3, write one sector
    inregs.CX = &H1   'at sector #1
    CALL INTERRUPTX(&H13, inregs, outregs)
NEXT

' Write the changes to the root directory
FOR Re = 1 TO 4
    inregs.DX = 0: inregs.AX = 0
    CALL INTERRUPTX(&H13, inregs, outregs)
    inregs.DX = &H100   'side 1, drive 0
    inregs.ES = VARSEG(RootBuffer$)
    inregs.BX = SADD(RootBuffer$)
    inregs.AX = &H30E 'function 3, write 14 sectors
    inregs.CX = 2 'starting at sector #2
    CALL INTERRUPTX(&H13, inregs, outregs)
NEXT

Note: most of these changes are made without Windows's knowledge or permission. If you run this program and then examine the floppy you will only notice a change in the volume label to "QWERTYUIOPA".
You will have to examine a different floppy and then reinsert your test floppy to see the changes.


Back to QBasic FAQ Index
Back to QBasic Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close