📄 cpgpdiskdrvwinutils.cpp
字号:
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 + -