下面的程序是读取大于 32MB 的大 Volumes 的 DBR:
/* 显示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(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);
/* 反转并输出二进制数字 */
do
{
printf ("%d", binary[count - 1]);
count--;
} while (count > 0);
return 0;
}
当运行程序读取大容量的DBR时,程序的输出显示如下:
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)
在程序的输出中,我们看到以下参数显示为零:
- 根目录条目
- 磁盘上的扇区数
- 每个 FAT 的扇区数
这些参数之所以如此是因为这些值设置为零,如果分区卷的大小大于 32MB,并且实际信息在 DBR 的扩展卷信息块中找到。
例如,在 DBR 信息的初始部分,每个 FAT 的扇区数为 0,在 DBR 的扩展卷信息块中,每个 FAT 的扇区数为 11003,这是这个大卷的实际值.
Volume 的 DBR 包含有关磁盘参数的重要信息,可用于链接所有数据信息以进行编程。例如,如果要访问磁盘上其他Partition卷的DBR,可以通过扇区数、写入DBR等相关信息来计算。
如果您想通过集群方式访问磁盘,您可以借助 Sectors per cluster、Sectors per FAT 等信息进行计算。
如果您使用大于 8.4 GB 的硬盘(参见本书前面讨论过的“磁盘和操作系统的逻辑方法”一章),请使用扩展来访问超过 8.4 GB 的磁盘的所有 DBR。请参阅前几章中给出的扩展读写功能
如何通过编程恢复 DBR
通过使用一些棘手的方法和逻辑计算,您可以将磁盘卷的 DBR 恢复到 100%。正如我们在本书前面的“磁盘和操作系统的逻辑方法”一章中讨论的文件系统的逻辑方法一样,DBR 中的每一个信息都是在一定的限制或规则内写入的。
DBR 中写入的每个参数都有一些特定的含义,并且遵循一些特定的规则和原因。这就是为什么 DBR 的信息如果丢失,可以重新链接或手动重写,如果您遵循这些规则并使用狡猾的头脑找出什么以及如何解决。
例如,下面给出的表格描述了不同文件系统的每个簇的扇区数,通过该表您可以找到磁盘的每个簇的扇区数。让我们假设您的磁盘中有大约 10GB 的容量,并且您使用的操作系统是 Windows 98。
现在,如果有的话,卷的 DBR 的“每个集群的扇区”信息是如何损坏的。让我们尝试找出您的磁盘卷中有哪个文件系统以及每个集群有多少个扇区。
由于你磁盘的操作系统是windows 98,它只支持FAT文件系统,所以你的Volume的文件系统是FAT。现在让我们考虑一下卷的大小,大约为 10GB。
我们知道 FAT16 不支持 10GB 分区(见下表),因此该卷的文件系统应该是 FAT32。
现在让我们尝试计算卷的每个簇的扇区数。正如我们在表中看到的,在 8GB 到 16GB 范围内的分区有 8 个扇区组成的一簇。
因此,现在我们可以得出结论,在卷中,文件系统是 FAT32,每个簇有 8 个扇区。类似地,我们可以使用本书前面章节中描述的其他逻辑方法来组装 DBR 的其他信息。
编写了以下程序来重写1.44Mb的DBR中的磁盘参数信息,3½英寸软盘,有80个磁道,2个磁头(面),每磁道18个扇区。
/* 更改 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;
}