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

📄 cpgpdiskdrvwinutils.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	pgpAssertStrValid(path);

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

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

	return derr.IsError();
}

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

PGPBoolean 
CPGPdiskDrv::IsFileInUse(LPCSTR path)
{
	pgpAssertStrValid(path);

	return (IsFileInUseByReader(path) || IsFileInUseByWriter(path));
}

// IsFileValid returns TRUE if the specified file exists.

PGPBoolean 
CPGPdiskDrv::IsFileValid(LPCSTR path)
{
	WORD attribs, error;

	pgpAssertStrValid(path);

	if (R0_GetFileAttributes((LPSTR) path, &attribs, &error))
		return TRUE;
	else
		return FALSE;
}

// GetFirstClustFile performs an IOCTL call to ask the system for the index
// of the first cluster corresponding to the given file on the given FAT
// drive.

DualErr 
CPGPdiskDrv::GetFirstClustFile(LPCSTR path, PGPUInt32 *firstClust)
{
	ALLREGS		allRegs;
	DualErr		derr;
	LockLevel	oldLock;
	PGPBoolean	lockedDown	= FALSE;
	PGPUInt8	drive;

	pgpAssertStrValid(path);
	pgpAssertAddrValid(firstClust, PGPBoolean);

	drive = DriveLetToNum(path[0]);
	oldLock = GetLockLevel(drive);

	allRegs.REAX	= 0x440D;			// function 440D
	allRegs.REBX	= BCS_WANSI;		// character set of path
	allRegs.RECX	= 0x0871;			// minor code 71 (Get First Cluster)
	allRegs.REDX	= (PGPUInt32) path;	// file path
	allRegs.RFLAGS	= 0x0001;			// carry flag cleared on error
	
	derr = AcquireLogicalVolLock(drive, kLock_L3);

	if (derr.IsntError())
	{
		lockedDown = TRUE;

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

	if (lockedDown)
		AcquireLogicalVolLock(drive, oldLock);

	if (derr.IsntError())
	{
		(* firstClust) = MakeLong((PGPUInt16) allRegs.REAX, (PGPUInt16) 
			allRegs.REDX);
	}
	
	return derr;
}

// HasOpenFiles returns TRUE if the specified drive has open file handles,
// FALSE otherwise.

DualErr 
CPGPdiskDrv::HasOpenFiles(PGPUInt8 drive, PGPBoolean *hasOpenFiles)
{
	ALLREGS		allRegs;
	static char	path[kMaxStringSize];
	DualErr		derr;
	LockLevel	oldLock;

	pgpAssertAddrValid(hasOpenFiles, PGPBoolean);
	pgpAssert(IsLegalDriveNumber(drive));

	oldLock = GetLockLevel(drive);

	if (AcquireLogicalVolLock(drive, kLock_L3).IsError())
	{
		(* hasOpenFiles) = TRUE;
	}
	else
	{
		allRegs.REAX	= 0x440D;			// function 440D
		allRegs.REBX	= drive + 1;		// drive to enumerate on
		allRegs.RECX	= 0x086D;			// minor code 6D (Enum Open Files)
		allRegs.REDX	= (PGPUInt32) path;	// file path
		allRegs.RESI	= 0;				// index to 0 to get first file
		allRegs.REDI	= 0;				// enumerate all files (0)
		allRegs.RFLAGS	= 0x0001;			// carry flag cleared on error

		// It is OK for this function to return an error since this is its
		// documented behavior if there are no open files on the drive.

		DoWinInt(0x21, &allRegs);

		// Note that FALSE is returned if the carry flag is set, since this
		// means that there are no open files on the drive.

		(* hasOpenFiles) = ((allRegs.RFLAGS & 0x0001) ? FALSE : TRUE);

		AcquireLogicalVolLock(drive, oldLock);
	}
	
	return derr;
}


//////////////////////////////
// Int21 file access functions
//////////////////////////////

// Int21OpenFile opens a file using the Int21 interface.

DualErr 
CPGPdiskDrv::Int21OpenFile(
	LPCSTR		path, 
	PGPUInt16	mode, 
	PGPUInt16	attribs, 
	PGPUInt16	action, 
	PGPUInt16	*pHandle)
{
	ALLREGS	allRegs;
	DualErr	derr;

	pgpAssertStrValid(path);
	pgpAssertAddrValid(pHandle, PGPUInt16);

	mode |= OPEN_FLAGS_NOCRITERR;

	allRegs.REAX	= 0x716C;			// function 716C
	allRegs.REBX	= mode;				// sharing and mode flags
	allRegs.RECX	= attribs;			// attribute flags
	allRegs.REDX	= action;			// action to take
	allRegs.RESI	= (PGPUInt32) path;	// file path
	allRegs.REDI	= 0;
	allRegs.RFLAGS	= 0x0001;			// carry flag cleared on error
	
	if (!DoWinInt(0x21, &allRegs))
		derr = DualErr(kPGDMinorError_R0OpenFailed, allRegs.REAX);

	if (derr.IsntError())
	{
		(* pHandle) = (PGPUInt16) allRegs.REAX;
	}
	
	return derr;
}

// Int21CloseFile closes a file using the Int21 interface.

DualErr 
CPGPdiskDrv::Int21CloseFile(PGPUInt16 handle)
{
	ALLREGS	allRegs;
	DualErr	derr;

	allRegs.REAX	= 0x3E00;		// function 3E
	allRegs.REBX	= handle;		// handle to close
	allRegs.RFLAGS	= 0x0001;		// carry flag cleared on error

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

// Int21GetFileLength gets the length of a file.

DualErr 
CPGPdiskDrv::Int21GetFileLength(PGPUInt16 handle, PGPUInt32 *pLength)
{
	ALLREGS		allRegs;
	DualErr		derr;

	allRegs.REAX	= 0x4202;		// function 42
	allRegs.REBX	= handle;		// file handle
	allRegs.RECX	= 0;
	allRegs.REDX	= 0;
	allRegs.RFLAGS	= 0x0001;		// carry flag cleared on error

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

	if (derr.IsntError())
	{
		(* pLength) = (allRegs.REDX << 16) | (allRegs.REAX & 0xFFFF);
	}

	return derr;
}

// Int21SetFilePos sets the position in a file.

DualErr 
CPGPdiskDrv::Int21SetFilePos(PGPUInt16 handle, PGPUInt32 pos)
{
	ALLREGS		allRegs;
	DualErr		derr;

	allRegs.REAX	= 0x4200;		// function 42
	allRegs.REBX	= handle;		// file handle
	allRegs.RECX	= pos >> 16;	// high word of pos
	allRegs.REDX	= pos & 0xFFFF;	// low word of pos
	allRegs.RFLAGS	= 0x0001;		// carry flag cleared on error

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

// Int21ReadFileAux is a helper function for Int21ReadFile.

DualErr 
CPGPdiskDrv::Int21ReadFileAux(
	PGPUInt16	handle, 
	PGPUInt8	*buf, 
	PGPUInt16	nBytes)
{
	ALLREGS	allRegs;
	DualErr	derr;

	pgpAssertAddrValid(buf, PGPUInt8);

	allRegs.REAX	= 0x3F00;			// function 3F
	allRegs.REBX	= handle;			// file handle
	allRegs.RECX	= nBytes;			// number of bytes to read
	allRegs.REDX	= (PGPUInt32) buf;	// buffer
	allRegs.RFLAGS	= 0x0001;			// carry flag cleared on error

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

	return derr;
}

// Int21WriteFileAux is a helper function for Int21WriteFile.

DualErr 
CPGPdiskDrv::Int21WriteFileAux(
	PGPUInt16	handle, 
	PGPUInt8	*buf, 
	PGPUInt16	nBytes)
{
	ALLREGS	allRegs;
	DualErr	derr;

	pgpAssertAddrValid(buf, PGPUInt8);

	allRegs.REAX	= 0x4000;			// function 40
	allRegs.REBX	= handle;			// file handle
	allRegs.RECX	= nBytes;			// number of bytes to write
	allRegs.REDX	= (PGPUInt32) buf;	// buffer
	allRegs.RFLAGS	= 0x0001;			// carry flag cleared on error

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

// Int21ReadFile reads from a file.

DualErr 
CPGPdiskDrv::Int21ReadFile(
	PGPUInt16	handle, 
	PGPUInt8	*buf, 
	PGPUInt32	pos, 
	PGPUInt32	nBytes)
{
	DualErr derr;

	pgpAssertAddrValid(buf, PGPUInt8);

	// Set the file position.
	derr = Int21SetFilePos(handle, pos);

	// We must read in chunks.
	if (derr.IsntError())
	{
		PGPUInt32 bufPos, bytesLeft;

		bufPos = 0;
		bytesLeft = nBytes;

		while (derr.IsntError() && (bytesLeft > 0))
		{
			PGPUInt16 bytesToRead;
			
			bytesToRead = (PGPUInt16) min(0x7000, nBytes - bufPos);
			derr = Int21ReadFileAux(handle, buf + bufPos, bytesToRead);

			if (derr.IsntError())
			{
				bufPos += bytesToRead;
				bytesLeft -= bytesToRead;
			}
		}
	}
	
	return derr;
}

// Int21WriteFile writes to a file.

DualErr 
CPGPdiskDrv::Int21WriteFile(
	PGPUInt16	handle, 
	PGPUInt8	*buf, 
	PGPUInt32	pos, 
	PGPUInt32	nBytes)
{
	DualErr derr;

	pgpAssertAddrValid(buf, PGPUInt8);

	// Set the file position.
	derr = Int21SetFilePos(handle, pos);

	// We must write in chunks.
	if (derr.IsntError())
	{
		PGPUInt32 bufPos, bytesLeft;

		bufPos = 0;
		bytesLeft = nBytes;

		while (derr.IsntError() && (bytesLeft > 0))
		{
			PGPUInt16 bytesToWrite;
			
			bytesToWrite = (PGPUInt16) min(0x7000, nBytes - bufPos);
			derr = Int21WriteFileAux(handle, buf + bufPos, bytesToWrite);

			if (derr.IsntError())
			{
				bufPos += bytesToWrite;
				bytesLeft -= bytesToWrite;
			}
		}
	}
	
	return derr;
}


///////////////////
// Memory functions
///////////////////

// LockUserBuffer locks memory passed in from Ring-3.

DualErr 
CPGPdiskDrv::LockUserBuffer(void *pMem, PGPUInt32 nBytes)
{
	DualErr		derr;
	PGPUInt32	numPages, page;

	pgpAssertAddrValid(pMem, VoidAlign);

	page = ((PGPUInt32) pMem) >> kWin32Power2PageSize;
	numPages = ((nBytes - 1) >> kWin32Power2PageSize) + 1;

	if (!::LinPageLock(page, numPages, NULL))
	{
		derr = DualErr(kPGDMinorError_LinPageLockFailed);
	}

	return derr;
}

// UnlockUserBuffer unlocks memory passed in from Ring-3.

DualErr 
CPGPdiskDrv::UnlockUserBuffer(void *pMem, PGPUInt32 nBytes)
{
	DualErr		derr;
	PGPUInt32	numPages, page;

	pgpAssertAddrValid(pMem, VoidAlign);

	page = ((PGPUInt32) pMem) >> kWin32Power2PageSize;
	numPages = ((nBytes - 1) >> kWin32Power2PageSize) + 1;

	if (!::LinPageUnLock(page, numPages, NULL))
	{
		derr = DualErr(kPGDMinorError_LinPageUnlockFailed);
	}

	return derr;
}

⌨️ 快捷键说明

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