📄 rtfbs.c
字号:
Sectors = NewStartSector - P->RelativeSector;
if (Sectors > P->Sectors)
return RTF_INVALID_FILE_SYSTEM;
if ((Sectors + SectorsPerCylinder) > P->Sectors)
return RTF_INVALID_FILE_SYSTEM;
if (NewStartCylinder >= 1024) // we can't put such values in the partition table
NewStartCylinder = 0;
// setup new partition
P[1].StartHead = 0;
P[1].StartSector = 1 | ((NewStartCylinder & 0x300) >> 2);
P[1].StartTrack = NewStartCylinder;
// move EndHead/Sector/Track from P to P+1
P[1].EndHead = P[0].EndHead;
P[1].EndSector = P[0].EndSector;
P[1].EndTrack = P[0].EndTrack;
P[1].RelativeSector = NewStartSector;
P[1].Sectors = P[0].RelativeSector + P[0].Sectors - NewStartSector;
// adjust P[0]'s EndHead/Sector/Track, Sectors
OldEndCylinder = (NewStartSector-2) / SectorsPerCylinder;
if (OldEndCylinder >= 1024)
OldEndCylinder = 0;
P[0].EndSector = (P[0].EndSector & 63) | ((OldEndCylinder & 0x300) >> 2);
P[0].EndTrack = OldEndCylinder;
P[0].Sectors = Sectors;
// Set OSTypes
P[0].OSType = DefaultOSType(P[0].Sectors, (P[0].RelativeSector + P[0].Sectors - 1) / SectorsPerCylinder);
P[1].OSType = DefaultOSType(P[1].Sectors, (P[1].RelativeSector + P[1].Sectors - 1) / SectorsPerCylinder);
return P - MBR->PTable + 1; // index of new partition
}
/*
Partition Size ClusterS ClusterC
------------------------------------
FAT-12 0- 1M 0.5k 0- 2k
1M- 4M 1k 1k- 4k
4M- 16M 2k 2k-
8M- 16M 4k 2k- 4k
FAT-16 2M- 8M 0.5k 4k- 16k
8M- 32M 1k 8k- 32k
32M-128M 2k 16k- 64k
128M-512M 4k 32k-
256M-512M 8k 32k- 64k
FAT-32
128M-256M 2k 64k-128k
256M- 1G 4k 64k-256k
1G- 4G 8k 128k-512k
4G- 16G 16k 256k- 1M
16G- 64G 32k 512k- 2M
64G-256G 32k 2M- 8M
256G- 1T 32k 8M- 32M
1T- 2T 32k 32M- 64M
Default configurations do not allow cluster sizes beyond 4k for FAT-12
and 8k for FAT-16
*/
/*-----------------------------------*/
static DWORD GetDefaultClusterSize(DWORD Sectors, int FatType)
{
DWORD Result = 1;
DWORD Size;
switch (FatType)
{
case 12:
Size = 1 M;
break;
case 16:
Size = 8 M;
break;
case 32:
Result = 4;
Size = 256 M;
break;
/* Remove RVCT warning, Karen Hsu, 2004/11/02, ADD START */
default:
Size = 1 M;
break;
/* Remove RVCT warning, Karen Hsu, 2004/11/02, ADD END */
}
while (Size < Sectors)
{
Result <<= 1;
Size <<= 2;
}
// the default must be Microsoft compatible, even though RTFiles supports more
return (Result > 64) ? 64 : Result;
}
/*-----------------------------------*/
int RTFAPI RTFCreateBootSector(void * BootSector,
const RTFPartitionRecord * Partition,
BYTE MediaDescriptor,
UINT MinSectorsPerCluster,
DWORD Flags)
{
RTFBootRecord * BR = BootSector;
int FatType;
DWORD SectorsPerCluster;
DWORD RootDirSectors, DataSectors, Clusters, NetSectors;
if (!QPowerTwo(MinSectorsPerCluster))
return RTF_PARAM_ERROR;
#define FMT_FAT_ALL_FLAGS (RTF_FMT_FAT_12 | RTF_FMT_FAT_16 | RTF_FMT_FAT_32)
switch (Flags & FMT_FAT_ALL_FLAGS)
{
case RTF_FMT_FAT_12:
case (RTF_FMT_FAT_12 | RTF_FMT_FAT_16):
FatType = 12;
break;
case RTF_FMT_FAT_16:
case (RTF_FMT_FAT_16 | RTF_FMT_FAT_32):
FatType = 16;
break;
case RTF_FMT_FAT_32:
if (Flags & RTF_FMT_NO_FAT_32)
return RTF_PARAM_ERROR;
FatType = 32;
break;
default:
if (Partition->Sectors < (16 M))
FatType = 12;
else if (Partition->Sectors < (512 M))
FatType = 16;
else
if (Flags & RTF_FMT_NO_FAT_32)
FatType = 16;
else
FatType = 32;
}
NewFATType:
if ((Flags & RTF_FMT_NO_FAT_32) && (FatType == 32))
return RTF_INVALID_FILE_SYSTEM; // this can only happen due to a retry
memset((void*)BR, 0, SECTOR_SIZE);
BR->NearJump[0] = 0xEB;
BR->NearJump[1] = 0x58;
BR->NearJump[2] = 0x90;
memcpy((void*)&BR->BootCode, (void*)BootCode, sizeof(BootCode));
memcpy((void*)BR->BP.OEMName, "FileSys ", 8);
BR->Signature = 0xAA55;
BR->BP.BytesPerSector = SECTOR_SIZE;
BR->BP.ReservedSectors = (FatType == 32) ? 32 : 1;
BR->BP.TotalSectors = Partition->Sectors;
BR->BP.SectorsOnDisk = (Partition->Sectors >= 0x10000l) ? 0 : Partition->Sectors;
BR->BP.NumberOfHiddenSectors = Partition->RelativeSector;
BR->BP.NumberOfFATs = (Flags & RTF_FMT_SINGLE_FAT) ? 1 : 2;
switch (FatType)
{
case 12: BR->BP.DirEntries = 128; break;
case 16: BR->BP.DirEntries = 512; break;
case 32: BR->BP.DirEntries = 0; break;
}
BR->BP.MediaDescriptor = MediaDescriptor;
BR->BP.SectorsPerTrack = Partition->EndSector & 63;
BR->BP.NumberOfHeads = Partition->EndHead + 1;
{
RTFExtendedBIOSParameter * EBPB = (FatType == 32) ? &BR->BP.E._32.BPB : &BR->BP.E._16.BPB;
EBPB->PhysicalDiskNumber = (BR->BP.MediaDescriptor == 0xF8) ? 0x80 : 0;
EBPB->Signature = 0x29; // keep NT happy
RTFSYSGetDateTime((RTFDOSDateTime*) &EBPB->SerialNumber);
memcpy((void*)EBPB->Label, "NO NAME ", sizeof(EBPB->Label));
switch (FatType)
{
case 12: memcpy((void*)EBPB->SystemID, "FAT12 ", 8); break;
case 16: memcpy((void*)EBPB->SystemID, "FAT16 ", 8); break;
case 32: memcpy((void*)EBPB->SystemID, "FAT32 ", 8); break;
}
}
if (FatType == 32)
{
BR->BP.E._32.RootDirCluster = 2;
BR->BP.E._32.FSInfoSector = 1;
BR->BP.E._32.BackupBootSector = 6;
}
RootDirSectors = (BR->BP.DirEntries * 32 + (BR->BP.BytesPerSector - 1)) / SECTOR_SIZE;
NetSectors = BR->BP.TotalSectors - BR->BP.ReservedSectors - RootDirSectors;
SectorsPerCluster = MinSectorsPerCluster ? MinSectorsPerCluster : GetDefaultClusterSize(BR->BP.TotalSectors, FatType);
NewClusterSize:
switch (FatType)
{
case 12:
case 16:
// calculate the maximum FAT size assuming that the FAT itself needs just one sector.
// Then, reduce the FAT one sector at a time until it no longer fits.
// increase the FAT by one sector to a valid configuration (this
// is done after the enclosing switch statement)
#define FAT_12_SECTORS(Clusters) ((((Clusters)+2) * 3 / 2 - 1) / SECTOR_SIZE + 1)
#define FAT_16_SECTORS(Clusters) ((((Clusters)+2) * 2 - 1) / SECTOR_SIZE + 1)
#define FAT_SECTORS(Clusters) ((FatType == 12) ? FAT_12_SECTORS(Clusters) : FAT_16_SECTORS(Clusters))
BR->BP.SectorsPerFAT = FAT_SECTORS((FatType == 12) ? MAX_CLUSTERS_12 : MAX_CLUSTERS_16); // too large
while (1)
{
DataSectors = NetSectors - BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT; // too small
Clusters = DataSectors / SectorsPerCluster;
// Do we have too many clusters?
// If so, increase cluster size. This loop will increase the
// number of data sectors, so this problem will not get fixed
// and is detected in the first iteration
if (Clusters > ((FatType == 12) ? MAX_CLUSTERS_12 : MAX_CLUSTERS_16))
{
if (SectorsPerCluster < (32l*1024))
{
if ((Flags & RTF_FMT_FAT_32) == 0) // we are allowd to pick FAT type
{
switch (FatType)
{
case 12:
if (SectorsPerCluster >= 16)
{
FatType = 16;
goto NewFATType;
}
break;
case 16:
if ((SectorsPerCluster >= 64) && ((Flags & RTF_FMT_NO_FAT_32) == 0))
{
FatType = 32;
goto NewFATType;
}
} // switch (FatType)
}
// increase cluster size if feasible or necessary
SectorsPerCluster *= 2;
goto NewClusterSize;
}
else
return RTF_INVALID_FILE_SYSTEM;
}
// Is our FAT big enough to hold all clusters?
// If it's too small, increment (success).
// This can't be true in the first interation as the maximum
// FAT size must accomodate for MAX_CLUSTERS
// If we have too many clusters, the previous check threw us
// out already
if (BR->BP.SectorsPerFAT < FAT_SECTORS(Clusters))
break;
BR->BP.SectorsPerFAT--;
}
BR->BP.SectorsPerFAT++;
DataSectors = NetSectors - BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT;
Clusters = DataSectors / SectorsPerCluster;
// check that we do not have too few clusters
if ((FatType == 16) && (Clusters <= MAX_CLUSTERS_12))
return RTF_INVALID_FILE_SYSTEM;
break;
case 32:
// we do not have to worry about too many clusters
// start with 512 cluster per fat (minimum for FAT-32) and increase until it fits.
#define FAT_32_SECTORS(Clusters) ((((Clusters)+2) * 4 - 1) / SECTOR_SIZE + 1)
for (BR->BP.E._32.SectorsPerFAT=512; ;BR->BP.E._32.SectorsPerFAT++)
{
DataSectors = NetSectors - BR->BP.NumberOfFATs * BR->BP.E._32.SectorsPerFAT;
Clusters = DataSectors / SectorsPerCluster;
// Is our FAT big enough to hold all clusters?
if (BR->BP.E._32.SectorsPerFAT >= FAT_32_SECTORS(Clusters))
break;
}
// check that we do not have too few clusters
if (Clusters <= MAX_CLUSTERS_16)
return RTF_INVALID_FILE_SYSTEM;
break;
}
// record SectorsPerCluster
if (SectorsPerCluster <= 128)
BR->BP.SectorsPerCluster = SectorsPerCluster;
else
{
BR->BP.SectorsPerCluster = 0;
while ((1 << BR->BP.SectorsPerCluster) < SectorsPerCluster)
BR->BP.SectorsPerCluster++;
BR->BP.SectorsPerCluster |= 0x80;
}
/* Add to support Renasas NAND, Karen Hsu, 2005/05/19, ADD START */
if (Flags & RTF_FMT_GET_DATA_SECTOR)
{
if (FatType == 12)
return (BR->BP.ReservedSectors + BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT + RootDirSectors);
else if (FatType == 16)
return (BR->BP.ReservedSectors + BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT + RootDirSectors);
else
return (BR->BP.ReservedSectors + BR->BP.NumberOfFATs * BR->BP.E._32.SectorsPerFAT);
}
else
/* Add to support Renasas NAND, Karen Hsu, 2005/05/19, ADD END */
return FatType;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -