📄 pgpdisklowlevelutils.cpp
字号:
//////////////////////////////////////////////////////////////////////////////
// PGPdiskLowLevelUtils.cpp
//
// Low-level utility functions for working with PGPdisks.
//////////////////////////////////////////////////////////////////////////////
// $Id: PGPdiskLowLevelUtils.cpp,v 1.8 1999/03/31 23:51:09 nryan Exp $
// Copyright (C) 1998 by Network Associates, Inc.
// All rights reserved.
#if defined(PGPDISK_MFC)
#include "StdAfx.h"
#include <new.h>
#elif defined(PGPDISK_95DRIVER)
#include <vtoolscp.h>
#include "PlacementNew.h"
#include LOCKED_CODE_SEGMENT
#include LOCKED_DATA_SEGMENT
#elif defined(PGPDISK_NTDRIVER)
#define __w64
#include <vdw.h>
#else
#error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
#endif // PGPDISK_MFC
#include "Required.h"
#include "PGPdiskHighLevelUtils.h"
#include "PGPdiskLowLevelUtils.h"
#include "SecureMemory.h"
#include "UtilityFunctions.h"
#include "File.h"
/////////////////////////////////////
// Low-level header utility functions
/////////////////////////////////////
// MakeEmptyHeader creates a PGPdisk header of the specified size.
DualErr
MakeEmptyHeader(PGPUInt32 headerSize, PGPdiskFileHeaderInfo **hdr)
{
DualErr derr;
pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo *);
#if defined(PGPDISK_MFC)
try
{
(* hdr) = (PGPdiskFileHeaderInfo *) new PGPUInt8[headerSize];
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
#else // !PGPDISK_MFC
(* hdr) = (PGPdiskFileHeaderInfo *) new PGPUInt8[headerSize];
if (IsNull((* hdr)))
derr = DualErr(kPGDMinorError_OutOfMemory);
#endif // PGPDISK_MFC
return derr;
}
// CopyHeader copies a PGPdisk header.
DualErr
CopyHeader(PGPdiskFileHeaderInfo *inHdr, PGPdiskFileHeaderInfo **outHdr)
{
DualErr derr;
pgpAssertAddrValid(inHdr, PGPdiskFileHeaderInfo);
pgpAssertAddrValid(outHdr, PGPdiskFileHeaderInfo *);
derr = MakeEmptyHeader(inHdr->headerSize, outHdr);
if (derr.IsntError())
{
pgpCopyMemory(inHdr, (* outHdr), inHdr->headerSize);
}
return derr;
}
// FreeHeader frees a PGPdisk headder allocated with MakeEmptyHeader.
void
FreeHeader(PGPdiskFileHeaderInfo *hdr)
{
pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo);
delete[] (PGPUInt8 *) hdr;
}
// ReadPGPdiskFileHeaderAtOffset reads in the header at the given offset.
DualErr
ReadPGPdiskFileHeaderAtOffset(
File *diskFile,
PGPUInt64 pos,
PGPdiskFileHeaderInfo **hdr)
{
DualErr derr;
PGPBoolean allocedFileHeader = FALSE;
PGPdiskFileHeaderInfo hdrInfo;
pgpAssertAddrValid(diskFile, File);
pgpAssert(diskFile->Opened());
pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo *);
// Read in next header.
derr = diskFile->Read((PGPUInt8 *) &hdrInfo, pos,
sizeof(PGPdiskFileHeaderInfo));
if (derr.IsntError())
{
if (strncmp(hdrInfo.headerMagic, kPGPdiskHeaderMagic, 4) != 0)
derr = DualErr(kPGDMinorError_BadHeaderMagic);
}
// Allocate space for header.
if (derr.IsntError())
{
derr = MakeEmptyHeader(hdrInfo.headerSize, hdr);
allocedFileHeader = derr.IsntError();
}
// Read it in.
if (derr.IsntError())
{
derr = diskFile->Read((PGPUInt8 *) (* hdr), pos, hdrInfo.headerSize);
}
// Cleanup on error.
if (derr.IsError())
{
if (allocedFileHeader)
FreeHeader((* hdr));
}
return derr;
}
// WritePGPdiskFileHeaderAtOffset writes a header at the given offset.
DualErr
WritePGPdiskFileHeaderAtOffset(
File *diskFile,
PGPUInt64 pos,
PGPdiskFileHeaderInfo *hdr)
{
DualErr derr;
PGPUInt8 blanks[kDefaultBlockSize];
pgpClearMemory(blanks, kDefaultBlockSize);
pgpAssertAddrValid(diskFile, File);
pgpAssert(diskFile->Opened());
pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo);
// Update header CRC.
UpdatePGPdiskFileHeaderCRC(hdr);
// Write out the header.
derr = diskFile->Write((PGPUInt8 *) hdr, pos, hdr->headerSize);
// Clear space up to block boundary.
if (hdr->headerSize % kDefaultBlockSize > 0)
{
derr = diskFile->Write(blanks, pos + hdr->headerSize,
kDefaultBlockSize - hdr->headerSize%kDefaultBlockSize);
}
return derr;
}
// FreePGPdiskFileHeader frees a header allocated with
// ReadPGPdiskFileHeaderAtOffset.
void
FreePGPdiskFileHeader(PGPdiskFileHeaderInfo *hdr)
{
pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo);
FreeHeader(hdr);
}
// MakeHeaderItem simply allocates a new header item.
DualErr
MakeHeaderItem(PGPdiskFileHeaderItem **item)
{
DualErr derr;
pgpAssertAddrValid(item, PGPdiskFileHeaderItem *);
#if defined(PGPDISK_MFC)
try
{
(* item) = new PGPdiskFileHeaderItem;
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
#else // !PGPDISK_MFC
(* item) = new PGPdiskFileHeaderItem;
if (IsNull((* item)))
derr = DualErr(kPGDMinorError_OutOfMemory);
#endif // PGPDISK_MFC
return derr;
}
// FreeHeaderItem frees an item allocated with MakeHeaderItem.
void
FreeHeaderItem(PGPdiskFileHeaderItem *item)
{
pgpAssertAddrValid(item, PGPdiskFileHeaderItem *);
delete item;
}
// InsertPGPdiskHeaderInList inserts a header item in a header item list.
DualErr
InsertPGPdiskHeaderInList(
PGPdiskFileHeaderItem *curItem,
PGPdiskFileHeaderInfo *newHdr)
{
DualErr derr;
PGPdiskFileHeaderItem *newItem;
pgpAssertAddrValid(curItem, PGPdiskFileHeaderItem *);
pgpAssertAddrValid(newHdr, PGPdiskFileHeader *);
// Get a new item.
derr = MakeHeaderItem(&newItem);
// Adjust the list.
if (derr.IsntError())
{
newItem->prev = curItem;
newItem->next = curItem->next;
newItem->hdr = newHdr;
if (IsntNull(newItem->next))
newItem->next->prev = newItem;
curItem->next = newItem;
}
return derr;
}
// RemovePGPdiskHeaderFromList removes a header item in a header item list.
void
RemovePGPdiskHeaderFromList(PGPdiskFileHeaderItem **itemToRemove)
{
PGPdiskFileHeaderItem *prevItem, *nextItem;
pgpAssertAddrValid(itemToRemove, PGPdiskFileHeaderItem *);
prevItem = (* itemToRemove)->prev;
nextItem = (* itemToRemove)->next;
// Remove the item from the linked list.
if (IsntNull(prevItem))
prevItem->next = nextItem;
if (IsntNull(nextItem))
nextItem->prev = prevItem;
// Free the item.
FreeHeaderItem((* itemToRemove));
(* itemToRemove) = (IsntNull(prevItem) ? prevItem : nextItem);
}
// GetHeaderItemList constructs an item list of the headers in the PGPdisk.
DualErr
GetHeaderItemList(File *diskFile, PGPdiskFileHeaderItem **itemList)
{
DualErr derr;
PGPdiskFileHeaderInfo *hdr;
PGPdiskFileHeaderItem *curItem, *firstItem, *nextItem;
pgpAssertAddrValid(diskFile, File);
pgpAssert(diskFile->Opened());
pgpAssertAddrValid(itemList, PGPdiskFileHeaderItem *);
// Read in main header.
derr = ReadPGPdiskFileMainHeader(diskFile, (PGPdiskFileHeader **) &hdr);
// Set it as first item.
if (derr.IsntError())
{
derr = MakeHeaderItem(&firstItem);
}
if (derr.IsntError())
{
firstItem->next = firstItem->prev = NULL;
firstItem->hdr = hdr;
}
// Read in remaining headers.
if (derr.IsntError())
{
PGPBoolean headersLeft = TRUE;
curItem = firstItem;
do
{
PGPUInt64 pos;
// Get position of next header.
pos = curItem->hdr->nextHeaderOffset;
if (pos == 0)
{
// There is no next header.
headersLeft = FALSE;
}
else
{
PGPBoolean readHeader = FALSE;
// Read in next header.
derr = ReadPGPdiskFileHeaderAtOffset(diskFile, pos, &hdr);
readHeader = derr.IsntError();
// Insert it into the list.
if (derr.IsntError())
{
derr = InsertPGPdiskHeaderInList(curItem, hdr);
}
// Iterate to next item.
if (derr.IsntError())
{
curItem = curItem->next;
}
// Cleanup on error.
if (derr.IsError())
{
if (readHeader)
FreePGPdiskFileHeader(hdr);
}
}
}
while (derr.IsntError() && headersLeft);
if (derr.IsntError())
{
curItem->next = NULL;
(* itemList) = firstItem;
}
}
// Cleanup on error.
if (derr.IsError())
{
curItem = firstItem;
while (IsntNull(curItem))
{
nextItem = curItem->next;
FreePGPdiskFileHeader(curItem->hdr);
FreeHeaderItem(curItem);
curItem = nextItem;
}
}
return derr;
}
// FreeHeaderItemList frees a list created with GetHeaderItemList.
void
FreeHeaderItemList(PGPdiskFileHeaderItem *itemList)
{
PGPdiskFileHeaderItem *curItem, *nextItem;
curItem = itemList;
while (IsntNull(curItem))
{
pgpAssertAddrValid(curItem, PGPdiskFileHeaderItem);
pgpAssertAddrValid(curItem->hdr, PGPdiskFileHeaderInfo);
nextItem = curItem->next;
FreePGPdiskFileHeader(curItem->hdr);
FreeHeaderItem(curItem);
curItem = nextItem;
}
}
// UpdateHeaderItemList writes out a header list to a PGPdisk.
DualErr
UpdateHeaderItemList(File *diskFile, PGPdiskFileHeaderItem *itemList)
{
DualErr derr;
PGPdiskFileHeader *mainHdr;
PGPdiskFileHeaderItem *curItem, *nextItem;
PGPUInt32 blockAfterData, i;
PGPUInt64 length;
pgpAssertAddrValid(diskFile, File);
pgpAssert(diskFile->Opened());
pgpAssertAddrValid(itemList, PGPdiskFileHeaderItem *);
pgpAssertAddrValid(itemList->hdr, PGPdiskFileHeaderInfo);
mainHdr = (PGPdiskFileHeader *) itemList->hdr;
blockAfterData = mainHdr->numHeaderBlocks + mainHdr->numDataBlocks;
// Set file size to minimum.
derr = diskFile->SetLength((PGPUInt64)
blockAfterData * kDefaultBlockSize);
// Wipe reserved header blocks.
if (derr.IsntError())
{
PGPUInt8 blanks[kDefaultBlockSize];
pgpClearMemory(blanks, kDefaultBlockSize);
for (i = 0; i < mainHdr->numHeaderBlocks; i++)
{
derr = diskFile->Write(blanks, i*kDefaultBlockSize,
kDefaultBlockSize);
if (derr.IsError())
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -