📄 fsctl.c
字号:
}
return Status;
}
NTSTATUS
FFSInvalidateVolumes(
IN PFFS_IRP_CONTEXT IrpContext)
{
NTSTATUS Status;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
HANDLE Handle;
PLIST_ENTRY ListEntry;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
BOOLEAN GlobalResourceAcquired = FALSE;
LUID Privilege = {SE_TCB_PRIVILEGE, 0};
__try
{
Irp = IrpContext->Irp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
if (!SeSinglePrivilegeCheck(Privilege, Irp->RequestorMode))
{
Status = STATUS_PRIVILEGE_NOT_HELD;
__leave;
}
if (
#ifndef _GNU_NTIFS_
IrpSp->Parameters.FileSystemControl.InputBufferLength
#else
((PEXTENDED_IO_STACK_LOCATION)(IrpSp))->
Parameters.FileSystemControl.InputBufferLength
#endif
!= sizeof(HANDLE))
{
Status = STATUS_INVALID_PARAMETER;
__leave;
}
Handle = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer;
Status = ObReferenceObjectByHandle(Handle,
0,
*IoFileObjectType,
KernelMode,
&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
__leave;
}
else
{
ObDereferenceObject(FileObject);
DeviceObject = FileObject->DeviceObject;
}
FFSPrint((DBG_INFO, "FFSInvalidateVolumes: FileObject=%xh ...\n", FileObject));
ExAcquireResourceExclusiveLite(
&FFSGlobal->Resource,
TRUE);
GlobalResourceAcquired = TRUE;
ListEntry = FFSGlobal->VcbList.Flink;
while (ListEntry != &FFSGlobal->VcbList)
{
PFFS_VCB Vcb;
Vcb = CONTAINING_RECORD(ListEntry, FFS_VCB, Next);
ListEntry = ListEntry->Flink;
FFSPrint((DBG_INFO, "FFSInvalidateVolumes: Vcb=%xh Vcb->Vpb=%xh...\n", Vcb, Vcb->Vpb));
if (Vcb->Vpb && (Vcb->Vpb->RealDevice == DeviceObject))
{
ExAcquireResourceExclusive(&Vcb->MainResource, TRUE);
FFSPrint((DBG_INFO, "FFSInvalidateVolumes: FFSPurgeVolume...\n"));
FFSPurgeVolume(Vcb, FALSE);
ClearFlag(Vcb->Flags, VCB_MOUNTED);
ExReleaseResource(&Vcb->MainResource);
//
// Vcb is still attached on the list ......
//
if (ListEntry->Blink == &Vcb->Next)
{
FFSPrint((DBG_INFO, "FFSInvalidateVolumes: FFSCheckDismount...\n"));
FFSCheckDismount(IrpContext, Vcb, FALSE);
}
}
}
}
__finally
{
if (GlobalResourceAcquired)
{
ExReleaseResourceForThreadLite(
&FFSGlobal->Resource,
ExGetCurrentResourceThread());
}
FFSCompleteIrpContext(IrpContext, Status);
}
return Status;
}
NTSTATUS
FFSAllowExtendedDasdIo(
IN PFFS_IRP_CONTEXT IrpContext)
{
PIO_STACK_LOCATION IrpSp;
PFFS_VCB Vcb;
PFFS_CCB Ccb;
IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
Vcb = (PFFS_VCB)IrpSp->FileObject->FsContext;
Ccb = (PFFS_CCB)IrpSp->FileObject->FsContext2;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
ASSERT(IsMounted(Vcb));
if (Ccb)
{
SetFlag(Ccb->Flags, CCB_ALLOW_EXTENDED_DASD_IO);
FFSCompleteIrpContext(IrpContext, STATUS_SUCCESS);
return STATUS_SUCCESS;
}
else
{
return STATUS_INVALID_PARAMETER;
}
}
NTSTATUS
FFSUserFsRequest(
IN PFFS_IRP_CONTEXT IrpContext)
{
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
ULONG FsControlCode;
NTSTATUS Status;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
Irp = IrpContext->Irp;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
#ifndef _GNU_NTIFS_
FsControlCode =
IoStackLocation->Parameters.FileSystemControl.FsControlCode;
#else
FsControlCode = ((PEXTENDED_IO_STACK_LOCATION)
IoStackLocation)->Parameters.FileSystemControl.FsControlCode;
#endif
switch (FsControlCode)
{
case FSCTL_LOCK_VOLUME:
Status = FFSLockVolume(IrpContext);
break;
case FSCTL_UNLOCK_VOLUME:
Status = FFSUnlockVolume(IrpContext);
break;
case FSCTL_DISMOUNT_VOLUME:
Status = FFSDismountVolume(IrpContext);
break;
case FSCTL_IS_VOLUME_MOUNTED:
Status = FFSIsVolumeMounted(IrpContext);
break;
case FSCTL_INVALIDATE_VOLUMES:
Status = FFSInvalidateVolumes(IrpContext);
break;
#if (_WIN32_WINNT >= 0x0500)
case FSCTL_ALLOW_EXTENDED_DASD_IO:
Status = FFSAllowExtendedDasdIo(IrpContext);
break;
#endif //(_WIN32_WINNT >= 0x0500)
default:
FFSPrint((DBG_ERROR, "FFSUserFsRequest: Invalid User Request: %xh.\n", FsControlCode));
Status = STATUS_INVALID_DEVICE_REQUEST;
FFSCompleteIrpContext(IrpContext, Status);
}
return Status;
}
BOOLEAN
FFSIsMediaWriteProtected(
IN PFFS_IRP_CONTEXT IrpContext,
IN PDEVICE_OBJECT TargetDevice)
{
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_IS_WRITABLE,
TargetDevice,
NULL,
0,
NULL,
0,
FALSE,
&Event,
&IoStatus);
if (Irp == NULL)
{
return FALSE;
}
SetFlag(IoGetNextIrpStackLocation(Irp)->Flags, SL_OVERRIDE_VERIFY_VOLUME);
Status = IoCallDriver(TargetDevice, Irp);
if (Status == STATUS_PENDING)
{
(VOID) KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
(PLARGE_INTEGER)NULL);
Status = IoStatus.Status;
}
return (BOOLEAN)(Status == STATUS_MEDIA_WRITE_PROTECTED);
}
NTSTATUS
FFSMountVolume(
IN PFFS_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT MainDeviceObject;
BOOLEAN GlobalDataResourceAcquired = FALSE;
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
PDEVICE_OBJECT TargetDeviceObject;
NTSTATUS Status = STATUS_UNRECOGNIZED_VOLUME;
PDEVICE_OBJECT VolumeDeviceObject = NULL;
PFFS_VCB Vcb;
PFFS_SUPER_BLOCK FFSSb = NULL;
ULONG dwBytes;
DISK_GEOMETRY DiskGeometry;
__try
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
MainDeviceObject = IrpContext->DeviceObject;
//
// Make sure we can wait.
//
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
//
// This request is only allowed on the main device object
//
if (MainDeviceObject != FFSGlobal->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
ExAcquireResourceExclusiveLite(
&(FFSGlobal->Resource),
TRUE);
GlobalDataResourceAcquired = TRUE;
if (FlagOn(FFSGlobal->Flags, FFS_UNLOAD_PENDING))
{
Status = STATUS_UNRECOGNIZED_VOLUME;
__leave;
}
Irp = IrpContext->Irp;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
TargetDeviceObject =
IoStackLocation->Parameters.MountVolume.DeviceObject;
dwBytes = sizeof(DISK_GEOMETRY);
Status = FFSDiskIoControl(
TargetDeviceObject,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
&dwBytes);
if (!NT_SUCCESS(Status))
{
__leave;
}
Status = IoCreateDevice(
MainDeviceObject->DriverObject,
sizeof(FFS_VCB),
NULL,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&VolumeDeviceObject);
if (!NT_SUCCESS(Status))
{
__leave;
}
VolumeDeviceObject->StackSize = (CCHAR)(TargetDeviceObject->StackSize + 1);
if (TargetDeviceObject->AlignmentRequirement >
VolumeDeviceObject->AlignmentRequirement)
{
VolumeDeviceObject->AlignmentRequirement =
TargetDeviceObject->AlignmentRequirement;
}
(IoStackLocation->Parameters.MountVolume.Vpb)->DeviceObject =
VolumeDeviceObject;
Vcb = (PFFS_VCB)VolumeDeviceObject->DeviceExtension;
RtlZeroMemory(Vcb, sizeof(FFS_VCB));
Vcb->Identifier.Type = FFSVCB;
Vcb->Identifier.Size = sizeof(FFS_VCB);
Vcb->TargetDeviceObject = TargetDeviceObject;
Vcb->DiskGeometry = DiskGeometry;
Status = FFSLoadDiskLabel(TargetDeviceObject, Vcb);
if (!NT_SUCCESS(Status))
{
__leave;
}
FFSSb = Vcb->ffs_super_block;
Vcb->BlockSize = FFSSb->fs_bsize;
Vcb->SectorBits = FFSLog2(SECTOR_SIZE);
Status = FFSInitializeVcb(IrpContext, Vcb, FFSSb, TargetDeviceObject,
VolumeDeviceObject, IoStackLocation->Parameters.MountVolume.Vpb);
if (NT_SUCCESS(Status))
{
if (FFSIsMediaWriteProtected(IrpContext, TargetDeviceObject))
{
SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
}
else
{
ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
}
SetFlag(Vcb->Flags, VCB_MOUNTED);
FFSInsertVcb(Vcb);
ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
}
}
__finally
{
if (GlobalDataResourceAcquired)
{
ExReleaseResourceForThreadLite(
&FFSGlobal->Resource,
ExGetCurrentResourceThread());
}
if (!NT_SUCCESS(Status))
{
if (FFSSb)
{
ExFreePool(FFSSb);
}
if (VolumeDeviceObject)
{
IoDeleteDevice(VolumeDeviceObject);
}
}
if (!IrpContext->ExceptionInProgress)
{
if (NT_SUCCESS(Status))
{
ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
}
FFSCompleteIrpContext(IrpContext, Status);
}
}
return Status;
}
NTSTATUS
FFSVerifyVolume(
IN PFFS_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PFFS_SUPER_BLOCK FFSSb = NULL;
PFFS_VCB Vcb;
BOOLEAN VcbResourceAcquired = FALSE;
BOOLEAN GlobalResourceAcquired = FALSE;
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
ULONG ChangeCount;
ULONG dwReturn;
__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;
}
ExAcquireResourceExclusiveLite(
&FFSGlobal->Resource,
TRUE);
GlobalResourceAcquired = TRUE;
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE);
VcbResourceAcquired = TRUE;
if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME))
{
Status = STATUS_SUCCESS;
__leave;
}
if (!IsMounted(Vcb))
{
Status = STATUS_WRONG_VOLUME;
__leave;
}
dwReturn = sizeof(ULONG);
Status = FFSDiskIoControl(
Vcb->TargetDeviceObject,
IOCTL_DISK_CHECK_VERIFY,
NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -