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

📄 memory.c

📁 FSD file system driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
 * 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 + -