📄 fsctl.c
字号:
ExFreePool(Ext2Sb);
}
if (VolumeDeviceObject)
{
IoDeleteDevice(VolumeDeviceObject);
}
}
if (!IrpContext->ExceptionInProgress)
{
if (NT_SUCCESS(Status))
{
ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
}
IrpContext->Irp->IoStatus.Status = Status;
Ext2CompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
Ext2FreeIrpContext(IrpContext);
}
}
return Status;
}
NTSTATUS
Ext2VerifyVolume (IN PEXT2_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEXT2_SUPER_BLOCK ext2_sb = NULL;
PEXT2_VCB Vcb;
BOOLEAN VcbResourceAcquired = FALSE;
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
__try
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
//
// This request is not allowed on the main device object
//
if (DeviceObject == gExt2Global->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
(Vcb->Identifier.Size == sizeof(EXT2_VCB)));
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE );
VcbResourceAcquired = TRUE;
if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME))
{
Status = STATUS_SUCCESS;
__leave;
}
Irp = IrpContext->Irp;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
ext2_sb = Ext2LoadSuper(Vcb->TargetDeviceObject);
if (ext2_sb && ext2_sb->s_magic == EXT2_SUPER_MAGIC)
{
ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
Ext2DbgPrint(D_FSCTL, "Ext2VerifyVolume: Volume verify succeeded.\n");
Status = STATUS_SUCCESS;
__leave;
}
else
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
VcbResourceAcquired = FALSE;
Ext2PurgeVolume(Vcb, FALSE);
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE
);
VcbResourceAcquired = TRUE;
SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
Ext2DbgPrint(D_FSCTL, "Ext2VerifyVolume: Volume verify failed\n");
__leave;
}
__leave;
}
__finally
{
if (ext2_sb)
ExFreePool(ext2_sb);
if (VcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (!IrpContext->ExceptionInProgress)
{
IrpContext->Irp->IoStatus.Status = Status;
Ext2CompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
Ext2FreeIrpContext(IrpContext);
}
}
return Status;
}
NTSTATUS
Ext2IsVolumeMounted (IN PEXT2_IRP_CONTEXT IrpContext)
{
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
return Ext2VerifyVolume(IrpContext);
}
NTSTATUS
Ext2DismountVolume (IN PEXT2_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEXT2_VCB Vcb;
BOOLEAN VcbResourceAcquired = FALSE;
__try
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
//
// This request is not allowed on the main device object
//
if (DeviceObject == gExt2Global->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
(Vcb->Identifier.Size == sizeof(EXT2_VCB)));
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE );
VcbResourceAcquired = TRUE;
if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
{
Ext2DbgPrint(D_FSCTL, "Ext2Dismount: Volume is not locked.\n");
Status = STATUS_ACCESS_DENIED;
__leave;
}
SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
Ext2DbgPrint(D_FSCTL, "Ext2Dismount: Volume dismount pending.\n");
Status = STATUS_SUCCESS;
}
__finally
{
if (VcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (!IrpContext->ExceptionInProgress)
{
IrpContext->Irp->IoStatus.Status = Status;
Ext2CompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
Ext2FreeIrpContext(IrpContext);
}
}
return Status;
}
NTSTATUS
Ext2PurgeVolume (IN PEXT2_VCB Vcb,
IN BOOLEAN FlushBeforePurge )
{
BOOLEAN VcbResourceAcquired = FALSE;
PEXT2_FCB Fcb;
LIST_ENTRY FcbList;
PLIST_ENTRY ListEntry;
PFCB_LIST_ENTRY FcbListEntry;
BOOLEAN Flush = FlushBeforePurge;
__try
{
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
(Vcb->Identifier.Size == sizeof(EXT2_VCB)));
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
{
Flush = FALSE;
}
ExAcquireResourceSharedLite(
&Vcb->MainResource,
TRUE );
VcbResourceAcquired = TRUE;
InitializeListHead(&FcbList);
for (ListEntry = Vcb->FcbList.Flink;
ListEntry != &Vcb->FcbList;
ListEntry = ListEntry->Flink )
{
Fcb = CONTAINING_RECORD(ListEntry, EXT2_FCB, Next);
ExAcquireResourceExclusiveLite(
&Fcb->CountResource,
TRUE );
Fcb->ReferenceCount++;
ExReleaseResourceForThreadLite(
&Fcb->CountResource,
ExGetCurrentResourceThread());
#if DBG
Ext2DbgPrint(D_FSCTL, "Ext2PurgeVolume: %s refercount=%xh\n", Fcb->AnsiFileName.Buffer, Fcb->ReferenceCount);
#endif
FcbListEntry = ExAllocatePool(PagedPool, sizeof(FCB_LIST_ENTRY));
if (!FcbListEntry)
{
Ext2DbgPrint(D_FSCTL, "Ext2PurgeVolume: Error allocating FcbListEntry ...\n");
}
FcbListEntry->Fcb = Fcb;
InsertTailList(&FcbList, &FcbListEntry->Next);
}
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread() );
VcbResourceAcquired = FALSE;
while (!IsListEmpty(&FcbList))
{
ListEntry = RemoveHeadList(&FcbList);
FcbListEntry = CONTAINING_RECORD(ListEntry, FCB_LIST_ENTRY, Next);
Fcb = FcbListEntry->Fcb;
Ext2PurgeFile(Fcb, FlushBeforePurge);
if (!Fcb->OpenHandleCount && Fcb->ReferenceCount == 1)
{
#if DBG
Ext2DbgPrint(D_FSCTL, "Ext2FreeFcb %s.\n", Fcb->AnsiFileName.Buffer);
#endif
Ext2FreeFcb(Fcb);
}
ExFreePool(FcbListEntry);
}
Ext2DbgPrint(D_FSCTL, "Ext2PurgeVolume: Volume flushed and purged.\n");
}
__finally
{
if (VcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread() );
}
}
return STATUS_SUCCESS;
}
NTSTATUS
Ext2PurgeFile (IN PEXT2_FCB Fcb,
IN BOOLEAN FlushBeforePurge )
{
IO_STATUS_BLOCK IoStatus;
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
if(!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) && FlushBeforePurge)
{
#if DBG
Ext2DbgPrint(D_FSCTL, "Ext2PurgeFile: CcFlushCache on %s.\n", Fcb->AnsiFileName.Buffer);
#endif
CcFlushCache(&Fcb->SectionObject, NULL, 0, &IoStatus);
ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
}
if (Fcb->SectionObject.ImageSectionObject)
{
#if DBG
Ext2DbgPrint(D_FSCTL, "Ext2PurgeFile: MmFlushImageSection on %s.\n", Fcb->AnsiFileName.Buffer);
#endif
MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
}
if (Fcb->SectionObject.DataSectionObject)
{
#if DBG
Ext2DbgPrint(D_FSCTL, "Ext2PurgeFile: CcPurgeCacheSection on %s.\n", Fcb->AnsiFileName.Buffer);
#endif
CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);
}
return STATUS_SUCCESS;
}
NTSTATUS
Ext2FileSystemControl (IN PEXT2_IRP_CONTEXT IrpContext)
{
NTSTATUS Status;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
switch (IrpContext->MinorFunction)
{
case IRP_MN_USER_FS_REQUEST:
Status = Ext2UserFsRequest(IrpContext);
break;
case IRP_MN_MOUNT_VOLUME:
Status = Ext2MountVolume(IrpContext);
break;
case IRP_MN_VERIFY_VOLUME:
Status = Ext2VerifyVolume(IrpContext);
break;
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
IrpContext->Irp->IoStatus.Status = Status;
Ext2CompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
Ext2FreeIrpContext(IrpContext);
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -