📄 dosformt.c
字号:
/******************************************************************************/
/* */
/* Copyright (C), 1995-2006, msystems Ltd. All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* 1. Redistributions of source code must retain the above copyright notice, */
/* this list of conditions and the following disclaimer. */
/* 2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the */
/* documentation and/or other materials provided with the distribution. */
/* 3. Neither the name of msystems nor the names of its contributors may be */
/* used to endorse or promote products derived from this software without */
/* specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */
/* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/******************************************************************************/
/*
* $Log: V:/PVCSDB/DiskOnChip/archives/Testing/TrueFFS 6.3/Drop 2.5/3/common/dosformt.c-arc $
*
* Rev 1.32 Sep 11 2006 13:45:18 yaniv.iarovici
* Legal header added
*
* Rev 1.31 Aug 24 2006 16:36:32 Polina.Marimont
* up to 4095.375 MG = 3.9993896484375 GB capacity support for FAT16 added
*
* Rev 1.30 Aug 09 2006 16:52:48 Polina.Marimont
* initial for DOC Driver 1.0
*/
/******************************/
/* Internal compilation flags */
/******************************/
#define FL_FDISK_COMPATIBILITY_MODE /* Partition size starts and is in full cylinders */
/* MSDN says that NT and up ignore CHS values anyway */
#include "dosformt.h"
#include "flstruct.h"
#include "blockdev.h"
#ifndef FL_MIGRATION_VERSION
#include "fsdefs.h"
#else /*FL_MIGRATION_VERSION*/
#include "bddefs.h"
#endif /*FL_MIGRATION_VERSION*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
extern TFFS_DLL_API void NAMING_CONVENTION flBuildGeometry(FLDword capacity, FLDword FAR2 *cylinders,
FLDword FAR2 *heads,FLDword FAR2 *sectors, FLBoolean oldFormat, FLWord wIrHandle);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#define flPartitionIsFAT12(formatParams) (formatParams->pType == FAT12_PARTIT)
/*Tables are optimized for best DiskOnChip performance, keeping */
/*a limitation of cluster size <= 4KB as default. */
/*Larger clusters are inefficient but improves performance. */
/*Also clusters bigger than 4KB causes WCTK to fail logo tests. */
static DiskParamsTable FAT12Params [] = {
{ 4080, 1}, /* disks up to 1.99 MB, .5k cluster */
{ 8160, 2}, /* disks up to 3.98 MB, 1k cluster */
{ 16320, 4}, /* disks up to 7.97 MB, 2k cluster */
{ 32640, 8}, /* disks up to 15.94 MB, 4k cluster */
{ 0xFFFFFFFF, 0} /* any disk greater than 15.94 MB, 0 value for SecPerClusVal trips an error */
};
static DiskParamsTable FAT16Params [] = {
{ 8400, 0}, /* disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error */
{ 16340, 2}, /* disks up to 8 MB, 1k cluster */
{ 32680, 4}, /* disks up to 16 MB, 2k cluster */
{ 262144, 8}, /* disks up to 128 MB, 4k cluster */
{ 524288, 8}, /* disks up to 256 MB, 4k cluster */
{ 1048576, 16}, /* disks up to 512 MB, 8k cluster */
/* The entries after this point are not used unless FAT16 is forced */
{ 2097152, 32}, /* disks up to 1 GB, 16k cluster */
{ 4194304, 64}, /* disks up to 2 GB, 32k cluster */
{ 8388608, 128}, /* disks up to 4 GB, 128k cluster*/
{ 0xFFFFFFFF, 0} /* any disk greater than 4GB, 0 value for SecPerClusVal trips an error */
};
static DiskParamsTable FAT32Params [] = {
{ 500000, 0}, /* disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error */
{ 532480, 8}, /* disks up to 260 MB, .5k cluster */
{ 16777216, 8}, /* disks up to 8 GB, 4k cluster */
{ 33554432, 16}, /* disks up to 16 GB, 8k cluster */
{ 67108864, 32}, /* disks up to 32 GB, 16k cluster */
{ 0xFFFFFFFF, 64} /* disks greater than 32GB, 32k cluster */
};
/*----------------------------------------------------------------------*/
#ifndef FL_NEW_MAPSECTOR
FLStatus findSectorTL(TL * pVol, SectorNo sectorNo, const void FAR0 ** retBuffer)
{
*retBuffer = pVol->mapSector(pVol->rec,sectorNo,NULL);
if(*retBuffer == NULL)
return flSectorNotFound;
if(*retBuffer == dataErrorToken)
return flDataError;
return flOK;
}
#else
#define findSectorTL(_tlVol, _sectorNo, _retBuffer) _tlVol->mapSector(_tlVol->rec, _sectorNo, _retBuffer)
#endif /* FL_NEW_MAPSECTOR */
/* NOTE: pure-TL version can not snoop cache; nor should it be needed for reading MBRs */
/*----------------------------------------------------------------------*/
FLStatus findLogicalPartition(TL * pVol, FLByte logPartition,
SectorNo * bootSectorNo, SectorNo * sectorsInVolume,
SectorNo * MBR, int * MBRslot)
{
SectorNo ptSector = 0, masterExtendedPtSector = 0;
SectorNo extendedPtSector = 0; /* Initialized for dumb compilers */
PartitionTable FAR0 *partitionTable;
Partition * ptEntry;
unsigned ptCount, extended_depth = 0, ptFound = 0;
FLBoolean extendedPtFound;
while (1)
{
checkStatus(findSectorTL(pVol, ptSector, (void * *)&partitionTable));
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
if (LE2(partitionTable->signature) != PARTITION_SIGNATURE)
#else
if (FL_GET_LE2(partitionTable, FL_PARTITION_TABLE_SIGNATURE_OFFSET) != PARTITION_SIGNATURE)
#endif
return flPartitionNotFound;
extendedPtFound = FALSE;
/* if we in real MBR - one thing, extended chain - another. But similar */
for(ptCount=0; ptCount < PARTITION_ENTRIES; ptCount++)
{
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
ptEntry = &partitionTable->ptEntry[ptCount];
switch (ptEntry->type)
{
#else
ptEntry = (Partition *) &FL_REF_1(partitionTable, FL_PARTITION_TABLE_PT_ENTRY_OFFSET + ptCount * sizeof(Partition));
switch (FL_REF_1(ptEntry, FL_PARTITION_TYPE_OFFSET))
{
#endif
case 0: /* empty slot - we do not count */
break; /* go check next partition */
case EX_PARTIT:
if (extendedPtFound) /* invalid! at most 1 EBR is allowed */
return flPartitionNotFound;
extendedPtFound = TRUE;
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
extendedPtSector = masterExtendedPtSector + UNAL4(ptEntry->startingSectorOfPartition);
#else
extendedPtSector = masterExtendedPtSector + FL_GET_UNAL4(ptEntry, FL_PARTITION_STARTING_SECTOR_OF_PARTITION_OFFSET);
#endif
break;
default:
if (ptFound++ == logPartition)
{
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
*bootSectorNo = UNAL4(ptEntry->startingSectorOfPartition) + ptSector;
*sectorsInVolume = UNAL4(ptEntry->sectorsInPartition);
#else
*bootSectorNo = FL_GET_UNAL4(ptEntry, FL_PARTITION_STARTING_SECTOR_OF_PARTITION_OFFSET) + ptSector;
*sectorsInVolume = FL_GET_UNAL4(ptEntry, FL_PARTITION_SECTORS_IN_PARTITION_OFFSET);
#endif
*MBR = ptSector;
*MBRslot = ptCount;
return flOK;
}
} /* switch */
} /* scan 4 partition entries */
if (extendedPtFound)
{ /* do extended after real ones */
ptSector = extendedPtSector;
if (!masterExtendedPtSector)
masterExtendedPtSector = extendedPtSector;
if (++extended_depth == FL_MAX_PARTITION_DEPTH) { /* do we need this limitation? */
DBG_PRINT_ERR(FLZONE_FORMAT,"ERROR - logical parition too deep in EXTENDED\r\n");
return flTooManyPartitions;
}
}
else
break; /* partition # not found, and no EBR - failure */
} /* while (TRUE) - either we run out of partitions, or we find the one we need */
return flPartitionNotFound;
}
#if defined(FL_LOGICAL_FORMAT_VOLUME) || defined(FS_FORMAT_VOLUME)
/************************************************************************/
/* c a l c F A T p a r a m e t e r s */
/* */
/* Calculate the FAT parameters of a logical partition and fill in the */
/* BPB structure of the partition boor sector. */
/* */
/* Parameters: */
/* pVol : Pointer identifying drive */
/* bootSectorNo : Sector number where boot sector written. */
/* totalSectorsInPartition : Logical partition size. */
/* bpb : Pointer to BPB structure that would */
/* recieve the function calculation results. */
/* formatParams : Pointet to user structure defining the */
/* format input params. */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/************************************************************************/
static FLStatus calcFATparameters (TL * pVol, SectorNo bootSectorNo, SectorNo totalSectorsInPartition,
BPB FAR2 *bpb, FATFormatParams FAR0 * formatParams)
{
/* totalSectorsInPartition include only the size of the logical partition with it's boot sector but */
/*without MBR or other partitions. */
FLWord rootDirectorySectors, sectorsPerFAT;
FLDword firstDataSector, sectorAlignment = 0;
FLDword noOfClusters = 0;
FLDword i;
FLDword clusterSize = formatParams->noOfSectorsPerCluster;
unsigned minNonDataSectors;
FLByte fatType;
fatType = formatParams->pType;
if ((clusterSize >= 128) || (clusterSize & (clusterSize - 1)))
{
DBG_PRINT_ERR(FLZONE_FORMAT,"ERROR - clusterSize too large or not power of 2\r\n");
return flBadParameter;
}
if (!pVol->cylinders || !pVol->heads || !pVol->sectorsPerTrack)
{
FLDword cylinders, heads, sectors;
SectorNo capacity = pVol->sectorsInVolume(pVol->rec); /* Volume size in sectors */
flBuildGeometry((FLDword)capacity, (FLDword FAR2 *)&cylinders,
(FLDword FAR2 *)&heads, (FLDword FAR2 *)§ors, FALSE,
(FLWord)FL_GET_DISK_HANDLE_FROM_S_P_LP(pVol->socketNo,pVol->partitionNo,0));
pVol->cylinders = (FLWord)cylinders;
pVol->heads = (FLWord)heads;
pVol->sectorsPerTrack = (FLWord)sectors;
}
/* first fill bpb with values we do not have to calculate */
#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
toLE2(bpb->noOfHeads, pVol->heads);
toLE2(bpb->sectorsPerTrack, pVol->sectorsPerTrack);
toLE4(bpb->noOfHiddenSectors, bootSectorNo);
toUNAL2(bpb->bytesPerSector,FL_SECTOR_SIZE);
bpb->noOfFATS = formatParams->noOfFATs;
bpb->mediaDescriptor = 0xf8; /* hard disk */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -