📄 fastio.c
字号:
/*
* FFS File System Driver for Windows
*
* fastio.c
*
* 2004.5.6 ~
*
* Lee Jae-Hong, http://www.pyrasis.com
*
* See License.txt
*
*/
#include "ntifs.h"
#include "ffsdrv.h"
/* Globals */
extern PFFS_GLOBAL FFSGlobal;
/* Definitions */
#ifdef ALLOC_PRAGMA
#if DBG
#pragma alloc_text(PAGE, FFSFastIoRead)
#pragma alloc_text(PAGE, FFSFastIoWrite)
#endif
#pragma alloc_text(PAGE, FFSFastIoCheckIfPossible)
#pragma alloc_text(PAGE, FFSFastIoQueryBasicInfo)
#pragma alloc_text(PAGE, FFSFastIoQueryStandardInfo)
#pragma alloc_text(PAGE, FFSFastIoQueryNetworkOpenInfo)
#pragma alloc_text(PAGE, FFSFastIoLock)
#pragma alloc_text(PAGE, FFSFastIoUnlockSingle)
#pragma alloc_text(PAGE, FFSFastIoUnlockAll)
#pragma alloc_text(PAGE, FFSFastIoUnlockAll)
#endif
BOOLEAN
FFSFastIoCheckIfPossible(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN BOOLEAN CheckForReadOperation,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN bPossible = FALSE;
PFFS_FCB Fcb;
LARGE_INTEGER lLength;
lLength.QuadPart = Length;
__try
{
__try
{
if (DeviceObject == FFSGlobal->DeviceObject)
{
bPossible = FastIoIsNotPossible;
__leave;
}
Fcb = (PFFS_FCB)FileObject->FsContext;
ASSERT(Fcb != NULL);
if (Fcb->Identifier.Type == FFSVCB)
{
bPossible = FastIoIsNotPossible;
__leave;
}
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
if (IsDirectory(Fcb))
{
bPossible = FALSE;
__leave;
}
FsRtlEnterFileSystem();
if (CheckForReadOperation)
{
bPossible = FsRtlFastCheckLockForRead(
&Fcb->FileLockAnchor,
FileOffset,
&lLength,
LockKey,
FileObject,
PsGetCurrentProcess());
if (!bPossible)
bPossible = FastIoIsQuestionable;
}
else
{
if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) ||
IsFlagOn(Fcb->Vcb->Flags, VCB_WRITE_PROTECTED))
{
bPossible = FastIoIsNotPossible;
}
else
{
bPossible = FsRtlFastCheckLockForWrite(
&Fcb->FileLockAnchor,
FileOffset,
&lLength,
LockKey,
FileObject,
PsGetCurrentProcess());
if (!bPossible)
bPossible = FastIoIsQuestionable;
}
}
FFSPrint((DBG_INFO, "FFSFastIIOCheckPossible: %s %s %s\n",
FFSGetCurrentProcessName(),
"FASTIO_CHECK_IF_POSSIBLE",
Fcb->AnsiFileName.Buffer));
FFSPrint((DBG_INFO,
"FFSFastIIOCheckPossible: Offset: %I64xg Length: %xh Key: %u %s %s\n",
FileOffset->QuadPart,
Length,
LockKey,
(CheckForReadOperation ? "CheckForReadOperation:" :
"CheckForWriteOperation:"),
(bPossible ? "Succeeded" : "Failed")));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
bPossible = FastIoIsNotPossible;
}
}
__finally
{
FsRtlExitFileSystem();
}
return bPossible;
}
#if DBG
BOOLEAN
FFSFastIoRead(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN Status;
PFFS_FCB Fcb;
Fcb = (PFFS_FCB)FileObject->FsContext;
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
FFSPrint((DBG_INFO, "FFSFastIoRead: %s %s %s\n",
FFSGetCurrentProcessName(),
"FASTIO_READ",
Fcb->AnsiFileName.Buffer));
FFSPrint((DBG_INFO, "FFSFastIoRead: Offset: %I64xh Length: %xh Key: %u\n",
FileOffset->QuadPart,
Length,
LockKey));
Status = FsRtlCopyRead(
FileObject, FileOffset, Length, Wait,
LockKey, Buffer, IoStatus, DeviceObject);
return Status;
}
BOOLEAN
FFSFastIoWrite(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN bRet;
PFFS_FCB Fcb;
Fcb = (PFFS_FCB)FileObject->FsContext;
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
FFSPrint((DBG_INFO,
"FFSFastIoWrite: %s %s %s\n",
FFSGetCurrentProcessName(),
"FASTIO_WRITE",
Fcb->AnsiFileName.Buffer));
FFSPrint((DBG_INFO,
"FFSFastIoWrite: Offset: %I64xh Length: %xh Key: %xh\n",
FileOffset->QuadPart,
Length,
LockKey));
if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
{
FFSBreakPoint();
return FALSE;
}
bRet = FsRtlCopyWrite(
FileObject, FileOffset, Length, Wait,
LockKey, Buffer, IoStatus, DeviceObject);
return bRet;
}
#endif /* DBG */
BOOLEAN
FFSFastIoQueryBasicInfo(
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN Status = FALSE;
PFFS_VCB Vcb;
PFFS_FCB Fcb;
BOOLEAN FcbMainResourceAcquired = FALSE;
__try
{
__try
{
if (DeviceObject == FFSGlobal->DeviceObject)
{
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
Status = TRUE;
__leave;
}
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
Fcb = (PFFS_FCB)FileObject->FsContext;
ASSERT(Fcb != NULL);
if (Fcb->Identifier.Type == FFSVCB)
{
IoStatus->Status = STATUS_INVALID_PARAMETER;
Status = TRUE;
__leave;
}
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
FFSPrint((DBG_INFO,
"FFSFastIoQueryBasicInfo: %s %s %s\n",
FFSGetCurrentProcessName(),
"FASTIO_QUERY_BASIC_INFO",
Fcb->AnsiFileName.Buffer));
FsRtlEnterFileSystem();
if (!ExAcquireResourceSharedLite(
&Fcb->MainResource,
Wait))
{
Status = FALSE;
__leave;
}
FcbMainResourceAcquired = TRUE;
RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));
/*
typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
*/
if (FS_VERSION == 1)
{
Buffer->CreationTime = FFSSysTime(Fcb->dinode1->di_ctime);
Buffer->LastAccessTime = FFSSysTime(Fcb->dinode1->di_atime);
Buffer->LastWriteTime = FFSSysTime(Fcb->dinode1->di_mtime);
Buffer->ChangeTime = FFSSysTime(Fcb->dinode1->di_mtime);
}
else
{
Buffer->CreationTime = FFSSysTime((ULONG)Fcb->dinode2->di_ctime);
Buffer->LastAccessTime = FFSSysTime((ULONG)Fcb->dinode2->di_atime);
Buffer->LastWriteTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);
Buffer->ChangeTime = FFSSysTime((ULONG)Fcb->dinode2->di_mtime);
}
Buffer->FileAttributes = Fcb->FFSMcb->FileAttr;
IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
IoStatus->Status = STATUS_SUCCESS;
Status = TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
IoStatus->Status = GetExceptionCode();
Status = TRUE;
}
}
__finally
{
if (FcbMainResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->MainResource,
ExGetCurrentResourceThread());
}
FsRtlExitFileSystem();
}
if (Status == FALSE)
{
FFSPrint((DBG_ERROR,
"FFSFastIoQueryBasicInfo: %s %s *** Status: FALSE ***\n",
FFSGetCurrentProcessName(),
"FASTIO_QUERY_BASIC_INFO"));
}
else if (IoStatus->Status != STATUS_SUCCESS)
{
FFSPrint((DBG_ERROR,
"FFSFastIoQueryBasicInfo: %s %s *** Status: %s (%#x) ***\n",
FFSFastIoQueryBasicInfo,
"FASTIO_QUERY_BASIC_INFO",
FFSNtStatusToString(IoStatus->Status),
IoStatus->Status));
}
return Status;
}
BOOLEAN
FFSFastIoQueryStandardInfo(
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_STANDARD_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN Status = FALSE;
PFFS_VCB Vcb;
PFFS_FCB Fcb;
BOOLEAN FcbMainResourceAcquired = FALSE;
__try
{
__try
{
if (DeviceObject == FFSGlobal->DeviceObject)
{
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
Status = TRUE;
__leave;
}
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
Fcb = (PFFS_FCB)FileObject->FsContext;
ASSERT(Fcb != NULL);
if (Fcb->Identifier.Type == FFSVCB)
{
IoStatus->Status = STATUS_INVALID_PARAMETER;
Status = TRUE;
__leave;
}
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
FFSPrint((DBG_INFO,
"FFSFastIoQueryStandardInfo: %s %s %s\n",
FFSGetCurrentProcessName(),
"FASTIO_QUERY_STANDARD_INFO",
Fcb->AnsiFileName.Buffer));
FsRtlEnterFileSystem();
if (!ExAcquireResourceSharedLite(
&Fcb->MainResource,
Wait))
{
Status = FALSE;
__leave;
}
FcbMainResourceAcquired = TRUE;
RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION));
/*
typedef struct _FILE_STANDARD_INFORMATION {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
*/
if (FS_VERSION == 1)
{
Buffer->AllocationSize.QuadPart =
(LONGLONG)(Fcb->dinode1->di_size);
Buffer->EndOfFile.QuadPart =
(LONGLONG)(Fcb->dinode1->di_size);
Buffer->NumberOfLinks = Fcb->dinode1->di_nlink;
}
else
{
Buffer->AllocationSize.QuadPart =
(LONGLONG)(Fcb->dinode2->di_size);
Buffer->EndOfFile.QuadPart =
(LONGLONG)(Fcb->dinode2->di_size);
Buffer->NumberOfLinks = Fcb->dinode2->di_nlink;
}
if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
{
Buffer->DeletePending = FALSE;
}
else
{
Buffer->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);
}
if (FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
Buffer->Directory = TRUE;
}
else
{
Buffer->Directory = FALSE;
}
IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
IoStatus->Status = STATUS_SUCCESS;
Status = TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
IoStatus->Status = GetExceptionCode();
Status = TRUE;
}
}
__finally
{
if (FcbMainResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->MainResource,
ExGetCurrentResourceThread()
);
}
FsRtlExitFileSystem();
}
#if DBG
if (Status == FALSE)
{
FFSPrint((DBG_INFO,
"FFSFastIoQueryStandardInfo: %s %s *** Status: FALSE ***\n",
FFSGetCurrentProcessName(),
"FASTIO_QUERY_STANDARD_INFO"));
}
else if (IoStatus->Status != STATUS_SUCCESS)
{
FFSPrint((DBG_INFO,
"FFSFastIoQueryStandardInfo: %s %s *** Status: %s (%#x) ***\n",
FFSGetCurrentProcessName(),
"FASTIO_QUERY_STANDARD_INFO",
FFSNtStatusToString(IoStatus->Status),
IoStatus->Status));
}
#endif
return Status;
}
BOOLEAN
FFSFastIoQueryNetworkOpenInfo(
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN Status = FALSE;
PFFS_VCB Vcb;
PFFS_FCB Fcb;
BOOLEAN FcbMainResourceAcquired = FALSE;
__try
{
__try
{
if (DeviceObject == FFSGlobal->DeviceObject)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -