📄 fsctl.c
字号:
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 + -