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

📄 cpgpdiskdrvwinutils.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////
// CPGPdiskDrvWinutils.cpp
//
// Contains utility functions for making interrupt calls to Windows/DOS.
//////////////////////////////////////////////////////////////////////////////

// $Id: CPGPdiskDrvWinutils.cpp,v 1.9 1999/02/13 04:24:34 nryan Exp $

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

#include <vtoolscp.h>

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

#include "CPGPdiskDrv.h"
#include "CPGPdiskDrvWinutils.h"


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

// The following are file attribute flags returned by R0_GetFileAttributes.

const PGPUInt16 _A_NORMAL	= 0x0000;		// normal file
const PGPUInt16 _A_RDONLY	= 0x0001;		// read-only
const PGPUInt16 _A_HIDDEN	= 0x0002;		// hidden
const PGPUInt16 _A_SYSTEM	= 0x0004;		// system
const PGPUInt16 _A_ARCH		= 0x0020;		// special OS file (?)

// The following are from the DDK.

#define LOCKP_ALLOW_WRITES		0x01	// Bit 0 set - allow writes
#define LOCKP_FAIL_WRITES		0x00	// Bit 0 clear - fail writes
#define LOCKP_FAIL_MEM_MAPPING	0x02	// Bit 1 set - fail memory mappings
#define LOCKP_ALLOW_MEM_MAPPING	0x00	// Bit 1 clear - allow memory mappings
#define LOCKP_USER_MASK			0x03	// Mask for user lock flags
#define LOCKP_LOCK_FOR_FORMAT	0x04	// Level 0 lock for format


//////////////////////////////////////
// Functions for performing interrupts
//////////////////////////////////////

// DoWinInt simulates a DOS interrupt.

PGPBoolean 
CPGPdiskDrv::DoWinInt(PGPUInt8 interrupt, ALLREGS *pAllRegs)
{
	pgpAssertAddrValid(pAllRegs, ALLREGS);

	// Execute the interrupt.
	Exec_VxD_Int(interrupt, pAllRegs);

	return (pAllRegs->RFLAGS & 0x0001 ? FALSE : TRUE);
}


//////////////////////////
// Drive locking functions
//////////////////////////

// GetLockLevel returns the level of the lock on the given drive.

LockLevel 
CPGPdiskDrv::GetLockLevel(PGPUInt8 drive)
{
	PGPInt32	pLockType;
	PGPUInt32	pLockFlags, pLockOwner;

	pgpAssert(drive < kMaxDrives);

	IFSMgr_GetLockState(drive, (PGPUInt32 *) &pLockType, &pLockFlags, 
		&pLockOwner);

	switch (pLockType)
	{
	case -1:
		return kLock_None;
	case 0:
		return (pLockFlags & LOCKP_LOCK_FOR_FORMAT ? kLock_L0MR : kLock_L0);
	case 1:
		return kLock_L1;
	case 2:
		return kLock_L2;
	case 3:
		return kLock_L3;

	default:
		pgpAssert(FALSE);
		return kLock_None;
	}
}

// AcquireLogicalVolLock gets a lock of the specified level on the specified
// drive, increasing or decreasing the lock level as needed. It doesn't
// handle L0 locks.

DualErr 
CPGPdiskDrv::AcquireLogicalVolLock(
	PGPUInt8	drive, 
	LockLevel	lock, 
	PGPUInt8	permissions)
{
	ALLREGS		allRegs;
	DualErr		derr;
	LockLevel	curLock;

	pgpAssert(lock != kLock_L0);
	pgpAssert(IsLegalDriveNumber(drive));

	// Make sure we aren't trying to alter a level-0 lock.
	curLock = GetLockLevel(drive);

	if (curLock == kLock_L0)
		derr = DualErr(kPGDMinorError_LockVolumeFailed);

	DebugOut("PGPdisk: Want lock %d on drive %u curlock %d", lock, drive, 
		curLock);

	// Since there is a special call to acquire a L1 lock, we do this first
	// before anything else.

	if (derr.IsntError())
	{
		if ((curLock == kLock_None) && (lock != kLock_None))
		{
			curLock = kLock_L1;

			allRegs.REAX	= 0x440D;				// function 440D
			allRegs.REBX	= 0x0100 + drive + 1;	// first get L1 lock
			allRegs.RECX	= 0x084A;				// (Lock Volume)
			allRegs.REDX	= permissions;			// locking permissions
			allRegs.RFLAGS	= 0x0001;				// carry cleared if error

			mLockInProgress = TRUE;
			mDriveBeingLocked = drive;

			if (!DoWinInt(0x21, &allRegs))
				derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);

			mLockInProgress = FALSE;
		}
	}

	// Now we calculate how many lock levels we need to go up or down.
	if (derr.IsntError())
	{
		PGPUInt8	locksUp		= 0;
		PGPUInt8	locksDown	= 0;

		if (curLock != lock)
		{
			switch (curLock)
			{
			case kLock_L1:
				switch (lock)
				{
				case kLock_None:
					locksDown = 1;
					break;
				case kLock_L2:
					locksUp = 1;
					break;
				case kLock_L3:
					locksUp = 2;
					break;
				default:
					pgpAssert(FALSE);
					break;
				}
				break;

			case kLock_L2:
				switch (lock)
				{
				case kLock_None:
					locksDown = 2;
					break;
				case kLock_L1:
					locksDown = 1;
					break;
				case kLock_L3:
					locksUp = 1;
					break;
				default:
					pgpAssert(FALSE);
					break;
				}
				break;

			case kLock_L3:
				switch (lock)
				{
				case kLock_None:
					locksDown = 3;
					break;
				case kLock_L1:
					locksDown = 2;
					break;
				case kLock_L2:
					locksDown = 1;
					break;
				default:
					pgpAssert(FALSE);
					break;
				}
				break;

				default:
					pgpAssert(FALSE);
					break;
			}
		}

		// If we need to get locks, we do that here.
		while (derr.IsntError() && (locksUp != 0))
		{
			PGPUInt16 lockValue;

			locksUp--;

			if (curLock == kLock_L1)
			{
				curLock = kLock_L2;
				lockValue = 2;
			}
			else
			{
				curLock = kLock_L3;
				lockValue = 3;
			}

			allRegs.REAX	= 0x440D;				// function 440D
			allRegs.REBX	= (lockValue << 8) + drive + 1;	// get next lock
			allRegs.RECX	= 0x084A;				// (Lock Volume)
			allRegs.REDX	= 0;					// > L1s expect zero here
			allRegs.RFLAGS	= 0x0001;				// carry cleared if error

			mLockInProgress = TRUE;
			mDriveBeingLocked = drive;

			if (!DoWinInt(0x21, &allRegs))
				derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);

			mLockInProgress = FALSE;
		}

		// If we need to release locks, we do that here.
		while (derr.IsntError() && (locksDown !=0))
		{
			locksDown--;

			if (curLock == kLock_L3)
				curLock = kLock_L2;
			else if (curLock == kLock_L2)
				curLock = kLock_L1;
			else if (curLock == kLock_L1)
				curLock = kLock_None;

			allRegs.REAX	= 0x440D;		// function 440D
			allRegs.REBX	= drive + 1;	// decrement lock level
			allRegs.RECX	= 0x086A;		// code 6A (Unlock Volume)
			allRegs.RFLAGS	= 0x0001;		// carry flag cleared on err

			if (!DoWinInt(0x21, &allRegs))
			{
				derr = DualErr(kPGDMinorError_UnlockVolumeFailed, 
					allRegs.REAX);
			}
		}
	}

	DebugOut("PGPdisk: Lock on drive %u is now %d", drive, 
		GetLockLevel(drive));

	return derr;
}

// GetFormatLockOnDrive locks the specified drive for formatting.

