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

📄 volume.cpp

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

// $Id: Volume.cpp,v 1.4 1999/03/31 23:51:08 nryan Exp $

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

#define	__w64
#include <vdw.h>

#include "Required.h"
#include "UtilityFunctions.h"

#include "CPGPdiskDriver.h"
#include "Globals.h"
#include "KernelModeUtils.h"
#include "PGPdiskRequestQueue.h"
#include "Volume.h"


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

// The Class Volume constructor.

Volume::Volume()
{
	mDevExtInfo = (PGPUInt32) this;

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

	mAttachedToLocalVol = FALSE;

	mDeviceObject = NULL;

	mVHDeviceObject	= NULL;
	mVHFileObject	= NULL;
	mVolumeHandle	= NULL;
}

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

Volume::~Volume()
{
	DualErr derr;

	if (Mounted())
	{
		if (AttachedToLocalVolume())
		{
			DetachLocalVolume();
		}
		else
		{
			derr = Unmount();
			pgpAssert(derr.IsntError());
		}
	}
}

// Mounted returns TRUE if the volume is mounted, FALSE if not.

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

// Unmounted returns TRUE if the volume is unmounted, FALSE if not.

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

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

PGPBoolean
Volume::HasOpenFiles()
{
	DualErr derr;

	pgpAssert(Mounted());

	// If lock fails, then the volume has open files.
	derr = LockVolumeForReadWrite();

	if (LockedForReadWrite())
		UnlockVolume();

	return derr.IsError();
}

// 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));
}

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

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

// GetDrive returns the drive number of the volume.

PGPUInt8 
Volume::GetDrive()
{
	pgpAssert(Mounted());

	return mDrive;
}

// GetBlockSize returns the block size of the volume.

PGPUInt16 
Volume::GetBlockSize()
{
	DualErr derr;

	pgpAssert(Mounted());

	derr = GetDriveGeometry();

	if (derr.IsntError())
		return (PGPUInt16) mGeometry.BytesPerSector;
	else
		return kDefaultBlockSize;
}

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

PGPUInt64 
Volume::GetTotalBlocks()
{
	DualErr derr;

	pgpAssert(Mounted());

	derr = GetDriveGeometry();

	if (derr.IsntError())
	{
		return (mGeometry.Cylinders.QuadPart * mGeometry.TracksPerCylinder * 
			mGeometry.SectorsPerTrack);
	}
	else
	{
		return 0;
	}
}

// GetDeviceObject returns the device object associated with the volume.

PDEVICE_OBJECT 
Volume::GetDeviceObject()
{
	pgpAssert(Mounted());

	return mDeviceObject;
}

// 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 (LockedForReadWrite() || LockedForFormat())
		UnlockVolume();

	mMountState	= kVol_Mounted;
	mLockState	= kLock_None;
	mDrive		= drive;

	mAttachedToLocalVol = TRUE;

	return derr;
}

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

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

	if (VolumeHandleOpened())
		CloseVolumeHandle();

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

	mAttachedToLocalVol = FALSE;
}

// Mount creates a device and links it to the specified drive letter.

DualErr 
Volume::Mount(LPCSTR deviceName, PGPUInt8 drive, PGPBoolean mountReadOnly)
{
	DualErr		derr;
	KUstring	uniDeviceName, drivePath;
	NTSTATUS	status;
	PGPBoolean	createdDevice, foundDrive;
	PGPUInt8	i;

	pgpAssertStrValid(deviceName);
	pgpAssert(Unmounted());
	pgpAssert(!AttachedToLocalVolume());

	createdDevice = foundDrive = FALSE;

	// If preferred drive letter is specified, is it available?
	if (IsLegalDriveNumber(drive))
	{
		derr = MakePathToDrive(drive, &drivePath);

		if (derr.IsntError())
		{
			foundDrive = !IsValidDeviceName(drivePath);
		}
	}

	// Find a drive letter we can use.
	if (derr.IsntError() && !foundDrive)
	{
		for (i = 2; i < kMaxDrives; i++)
		{
			derr = MakePathToDrive(i, &drivePath);

			if (derr.IsntError())
			{
				if (!IsValidDeviceName(drivePath))
				{
					foundDrive = TRUE;
					drive = i;
					break;
				}
			}
			
			if (derr.IsError())
				break;
		}
	}

	// Die if no free drive found.
	if (derr.IsntError())
	{
		if (!foundDrive)
			derr = DualErr(kPGDMinorError_NoDriveLettersFree);
	}

	// Prepare device name.
	if (derr.IsntError())
	{
		derr = AssignToUni(&uniDeviceName, deviceName);
	}

	// Prepend device prefix.
	if (derr.IsntError())
	{
		derr = PrependToUni(&uniDeviceName, kNTDevicePathPrefix);
	}

	// Append driver letter.
	if (derr.IsntError())
	{
		char driveLet[2];

		driveLet[0] = DriveNumToLet(drive);
		driveLet[1] = '\0';

		derr = AppendToUni(&uniDeviceName, driveLet);
	}

	// Create a new device object.
	if (derr.IsntError())
	{
		PGPUInt32 attribs = FILE_VIRTUAL_VOLUME;

		if (mountReadOnly)
			attribs |= FILE_READ_ONLY_DEVICE;

		status = IoCreateDevice(Interface->mPGPdiskDriver->DriverObject(), 
			0, uniDeviceName, FILE_DEVICE_DISK, attribs, FALSE, 
			&mDeviceObject);

		if (!NT_SUCCESS(status))
			derr = DualErr(kPGDMinorError_IoCreateDeviceFailed, status);

		createdDevice = derr.IsntError();
	}

	// Assign the link name.
	if (derr.IsntError())
	{
		derr = AssignToUni(&mLinkName, drivePath);
	}

	// Create the link.
	if (derr.IsntError())
	{
		mDeviceObject->Flags |= DO_DIRECT_IO;
		mDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

		mDeviceObject->DeviceExtension = (void *) mDevExtInfo;

		status = IoCreateSymbolicLink(mLinkName, uniDeviceName);

		if (!NT_SUCCESS(status))
			derr = DualErr(kPGDMinorError_IoCreateSymbolicLinkFailed, status);
	}

	// Initialize variables on success.
	if (derr.IsntError())
	{
		mMountState	= kVol_Mounted;
		mLockState	= kLock_None;
		mDrive		= drive;

		mAttachedToLocalVol = FALSE;
	}

	// Cleanup on error.
	if (derr.IsError())
	{
		if (createdDevice)
		{
			IoDeleteDevice(mDeviceObject);
			mDeviceObject = NULL;
		}
	}

	return derr;
}

// Unmount unmounts a mounted Volume.

DualErr 
Volume::Unmount(PGPBoolean isThisEmergency)
{
	DualErr		derr;
	NTSTATUS	status;

	pgpAssert(Mounted());
	pgpAssert(!AttachedToLocalVolume());

	if (LockedForReadWrite() || LockedForFormat())
		UnlockVolume();

	// Lock the volume.
	derr = LockVolumeForReadWrite();

	// Dismount the volume.
	if (derr.IsntError())
	{
		derr = SendUserFSCTLRequest(FSCTL_DISMOUNT_VOLUME);
	}

	if (isThisEmergency)
		derr = DualErr::NoError;

	// Delete the symbolic link.
	if (derr.IsntError())
	{
		status = IoDeleteSymbolicLink(mLinkName);

		if (!NT_SUCCESS(status))
			derr = DualErr(kPGDMinorError_IoDeleteSymbolicLinkFailed, status);

		if (isThisEmergency)
			derr = DualErr::NoError;
	}

	// Delete the device object and finish up.
	if (derr.IsntError())
	{
		if (!isThisEmergency || (isThisEmergency && LockedForReadWrite()))
			UnlockVolume();

		mDeviceObject->DeviceExtension = NULL;

		IoDeleteDevice(mDeviceObject);
		mDeviceObject = NULL;

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

	if (derr.IsError())

⌨️ 快捷键说明

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