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; }
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; }
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; }