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

📄 fsctl.c

📁 FSD file system driver
💻 C
📖 第 1 页 / 共 3 页
字号:
				0,
				&ChangeCount,
				&dwReturn);

		if (ChangeCount != Vcb->ChangeCount)
		{
			Status = STATUS_WRONG_VOLUME;
			__leave;
		}

		Irp = IrpContext->Irp;

		IoStackLocation = IoGetCurrentIrpStackLocation(Irp);


		if (((FFSSb = FFSLoadSuper(Vcb, TRUE, SBLOCK_UFS1)) && (FFSSb->fs_magic == FS_UFS1_MAGIC) ||
			((FFSSb = FFSLoadSuper(Vcb, TRUE, SBLOCK_UFS2)) && (FFSSb->fs_magic == FS_UFS2_MAGIC))) &&
				(memcmp(FFSSb->fs_id, SUPER_BLOCK->fs_id, 16) == 0) &&
				(memcmp(FFSSb->fs_volname, SUPER_BLOCK->fs_volname, 16) == 0))
		{
			ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);

			if (FFSIsMediaWriteProtected(IrpContext, Vcb->TargetDeviceObject))
			{
				SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
			}
			else
			{
				ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
			}

			FFSPrint((DBG_INFO, "FFSVerifyVolume: Volume verify succeeded.\n"));

			Status = STATUS_SUCCESS;
		}
		else
		{
			Status = STATUS_WRONG_VOLUME;

			FFSPurgeVolume(Vcb, FALSE);

			SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);

			ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);

			FFSPrint((DBG_INFO, "FFSVerifyVolume: Volume verify failed.\n"));
		}
	}

	__finally
	{
		if (FFSSb)
			ExFreePool(FFSSb);

		if (VcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Vcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (GlobalResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&FFSGlobal->Resource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			FFSCompleteIrpContext(IrpContext,  Status);
		}
	}

	return Status;
}


NTSTATUS
FFSIsVolumeMounted(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	ASSERT(IrpContext);

	ASSERT((IrpContext->Identifier.Type == FFSICX) &&
			(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

	return FFSVerifyVolume(IrpContext);
}


NTSTATUS
FFSDismountVolume(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT  DeviceObject;
	NTSTATUS        Status = STATUS_UNSUCCESSFUL;
	PFFS_VCB        Vcb;
	BOOLEAN         VcbResourceAcquired = FALSE;

	__try
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;

		//
		// This request is not allowed on the main device object
		//
		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			__leave;
		}

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		ASSERT(IsMounted(Vcb));

		ExAcquireResourceExclusiveLite(
				&Vcb->MainResource,
				TRUE);

		VcbResourceAcquired = TRUE;

		if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
		{
			Status = STATUS_VOLUME_DISMOUNTED;
			__leave;
		}

		/*        
		if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
		{
			FFSPrint((DBG_ERROR, "FFSDismount: Volume is not locked.\n"));

			Status = STATUS_ACCESS_DENIED;
			__leave;
		}
		*/

		FFSFlushFiles(Vcb, FALSE);

		FFSFlushVolume(Vcb, FALSE);

		FFSPurgeVolume(Vcb, TRUE);

		ExReleaseResourceForThreadLite(
				&Vcb->MainResource,
				ExGetCurrentResourceThread());

		VcbResourceAcquired = FALSE;

		FFSCheckDismount(IrpContext, Vcb, TRUE);

		FFSPrint((DBG_INFO, "FFSDismount: Volume dismount pending.\n"));

		Status = STATUS_SUCCESS;
	}
	__finally
	{
		if (VcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Vcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			FFSCompleteIrpContext(IrpContext,  Status);
		}
	}

	return Status;
}


