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