Chapter – 13
Reading and Modifying MBR with Programming
DOS Boot Record (DBR) / DOS Boot Sector
DOS Boot Record (DBR) / DOS Boot Sector
After the partition table, the DOS Boot Record (DBR) or sometimes called DOS Boot Sector is the second most important information on your hard drive.
For a Detailed study about DBR, refer the chapter, “Logical Approach to Disks and OS”, Discussed earlier in this book.
First logical sector of each DOS partition will contain a DOS Boot Record (DBR) or DOS Boot Sector. The job of the DBR is to load the operating system from the hard disk drive into the main memory of computer and give the system’s control to the loaded program.
The DOS Boot Record (DBR) for the first partition on a hard disk is usually found at Absolute Sector 63 (the 64th sector on the disk drive) or in CHS form we can say C–H–S = 0–1–1 for most drives.
However this location may vary depending upon the SPT (Sectors per Track) of the Drive. For example, on an old 245MB drive having only 31 SPT, the Boot Record was located on the 32nd sector (Absolute Sector 31).
Since the floppy has no partitions on it therefore it has no MBR or Master Partition Table on its first sector, instead it contains the DBR on its very first sector.
The DBR is created by the FORMAT command of DOS, after partitioning is done using the FDISK command. The sector on which DBR resides becomes logical sector 1 of that particular partition for the DOS. The sector number used by DOS starts from the physical sector on which DBR is located.
The DBR contains a small program which is executed by the Master Boot Record (MBR) Executable program. All DOS partitions contain the program code to boot the machine i.e. load the operating system, but only that partition is given control by the Master Boot Record which is specified as active partition, in the partition table entry.
If the DBR is corrupted any how, the drive should be accessible if you boot the system from the bootable floppy or CD. Although the hard disk is not bootable (if the DBR of Active partition is corrupted), yet generally that should not affect access to the data of the disk drive. After booting the system with the bootable disk you can access the data.
/* Display boot parameters of floppy */
# include <dos.h>
# include <stdio.h>
main( )
{
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ;/* OEM Name and Version*/
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Sectors Per Cluster */
int res_sec ; /* Reserved Sectors */
char fat_copies ; /* Number of FATs */
int root_dir_entry ; /* Number of Root
Directory Entries */
unsigned int no_sects ; /* Number of Sectors in
Logical Volume */
unsigned char format_id ; /* Media Descriptor Byte
*/
int sec_per_fat ; /* Sectors Per FAT */
int sec_per_trk ; /* Sectors Per Track */
int no_sides ; /* Number of Heads */
int no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned char rest_code[482] ; /* Rest of the code */
} ;
struct boot b ;
char temp[4] ;
int val, drive ;
val = absread(0, 1, 0, &b) ; /* Use For Floppy Disk*/
if ( val == -1 )
{
printf ( "Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
printf ( "System ID = %s\n",
b.system_id ) ;
printf ( "Bytes per sector = %d\n",
b.bytes_per_sec ) ;
printf ( "Sectors per cluster = %d\n",
b.sec_per_clus ) ;
printf ( "Reserved sectors = %d\n",
b.res_sec ) ;
printf ( "FAT copies = %d\n",
b.fat_copies ) ;
printf ( "Root directory entries = %d\n",
b.root_dir_entry ) ;
printf ( "No. of sectors on disk = %u\n",
b.no_sects ) ;
printf ( "Media Descriptor Byte = %X\n",
b.format_id ) ;
printf ( "Sectors per FAT = %d\n",
b.sec_per_fat ) ;
printf ( "Sectors per track = %d\n",
b.sec_per_trk ) ;
printf ( "No. of sides = %d\n",
b.no_sides ) ;
printf ( "No. of reserved sectors = %d\n",
b.no_sp_res_sect ) ;
return 0;
}
If you run this program to test the DBR of 1.44M, 3½ Inch Floppy disk having 70 tracks, two sides, 18 sectors per track and 512 bytes in a sector, The Output of the Program will be displayed similar to as follows:
System ID = +1<*uIHC
Bytes per sector = 512
Sectors per cluster = 1
Reserved sectors = 1
FAT copies = 2
Root directory entries = 224
No. of sectors on disk = 2880
Media Descriptor Byte = F0
Sectors per FAT = 9
Sectors per track = 18
No. of sides = 2
No. of reserved sectors = 0
Reading the DBR of Large Volumes
The Partition volumes which are greater than 32MB in size have some different format of DBR than the DBR for less then or Equal to 32MB Volumes.
It is so to provide the support to large Volumes of the disk (For a Detailed description on it, refer the chapter “Logical Approach to Disks and OS”, Discussed earlier in this book).
The format of DOS Boot Record of a FAT32 volume has been given in the following table:
The following program is to read the DBR of large Volumes, which are greater than 32MB in size:
/* Program to display boot parameters of Large Disk Volume */
# include "dos.h"
# include "stdio.h"
void main()
{
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ; /* OEM name & Version */
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Sectors Per Cluster*/
unsigned int res_sec ; /* Number of Reserved
Sectors */
char fat_copies ; /* Number of FATs */
unsigned int root_dir_entry ;/* Number of Root
Directory Entry */
unsigned int no_sects ; /* Number of Sectors in
Logical Volume (if
Volume is <= 32MB) */
unsigned char Media_id ; /* Media Descriptor Byte
*/
unsigned int sec_per_fat ; /* Sector Per FAT */
unsigned int sec_per_trk ; /* Sectors Per Track */
unsigned int no_sides ; /* Number of Heads */
unsigned long no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned long long_sec_num ; /* Total Sectors in
Logical Volume
( Size >32MB) */
unsigned long num_sec_per_FAT; /* Sectors Per FAT */
unsigned int binary_flags; /* Binary Flags */
unsigned char version_of_FAT1; /* First Byte of FAT
Version */
unsigned char version_of_FAT2; /* Second Byte of FAT
Version */
unsigned long root_dir_start_cluster;
/* Root Directory
Starting Cluster
Number */
unsigned int sec_num_of_file_sys;
/* Sector Number of
File System
Information Sector
*/
unsigned int sec_num_of_backup_boot_sec;
/* Sector Number of
Backup Boot Sector
*/
unsigned char reserved[12]; /* Reserved */
unsigned char logical_drive_number;
/* Physical Drive
Number of Logical
Volume */
unsigned char unused_byte; /* Unused Byte */
unsigned char hex_extd_boot_signature;
/* Extended Boot
Signature(29H) */
unsigned long binary_volume_ID;/* Binary Volume ID */
unsigned char volume_label[11];/* Volume Label */
unsigned char FAT_name[8]; /* FAT Name */
unsigned char rest_code[420] ; /* Rest 420 Bytes of
The DBR */
unsigned char magic_number[2]; /* Magic Number */
} ;
struct boot b ;
char temp[4] ;
int val, drive,i;
val = biosdisk( 2, 0x80, 1,0,1,1, &b ) ;
/* For First Hard Disk */
if ( val == -1 )
{
printf ( "Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
printf ( " Jump Instruction Code = ");
for(i=0;i<=2;i++)
{
printf("%X",b.code[i]);
}
printf("(H)\n ");
printf ( "OEM name and version = %s\n ",
b.system_id ) ;
printf ( "Bytes per sector = %u\n ",
b.bytes_per_sec ) ;
printf ( "Sectors per cluster = %u\n ",
b.sec_per_clus ) ;
printf ( "Reserved sectors = %u\n ",
b.res_sec ) ;
printf ( "FAT copies = %d\n ",
b.fat_copies ) ;
printf ( "Root directory entries = %u\n ",
b.root_dir_entry ) ;
printf ( "No. of sectors on disk = %u\n ",
b.no_sects ) ;
printf ( "Media Descriptor Byte = %X(H)\n",
b.Media_id ) ;
printf ( "Sectors per FAT = %u\n ",
b.sec_per_fat ) ;
printf ( "Sectors per track = %u\n ",
b.sec_per_trk ) ;
printf ( "No. of sides = %u\n ",
b.no_sides ) ;
printf ( "No. of reserved (Hidden) sectors= %lu\n ",
b.no_sp_res_sect ) ;
printf ( "========== For Large(>32MB) Disks ========\n");
printf ( "No. of sectors,(if Volume is >32MB) = %lu\n ",
b.long_sec_num) ;
printf ( “Number of Sectors Per FAT = %lu\n “,
b.num_sec_per_FAT );
printf ( "Root Directory Starting Cluster = %lu\n ",
b.root_dir_start_cluster);
printf ( "File System Information Sector = %u\n ",
b.sec_num_of_file_sys);
printf ( "Sector Number of Backup Boot Sector = %u\n ",
b.sec_num_of_backup_boot_sec);
printf ( "Physical Drive Number = %X(H)\n",
b.logical_drive_number);
printf ( "Extended Boot Signature = %X(H)\n",
b.hex_extd_boot_signature);
printf ( "32-Bit Binary Volume ID = ");
Decimal_to_Binary (b.binary_volume_ID,32);
printf ( " (B)\n ");
printf ( "Volume Label = ");
for(i=0;i<=10;i++)
{
printf ( "%c",b.volume_label[i]);
}
printf ( "\n FAT name = ");
for(i=0;i<=7;i++)
{
printf ( "%c",b.FAT_name[i]);
}
printf ( "\n ");
printf ( "Magic Number = %X%X(H)",
b.magic_number[0],b.magic_number[1]);
getch();
}
//////// Decimal to Binary Conversion Function \\\\\\\\
Decimal_to_Binary(unsigned long input)
{
unsigned long i;
int count = 0;
int binary [32]; /* 32 Bit MAX only 32
elements total */
do
{
i = input%2; /* MOD 2 to get 1 or a 0*/
binary[count] = i; /* Load Elements into the
Binary Array */
input = input/2; /* Divide input by 2 to
decrement via binary */
count++; /* Count howy elements
are needed */
}while (input > 0);
/* Reverse and output binary digits */
do
{
printf ("%d", binary[count - 1]);
count--;
} while (count > 0);
return 0;
}
When the program is run to read the DBR of a large volume, The Output of the Program is displayed as follows:
Jump Instruction Code = EB5890 (H)
OEM name and version = MSWIN4.1
Bytes per sector = 512
Sectors per cluster = 8
Reserved sectors = 32
FAT copies = 2
Root directory entries = 0
No. of sectors on disk = 0
Media Descriptor Byte = F8 (H)
Sectors per FAT = 0
Sectors per track = 63
No. of sides = 255
No. of reserved (Hidden) sectors = 63
=========== For Large (>32MB) Disks ===========
No. of sectors, (if Volume is >32MB) = 11277567
Number of Sectors per FAT = 11003
Root Directory Starting Cluster = 2
File System Information Sector = 1
Sector Number of Backup Boot Sector = 6
Physical Drive Number = 80 (H)
Extended Boot Signature = 29 (H)
32-Bit Binary Volume ID = 110101010001100001110111100101 (B)
Volume Label = SAAYA
FAT name = FAT32
Magic Number = 55AA (H)
In the output of the program we see that the following parameters are shown zero:
- Root Directory Entry
- Number of Sectors on Disk
- Number Sectors Per FAT
These parameters are so because these values are set to zero, if the partition volume is greater then 32MB in size and the actual information is found in the Extended Volume Information Block of the DBR.
For Example, in the initial part of the DBR information, the number of Sectors per FAT is 0 and in the Extended Volume Information Block of DBR the Number of Sectors per FAT is 11003, which is the Actual Value for this large Volume.
The DBR of the Volume has the important information about the disk parameters, which can be used to link the all data information for programming purpose. For Example, if you want to access the DBRs of other Partition volume on the disk, you can calculate it by number of sectors, written in DBR and other related information.
If you want to access the Disk with cluster approach, you can make calculations with the help of Sectors per cluster, sectors per FAT and other information.
If you are using the hard disk larger than 8.4 GB (See the chapter, “Logical Approach to Disks and OS”, Discussed earlier in this book), use extensions to access all the DBR’s of the disk beyond 8.4 GB. Refer the Extended read-write functions, given in the previous chapters
How to Recover DBR with Programming
You can recover the DBR of the disk volume up to 100 percent by using some tricky approach and logical calculations. As we discussed about logical approaches of file systems in the chapter, “Logical Approach to Disks and OS”, earlier in this book, the every information in DBR is written within being some limit or rule.
Every parameter written in the DBR has some Specific meaning and written so by following some specific rule and reason. That is why the information of DBR if lost, can be Re-linked or rewritten manually if you follow these rule and use the tricky mind to find out what and how to cure.
For example, the table given next describes the number of sectors per cluster for different file systems, by using which you can find the number of sectors per cluster for your disk. Let us assume that you had a volume of approximately 10GB in your disk and the operating system which you were using was Windows 98.
Now, if any how the “Sectors per cluster” information of the DBR of the volume is corrupted. Let us try to find out which file system and how many sectors per clusters you had in the volume of your disk.
As the operating system in you disk was windows 98, which supports only FAT file system, therefore the File system of your Volume was FAT. Now let us think about the size of the volume, which was approximately 10GB.
We know that the 10GB Partition is not Supported by FAT16 (See the table given next) therefore the File system of the volume should be FAT32.
Now let us try to calculate the number of sectors per cluster for the volume. As we see in the table that the partition within the range of 8GB to 16GB has one cluster of 8 sectors.
Therefore, now we can conclude that in the volume, The File system was FAT32 with 8 sectors per cluster. Similarly we can assemble the other information of the DBR using other logical approaches described in the previous chapters of this book.
The following program has been written to rewrite the information of disk parameters in DBR of 1.44Mb, 3½ inch floppy disk, with 80 tracks, 2 heads (sides) and 18 sectors per track.
/* Program to Rewrite the parameters of 1.44MB, 3½ inch floppy disk to its DBR */
# include "dos.h"
# include "stdio.h"
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ; /* OEM ID and Version*/
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Number of Sectors
Per Cluster */
int res_sec ; /* Reserved Sectors */
char fat_copies ; /* Number of FATs */
int root_dir_entry ; /* Number of Root
Directory Entries */
unsigned int no_sects ; /* Number of Total
Sectors */
unsigned char format_id ; /* Media Descriptor
Byte */
int sec_per_fat ; /* Sectors Per FAT */
int sec_per_trk ; /* Sectors Per FAT */
int no_sides ; /* Number of
Sides(Heads) */
int no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned char rest_code[482] ;/* Rest 482 Bytes code
of DBR */
} ;
struct boot b ;
main( )
{
int val ;
val = absread(0, 1, 0, &b); /* Use For Floppy Disk */
if ( val == -1 )
{
printf ( "\n Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
display_info();
getch();
printf("\n Now Recovering BDR of Floppy.....\n");
Recover_with_values();
printf ( "\n Disk Recovered Successfully." ) ;
display_info();
return 0;
}
/* Function To Change the Parameters of DBR */
Recover_with_values()
{
int val =0;
/* Jump Code of 3 Bytes For Floppy */
b.code[0] = 0xEB;
b.code[1]= 0x3E;
b.code[2]= 0x90 ;
/* System Id of 8 Bytes */
strcpy(b.system_id, "+05PSIHC");
/* Bytes Per Sector = 512 */
b.bytes_per_sec = 512;
/* Sector per Cluster for 1.44M 3.5" Floppy = 1 */
b.sec_per_clus = 1;
/* Number of Reserved Sectors = 1 */
b.res_sec =1;
/* Number of FAT Copies = 2 */
b.fat_copies =2;
/* Number of Root Directory Entry = 224 */
b.root_dir_entry =224;
/* Number of Sectors on Disk = 2880 */
b.no_sects =2880;
/* Media Descriptor Byte For Floppy = F0 (H) */
b.format_id =0xF0;
/* Sectors Per FAT = 9 */
b.sec_per_fat =9;
/* Sectors Per Track = 18 */
b.sec_per_trk =18;
/* Number of Sides = 2 */
b.no_sides =2;
/* Number of Special Reserved Sectors (or Hidden
Sectors) = 0 */
b.no_sp_res_sect =0;
/* Use For Floppy Disk*/
val = abswrite ( 0, 1, 0, &b ) ;
if ( val == -1 )
{
printf ( "\n Disk Write Error...bad sector\n" ) ;
printf ( " Disk was not Recovered." ) ;
exit ( 1 ) ;
}
return 0;
}
display_info()
{
printf ( "\n Jump Code (Hex) = %X%X%X (H)\n",
b.code[0],b.code[1],b.code[2]);
printf ( " System ID = %s\n",
b.system_id ) ;
printf ( " Bytes per sector = %d\n",
b.bytes_per_sec ) ;
printf ( " Sectors per cluster = %d\n",
b.sec_per_clus ) ;
printf ( " Reserved sectors = %d\n",
b.res_sec ) ;
printf ( " FAT copies = %d\n",
b.fat_copies ) ;
printf ( " Root directory entries = %d\n",
b.root_dir_entry ) ;
printf ( " No. of sectors on disk = %u\n",
b.no_sects ) ;
printf ( " Media Descriptor Byte = %X\n",
b.format_id ) ;
printf ( " Sectors per FAT = %d\n",
b.sec_per_fat ) ;
printf ( " Sectors per track = %d\n",
b.sec_per_trk ) ;
printf ( " No.sides = %d\n",
b.no_sides ) ;
printf ( " No. of reserved sectors = %d\n",
b.no_sp_res_sect ) ;
return 0;
}
Comments on coding:
The structure boot is used to access the DBR, to read-write the parameters of the disk. The function display_info(), displays the various parameters of the disk, reading from the DBR. The function Recover_with_values() is used to modify and recover the parameters of DBR of Floppy.
The values used by the function Recover_with_values(), are for parameters of 1.44MB, 3 ½ inch floppy disk’s DBR. The description of these values has been given in the table given next:
Page Modified on: 17/01/2022