Hoofdstuk – 12
MBR lezen en wijzigen met programmeren
Master Boot Record (MBR) of Master Partition Table (MPT)
De Master Boot Record (MBR) of soms de Master Partition Table (MPT) genoemd, wordt gemaakt op de harde schijf door de opdracht FDISK.EXE van DOS uit te voeren.
De MBR bevat een klein programma om de actieve (of opstartbare) partitie vanaf de harde schijf te laden en te starten. De Master boot Record bevat informatie over alle vier de primaire partities op de harde schijf, zoals de startsector, eindsector, grootte van de partitie enz.
De MBR bevindt zich op Absolute Sector 0 of we kunnen zeggen op cilinder 0, head 0 en sector1 en als er meer dan één partitie op de schijf aanwezig is, zijn er Extended Master Boot Records, aan het begin van elk uitgebreid partitievolume.
Raadpleeg voor een gedetailleerde beschrijving het hoofdstuk "Logische benadering van schijven en besturingssysteem", dat eerder in dit boek is besproken.
Indeling hoofdopstartrecord
We kunnen de harde schijf opdelen in verschillende logische stations die over het algemeen hun eigen stationsletter krijgen door DOS). Er kan slechts één partitie tegelijk worden gemarkeerd als de actieve (of opstartbare) partitie.
Het Master Boot Record heeft de limiet van vier items in de Master Partition Table. De locatie van Extended Master Boot Record kan echter worden verkregen met behulp van Master Boot Record die uitgebreide partitietabellen bevat, waarvan het formaat precies hetzelfde is als van de hoofdpartitietabel, behalve dat er geen opstartcode is en deze ruimte van 446 bytes normaal is gereserveerd voor de opstartcode en blijft leeg.
Alle 512Bytes van het Master Boot Record zijn als volgt verbroken, zoals weergegeven in de tabel:
Alle uitgebreide partities moeten bestaan binnen de ruimte die is gereserveerd door de uitgebreide partitie-invoer. Slechts twee van de uitgebreide partities zijn bedoeld om te worden gebruikt, de eerste als een normale partitie en de tweede als een andere uitgebreide partitie, indien aanwezig.
Dus met behulp van één Master Partition Table kunnen we de locatie van een andere Extended Master Partition Table ernaast krijgen, indien aanwezig.
Partitietabel invoerformaat
Het formaat van de partitietabelinvoer van elke partitie in MBR is gegeven in de volgende tabel. Elke partitie-invoer van een MBR kan worden opgedeeld in de volgende bytes met hun specifieke betekenis:
Programma schrijven om de partitietabel van MBR te lezen
Het programma om alle vier de partitie-ingangen uit de partitietabel van MBR te lezen, wordt hierna gegeven. Het programma toont alle parameters van partitie-informatie, geschreven in partitietabel van MBR.
De codering van het programma is als volgt:
/* Programma om MBR-partitietabel te lezen */
# include <bios.h>
/* structuur om het partitie-item uit de partitietabel te lezen */
struct partition
{
unsigned char bootable ; /* Active Partition Byte */
unsigned char start_side ;/* Starting Head */
unsigned int start_sec_cyl ; /* combination of
Starting sector and
cylinder number */
unsigned char parttype ; /* File system
Indicator Byte */
unsigned char end_side ; /* Ending Head */
unsigned int end_sec_cyl ; /* combination of
Starting sector and
cylinder number */
unsigned long part_beg ; /* Relative Sector
Number */
unsigned long plen ; /* Partition length in
sectors */
} ;
/* Structuur om MBR . te lezen */
struct part
{
unsigned char master_boot[446] ; /* IPL (Initial
Program Loader)*/
struct partition pt[4] ; /* Partition table */
int lasttwo ; /* Magic Number */
} ;
struct part p ;
void main()
{
clrscr();
/* Lees eerste sector van eerste harde schijf */
biosdisk ( 2, 0x80, 0, 0, 1, 1, &p ) ;
display(); /* Display the information of MBR
Partition Table */
getch();
}
/* Functie om de informatie van de partitietabel van MBR . weer te geven */
display()
{
unsigned int s_sec, s_trk, e_sec, e_trk, i, t1, t2 ;
char type[20], boot[5] ;
printf("\n\nPart. Boot Starting location
Ending Location Relative Number of");
printf("\nType Side Cylinder Sector
Side Cylinder Sector Sectors Sectors\n");
for ( i = 0 ; i <= 3 ; i++ )
{
if ( p.pt[i].bootable == 0x80 )
strcpy ( boot, "Yes" ) ;
else
strcpy ( boot, "No" ) ;
switch ( p.pt[i].parttype )
{
case 0x00 :
strcpy ( type, "Unused" ) ; break ;
case 0x1 :
strcpy ( type, "FAT12" ) ; break ;
case 0x2 :
strcpy ( type, "Xenix" ) ; break ;
case 0x3 :
strcpy ( type, "Xenix:usr" ) ; break ;
case 0x4 :
strcpy ( type, "FAT16<32M" ) ; break ;
case 0x5 :
strcpy ( type, "DOS-Ext." ) ; break ;
case 0x6 :
strcpy ( type, "FAT16>32M" ) ; break ;
case 0x7 :
strcpy ( type, "NTFS" ) ; break ;
case 0x0b :
strcpy ( type, "FAT32" ) ; break ;
case 0x0c :
strcpy ( type, "FAT32-LBA" ) ; break ;
case 0x0d :
strcpy ( type, "VFAT16" ) ; break ;
case 0x0e :
strcpy ( type, "VFAT16-LBA" ) ; break ;
case 0x0f :
strcpy ( type, "VFAT EXT" ) ; break ;
case 0x17 :
strcpy ( type, "HPFS" ) ; break ;
case 0x81 :
strcpy ( type, "Old LINUX" ) ; break ;
case 0x82 :
strcpy ( type, "LinuxSwap" ) ; break ;
case 0x83 :
strcpy ( type, "LinuxNative" ) ; break ;
case 0x85 :
strcpy ( type, "Linux Ext." ) ; break ;
default :
strcpy ( type, "Unknown" ) ; break ;
}
s_sec = ( p.pt[i].start_sec_cyl & 0x3f ) ; /* starting
Sector of the
partition */
t1 = ( p.pt[i].start_sec_cyl & 0xff00 ) >> 8 ;
t2 = ( p.pt[i].start_sec_cyl & 0x00c0 ) << 2 ;
s_trk = t1 | t2 ; /* Starting Cylinder */
e_sec = ( p.pt[i].end_sec_cyl & 0x3f ) ; /*Ending Sector */
t1 = ( p.pt[i].end_sec_cyl & 0xff00 ) >> 8 ;
t2 = ( p.pt[i].end_sec_cyl & 0x00c0 ) << 2 ;
e_trk = t1 | t2 ; /* ending Cylinder */
printf ( "\n%6s %3s", type, boot ) ;
printf ( "%4d %6d %8d", p.pt[i].start_side, s_trk,s_sec ) ;
printf ( "%7d %6u %8u", p.pt[i].end_side, e_trk, e_sec ) ;
printf ( " %10lu %10lu", p.pt[i].part_beg,
p.pt[i].plen ) ;
}
return 0;
}
De informatie die wordt gegeven door de uitvoer van het programma wordt weergegeven zoals hieronder weergegeven:
Opmerkingen over codering:
De structuurpartitie wordt gebruikt om de verschillende parameters van partitie-invoer van partitie in partitietabel van MBR te lezen. Het structuurgedeelte wordt gebruikt om MBR-informatie te lezen.
De functie display() toont de informatie van de MBR-partitietabelparameters op het scherm. Zoals we de uitvoer van het programma zien, worden de begin- en eindcilinder en het sectornummer als volgt weergegeven:
Starting Sector = 1
Starting Cylinder = 0
Ending Sector = 63
Ending Cylinder = 701
Deze sector- en cilindernummers worden berekend uit de combinatie van twee bytes. De volgende tabellen laten zien hoe deze getallen worden berekend:
Dus C-H-S van de partitie starten = 0-0-1.
Evenzo zijn de codering voor de eindcilinder en het sectornummer van de partitie gegeven in de volgende tabel:
Dus het einde C-H-S van de partitie = 701-254-63.
Programma om alle logische partities en hun informatie te vinden
Het programma dat we eerder bespraken was om de partitie-informatie uit de partitietabel van MBR te lezen. Maar alleen door de MBR te lezen, kunnen we geen informatie krijgen van andere logische partities die zich in de uitgebreide partitie van de schijf bevinden.
We hebben al besproken dat de Master Boot Record de limiet heeft van vier items in de Master Partition Table. De locatie van Extended Master Boot Record kan echter worden verkregen met behulp van Master Boot Record dat Extended Partition Tables bevat, waarvan de indeling exact hetzelfde is als die van de hoofdpartitietabel.
Alle uitgebreide partities zouden moeten bestaan binnen de ruimte die is gereserveerd door de uitgebreide partitie-invoer. Slechts twee van de uitgebreide partities zijn bedoeld om te worden gebruikt, de eerste als een normale partitie en de tweede als een andere uitgebreide partitie, indien aanwezig.
Dus met behulp van één Master Partition Table kunnen we de locatie van een andere Extended Master Partition Table ernaast krijgen, indien aanwezig.
Het volgende programma is voor het vinden van alle logische partities en hun partitie-invoerinformatie, het lezen van MBR en uitgebreide MBR's van de schijf. De codering van het programma is als volgt:
/* Programma om de parameters van alle logische partities op de schijf te lezen */
#include<dos.h>
har buffer[512], report_par[20];
unsigned drive_num =0x80;
unsigned long star_sec[20], sec;
/* Structuur van schijfadrespakketformaat, te gebruiken door de readabsolutesectors Functie */
struct diskaddrpacket
{
char packetsize ; /* Size of Packet, generally 10H */
char reserved ; /* Reserved (0) */
int blockcount ; /* Number of Blocks to Transfer */
char far *bufferaddress ; /* address to Transfer
Buffer */
unsigned long blocknumber[2] ; /* Starting Absolute
Block Number */
} ;
void main()
{
int no_par,i;
clrscr();
no_par = 0;
All_partition_information (star_sec,&no_par, &sec, buffer,
report_par);
printf(" \n\n Total Partitions in Disk = %d\n ",
no_par);
for(i=0;i<no_par;i++)
{
printf("\n Starting Sector Number of Partition %d =
%lu " , i+1, star_sec[i]);
}
printf("\n");
getch();
}
De uitvoer van het programma wordt als volgt weergegeven:
Partition 1 - FAT32
Partition 2 - FAT32
Partition 3 - FAT32
Total Partitions in Disk = 3
Starting Sector Number of Partition 1 = 63
Starting Sector Number of Partition 2 = 11277693
Starting Sector Number of Partition 3 = 25623738
Opmerkingen over codering:
De structuur diskaddrpacket wordt gebruikt om het Disk Address-pakketformaat te lezen, te gebruiken door de readabsolutesectors-functie.
De functie All_partition_information( ) wordt gebruikt om alle parameters van alle partities uit het partitie-item te vinden.
Hoewel we in dit programma alleen het bestandssysteem en de relatieve sectorinformatie van alle beschikbare logische partities op de schijf hebben weergegeven, kunt u ook de informatie van andere parameters van partitie-informatie afdrukken met behulp van de functie All_partition_information( ) met wat meer printf.
De codering van de functie is als volgt:
/* Functie om alle logische partities te zoeken’ informatie die hun partitie-invoer leest */
All_partition_information( unsigned long *star_sec,
unsigned *no_par,
long *sec, char *buffer,
unsigned char *report_par )
{
unsigned long fat_check;
unsigned long *sectors_part;
static long se_p;
int temp_var1,active_offset,active_pos=0,i, extended_pos=0, partloc1;
unsigned long b_sec,se;
unsigned char active_par;
long relative_sec;
long no_sectors;
if(*sec==0 || *sec==1)
se_p=0;
do{
se=*sec;
/* Lees absolute sector gespecificeerd door *sec */
leesabsolutesectoren (drive_num,*sec,1,buffer);
/* ***** controleer op actieve partitie ***** */
if(*sec==se && *no_par==0) /*if primary
partition */
{
*sec=se=0;
for(active_offset=446; active_offset<=494;active_offset+=16)
{
active_par=buffer[active_offset];
if(active_par==0x80) /* check for active
partition */
break;
else
active_pos++; /* position of active
partition */
}
/* voor uitgebreide partitie */
for(active_offset=450; active_offset<=511;active_offset+=16)
{
active_par=buffer[active_offset];
if(active_par==0x05 | active_par==0x0F)
/*check for extended partition */
break;
else
extended_pos++; /*position of extended
partition */
}
if(active_pos==4)
active_pos=1;
if(extended_pos==4)
extended_pos=1;
partloc1=0x1C0+extended_pos*16;
}
else
{
active_pos=0;
extended_pos=1;
partloc1=0x1D0;
if(se_p!=0)
{
*sec=se=se_p; /*starting of extended
partition */
}
}
/* Relatieve sectoren in partitie */
relative_sec= *(unsigned long *)(buffer+454+active_pos*16);
/* Aantal sectoren in partitie */
no_sectors=*(long *)(buffer+458+active_pos*16);
/* Identificeer de bestandssysteemindicatorbyte */
if( buffer[0x1C2+active_pos*16]==0x04 ||
buffer[0x1C2+active_pos*16]==0x05 ||
buffer[0x1C2+active_pos*16]==0x06 ||
buffer[0x1C2+active_pos*16]==0x0B ||
buffer[0x1C2+active_pos*16]==0x0C ||
buffer[0x1C2+active_pos*16]==0x0E ||
buffer[0x1C2+active_pos*16]==0x0F ||
buffer[0x1C2+active_pos*16]==0x07)
{
switch(buffer[0x1C2+active_pos*16])
{
/* For NTFS Partition */
case 0x07: report_par[*no_par]='N';
printf("\n Partition -%d = NTFS",
*no_par+1);
break;
/* Voor FAT32-partitie */
case 0x0B:
case 0x0C: report_par[*no_par]='3';
printf("\n Partition -%d = FAT32",
*no_par+1);
break;
/* Voor FAT16-partitie */
case 0x04:
case 0x06:
case 0x0E: report_par[*no_par]='1';
printf("\n Partition -%d = FAT16",
*no_par+1);
break;
} // End of the Switch
b_sec=*sec+relative_sec;
sectors_part[*no_par]=no_sectors; /* Array to store Number of sectors of partitions */
} //End of if Condition
else
{ /* if partition indicator not match */
if(*sec==0)
{ no_par=0;
break;
}
if((fat_check!=0x3631)&&(fat_check!=0x3233))
b_sec=*sec=0;
}
if((b_sec!=0)&&(sec!=0))
{
star_sec[*no_par]=b_sec;
(*no_par)++;
}
else
break;
/* controleren of uitgebreide partitie bestaat */
if(buffer[0x1C2+extended_pos*16]==0x05 ||
buffer[0x1C2+extended_pos*16]==0x0F )
{
temp_var1=(unsigned )buffer[partloc1];
*sec=temp_var1 & 0x003F; /* sector of
extended
partition */
if(*sec!=0)
{
se_p=se+relative_sec+no_sectors;
*sec=se_p;
}
else
{ *sec=-1;
break;
}
} //close of if statement
else
{
if(*sec>0)
*sec=-1;
break;
}
} while(1); // close of do–while loop
/* controleer op andere niet-actieve primaire partities op sector 0 */
if(*sec==0)
{
for(i=0;i<4;i++)
{
active_par=buffer[446+i*16];
/* Identificeer de bestandssysteemindicator Byte */
if((buffer[0x1C2+i*16]==(char)0x06 ||
buffer[0x1C2+i*16]==(char)0x0B ||
buffer[0x1C2+i*16]==(char)0x0C ||
buffer[0x1C2+i*16]==(char)0x07 ||
buffer[0x1C2+i*16]==(char)0x0E ||
buffer[0x1C2+i*16]==(char)0x04) && active_par!=0x80)
{
switch(buffer[0x1C2+active_pos*16])
{
/* Voor NTFS-partitie */
case 0x07: report_par[*no_par]='N';
printf("\n Partition -%d = NTFS",
*no_par+1);
break;
/* Voor FAT32-partitie */
case 0x0B:
case 0x0C: report_par[*no_par]='3';
printf("\n Partition -%d = FAT32",
*no_par+1);
break;
/* Voor FAT16-partitie */
case 0x04:
case 0x06:
case 0x0E: report_par[*no_par]='1';
printf("\n Partition -%d = FAT16",
*no_par+1);
break;
} // End of switch
/* relatieve sectoren Aantal partities */
relative_sec=*(long *)(buffer+454+i*16);
no_sectors=*(long *)(buffer+458+i*16); /* number of
sectors in
partition*/
sectors_part[*no_par]=no_sectors; /* Array to store
Number of
sectors of
partitions */
*sec=star_sec[*no_par]=relative_sec;
(*no_par)++;
}
} //loop close of for(i=0;i<4;i++)
} //loop close of if(*sec==0)
return;
}
Opmerkingen over codering:
De functie begint met het lezen van de partitie-informatie van de MBR en leest vervolgens de Uitgebreide MBR's indien nodig. De functie readabsolutesectors leest de absolute sector, gespecificeerd door *sec.
sectors_part[*no_par] is de array om het aantal sectoren van partities op te slaan. Het partitienummer wordt gespecificeerd door *no_par vanaf 0.
no_sectors is het aantal sectoren in de partitie en relatieve_sec is het relatieve sectornummer voor die partitie.
star_sec[*no_par] is de array om de genoemde sectornummers van partities op te slaan. Het partitienummer wordt gespecificeerd door *no_par vanaf 0.
star_cyl, star_hea en star_sec zijn de arrays die de informatie over het starten van elke partitie bewaren in termen van CHS. star_cyl slaat de informatie van startcilinders op, star_hea slaat de informatie op van startkoppen en star_sec slaat de informatie op van startsectoren van partities.
Voor de beschrijving van de functie readabsolutesectors verwijzen we naar de hoofdstukken die eerder in dit boek zijn gegeven.
MBR wijzigen door te programmeren
Het voorbeeldprogramma om te laten zien hoe we de waarden van MBR-partitietabelinvoer kunnen wijzigen, wordt hieronder gegeven. Het programma wijzigt de waarden tweede partitie-invoer van MBR-partitietabel.
De codering van het programma is hieronder weergegeven:
/* Programma om de waarden van de partitietabelinvoer van MBR te wijzigen */
# include <bios.h>
/* structuur om het partitie-item uit de partitietabel te lezen */
struct partition
{
unsigned char bootable ; /* Active Partition
Byte */
unsigned char start_side ; /* Starting Head */
unsigned int start_sec_cyl ; /* combination of
Starting sector and
cylinder number */
unsigned char parttype ; /* File system
Indicator Byte */
unsigned char end_side ; /* Ending Head */
unsigned int end_sec_cyl ; /* combination of
Starting sector and
cylinder number */
unsigned long part_beg ; /* Relative Sector
Number */
unsigned long plen ; /* Partition length in
sectors */
} ;
/* Structuur om MBR . te lezen */
struct part
{
unsigned char master_boot[446] ; /* IPL (Initial
Program Loader)*/
struct partition pt[4] ; /* Partition table*/
int lasttwo ; /* Magic Number */
} ;
struct part p ;
void main()
{
unsigned int t1,t2;
clrscr();
biosdisk ( 2, 0x80, 0, 0, 1, 1, &p ) ;
display(); /* display the partition
Table information */
getch();
/* Laten we aannemen dat we de partitie-informatie van het tweede partitie-item uit de partitietabel van MBR willen wijzigen, met deze waarden */
p.pt[1].bootable = 0x80; /* Active Boot Partition */
p.pt[1].parttype = 0x7; /* NTFS Partition */
p.pt[1].start_side = 0; /* Starting Head =0 */
p.pt[1].end_side = 31; /* Ending Head == 31 */
p.pt[1].part_beg = 808416;/* Relative Sector = 808416 */
p.pt[1].plen = 405216; /* Total Sectors in Partition = 405216 */
/* Schrijf nieuwe informatie naar MBR *\
/* Om de waarden naar de MBR-partitietabel te schrijven, maakt u de onderstaande biosdisk-functie ongedaan */
// biosdisk ( 3, 0x80, 0, 0, 1, 1, &p ) ;
display(); /* Display the Modified
Information */
getch();
}
Opmerkingen over codering:
Het bovenstaande programma is een voorbeeldprogramma om te laten zien hoe we de waarden van partitietabelinvoer van MBR kunnen wijzigen. Als u de waarden van partitie-invoer wilt wijzigen voor dergelijke logische partities, die in uitgebreide partitie liggen, moet u de waarden in de partitietabel van Extended MBR wijzigen .
De waarden die hier zijn gegeven om de partitietabel te wijzigen, zijn alleen bedoeld om te demonstreren, hoe te wijzigen. Wijzig nooit partitietabel met illegale of onlogische waarden. Hierdoor kan de hele partitie ontoegankelijk worden.
De structuurpartitie wordt gebruikt om het partitie-item uit de partitietabel te lezen en het structuurgedeelte om MBR te lezen. Om de wijzigingen in de partitietabel daadwerkelijk aan te brengen, verwijdert u de functie biosdisk( ).
Als u de waarden van het begin en einde, sectoren en cilindernummers van de partitie wilt wijzigen, berekent u de waarden, zoals beschreven in de opmerkingen van het programma om de partitietabel van MBR te lezen en weer te geven, besproken in het begin van dit hoofdstuk.
Pagina aangepast op: 17/01/2022