{
struct boot_sectorb;
unsignedtotal_sectors;
unsignedshort logical_sector_size, sectors;
unsignedfat_length;
loff_t data_size;
fs_read(0,sizeof(b),&b);
logical_sector_size = GET_UNALIGNED_W(b.sector_size);
if (!logical_sector_size) die("Logical sector size is zero.");
fs->cluster_size = b.cluster_size*logical_sector_size;
if (!fs->cluster_size) die("Cluster size is zero.");
if (b.fats != 2 && b.fats != 1)
die("Currently, only 1 or 2 FATs are supported, not %d.\n",b.fats);
fs->nfats = b.fats;
sectors = GET_UNALIGNED_W(b.sectors);
total_sectors = sectors ? sectors : CF_LE_L(b.total_sect);
if (FsCheckFlags & FSCHECK_VERBOSE) VfatPrint("Checking we can access the last sector of the filesystem\n");
/* Can't access last odd sector anyway, so round down */fs_test((loff_t)((total_sectors & ~1)-1)*(loff_t)logical_sector_size,
logical_sector_size);
fat_length = CF_LE_W(b.fat_length) ?
CF_LE_W(b.fat_length) : CF_LE_L(b.fat32_length);
fs->fat_start = (off_t)CF_LE_W(b.reserved)*logical_sector_size;
fs->root_start = ((off_t)CF_LE_W(b.reserved)+b.fats*fat_length)*
logical_sector_size;
fs->root_entries = GET_UNALIGNED_W(b.dir_entries);
fs->data_start = fs->root_start+ROUND_TO_MULTIPLE(fs->root_entries <<
MSDOS_DIR_BITS,logical_sector_size);
data_size = (loff_t)total_sectors*logical_sector_size-fs->data_start;
fs->clusters = data_size/fs->cluster_size;
fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */
fs->fsinfo_start = 0; /* no FSINFO structure */
fs->free_clusters = -1; /* unknown */if (!b.fat_length && b.fat32_length) {
fs->fat_bits = 32;
fs->root_cluster = CF_LE_L(b.root_cluster);
if (!fs->root_cluster && fs->root_entries)
/* M$ hasn't specified this, but it looks reasonable: If * root_cluster is 0 but there is a separate root dir * (root_entries != 0), we handle the root dir the old way. Give a * warning, but convertig to a root dir in a cluster chain seems * to complex for now... */VfatPrint( "Warning: FAT32 root dir not in cluster chain! ""Compability mode...\n" );
elseif (!fs->root_cluster && !fs->root_entries)
die("No root directory!");
elseif (fs->root_cluster && fs->root_entries)
VfatPrint( "Warning: FAT32 root dir is in a cluster chain, but ""a separate root dir\n"" area is defined. Cannot fix this easily.\n" );
fs->backupboot_start = CF_LE_W(b.backup_boot)*logical_sector_size;
check_backup_boot(fs,&b,logical_sector_size);
read_fsinfo(fs,&b,logical_sector_size);
}
else {
/* On real MS-DOS, a 16 bit FAT is used whenever there would be too * much clusters otherwise. */
fs->fat_bits = (fs->clusters > MSDOS_FAT12) ? 16 : 12;
}
/* On FAT32, the high 4 bits of a FAT entry are reserved */
fs->eff_fat_bits = (fs->fat_bits == 32) ? 28 : fs->fat_bits;
fs->fat_size = fat_length*logical_sector_size;
if (fs->clusters > ((__u64)fs->fat_size*8/fs->fat_bits)-2)
die("File system has %d clusters but only space for %d FAT entries.",
fs->clusters,((__u64)fs->fat_size*8/fs->fat_bits)-2);
if (!fs->root_entries && !fs->root_cluster)
die("Root directory has zero size.");
if (fs->root_entries & (MSDOS_DPS-1))
die("Root directory (%d entries) doesn't span an integral number of ""sectors.",fs->root_entries);
if (logical_sector_size & (SECTOR_SIZE-1))
die("Logical sector size (%d bytes) is not a multiple of the physical ""sector size.",logical_sector_size);
/* ++roman: On Atari, these two fields are often left uninitialized */if ((!b.secs_track || !b.heads))
die("Invalid disk format in boot sector.");
if (FsCheckFlags & FSCHECK_VERBOSE) dump_boot(fs,&b,logical_sector_size);
}
Generated on Mon May 28 2012 06:04:43 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.