DualErr 
CPGPdiskDrv::GetFormatLockOnDrive(PGPUInt8 drive)
{
	ALLREGS		allRegs;
	DualErr		derr;
	PGPUInt32	locksTaken	= 0;

	pgpAssert(IsLegalDriveNumber(drive));

	// Make sure we aren't already locked;
	if (GetLockLevel(drive) != kLock_None)
		derr = DualErr(kPGDMinorError_LockVolumeFailed);

	// First get a 'normal' level-0 lock.
	if (derr.IsntError())
	{
		allRegs.REAX	= 0x440D;				// function 440D
		allRegs.REBX	= 0x0000 + drive + 1;	// L0 lock
		allRegs.RECX	= 0x084A;				// (Lock Volume)
		allRegs.REDX	= 0;					// must be 0
		allRegs.RFLAGS	= 0x0001;				// carry set if error

		mLockInProgress = TRUE;
		mDriveBeingLocked = drive;

		if (!DoWinInt(0x21, &allRegs))
			derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);
		else
			locksTaken++;

		mLockInProgress = FALSE;
	}

	// Now get a 'more restrictive' level-0 lock.
	if (derr.IsntError())
	{
		allRegs.REAX	= 0x440D;				// function 440D
		allRegs.REBX	= 0x0000 + drive + 1;	// L0 lock
		allRegs.RECX	= 0x084A;				// (Lock Volume)
		allRegs.REDX	= 4;					// must be 4
		allRegs.RFLAGS	= 0x0001;				// carry set if error

		mLockInProgress = TRUE;
		mDriveBeingLocked = drive;

		if (!DoWinInt(0x21, &allRegs))
			derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);
		else
			locksTaken++;

		mLockInProgress = FALSE;
	}

	// Undo what we did on error.
	if (derr.IsError())
	{
		while (locksTaken-- > 0)
		{
			allRegs.REAX	= 0x440D;		// function 440D
			allRegs.REBX	= drive + 1;	// decrement lock level
			allRegs.RECX	= 0x086A;		// code 6A (Unlock Volume)
			allRegs.RFLAGS	= 0x0001;		// carry flag set on error

			DoWinInt(0x21, &allRegs);
		}
	}

	return derr;
}

// ReleaseFormatLockOnDrive release a formatting lock on the specified drive.

DualErr 
CPGPdiskDrv::ReleaseFormatLockOnDrive(PGPUInt8 drive)
{
	ALLREGS		allRegs;
	DualErr		derr;
	PGPUInt32	locksTaken	= 2;

	pgpAssert(IsLegalDriveNumber(drive));

	// Make sure we are already locked;
	if (GetLockLevel(drive) != kLock_L0MR)
		derr = DualErr(kPGDMinorError_UnlockVolumeFailed);

	// Release locks.
	while (derr.IsntError() && (locksTaken-- > 0))
	{
		allRegs.REAX	= 0x440D;		// function 440D
		allRegs.REBX	= drive + 1;	// decrement lock level
		allRegs.RECX	= 0x086A;		// code 6A (Unlock Volume)
		allRegs.RFLAGS	= 0x0001;		// carry flag set on error

		if (!DoWinInt(0x21, &allRegs))
			derr = DualErr(kPGDMinorError_UnlockVolumeFailed, allRegs.REAX);
	}

	return derr;
}


/////////////////////////
// File utility functions
/////////////////////////

// IsFileInUseByReader returns TRUE if someone has opened the specified file
// with read access, FALSE otherwise.

PGPBoolean 
CPGPdiskDrv::IsFileInUseByReader(LPCSTR path)
{
	File	existingFile;
	DualErr	derr;

	pgpAssertStrValid(path);

	derr = existingFile.Open(path, 
		kOF_ReadOnly | kOF_DenyRead | kOF_MustExist);

	if (existingFile.Opened())
	{
		existingFile.Close();
	}

	return derr.IsError();
}

// IsFileInUseByWriter returns TRUE if someone has opened the specified file
// with write access, FALSE otherwise.

PGPBoolean 
CPGPdiskDrv::IsFileInUseByWriter(LPCSTR path)
{
	File	existingFile;
	DualErr	derr;

⌨️ 快捷键说明

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