📄 cpgpdiskformatter.cpp
字号:
bs16.bsJump[0] = 0xEB; // fill in jmp instruction to look real
bs16.bsJump[1] = 0x3C;
bs16.bsJump[2] = 0x90;
strncpy(bs16.bsOemName, kDefaultOEMName, sizeof(bs16.bsOemName));
bs16.bsBytesPerSec = kPGPdiskBlockSize; // bytes per sector
bs16.bsSecPerClust = static_cast<PGPUInt8>(fatData.fdSpc);
bs16.bsResSectors = fatData.fdReservedSecs; // reserved sectors
bs16.bsFats = fatData.fdFatCount; // number of FATs
bs16.bsRootDirEnts = fatData.fdRootDirEnts; // entries in root dir
bs16.bsSectors = (megsDisk < 32 ? blocksDisk : 0);
bs16.bsMedia = FileSys::kFatMediaByte; // a hard disk
bs16.bsFatSecs = static_cast<PGPUInt16>(fatData.fdFatSize);
bs16.bsSecPerTrack = static_cast<PGPUInt16>(secsPerTrack);
bs16.bsHeads = static_cast<PGPUInt16>(tracksPerCyl);
bs16.bsHiddenSecs = 0; // no hidden sectors
bs16.bsHugeSectors = (megsDisk >= 32 ? blocksDisk : 0);
bs16.bsDriveNumber = FileSys::kFatHardDriveId; // a hard drive
bs16.bsBootSignature = FileSys::kFatFirstBootSig;
bs16.bsVolumeId = static_cast<PGPUInt32>(UTime::GetSystemTicks());
bs16.bsSignature = FileSys::kFatSecondBootSig;
strncpy(bs16.bsVolumeLabel, kDefaultVolLabel,
sizeof(bs16.bsVolumeLabel));
memset(bs16.bsFileSysType, ' ', sizeof(bs16.bsFileSysType));
strncpy(bs16.bsFileSysType, FileSys::kFat16IdStr,
strlen(FileSys::kFat16IdStr));
}
void
CPGPdiskFormatter::InitBootSectorFat32(
PGPUInt32 blocksDisk,
const UFileSys::FatData& fatData,
FileSys::BootSectorFat32& bs32,
FileSys::BigFatBootFSInfo& bfInfo) const
{
pgpClearMemory(&bs32, sizeof(bs32));
pgpClearMemory(&bfInfo, sizeof(bfInfo));
PGPUInt32 megsDisk = static_cast<PGPUInt32>(
UFileSys::CalcMegsDisk(blocksDisk, kPGPdiskBlockSize));
PGPUInt64 bytesDisk = blocksDisk * kPGPdiskBlockSize;
PGPUInt32 secsPerTrack, tracksPerCyl;
PGPUInt64 cylinders;
UFileSys::CalcFakeFatGeom(kPGPdiskBlockSize, tracksPerCyl, cylinders,
secsPerTrack);
bs32.bsJump[0] = 0xEB; // fill in jmp instruction to look real
bs32.bsJump[1] = 0x3C;
bs32.bsJump[2] = 0x90;
strncpy(bs32.bsOemName, kDefaultOEMName, sizeof(bs32.bsOemName));
bs32.bsBytesPerSec = kPGPdiskBlockSize; // bytes per sector
bs32.bsSecPerClust = static_cast<PGPUInt8>(fatData.fdSpc);
bs32.bsResSectors = fatData.fdReservedSecs; // reserved sectors
bs32.bsFats = fatData.fdFatCount; // number of FATs
bs32.bsRootDirEnts = 0;
bs32.bsSectors = 0;
bs32.bsMedia = FileSys::kFatMediaByte; // a hard disk
bs32.bsFatSecs = 0;
bs32.bsSecPerTrack = static_cast<PGPUInt32>(secsPerTrack);
bs32.bsHeads = static_cast<PGPUInt32>(tracksPerCyl);
bs32.bsHiddenSecs = 0; // no hidden sectors
bs32.bsHugeSectors = blocksDisk;
bs32.bsBigSectorsPerFat = fatData.fdFatSize; // total secs per FAT
bs32.bsExtFlags = 0; // extended flags
bs32.bsFS_Version = 0; // filesystem version
bs32.bsRootDirStrtClus = FileSys::kTypicalRootDirStart;
bs32.bsFsInfoSec = FileSys::kTypicalBigFatStart;
bs32.bsBkUpBootSec = -1; // no backup boot sec
bs32.bsDriveNumber = FileSys::kFatHardDriveId; // a hard drive
bs32.bsBootSignature = FileSys::kFatFirstBootSig;
bs32.bsVolumeId = static_cast<PGPUInt32>(UTime::GetSystemTicks());
bs32.bsSignature = FileSys::kFatSecondBootSig;
strncpy(bs32.bsVolumeLabel, kDefaultVolLabel,
sizeof(bs32.bsVolumeLabel));
memset(bs32.bsFileSysType, ' ', sizeof(bs32.bsFileSysType));
strncpy(bs32.bsFileSysType, FileSys::kFat32IdStr,
strlen(FileSys::kFat32IdStr));
// Finally initialize the BigFatBootInfo structure.
bfInfo.bfSecSig = FileSys::kBigFatSecSig;
bfInfo.bfFSInf_Sig = FileSys::kBigFatSig;
bfInfo.bfFSInf_next_free_clus = FileSys::kTypicalRootDirStart;
bfInfo.bsSignature = FileSys::kFatSecondBootSig;
bfInfo.bfFSInf_free_clus_cnt = static_cast<PGPUInt32>(
bytesDisk / (fatData.fdSpc * kPGPdiskBlockSize) + 2);
}
void
CPGPdiskFormatter::FormatCustomFat(
CPGPdiskDisk& disk,
const char *root,
const char *volName,
FileSys::Type fsType,
NewDiskStatusFuncType userCallback,
void *userValue)
{
if (!UFileSys::IsFatFileSys(fsType))
THROW_PGPERROR(kPGPError_BadParams);
// Get number of blocks on disk.
PGPUInt64 bigBlocksDisk = disk.GetBlocksDisk();
if (UMath::GetHighDWord(bigBlocksDisk) != 0)
THROW_PGPERROR(kPGPError_BadParams);
PGPUInt32 blocksDisk = UMath::GetLowDWord(bigBlocksDisk);
PGPUInt32 megsDisk = static_cast<PGPUInt32>(
UFileSys::CalcMegsDisk(blocksDisk, kPGPdiskBlockSize));
if (!UFileSys::IsFileSysValidForSize(fsType, megsDisk))
THROW_PGPERROR(kPGPError_BadParams);
// Initialize some FAT data.
if (fsType == FileSys::kFat12Or16FileSys)
{
fsType = ((megsDisk < FileSys::kMinFat16Megs) ?
FileSys::kFat12FileSys : FileSys::kFat16FileSys);
}
UFileSys::FatData fatData;
UFileSys::InitFatData(blocksDisk, fsType, fatData);
// Lock the volume for format. Retry since volume may have just been
// mounted and may not be 'ready' yet.
PGPUInt32 retryCount = 0;
while (TRUE)
{
try
{
disk.LockVolume(TRUE);
break;
}
catch (CComboError& caughtErr)
{
Sleep(kLockRetryMsDelay);
if (retryCount++ > kMaxLockRetries)
{
// Give up.
throw caughtErr;
}
}
}
// Clear filesystem blocks.
ClearBlocks(disk, 0, fatData.fdFirstSecData, userCallback, userValue);
// Initialize and write out the FAT data structures.
CArray<PGPUInt8> blockBuf(kPGPdiskBlockSize);
blockBuf.Wipe();
PGPUInt32 *bufIn32 = reinterpret_cast<PGPUInt32 *>(blockBuf.Get());
if (fsType == FileSys::kFat12FileSys)
{
FileSys::BootSectorFat12 bs12;
InitBootSectorFat12(static_cast<PGPUInt32>(blocksDisk), fatData,
bs12);
// Write boot sector.
pgpCopyMemory(&bs12, blockBuf.Get(), sizeof(bs12));
disk.WriteVolume(blockBuf.Get(), 0, 1);
// Prepare fat ID sector.
blockBuf.Wipe();
bufIn32[0] = FileSys::kFat12Sig;
}
else if (fsType == FileSys::kFat16FileSys)
{
FileSys::BootSectorFat16 bs16;
InitBootSectorFat16(static_cast<PGPUInt32>(blocksDisk), fatData,
bs16);
// Write boot sector.
pgpCopyMemory(&bs16, blockBuf.Get(), sizeof(bs16));
disk.WriteVolume(blockBuf.Get(), 0, 1);
// Prepare fat ID sector.
blockBuf.Wipe();
bufIn32[0] = FileSys::kFat16Sig;
}
else if (fsType == FileSys::kFat32FileSys)
{
FileSys::BigFatBootFSInfo bfInfo;
FileSys::BootSectorFat32 bs32;
InitBootSectorFat32(static_cast<PGPUInt32>(blocksDisk), fatData,
bs32, bfInfo);
// Write boot sector.
pgpCopyMemory(&bs32, blockBuf.Get(), sizeof(bs32));
disk.WriteVolume(blockBuf.Get(), 0, 1);
// Write big fat boot sector info.
blockBuf.Wipe();
pgpCopyMemory(&bfInfo, blockBuf.Get(), sizeof(bfInfo));
disk.WriteVolume(blockBuf.Get(), bs32.bsFsInfoSec, 1);
// Prepare fat ID sector.
blockBuf.Wipe();
bufIn32[0] = FileSys::kFat32Clust1;
bufIn32[1] = FileSys::kFat32Clust2;
bufIn32[2] = FileSys::kFat32Clust3;
}
// Write FAT ids we just prepared;
PGPUInt64 fatSec = fatData.fdReservedSecs;
for (PGPUInt32 i = 0; i < fatData.fdFatCount; i++)
{
disk.WriteVolume(blockBuf.Get(), fatSec, 1);
fatSec += fatData.fdFatSize;
}
// Unlock the volume.
disk.UnlockVolume();
}
BOOLEAN
_stdcall
CPGPdiskFormatter::FormatExCallback(
UDynLink::FormatExCallbackCommand command,
DWORD subAction,
PVOID actionInfo)
{
PGPUInt32 percent;
switch (command)
{
case UDynLink::kFMIFS_ProgressCmd:
percent = static_cast<PGPUInt32>(
*static_cast<PGPUInt32 *>(actionInfo) * 0.90);
if (!mUserCallback(TRUE, percent, mUserValue))
mError.pgpErr = kPGPError_UserAbort;
break;
case UDynLink::kFMIFS_Done:
if (!*reinterpret_cast<PGPBoolean *>(actionInfo))
mError.pgpErr = kPGPError_VolumeOpFailed; // NETABUG format error?
else
mUserCallback(TRUE, 100, mUserValue);
break;
case UDynLink::kFMIFS_InsufficientRights:
mError.pgpErr = kPGPError_VolumeOpFailed; // NETABUG format error?
break;
default:
break;
}
return mError.IsntError();
}
void
CPGPdiskFormatter::FormatWinNT(
CPGPdiskDisk& disk,
const char *root,
const char *volName,
FileSys::Type fsType,
NewDiskStatusFuncType userCallback,
void *userValue)
{
pgpAssert(UWinVersion::IsWinNT4Compatible());
// Get number of blocks on disk.
PGPUInt64 blocksDisk = disk.GetBlocksDisk();
PGPUInt64 megsDisk = UFileSys::CalcMegsDisk(
blocksDisk, kPGPdiskBlockSize);
if (!UFileSys::IsFileSysValidForSize(fsType, megsDisk))
THROW_PGPERROR(kPGPError_BadParams);
// get the appropriate root
CPath croot(root);
if (UWinVersion::IsWin2000Compatible())
{
croot.EndInSlash();
PGPBoolean succeeded =
UDynLink::Win2k_GetVolumeNameForVolumeMountPoint(croot,
croot.GetBuffer(kPGPdiskMaxPathLength), kPGPdiskMaxPathLength);
croot.ReleaseBuffer();
if (!succeeded)
THROW_PGPERROR(kPGPError_VolumeOpFailed);
croot.DontEndInSlash();
}
// convert to unicode
CArray<WCHAR> uniFSString, uniRoot, uniVolName;
UUnicode::AsciiToUni(GetFSStringForFormat(fsType), uniFSString);
UUnicode::AsciiToUni(croot, uniRoot);
UUnicode::AsciiToUni(volName, uniVolName);
// Format the drive.
mUserCallback = userCallback;
mUserValue = userValue;
mError = CComboError();
UDynLink::WinNT_FormatEx(uniRoot.Get(),
UDynLink::kFMIFS_HardDiskType, uniFSString.Get(),
uniVolName.Get(), FALSE, 0, FormatExCallback);
THROW_IF_ERROR(mError);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -