Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Low-level disk access with QB45

Low-level disk access with QB45

by  Alt255  Posted    (Edited  )
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!
[tt]
DEFINT A-Z[/tt]

' First, declare the registers.[tt]
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
[/tt]

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

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

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

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

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

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

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

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

'' Set a new serial number in the buffer
'' and write it to the disk.[tt]
'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)[/tt]

''..... 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.[tt]
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$
[/tt]

' 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.[tt]
LBL$ ="QWERTYUIOPA"
SHL$ ="LABEL A: " + LBL$
SHELL SHL$
[/tt]

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

' get the root directory entries[tt]
FOR Re = 1 TO 4
inregs.DX = 0: inregs.AX = 0
CALL INTERRUPTX(&H13, inregs, outregs)
inregs.DX = &H100 [/tt]
'side 1, drive 0[tt]
inregs.ES = VARSEG(RootBuffer$)
inregs.BX = SADD(RootBuffer$)
inregs.AX = &H20E [/tt]
'function 2, read 14 sectors[tt]
inregs.CX = 2 [/tt]
'starting at sector #2[tt]
CALL INTERRUPTX(&H13, inregs, outregs)
NEXT
[/tt]

' Set the volume label to something strange.[tt]
NLabel$ = "Tek-Tips?!?"
MID$(RootBuffer$, INSTR(UCASE$(RootBuffer$), LBL$), 11) = NLabel$[/tt]

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

' Let's write those changes to the floppy boot record.[tt]
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
[/tt]

' Write the changes to the root directory[tt]
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
[/tt]

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.

Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top