Beispiel #1
0
NTSTATUS
NTAPI
FsRecVfatFsControl(IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp)
{
    PIO_STACK_LOCATION Stack;
    NTSTATUS Status;
    PDEVICE_OBJECT MountDevice;
    PPACKED_BOOT_SECTOR Bpb = NULL;
    ULONG SectorSize;
    LARGE_INTEGER Offset = {{0, 0}};
    BOOLEAN DeviceError = FALSE;
    PAGED_CODE();

    /* Get the I/O Stack and check the function type */
    Stack = IoGetCurrentIrpStackLocation(Irp);
    switch (Stack->MinorFunction)
    {
        case IRP_MN_MOUNT_VOLUME:

            /* Assume failure */
            Status = STATUS_UNRECOGNIZED_VOLUME;

            /* Get the device object and request the sector size */
            MountDevice = Stack->Parameters.MountVolume.DeviceObject;
            if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize))
            {
                /* Try to read the BPB */
                if (FsRecReadBlock(MountDevice,
                                   &Offset,
                                   512,
                                   SectorSize,
                                   (PVOID)&Bpb,
                                   &DeviceError))
                {
                    /* Check if it's an actual FAT volume */
                    if (FsRecIsFatVolume(Bpb))
                    {
                        /* It is! */
                        Status = STATUS_FS_DRIVER_REQUIRED;
                    }
                }

                /* Free the boot sector if we have one */
                ExFreePool(Bpb);
            }
            else
            {
                /* We have some sort of failure in the storage stack */
                DeviceError = TRUE;
            }

            /* Check if we have an error on the stack */
            if (DeviceError)
            {
                /* Was this because of a floppy? */
                if (MountDevice->Characteristics & FILE_FLOPPY_DISKETTE)
                {
                    /* Let the FS try anyway */
                    Status = STATUS_FS_DRIVER_REQUIRED;
                }
            }

            break;

        case IRP_MN_LOAD_FILE_SYSTEM:

            /* Load the file system */
            Status = FsRecLoadFileSystem(DeviceObject,
                                         L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\fastfat");
            break;

        default:

            /* Invalid request */
            Status = STATUS_INVALID_DEVICE_REQUEST;
    }

    /* Return Status */
    return Status;
}
Beispiel #2
0
BOOLEAN
IsUdfsVolume (
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONG SectorSize
    )

/*++

Routine Description:

    This routine walks the Volume Recognition Sequence to determine
    whether this volume contains an NSR02 (ISO 13346 Section 4) image.
    
    Note: this routine is pretty much diked out of UdfsRecognizeVolume
    in the real filesystem, modulo fitting it into the fs recognizer.

Arguments:

    DeviceObject - device we are checking

    SectorSize - size of a physical sector on this device

Return Value:

    Boolean TRUE if we found NSR02, FALSE otherwise.

--*/

{
    BOOLEAN FoundNSR = FALSE;

    BOOLEAN FoundBEA = FALSE;
    BOOLEAN Resolved = FALSE;

    PVSD_GENERIC VolumeStructureDescriptor = NULL;
    ULONGLONG Offset = SectorAlignN( SectorSize, VRA_BOUNDARY_LOCATION );

    PAGED_CODE();

    DebugTrace(( +1, Dbg,
                 "IsUdfsVolume, DevObj %08x SectorSize %08x\n",
                 DeviceObject,
                 SectorSize ));

    while (!Resolved) {
    
        if (!FsRecReadBlock( DeviceObject,
                             (PLARGE_INTEGER)&Offset,
                             sizeof(VSD_GENERIC),
                             SectorSize,
                             (PVOID) &VolumeStructureDescriptor,
                             NULL )) {

            break;
        }
    
        //
        //  Now check the type of the descriptor. All ISO 13346 VSDs are
        //  of Type 0, 9660 PVDs are Type 1, 9660 SVDs are Type 2, and 9660
        //  terminating descriptors are Type 255.
        //
    
        if (VolumeStructureDescriptor->Type == 0) {

            //
            //  In order to properly recognize the volume, we must know all of the
            //  Structure identifiers in ISO 13346 so that we can terminate if a
            //  badly formatted (or, shockingly, non 13346) volume is presented to us.
            //

            switch (UdfsFindInParseTable( VsdIdentParseTable,
                                         VolumeStructureDescriptor->Ident,
                                         VSD_LENGTH_IDENT )) {
                case VsdIdentBEA01:

                    //
                    //  Only one BEA may exist and its version must be 1 (2/9.2.3)
                    //

                    DebugTrace(( 0, Dbg, "IsUdfsVolume, got a BEA01\n" ));


                    if ((FoundBEA &&
                         DebugTrace(( 0, Dbg,
                                      "IsUdfsVolume, ... but it is a duplicate!\n" ))) ||

                        (VolumeStructureDescriptor->Version != 1 &&
                         DebugTrace(( 0, Dbg,
                                      "IsUdfsVolume, ... but it has a wacky version number %02x != 1!\n",
                                      VolumeStructureDescriptor->Version )))) {

                        Resolved = TRUE;
                        break;
                    }

                    FoundBEA = TRUE;
                    break;

                case VsdIdentTEA01:

                    //
                    //  If we reach the TEA it must be the case that we don't recognize
                    //

                    DebugTrace(( 0, Dbg, "IsUdfsVolume, got a TEA01\n" ));

                    Resolved = TRUE;
                    break;

                case VsdIdentNSR02:

                    //
                    //  We recognize NSR02 version 1 embedded after a BEA (3/9.1.3).  For
                    //  simplicity we will not bother being a complete nitpick and check
                    //  for a bounding TEA, although we will be optimistic in the case where
                    //  we fail to match the version.
                    //

                    DebugTrace(( 0, Dbg, "IsUdfsVolume, got an NSR02\n" ));

                    if ((FoundBEA ||
                         !DebugTrace(( 0, Dbg, "IsUdfsVolume, ... but we haven't seen a BEA01 yet!\n" ))) &&

                        (VolumeStructureDescriptor->Version == 1 ||
                         !DebugTrace(( 0, Dbg, "IsUdfsVolume, ... but it has a wacky version number %02x != 1\n",
                                       VolumeStructureDescriptor->Version )))) {

                        FoundNSR = Resolved = TRUE;
                        break;
                    }

                    break;

                case VsdIdentCD001:
                case VsdIdentCDW01:
                case VsdIdentNSR01:
                case VsdIdentCDW02:
                case VsdIdentBOOT2:

                    DebugTrace(( 0, Dbg, "IsUdfsVolume, got a valid but uninteresting 13346 descriptor\n" ));

                    //
                    //  Valid but uninteresting (to us) descriptors
                    //

                    break;

                default:

                    DebugTrace(( 0, Dbg, "IsUdfsVolume, got an invalid 13346 descriptor\n" ));

                    //
                    //  Stumbling across something we don't know, it must be that this
                    //  is not a valid 13346 image
                    //

                    Resolved = TRUE;
                    break;

            }

        } else if (!FoundBEA && (VolumeStructureDescriptor->Type < 3 ||
                                 VolumeStructureDescriptor->Type == 255)) {

            DebugTrace(( 0, Dbg, "IsUdfsVolume, got a 9660 descriptor\n" ));

            //
            //  Only HSG (CDROM) and 9660 (CD001) are possible, and they are only legal
            //  before the ISO 13346 BEA/TEA extent.  By design, an ISO 13346 VSD precisely
            //  overlaps a 9660 PVD/SVD in the appropriate fields.
            //
            //  Note that we aren't being strict about the structure of the 9660 descriptors
            //  since that really isn't very interesting.  We care more about the 13346.
            //  
            //

            switch (UdfsFindInParseTable( VsdIdentParseTable,
                                          VolumeStructureDescriptor->Ident,
                                          VSD_LENGTH_IDENT )) {
                case VsdIdentCDROM:
                case VsdIdentCD001:

                    DebugTrace(( 0, Dbg, "IsUdfsVolume, ... seems we have 9660 here\n" ));

                    //
                    //  Note to our caller that we seem to have ISO 9660 here
                    //

                    break;

                default:

                    DebugTrace(( 0, Dbg, "IsUdfsVolume, ... but it looks wacky\n" ));

                    //
                    //  This probably was a false alert, but in any case there is nothing
                    //  on this volume for us.
                    //

                    Resolved = TRUE;
                    break;
            }

        } else {

            //
            //  Something else must be recorded on this volume.
            //

            DebugTrace(( 0, Dbg, "IsUdfsVolume, got an unrecognizeable descriptor, probably not 13346/9660\n" ));
            break;
        }

        //
        //  Align our next read with the sector following the current descriptor
        //

        Offset += SectorAlignN( SectorSize, sizeof(VSD_GENERIC) );
    }

    DebugTrace(( -1, Dbg, "IsUdfsVolume -> %c\n", ( FoundNSR ? 'T' : 'F' )));

    //
    //  Free up our temporary buffer
    //

    if (VolumeStructureDescriptor) {
    
        ExFreePool( VolumeStructureDescriptor );
    }

    return FoundNSR;
}
Beispiel #3
0
NTSTATUS
NTAPI
FsRecNtfsFsControl(IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp)
{
    PIO_STACK_LOCATION Stack;
    NTSTATUS Status;
    PDEVICE_OBJECT MountDevice;
    PPACKED_BOOT_SECTOR Bpb = NULL;
    ULONG SectorSize;
    LARGE_INTEGER Offset = {{0, 0}}, Offset2, Offset3, SectorCount;
    PAGED_CODE();

    /* Get the I/O Stack and check the function type */
    Stack = IoGetCurrentIrpStackLocation(Irp);
    switch (Stack->MinorFunction)
    {
        case IRP_MN_MOUNT_VOLUME:

            /* Assume failure */
            Status = STATUS_UNRECOGNIZED_VOLUME;

            /* Get the device object and request the sector size */
            MountDevice = Stack->Parameters.MountVolume.DeviceObject;
            if ((FsRecGetDeviceSectorSize(MountDevice, &SectorSize)) &&
                (FsRecGetDeviceSectors(MountDevice, SectorSize, &SectorCount)))
            {
                /* Setup other offsets to try */
                Offset2.QuadPart = SectorCount.QuadPart >> 1;
                Offset2.QuadPart *= SectorSize;
                Offset3.QuadPart = (SectorCount.QuadPart - 1) * SectorSize;

                /* Try to read the BPB */
                if (FsRecReadBlock(MountDevice,
                                   &Offset,
                                   512,
                                   SectorSize,
                                   (PVOID)&Bpb,
                                   NULL))
                {
                    /* Check if it's an actual NTFS volume */
                    if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
                    {
                        /* It is! */
                        Status = STATUS_FS_DRIVER_REQUIRED;
                    }
                }
                else if (FsRecReadBlock(MountDevice,
                                        &Offset2,
                                        512,
                                        SectorSize,
                                        (PVOID)&Bpb,
                                        NULL))
                {
                    /* Check if it's an actual NTFS volume */
                    if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
                    {
                        /* It is! */
                        Status = STATUS_FS_DRIVER_REQUIRED;
                    }
                }
                else if (FsRecReadBlock(MountDevice,
                                        &Offset3,
                                        512,
                                        SectorSize,
                                        (PVOID)&Bpb,
                                        NULL))
                {
                    /* Check if it's an actual NTFS volume */
                    if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
                    {
                        /* It is! */
                        Status = STATUS_FS_DRIVER_REQUIRED;
                    }
                }

                /* Free the boot sector if we have one */
                ExFreePool(Bpb);
            }
            break;

        case IRP_MN_LOAD_FILE_SYSTEM:

            /* Load the file system */
            Status = FsRecLoadFileSystem(DeviceObject,
                                         L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Ntfs");
            break;

        default:

            /* Invalid request */
            Status = STATUS_INVALID_DEVICE_REQUEST;
    }