📄 rfatsa.cxx
字号:
}
//
// Compute and return the FAT size
//
*ClusterCount = clusters + FirstDiskCluster;
return VALID;
}
DebugAbort("This line should never be executed.\n");
return TOO_BIG;
}
ULONG
ComputeClusters(
IN ULONG ClusterSize,
IN ULONG Sectors,
IN ULONG SectorSize,
IN ULONG ReservedSectors,
IN ULONG Fats,
IN FATTYPE FatType
)
/*++
Routine Description:
This routine computes the number of clusters on a volume given
the cluster size, volume size and the fat type.
Arguments:
ClusterSize - Supplies the size of a cluster in number of bytes.
Sectors - Supplies the total number of sectors in the volume.
SectorSize - Supplies the size of a sector in number of bytes.
ReservedSectors - Supplies the number of reserved sectors.
Fats - Supplies the number of copies of fat for this volume.
FatType - Supplies the fat type.
Return Value:
ULONG - The total number of clusters for the given configuration.
++*/
{
ULONG entries_per_sec; // Number of FAT entries per sector.
ULONG fat_entry_size; // Size of each FAT entry in number of BITS.
ULONG sectors_left; // Number of sectors left for consideration.
ULONG residue; // The residue number of bits per sector.
ULONG acc_residue = 0; // The accumulated residue number of FAT entry
// bits.
ULONG sec_per_clus; // Sectors per cluster.
ULONG increment = 1; // Increment step size in number of FAT sectors.
ULONG additional_clus; // Number of additional clusters possible due to
// the accumulated residue bits in the fat.
ULONG clusters = 0; // Number of clusters in total.
ULONG temp; // Temporary place-holder for optimizing certain
// computations.
sectors_left = Sectors - ReservedSectors;
sec_per_clus = ClusterSize / SectorSize;
//
// Determine the Fat entry size in number of bits based on the
// fat type.
//
switch (FatType) {
case SMALL:
fat_entry_size = 12;
break;
case LARGE16:
fat_entry_size = 16;
break;
case LARGE32:
fat_entry_size = 32;
break;
}
//
// Compute the number of FAT entries a sector can hold.
// NOTE that fat_entry_size is the size in BITS,
// this is the reason for the "* 8" (bits per byte).
//
entries_per_sec = (SectorSize * 8) / fat_entry_size;
//
// If the FAT entry size doesn't divide the sector
// size evenly, we want to know the residue.
//
residue = (SectorSize * 8) % fat_entry_size;
//
// Compute a sensible increment step size to begin with.
//
while (Sectors / (increment * entries_per_sec * sec_per_clus) > 1) {
increment *= 2;
}
//
// We have to handle the first sector of FAT entries
// separately because the first two entries are reserved.
//
temp = Fats + ((entries_per_sec - 2) * sec_per_clus);
if (sectors_left < temp) {
return (sectors_left - Fats) / sec_per_clus;
} else {
sectors_left -= temp;
acc_residue += residue;
clusters += entries_per_sec - 2;
while (increment && sectors_left) {
additional_clus = (acc_residue + (increment * residue)) / fat_entry_size;
temp = (Fats + entries_per_sec * sec_per_clus) * increment + additional_clus * sec_per_clus;
if (sectors_left < temp) {
//
// If the increment step is only one, try to utilize the remaining sectors
// as much as possible.
//
if (increment == 1) {
//
// Exhaust the residue fat entries first
//
temp = acc_residue / fat_entry_size;
if (temp <= sectors_left / sec_per_clus) {
clusters += temp;
sectors_left -= temp * sec_per_clus;
} else {
clusters += sectors_left / sec_per_clus;
sectors_left -= sectors_left / sec_per_clus;
}
//
// Additional clusters may be possible after allocating
// one more sector of fat.
//
if ( sectors_left > Fats) {
temp = (sectors_left - Fats) / sec_per_clus;
if (temp > 0) {
clusters += temp;
}
}
}
//
// Cut the increment step by half if it is too big.
//
increment /= 2;
} else {
if (additional_clus) {
acc_residue = (acc_residue + (increment * residue)) % (additional_clus * fat_entry_size);
} else {
acc_residue += increment * residue;
}
sectors_left -= temp;
clusters += increment * entries_per_sec + additional_clus;
}
}
return clusters;
}
DebugAbort("This line should never be executed.");
return 0;
}
ULONG
REAL_FAT_SA::ComputeDefaultClusterSize(
IN ULONG Sectors,
IN ULONG SectorSize,
IN ULONG ReservedSectors,
IN ULONG Fats,
IN MEDIA_TYPE MediaType,
IN FATTYPE FatType,
OUT PULONG FatSize,
OUT PULONG ClusterCount
)
/*++
Routine Description:
This routine computes a default cluster size given the total number
of free sectors and fat type.
Arguments:
Sectors - Supplies the total number of sectors on the volume.
SectorSize - Supplies the size of a sector in bytes.
ReservedSectors - Supplies the number of reserved sectors.
Fats - Supplies the number of fats.
MediaType - Supplies the media type.
FatType - Supplies the fat type.
FatSize - Supplies a location for this routine to pass back the
size of a FAT in number of sectors back to the caller.
ClusterCount - Supplies a location for this routine to pass back
the total number of clusters on the volume.
Return Values:
ULONG - The number of clusters that should on the volume computed
by the default algorithm.
++*/
{
ULONG fat_size; // Number of sectors per fat.
ULONG sec_per_clus; // Number of sectors per cluster.
VALIDATION_STATUS result; // Result after validating
// the cluster size.
//
// Assign a reasonable value to sec_per_clus
// base on the number of sectors in total.
//
switch (FatType) {
case LARGE32:
//
// The numbers in this may look a bit odd and arbitrary, they are.
// They match the ones that MS-DOS/Win95 use for FAT32 drives, at least
// for 512 byte sectors. NOTE than in the case of other sector sizes
//
if (Sectors >= 64*1024*1024) { // >= 32GB
sec_per_clus = 64; // 32k cluster @ 512 byt/sec
} else if (Sectors >= 32*1024*1024) { // >= 16GB
sec_per_clus = 32; // 16k cluster @ 512 byt/sec
} else if (Sectors >= 16*1024*1024) { // >= 8GB
sec_per_clus = 16; // 8k cluster @ 512 byt/sec
} else { // else
sec_per_clus = 8; // 4k cluster @ 512 byt/sec
}
break;
case LARGE16:
sec_per_clus = 1;
break;
case SMALL:
sec_per_clus = 1;
break;
default:
DebugAbort("This cannot happen.");
}
//
// If this is a floppy disk, we just choose a default value.
//
switch (MediaType) {
case F5_320_512:
case F5_360_512:
case F3_720_512:
case F3_2Pt88_512:
#if defined(FE_SB) && defined(_X86_)
case F5_640_512:
case F3_640_512:
case F5_720_512:
#endif
sec_per_clus = 2;
break;
case F3_20Pt8_512:
#if defined(FE_SB)
case F3_128Mb_512:
#if defined(_X86_)
case F8_256_128:
#endif
#endif
sec_per_clus = 4;
break;
#if defined(FE_SB)
case F3_230Mb_512:
sec_per_clus = 8;
break;
#endif
default:
break;
}
//
// Validate the assigned number of sectors per
// cluster and readjust them if necessary.
//
result = ValidateClusterSize( sec_per_clus * SectorSize,
Sectors,
SectorSize,
Fats,
&_ft,
&fat_size,
ClusterCount);
switch (result) {
case TOO_SMALL:
//
// If the cluster size is too small, keep enlarging
// it by a factor of 2 until it is valid.
//
do {
sec_per_clus *= 2;
if ( sec_per_clus > 128 ) {
return (sec_per_clus * SectorSize);
}
} while (ValidateClusterSize( sec_per_clus * SectorSize,
Sectors,
SectorSize,
Fats,
&_ft,
&fat_size,
ClusterCount) != VALID);
break;
case TOO_BIG:
//
// If the cluster size is too big, keep reducing it
// by half until it is valid.
//
do {
sec_per_clus /= 2;
if ( sec_per_clus == 0 ) {
return (sec_per_clus * SectorSize);
}
} while (ValidateClusterSize( sec_per_clus * SectorSize,
Sectors,
SectorSize,
Fats,
&_ft,
&fat_size,
ClusterCount) != VALID);
break;
case VALID:
break;
default:
DebugAbort("This should never happen.");
break;
}
*FatSize = fat_size;
return (sec_per_clus * SectorSize);
}
BOOLEAN
REAL_FAT_SA::SetBpb(
)
{
DebugAbort("This method should never be called.");
return FALSE;
}
BOOLEAN
REAL_FAT_SA::SetBpb(
IN ULONG ClusterSize,
IN BOOLEAN BackwardCompatible,
IN PMESSAGE Message
)
/*++
Routine Description:
This routine sets up the BPB from scratch for the FAT file system.
Arguments:
ClusterSize - Supplies the desired number of bytes per cluster.
BackwardCompatible - Supplies whether the volume should remain
FAT16/12 compatible.
Message - Supplies an outlet for messages.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
#if defined( _SETUP_LOADER_ )
return FALSE;
#else // _SETUP_LOADER_
SECTORCOUNT sectors; // Total number of sectors.
ULONG sector_size; // Size of each sector in bytes.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -