📄 cfileimpdrv98.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, ®s);
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, ®s);
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, ®s);
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, ®s);
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, ®s);
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, ®s);
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 + -