BOOLEAN
FFSCheckDismount(
	IN PFFS_IRP_CONTEXT  IrpContext,
	IN PFFS_VCB          Vcb,
	IN BOOLEAN           bForce)
{
	KIRQL   Irql;
	PVPB    Vpb = Vcb->Vpb;
	BOOLEAN bDeleted = FALSE;
	ULONG   UnCleanCount = 0;

	ExAcquireResourceExclusiveLite(
			&FFSGlobal->Resource, TRUE);

	ExAcquireResourceExclusiveLite(
			&Vcb->MainResource, TRUE);

	if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
			(IrpContext->RealDevice == Vcb->RealDevice))
	{
		UnCleanCount = 3;
	}
	else
	{
		UnCleanCount = 2;
	}

	IoAcquireVpbSpinLock(&Irql);

	if ((Vpb->ReferenceCount == UnCleanCount) || bForce)
	{

		if ((Vpb->ReferenceCount != UnCleanCount) && bForce)
		{
			FFSBreakPoint();
		}

		ClearFlag(Vpb->Flags, VPB_MOUNTED);
		ClearFlag(Vpb->Flags, VPB_LOCKED);

		if ((Vcb->RealDevice != Vpb->RealDevice) &&
				(Vcb->RealDevice->Vpb == Vpb))
		{
			SetFlag(Vcb->RealDevice->Flags, DO_DEVICE_INITIALIZING);
			SetFlag(Vpb->Flags, VPB_PERSISTENT);
		}

		FFSRemoveVcb(Vcb);

		ClearFlag(Vpb->Flags, VPB_MOUNTED);
		SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);

		Vpb->DeviceObject = NULL;

		bDeleted = TRUE;
	}

#if 0

	else if ((Vpb->RealDevice->Vpb == Vpb) && bForce)
	{
		PVPB NewVpb;

#define TAG_VPB                         ' bpV'

		NewVpb = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, 
				sizeof(VPB), TAG_VPB);

		NewVpb->Type = IO_TYPE_VPB;
		NewVpb->Size = sizeof(VPB);
		NewVpb->RealDevice = Vcb->Vpb->RealDevice;

		NewVpb->RealDevice->Vpb = NewVpb;

		NewVpb->Flags = FlagOn(Vcb->Vpb->Flags, VPB_REMOVE_PENDING);

		NewVpb = NULL;

		ClearFlag(Vcb->Flags, VCB_MOUNTED);
		ClearFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
	}

#endif

	IoReleaseVpbSpinLock(Irql);

	ExReleaseResourceForThreadLite(
			&Vcb->MainResource,
			ExGetCurrentResourceThread());

	ExReleaseResourceForThreadLite(
			&FFSGlobal->Resource,
			ExGetCurrentResourceThread());

	if (bDeleted)
	{
#if 0
		FFSBreakPoint(); /* XP俊辑 宏饭捞农 器牢飘 惯积 */
#endif

		FFSFreeVcb(Vcb);
	}

	return bDeleted;
}


NTSTATUS
FFSPurgeVolume(
	IN PFFS_VCB Vcb,
	IN BOOLEAN  FlushBeforePurge)
{
	PFFS_FCB        Fcb;
	LIST_ENTRY      FcbList;
	PLIST_ENTRY     ListEntry;
	PFCB_LIST_ENTRY FcbListEntry;

	__try
	{
		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
				IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
		{
			FlushBeforePurge = FALSE;
		}

		FcbListEntry= NULL;
		InitializeListHead(&FcbList);

		for (ListEntry = Vcb->FcbList.Flink;
				ListEntry != &Vcb->FcbList;
				ListEntry = ListEntry->Flink)
		{
			Fcb = CONTAINING_RECORD(ListEntry, FFS_FCB, Next);

			Fcb->ReferenceCount++;

			FFSPrint((DBG_INFO, "FFSPurgeVolume: %s refercount=%xh\n", Fcb->AnsiFileName.Buffer, Fcb->ReferenceCount));

			FcbListEntry = ExAllocatePool(PagedPool, sizeof(FCB_LIST_ENTRY));

			if (FcbListEntry)
			{
				FcbListEntry->Fcb = Fcb;

				InsertTailList(&FcbList, &FcbListEntry->Next);
			}
			else
			{
				FFSPrint((DBG_ERROR, "FFSPurgeVolume: Error allocating FcbListEntry ...\n"));
			}
		}

		while (!IsListEmpty(&FcbList))
		{
			ListEntry = RemoveHeadList(&FcbList);

			FcbListEntry = CONTAINING_RECORD(ListEntry, FCB_LIST_ENTRY, Next);

			Fcb = FcbListEntry->Fcb;

			if (ExAcquireResourceExclusiveLite(
						&Fcb->MainResource,
						TRUE))
			{
				FFSPurgeFile(Fcb, FlushBeforePurge);

				if (!Fcb->OpenHandleCount && Fcb->ReferenceCount == 1)
				{
					RemoveEntryList(&Fcb->Next);
					FFSFreeFcb(Fcb);
				}
				else
				{
					ExReleaseResourceForThreadLite(
						&Fcb->MainResource,
						ExGetCurrentResourceThread());
				}
			}

			ExFreePool(FcbListEntry);
		}

		if (FlushBeforePurge)
		{
			ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
			ExReleaseResource(&Vcb->PagingIoResource);

			CcFlushCache(&Vcb->SectionObject, NULL, 0, NULL);
		}

		if (Vcb->SectionObject.ImageSectionObject)
		{
			MmFlushImageSection(&Vcb->SectionObject, MmFlushForWrite);
		}

		if (Vcb->SectionObject.DataSectionObject)
		{
			CcPurgeCacheSection(&Vcb->SectionObject, NULL, 0, FALSE);
		}

		FFSPrint((DBG_INFO, "FFSPurgeVolume: Volume flushed and purged.\n"));
	}
	__finally
	{
		// Nothing
	}

	return STATUS_SUCCESS;
}


NTSTATUS
FFSPurgeFile(
	IN PFFS_FCB Fcb,
	IN BOOLEAN  FlushBeforePurge)
{
	IO_STATUS_BLOCK    IoStatus;

	ASSERT(Fcb != NULL);

	ASSERT((Fcb->Identifier.Type == FFSFCB) &&
			(Fcb->Identifier.Size == sizeof(FFS_FCB)));


	if(!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) && FlushBeforePurge &&
			!IsFlagOn(Fcb->Vcb->Flags, VCB_WRITE_PROTECTED))
	{

		FFSPrint((DBG_INFO, "FFSPurgeFile: CcFlushCache on %s.\n", 
					Fcb->AnsiFileName.Buffer));

		ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
		ExReleaseResource(&Fcb->PagingIoResource);

		CcFlushCache(&Fcb->SectionObject, NULL, 0, &IoStatus);

		ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
	}

	if (Fcb->SectionObject.ImageSectionObject)
	{

		FFSPrint((DBG_INFO, "FFSPurgeFile: MmFlushImageSection on %s.\n", 
					Fcb->AnsiFileName.Buffer));

		MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
	}

	if (Fcb->SectionObject.DataSectionObject)
	{

		FFSPrint((DBG_INFO, "FFSPurgeFile: CcPurgeCacheSection on %s.\n",
					Fcb->AnsiFileName.Buffer));

		CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);
	}

	return STATUS_SUCCESS;
}


NTSTATUS
FFSSelectBSDPartition(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PIRP                Irp;
	NTSTATUS            Status;
	PFFS_BSD_PARTITION  BSDPartition;

	__try
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		Irp = IrpContext->Irp;

		BSDPartition = (PFFS_BSD_PARTITION)Irp->AssociatedIrp.SystemBuffer;
		FFSGlobal->PartitionNumber = BSDPartition->Number;

		Status = STATUS_SUCCESS;
	}
	__finally
	{
		if (!IrpContext->ExceptionInProgress)
		{
			FFSCompleteIrpContext(IrpContext,  Status);
		}
	}

	return Status;
}


NTSTATUS
FFSFileSystemControl(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	NTSTATUS    Status;

	ASSERT(IrpContext);

	ASSERT((IrpContext->Identifier.Type == FFSICX) &&
			(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

	switch (IrpContext->MinorFunction)
	{
		case IRP_MN_USER_FS_REQUEST:
			Status = FFSUserFsRequest(IrpContext);
			break;

		case IRP_MN_MOUNT_VOLUME:
			Status = FFSMountVolume(IrpContext);
			break;

		case IRP_MN_VERIFY_VOLUME:
			Status = FFSVerifyVolume(IrpContext);
			break;

		default:

			FFSPrint((DBG_ERROR, "FFSFilsSystemControl: Invalid Device Request.\n"));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			FFSCompleteIrpContext(IrpContext,  Status);
	}

	return Status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -