⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsctl.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 3 页
字号:

                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 + -