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

📄 cfileimpdrv98.cpp

📁 可以实现对邮件的加密解密以及签名
💻 CPP
字号:
/*____________________________________________________________________________
		Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CFileImpDrv98.cpp,v 1.4 2002/11/21 18:42:55 wjb Exp $
____________________________________________________________________________*/

#include "pgpClassesConfig.h"
#include "CFileImpDrv98.h"

_USING_PGP

// Class CFileImpDrv98 member functions

CFileImpDrv98::~CFileImpDrv98()
{
	if (IsOpened())
		Close();
}

CComboError 
CFileImpDrv98::GetLength(PGPUInt64& length) const
{
	pgpAssert(IsOpened());

	if (mUseInt21)
		return GetLengthInt21(length);
	else
		return GetLengthRing0(length);
}

CComboError 
CFileImpDrv98::GetUniqueFileId(PGPUInt64& fileId) const
{
	pgpDebugMsg("PGPdisk: Unimplemented function.\n");
	return CComboError(CComboError::kPGPError, kPGPError_FeatureNotAvailable);
}

CComboError 
CFileImpDrv98::SetIsCompressed(PGPBoolean isCompressed)
{
	pgpDebugMsg("PGPdisk: Unimplemented function.\n");
	return CComboError(CComboError::kPGPError, kPGPError_FeatureNotAvailable);
}

CComboError 
CFileImpDrv98::SetLength(PGPUInt64 length)
{
	pgpDebugMsg("PGPdisk: Unimplemented function.\n");
	return CComboError(CComboError::kPGPError, kPGPError_FeatureNotAvailable);
}

void 
CFileImpDrv98::Flush()
{
	pgpDebugMsg("PGPdisk: Unimplemented function.\n");
}

CComboError 
CFileImpDrv98::Open(const char *path, PGPUInt32 flags)
{
	pgpAssert(!IsOpened());
	pgpAssertStrValid(path);

	CComboError error;
	error = mPath.Assign(path);

	if (error.IsntError())
	{
		error = OpenRing0(flags);

		// If the open fails, fall upon the int21 functions. (This will
		// happen for Novell volumes only.)

		if (error.IsError())
		{
			error = OpenInt21(flags);

			if (error.IsntError())
				mUseInt21 = TRUE;
		}
		else
		{
			mUseInt21 = FALSE;
		}

		if (error.IsntError())
		{
			mIsOpened = TRUE;
			mOpenFlags = flags;
		}
	}

	return error;
}

CComboError 
CFileImpDrv98::Close()
{
	pgpAssert(IsOpened());

	CComboError	error;

	if (mUseInt21)
		error = CloseInt21();
	else
		error = CloseRing0();

	if (error.IsntError())
	{
		mIsOpened = FALSE;
		mOpenFlags = CFile::kNoFlags;
	}

	return error;
}

CComboError 
CFileImpDrv98::Delete(const char *path)
{
	pgpDebugMsg("PGPdisk: Unimplemented function.\n");
	return CComboError(CComboError::kPGPError, kPGPError_FeatureNotAvailable);
}

CComboError 
CFileImpDrv98::Move(const char *oldPath, const char *newPath)
{
	pgpDebugMsg("PGPdisk: Unimplemented function.\n");
	return CComboError(CComboError::kPGPError, kPGPError_FeatureNotAvailable);
}

CComboError 
CFileImpDrv98::Read(void *buf, PGPUInt64 pos, PGPUInt32 nBytes) const
{
	pgpAssert(IsOpened());
	pgpAssertAddrValid(buf, VoidAlign);

	if (mUseInt21)
		return ReadInt21(buf, pos, nBytes);
	else
		return ReadRing0(buf, pos, nBytes);
}

CComboError 
CFileImpDrv98::Write(const void *buf, PGPUInt64 pos, PGPUInt32 nBytes)// const
{
	pgpAssert(IsOpened());
	pgpAssert(!IsReadOnly());
	pgpAssertAddrValid(buf, VoidAlign);

	if (mUseInt21)
		return WriteInt21(buf, pos, nBytes);
	else
		return WriteRing0(buf, pos, nBytes);
}

CComboError 
CFileImpDrv98::GetLengthRing0(PGPUInt64& length) const
{
	pgpAssert(IsOpened());

	CComboError	error;

	PGPUInt32	length32;
	error.err = R0_GetFileSize(mRing0Handle, &length32);

	if (error.HaveNonPGPError())
		error.pgpErr = kPGPError_FileOpFailed;

	if (error.IsntError())
		length = length32;

	return error;
}

CComboError 
CFileImpDrv98::GetLengthInt21(PGPUInt64& length) const
{
	pgpAssert(IsOpened());

	CComboError	error;
	VxdIntRegs	regs;

	regs.eax	= 0x4202;			// function 42
	regs.ebx	= mInt21Handle;		// file handle
	regs.ecx	= 0;
	regs.edx	= 0;
	regs.flags	= 0x0001;			// carry flag set on error

	Exec_VxD_Int(0x21, &regs);

	if (regs.flags & 0x0001)
	{
		error.pgpErr = kPGPError_FileOpFailed;
		error.err = regs.eax;
	}

	if (error.IsntError())
		length = (regs.edx << 16) | (regs.eax & 0xFFFF);

	return error;
}

CComboError 
CFileImpDrv98::OpenRing0(PGPUInt16 flags)
{
	pgpAssert(!IsOpened());

	CComboError	error;
	PGPUInt8	action, pAction, specialFlags;
	PGPUInt16	mode;

	if (flags & CFile::kReadOnlyFlag)
		mode = ACCESS_READONLY;
	else
		mode = ACCESS_READWRITE;

	if ((flags & CFile::kDenyReadFlag) && !(flags & CFile::kShareWriteFlag))
		mode |= SHARE_DENYREADWRITE;
	else if ((flags & CFile::kDenyReadFlag))
		mode |= SHARE_DENYREAD;
	else if (!(flags & CFile::kShareWriteFlag))
		mode |= SHARE_DENYWRITE;
	else
		mode |= SHARE_DENYNONE;

	if (flags & CFile::kCreateIfFlag)
		action = ACTION_EXISTS_OPEN | ACTION_NEXISTS_CREATE;
	else
		action = ACTION_EXISTS_OPEN;

	// MUST set 'specialFlags' to 0x81 to prevent deadlocks in virtual
	// volume mode.

	if (flags & CFile::kNoBufferingFlag)
		specialFlags = 0x81;
	else
		specialFlags = 0;

	error.err = R0_OpenCreateFile(FALSE, const_cast<char *>(mPath.Get()), 
		 mode, 0, action, specialFlags, &mRing0Handle, &pAction);

	if (error.HaveNonPGPError())
		error.pgpErr = kPGPError_CantOpenFile;

	return error;
}

CComboError 
CFileImpDrv98::OpenInt21(PGPUInt16 flags)
{
	pgpAssert(!IsOpened());

	CComboError	error;
	PGPUInt8	action;
	PGPUInt16	mode;
	VxdIntRegs	regs;

	if (flags & CFile::kReadOnlyFlag)
		mode = ACCESS_READONLY;
	else
		mode = ACCESS_READWRITE;

	if ((flags & CFile::kDenyReadFlag) && !(flags & CFile::kShareWriteFlag))
		mode |= SHARE_DENYREADWRITE;
	else if ((flags & CFile::kDenyReadFlag))
		mode |= SHARE_DENYREAD;
	else if (!(flags & CFile::kShareWriteFlag))
		mode |= SHARE_DENYWRITE;
	else
		mode |= SHARE_DENYNONE;

	mode |= OPEN_FLAGS_NOCRITERR;

	if (flags & CFile::kCreateIfFlag)
		action = ACTION_EXISTS_OPEN | ACTION_NEXISTS_CREATE;
	else
		action = ACTION_EXISTS_OPEN;

	regs.eax	= 0x716C;		// function 716C
	regs.ebx	= mode;			// sharing and mode flags
	regs.ecx	= 0;			// attribute flags
	regs.edx	= action;		// action to take
	regs.esi	= reinterpret_cast<PGPUInt32>(mPath.Get());	// file path
	regs.edi	= 0;
	regs.flags	= 0x0001;		// carry flag set on success
	
	Exec_VxD_Int(0x21, &regs);

	if (regs.flags & 0x0001)
	{
		error.pgpErr = kPGPError_CantOpenFile;
		error.err = regs.eax;
	}

	if (error.IsntError())
		mInt21Handle = static_cast<PGPUInt16>(regs.eax);

	return error;
}

CComboError 
CFileImpDrv98::CloseRing0()
{
	pgpAssert(IsOpened());

	CComboError	error;

	error.err = R0_CloseFile(mRing0Handle);

	if (error.HaveNonPGPError())
		error.pgpErr = kPGPError_FileOpFailed;

	if (error.IsntError())
		mRing0Handle = NULL;

	return error;
}

CComboError 
CFileImpDrv98::CloseInt21()
{
	pgpAssert(IsOpened());

	CComboError	error;
	VxdIntRegs	regs;

	regs.eax	= 0x3E00;			// function 3E
	regs.ebx	= mInt21Handle;		// handle to close
	regs.flags	= 0x0001;			// carry flag set on error

	Exec_VxD_Int(0x21, &regs);

	if (regs.flags & 0x0001)
	{
		error.pgpErr = kPGPError_FileOpFailed;
		error.err = regs.eax;
	}

	if (error.IsntError())
		mInt21Handle = NULL;

	return error;
}

CComboError 
CFileImpDrv98::SetFilePosInt21(PGPUInt32 pos) const
{
	pgpAssert(IsOpened());

	CComboError	error;
	VxdIntRegs	regs;

	regs.eax	= 0x4200;			// function 42
	regs.ebx	= mInt21Handle;		// file handle
	regs.ecx	= pos >> 16;		// high word of pos
	regs.edx	= pos & 0xFFFF;		// low word of pos
	regs.flags	= 0x0001;			// carry flag set on error

	Exec_VxD_Int(0x21, &regs);

	if (regs.flags & 0x0001)
	{
		error.pgpErr = kPGPError_FileOpFailed;
		error.err = regs.eax;
	}

	return error;
}

CComboError 
CFileImpDrv98::ReadRing0(void *buf, PGPUInt64 pos, PGPUInt32 nBytes) const
{
	pgpAssert(IsOpened());
	pgpAssertAddrValid(buf, VoidAlign);
	pgpAssert(pos <= 0xFFFFFFFF);

	CComboError	error;
	PGPUInt32	bytesRead;

	error.err = R0_ReadFile(FALSE, mRing0Handle, buf, nBytes, 
		static_cast<PGPUInt32>(pos), &bytesRead);

	if (error.HaveNonPGPError())
		error.pgpErr = kPGPError_ReadFailed;

	return error;
}

CComboError 
CFileImpDrv98::ReadInt21Aux(void *buf, PGPUInt32 nBytes) const
{
	pgpAssertAddrValid(buf, VoidAlign);

	CComboError	error;
	VxdIntRegs	regs;

	regs.eax	= 0x3F00;			// function 3F
	regs.ebx	= mInt21Handle;		// file handle
	regs.ecx	= nBytes;			// number of bytes to read
	regs.edx	= reinterpret_cast<PGPUInt32>(buf);	// buffer
	regs.flags	= 0x0001;			// carry flag set on error

	Exec_VxD_Int(0x21, &regs);

	if (regs.flags & 0x0001)
	{
		error.pgpErr = kPGPError_ReadFailed;
		error.err = regs.eax;
	}

	return error;
}

CComboError 
CFileImpDrv98::ReadInt21(void *buf, PGPUInt64 pos, PGPUInt32 nBytes) const
{
	pgpAssert(IsOpened());
	pgpAssertAddrValid(buf, VoidAlign);
	pgpAssert(pos <= 0xFFFFFFFF);

	CComboError	error;

	// Set the file position.
	error = SetFilePosInt21(static_cast<PGPUInt32>(pos));

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

		bufPos = 0;
		bytesLeft = nBytes;

		while (error.IsntError() && (bytesLeft > 0))
		{
			PGPUInt16	bytesToRead;
			
			bytesToRead = static_cast<PGPUInt16>(
				min(0x7000, nBytes - bufPos));

			error = ReadInt21Aux(static_cast<PGPByte *>(buf) + bufPos, 
				bytesToRead);

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

CComboError 
CFileImpDrv98::WriteRing0(
	const void	*buf, 
	PGPUInt64	pos, 
	PGPUInt32	nBytes) const
{
	pgpAssert(IsOpened());
	pgpAssertAddrValid(buf, VoidAlign);
	pgpAssert(pos <= 0xFFFFFFFF);

	CComboError	error;
	PGPUInt32	bytesWritten;

	error.err = R0_WriteFile(FALSE, mRing0Handle, const_cast<void *>(buf), 
		nBytes, static_cast<PGPUInt32>(pos), &bytesWritten);

	if (error.HaveNonPGPError())
		error.pgpErr = kPGPError_WriteFailed;

	return error;
}

CComboError 
CFileImpDrv98::WriteInt21Aux(const void *buf, PGPUInt32 nBytes) const
{
	pgpAssertAddrValid(buf, VoidAlign);

	CComboError	error;
	VxdIntRegs	regs;

	regs.eax	= 0x4000;			// function 40
	regs.ebx	= mInt21Handle;		// file handle
	regs.ecx	= nBytes;			// number of bytes to write
	regs.edx	= reinterpret_cast<PGPUInt32>(buf);	// buffer
	regs.flags	= 0x0001;			// carry flag set on error

	Exec_VxD_Int(0x21, &regs);

	if (regs.flags & 0x0001)
	{
		error.pgpErr = kPGPError_WriteFailed;
		error.err = regs.eax;
	}

	return error;
}

CComboError 
CFileImpDrv98::WriteInt21(
	const void	*buf, 
	PGPUInt64	pos, 
	PGPUInt32	nBytes) const
{
	pgpAssert(IsOpened());
	pgpAssertAddrValid(buf, VoidAlign);
	pgpAssert(pos <= 0xFFFFFFFF);

	CComboError	error;

	// Set the file position.
	error = SetFilePosInt21(static_cast<PGPUInt32>(pos));

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

		bufPos = 0;
		bytesLeft = nBytes;

		while (error.IsntError() && (bytesLeft > 0))
		{
			PGPUInt16	bytesToWrite;
			
			bytesToWrite = static_cast<PGPUInt16>(
				min(0x7000, nBytes - bufPos));

			error = WriteInt21Aux(static_cast<const PGPByte *>(buf) + 
				bufPos, bytesToWrite);

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

⌨️ 快捷键说明

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