📄 dosformt.c
字号:
return flOK;
}
/************************************************************************/
/* f l F A T F o r m a t */
/* */
/* Format a logical partition with FAT. */
/* */
/* Parameters: */
/* pVol : Pointer identifying drive */
/* formatParams : Pointer to structure with user input param*/
/* bootSectorNo : Sector 0 of the partition where the boot */
/* sector is written. */
/* sectorsInVolume : Number of sectors in logical partition. */
/* MBRsector : Sector where the MBR/EBR which defined */
/* the logical partition is written. */
/* MBRslot : Logical partition entry in the MBR/EBR */
/* partition table */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/************************************************************************/
static FLStatus flFATFormat(TL * pVol, FATFormatParams FAR0 * formatParams,
SectorNo bootSectorNo, SectorNo sectorsInVolume,
SectorNo MBRsector, int MBRslot)
{
FLSDword tmp;
FLByte orgNoOfFATS;
#ifdef NORMAL_COMPILER_NO_ALIGNMENT_BUG
BPB bpb;
#else
FLDword bpbBuffer[sizeof(BPB)>>2];
BPB * bpb = (BPB *)bpbBuffer;
#endif /* NORMAL_COMPILER_NO_ALIGNMENT_BUG */
tffsset (bpb, 0, sizeof(bpb));
if (formatParams->pType == 0)
formatParams->pType = FAT16_PARTIT;
if (sectorsInVolume < FAT16Params[0].size)
formatParams->pType = FAT12_PARTIT;
else if (formatParams->pType == FAT32_PARTIT && sectorsInVolume <= FAT32Params[0].size)
formatParams->pType = FAT16_PARTIT;
else if (formatParams->pType == FAT12_PARTIT && sectorsInVolume > FAT12Params[3].size)
formatParams->pType = FAT16_PARTIT;
orgNoOfFATS = formatParams->noOfFATs;
if (formatParams->flags & FL_TFAT_MODE)
{
formatParams->noOfFATs = 2;
}
checkStatus(calcFATparameters(pVol, bootSectorNo, sectorsInVolume, bpb, formatParams));
checkStatus(createDOSbootSector(pVol, bpb, formatParams->volumeId, formatParams->volumeLabel, formatParams->pType, formatParams->flags));
checkStatus(createFATs(pVol, bootSectorNo, formatParams->pType));
checkStatus(createRootDirectory(pVol, bootSectorNo, formatParams->volumeLabel, formatParams->pType));
tmp = FL_MAXIMUM_DEFRAGMENTATION;
pVol->defragment(pVol->rec, &tmp, 0);
formatParams->noOfFATs = orgNoOfFATS;
if (MBRslot != -1)
{
PartitionTable partitionTable;
Partition* ptEntry;
checkStatus(pVol->readSectors(pVol->rec, MBRsector, &partitionTable, 1));
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
ptEntry = &partitionTable.ptEntry[MBRslot];
if (ptEntry->type != formatParams->pType) {
ptEntry->type = formatParams->pType;
#else
ptEntry = (Partition *) &FL_REF_1(partitionTable, FL_PARTITION_TABLE_PT_ENTRY_OFFSET + MBRslot * sizeof(Partition));
if (FL_REF_1(ptEntry, FL_PARTITION_TYPE_OFFSET) != formatParams->pType)
{
FL_REF_1(ptEntry, FL_PARTITION_TYPE_OFFSET) = formatParams->pType;
#endif
return pVol->writeSector(pVol->rec, MBRsector, &partitionTable);
}
}
return flOK;
}
#endif /* FL_LOGICAL_FORMAT_VOLUME */
#if defined(FL_CREATE_LOGICAL) || defined (FS_CREATE_LOGICAL_PARTITIONS)
/************************************************************************/
/* r e c o r d C H S */
/* */
/* Auxilary routine that gets an absolute sector number, convert it */
/* into C, H, S format and record it in the partition entry as the */
/* start / end sector of a partition. */
/* */
/* Parameters: */
/* ptEntry : Pointer for partition entry record to be */
/* updated. */
/* fullCylinderSize : Specify how many sectors in a cylindar, */
/* for all heads. */
/* sectorsPerTrack : Specify how many sectors in a single head */
/* cylindar. */
/* sectorNumber : Sector number to be converted. */
/* startParams : Boolean specifying it the calculation and */
/* record update is done for the start sector */
/* (true) or end sector (false) of a */
/* partition. */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/************************************************************************/
static void recordCHS(Partition* ptEntry, unsigned fullCylinderSize, unsigned sectorsPerTrack,
FLDword sectorNumber, FLBoolean startParams) {
unsigned cylinder = sectorNumber / fullCylinderSize;
unsigned sector = (sectorNumber % fullCylinderSize);
unsigned head = sector / sectorsPerTrack;
sector = sector - (head * sectorsPerTrack) + 1;
/* printf("CHS %u - %u - %u\n", cylinder, head, sector); */
if (startParams)
{
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
toLE2(ptEntry->startingCylinderSector, CYLINDER_SECTOR(cylinder, sector));
ptEntry->startingHead = head;
#else
FL_SET_LE2(ptEntry, FL_PARTITION_STARTING_CYLINDER_SECTOR_OFFSET, CYLINDER_SECTOR(cylinder, sector));
FL_REF_1(ptEntry, FL_PARTITION_STARTING_HEAD_OFFSET) = head;
#endif
}
else
{
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
toLE2(ptEntry->endingCylinderSector, (FLWord)CYLINDER_SECTOR(cylinder, sector));
ptEntry->endingHead = head;
#else
FL_SET_LE2(ptEntry, FL_PARTITION_ENDING_CYLINDER_SECTOR_OFFSET, CYLINDER_SECTOR(cylinder, sector));
FL_REF_1(ptEntry, FL_PARTITION_ENDING_HEAD_OFFSET) = head;
#endif
}
}
/************************************************************************/
/* c r e a t e L o g i c a l P a r t i t i o n s */
/* */
/* Create MBR and/or EBR (Extended boot record) according to user */
/* params. This routin is the equivalent for FDISK creating the logical */
/* partition of the media. */
/* */
/* Parameters: */
/* pVol : Pointer identifying drive */
/* partitionParams : pointer to user array of struct defining */
/* the created partitions. size of the array */
/* depend on the partitionsNumber parameter. */
/* partitionsNumber : Number of logical partitions to create. */
/* */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/************************************************************************/
static FLStatus createLogicalPartitions(TL * pVol, LogicalPartitionParams FAR0 * partitionParams,
int partitionsNumber)
{
static const FLByte bootCode[] =
{
0xFA, 0x33, 0xC0, 0x8E, 0xD0, 0xBC, 0x00, 0x7C,
0x8B, 0xF4, 0x50, 0x07, 0x50, 0x1F, 0xFB, 0xFC,
0xBF, 0x00, 0x06, 0xB9, 0x00, 0x01, 0xF2, 0xA5,
0xEA, 0x1D, 0x06, 0x00, 0x00, 0xBE, 0xBE, 0x07,
0xB3, 0x04, 0x80, 0x3C, 0x80, 0x74, 0x0E, 0x80,
0x3C, 0x00, 0x75, 0x1C, 0x83, 0xC6, 0x10, 0xFE,
0xCB, 0x75, 0xEF, 0xCD, 0x18, 0x8B, 0x14, 0x8B,
0x4C, 0x02, 0x8B, 0xEE, 0x83, 0xC6, 0x10, 0xFE,
0xCB, 0x74, 0x1A, 0x80, 0x3C, 0x00, 0x74, 0xF4,
0xBE, 0x8B, 0x06, 0xAC, 0x3C, 0x00, 0x74, 0x0B,
0x56, 0xBB, 0x07, 0x00, 0xB4, 0x0E, 0xCD, 0x10,
0x5E, 0xEB, 0xF0, 0xEB, 0xFE, 0xBF, 0x05, 0x00,
0xBB, 0x00, 0x7C, 0xB8, 0x01, 0x02, 0x57, 0xCD,
0x13, 0x5F, 0x73, 0x0C, 0x33, 0xC0, 0xCD, 0x13,
0x4F, 0x75, 0xED, 0xBE, 0xA3, 0x06, 0xEB, 0xD3,
0xBE, 0xC2, 0x06, 0xBF, 0xFE, 0x7D, 0x81, 0x3D,
0x55, 0xAA, 0x75, 0xC7, 0x8B, 0xF5, 0xEA, 0x00,
0x7C, 0x00, 0x00, 0x49, 0x6E, 0x76, 0x61, 0x6C,
0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69,
0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x61, 0x62,
0x6C, 0x65, 0x00, 0x45, 0x72, 0x72, 0x6F, 0x72,
0x20, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67,
0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
0x6D, 0x00, 0x4D, 0x69, 0x73, 0x73, 0x69, 0x6E,
0x67, 0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6D
};
SectorNo mainEBR = 0;
SectorNo currentMEBR = 0;
int currentMBRslot = 0;
FLBoolean bootableMarked = FALSE;
FLByte realNumberOfPrimaryPartitions = 0;
int idx;
SectorNo freeSpaceStartSector = 1;
SectorNo totalSectorsInVolume = pVol->sectorsInVolume(pVol->rec);
SectorNo freeSpaceSectorsNumber;
unsigned fullCylinderSize;
PartitionTable partitionTable;
Partition* ptEntry;
tffsset(&partitionTable, 0, sizeof partitionTable);
tffscpy(&partitionTable, bootCode, sizeof bootCode);
/*Make sure Cylinder heads and sectors are calculated.*/
if (!pVol->cylinders || !pVol->heads || !pVol->sectorsPerTrack)
{
FLDword cylinders, heads, sectors;
flBuildGeometry((FLDword)totalSectorsInVolume, (FLDword FAR2 *)&cylinders,
(FLDword FAR2 *)&heads, (FLDword FAR2 *)§ors, FALSE,
(FLWord)FL_GET_DISK_HANDLE_FROM_S_P_LP(pVol->socketNo,pVol->partitionNo,0));
/*Adjust the number of sectors to match CHS calculation*/
pVol->cylinders = (FLWord)cylinders;
pVol->heads = (FLWord)heads;
pVol->sectorsPerTrack = (FLWord)sectors;
}
totalSectorsInVolume = pVol->cylinders * pVol->heads * pVol->sectorsPerTrack;
freeSpaceSectorsNumber = totalSectorsInVolume - 1;
fullCylinderSize = pVol->heads * pVol->sectorsPerTrack;
if ((pVol->cylinders == 0) || (pVol->heads == 0) || (pVol->sectorsPerTrack==0))
{
DBG_PRINT_ERR(FLZONE_FORMAT,"ERROR - Can't create MBR on empty media.\r\n");
return flNoSpaceInVolume;
}
/*Make sure partition number is legal*/
for (idx = 0; ((idx < PARTITION_ENTRIES) && (idx < partitionsNumber)); idx++)
{
if (partitionParams[idx].pType == EX_PARTIT)
break;
realNumberOfPrimaryPartitions++;
}
if (partitionsNumber > (FL_MAX_PARTITION_DEPTH + realNumberOfPrimaryPartitions))
{
DBG_PRINT_ERR(FLZONE_FORMAT,"ERROR - total number of logical paritions too high\r\n");
return flTooManyPartitions;
}
#ifdef FL_FDISK_COMPATIBILITY_MODE
#define shiftToActualPartition pVol->sectorsPerTrack
#else
#define shiftToActualPartition 1
#endif
while (partitionsNumber--)
{
FLDword partitionStart;
FLDword partitionSize;
/* determines the start and size in compatibility mode (all rounded to cylinders) or normal mode (to sectors) */
#ifdef FL_FDISK_COMPATIBILITY_MODE
/* in this mode, partition can start only on TRACK boundary, and end on CYLINDER boundary */
if (freeSpaceStartSector % pVol->sectorsPerTrack)
{
unsigned bumpValue = pVol->sectorsPerTrack - (freeSpaceStartSector % pVol->sectorsPerTrack);
if (bumpValue > freeSpaceSectorsNumber)
{
DBG_PRINT_ERR(FLZONE_FORMAT,"ERROR - logical parition too large\r\n");
return flBadPartitionSize;
}
freeSpaceStartSector += bumpValue;
freeSpaceSectorsNumber -= bumpValue;
}
/* now freeSpaceStartSector starts on track boundary */
#endif /* FL_FDISK_COMPATIBILITY_MODE */
/* Make sure not to use last sectors of the partition */
freeSpaceSectorsNumber -= freeSpaceSectorsNumber % fullCylinderSize;
partitionSize = partitionParams->length; /* default is in sectors */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -