NTSTATUS FatMount ( _In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY* FileEntry ) { BL_DEVICE_INFORMATION DeviceInformation; ULONG UnknownFlag; NTSTATUS Status; PACKED_BOOT_SECTOR FatBootSector; BIOS_PARAMETER_BLOCK BiosBlock; /* Capture thing */ BlDeviceGetInformation(DeviceId, &DeviceInformation); UnknownFlag = DeviceInformation.BlockDeviceInfo.Unknown; /* Set thing to 1 */ DeviceInformation.BlockDeviceInfo.Unknown |= 1; BlDeviceSetInformation(DeviceId, &DeviceInformation); /* Read the boot sector */ Status = BlDeviceReadAtOffset(DeviceId, sizeof(FatBootSector), 0, &FatBootSector, NULL); /* Restore thing back */ DeviceInformation.BlockDeviceInfo.Unknown = UnknownFlag; BlDeviceSetInformation(DeviceId, &DeviceInformation); if (!NT_SUCCESS(Status)) { EfiPrintf(L"Failed reading drive: %lx\r\n", Status); return Status; } FatUnpackBios(&BiosBlock, &FatBootSector.PackedBpb); /* For now, quickly fail if this isn't FAT */ if (FatBootSector.Jump[0] != 0xE9) { return STATUS_UNSUCCESSFUL; } EfiPrintf(L"Jump: %lx Bytes Per Sector: %d Sectors Per Cluster: %d Reserved: %d Fats: %d Sectors: %d Large Sectors: %d Media: %lx RootEntries: %d\r\n", FatBootSector.Jump[0], BiosBlock.BytesPerSector, BiosBlock.SectorsPerCluster, BiosBlock.ReservedSectors, BiosBlock.Fats, BiosBlock.Sectors, BiosBlock.LargeSectors, BiosBlock.Media, BiosBlock.RootEntries); return STATUS_NOT_IMPLEMENTED; }
BOOLEAN NTAPI FsRecIsFatVolume(IN PPACKED_BOOT_SECTOR PackedBootSector) { BIOS_PARAMETER_BLOCK Bpb; BOOLEAN Result = TRUE; PAGED_CODE(); RtlZeroMemory(&Bpb, sizeof(BIOS_PARAMETER_BLOCK)); /* Unpack the BPB and do a small fix up */ FatUnpackBios(&Bpb, &PackedBootSector->PackedBpb); if (Bpb.Sectors) Bpb.LargeSectors = 0; /* Recognize jump */ if ((PackedBootSector->Jump[0] != 0x49) && (PackedBootSector->Jump[0] != 0xE9) && (PackedBootSector->Jump[0] != 0xEB)) { /* Fail */ Result = FALSE; } else if ((Bpb.BytesPerSector != 128) && (Bpb.BytesPerSector != 256) && (Bpb.BytesPerSector != 512) && (Bpb.BytesPerSector != 1024) && (Bpb.BytesPerSector != 2048) && (Bpb.BytesPerSector != 4096)) { /* Fail */ Result = FALSE; } else if ((Bpb.SectorsPerCluster != 1) && (Bpb.SectorsPerCluster != 2) && (Bpb.SectorsPerCluster != 4) && (Bpb.SectorsPerCluster != 8) && (Bpb.SectorsPerCluster != 16) && (Bpb.SectorsPerCluster != 32) && (Bpb.SectorsPerCluster != 64) && (Bpb.SectorsPerCluster != 128)) { /* Fail */ Result = FALSE; } else if (!Bpb.ReservedSectors) { /* Fail */ Result = FALSE; } else if (!(Bpb.Sectors) && !(Bpb.LargeSectors)) { /* Fail */ Result = FALSE; } else if ((Bpb.Media != 0x00) && (Bpb.Media != 0x01) && (Bpb.Media != 0xf0) && (Bpb.Media != 0xf8) && (Bpb.Media != 0xf9) && (Bpb.Media != 0xfa) && (Bpb.Media != 0xfb) && (Bpb.Media != 0xfc) && (Bpb.Media != 0xfd) && (Bpb.Media != 0xfe) && (Bpb.Media != 0xff)) { /* Fail */ Result = FALSE; } else if ((Bpb.SectorsPerFat) && !(Bpb.RootEntries)) { /* Fail */ Result = FALSE; } /* Return the result */ return Result; }