📄 fsctl.c
字号:
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
rfsd_sb = RfsdLoadSuper(Vcb, TRUE);
// FUTURE: use the volume name and uuid from the extended superblock to make this happen.
// NOTE: The magic check will have to use the same thing as mount did!
if ((rfsd_sb != NULL) /*&& (rfsd_sb->s_magic == RFSD_SUPER_MAGIC) &&
(memcmp(rfsd_sb->s_uuid, SUPER_BLOCK->s_uuid, 16) == 0) &&
(memcmp(rfsd_sb->s_volume_name, SUPER_BLOCK->s_volume_name, 16) ==0)*/) {
ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
if (RfsdIsMediaWriteProtected(IrpContext, Vcb->TargetDeviceObject)) {
SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
} else {
ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
}
RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify succeeded.\n"));
Status = STATUS_SUCCESS;
} else {
Status = STATUS_WRONG_VOLUME;
RfsdPurgeVolume(Vcb, FALSE);
SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify failed.\n"));
}
} __finally {
if (rfsd_sb)
ExFreePool(rfsd_sb);
if (VcbResourceAcquired) {
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (GlobalResourceAcquired) {
ExReleaseResourceForThreadLite(
&RfsdGlobal->Resource,
ExGetCurrentResourceThread() );
}
if (!IrpContext->ExceptionInProgress) {
RfsdCompleteIrpContext(IrpContext, Status);
}
}
return Status;
}
NTSTATUS
RfsdIsVolumeMounted (IN PRFSD_IRP_CONTEXT IrpContext)
{
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
return RfsdVerifyVolume(IrpContext);
}
NTSTATUS
RfsdDismountVolume (IN PRFSD_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PRFSD_VCB Vcb;
BOOLEAN VcbResourceAcquired = FALSE;
__try {
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
//
// This request is not allowed on the main device object
//
if (DeviceObject == RfsdGlobal->DeviceObject) {
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_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)) {
RfsdPrint((DBG_ERROR, "RfsdDismount: Volume is not locked.\n"));
Status = STATUS_ACCESS_DENIED;
__leave;
}
*/
#if DISABLED
RfsdFlushFiles(Vcb, FALSE);
RfsdFlushVolume(Vcb, FALSE);
RfsdPurgeVolume(Vcb, TRUE);
#endif
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread() );
VcbResourceAcquired = FALSE;
RfsdCheckDismount(IrpContext, Vcb, TRUE);
RfsdPrint((DBG_INFO, "RfsdDismount: Volume dismount pending.\n"));
Status = STATUS_SUCCESS;
} __finally {
if (VcbResourceAcquired) {
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (!IrpContext->ExceptionInProgress) {
RfsdCompleteIrpContext(IrpContext, Status);
}
}
return Status;
}
BOOLEAN
RfsdCheckDismount (
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN BOOLEAN bForce )
{
KIRQL Irql;
PVPB Vpb = Vcb->Vpb;
BOOLEAN bDeleted = FALSE;
ULONG UnCleanCount = 0;
ExAcquireResourceExclusiveLite(
&RfsdGlobal->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) {
KdPrint(("RfsdCheckDismount: force dismount ...\n"));
}
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 );
}
RfsdRemoveVcb(Vcb);
ClearFlag(Vpb->Flags, VPB_MOUNTED);
SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
Vpb->DeviceObject = NULL;
bDeleted = TRUE;
}
IoReleaseVpbSpinLock(Irql);
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread() );
ExReleaseResourceForThreadLite(
&RfsdGlobal->Resource,
ExGetCurrentResourceThread() );
if (bDeleted) {
KdPrint(("RfsdCheckDismount: now free the vcb ...\n"));
RfsdFreeVcb(Vcb);
}
return bDeleted;
}
NTSTATUS
RfsdPurgeVolume (IN PRFSD_VCB Vcb,
IN BOOLEAN FlushBeforePurge )
{
PRFSD_FCB Fcb;
LIST_ENTRY FcbList;
PLIST_ENTRY ListEntry;
PFCB_LIST_ENTRY FcbListEntry;
__try {
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_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, RFSD_FCB, Next);
Fcb->ReferenceCount++;
RfsdPrint((DBG_INFO, "RfsdPurgeVolume: %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 {
RfsdPrint((DBG_ERROR, "RfsdPurgeVolume: 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 )) {
RfsdPurgeFile(Fcb, FlushBeforePurge);
if (!Fcb->OpenHandleCount && Fcb->ReferenceCount == 1) {
RemoveEntryList(&Fcb->Next);
RfsdFreeFcb(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);
}
RfsdPrint((DBG_INFO, "RfsdPurgeVolume: Volume flushed and purged.\n"));
} __finally {
// Nothing
}
return STATUS_SUCCESS;
}
NTSTATUS
RfsdPurgeFile ( IN PRFSD_FCB Fcb,
IN BOOLEAN FlushBeforePurge )
{
IO_STATUS_BLOCK IoStatus;
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
(Fcb->Identifier.Size == sizeof(RFSD_FCB)));
if( !IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) && FlushBeforePurge &&
!IsFlagOn(Fcb->Vcb->Flags, VCB_WRITE_PROTECTED)) {
RfsdPrint((DBG_INFO, "RfsdPurgeFile: 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) {
RfsdPrint((DBG_INFO, "RfsdPurgeFile: MmFlushImageSection on %s.\n",
Fcb->AnsiFileName.Buffer));
MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
}
if (Fcb->SectionObject.DataSectionObject) {
RfsdPrint((DBG_INFO, "RfsdPurgeFile: CcPurgeCacheSection on %s.\n",
Fcb->AnsiFileName.Buffer));
CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);
}
return STATUS_SUCCESS;
}
NTSTATUS
RfsdFileSystemControl (IN PRFSD_IRP_CONTEXT IrpContext)
{
NTSTATUS Status;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
switch (IrpContext->MinorFunction) {
case IRP_MN_USER_FS_REQUEST:
Status = RfsdUserFsRequest(IrpContext);
break;
case IRP_MN_MOUNT_VOLUME:
Status = RfsdMountVolume(IrpContext);
break;
case IRP_MN_VERIFY_VOLUME:
Status = RfsdVerifyVolume(IrpContext);
break;
default:
RfsdPrint((DBG_ERROR, "RfsdFilsSystemControl: Invalid Device Request.\n"));
Status = STATUS_INVALID_DEVICE_REQUEST;
RfsdCompleteIrpContext(IrpContext, Status);
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -