EFI_STATUS BdsLoadOptionFileSystemList ( IN OUT LIST_ENTRY* BdsLoadOptionList ) { EFI_STATUS Status; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINTN Index; BDS_SUPPORTED_DEVICE *SupportedDevice; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileProtocol; EFI_FILE_HANDLE Fs; UINTN Size; EFI_FILE_SYSTEM_INFO* FsInfo; EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; // List all the Simple File System Protocols Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR (Status)) { return Status; } for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); if (!EFI_ERROR(Status)) { // Allocate BDS Supported Device structure SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE)); FileProtocol = NULL; Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileProtocol); ASSERT_EFI_ERROR(Status); FileProtocol->OpenVolume (FileProtocol, &Fs); // Generate a Description from the file system Size = 0; FsInfo = NULL; Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo); if (Status == EFI_BUFFER_TOO_SMALL) { FsInfo = AllocatePool (Size); Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo); } UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"%s (%d MB)",FsInfo->VolumeLabel,(UINT32)(FsInfo->VolumeSize / (1024 * 1024))); FreePool(FsInfo); Fs->Close (Fs); SupportedDevice->DevicePathProtocol = DevicePathProtocol; SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_FILESYSTEM]; InsertTailList (BdsLoadOptionList,&SupportedDevice->Link); } } return EFI_SUCCESS; }
EFI_STATUS ReadFileFromVol ( IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol, IN CHAR16 *FileName, OUT UINTN *BufferSize, OUT VOID **Buffer ) /*++ Routine Description: Read a file. Arguments: Vol - File System Volume FileName - The file to be read. BufferSize - The file buffer size Buffer - The file buffer Returns: EFI_SUCCESS - read file successfully EFI_NOT_FOUND - file not found --*/ { EFI_STATUS Status; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; UINTN FileInfoSize; EFI_FILE_INFO *FileInfo; UINTN TempBufferSize; VOID *TempBuffer; // // Open the root directory // Status = Vol->OpenVolume (Vol, &RootDir); if (EFI_ERROR (Status)) { return Status; } // // Open the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } RootDir->Close (RootDir); // // Get the file information // FileInfoSize = sizeof(EFI_FILE_INFO) + 1024; FileInfo = EfiLibAllocateZeroPool (FileInfoSize); if (FileInfo == NULL) { Handle->Close (Handle); return Status; } Status = Handle->GetInfo ( Handle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo ); if (EFI_ERROR (Status)) { Handle->Close (Handle); gBS->FreePool (FileInfo); return Status; } // // Allocate buffer for the file data. The last CHAR16 is for L'\0' // TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16); TempBuffer = EfiLibAllocateZeroPool (TempBufferSize); if (TempBuffer == NULL) { Handle->Close (Handle); gBS->FreePool (FileInfo); return Status; } gBS->FreePool (FileInfo); // // Read the file data to the buffer // Status = Handle->Read ( Handle, &TempBufferSize, TempBuffer ); if (EFI_ERROR (Status)) { Handle->Close (Handle); gBS->FreePool (TempBuffer); return Status; } Handle->Close (Handle); *BufferSize = TempBufferSize; *Buffer = TempBuffer; return EFI_SUCCESS; }
/** Get the headers (dos, image, optional header) from an image @param Device SimpleFileSystem device handle @param FileName File name for the image @param DosHeader Pointer to dos header @param Hdr The buffer in which to return the PE32, PE32+, or TE header. @retval EFI_SUCCESS Successfully get the machine type. @retval EFI_NOT_FOUND The file is not found. @retval EFI_LOAD_ERROR File is not a valid image file. **/ EFI_STATUS EFIAPI BdsLibGetImageHeader ( IN EFI_HANDLE Device, IN CHAR16 *FileName, OUT EFI_IMAGE_DOS_HEADER *DosHeader, OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr ) { EFI_STATUS Status; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_HANDLE Root; EFI_FILE_HANDLE ThisFile; UINTN BufferSize; UINT64 FileSize; EFI_FILE_INFO *Info; Root = NULL; ThisFile = NULL; // // Handle the file system interface to the device // Status = gBS->HandleProtocol ( Device, &gEfiSimpleFileSystemProtocolGuid, (VOID *) &Volume ); if (EFI_ERROR (Status)) { goto Done; } Status = Volume->OpenVolume ( Volume, &Root ); if (EFI_ERROR (Status)) { Root = NULL; goto Done; } // ASSERT (Root != NULL); Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { goto Done; } // ASSERT (ThisFile != NULL); // // Get file size // BufferSize = SIZE_OF_EFI_FILE_INFO + 200; do { Info = NULL; Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); if (EFI_ERROR (Status)) { goto Done; } Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (!EFI_ERROR (Status)) { break; } if (Status != EFI_BUFFER_TOO_SMALL) { FreePool (Info); goto Done; } FreePool (Info); } while (TRUE); FileSize = Info->FileSize; FreePool (Info); // // Read dos header // BufferSize = sizeof (EFI_IMAGE_DOS_HEADER); Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader); if (EFI_ERROR (Status) || BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) || FileSize <= DosHeader->e_lfanew || DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { Status = EFI_LOAD_ERROR; goto Done; } // // Move to PE signature // Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew); if (EFI_ERROR (Status)) { Status = EFI_LOAD_ERROR; goto Done; } // // Read and check PE signature // BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32); if (EFI_ERROR (Status) || BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) || Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { Status = EFI_LOAD_ERROR; goto Done; } // // Check PE32 or PE32+ magic // if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC && Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { Status = EFI_LOAD_ERROR; goto Done; } Done: if (ThisFile != NULL) { ThisFile->Close (ThisFile); } if (Root != NULL) { Root->Close (Root); } return Status; }
/** Internal work function to fill in EFI_OPEN_FILE information for the Fs and BlkIo @param File Open file handle @param FileName Name of file after device stripped off **/ EFI_STATUS EblFileDevicePath ( IN OUT EFI_OPEN_FILE *File, IN CHAR8 *FileName, IN CONST UINT64 OpenMode ) { EFI_STATUS Status; UINTN Size; FILEPATH_DEVICE_PATH *FilePath; EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; CHAR16 UnicodeFileName[MAX_PATHNAME]; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; EFI_FILE_HANDLE Root; if ( *FileName != 0 ) { AsciiStrToUnicodeStr (FileName, UnicodeFileName); } else { AsciiStrToUnicodeStr ("\\", UnicodeFileName); } Size = StrSize (UnicodeFileName); FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL)); if (FileDevicePath != NULL) { FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath; FilePath->Header.Type = MEDIA_DEVICE_PATH; FilePath->Header.SubType = MEDIA_FILEPATH_DP; CopyMem (&FilePath->PathName, UnicodeFileName, Size); SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header)); if (File->EfiHandle != NULL) { File->DevicePath = DevicePathFromHandle (File->EfiHandle); } File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath); FreePool (FileDevicePath); } Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo); if (!EFI_ERROR (Status)) { File->FsBlockIoMedia = BlkIo->Media; File->FsBlockIo = BlkIo; // If we are not opening the device this will get over written with file info File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize); } if (File->Type == EfiOpenFileSystem) { Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs); if (!EFI_ERROR (Status)) { Status = Fs->OpenVolume (Fs, &Root); if (!EFI_ERROR (Status)) { // Get information about the volume Size = 0; Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo); if (Status == EFI_BUFFER_TOO_SMALL) { File->FsInfo = AllocatePool (Size); Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo); } // Get information about the file Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0); if (!EFI_ERROR (Status)) { Size = 0; Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL); if (Status == EFI_BUFFER_TOO_SMALL) { File->FsFileInfo = AllocatePool (Size); Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo); if (!EFI_ERROR (Status)) { File->Size = (UINTN)File->FsFileInfo->FileSize; File->MaxPosition = (UINT64)File->Size; } } } Root->Close (Root); } } } else if (File->Type == EfiOpenBlockIo) { File->Size = (UINTN)File->MaxPosition; } return Status; }
EFI_STATUS ReadFileToBuffer ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *FileName, OUT UINTN *BufferSize, OUT VOID **Buffer ) /*++ Routine Description: Read a file. --*/ { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; UINTN FileInfoSize; EFI_FILE_INFO *FileInfo; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; UINTN TempBufferSize; VOID *TempBuffer; // // Check parameters // if ((DevicePath == NULL) || (FileName == NULL) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } // // Locate the device handle // RemainingDevicePath = DevicePath; Status = BS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &RemainingDevicePath, &DeviceHandle ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Locate device path - %r", Status)); return Status; } // // Locate the simple file system // Status = BS->HandleProtocol ( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, &Vol ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Handle protocol - %r", Status)); return Status; } // // Open the root directory // Status = Vol->OpenVolume (Vol, &RootDir); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open volume - %r", Status)); return Status; } // // Open the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open file - %r", Status)); RootDir->Close (RootDir); return Status; } RootDir->Close (RootDir); // // Get the file information // FileInfoSize = sizeof(EFI_FILE_INFO) + 1024; Status = BS->AllocatePool ( EfiBootServicesData, FileInfoSize, &FileInfo ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Allocate pool - %r", Status)); Handle->Close (Handle); return Status; } ZeroMem (FileInfo, FileInfoSize); Status = Handle->GetInfo ( Handle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Get file info - %r", Status)); Handle->Close (Handle); BS->FreePool (FileInfo); return Status; } // // Allocate buffer for the file data. The last CHAR16 is for L'\0' // TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16); Status = BS->AllocatePool ( EfiBootServicesData, TempBufferSize, &TempBuffer ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Allocate pool - %r", Status)); Handle->Close (Handle); BS->FreePool (FileInfo); return Status; } ZeroMem (TempBuffer, TempBufferSize); BS->FreePool (FileInfo); // // Read the file data to the buffer // Status = Handle->Read ( Handle, &TempBufferSize, TempBuffer ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Read file - %r", Status)); Handle->Close (Handle); BS->FreePool (TempBuffer); return Status; } Handle->Close (Handle); *BufferSize = TempBufferSize; *Buffer = TempBuffer; return EFI_SUCCESS; }
/** Read a file from this volume. @param[in] Vol File System Volume @param[in] FileName The file to be read. @param[out] BufferSize The file buffer size @param[out] Buffer The file buffer @retval EFI_SUCCESS Read file successfully @retval EFI_NOT_FOUND File not found **/ EFI_STATUS ReadFileFromVol ( IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol, IN CHAR16 *FileName, OUT UINTN *BufferSize, OUT VOID **Buffer ) { EFI_STATUS Status; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; UINTN FileInfoSize; EFI_FILE_INFO *FileInfo; UINTN TempBufferSize; VOID *TempBuffer; // // Open the root directory // Status = Vol->OpenVolume (Vol, &RootDir); if (EFI_ERROR (Status)) { return Status; } // // Open the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } RootDir->Close (RootDir); // // Get the file information // FileInfoSize = sizeof(EFI_FILE_INFO) + 1024; FileInfo = AllocateZeroPool (FileInfoSize); if (FileInfo == NULL) { Handle->Close (Handle); return Status; } Status = Handle->GetInfo ( Handle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo ); if (EFI_ERROR (Status)) { Handle->Close (Handle); gBS->FreePool (FileInfo); return Status; } // // Allocate buffer for the file data. The last CHAR16 is for L'\0' // TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16); TempBuffer = AllocateZeroPool (TempBufferSize); if (TempBuffer == NULL) { Handle->Close (Handle); gBS->FreePool (FileInfo); return Status; } gBS->FreePool (FileInfo); // // Read the file data to the buffer // Status = Handle->Read ( Handle, &TempBufferSize, TempBuffer ); if (EFI_ERROR (Status)) { Handle->Close (Handle); gBS->FreePool (TempBuffer); return Status; } Handle->Close (Handle); *BufferSize = TempBufferSize; *Buffer = TempBuffer; return EFI_SUCCESS; }
/** Update Device List Global Variables **/ VOID EblUpdateDeviceLists ( VOID ) { EFI_STATUS Status; UINTN Size; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; EFI_FILE_HANDLE Root; UINTN Index; if (mBlkIo != NULL) { FreePool (mBlkIo); } gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &mBlkIoCount, &mBlkIo); if (mFv != NULL) { FreePool (mFv); } gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &mFvCount, &mFv); if (mLoadFile != NULL) { FreePool (mLoadFile); } gBS->LocateHandleBuffer (ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &mLoadFileCount, &mLoadFile); if (mFs != NULL) { FreePool (mFs); } if (&mFsInfo[0] != NULL) { // Need to Free the mFsInfo prior to recalculating mFsCount so don't move this code for (Index = 0; Index < mFsCount; Index++) { if (mFsInfo[Index] != NULL) { FreePool (mFsInfo[Index]); } } FreePool (mFsInfo); } gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs); mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *)); if (mFsInfo == NULL) { // If we can't do this then we can't support file system entries mFsCount = 0; } else { // Loop through all the file system structures and cache the file system info data for (Index =0; Index < mFsCount; Index++) { Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs); if (!EFI_ERROR (Status)) { Status = Fs->OpenVolume (Fs, &Root); if (!EFI_ERROR (Status)) { // Get information about the volume Size = 0; Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); if (Status == EFI_BUFFER_TOO_SMALL) { mFsInfo[Index] = AllocatePool (Size); Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); } Root->Close (Root); } } } } }
EFI_STATUS EntryPoint ( EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable ) { EFI_STATUS Status = 0; UINTN i = 0; EFI_FILE_IO_INTERFACE *Vol = 0; EFI_FILE_HANDLE RootFs = 0; EFI_FILE_HANDLE FileHandle = 0; EFI_HANDLE* Search = 0; EFI_HANDLE DeviceHandle = 0; UINTN Size = 0; VOID* BootmgrBuffer = 0; EFI_FILE_INFO* FileInfoBuffer = 0; EFI_HANDLE BootmgrHandle = NULL; EFI_LOADED_IMAGE *BootmgrLoadedImage = 0; EFI_LOADED_IMAGE *LoadedImage = 0; CHAR16 *BOOTMGFW = L"\\EFI\\Microsoft\\BOOT\\BOOTMGFW.EFI"; CHAR16 *BOOTMGFW_BAK = L"\\EFI\\Microsoft\\BOOT\\BOOTMGFW.BAK"; EFI_DEVICE_PATH_PROTOCOL* DevPath = 0; ST = SystemTable; BS = ST->BootServices; RS = ST->RuntimeServices; Status = Main(); //=========================================================================// // get device handle for the loaded (this) image // //=========================================================================// Status = BS->HandleProtocol(ImageHandle, &gLoadedImageProtocol, (VOID **) &LoadedImage); if (EFI_ERROR (Status)) { return Status; } DeviceHandle = LoadedImage->DeviceHandle; //=========================================================================// // get file io interface for device image was loaded from // //=========================================================================// Status = BS->HandleProtocol(DeviceHandle, &gFileSystemProtocol, (VOID **) &Vol); if (EFI_ERROR (Status)) { return Status; } //=========================================================================// // open file system root for the device image was loaded from // //=========================================================================// Status = Vol->OpenVolume(Vol, &RootFs); if (EFI_ERROR (Status)) { return Status; } //=========================================================================// // try to open bootmgfw on file system that image was loaded from // //=========================================================================// //=========================================================================// // look for BOOTMGFW.BAK first to support BOOTMGFW.EFI replacement // // install method. // //=========================================================================// Status = RootFs->Open(RootFs, &FileHandle, BOOTMGFW_BAK, EFI_FILE_MODE_READ, 0); if (Status == EFI_SUCCESS) { BOOTMGFW = BOOTMGFW_BAK; } else if (Status == EFI_NOT_FOUND) { /* if BOOTMGFW.BAK not found search for BOOTMGFW.EFI */ Status = RootFs->Open(RootFs, &FileHandle, BOOTMGFW, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { RootFs->Close(RootFs); switch(Status) { case EFI_NOT_FOUND: //=========================================================================// // failed to find bootmgfw on same device, look for it on other devices. // // get array of device handle's that bootmgfw might be installed on // // first get size of array // //=========================================================================// Size = 0; Status = BS->LocateHandle(ByProtocol, &gFileSystemProtocol, NULL, &Size, 0); if(Status == EFI_BUFFER_TOO_SMALL) { /* allocate memory for array */ Search = (EFI_HANDLE *) AllocatePool(Size); } if(Search) { /* get the array */ Status = BS->LocateHandle(ByProtocol, &gFileSystemProtocol, NULL, &Size, Search); /* loop through handle's open each file system & try to open bootmgfw */ if(Status == EFI_SUCCESS) { for(i = 0; i < Size / sizeof(EFI_HANDLE); i++) { /* we already know bootmgfw is not in the same device as the loaded image, skip */ if(Search[i] == DeviceHandle) { continue; } /* get file io interface */ Status = BS->HandleProtocol(Search[i], &gFileSystemProtocol, (VOID **) &Vol); if(EFI_ERROR (Status)) { continue; } /* open file system root on the device */ Status = Vol->OpenVolume(Vol, &RootFs); if(EFI_ERROR (Status)) { continue; } /* try to open bootmgfw on the file system */ Status = RootFs->Open(RootFs, &FileHandle, BOOTMGFW, EFI_FILE_MODE_READ, 0); if(Status == EFI_SUCCESS) { /* found it, set DeviceHandle & break the loop */ DeviceHandle = Search[i]; break; } /* clean up for next pass */ RootFs->Close(RootFs); } /* free array of device handles, if EFI_SUCCESS break */ /* the switch/case else fall through to the error */ BS->FreePool(Search); if(Status == EFI_SUCCESS) { break; } } } default: return Status; } } } else { return Status; } //============================================================================// // RootFs is open, FileHandle is open, DeviceHandle is set // // get size of bootmgfw.efi by retriving an EFI_FILE_INFO // // first get the size of the STRUCT and allocate memory // //============================================================================// Size = 0; Status = FileHandle->GetInfo(FileHandle, &gFileInfo, &Size, NULL); if(Status == EFI_BUFFER_TOO_SMALL) { /* allocate memory for EFI_FILE_INFO */ FileInfoBuffer = (EFI_FILE_INFO *) AllocatePool(Size); } else { FileHandle->Close(FileHandle); RootFs->Close(RootFs); return Status; } //=========================================================================// // get EFI_FILE_INFO for bootmgfw.efi // //=========================================================================// Status = FileHandle->GetInfo(FileHandle, &gFileInfo, &Size, FileInfoBuffer); if(EFI_ERROR(Status)) { FileHandle->Close(FileHandle); RootFs->Close(RootFs); return Status; } //=========================================================================// // get size of bootmgfw.efi // //=========================================================================// Size = FileInfoBuffer->FileSize; //=========================================================================// // free EFI_FILE_INFO buffer // //=========================================================================// BS->FreePool(FileInfoBuffer); //=========================================================================// // allocate memory for bootmgfw.efi // //=========================================================================// BootmgrBuffer = AllocatePool(Size); if (!BootmgrBuffer) { BS->FreePool(BootmgrBuffer); FileHandle->Close(FileHandle); RootFs->Close(RootFs); return Status; } //=========================================================================// // read bootmgfw.efi into buffer // //=========================================================================// Status = FileHandle->Read(FileHandle, &Size, BootmgrBuffer); if (EFI_ERROR (Status)) { BS->FreePool(BootmgrBuffer); FileHandle->Close(FileHandle); RootFs->Close(RootFs); return Status; } //=========================================================================// // close handle for bootmgfw.efi // //=========================================================================// Status = FileHandle->Close(FileHandle); if (EFI_ERROR (Status)) { } //=========================================================================// // close handle for file system root // //=========================================================================// Status = RootFs->Close(RootFs); if (EFI_ERROR (Status)) { } //=========================================================================// // load bootmgfw.efi from buffer to execution space // //=========================================================================// Status = BS->LoadImage(FALSE, ImageHandle, 0, BootmgrBuffer, Size, &BootmgrHandle); if (EFI_ERROR (Status)) { BS->FreePool(BootmgrBuffer); return Status; } BS->FreePool(BootmgrBuffer); //=========================================================================// // set bootmgfw.efi start variables // //=========================================================================// Status = BS->HandleProtocol(BootmgrHandle, &gLoadedImageProtocol, (VOID **) &BootmgrLoadedImage); if (EFI_ERROR (Status)) { return Status; } BootmgrLoadedImage->DeviceHandle = DeviceHandle; BootmgrLoadedImage->ParentHandle = NULL; BootmgrLoadedImage->FilePath = FileDevicePath(DeviceHandle, BOOTMGFW); //=========================================================================// // start bootmgfw.efi execution // //=========================================================================// Status = BS->StartImage(BootmgrHandle, 0, 0); //============================================================================// // should never get here show error // //============================================================================// if (BootmgrHandle != NULL) { Status = BS->UnloadImage(BootmgrHandle); } return Status; }
EFIAPI GetFileBufferByFilePath ( IN BOOLEAN BootPolicy, IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath, OUT UINTN *FileSize, OUT UINT32 *AuthenticationStatus ) { EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode; EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode; EFI_HANDLE Handle; EFI_GUID *FvNameGuid; EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; EFI_SECTION_TYPE SectionType; UINT8 *ImageBuffer; UINTN ImageBufferSize; EFI_FV_FILETYPE Type; EFI_FV_FILE_ATTRIBUTES Attrib; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_HANDLE FileHandle; EFI_FILE_HANDLE LastHandle; EFI_FILE_INFO *FileInfo; UINTN FileInfoSize; EFI_LOAD_FILE_PROTOCOL *LoadFile; EFI_LOAD_FILE2_PROTOCOL *LoadFile2; EFI_STATUS Status; // // Check input File device path. // if (FilePath == NULL || FileSize == NULL || AuthenticationStatus == NULL) { return NULL; } // // Init local variable // TempDevicePathNode = NULL; FvNameGuid = NULL; FileInfo = NULL; FileHandle = NULL; ImageBuffer = NULL; ImageBufferSize = 0; *AuthenticationStatus = 0; // // Copy File Device Path // OrigDevicePathNode = DuplicateDevicePath (FilePath); if (OrigDevicePathNode == NULL) { return NULL; } // // Check whether this device path support FV2 protocol. // Is so, this device path may contain a Image. // DevicePathNode = OrigDevicePathNode; Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status)) { // // For FwVol File system there is only a single file name that is a GUID. // FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePathNode); if (FvNameGuid == NULL) { Status = EFI_INVALID_PARAMETER; } else { // // Read image from the firmware file // Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol); if (!EFI_ERROR (Status)) { SectionType = EFI_SECTION_PE32; ImageBuffer = NULL; Status = FwVol->ReadSection ( FwVol, FvNameGuid, SectionType, 0, (VOID **)&ImageBuffer, &ImageBufferSize, AuthenticationStatus ); if (EFI_ERROR (Status)) { // // Try a raw file, since a PE32 SECTION does not exist // if (ImageBuffer != NULL) { FreePool (ImageBuffer); *AuthenticationStatus = 0; } ImageBuffer = NULL; Status = FwVol->ReadFile ( FwVol, FvNameGuid, (VOID **)&ImageBuffer, &ImageBufferSize, &Type, &Attrib, AuthenticationStatus ); } } } if (!EFI_ERROR (Status)) { goto Finish; } } // // Attempt to access the file via a file system interface // DevicePathNode = OrigDevicePathNode; Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status)) { Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume); if (!EFI_ERROR (Status)) { // // Open the Volume to get the File System handle // Status = Volume->OpenVolume (Volume, &FileHandle); if (!EFI_ERROR (Status)) { // // Duplicate the device path to avoid the access to unaligned device path node. // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH // nodes, It assures the fields in device path nodes are 2 byte aligned. // TempDevicePathNode = DuplicateDevicePath (DevicePathNode); if (TempDevicePathNode == NULL) { FileHandle->Close (FileHandle); // // Setting Status to an EFI_ERROR value will cause the rest of // the file system support below to be skipped. // Status = EFI_OUT_OF_RESOURCES; } // // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the // directory information and filename can be seperate. The goal is to inch // our way down each device path node and close the previous node // DevicePathNode = TempDevicePathNode; while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) { if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH || DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) { Status = EFI_UNSUPPORTED; break; } LastHandle = FileHandle; FileHandle = NULL; Status = LastHandle->Open ( LastHandle, &FileHandle, ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName, EFI_FILE_MODE_READ, 0 ); // // Close the previous node // LastHandle->Close (LastHandle); DevicePathNode = NextDevicePathNode (DevicePathNode); } if (!EFI_ERROR (Status)) { // // We have found the file. Now we need to read it. Before we can read the file we need to // figure out how big the file is. // FileInfo = NULL; FileInfoSize = 0; Status = FileHandle->GetInfo ( FileHandle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo ); if (Status == EFI_BUFFER_TOO_SMALL) { FileInfo = AllocatePool (FileInfoSize); if (FileInfo == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { Status = FileHandle->GetInfo ( FileHandle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo ); } } if (!EFI_ERROR (Status) && (FileInfo != NULL)) { // // Allocate space for the file // ImageBuffer = AllocatePool ((UINTN)FileInfo->FileSize); if (ImageBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { // // Read the file into the buffer we allocated // ImageBufferSize = (UINTN)FileInfo->FileSize; Status = FileHandle->Read (FileHandle, &ImageBufferSize, ImageBuffer); } } } // // Close the file and Free FileInfo and TempDevicePathNode since we are done // if (FileInfo != NULL) { FreePool (FileInfo); } if (FileHandle != NULL) { FileHandle->Close (FileHandle); } if (TempDevicePathNode != NULL) { FreePool (TempDevicePathNode); } } } if (!EFI_ERROR (Status)) { goto Finish; } } // // Attempt to access the file via LoadFile2 interface // if (!BootPolicy) { DevicePathNode = OrigDevicePathNode; Status = gBS->LocateDevicePath (&gEfiLoadFile2ProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status)) { Status = gBS->HandleProtocol (Handle, &gEfiLoadFile2ProtocolGuid, (VOID**)&LoadFile2); if (!EFI_ERROR (Status)) { // // Call LoadFile2 with the correct buffer size // ImageBufferSize = 0; ImageBuffer = NULL; Status = LoadFile2->LoadFile ( LoadFile2, DevicePathNode, FALSE, &ImageBufferSize, ImageBuffer ); if (Status == EFI_BUFFER_TOO_SMALL) { ImageBuffer = AllocatePool (ImageBufferSize); if (ImageBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { Status = LoadFile2->LoadFile ( LoadFile2, DevicePathNode, FALSE, &ImageBufferSize, ImageBuffer ); } } } if (!EFI_ERROR (Status)) { goto Finish; } } } // // Attempt to access the file via LoadFile interface // DevicePathNode = OrigDevicePathNode; Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status)) { Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID**)&LoadFile); if (!EFI_ERROR (Status)) { // // Call LoadFile with the correct buffer size // ImageBufferSize = 0; ImageBuffer = NULL; Status = LoadFile->LoadFile ( LoadFile, DevicePathNode, BootPolicy, &ImageBufferSize, ImageBuffer ); if (Status == EFI_BUFFER_TOO_SMALL) { ImageBuffer = AllocatePool (ImageBufferSize); if (ImageBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { Status = LoadFile->LoadFile ( LoadFile, DevicePathNode, BootPolicy, &ImageBufferSize, ImageBuffer ); } } } } Finish: if (EFI_ERROR (Status)) { if (ImageBuffer != NULL) { FreePool (ImageBuffer); ImageBuffer = NULL; } *FileSize = 0; } else { *FileSize = ImageBufferSize; } FreePool (OrigDevicePathNode); return ImageBuffer; }
/** * Read a file from floppy disk. */ EFI_STATUS ReadFloppyFile ( IN CHAR16 *FileName, OUT UINT32 *Length, OUT VOID **Buffer ) { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; EFI_FILE_INFO *FileInfo; UINTN FileInfoSize; VOID* FileBuffer; UINTN FileSize; EFI_DEVICE_PATH_PROTOCOL *DevicePath; // // Get floppy device path // Status = GetFloppyDevicePath (&DevicePath); if (EFI_ERROR(Status)) { return Status; } // // Determine device handle for fs protocol on floppy device path // Status = gtBS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &DevicePath, &DeviceHandle ); if (EFI_ERROR(Status) ) { return Status; } // // Determine volume for file system on device handle // Status = gtBS->HandleProtocol ( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID*)&Vol ); if (EFI_ERROR(Status) ) { return Status; } // // Open volume for file system on device path // Status = Vol->OpenVolume (Vol, &RootDir); if (Status == EFI_MEDIA_CHANGED) { // // Reopen the volume // Status = gtBS->HandleProtocol ( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID*)&Vol ); if (EFI_ERROR(Status) ) { return Status; } Status = Vol->OpenVolume (Vol, &RootDir); } if (EFI_ERROR(Status) ) { return Status; } // // Open file for read // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR(Status) ) { RootDir->Close (RootDir); return Status; } // // Get file size // FileInfoSize = 1; Status = gtBS->AllocatePool ( EfiBootServicesData, FileInfoSize, &FileInfo ); if (EFI_ERROR(Status) ) { Handle->Close (Handle); RootDir->Close (RootDir); return Status; } // // the return code should be EFI_BUFFER_TOO_SMALL // Status = Handle->GetInfo ( Handle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo ); gtBS->FreePool (FileInfo); Status = gtBS->AllocatePool ( EfiBootServicesData, FileInfoSize, &FileInfo ); if (EFI_ERROR(Status) ) { Handle->Close (Handle); RootDir->Close (RootDir); return Status; } Status = Handle->GetInfo ( Handle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo ); FileSize = (UINTN)FileInfo->FileSize; gtBS->FreePool (FileInfo); // // Read the file // Status = gtBS->AllocatePool ( EfiBootServicesData, FileSize, &FileBuffer ); if (EFI_ERROR(Status) ) { Handle->Close (Handle); RootDir->Close (RootDir); return Status; } Status = Handle->Read ( Handle, &FileSize, FileBuffer ); if (EFI_ERROR(Status) ) { gtBS->FreePool (FileBuffer); } else { *Buffer = FileBuffer; *Length = (UINT32)FileSize; } Handle->Close (Handle); RootDir->Close (RootDir); return Status; }
/** Get the headers (dos, image, optional header) from an image @param Device SimpleFileSystem device handle @param FileName File name for the image @param DosHeader Pointer to dos header @param Hdr The buffer in which to return the PE32, PE32+, or TE header. @retval EFI_SUCCESS Successfully get the machine type. @retval EFI_NOT_FOUND The file is not found. @retval EFI_LOAD_ERROR File is not a valid image file. **/ EFI_STATUS EFIAPI BdsLibGetImageHeader ( IN EFI_HANDLE Device, IN CHAR16 *FileName, OUT EFI_IMAGE_DOS_HEADER *DosHeader, OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr, IN OUT CHAR16 **NewFileName ) { EFI_STATUS Status; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_HANDLE Root; EFI_FILE_HANDLE ThisFile; UINTN BufferSize; UINT64 FileSize; EFI_FILE_INFO *Info; CHAR16 *FileName0 = NULL; /*application's file*/ Root = NULL; ThisFile = NULL; // // Handle the file system interface to the device // Status = gBS->HandleProtocol ( Device, &gEfiSimpleFileSystemProtocolGuid, (VOID *) &Volume ); if (EFI_ERROR (Status)) { goto Done; } Status = Volume->OpenVolume ( Volume, &Root ); if (EFI_ERROR (Status)) { Root = NULL; goto Done; } Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); DEBUG((DEBUG_INFO, "%a:%d Open FileName:'%s' - %r \n", __FILE__, __LINE__, FileName, Status)); if (EFI_ERROR (Status)) { goto Done; } // // Get file size // do { BufferSize = 0; Info = NULL; /* Get right size we need to allocate */ Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { goto Done; } Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); if (EFI_ERROR (Status)) { goto Done; } Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (!EFI_ERROR (Status)) { DEBUG((DEBUG_INFO, "%a:%d Open FileName:%s from Info %r \n", __FILE__, __LINE__, Info->FileName, Status)); Status = gBS->AllocatePool (EfiBootServicesData, StrLen(Info->FileName), (VOID **) &FileName0); StrCpy(FileName0, Info->FileName); if (EFI_ERROR (Status)) { goto Done; } break; } if (Status != EFI_BUFFER_TOO_SMALL) { FreePool (Info); goto Done; } FreePool (Info); } while (TRUE); FileSize = Info->FileSize; FreePool (Info); // // Read dos header // #ifndef VBOX BufferSize = sizeof (EFI_IMAGE_DOS_HEADER); Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader); if (EFI_ERROR (Status) || BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) || FileSize <= DosHeader->e_lfanew || DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { Status = EFI_LOAD_ERROR; goto Done; } // // Move to PE signature // Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew); if (EFI_ERROR (Status)) { Status = EFI_LOAD_ERROR; goto Done; } // // Read and check PE signature // BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32); if (EFI_ERROR (Status) || BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) || Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { Status = EFI_LOAD_ERROR; goto Done; } // // Check PE32 or PE32+ magic // if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC && Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { Status = EFI_LOAD_ERROR; goto Done; } #endif Done: if (!EFI_ERROR(Status)) { EFI_STATUS Status0; /* We need prepare the correct file path for case sensitive loaders ... Sigh.*/ CHAR16 *dup; CHAR16 *p, *pp; dup = AllocateZeroPool(StrSize(FileName)); StrCpy(dup, FileName); pp = p = dup; while (*p != L'\0') { BufferSize = 0; Info = NULL; if (*p == L'\\' && p != dup) { *p = L'\0'; Status0 = Root->Open (Root, &ThisFile, dup, EFI_FILE_MODE_READ, 1); DEBUG((DEBUG_INFO, "%a:%d Open FileName:%s - %r \n", __FILE__, __LINE__, dup, Status)); if (EFI_ERROR (Status)) { goto Done; } /* Get right size we need to allocate */ Status0 = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { DEBUG((DEBUG_INFO, "%a:%d GetInfo(1) FileName:%s %r \n", __FILE__, __LINE__, FileName, Status)); goto Done; } Status0 = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); if (EFI_ERROR (Status)) { goto Done; } Status0 = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (!EFI_ERROR (Status0)) { DEBUG((DEBUG_INFO, "%a:%d Open FileName:%s from Info %r \n", __FILE__, __LINE__, Info->FileName, Status)); StrCpy(pp + 1, Info->FileName); } * p = L'\\'; pp = p; } p++; } StrCpy(pp + 1, FileName0); DEBUG((DEBUG_INFO, "%a:%d NewFileName:'%s'\n", __FILE__, __LINE__, dup)); *NewFileName = dup; } DEBUG((DEBUG_INFO, "%a:%d %s - %r\n", __FILE__, __LINE__, FileName, Status)); if (ThisFile != NULL) { ThisFile->Close (ThisFile); } if (Root != NULL) { Root->Close (Root); } return Status; }
/** Entrypoint of Acpi Platform driver. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; // INTN Instance; // EFI_ACPI_COMMON_HEADER *CurrentTable; EFI_ACPI_COMMON_HEADER *oldDSDT; UINTN TableHandle; UINTN TableSize; // UINTN Size; #if READTABLES UINTN Index; CHAR16* FileName; #if LIP EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; #endif VOID *FileBuffer; // VOID** TmpHandler; UINT64 FileSize; UINTN BufferSize; // UINTN Key; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_INFO *Info; EFI_FILE_HANDLE Root = NULL; EFI_FILE_HANDLE ThisFile = NULL; #endif EFI_PHYSICAL_ADDRESS *Acpi20; EFI_PEI_HOB_POINTERS GuidHob; EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; // EFI_ACPI_DESCRIPTION_HEADER *Rsdt, *Xsdt; // EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; EFI_ACPI_DESCRIPTION_HEADER *Table; SIGNAT Signature; // EFI_ACPI_TABLE_INSTANCE *AcpiInstance; Msg = NULL; Status = gBS->LocateProtocol(&gMsgLogProtocolGuid, NULL, (VOID **) &Msg); if (!EFI_ERROR(Status) && (Msg != NULL)) { msgCursor = Msg->Cursor; BootLog("MsgLog Protocol installed in AcpiPlatform\n"); } // // Find the AcpiTable protocol // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); if (EFI_ERROR (Status)) { return EFI_ABORTED; } #if DEBUG_ACPI AcpiInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS(AcpiTable); DBG(L"Rsdp1 %x\n", AcpiInstance->Rsdp1); DBG(L"Rsdp3 %x\n", AcpiInstance->Rsdp3); DBG(L"Rsdt1 %x\n", AcpiInstance->Rsdt1); DBG(L"Rsdt3 %x\n", AcpiInstance->Rsdt3); DBG(L"Xsdt %x\n", AcpiInstance->Xsdt); DBG(L"Fadt1 %x\n", AcpiInstance->Fadt1); DBG(L"Fadt3 %x\n", AcpiInstance->Fadt3); #endif // Instance = 0; // CurrentTable = NULL; TableHandle = 0; GuidHob.Raw = GetFirstGuidHob (&gEfiAcpiTableGuid); if (GuidHob.Raw == NULL) { GuidHob.Raw = GetFirstGuidHob (&gEfiAcpi10TableGuid); if (GuidHob.Raw == NULL) { return EFI_ABORTED; } //Slice: TODO if we found only Acpi1.0 we need to convert it to Acpi2.0 // like I did in Chameleon } Acpi20 = GET_GUID_HOB_DATA (GuidHob.Guid); if (Acpi20 == NULL) { return EFI_ABORTED; } Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)*Acpi20; DBG(L"Rsdp @ %x\n", (UINTN)Rsdp); DBG(L"Rsdt @ %x\n", (UINTN)(Rsdp->RsdtAddress)); DBG(L"Xsdt @ %x\n", (UINTN)(Rsdp->XsdtAddress)); InstallLegacyTables(AcpiTable, Rsdp); // DBG(L"LegacyTables installed\n"); oldDSDT = (EFI_ACPI_COMMON_HEADER*)(UINTN)Fadt->Dsdt; DBG(L"Fadt @ %x\n", (UINTN)Fadt); DBG(L"oldDSDT @ %x\n", (UINTN)oldDSDT); #if READTABLES #if LIP // Looking for a volume from what we boot /* TODO - look for a volume we want to boot System it is possible if we fix in BdsBoot.c gRT->SetVariable ( L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (UINT16), &Option->BootCurrent ); gRT->GetVariable ( L"BootNext", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, &BootNext ); and extract DevicePath from BootNext - first available :( In Gui.efi we can repeat this patch with DSDT.aml loaded from another place */ Status = gBS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID*)&LoadedImage ); if (EFI_ERROR (Status)) { return EFI_ABORTED; } Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID *) &Volume ); if (EFI_ERROR (Status)) { return EFI_ABORTED; } // DBG(L"Volume found\n"); // // Open the root directory of the volume // if (!EFI_ERROR (Status)) { Status = Volume->OpenVolume (Volume, &Root); } #else //Multiple FS protocols EFI_HANDLE *mFs = NULL; UINTN mFsCount = 0; // mFsInfo[] array entries must match mFs[] handles EFI_FILE_SYSTEM_INFO **mFsInfo = NULL; gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs); mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *)); if (mFsInfo == NULL) { // If we can't do this then we can't support file system entries mFsCount = 0; } else { // Loop through all the file system structures and cache the file system info data for (Index =0; Index < mFsCount; Index++) { Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Volume); if (!EFI_ERROR (Status)) { Status = Volume->OpenVolume (Volume, &Root); if (!EFI_ERROR (Status)) { // Get information about the volume /* Size = 0; Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); if (Status == EFI_BUFFER_TOO_SMALL) { mFsInfo[Index] = AllocatePool (Size); Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]); } */ // Root->Close (Root); break; //I will stop at first volume //TODO try to find DSDT in all volumes } } } } #endif FileName = AllocateZeroPool(32); //Should be enough // // Read tables from the first volume. // for (Index=0; Index<NUM_TABLES; Index++) { StrCpyS(FileName, 32, ACPInames[Index]); // DBG(L"File probe %s\n", FileName); Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { continue; } /* Get right size we need to allocate */ Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { continue; } DBG(L"Buffer size %d\n", BufferSize); // DBG(L"GetInfo success!\n"); Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); if (EFI_ERROR (Status)) { // DBG(L"No pool!\n"); continue; } Status = ThisFile->GetInfo ( ThisFile, &gEfiFileInfoGuid, &BufferSize, Info ); FileSize = Info->FileSize; // DBG(L"FileSize = %d!\n", FileSize); gBS->FreePool (Info); //Slice - this is the problem. // FileBuffer = AllocatePool(FileSize); Status = gBS->AllocatePool (EfiBootServicesData, FileSize, (VOID **) &FileBuffer); if (EFI_ERROR (Status)) { // DBG(L"No pool for FileBuffer size %d!\n", FileSize); continue; } /* Status = gBS->AllocatePages ( AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES(FileSize), FileBuffer ); if (EFI_ERROR (Status)) { // DBG(L"No pool for FileBuffer size %d!\n", FileSize); continue; } */ //should use ACPI memory // Status=gBS->AllocatePages(AllocateMaxAddress, // EfiACPIReclaimMemory,RoundPage(FileSize)/EFI_PAGE_SIZE, FileBuffer); DBG(L"FileBuffer @ %x\n", (UINTN)FileBuffer); Status = ThisFile->Read (ThisFile, &FileSize, FileBuffer); //(VOID**)& // DBG(L"FileRead status=%x\n", Status); if (!EFI_ERROR(Status)) { // // Add the table // // TableHandle = 0; if (ThisFile != NULL) { ThisFile->Close (ThisFile); //close file before use buffer?! Flush?! } // DBG(L"FileRead success: %c%c%c%c\n", // ((CHAR8*)FileBuffer)[0], ((CHAR8*)FileBuffer)[1], ((CHAR8*)FileBuffer)[2], ((CHAR8*)FileBuffer)[3]); TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length; //ASSERT (BufferSize >= TableSize); DBG(L"Table size=%d\n", TableSize); if (FileSize < TableSize) { //Data incorrect. What TODO? Quick fix // ((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length = FileSize; // TableSize = FileSize; DBG(L"Table size > file size :(\n"); continue; //do nothing with broken table } // // Checksum ACPI table // AcpiPlatformChecksum ((UINT8*)FileBuffer, TableSize); if ((Index==0) && oldDSDT) { //DSDT always at index 0 if (((EFI_ACPI_DESCRIPTION_HEADER *) oldDSDT)->Length > TableSize) { CopyMem(oldDSDT, FileBuffer, TableSize); DBG(L"New DSDT copied to old place\n"); } } // // Install ACPI table // //TmpHandler = &FileBuffer; Status = AcpiTable->InstallAcpiTable ( AcpiTable, FileBuffer, TableSize, &TableHandle ); DBG(L"Table install status=%x\n", Status); if (EFI_ERROR(Status)) { continue; } // DBG(L"Table installed #%d\n", Index); // // Increment the instance // // Instance++; //for a what? FileBuffer = NULL; } else if (oldDSDT && (Index==0)) { //if new DSDT not found then install legacy one Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt)); TableSize = Table->Length; Signature.Sign = Table->Signature; DBG(L"Install legacy table: %c%c%c%c\n", Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]); Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableHandle ); } } if (Root != NULL) { Root->Close (Root); } #else //just install legacy tables if (oldDSDT) { //if new DSDT not found then install legacy one Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt)); TableSize = Table->Length; Signature.Sign = Table->Signature; DBG(L"Install legacy table: %c%c%c%c\n", Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]); /*Status = */AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableHandle ); } #endif #if DEBUG_ACPI==2 gBS->Stall(5000000); #endif return EFI_SUCCESS; }