📄 fsctl.c
字号:
if (ListEntry->Blink == &Vcb->Next)
{
RfsdPrint((DBG_INFO, "RfsdInvalidateVolumes: RfsdCheckDismount...\n"));
RfsdCheckDismount(IrpContext, Vcb, FALSE);
}
}
}
} __finally {
if (GlobalResourceAcquired) {
ExReleaseResourceForThreadLite(
&RfsdGlobal->Resource,
ExGetCurrentResourceThread() );
}
RfsdCompleteIrpContext(IrpContext, Status);
}
return Status;
}
NTSTATUS
RfsdAllowExtendedDasdIo(IN PRFSD_IRP_CONTEXT IrpContext)
{
PIO_STACK_LOCATION IrpSp;
PRFSD_VCB Vcb;
PRFSD_CCB Ccb;
IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
Vcb = (PRFSD_VCB) IrpSp->FileObject->FsContext;
Ccb = (PRFSD_CCB) IrpSp->FileObject->FsContext2;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_VCB)));
ASSERT(IsMounted(Vcb));
if (Ccb) {
SetFlag(Ccb->Flags, CCB_ALLOW_EXTENDED_DASD_IO);
RfsdCompleteIrpContext(IrpContext, STATUS_SUCCESS);
return STATUS_SUCCESS;
} else {
return STATUS_INVALID_PARAMETER;
}
}
NTSTATUS
RfsdUserFsRequest (IN PRFSD_IRP_CONTEXT IrpContext)
{
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
ULONG FsControlCode;
NTSTATUS Status;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_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 = RfsdLockVolume(IrpContext);
break;
case FSCTL_UNLOCK_VOLUME:
Status = RfsdUnlockVolume(IrpContext);
break;
case FSCTL_DISMOUNT_VOLUME:
Status = RfsdDismountVolume(IrpContext);
break;
case FSCTL_IS_VOLUME_MOUNTED:
Status = RfsdIsVolumeMounted(IrpContext);
break;
case FSCTL_INVALIDATE_VOLUMES:
Status = RfsdInvalidateVolumes(IrpContext);
break;
#if (_WIN32_WINNT >= 0x0500)
case FSCTL_ALLOW_EXTENDED_DASD_IO:
Status = RfsdAllowExtendedDasdIo(IrpContext);
break;
#endif //(_WIN32_WINNT >= 0x0500)
default:
RfsdPrint((DBG_ERROR, "RfsdUserFsRequest: Invalid User Request: %xh.\n", FsControlCode));
Status = STATUS_INVALID_DEVICE_REQUEST;
RfsdCompleteIrpContext(IrpContext, Status);
}
return Status;
}
BOOLEAN
RfsdIsMediaWriteProtected (
IN PRFSD_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
RfsdMountVolume (IN PRFSD_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;
PRFSD_VCB Vcb;
PRFSD_SUPER_BLOCK RfsdSb = NULL;
ULONG dwBytes;
DISK_GEOMETRY DiskGeometry;
__try {
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_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 != RfsdGlobal->DeviceObject) {
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
ExAcquireResourceExclusiveLite(
&(RfsdGlobal->Resource),
TRUE );
GlobalDataResourceAcquired = TRUE;
if (FlagOn(RfsdGlobal->Flags, RFSD_UNLOAD_PENDING)) {
Status = STATUS_UNRECOGNIZED_VOLUME;
__leave;
}
Irp = IrpContext->Irp;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
TargetDeviceObject =
IoStackLocation->Parameters.MountVolume.DeviceObject;
dwBytes = sizeof(DISK_GEOMETRY);
Status = RfsdDiskIoControl(
TargetDeviceObject,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
&dwBytes );
if (!NT_SUCCESS(Status)) {
__leave;
}
Status = IoCreateDevice(
MainDeviceObject->DriverObject,
sizeof(RFSD_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 = (PRFSD_VCB) VolumeDeviceObject->DeviceExtension;
RtlZeroMemory(Vcb, sizeof(RFSD_VCB));
Vcb->Identifier.Type = RFSDVCB;
Vcb->Identifier.Size = sizeof(RFSD_VCB);
Vcb->TargetDeviceObject = TargetDeviceObject;
Vcb->DiskGeometry = DiskGeometry;
RfsdSb = RfsdLoadSuper(Vcb, FALSE);
if (RfsdSb) {
if ( SuperblockContainsMagicKey(RfsdSb) ) {
RfsdPrint((DBG_INFO, "Volume of ReiserFS rfsd file system is found.\n"));
Status = STATUS_SUCCESS;
} else {
Status = STATUS_UNRECOGNIZED_VOLUME;
}
}
if (!NT_SUCCESS(Status)) {
__leave;
}
Vcb->BlockSize = RfsdSb->s_blocksize; // NOTE: FFS also does this here, since LoadGroup is not called in the non-ext2 drivers
Vcb->GroupDesc = NULL; // NOTE: GroupDesc is not used for ReiserFS. Setting it to NULL will keep other code from barfing.
// Vcb->SectorBits = RFSDLog(SECTOR_SIZE); // NOTE: SectorBits are unused for ReiserFS
Status = RfsdInitializeVcb(IrpContext, Vcb, RfsdSb, TargetDeviceObject,
VolumeDeviceObject, IoStackLocation->Parameters.MountVolume.Vpb);
if (NT_SUCCESS(Status)) {
if (RfsdIsMediaWriteProtected(IrpContext, TargetDeviceObject)) {
SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
} else {
ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
}
SetFlag(Vcb->Flags, VCB_MOUNTED);
RfsdInsertVcb(Vcb);
ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
}
} __finally {
if (GlobalDataResourceAcquired) {
ExReleaseResourceForThreadLite(
&RfsdGlobal->Resource,
ExGetCurrentResourceThread() );
}
if (!NT_SUCCESS(Status)) {
if (RfsdSb) {
ExFreePool(RfsdSb);
}
if (VolumeDeviceObject) {
IoDeleteDevice(VolumeDeviceObject);
}
}
if (!IrpContext->ExceptionInProgress) {
if (NT_SUCCESS(Status)) {
ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
}
RfsdCompleteIrpContext(IrpContext, Status);
}
}
return Status;
}
NTSTATUS
RfsdVerifyVolume (IN PRFSD_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PRFSD_SUPER_BLOCK rfsd_sb = NULL;
PRFSD_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 == 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;
}
ExAcquireResourceExclusiveLite(
&RfsdGlobal->Resource,
TRUE );
GlobalResourceAcquired = TRUE;
Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_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 = RfsdDiskIoControl(
Vcb->TargetDeviceObject,
IOCTL_DISK_CHECK_VERIFY,
NULL,
0,
&ChangeCount,
&dwReturn );
if (ChangeCount != Vcb->ChangeCount) {
Status = STATUS_WRONG_VOLUME;
__leave;
}
Irp = IrpContext->Irp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -