Example #1
0
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;
}
Example #2
0
NTSTATUS
BlFileOpen (
    _In_ ULONG DeviceId,
    _In_ PWCHAR FileName,
    _In_ ULONG Flags,
    _Out_ PULONG FileId
    )
{
    NTSTATUS Status;
    PBL_FILE_ENTRY FileEntry;
    BL_DEVICE_INFORMATION DeviceInformation;

    /* Make sure we have a valid file name, access flags and parameters */
    if (!(FileName) ||
        (*FileName != OBJ_NAME_PATH_SEPARATOR) ||
        !(FileId) ||
        !(Flags & (BL_FILE_READ_ACCESS | BL_FILE_WRITE_ACCESS)))
    {
        EfiPrintf(L"Invalid file options\r\n");
        return STATUS_INVALID_PARAMETER;
    }

    /* Get information on the underlying device */
    Status = BlDeviceGetInformation(DeviceId, &DeviceInformation);
    if (!NT_SUCCESS(Status))
    {
        EfiPrintf(L"Get device info failed: %lx\r\n", Status);
        return Status;
    }

    /* Make sure it's a device that can host files */
    if ((DeviceInformation.DeviceType != DiskDevice) &&
        (DeviceInformation.DeviceType != LegacyPartitionDevice) &&
        (DeviceInformation.DeviceType != UdpDevice))
    {
        EfiPrintf(L"Invalid device type\r\n");
        return STATUS_INVALID_PARAMETER;
    }

    /* Open a file on this device, creating one if needed */
    Status = FileIoOpen(DeviceId,
                        FileName,
                        Flags,
                        0,
                        FileTableCompareWithSameAttributes,
                        &FileEntry);
    if (NT_SUCCESS(Status))
    {
        /* Return the file ID back to the caller */
        EfiPrintf(L"File opened: %lx\r\n", FileEntry->FileId);
        *FileId = FileEntry->FileId;
    }

    /* All good */
    return Status;
}
Example #3
0
NTSTATUS
BlFileReadEx (
    _In_ ULONG FileId,
    _Out_ PVOID Buffer,
    _In_ ULONG Size,
    _Out_ PULONG BytesReturned,
    _In_ ULONG Flags
    )
{
    PBL_FILE_ENTRY FileEntry;
    NTSTATUS Status;
    ULONG OldUnknown, RequiredSize;
    BOOLEAN ChangedUnknown;
    BL_DEVICE_INFORMATION DeviceInfo;
    BL_FILE_INFORMATION fileInfo;

    /* Initialize variables */
    RtlZeroMemory(&DeviceInfo, sizeof(DeviceInfo));
    OldUnknown = 0;
    ChangedUnknown = FALSE;

    /* Bail out if there's no buffer */
    if (!Buffer)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Bail out of the file ID is invalid */
    if (FileId > FileEntries)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Bail out if there's no file opened for read access */
    FileEntry = FileTable[FileId];
    if (!(FileEntry) ||
        !(FileEntry->Flags & (BL_FILE_ENTRY_OPENED | BL_FILE_ENTRY_READ_ACCESS)))
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Bail out if we can't read the file's information */
    Status = BlFileGetInformation(FileId, &fileInfo);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Ensure the read attempt is valid, and fix up the size if needed */
    RequiredSize = Size;
    Status = FileInformationCheck(&fileInfo,
                                  FALSE,
                                  &RequiredSize,
                                  BytesReturned,
                                  &RequiredSize);
    if (!NT_SUCCESS(Status))
    {
        /* Invalid or illegal read attempt */
        return Status;
    }

    /* Is there anything left to read after all? */
    if (RequiredSize)
    {
        /* Check if flags 2 or 4 are set */
        if ((Flags & 2) || (Flags & 4))
        {
            /* Check if this is a disk or partition device */
            BlDeviceGetInformation(FileEntry->DeviceId, &DeviceInfo);
            if ((DeviceInfo.DeviceType == DiskDevice) ||
                (DeviceInfo.DeviceType == LegacyPartitionDevice))
            {
                /* Check if request flags are incompatible with device flags */
                if ((!(DeviceInfo.BlockDeviceInfo.Unknown & 1) && (Flags & 2)) ||
                    (!(DeviceInfo.BlockDeviceInfo.Unknown & 2) && (Flags & 4)))
                {
                    /* We're going to change the device flags */
                    ChangedUnknown = TRUE;

                    /* Set unknown flag 1 for request flag 2 */
                    if (Flags & 2)
                    {
                        DeviceInfo.BlockDeviceInfo.Unknown |= 1;
                    }

                    /* Set unknown flag 2 for request flag 4 */
                    if (Flags & 4)
                    {
                        DeviceInfo.BlockDeviceInfo.Unknown |= 2;
                    }

                    /* Save the new device flags */
                    BlDeviceSetInformation(FileEntry->DeviceId, &DeviceInfo);
                }
            }
        }

        /* Issue the read to the underlying file system */
        Status = FileEntry->Callbacks.Read(FileEntry,
                                           Buffer,
                                           RequiredSize,
                                           BytesReturned);
        if (!NT_SUCCESS(Status))
        {
            /* Don't update the bytes read on failure */
            RequiredSize = 0;
        }
    }
    else
    {
        /* There's nothing to do, return success and 0 bytes */
        Status = STATUS_SUCCESS;
        if (BytesReturned)
        {
            *BytesReturned = 0;
        }
    }

    /* Increment the number of bytes read */
    FileEntry->TotalBytesRead += RequiredSize;

    /* Check if the unknown flag on the device was changed during this routine */
    if (ChangedUnknown)
    {
        /* Reset it back to its original value */
        DeviceInfo.BlockDeviceInfo.Unknown = OldUnknown;
        BlDeviceSetInformation(FileEntry->DeviceId, &DeviceInfo);
    }

    /* Return the final status */
    return Status;
}