📄 memory.c
字号:
/*
* FFS File System Driver for Windows
*
* memory.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
#pragma alloc_text(PAGE, FFSAllocateIrpContext)
#pragma alloc_text(PAGE, FFSFreeIrpContext)
#pragma alloc_text(PAGE, FFSv1AllocateFcb)
#pragma alloc_text(PAGE, FFSv2AllocateFcb)
#pragma alloc_text(PAGE, FFSFreeFcb)
#pragma alloc_text(PAGE, FFSAllocateMcb)
#pragma alloc_text(PAGE, FFSSearchMcbTree)
#pragma alloc_text(PAGE, FFSSearchMcb)
#pragma alloc_text(PAGE, FFSGetFullFileName)
#pragma alloc_text(PAGE, FFSRefreshMcb)
#pragma alloc_text(PAGE, FFSAddMcbNode)
#pragma alloc_text(PAGE, FFSDeleteMcbNode)
#pragma alloc_text(PAGE, FFSFreeMcbTree)
#pragma alloc_text(PAGE, FFSCheckBitmapConsistency)
#pragma alloc_text(PAGE, FFSCheckSetBlock)
#pragma alloc_text(PAGE, FFSInitializeVcb)
#pragma alloc_text(PAGE, FFSFreeCcb)
#pragma alloc_text(PAGE, FFSAllocateCcb)
#pragma alloc_text(PAGE, FFSFreeVcb)
#pragma alloc_text(PAGE, FFSCreateFcbFromMcb)
#pragma alloc_text(PAGE, FFSSyncUninitializeCacheMap)
#endif
PFFS_IRP_CONTEXT
FFSAllocateIrpContext(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStackLocation;
PFFS_IRP_CONTEXT IrpContext;
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
IrpContext = (PFFS_IRP_CONTEXT)(ExAllocateFromNPagedLookasideList(&(FFSGlobal->FFSIrpContextLookasideList)));
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
if (IrpContext == NULL)
{
IrpContext = ExAllocatePool(NonPagedPool, sizeof(FFS_IRP_CONTEXT));
//
// Zero out the irp context and indicate that it is from pool and
// not region allocated
//
RtlZeroMemory(IrpContext, sizeof(FFS_IRP_CONTEXT));
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_FROM_POOL);
}
else
{
//
// Zero out the irp context and indicate that it is from zone and
// not pool allocated
//
RtlZeroMemory(IrpContext, sizeof(FFS_IRP_CONTEXT));
}
if (!IrpContext)
{
return NULL;
}
IrpContext->Identifier.Type = FFSICX;
IrpContext->Identifier.Size = sizeof(FFS_IRP_CONTEXT);
IrpContext->Irp = Irp;
IrpContext->MajorFunction = IoStackLocation->MajorFunction;
IrpContext->MinorFunction = IoStackLocation->MinorFunction;
IrpContext->DeviceObject = DeviceObject;
IrpContext->FileObject = IoStackLocation->FileObject;
if (IrpContext->FileObject != NULL)
{
IrpContext->RealDevice = IrpContext->FileObject->DeviceObject;
}
else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL)
{
if (IoStackLocation->Parameters.MountVolume.Vpb)
{
IrpContext->RealDevice =
IoStackLocation->Parameters.MountVolume.Vpb->RealDevice;
}
}
if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
IrpContext->MajorFunction == IRP_MJ_SHUTDOWN)
{
IrpContext->IsSynchronous = TRUE;
}
else if (IrpContext->MajorFunction == IRP_MJ_CLEANUP ||
IrpContext->MajorFunction == IRP_MJ_CLOSE)
{
IrpContext->IsSynchronous = FALSE;
}
#if (_WIN32_WINNT >= 0x0500)
else if (IrpContext->MajorFunction == IRP_MJ_PNP)
{
if (IoGetCurrentIrpStackLocation(Irp)->FileObject == NULL)
{
IrpContext->IsSynchronous = TRUE;
}
else
{
IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
}
}
#endif //(_WIN32_WINNT >= 0x0500)
else
{
IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
}
#if 0
//
// Temporary workaround for a bug in close that makes it reference a
// fileobject when it is no longer valid.
//
if (IrpContext->MajorFunction == IRP_MJ_CLOSE)
{
IrpContext->IsSynchronous = TRUE;
}
#endif
IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
IrpContext->ExceptionInProgress = FALSE;
return IrpContext;
}
VOID
FFSFreeIrpContext(
IN PFFS_IRP_CONTEXT IrpContext)
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
FFSUnpinRepinnedBcbs(IrpContext);
// Return the Irp context record to the region or to pool depending on
// its flag
if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FROM_POOL))
{
IrpContext->Identifier.Type = 0;
IrpContext->Identifier.Size = 0;
ExFreePool(IrpContext);
}
else
{
IrpContext->Identifier.Type = 0;
IrpContext->Identifier.Size = 0;
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
ExFreeToNPagedLookasideList(&(FFSGlobal->FFSIrpContextLookasideList), IrpContext);
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
}
}
VOID
FFSRepinBcb(
IN PFFS_IRP_CONTEXT IrpContext,
IN PBCB Bcb)
{
PFFS_REPINNED_BCBS Repinned;
ULONG i;
Repinned = &IrpContext->Repinned;
return;
while (Repinned)
{
for (i = 0; i < FFS_REPINNED_BCBS_ARRAY_SIZE; i += 1)
{
if (Repinned->Bcb[i] == Bcb)
{
return;
}
}
Repinned = Repinned->Next;
}
while (TRUE)
{
for (i = 0; i < FFS_REPINNED_BCBS_ARRAY_SIZE; i += 1)
{
if (Repinned->Bcb[i] == Bcb)
{
return;
}
if (Repinned->Bcb[i] == NULL)
{
Repinned->Bcb[i] = Bcb;
CcRepinBcb(Bcb);
return;
}
}
if (Repinned->Next == NULL)
{
Repinned->Next = ExAllocatePool(PagedPool, sizeof(FFS_REPINNED_BCBS));
RtlZeroMemory(Repinned->Next, sizeof(FFS_REPINNED_BCBS));
}
Repinned = Repinned->Next;
}
}
VOID
FFSUnpinRepinnedBcbs(
IN PFFS_IRP_CONTEXT IrpContext)
{
IO_STATUS_BLOCK RaiseIosb;
PFFS_REPINNED_BCBS Repinned;
BOOLEAN WriteThroughToDisk;
PFILE_OBJECT FileObject = NULL;
BOOLEAN ForceVerify = FALSE;
ULONG i;
Repinned = &IrpContext->Repinned;
RaiseIosb.Status = STATUS_SUCCESS;
WriteThroughToDisk = (BOOLEAN)(IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH) ||
IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY));
while (Repinned != NULL)
{
for (i = 0; i < FFS_REPINNED_BCBS_ARRAY_SIZE; i += 1)
{
if (Repinned->Bcb[i] != NULL)
{
IO_STATUS_BLOCK Iosb;
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY))
{
FileObject = CcGetFileObjectFromBcb(Repinned->Bcb[i]);
}
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
CcUnpinRepinnedBcb(Repinned->Bcb[i],
WriteThroughToDisk,
&Iosb);
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
if (!NT_SUCCESS(Iosb.Status))
{
if (RaiseIosb.Status == STATUS_SUCCESS)
{
RaiseIosb = Iosb;
}
if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY) &&
(IrpContext->MajorFunction != IRP_MJ_CLEANUP) &&
(IrpContext->MajorFunction != IRP_MJ_FLUSH_BUFFERS) &&
(IrpContext->MajorFunction != IRP_MJ_SET_INFORMATION))
{
CcPurgeCacheSection(FileObject->SectionObjectPointer,
NULL,
0,
FALSE);
ForceVerify = TRUE;
}
}
Repinned->Bcb[i] = NULL;
}
else
{
break;
}
}
if (Repinned != &IrpContext->Repinned)
{
PFFS_REPINNED_BCBS Saved;
Saved = Repinned->Next;
ExFreePool(Repinned);
Repinned = Saved;
}
else
{
Repinned = Repinned->Next;
IrpContext->Repinned.Next = NULL;
}
}
if (!NT_SUCCESS(RaiseIosb.Status))
{
FFSBreakPoint();
if (ForceVerify && FileObject)
{
SetFlag(FileObject->DeviceObject->Flags, DO_VERIFY_VOLUME);
IoSetHardErrorOrVerifyDevice(IrpContext->Irp,
FileObject->DeviceObject);
}
IrpContext->Irp->IoStatus = RaiseIosb;
FFSNormalizeAndRaiseStatus(IrpContext, RaiseIosb.Status);
}
return;
}
PFFS_FCB
FFSv1AllocateFcb(
IN PFFS_VCB Vcb,
IN PFFS_MCB FFSMcb,
IN PFFSv1_INODE dinode1)
{
PFFS_FCB Fcb;
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
Fcb = (PFFS_FCB)(ExAllocateFromNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList)));
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
if (Fcb == NULL)
{
Fcb = (PFFS_FCB)ExAllocatePool(NonPagedPool, sizeof(FFS_FCB));
RtlZeroMemory(Fcb, sizeof(FFS_FCB));
SetFlag(Fcb->Flags, FCB_FROM_POOL);
}
else
{
RtlZeroMemory(Fcb, sizeof(FFS_FCB));
}
if (!Fcb)
{
return NULL;
}
Fcb->Identifier.Type = FFSFCB;
Fcb->Identifier.Size = sizeof(FFS_FCB);
FsRtlInitializeFileLock(
&Fcb->FileLockAnchor,
NULL,
NULL);
Fcb->OpenHandleCount = 0;
Fcb->ReferenceCount = 0;
Fcb->Vcb = Vcb;
#if DBG
Fcb->AnsiFileName.MaximumLength = (USHORT)
RtlxUnicodeStringToOemSize(&(FFSMcb->ShortName)) + 1;
Fcb->AnsiFileName.Buffer = (PUCHAR)
ExAllocatePool(PagedPool, Fcb->AnsiFileName.MaximumLength);
if (!Fcb->AnsiFileName.Buffer)
{
goto errorout;
}
RtlZeroMemory(Fcb->AnsiFileName.Buffer, Fcb->AnsiFileName.MaximumLength);
FFSUnicodeToOEM(&(Fcb->AnsiFileName),
&(FFSMcb->ShortName));
#endif
FFSMcb->FileAttr = FILE_ATTRIBUTE_NORMAL;
if ((dinode1->di_mode & IFMT) == IFDIR)
{
SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY);
}
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
FFSIsReadOnly(dinode1->di_mode))
{
SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_READONLY);
}
Fcb->dinode1 = dinode1;
Fcb->FFSMcb = FFSMcb;
FFSMcb->FFSFcb = Fcb;
RtlZeroMemory(&Fcb->Header, sizeof(FSRTL_COMMON_FCB_HEADER));
Fcb->Header.NodeTypeCode = (USHORT)FFSFCB;
Fcb->Header.NodeByteSize = sizeof(FFS_FCB);
Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
Fcb->Header.Resource = &(Fcb->MainResource);
Fcb->Header.PagingIoResource = &(Fcb->PagingIoResource);
{
ULONG Totalblocks = (Fcb->dinode1->di_blocks);
Fcb->Header.AllocationSize.QuadPart =
(((LONGLONG)FFSDataBlocks(Vcb, Totalblocks)) << BLOCK_BITS);
}
Fcb->Header.FileSize.QuadPart = (LONGLONG)(Fcb->dinode1->di_size);
Fcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff);
Fcb->SectionObject.DataSectionObject = NULL;
Fcb->SectionObject.SharedCacheMap = NULL;
Fcb->SectionObject.ImageSectionObject = NULL;
ExInitializeResourceLite(&(Fcb->MainResource));
ExInitializeResourceLite(&(Fcb->PagingIoResource));
InsertTailList(&Vcb->FcbList, &Fcb->Next);
#if DBG
ExAcquireResourceExclusiveLite(
&FFSGlobal->CountResource,
TRUE);
FFSGlobal->FcbAllocated++;
ExReleaseResourceForThreadLite(
&FFSGlobal->CountResource,
ExGetCurrentResourceThread());
#endif
return Fcb;
#if DBG
errorout:
#endif
if (Fcb)
{
#if DBG
if (Fcb->AnsiFileName.Buffer)
ExFreePool(Fcb->AnsiFileName.Buffer);
#endif
if (FlagOn(Fcb->Flags, FCB_FROM_POOL))
{
ExFreePool(Fcb);
}
else
{
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
ExFreeToNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList), Fcb);
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
}
}
return NULL;
}
PFFS_FCB
FFSv2AllocateFcb(
IN PFFS_VCB Vcb,
IN PFFS_MCB FFSMcb,
IN PFFSv2_INODE dinode2)
{
PFFS_FCB Fcb;
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
Fcb = (PFFS_FCB)(ExAllocateFromNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList)));
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
if (Fcb == NULL)
{
Fcb = (PFFS_FCB)ExAllocatePool(NonPagedPool, sizeof(FFS_FCB));
RtlZeroMemory(Fcb, sizeof(FFS_FCB));
SetFlag(Fcb->Flags, FCB_FROM_POOL);
}
else
{
RtlZeroMemory(Fcb, sizeof(FFS_FCB));
}
if (!Fcb)
{
return NULL;
}
Fcb->Identifier.Type = FFSFCB;
Fcb->Identifier.Size = sizeof(FFS_FCB);
FsRtlInitializeFileLock(
&Fcb->FileLockAnchor,
NULL,
NULL);
Fcb->OpenHandleCount = 0;
Fcb->ReferenceCount = 0;
Fcb->Vcb = Vcb;
#if DBG
Fcb->AnsiFileName.MaximumLength = (USHORT)
RtlxUnicodeStringToOemSize(&(FFSMcb->ShortName)) + 1;
Fcb->AnsiFileName.Buffer = (PUCHAR)
ExAllocatePool(PagedPool, Fcb->AnsiFileName.MaximumLength);
if (!Fcb->AnsiFileName.Buffer)
{
goto errorout;
}
RtlZeroMemory(Fcb->AnsiFileName.Buffer, Fcb->AnsiFileName.MaximumLength);
FFSUnicodeToOEM(&(Fcb->AnsiFileName),
&(FFSMcb->ShortName));
#endif
FFSMcb->FileAttr = FILE_ATTRIBUTE_NORMAL;
if ((dinode2->di_mode & IFMT) == IFDIR)
{
SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY);
}
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
FFSIsReadOnly(dinode2->di_mode))
{
SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_READONLY);
}
Fcb->dinode2 = dinode2;
Fcb->FFSMcb = FFSMcb;
FFSMcb->FFSFcb = Fcb;
RtlZeroMemory(&Fcb->Header, sizeof(FSRTL_COMMON_FCB_HEADER));
Fcb->Header.NodeTypeCode = (USHORT)FFSFCB;
Fcb->Header.NodeByteSize = sizeof(FFS_FCB);
Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
Fcb->Header.Resource = &(Fcb->MainResource);
Fcb->Header.PagingIoResource = &(Fcb->PagingIoResource);
{
ULONG Totalblocks = (ULONG)(Fcb->dinode2->di_blocks);
Fcb->Header.AllocationSize.QuadPart =
(((LONGLONG)FFSDataBlocks(Vcb, Totalblocks)) << BLOCK_BITS);
}
Fcb->Header.FileSize.QuadPart = (LONGLONG)(Fcb->dinode2->di_size);
Fcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff);
Fcb->SectionObject.DataSectionObject = NULL;
Fcb->SectionObject.SharedCacheMap = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -