/** Function opens and returns a file handle to the root directory of a volume. @param DeviceHandle A handle for a device @return A valid file handle or NULL is returned **/ EFI_FILE_HANDLE LibOpenRoot ( IN EFI_HANDLE DeviceHandle ) { EFI_STATUS Status; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_HANDLE File; File = NULL; // // File the file system interface to the device // Status = gBS->HandleProtocol ( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID *) &Volume ); // // Open the root directory of the volume // if (!EFI_ERROR (Status)) { Status = Volume->OpenVolume ( Volume, &File ); } // // Done // return EFI_ERROR (Status) ? NULL : File; }
void init_logfile() { EFI_GUID sfspGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_HANDLE* handles = NULL; UINTN handleCount = 0; EFI_STATUS efiStatus = gBS->LocateHandleBuffer(ByProtocol, &sfspGuid, NULL, &handleCount, &handles); for (int index = 0; index < (int)handleCount; index++) { EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs = NULL; efiStatus = gBS->HandleProtocol(handles[index], &sfspGuid, (void**)&fs); if(EFI_ERROR(efiStatus)) { continue; } efiStatus = fs->OpenVolume(fs, &root); if (EFI_ERROR(efiStatus)) { continue; } efiStatus = root->Open( root, &logfile, logfile_path, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ, 0); if (EFI_ERROR(efiStatus)) { continue; } CHAR8 *buf = "LOGFILE\n"; UINTN bufSize = 8; offset += bufSize; efiStatus = logfile->Write(logfile, &bufSize, (CHAR16 *)buf); if (EFI_ERROR(efiStatus)) { continue; } efiStatus = logfile->Close(logfile); if (EFI_ERROR(efiStatus)) { continue; } break; } init = 1; }
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 EFIAPI GetVolumeHandleWithDir(CHAR16 *SearchDir, OUT EFI_HANDLE *Handle) { EFI_STATUS Status; UINTN HandlesSize; UINTN Idx; EFI_HANDLE *Handles; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FS = NULL; EFI_FILE_PROTOCOL *FP = NULL; EFI_FILE_PROTOCOL *FP2 = NULL; // get all handles with EFI_SIMPLE_FILE_SYSTEM_PROTOCOL Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandlesSize, &Handles); if (EFI_ERROR(Status)) { Print(L"LocateHandleBuffer: %r\n", Status); return Status; } Print(L"LocateHandleBuffer: %r, got %d handles\n", Status, HandlesSize); // find handle that contains SearchDir for (Idx = 0; Idx < HandlesSize; Idx++) { // get EFI_SIMPLE_FILE_SYSTEM_PROTOCOL first Print(L"Trying handle: %p\n", Handles[Idx]); Status = gBS->OpenProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, (void **)&FS, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { Print(L"OpenProtocol(gEfiSimpleFileSystemProtocolGuid): %r\n", Status); continue; } // open volume Status = FS->OpenVolume(FS, &FP); if (EFI_ERROR(Status)) { Print(L"OpenVolume(): %r\n", Status); gBS->CloseProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, gImageHandle, NULL); continue; } // try to open injection dir Status = FP->Open(FP, &FP2, SearchDir, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { Print(L"Open(%s): %r\n", SearchDir, Status); FP->Close(FP); gBS->CloseProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, gImageHandle, NULL); continue; } // we have found it - close it and return handle FP2->Close(FP2); FP->Close(FP); *Handle = Handles[Idx]; return EFI_SUCCESS; } // not found return EFI_NOT_FOUND; }
/** Open the NvVars file for reading or writing @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance @param[in] ReadingFile - TRUE: open the file for reading. FALSE: writing @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated with the opened NvVars file. @return EFI_SUCCESS if the file was opened **/ EFI_STATUS GetNvVarsFile ( IN EFI_HANDLE FsHandle, IN BOOLEAN ReadingFile, OUT EFI_FILE_HANDLE *NvVarsFile ) { EFI_STATUS Status; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; EFI_FILE_HANDLE Root; // // Get the FileSystem protocol on that handle // Status = gBS->HandleProtocol ( FsHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs ); if (EFI_ERROR (Status)) { return Status; } // // Get the volume (the root directory) // Status = Fs->OpenVolume (Fs, &Root); if (EFI_ERROR (Status)) { return Status; } // // Attempt to open the NvVars file in the root directory // Status = Root->Open ( Root, NvVarsFile, L"NvVars", ReadingFile ? EFI_FILE_MODE_READ : ( EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE ), 0 ); if (EFI_ERROR (Status)) { return Status; } 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; }
EFI_STATUS EFIAPI TOLOpen ( IN EFI_TEST_OUTPUT_LIBRARY_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *FileName, IN BOOLEAN OverwriteFile, OUT EFI_FILE **FileHandle ) /*++ Routine Description: One interface function of the TestOutputLibrary to open a file. Arguments: This - the protocol instance structure. DevicePath - the file's root device path. FileName - the file's name relative to the root. OverwriteFile - whether to overwrite the file. FileHandle - return the file's handle. Returns: EFI_SUCCESS - open the file successfully. EFI_NOT_READY - to overwrite an opened file is not allowed. EFI_OUT_OF_RESOURCES - not enough memory. --*/ { EFI_STATUS Status; TEST_OUTPUT_FILE *OutputFile; TEST_OUTPUT_PRIVATE_DATA *Private; EFI_HANDLE DeviceHandle; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; UINTN BufSize; CHAR8 Buffer[2]; EFI_DEVICE_PATH_PROTOCOL *PreDevicePath; Private = TEST_OUTPUT_PRIVATE_DATA_FROM_THIS (This); // // Search the file in OutputFileList to see whether the file has been opened // OutputFile = Private->OutputFileList; while (OutputFile != NULL) { if ((SctDevicePathCompare (DevicePath, OutputFile->DevicePath) == 0) && (StrCmp (FileName, OutputFile->FileName) == 0)) { break; } OutputFile = OutputFile->Next; } if (OutputFile == NULL) { // // Not found, open the file and add to the list // PreDevicePath = DevicePath; // // Determine device handle for fs protocol on specified device path // Status = BS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &PreDevicePath, &DeviceHandle ); if (EFI_ERROR (Status)) { return Status; } // // Determine volume for file system on device handle // Status = BS->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 (EFI_ERROR (Status)) { return Status; } // // Determine the existence of the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, 0 ); if (Status == EFI_NOT_FOUND) { // // The file not exist, create it // Status = SctCreateFile (RootDir, FileName, &Handle); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } // // Write the head of Unicode text file // Buffer[0] = 0xff; Buffer[1] = 0xfe; BufSize = 2; Status = Handle->Write (Handle, &BufSize, Buffer); if (EFI_ERROR (Status)) { Handle->Close (Handle); return Status; } } else if (EFI_ERROR (Status)) { RootDir->Close(RootDir); return Status; } if (OverwriteFile) { // // Overwrite the file // // // Delete the file // Status = Handle->Delete (Handle); // // EFI_FILE.Delete() return a warning status // if (Status != EFI_SUCCESS) { RootDir->Close (RootDir); return EFI_UNSUPPORTED; } // // Recreate the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } // // Write the head of Unicode text file // Buffer[0] = 0xff; Buffer[1] = 0xfe; BufSize = 2; Status = Handle->Write (Handle, &BufSize, Buffer); if (EFI_ERROR (Status)) { Handle->Close (Handle); return Status; } } else { // // Append the file // // // Set position to the end of file // Status = Handle->SetPosition (Handle, (UINT64)-1); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } } RootDir->Close (RootDir); // // Add the opened file to the OutputFileList // Status = BS->AllocatePool ( EfiBootServicesData, sizeof(TEST_OUTPUT_FILE), (VOID **)&OutputFile ); if (EFI_ERROR (Status)) { Handle->Close (Handle); return Status; } ZeroMem (OutputFile, sizeof(TEST_OUTPUT_FILE)); OutputFile->DevicePath = DuplicateDevicePath (DevicePath); if (OutputFile->DevicePath == NULL) { Handle->Close (Handle); BS->FreePool (OutputFile); return EFI_OUT_OF_RESOURCES; } OutputFile->FileName = StrDuplicate (FileName); if (OutputFile->FileName == NULL) { Handle->Close (Handle); BS->FreePool (OutputFile->DevicePath); BS->FreePool (OutputFile); return EFI_OUT_OF_RESOURCES; } OutputFile->FileHandle = Handle; OutputFile->Next = Private->OutputFileList; Private->OutputFileList = OutputFile; } // // Add the open count and return the file handle // OutputFile->OpenCount ++; *FileHandle = OutputFile->FileHandle; return EFI_SUCCESS; }
/** 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; }
/** 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); } } } } }
/** Write a file. @param[in] FileName The file to be written. @param[in] BufferSize The file buffer size @param[in] Buffer The file buffer @retval EFI_SUCCESS Write file successfully **/ EFI_STATUS WriteFileFromBuffer ( IN CHAR16 *FileName, IN UINTN BufferSize, IN VOID *Buffer ) { EFI_STATUS Status; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; UINTN TempBufferSize; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; Vol = GetMyVol(); if (Vol == NULL) { return EFI_NOT_FOUND; } // // 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 | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } // // Delete file // Status = Handle->Delete(Handle); if (EFI_ERROR(Status)) { return Status; } // // Open the file again // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } RootDir->Close (RootDir); // // Write the file data from the buffer // TempBufferSize = BufferSize; Status = Handle->Write ( Handle, &TempBufferSize, Buffer ); if (EFI_ERROR (Status)) { Handle->Close (Handle); return Status; } Handle->Close (Handle); return EFI_SUCCESS; }
/** This function will open a file or directory referenced by DevicePath. This function opens a file with the open mode according to the file path. The Attributes is valid only for EFI_FILE_MODE_CREATE. @param[in, out] FilePath On input, the device path to the file. On output, the remaining device path. @param[out] FileHandle Pointer to the file handle. @param[in] OpenMode The mode to open the file with. @param[in] Attributes The file's file attributes. @retval EFI_SUCCESS The information was set. @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. @retval EFI_UNSUPPORTED Could not open the file path. @retval EFI_NOT_FOUND The specified file could not be found on the device or the file system could not be found on the device. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no longer supported. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED The file or medium is write protected. @retval EFI_ACCESS_DENIED The file was opened read only. @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. @retval EFI_VOLUME_FULL The volume is full. **/ EFI_STATUS EFIAPI OpenFileByDevicePath( IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, OUT EFI_FILE_HANDLE *FileHandle, IN UINT64 OpenMode, IN UINT64 Attributes ) { EFI_STATUS Status; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol; EFI_FILE_PROTOCOL *Handle1; EFI_FILE_PROTOCOL *Handle2; EFI_HANDLE DeviceHandle; if ((FilePath == NULL || FileHandle == NULL)) { return EFI_INVALID_PARAMETER; } Status = gBS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, FilePath, &DeviceHandle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&EfiSimpleFileSystemProtocol, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1); if (EFI_ERROR (Status)) { FileHandle = NULL; return Status; } // // go down directories one node at a time. // while (!IsDevicePathEnd (*FilePath)) { // // For file system access each node should be a file path component // if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH || DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP ) { FileHandle = NULL; return (EFI_INVALID_PARAMETER); } // // Open this file path node // Handle2 = Handle1; Handle1 = NULL; // // Try to test opening an existing file // Status = Handle2->Open ( Handle2, &Handle1, ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, OpenMode &~EFI_FILE_MODE_CREATE, 0 ); // // see if the error was that it needs to be created // if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) { Status = Handle2->Open ( Handle2, &Handle1, ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, OpenMode, Attributes ); } // // Close the last node // Handle2->Close (Handle2); if (EFI_ERROR(Status)) { return (Status); } // // Get the next node // *FilePath = NextDevicePathNode (*FilePath); } // // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also! // *FileHandle = (VOID*)Handle1; 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; }
CHAR16 * GetFileNameUnderDir ( IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *DirName, IN CHAR16 *FileName, IN OUT UINTN *Index ) /*++ Routine Description: Get file name under this dir with index Arguments: DebuggerPrivate - EBC Debugger private data structure DirName - The dir to be read. FileName - The file name pattern under this dir Index - The file index under this dir Returns: File Name which match the pattern and index. --*/ { EFI_STATUS Status; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; UINTN FileInfoSize; EFI_FILE_INFO *FileInfo; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; VOID *TempName; UINTN FileIndex; if (DebuggerPrivate->Vol == NULL) { Status = gBS->LocateProtocol ( &gEfiSimpleFileSystemProtocolGuid, NULL, &DebuggerPrivate->Vol ); if (EFI_ERROR(Status)) { return NULL; } } Vol = DebuggerPrivate->Vol; // // Open the root directory // Status = Vol->OpenVolume (Vol, &RootDir); if (EFI_ERROR (Status)) { return NULL; } // // Open the file // Status = RootDir->Open ( RootDir, &Handle, DirName, EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return NULL; } RootDir->Close (RootDir); // // Set Dir Position // Status = Handle->SetPosition (Handle, 0); if (EFI_ERROR (Status)) { Handle->Close (Handle); return NULL; } // // Get the file information // FileInfoSize = sizeof(EFI_FILE_INFO) + 1024; FileInfo = EfiLibAllocateZeroPool (FileInfoSize); if (FileInfo == NULL) { Handle->Close (Handle); return NULL; } // // Walk through each file in the directory // FileIndex = 0; TempName = NULL; while (TRUE) { // // Read a file entry // FileInfoSize = sizeof(EFI_FILE_INFO) + 1024; Status = Handle->Read ( Handle, &FileInfoSize, FileInfo ); if (EFI_ERROR (Status) || (FileInfoSize == 0)) { break; } if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) { // // This is a file // // // Only deal with the EFI key file // if (!StrEndWith (FileInfo->FileName, FileName)) { continue; } if (FileIndex == *Index) { TempName = StrDuplicate (FileInfo->FileName); *Index = *Index + 1; break; } FileIndex ++; } } // // Free resources // gBS->FreePool (FileInfo); Handle->Close (Handle); return TempName; }
EFI_STATUS BdsFileSystemLoadImage ( IN EFI_DEVICE_PATH *DevicePath, IN EFI_HANDLE Handle, IN EFI_DEVICE_PATH *RemainingDevicePath, IN EFI_ALLOCATE_TYPE Type, IN OUT EFI_PHYSICAL_ADDRESS* Image, OUT UINTN *ImageSize ) { FILEPATH_DEVICE_PATH* FilePathDevicePath; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol; EFI_FILE_PROTOCOL *Fs; EFI_STATUS Status; EFI_FILE_INFO *FileInfo; EFI_FILE_PROTOCOL *File; UINTN Size; ASSERT (IS_DEVICE_PATH_NODE(RemainingDevicePath,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP)); FilePathDevicePath = (FILEPATH_DEVICE_PATH*)RemainingDevicePath; Status = gBS->HandleProtocol(Handle,&gEfiSimpleFileSystemProtocolGuid, (VOID **)&FsProtocol); if (EFI_ERROR(Status)) { return Status; } // Try to Open the volume and get root directory Status = FsProtocol->OpenVolume (FsProtocol, &Fs); if (EFI_ERROR(Status)) { return Status; } File = NULL; Status = Fs->Open(Fs, &File, FilePathDevicePath->PathName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { return Status; } Size = 0; File->GetInfo(File, &gEfiFileInfoGuid, &Size, NULL); FileInfo = AllocatePool (Size); Status = File->GetInfo(File, &gEfiFileInfoGuid, &Size, FileInfo); if (EFI_ERROR(Status)) { return Status; } // Get the file size Size = FileInfo->FileSize; if (ImageSize) { *ImageSize = Size; } FreePool(FileInfo); Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image); // Try to allocate in any pages if failed to allocate memory at the defined location if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) { Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image); } if (!EFI_ERROR(Status)) { Status = File->Read (File, &Size, (VOID*)(UINTN)(*Image)); } return Status; }
EFI_STATUS FileOpen ( IN EFI_DEVICE_PATH_PROTOCOL *Device, IN CHAR16 *MappedFile, OUT EFI_FILE_PROTOCOL **File, IN UINT64 OpenMode ) { EFI_HANDLE Handle; EFI_FILE_HANDLE Root; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_STATUS Status; *File = NULL; Status = gBS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &Device, &Handle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->HandleProtocol ( Handle, &gEfiSimpleFileSystemProtocolGuid, &Volume ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } // // Open the root directory of the volume // Root = NULL; Status = Volume->OpenVolume ( Volume, &Root ); ASSERT_EFI_ERROR (Status); ASSERT (Root != NULL); // // Open file // Status = Root->Open ( Root, File, MappedFile, OpenMode, 0 ); if (EFI_ERROR (Status)) { *File = NULL; } // // Close the Root directory // Root->Close (Root); return Status; }
/** * 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; }
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; }
EFI_STATUS LoadSupportFiles ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *FilePath, IN BOOLEAN Recursive, OUT EFI_LIST_ENTRY *SupportFileList ) /*++ Routine Description: Load all test support files. Arguments: DevicePath - Device path of the files. FilePath - Path of the files. Recursive - Recursively. SupportFileList - Pointer to the support file list. Returns: EFI_SUCCESS - Successfully. Other value - Something failed. --*/ { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE SupportDir; CHAR16 *SubDir; CHAR16 *FileName; UINTN FileInfoSize; EFI_FILE_INFO *FileInfo; EFI_SCT_TEST_FILE *SupportFile; EFI_DEVICE_PATH_PROTOCOL *RemainderPath; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; // // Check parameters // if ((DevicePath == NULL) || (FilePath == NULL) || (SupportFileList == NULL)) { return EFI_INVALID_PARAMETER; } // // Debug information // EFI_SCT_DEBUG ((EFI_SCT_D_TRACE, L"Load support files from <%s>", FilePath)); // // Locate the device handle from the device path // RemainderPath = DevicePath; Status = BS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &RemainderPath, &DeviceHandle ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Locate device handle - %r", Status)); return Status; } // // Locate the volume of the file system // Status = BS->HandleProtocol ( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, &Vol ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Locate file system - %r", Status)); return Status; } // // Open the root volume // Status = Vol->OpenVolume (Vol, &RootDir); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open root volume - %r", Status)); return Status; } // // Open the support directory // Status = RootDir->Open ( RootDir, &SupportDir, FilePath, EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open support directory - %r", Status)); RootDir->Close (RootDir); return Status; } RootDir->Close (RootDir); // // Allocate memory for the entries in the directory // 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)); SupportDir->Close (SupportDir); return Status; } // // Walk through each file in the directory // while (TRUE) { // // Read a file entry // FileInfoSize = sizeof(EFI_FILE_INFO) + 1024; Status = SupportDir->Read ( SupportDir, &FileInfoSize, FileInfo ); if (EFI_ERROR (Status) || (FileInfoSize == 0)) { break; } if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) { // // This is a file // if (SctStrEndWith (FileInfo->FileName, L".efi")) { // // Load the support file // FileName = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName); if (FileName == NULL) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources")); break; } Status = LoadSingleSupportFile ( DevicePath, FileName, &SupportFile ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Load a support file - %r", Status)); BS->FreePool (FileName); continue; } BS->FreePool (FileName); // // Add the support file to the support file list // InsertTailList (SupportFileList, &SupportFile->Link); } } else { // // This is a directory // if (Recursive) { // // Skip the '.' and '..' dir // if ((StrCmp (FileInfo->FileName, L".") == 0) || (StrCmp (FileInfo->FileName, L"..") == 0)) { continue; } // // Load the support files under the sub directory // SubDir = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName); if (SubDir == NULL) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources")); break; } Status = LoadSupportFiles ( DevicePath, SubDir, Recursive, SupportFileList ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Load support files - %r", Status)); BS->FreePool (SubDir); continue; } BS->FreePool (SubDir); } } } // // Free resources // BS->FreePool (FileInfo); SupportDir->Close (SupportDir); // // Done // return EFI_SUCCESS; }
BOOLEAN FileExist ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *FileName ) /*++ Routine Description: Check whether a file exists. --*/ { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; // // Check parameters // if ((DevicePath == NULL) || (FileName == NULL)) { return FALSE; } // // Locate the device handle // RemainingDevicePath = DevicePath; Status = BS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &RemainingDevicePath, &DeviceHandle ); if (EFI_ERROR (Status)) { return FALSE; } // // Locate the simple file system // Status = BS->HandleProtocol ( DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, &Vol ); if (EFI_ERROR (Status)) { return FALSE; } // // Open the root directory // Status = Vol->OpenVolume (Vol, &RootDir); if (EFI_ERROR (Status)) { return FALSE; } // // Open the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return FALSE; } RootDir->Close (RootDir); Handle->Close (Handle); return TRUE; }
VOID EFIAPI PlatformBdsPolicyBehavior ( IN OUT LIST_ENTRY *DriverOptionList, IN OUT LIST_ENTRY *BootOptionList, IN PROCESS_CAPSULES ProcessCapsules, IN BASEM_MEMORY_TEST BaseMemoryTest ) /*++ Routine Description: The function will excute with as the platform policy, current policy is driven by boot mode. IBV/OEM can customize this code for their specific policy action. Arguments: DriverOptionList - The header of the driver option link list BootOptionList - The header of the boot option link list ProcessCapsules - A pointer to ProcessCapsules() BaseMemoryTest - A pointer to BaseMemoryTest() Returns: None. --*/ { EFI_STATUS Status; UINT16 Timeout; EFI_EVENT UserInputDurationTime; LIST_ENTRY *Link; BDS_COMMON_OPTION *BootOption; UINTN Index; EFI_INPUT_KEY Key; EFI_TPL OldTpl; EFI_BOOT_MODE BootMode; VBoxLogFlowFuncEnter(); ConnectRootBridge (); if (PcdGetBool (PcdOvmfFlashVariablesEnable)) { DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars " "from disk since flash variables appear to be supported.\n")); } else { // // Try to restore variables from the hard disk early so // they can be used for the other BDS connect operations. // PlatformBdsRestoreNvVarsFromHardDisk (); } // // Init the time out value // Timeout = PcdGet16 (PcdPlatformBootTimeOut); // // Load the driver option as the driver option list // PlatformBdsGetDriverOption (DriverOptionList); // // Get current Boot Mode // Status = BdsLibGetBootMode (&BootMode); DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode)); // // Go the different platform policy with different boot mode // Notes: this part code can be change with the table policy // ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION); // // Connect platform console // Status = PlatformBdsConnectConsole (gPlatformConsole); if (EFI_ERROR (Status)) { // // Here OEM/IBV can customize with defined action // PlatformBdsNoConsoleAction (); } // // Create a 300ms duration event to ensure user has enough input time to enter Setup // Status = gBS->CreateEvent ( EVT_TIMER, 0, NULL, NULL, &UserInputDurationTime ); ASSERT (Status == EFI_SUCCESS); Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000); ASSERT (Status == EFI_SUCCESS); // // Memory test and Logo show // PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest); // // Perform some platform specific connect sequence // PlatformBdsConnectSequence (); // // Process QEMU's -kernel command line option // TryRunningQemuKernel (); // // Give one chance to enter the setup if we // have the time out // if (Timeout != 0) { //PlatformBdsEnterFrontPage (Timeout, FALSE); } DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n")); BdsLibConnectAll (); #ifdef VBOX { UINTN cFileSystem = 0; EFI_HANDLE *phFileSystem = NULL; BDS_COMMON_OPTION *BootOption0080 = NULL; EFI_STATUS rc = EFI_SUCCESS; DEBUG ((EFI_D_INFO, "------------------ VBox Platform Specific Initialization Start -----------------------\n")); BootOption0080 = BdsLibVariableToOption(BootOptionList, L"Boot0080"); if (!BootOption0080) { rc = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &cFileSystem, &phFileSystem); VBoxLogFlowFuncMarkRC(rc); VBoxLogFlowFuncMarkVar(cFileSystem, "%d"); if ( rc == EFI_SUCCESS && cFileSystem > 0) { EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFSVolume; EFI_FILE_HANDLE hFSRoot; EFI_FILE_HANDLE hBootEfiFile; UINTN iFileSystem = 0; /* Ok, we've found several simple file system handles * 1. we should find if '\\System\\Library\\CoreServices\\boot.efi' present * 2. Alter 'BootOrder' to include this file in boot sequence. */ for (iFileSystem = 0; iFileSystem < cFileSystem; ++iFileSystem) { EFI_DEVICE_PATH_PROTOCOL *pDevicePath = NULL; /* mount and look up the boot.efi */ rc = gBS->HandleProtocol (phFileSystem[iFileSystem], &gEfiSimpleFileSystemProtocolGuid, (VOID *) &pFSVolume); VBoxLogFlowFuncMarkVar(iFileSystem, "%d"); VBoxLogFlowFuncMarkRC(rc); if (EFI_ERROR(rc)) continue; rc = pFSVolume->OpenVolume(pFSVolume, &hFSRoot); VBoxLogFlowFuncMarkRC(rc); if (EFI_ERROR(rc)) continue; rc = hFSRoot->Open(hFSRoot, &hBootEfiFile, L"\\System\\Library\\CoreServices\\boot.efi", EFI_FILE_MODE_READ, 0); VBoxLogFlowFuncMarkRC(rc); if (EFI_ERROR(rc)) continue; /* nice file is found and we have to register it */ pDevicePath = FileDevicePath(phFileSystem[iFileSystem], L"\\System\\Library\\CoreServices\\boot.efi"); VBoxLogFlowFuncMarkVar(pDevicePath,"%p"); if (!pDevicePath) continue; rc = BdsLibRegisterNewOption (BootOptionList, pDevicePath, L"Mac Boot", L"BootOrder"); VBoxLogFlowFuncMarkRC(rc); } } } else { VBoxLogFlowFuncMarkVar(BootOption0080->LoadOptionsSize, "%d"); if (BootOption0080->LoadOptionsSize) VBoxLogFlowFuncMarkVar(BootOption0080->LoadOptions, "%s"); #if 0 /* Boot0080 option is found */ UINT16 *BootOrder; UINTN BootOrderSize; UINTN Index = 0; CHAR16 *BootOptionName; ASSERT(BootOption0080->Signature == BDS_LOAD_OPTION_SIGNATURE); BootOrder = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderSize); ASSERT(BootOrder); BootOptionName = AllocateRuntimePool(256 * sizeof(UINT16)); UnicodeSPrint(BootOptionName, 256 * sizeof(UINT16), L"Boot%04x", BootOrder[Index]); BootOption0080->OptionName = BootOptionName; rc = gRT->SetVariable(BootOptionName, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(BDS_COMMON_OPTION), BootOption0080); LogFlowFuncMarkRC(rc); #if 0 rc = BdsLibRegisterNewOption (BootOptionList, BootOption0080->DevicePath, L"Mac Boot Temp", L"BootOrder"); #endif LogFlowFuncMarkRC(rc); #endif } DEBUG ((EFI_D_INFO, "------------------ VBox Platform Specific Initialization End -----------------------\n")); } #endif BdsLibEnumerateAllBootOption (BootOptionList); SetBootOrderFromQemu (BootOptionList); // // The BootOrder variable may have changed, reload the in-memory list with // it. // BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder"); // // To give the User a chance to enter Setup here, if user set TimeOut is 0. // BDS should still give user a chance to enter Setup // // Connect first boot option, and then check user input before exit // for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) { BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) { // // skip the header of the link list, becuase it has no boot option // continue; } else { // // Make sure the boot option device path connected, but ignore the BBS device path // if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) { BdsLibConnectDevicePath (BootOption->DevicePath); } break; } } // // Check whether the user input after the duration time has expired // OldTpl = EfiGetCurrentTpl(); gBS->RestoreTPL (TPL_APPLICATION); gBS->WaitForEvent (1, &UserInputDurationTime, &Index); gBS->CloseEvent (UserInputDurationTime); Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); gBS->RaiseTPL (OldTpl); if (!EFI_ERROR (Status)) { // // Enter Setup if user input // Timeout = 0xffff; PlatformBdsEnterFrontPage (Timeout, FALSE); } VBoxLogFlowFuncLeave(); return ; }
/** 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; }
EFI_STATUS GetProtocolAssertion ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *FilePath, OUT UINT32 *PassNumber, OUT UINT32 *WarnNumber, OUT UINT32 *FailNumber ) /*++ Routine Description: Get the assertion number of a protocol or service. Arguments: DevicePath - Device path of the key files. FilePath - Path of the key files. PassNumber - The number of passed assertions. WarnNumber - The number of warning assertions. FailNumber - The number of failed assertions. Returns: EFI_SUCCESS - Get instance assertion number successfully. --*/ { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE LogDir; UINTN FileInfoSize; EFI_FILE_INFO *FileInfo; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; UINTN BufferSize; CHAR16 *Buffer; CHAR16 *FileName; CHAR16 *LogName; CHAR16 *TempName; CHAR16 *CaseIndexStr; CHAR16 *CaseIterationStr; // // Check parameters // if ((DevicePath == NULL) || (FilePath == NULL) || (PassNumber == NULL) || (WarnNumber == NULL) || (FailNumber == 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 log directory // Status = RootDir->Open ( RootDir, &LogDir, FilePath, EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open directory - %r", Status)); RootDir->Close (RootDir); return Status; } RootDir->Close (RootDir); // // Allocate memory for the entries in the directory // 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)); LogDir->Close (LogDir); return Status; } // // Walk through each file in the directory // while (TRUE) { // // Read a file entry // FileInfoSize = sizeof(EFI_FILE_INFO) + 1024; Status = LogDir->Read ( LogDir, &FileInfoSize, FileInfo ); if (EFI_ERROR (Status) || (FileInfoSize == 0)) { break; } if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) { // // This is a file // // // Only deal with the EFI key file // if (!SctStrEndWith (FileInfo->FileName, L".ekl")) { continue; } // // Read the file to a buffer // FileName = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName); if (FileName == NULL) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources")); return EFI_OUT_OF_RESOURCES; } Status = ReadFileToBuffer ( DevicePath, FileName, &BufferSize, &Buffer ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Read file to buffer - %r", Status)); BS->FreePool (FileName); continue; } BS->FreePool (FileName); // // Get the index and iteration from the file name // TempName = StrDuplicate (FileInfo->FileName); // // The following function didn't allocate memory for CaseIndexStr and // CaseIterationStr. So DON'T free the TempName before these two strings // are still used. // Status = GetIndexFromFileName ( TempName, &CaseIndexStr, &CaseIterationStr ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Get index from file name - %r", Status)); BS->FreePool (TempName); continue; } // // Load the buffer to the report information structure // LogName = SctStrEndReplace (FileInfo->FileName, L"log"); Status = LoadReportInfor ( CaseIndexStr, CaseIterationStr, Buffer, LogName ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Load report infor - %r", Status)); BS->FreePool (TempName); BS->FreePool (LogName); BS->FreePool (Buffer); continue; } BS->FreePool (TempName); BS->FreePool (LogName); BS->FreePool (Buffer); // // Get the assertion number (free the GUID assertion table) // Status = GetAssertionNumber (PassNumber, WarnNumber, FailNumber); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Get assertion number - %r", Status)); continue; } } else { // // This is a directory // // // Skip the '.' and '..' dir // if ((StrCmp (FileInfo->FileName, L".") == 0) || (StrCmp (FileInfo->FileName, L"..") == 0)) { continue; } // // Get the report information from the sub directories // FileName = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName); if (FileName == NULL) { EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources")); return EFI_OUT_OF_RESOURCES; } Status = GetProtocolAssertion ( DevicePath, FileName, PassNumber, WarnNumber, FailNumber ); if (EFI_ERROR (Status)) { EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Get protocol assertion - %r", Status)); BS->FreePool (FileName); continue; } BS->FreePool (FileName); } } // // Free resources // BS->FreePool (FileInfo); LogDir->Close (LogDir); // // Done // return EFI_SUCCESS; }
/** * Write a file to floppy disk. */ EFI_STATUS WriteFloppyFile ( IN CHAR16 *FileName, IN OUT UINT32 Length, IN VOID *Buffer ) { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN BufLen; // // 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; } // // Determine the existence of the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0 ); if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_FOUND)) { RootDir->Close (RootDir); return Status; } if (Status == EFI_SUCCESS) { // // Delete the existent file // Status = Handle->Delete (Handle); if (Status != EFI_SUCCESS) { Handle->Close (Handle); RootDir->Close (RootDir); return Status; } } // // Create the file // Status = RootDir->Open ( RootDir, &Handle, FileName, EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR(Status)) { RootDir->Close (RootDir); return Status; } // // Write the file // BufLen = Length; Status = Handle->Write (Handle, &BufLen, Buffer); Handle->Close (Handle); RootDir->Close (RootDir); return Status; }
EFI_STATUS EFIAPI TrlReadResetRecord ( IN EFI_TEST_RECOVERY_LIBRARY_PROTOCOL *This, OUT UINTN *Size, OUT VOID *Buffer ) /*++ Routine Description: One interface function of the TestRecoveryLibrary to read reset record. Arguments: This - the protocol instance structure. Size - return the bytes been read. Buffer - buffer to store the record, it can't less than 1024Bytes. Returns: EFI_SUCCESS - read the record successfully. EFI_INVALID_PARAMETER - invalid parameters. --*/ { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; TEST_RECOVERY_PRIVATE_DATA *Private; EFI_DEVICE_PATH_PROTOCOL *PreDevicePath; Private = TEST_RECOVERY_PRIVATE_DATA_FROM_TRL (This); // // Determine device handle for fs protocol on specified device path // PreDevicePath = Private->DevicePath; Status = gBS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &PreDevicePath, &DeviceHandle ); if (EFI_ERROR (Status)) { return Status; } // // Determine volume for file system on device handle // Status = gBS->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 (EFI_ERROR (Status)) { return Status; } // // Open file for read // Status = RootDir->Open ( RootDir, &Handle, Private->FileName, EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } *Size = MAX_BUFFER_SIZE; Status = Handle->Read (Handle, Size, Buffer); Handle->Close (Handle); RootDir->Close (RootDir); return Status; }
EFI_STATUS EFIAPI TrlWriteResetRecord ( IN EFI_TEST_RECOVERY_LIBRARY_PROTOCOL *This, IN UINTN Size, IN VOID *Buffer ) /*++ Routine Description: One interface function of the TestRecoveryLibrary to write reset record. Arguments: This - the protocol instance structure. Size - the bytes to be write, it can't bigger than 1024Bytes. Buffer - buffer contain the record to be written. Returns: EFI_SUCCESS - write the record successfully. EFI_INVALID_PARAMETER - invalid parameters. --*/ { EFI_STATUS Status; EFI_HANDLE DeviceHandle; EFI_FILE_HANDLE RootDir; EFI_FILE_HANDLE Handle; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; TEST_RECOVERY_PRIVATE_DATA *Private; EFI_DEVICE_PATH_PROTOCOL *PreDevicePath; Private = TEST_RECOVERY_PRIVATE_DATA_FROM_TRL (This); // // Determine device handle for fs protocol on specified device path // PreDevicePath = Private->DevicePath; Status = gBS->LocateDevicePath ( &gEfiSimpleFileSystemProtocolGuid, &PreDevicePath, &DeviceHandle ); if (EFI_ERROR (Status)) { return Status; } // // Determine volume for file system on device handle // Status = gBS->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 (EFI_ERROR (Status)) { return Status; } // // Open file for read // Status = RootDir->Open ( RootDir, &Handle, Private->FileName, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0 ); if (Status == EFI_NOT_FOUND) { // // The file not exist, create it // Status = RootDir->Open ( RootDir, &Handle, Private->FileName, EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } } else if (Status == EFI_SUCCESS) { // // The file exist, delete it // Status = Handle->Delete (Handle); // // EFI_FILE.Delete() return a warning status // if (Status != EFI_SUCCESS) { Handle->Close (Handle); RootDir->Close (RootDir); return EFI_UNSUPPORTED; } // // Recreate the file // Status = RootDir->Open ( RootDir, &Handle, Private->FileName, EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { RootDir->Close (RootDir); return Status; } } else { RootDir->Close (RootDir); return Status; } // // Write buffer // Status = Handle->Write (Handle, &Size, Buffer); Handle->Close (Handle); RootDir->Close (RootDir); return Status; }
/** Find the file handle from the input device path info. @param RootDirectory Device path info. @param RetFileHandle Return the file handle for the input device path. @param ParentFileName Parent file name. @param DeviceHandle Driver handle for this partition. @retval EFI_SUCESS Find the file handle success. @retval Other Find the file handle failure. **/ EFI_STATUS LibGetFileHandleFromDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL *RootDirectory, OUT EFI_FILE_HANDLE *RetFileHandle, OUT UINT16 **ParentFileName, OUT EFI_HANDLE *DeviceHandle ) { EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode; EFI_STATUS Status; EFI_HANDLE Handle; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_HANDLE FileHandle; EFI_FILE_HANDLE LastHandle; CHAR16 *TempPath; *ParentFileName = NULL; // // Attempt to access the file via a file system interface // DevicePathNode = RootDirectory; Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle); if (EFI_ERROR (Status)) { return Status; } Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume); if (EFI_ERROR (Status)) { return Status; } // // Open the Volume to get the File System handle // Status = Volume->OpenVolume (Volume, &FileHandle); if (EFI_ERROR (Status)) { return Status; } *DeviceHandle = Handle; if (IsDevicePathEnd(DevicePathNode)) { *ParentFileName = AllocateCopyPool (StrSize (L"\\"), L"\\"); *RetFileHandle = FileHandle; return EFI_SUCCESS; } // // 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) { // // 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; goto Done; } // // 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; goto Done; } LastHandle = FileHandle; FileHandle = NULL; Status = LastHandle->Open ( LastHandle, &FileHandle, ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName, EFI_FILE_MODE_READ, 0 ); if (*ParentFileName == NULL) { *ParentFileName = AllocateCopyPool (StrSize (((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName), ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName); } else { TempPath = LibAppendFileName (*ParentFileName, ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName); if (TempPath == NULL) { LastHandle->Close (LastHandle); Status = EFI_OUT_OF_RESOURCES; goto Done; } FreePool (*ParentFileName); *ParentFileName = TempPath; } // // Close the previous node // LastHandle->Close (LastHandle); DevicePathNode = NextDevicePathNode (DevicePathNode); } if (EFI_ERROR (Status)) { goto Done; } *RetFileHandle = FileHandle; Status = EFI_SUCCESS; Done: if (TempDevicePathNode != NULL) { FreePool (TempDevicePathNode); } if ((FileHandle != NULL) && (EFI_ERROR (Status))) { FileHandle->Close (FileHandle); } 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; }