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