📄 ufilesys.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: UFileSys.cpp,v 1.5 2002/08/06 20:10:18 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include "UMath.h"
#include "UFileSys.h"
_USING_PGP
// Functions
PGPBoolean
UFileSys::IsFatFileSys(FileSys::Type fsType)
{
switch (fsType)
{
case FileSys::kFat12FileSys:
case FileSys::kFat16FileSys:
case FileSys::kFat12Or16FileSys:
case FileSys::kFat32FileSys:
return TRUE;
default:
return FALSE;
}
}
PGPBoolean
UFileSys::IsFileSysValidForSize(
FileSys::Type fsType,
PGPUInt64 megsDisk)
{
switch (fsType)
{
case FileSys::kFat12FileSys:
return (megsDisk < FileSys::kMaxFat12Megs);
case FileSys::kFat16FileSys:
return ((megsDisk >= FileSys::kMinFat16Megs) &&
(megsDisk <= FileSys::kMaxFat16Megs));
case FileSys::kFat12Or16FileSys:
return (megsDisk < FileSys::kMaxFat16Megs);
case FileSys::kFat32FileSys:
return (megsDisk >= FileSys::kMinFat32Megs);
case FileSys::kNTFSFileSys:
return (megsDisk >= FileSys::kMinNTFSMegs);
default:
return FALSE;
}
}
PGPUInt64
UFileSys::CalcMegsDisk(PGPUInt64 blocksDisk, PGPUInt16 blockSize)
{
return (blocksDisk * blockSize) / PFLConstants::kBytesPerMb;
}
// CalcFat16Spc calculates the sectors per cluster required for a FAT16
// volume of the given size in blocks.
PGPUInt16
UFileSys::CalcFat16Spc(PGPUInt32 blocksDisk, PGPUInt16 blockSize)
{
PGPUInt32 megsData = static_cast<PGPUInt32>(
CalcMegsDisk(blocksDisk, blockSize));
if (megsData < 32)
return 1;
else if (megsData < 64)
return 2;
else if (megsData < 128)
return 4;
else if (megsData < 256)
return 8;
else if (megsData < 512)
return 16;
else if (megsData < 1024)
return 32;
else
return 64;
}
// CalcFat32Spc calculates the sectors per cluster required for a FAT32
// volume of the given size in blocks.
PGPUInt16
UFileSys::CalcFat32Spc(PGPUInt32 blocksDisk, PGPUInt16 blockSize)
{
PGPUInt32 megsData = static_cast<PGPUInt32>(
CalcMegsDisk(blocksDisk, blockSize));
// This function is not reliable for sizes above 8 gigabytes as Microsoft
// hasn't appeared to have told us yet what clusters sizes should be in
// volumes above 8 gigs.
if (megsData < 8192)
return 8;
else
return 32;
}
void
UFileSys::CalcFakeFatGeom(
PGPUInt32 blockSize,
PGPUInt32& tracksPerCyl,
PGPUInt64& cylinders,
PGPUInt32& secsPerTrack)
{
tracksPerCyl = FileSys::kMaxHeads - 1;
cylinders = FileSys::kMaxCyls - 1;
secsPerTrack = FileSys::kMaxSpt - 1;
}
// CalcFatSize will calculate the size of the FAT tables for a volume.
//
// On entry the fdBlockSize, fdFatCount, fdReservedSecs, and fdSPC members
// must be specified.
//
// On exit fdFatSize will have been filled in.
void
UFileSys::CalcFatSize(FatData& fatData, PGPUInt32 blocksDisk)
{
pgpAssert(fatData.fdBlockSize > 0);
pgpAssert(fatData.fdFatCount > 0);
pgpAssert(fatData.fdSpc > 0);
PGPUInt32 bitsPerBlock, bitsPerDiskClust, bitsPerTableClust, numClusts;
PGPUInt64 bitsAvail;
switch (fatData.fdFsType)
{
case FileSys::kFat12FileSys:
bitsPerTableClust = FileSys::kBitsFat12Clust;
break;
case FileSys::kFat16FileSys:
bitsPerTableClust = FileSys::kBitsFat16Clust;
break;
case FileSys::kFat32FileSys:
bitsPerTableClust = FileSys::kBitsFat32Clust;
break;
default:
pgpAssert(FALSE);
break;
}
// Bits per block = bytes per block * bits per byte.
bitsPerBlock = fatData.fdBlockSize * PFLConstants::kBitsPerByte;
// Bits available = (# of blocks on disk - # of reserved sectors) *
// bits per block.
bitsAvail = blocksDisk - fatData.fdReservedSecs;
bitsAvail *= bitsPerBlock;
// Bits per cluster on disk = # of spc * bits per block.
bitsPerDiskClust = fatData.fdSpc * bitsPerBlock;
// # of clusters = available bits / (bits per cluster on disk +
// (# fats * bits per fat table cluster)).
numClusts = static_cast<PGPUInt32>(bitsAvail /
(bitsPerDiskClust + (fatData.fdFatCount * bitsPerTableClust)));
// Blocks per FAT = ceiling of (# of clusters * bits per cluster) divided
// by (bits per block);
fatData.fdFatSize = UMath::CeilDiv<PGPUInt32>(
(numClusts * bitsPerTableClust), bitsPerBlock);
}
// CalcFatDataSec will calculate and return the index of the first sector on
// disk of the data area of a FAT drive.
//
// On entry the fdBlockSize, fdFatCount, fdReservedSecs, fdSPC,
// fdRootDirEnts (if non-FAT32), and fdFatSize members must be specified.
//
// On exit fdFirstSecData will have been filled in.
void
UFileSys::CalcFatDataSec(FatData& fatData)
{
pgpAssert(fatData.fdBlockSize > 0);
pgpAssert(fatData.fdFatCount > 0);
pgpAssert(fatData.fdSpc > 0);
pgpAssert(fatData.fdFatSize > 0);
PGPUInt32 bytesDirEnt, secsRootDir;
switch (fatData.fdFsType)
{
case FileSys::kFat12FileSys:
case FileSys::kFat16FileSys:
// Size of the root directory = ceiling of (# of root directory
// entries * the size of each entry) divided by (# bytes per sector).
bytesDirEnt = (fatData.fdFsType == FileSys::kFat12FileSys ?
FileSys::kBytesFat12DirEnt : FileSys::kBytesFat16DirEnt);
// First sector of data area = (# of reserved sectors) plus (# of FAT
// tables times size of each table in sectors) plus (sectors in the
// root directory).
secsRootDir = UMath::CeilDiv<PGPUInt32>(
(fatData.fdRootDirEnts * bytesDirEnt),
fatData.fdBlockSize);
fatData.fdFirstSecData = fatData.fdReservedSecs +
(fatData.fdFatCount * fatData.fdFatSize) + secsRootDir;
break;
case FileSys::kFat32FileSys:
// First sector of data area = (# of reserved sectors) plus (# of FAT
// tables times size of each table in sectors).
fatData.fdFirstSecData = fatData.fdReservedSecs +
(fatData.fdFatCount*fatData.fdFatSize);
break;
default:
pgpAssert(FALSE);
break;
}
}
// InitFatData will initialize a FatData structure with default values.
void
UFileSys::InitFatData(
PGPUInt32 blocksDisk,
FileSys::Type fsType,
FatData& fatData)
{
pgpClearMemory(&fatData, sizeof(fatData));
fatData.fdFsType = fsType;
switch (fsType)
{
case FileSys::kFat12FileSys:
fatData.fdBlockSize = FileSys::kTypicalBlockSize;
fatData.fdActiveFat = 0;
fatData.fdFatCount = FileSys::kTypicalFatCount;
fatData.fdReservedSecs = FileSys::kTypicalFat12Reserved;
fatData.fdRootDirEnts = FileSys::kTypicalRootDirEnts;
fatData.fdSpc = 1;
break;
case FileSys::kFat16FileSys:
fatData.fdBlockSize = FileSys::kTypicalBlockSize;
fatData.fdActiveFat = 0;
fatData.fdFatCount = FileSys::kTypicalFatCount;
fatData.fdReservedSecs = FileSys::kTypicalFat16Reserved;
fatData.fdRootDirEnts = FileSys::kTypicalRootDirEnts;
fatData.fdSpc = CalcFat16Spc(blocksDisk,
fatData.fdBlockSize);
break;
case FileSys::kFat32FileSys:
fatData.fdBlockSize = FileSys::kTypicalBlockSize;
fatData.fdActiveFat = FileSys::kTypicalActiveFat;
fatData.fdFatCount = FileSys::kTypicalFatCount;
fatData.fdReservedSecs = FileSys::kTypicalFat32Reserved;
fatData.fdRootDirEnts = 0;
fatData.fdSpc = CalcFat32Spc(blocksDisk,
fatData.fdBlockSize);
break;
default:
pgpAssert(FALSE);
break;
}
CalcFatSize(fatData, blocksDisk);
CalcFatDataSec(fatData);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -