Exemplo n.º 1
0
PBL_BLOCK_DESCRIPTOR
MmBapFindBlockInformation (
    ULONG BlockId
    )
{
    ULONG EntryId;

    /* Find the block that matches */
    EntryId = BlockId;
    return BlTblFindEntry(MmBlockAllocatorTable,
                          MmBlockAllocatorTableEntries,
                          &EntryId,
                          MmBapCompareBlockAllocatorTableEntry,
                          UlongToPtr(EntryId),
                          NULL,
                          NULL,
                          NULL);
}
Exemplo n.º 2
0
NTSTATUS
FileIoOpen (
    _In_ ULONG DeviceId,
    _In_ PWCHAR FileName,
    _In_ ULONG Flags,
    _In_ ULONG Unknown,
    _In_ PBL_TBL_LOOKUP_ROUTINE CompareRoutine,
    _Out_opt_ PBL_FILE_ENTRY *NewFileEntry
    )
{
    PWCHAR FileNameCopy, ParentFileName;
    NTSTATUS Status;
    PBL_DEVICE_ENTRY DeviceEntry;
    PBL_FILE_SYSTEM_ENTRY FileSystem;
    ULONG FileId, CheckFlags;
    PBL_FILE_ENTRY DirectoryEntry, FileEntry;
    PLIST_ENTRY NextEntry, ListHead;

    /* Preinitialize variables for failure */
    DirectoryEntry = NULL;
    FileNameCopy = NULL;
    ParentFileName = NULL;
    Status = STATUS_SUCCESS;

    /* Bail out if the device ID is invalid */
    if (DmTableEntries <= DeviceId)
    {
        return STATUS_ACCESS_DENIED;
    }

    /* Bail out if there's no device entry */
    DeviceEntry = DmDeviceTable[DeviceId];
    if (!DeviceEntry)
    {
        return STATUS_ACCESS_DENIED;
    }

    /* Read access is always required for touching the device */
    CheckFlags = Flags | BL_FILE_READ_ACCESS;

    /* Check if the device is granting us read access */
    if ((CheckFlags & BL_FILE_READ_ACCESS) &&
        (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
         !(DeviceEntry->Flags & BL_DEVICE_ENTRY_READ_ACCESS)))
    {
        EfiPrintf(L"Access denied\r\n");
        return STATUS_ACCESS_DENIED;
    }

    /* Check if the device is granting us write access */
    if ((CheckFlags & BL_FILE_WRITE_ACCESS) &&
        (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
         !(DeviceEntry->Flags & BL_DEVICE_ENTRY_WRITE_ACCESS)))
    {
        EfiPrintf(L"Access denied2\r\n");
        return STATUS_ACCESS_DENIED;
    }

    /* Check if we already have this file open */
    FileEntry = (PBL_FILE_ENTRY )BlTblFindEntry(FileTable,
                                                FileEntries,
                                                &FileId,
                                                CompareRoutine,
                                                &DeviceId,
                                                FileName,
                                                &Flags,
                                                &Unknown);
    if (FileEntry)
    {
        EfiPrintf(L"Entry exists: %p\n", FileEntry);
        goto FileOpened;
    }

    /* Check if we are opening the root drive or an actual file/directory */
    if ((*FileName != OBJ_NAME_PATH_SEPARATOR) || (FileName[1]))
    {
        /* Get the name of the directory */
        ParentFileName = FileIoCopyParentDirectoryPath(FileName);
        if (!ParentFileName)
        {
            Status = STATUS_NO_MEMORY;
            goto Quickie;
        }

        /* Open it */
        Status = FileIoOpen(DeviceId,
                            ParentFileName,
                            BL_FILE_READ_ACCESS | BL_DIRECTORY_ACCESS,
                            Unknown,
                            FileTableCompareWithSubsetAttributes,
                            &DirectoryEntry);
        if (!NT_SUCCESS(Status))
        {
            goto Quickie;
        }

        /* Now get the the file name itself */
        FileNameCopy = FileIoCopyFileName(FileName);
        if (!FileNameCopy)
        {
            Status = STATUS_NO_MEMORY;
            goto Quickie;
        }

        /* Open it */
        Status = DirectoryEntry->Callbacks.Open(DirectoryEntry,
                                                FileNameCopy,
                                                Flags,
                                                &FileEntry);
    }
    else
    {
        /* We're opening the root, scan through all the file systems */
        Status = STATUS_UNSUCCESSFUL;
        ListHead = &RegisteredFileSystems;
        NextEntry = ListHead->Flink;
        while (NextEntry != ListHead)
        {
            /* Try to mount this one */
            FileSystem = CONTAINING_RECORD(NextEntry, BL_FILE_SYSTEM_ENTRY, ListEntry);
            Status = FileSystem->MountCallback(DeviceId, Unknown, &FileEntry);
            if (NT_SUCCESS(Status))
            {
                /* Mount successful */
                break;
            }

            /* Try the next file system */
            NextEntry = NextEntry->Flink;
        }

        /* Nothing to free on this path */
        FileNameCopy = NULL;
    }

    /* Handle failure */
    if (!NT_SUCCESS(Status))
    {
        EfiPrintf(L"Could not open file!: %lx\r\n", Status);
        goto Quickie;
    }

    /* Save the unknown */
    FileEntry->Unknown = Unknown;

    /* Convert open flags into entry flags */
    if (Flags & BL_FILE_READ_ACCESS)
    {
        FileEntry->Flags |= BL_FILE_ENTRY_READ_ACCESS;
    }
    if (Flags & BL_FILE_WRITE_ACCESS)
    {
        FileEntry->Flags |= BL_FILE_ENTRY_WRITE_ACCESS;
    }

    /* Save the file into the file table */
    Status = BlTblSetEntry(&FileTable,
                           &FileEntries,
                           (PVOID)FileEntry,
                           &FileId,
                           FileTablePurgeEntry);
    if (!NT_SUCCESS(Status))
    {
        /* Close it if that failed */
        FileEntry->Callbacks.Close(FileEntry);
        goto Quickie;
    }

    /* Add a reference on the device, and save our file ID  */
    ++DeviceEntry->ReferenceCount;
    Status = STATUS_SUCCESS;
    FileEntry->FileId = FileId;

    EfiPrintf(L"File %s opened with ID: %lx\r\n", FileEntry->FilePath, FileId);

FileOpened:
    /* Add a reference to the file entry, and see if this is the first one */
    if (++FileEntry->ReferenceCount == 1)
    {
        /* Reset unknowns */
        FileEntry->TotalBytesRead = 0;
        FileEntry->Unknown2 = 0;
    }

    /* Set the file as opened */
    FileEntry->Flags |= BL_FILE_ENTRY_OPENED;

    /* Not sure what this flag does */
    if (Flags & BL_UNKNOWN_ACCESS)
    {
        FileEntry->Flags |= BL_FILE_ENTRY_UNKNOWN_ACCESS;
    }

    /* If the caller wanted the entry back, return it */
    if (NewFileEntry)
    {
        *NewFileEntry = FileEntry;
    }

Quickie:
    /* Close the parent */
    if (DirectoryEntry)
    {
        BlFileClose(DirectoryEntry->FileId);
    }

    /* Free the parent name copy */
    if (ParentFileName)
    {
        BlMmFreeHeap(ParentFileName);
    }

    /* Free the file name copy */
    if (FileNameCopy)
    {
        BlMmFreeHeap(FileNameCopy);
    }

    /* Return back to caller */
    return Status;
}