📄 rfatsa.cxx
字号:
// super area SECRUN buffer.
ULONG root_size; // Size of the root directory in number of sectors.
ULONG sector_size; // Well, it's kind of obvious isn't it.
sector_size = _drive->QuerySectorSize();
if (!(_dir = NEW ROOTDIR)) {
Destroy();
Message->Set(MSG_FMT_NO_MEMORY);
Message->Display("");
return FALSE;
} else {
ULONG root_offset; // Sector offset of the root directory from the
// beginning of the disk.
//
// Computes the sector offset of the root directory.
//
root_offset = _sector_zero.Bpb.ReservedSectors +
_sector_zero.Bpb.SectorsPerFat *
_sector_zero.Bpb.Fats;
//
// Size of the root directory in number of bytes. Note that the
// result is rounded up to the nearest size size.
//
root_size = ((_sector_zero.Bpb.RootEntries * BytesPerDirent - 1)
/ sector_size + 1) * sector_size;
//
// Now it's time to initialize the root directory. Note that this operation
// shouldn't fail because REAL_FAT_SA::Initialize should have allocated
// enough memory for the root directory through REAL_FAT_SA::DosSaInit.
//
if(!cmem.Initialize((PCHAR) SECRUN::GetBuf() + (root_offset * sector_size), root_size) ||
!_dir->Initialize(&cmem, _drive, root_offset, _sector_zero.Bpb.RootEntries)) {
DebugPrintTrace(("The secrun buffer should have enough space, big bug in code.\n"));
Message->Set(MSG_FMT_NO_MEMORY);
Message->Display("");
Destroy();
return FALSE;
}
}
}
return TRUE;
}
BOOLEAN
REAL_FAT_SA::CreateBootSector(
IN ULONG ClusterSize,
IN BOOLEAN BackwardCompatible,
IN PMESSAGE Message
)
/*++
Routine Description:
This routine updates fields in sector 0.
Arguments:
ClusterSize - Supplies the desired number of bytes per cluster.
BackwardCompatible - Supplies whether the volume should be
compatible with FAT16.
Message - Supplies an outlet for messages.
Return Value:
TRUE - Success.
FALSE - Failure.
--*/
{
#if defined _SETUP_LOADER_
return FALSE;
#else
SetVolId(ComputeVolId());
return SetBpb(ClusterSize, BackwardCompatible, Message) &&
SetBootCode() &&
SetPhysicalDriveType(_drive->IsRemovable() ?
PHYS_REMOVABLE : PHYS_FIXED) &&
SetOemData() &&
SetSignature();
#endif // _SETUP_LOADER_
}
VALIDATION_STATUS
REAL_FAT_SA::ValidateClusterSize(
IN ULONG ClusterSize,
IN ULONG Sectors,
IN ULONG SectorSize,
IN ULONG Fats,
IN OUT FATTYPE *FatType,
OUT PULONG FatSize,
OUT PULONG ClusterCount
)
/*++
Routine Description:
This routine validates whether a given cluster size is
valid for a particular FAT type. If the fat type provided is
INVALID_FATTYPE, this routine would determine whether FAT12 or
FAT16 should be used.
Arguments:
ClusterSize - Supplies the cluster size to be validated.
Sectors - Supplies the total number of sectors on the volume.
SectorSize - Supplies the number of bytes per sector.
Fats - Supplies the number of FATs in the volume.
FatType - Supplies the FAT type that the volume is going to be
formatted. The caller will supply INVALID_FATTYPE if
it is unsure whether the volume should be formatted
as a FAT16 volume or a FAT12 volume and let this function
to make the descision.
FatSize - Supplies a location where the size of a fat in number
of sectors can be passed back to the caller if the
cluster size is valid.
ClusterCounter - Supplies a location where the total number
of clusters can be passed back to the caller if the
given cluster size is valid.
Return Values:
VALIDATION_STATUS
VALID - The given cluster size is valid.
TOO_SMALL - The given cluster size is too small (Too many clusters).
TOO_BIG - The given cluster size is too big. (Too few clusters).
++*/
{
ULONG min_sec_req; // Minimum number of sectors required.
ULONG min_fat_size; // Minimum size of the FATs in number
// of sectors.
ULONG fat_entry_size; // Number of bytes per fat entry.
ULONG sec_per_clus; // Number of sectors per cluster.
ULONG clusters; // Number of clusters.
FATTYPE fat_type; // Local fat type.
ULONG initial_data_sector_offset;
ULONG data_sector_offset;
ULONG pad; // Padding to be added to the reserved sectors
// for data alignment
DebugAssert(ClusterSize);
//
// Check for absolute minumum (one sector per cluster)
//
if (ClusterSize < SectorSize) {
return TOO_SMALL;
}
//
// Compute the number of sectors per cluster.
//
sec_per_clus = ClusterSize / SectorSize;
//
// Make sure that sec_per_clus <= 128
//
if (sec_per_clus > 128) {
return TOO_BIG;
}
fat_type = *FatType;
if (fat_type == INVALID_FATTYPE) {
// If the caller doesn't specify the fat type,
// try FAT16 first unless the volume is > 2Gig bytes
// in size (512 byte sectors only).
if((SectorSize == 512) && (Sectors > (4 * 1024 * 1024))) {
fat_type = LARGE32;
} else {
fat_type = LARGE16;
}
}
//
// Compute the minimum number of sectors required by the
// FAT(s)
// The minimum number of sectors that the fats on a volume will
// occupy is given by: RoundUp(Number of fats * (minimum number of
// clusters + 2) * bytes per fat entry / sector size).
//
if (fat_type == LARGE32) {
fat_entry_size = 4;
min_fat_size = RoundUpDiv( Fats * (MIN_CLUS_BIG32 + 2) * fat_entry_size,
SectorSize);
min_sec_req = min_fat_size + MIN_CLUS_BIG32 * sec_per_clus;
if (Sectors > min_sec_req) { // Meets the minimum requirement
//
// Compute the number of clusters
//
initial_data_sector_offset = max(32, _sec_per_boot);
for (pad=0; ; pad++) {
data_sector_offset = initial_data_sector_offset + pad;
clusters = ComputeClusters( ClusterSize,
Sectors,
SectorSize,
data_sector_offset,
Fats,
fat_type);
*FatSize = RoundUpDiv((clusters+2) * fat_entry_size , SectorSize);
data_sector_offset += (*FatSize * Fats);
if (_drive->IsFloppy() ||
((((BIG_INT)data_sector_offset*SectorSize).GetLowPart() &
(FAT_FIRST_DATA_CLUSTER_ALIGNMENT-1)) == 0)) {
_AdditionalReservedSectors = pad;
break;
}
}
//
// Check to see if the cluster size is too small
//
if ( clusters > MAX_CLUS_BIG32 ) {
return TOO_SMALL;
}
//
// See if this cluster size makes the FAT too big. Win95's FAT32
// support does not support FATs > 16Meg - 64k bytes in size because
// the GUI version of SCANDISK is a 16-bit windows application that
// has this limit on its allocation block size. This value is also
// a quite reasonable lid on FAT size.
//
if ((clusters * 4) > ((16 * 1024 * 1024) - (64 * 1024))) {
return TOO_SMALL;
}
//
// Return the fat type if the caller
// doesn't specify it.
//
if (*FatType == INVALID_FATTYPE) {
*FatType = LARGE32;
}
//
// Compute the fat size and return it to the caller
//
*ClusterCount = clusters + FirstDiskCluster;
return VALID;
}
// Volume is too small for FAT32
return TOO_BIG;
}
//
// The code in this function may look a bit asymmetrical
// but that's because we treat FAT32 separately from
// FAT16/12.
//
if (fat_type == LARGE16) {
//
// Again, we compute the minimum number of sectors required if the
// if the volume is formatted as a FAT16 volume.
//
fat_entry_size = 2;
min_fat_size = RoundUpDiv( Fats * (MIN_CLUS_BIG + 2) * fat_entry_size, SectorSize);
min_sec_req = min_fat_size + MIN_CLUS_BIG * sec_per_clus;
if (Sectors > min_sec_req) { // Meets the minimum requirement
//
// Compute the number of clusters
//
initial_data_sector_offset = _sec_per_boot +
(_sector_zero.Bpb.RootEntries * BytesPerDirent - 1) /
SectorSize + 1;
for (pad=0; ; pad++) {
data_sector_offset = initial_data_sector_offset + pad;
clusters = ComputeClusters( ClusterSize,
Sectors,
SectorSize,
data_sector_offset,
Fats,
fat_type );
*FatSize = RoundUpDiv((clusters + 2) * fat_entry_size, SectorSize);
data_sector_offset += (*FatSize * Fats);
if (_drive->IsFloppy() ||
((((BIG_INT)data_sector_offset*SectorSize).GetLowPart() &
(FAT_FIRST_DATA_CLUSTER_ALIGNMENT-1)) == 0)) {
_AdditionalReservedSectors = pad;
break;
}
}
if (clusters > MAX_CLUS_BIG) {
return TOO_SMALL;
} else {
//
// Return the fat type if the caller
// doesn't specify it.
//
if (*FatType == INVALID_FATTYPE) {
*FatType = LARGE16;
}
//
// Compute and return the fat size to the caller.
//
*ClusterCount = clusters + FirstDiskCluster;
return VALID;
}
} else {
//
// Don't bother to fall over to the FAT12 section if the
// volume has more that 32679 sectors.
//
if (*FatType == INVALID_FATTYPE && Sectors < CSEC_FAT16BIT ) {
//
// Fall over to the FAT12 section
//
fat_type = SMALL;
} else {
return TOO_BIG;
}
}
}
//
// A volume is never too small for FAT12 so we just
// check whether it is too big.
//
if (fat_type == SMALL) {
initial_data_sector_offset = _sec_per_boot +
(_sector_zero.Bpb.RootEntries * BytesPerDirent - 1) /
SectorSize + 1;
for (pad=0; ; pad++) {
data_sector_offset = initial_data_sector_offset + pad;
clusters = ComputeClusters( ClusterSize,
Sectors,
SectorSize,
data_sector_offset,
Fats,
fat_type );
*FatSize = RoundUpDiv(RoundUpDiv((clusters + 2) * 3, 2), SectorSize);
data_sector_offset += (*FatSize * Fats);
if (_drive->IsFloppy() ||
((((BIG_INT)data_sector_offset*SectorSize).GetLowPart() &
(FAT_FIRST_DATA_CLUSTER_ALIGNMENT-1)) == 0)) {
_AdditionalReservedSectors = pad;
break;
}
}
if (clusters > MAX_CLUS_SMALL) {
return TOO_SMALL;
}
//
// Return fat type to caller if necessary
//
if (*FatType == INVALID_FATTYPE) {
*FatType = SMALL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -