📄 fsctl.c
字号:
0,
FALSE,
&VolumeDeviceObject
);
if (!NT_SUCCESS(Status))
{
__leave;
}
VolumeDeviceObject->StackSize = TargetDeviceObject->StackSize;
(IrpSp->Parameters.MountVolume.Vpb)->DeviceObject = VolumeDeviceObject;
Vcb = (PFSD_VCB) VolumeDeviceObject->DeviceExtension;
RtlZeroMemory(Vcb, sizeof(FSD_VCB));
Vcb->Identifier.Type = VCB;
Vcb->Identifier.Size = sizeof(FSD_VCB);
ExInitializeResourceLite(&Vcb->MainResource);
ExInitializeResourceLite(&Vcb->PagingIoResource);
VcbResourceInitialized = TRUE;
Vcb->Vpb = IrpSp->Parameters.MountVolume.Vpb;
InitializeListHead(&Vcb->FcbList);
InitializeListHead(&Vcb->NotifyList);
FsRtlNotifyInitializeSync(&Vcb->NotifySync);
NotifySyncInitialized = TRUE;
Vcb->DeviceObject = VolumeDeviceObject;
Vcb->TargetDeviceObject = TargetDeviceObject;
Vcb->OpenFileHandleCount = 0;
Vcb->ReferenceCount = 0;
Vcb->Flags = 0;
Vcb->romfs_super_block = romfs_super_block =
(struct romfs_super_block *)
FsdAllocatePool(NonPagedPool, SECTOR_SIZE, 'puSR');
if (!romfs_super_block)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
Offset.QuadPart = 0;
Status = FsdReadBlockDevice(
TargetDeviceObject,
&Offset,
SECTOR_SIZE,
romfs_super_block
);
if (!NT_SUCCESS(Status))
{
__leave;
}
VolumeLabelLength = (USHORT) strnlen(
Vcb->romfs_super_block->name,
ROMFS_MAXFN
);
if (VolumeLabelLength > MAXIMUM_VOLUME_LABEL_LENGTH / 2)
{
VolumeLabelLength = MAXIMUM_VOLUME_LABEL_LENGTH / 2;
}
Vcb->Vpb->VolumeLabelLength = VolumeLabelLength * 2;
FsdCharToWchar(
Vcb->Vpb->VolumeLabel,
Vcb->romfs_super_block->name,
VolumeLabelLength
);
Vcb->Vpb->SerialNumber = be32_to_cpu(Vcb->romfs_super_block->checksum);
Vcb->root_inode_number = (ROMFH_SIZE +
strnlen(Vcb->romfs_super_block->name, ROMFS_MAXFN)
+ 1 + ROMFH_PAD) & ROMFH_MASK;
Vcb->root_inode_number = cpu_to_be32(Vcb->root_inode_number);
Inode = FsdAllocatePool(
NonPagedPool,
sizeof(struct romfs_inode) + ROMFS_MAXFN,
'niRR'
);
if (Inode == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
Status = FsdReadInodeByIndex(
TargetDeviceObject,
Vcb->root_inode_number,
Inode
);
if (!NT_SUCCESS(Status))
{
__leave;
}
Vcb->root_inode = Inode;
IoctlSize = sizeof(DISK_GEOMETRY);
Status = FsdBlockDeviceIoControl(
TargetDeviceObject,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&Vcb->DiskGeometry,
&IoctlSize
);
if (!NT_SUCCESS(Status))
{
__leave;
}
IoctlSize = sizeof(PARTITION_INFORMATION);
Status = FsdBlockDeviceIoControl(
TargetDeviceObject,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&Vcb->PartitionInformation,
&IoctlSize
);
if (!NT_SUCCESS(Status))
{
Vcb->PartitionInformation.StartingOffset.QuadPart = 0;
Vcb->PartitionInformation.PartitionLength.QuadPart =
Vcb->DiskGeometry.Cylinders.QuadPart *
Vcb->DiskGeometry.TracksPerCylinder *
Vcb->DiskGeometry.SectorsPerTrack *
Vcb->DiskGeometry.BytesPerSector;
Status = STATUS_SUCCESS;
}
InsertTailList(&FsdGlobalData.VcbList, &Vcb->Next);
}
__finally
{
if (GlobalDataResourceAcquired)
{
ExReleaseResourceForThreadLite(
&FsdGlobalData.Resource,
ExGetCurrentResourceThread()
);
}
if (!NT_SUCCESS(Status))
{
if (Inode)
{
FsdFreePool(Inode);
}
if (romfs_super_block)
{
FsdFreePool(romfs_super_block);
}
if (NotifySyncInitialized)
{
FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
}
if (VcbResourceInitialized)
{
ExDeleteResourceLite(&Vcb->MainResource);
ExDeleteResourceLite(&Vcb->PagingIoResource);
}
if (VolumeDeviceObject)
{
IoDeleteDevice(VolumeDeviceObject);
}
}
if (!AbnormalTermination())
{
if (NT_SUCCESS(Status))
{
ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
}
IrpContext->Irp->IoStatus.Status = Status;
FsdCompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
FsdFreeIrpContext(IrpContext);
}
}
return Status;
}
#pragma code_seg() // end FSD_PAGED_CODE
NTSTATUS
FsdVerifyVolume (
IN PFSD_IRP_CONTEXT IrpContext
)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PFSD_VCB Vcb;
BOOLEAN VcbResourceAcquired = FALSE;
PIRP Irp;
__try
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == ICX) &&
(IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
if (DeviceObject == FsdGlobalData.DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
Vcb = (PFSD_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == VCB) &&
(Vcb->Identifier.Size == sizeof(FSD_VCB)));
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE
);
VcbResourceAcquired = TRUE;
if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME))
{
Status = STATUS_SUCCESS;
__leave;
}
Irp = IrpContext->Irp;
Status = FsdIsDeviceSameRomfs(
Vcb->TargetDeviceObject,
be32_to_cpu(Vcb->romfs_super_block->checksum)
);
if (NT_SUCCESS(Status))
{
ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
KdPrint((DRIVER_NAME ": Volume verify succeeded\n"));
__leave;
}
else
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
VcbResourceAcquired = FALSE;
FsdPurgeVolume(Vcb, FALSE);
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE
);
VcbResourceAcquired = TRUE;
SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
KdPrint((DRIVER_NAME ": Volume verify failed\n"));
__leave;
}
}
__finally
{
if (VcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (!AbnormalTermination())
{
IrpContext->Irp->IoStatus.Status = Status;
FsdCompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
FsdFreeIrpContext(IrpContext);
}
}
return Status;
}
#pragma code_seg(FSD_PAGED_CODE)
typedef struct _FCB_LIST_ENTRY {
PFSD_FCB Fcb;
LIST_ENTRY Next;
} FCB_LIST_ENTRY, *PFCB_LIST_ENTRY;
VOID
FsdPurgeVolume (
IN PFSD_VCB Vcb,
IN BOOLEAN FlushBeforePurge
)
{
BOOLEAN VcbResourceAcquired = FALSE;
PFSD_FCB Fcb;
LIST_ENTRY FcbList;
PLIST_ENTRY ListEntry;
PFCB_LIST_ENTRY FcbListEntry;
__try
{
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == VCB) &&
(Vcb->Identifier.Size == sizeof(FSD_VCB)));
ExAcquireResourceSharedLite(
&Vcb->MainResource,
TRUE
);
VcbResourceAcquired = TRUE;
#ifndef FSD_RO
if (FlagOn(Vcb->Flags, VCB_READ_ONLY))
{
FlushBeforePurge = FALSE;
}
#endif
InitializeListHead(&FcbList);
for (
ListEntry = Vcb->FcbList.Flink;
ListEntry != &Vcb->FcbList;
ListEntry = ListEntry->Flink
)
{
Fcb = CONTAINING_RECORD(ListEntry, FSD_FCB, Next);
ExAcquireResourceExclusiveLite(
&Fcb->MainResource,
TRUE
);
Fcb->ReferenceCount++;
ExReleaseResourceForThreadLite(
&Fcb->MainResource,
ExGetCurrentResourceThread()
);
FcbListEntry = FsdAllocatePool(
NonPagedPool,
sizeof(FCB_LIST_ENTRY),
'1mTR'
);
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;
FsdPurgeFile(Fcb, FlushBeforePurge);
Fcb->ReferenceCount--;
if (!Fcb->ReferenceCount)
{
KdPrint(("FsdFreeFcb %s\n", Fcb->AnsiFileName.Buffer));
FsdFreeFcb(Fcb);
}
FsdFreePool(FcbListEntry);
}
KdPrint((DRIVER_NAME ": Volume flushed and purged\n"));
}
__finally
{
if (VcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
}
}
}
VOID
FsdPurgeFile (
IN PFSD_FCB Fcb,
IN BOOLEAN FlushBeforePurge
)
{
#ifndef FSD_RO
IO_STATUS_BLOCK IoStatus;
#endif
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == FCB) &&
(Fcb->Identifier.Size == sizeof(FSD_FCB)));
#ifndef FSD_RO
if (FlushBeforePurge)
{
KdPrint(("CcFlushCache on %s\n", Fcb->AnsiFileName.Buffer));
CcFlushCache(&Fcb->SectionObject, NULL, 0, &IoStatus);
}
#endif
if (Fcb->SectionObject.ImageSectionObject)
{
KdPrint(("MmFlushImageSection on %s\n", Fcb->AnsiFileName.Buffer));
MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
}
if (Fcb->SectionObject.DataSectionObject)
{
KdPrint(("CcPurgeCacheSection on %s\n", Fcb->AnsiFileName.Buffer));
CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);
}
}
#pragma code_seg() // end FSD_PAGED_CODE
VOID
FsdSetVpbFlag (
IN PVPB Vpb,
IN USHORT Flag
)
{
KIRQL OldIrql;
IoAcquireVpbSpinLock(&OldIrql);
Vpb->Flags |= Flag;
IoReleaseVpbSpinLock(OldIrql);
}
VOID
FsdClearVpbFlag (
IN PVPB Vpb,
IN USHORT Flag
)
{
KIRQL OldIrql;
IoAcquireVpbSpinLock(&OldIrql);
Vpb->Flags &= ~Flag;
IoReleaseVpbSpinLock(OldIrql);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -