⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 volume.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////
// Volume.cpp
//
// Implementation of class Volume.
//////////////////////////////////////////////////////////////////////////////

// $Id: Volume.cpp,v 1.5 1998/12/14 18:58:55 nryan Exp $

// Copyright (C) 1998 by Network Associates, Inc.
// All rights reserved.

#include "StdAfx.h"
#include <Dbt.h>
#include <Shlobj.h>

#include "Required.h"
#include "DriverComm.h"
#include "UtilityFunctions.h"
#include "WindowsVersion.h"

#include "Globals.h"
#include "Volume.h"


////////////
// Constants
////////////

const PGPUInt32	kSHNotifySleepDelayMs = 500;
const PGPUInt64	kMaxBlocksDiskWeFormat = 
	(2047*kBytesPerMeg)/kDefaultBlockSize;

static LPCSTR	kVWin32DriverString	= "\\\\.\\VWIN32";
static LPCSTR	kVolumeOpenString	= "\\\\.\\%c:";

const PGPUInt32	kMaxBlocksPerWrite = 2000;
const PGPUInt32	kMinBlocksPerWrite = 10;

const PGPUInt32	kIdealNumWritesPerData = 10;


///////////////////////////////////////
// Class Volume public member functions
///////////////////////////////////////

// The Class Volume constructor.

Volume::Volume(PGPUInt8 drive)
{
	if (drive != kInvalidDrive)
		mMountState = kVol_Mounted;
	else
		mMountState = kVol_Unmounted;

	mLockState = kLock_None;
	mDrive = drive;

	mAttachedToLocalVol	= FALSE;

	mBlockSize = 0;
}

// The Volume destructor unmounted the volume if was mounted by us.

Volume::~Volume()
{
	DualErr derr;

	if (Mounted())
	{
		if (AttachedToLocalVolume())
			DetachLocalVolume();
	}
}

// GetDrive returns the drive number the volume is mounted on.

PGPUInt8 
Volume::GetDrive()
{
	return mDrive;
}

// GetBlockSize returns the block size of the mounted volume.

PGPUInt16 
Volume::GetBlockSize()
{
	pgpAssert(Mounted());

	return mBlockSize;
}

// GetTotalBlocks returns the total number of blocks on the volume.

PGPUInt64 
Volume::GetTotalBlocks()
{
	pgpAssert(Mounted());

	return mTotalBlocks;
}

// Mounted returns TRUE if the Volume is mounted.

PGPBoolean 
Volume::Mounted()
{
	return (mMountState == kVol_Mounted);
}

// Unmounted returns TRUE if the Volume is unmounted.

PGPBoolean 
Volume::Unmounted()
{
	return (mMountState == kVol_Unmounted);
}

// AttachedToLocalVolume returns TRUE if the Volume object is attached to a
// local volume, FALSE if not.

PGPBoolean 
Volume::AttachedToLocalVolume()
{
	return mAttachedToLocalVol;
}

// HasOpenFiles returns TRUE if the volume has open files, FALSE otherwise.

PGPBoolean
Volume::HasOpenFiles()
{
	DualErr		derr;
	PGPBoolean	hasOpenFiles;

	pgpAssert(Mounted());

	derr = AreFilesOpenOnDrive(mDrive, &hasOpenFiles);

	if (derr.IsntError())
		return hasOpenFiles;
	else
		return TRUE;
}

// LockedForReadWrite returns TRUE if the volume is mounted and locked for
// read/write access, FALSE otherwise.

PGPBoolean 
Volume::LockedForReadWrite()
{
	return (Mounted() && (mLockState == kLock_ReadWrite));
}

// LockedForReadWrite returns TRUE if the volume is mounted and locked for
// format access, FALSE otherwise.

PGPBoolean 
Volume::LockedForFormat()
{
	return (Mounted() && (mLockState == kLock_Format));
}

// BrowseToVolume opens a view to the volume in an explorer window.

void 
Volume::BrowseToVolume()
{
	CString root;

	pgpAssert(Mounted());

	if (MakeRoot(mDrive, &root).IsntError())
	{
		ShellExecute(NULL, "explore", root, NULL, NULL, SW_SHOWNORMAL);
	}
}

// GetVolumeLabel retrieves the volume label associated with a mounted volume.

DualErr 
Volume::GetVolumeLabel(LPSTR label, PGPUInt32 size)
{
	DualErr	derr;
	CString root;

	pgpAssertAddrValid(label, LPSTR);
	pgpAssert(Mounted());

	derr = MakeRoot(mDrive, &root);

	if (derr.IsntError())
	{
		if (GetVolumeInformation(root, label, size, NULL, NULL, NULL, NULL, 
			0))
		{
			derr = DualErr(kPGDMinorError_GetVolumeInfoFailed, 
				GetLastError());
		}
	}

	return derr;
}

// SetVolumeLabel sets the 11-character label of the mounted volume.

DualErr 
Volume::SetVolumeLabel(LPCSTR label)
{
	DualErr	derr;
	CString	volName, root;

	pgpAssertStrValid(label);
	pgpAssert(Mounted());

	derr = CanonicalizeVolumeName(label, &volName);

	if (derr.IsntError())
	{
		derr = MakeRoot(mDrive, &root);
	}

	if (derr.IsntError())
	{
		if (!::SetVolumeLabel(root, volName))
		{
			derr = DualErr(kPGDMinorError_SetVolumeLabelFailed, 
				GetLastError());
		}
	}

	return derr;
}

// AttachLocalVolume initializes this Volume object for access to an already
// mounted volume on the local computer.

DualErr 
Volume::AttachLocalVolume(PGPUInt8 drive)
{
	DualErr derr;

	pgpAssert(IsLegalDriveNumber(drive));
	pgpAssert(!Mounted());
	pgpAssert(!AttachedToLocalVolume());

	if (!App->IsVolumeValid(drive))
		derr = DualErr(kPGDMinorError_InvalidParameter);

	if (derr.IsntError())
	{
		mMountState	= kVol_Mounted;
		mLockState	= kLock_None;
		mDrive		= drive;

		mAttachedToLocalVol = TRUE;

		if (FillInVolInfo().IsError())
		{
			mBlockSize = kDefaultBlockSize;
			mTotalBlocks = 0;
		}
	}

	return derr;
}

// DetachLocalVolume marks this Volume object as no longer being associated
// with a local volume.

void 
Volume::DetachLocalVolume()
{
	pgpAssert(Mounted());
	pgpAssert(AttachedToLocalVolume());

	mMountState	= kVol_Unmounted;
	mLockState	= kLock_None;
	mDrive		= kInvalidDrive;

	mAttachedToLocalVol = FALSE;
}

// LockVolumeForReadWrite locks the mounted volume for direct read/write
// access.

DualErr 
Volume::LockVolumeForReadWrite()
{
	DualErr derr;
	
	pgpAssert(Mounted());
	pgpAssert(!LockedForReadWrite() && !LockedForFormat());

	derr = LockUnlockVolume(mDrive, kLO_LockReadWrite);

	if (derr.IsntError())
	{
		mLockState = kLock_ReadWrite;
	}

	return derr;
}

// LockVolumeForFormat locks the mounted volume for formatting.

DualErr 
Volume::LockVolumeForFormat()
{
	DualErr derr;
	
	pgpAssert(Mounted());
	pgpAssert(!LockedForReadWrite() && !LockedForFormat());

	derr = LockUnlockVolume(mDrive, kLO_LockFormat);

	if (derr.IsntError())
	{
		mLockState = kLock_Format;
	}

	return derr;
}

// UnlockVolume removes any outstanding locks on the volume;

DualErr 
Volume::UnlockVolume()
{
	DualErr derr;

	pgpAssert(Mounted());
	pgpAssert(LockedForReadWrite() || LockedForFormat());

	derr = LockUnlockVolume(mDrive, (LockedForReadWrite() ? 
		kLO_UnlockReadWrite : kLO_UnlockFormat));

	if (derr.IsntError())
	{
		mLockState = kLock_None;
	}

	return derr;
}

// Read reads blocks from the locked mounted volume.

DualErr 
Volume::Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks)
{
	DualErr derr;

	pgpAssertAddrValid(buf, PGPUInt8);
	pgpAssert(Mounted());
	pgpAssert(LockedForReadWrite() || LockedForFormat());

	derr = DirectDiskRead(mDrive, buf, nBlocks * GetBlockSize(), pos, 
		nBlocks);

	return derr;
}

// Write writes blocks to the locked mounted volume.

DualErr 
Volume::Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks)
{
	DualErr derr;

	pgpAssertAddrValid(buf, PGPUInt8);
	pgpAssert(Mounted());
	pgpAssert(LockedForReadWrite() || LockedForFormat());

	derr = DirectDiskWrite(mDrive, buf, nBlocks * GetBlockSize(), pos, 
		nBlocks);

	return derr;
}

// Format formats the mounted volume using our own algorithms.

DualErr 
Volume::Format()
{
	DualErr		derr;
	FatData		fat;
	PGPBoolean	allocedBlockBuf, lockedForFormat;
	PGPUInt8	*blockBuf;
	PGPUInt64	megsDisk;

	pgpAssert(Mounted());
	pgpAssert(!LockedForReadWrite() || !LockedForFormat());

	allocedBlockBuf = lockedForFormat = FALSE;
	megsDisk = (GetTotalBlocks() * kDefaultBlockSize) / kBytesPerMeg;

	// Can only format drives with standard block sizes.
	if (GetBlockSize() != kDefaultBlockSize)
		derr = DualErr(kPGDMinorError_CantFormatDrive);

	// Too big for format?
	if (derr.IsntError())
	{
		if (GetBlockSize() > kMaxBlocksDiskWeFormat)
			derr = DualErr(kPGDMinorError_DiskTooBigToFormat);
	}

	// Get block buffer.
	if (derr.IsntError())
	{
		derr = GetByteBuffer(kDefaultBlockSize, &blockBuf);
		allocedBlockBuf = derr.IsntError();
	}

	// Lock the volume for format.
	if (derr.IsntError())
	{
		derr = LockVolumeForFormat();
		lockedForFormat = derr.IsntError();
	}

	if (derr.IsntError())
	{
		// Initialize FAT data.
		fat.fdFsId = kFS_FAT16;

		if (megsDisk < 2)
		{
			fat.fdFsId = kFS_FAT12;
		}
		else if ((megsDisk >= kMinFat32Megs) && 
			IsWin95OSR2CompatibleMachine())
		{
			fat.fdFsId = kFS_FAT32;
		}

		InitFatData(&fat, GetBlockSize());

		derr = ClearBlocks(0, fat.fdFirstSecData);
	}

	// Write out the FAT data structures.
	if (derr.IsntError())
	{
		BigFatBootFSInfo	bfInfo;
		BootSector12		bb12;
		BootSector16		bb16;
		BootSector32		bb32;
		PGPUInt32			fat16Sig;
		PGPUInt64			pos;

		pgpAssert(sizeof(bb12) == kDefaultBlockSize);
		pgpAssert(sizeof(bb16) == kDefaultBlockSize);
		pgpAssert(sizeof(bb32) == kDefaultBlockSize);

		pgpClearMemory(blockBuf, kDefaultBlockSize);

		pos = 0;

		switch (fat.fdFsId)
		{

		case kFS_FAT12:
			// Init the boot block.
			InitFAT12BootBlock(GetBlockSize(), &fat, &bb12);

			// Write the boot block.
			derr = Write((PGPUInt8 *) &bb12, pos, 1);

			// Write the first FAT.
			if (derr.IsntError())
			{
				pgpCopyMemory((PGPUInt8 *) &kFat12Sig, blockBuf, 
					sizeof(kFat12Sig));

				pos += fat.fdReservedSecs;
				derr = Write(blockBuf, pos, 1);
			}

			// Write the second FAT.
			if (derr.IsntError())
			{
				pos += fat.fdFatSize;
				derr = Write(blockBuf, pos, 1);
			}
			break;

		case kFS_FAT16:
			// Init the boot block.
			InitFAT16BootBlock(GetBlockSize(), &fat, &bb16);

			// Decide on a FAT signature.
			fat16Sig = (megsDisk < 16 ? kUnder16MbFat16Sig : 
				kOver16MbFat16Sig);

			// Write the boot block.
			derr = Write((PGPUInt8 *) &bb16, pos, 1);

			// Write the first FAT.
			if (derr.IsntError())
			{
				pgpCopyMemory((PGPUInt8 *) &fat16Sig, blockBuf, 
					sizeof(fat16Sig));

				pos += fat.fdReservedSecs;
				derr = Write(blockBuf, pos, 1);
			}

			// Write the second FAT.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -