/** Create a new file or folder in current directory. @param FileName Point to the fileNmae or folder name. @param CreateFile CreateFile== TRUE means create a new file. CreateFile== FALSE means create a new Folder. **/ EFI_STATUS LibCreateNewFile ( IN CHAR16 *FileName, IN BOOLEAN CreateFile ) { EFI_FILE_HANDLE FileHandle; EFI_FILE_HANDLE NewHandle; EFI_HANDLE DeviceHandle; EFI_STATUS Status; CHAR16 *ParentName; CHAR16 *FullFileName; NewHandle = NULL; FullFileName = NULL; LibGetFileHandleFromDevicePath(gFileExplorerPrivate.RetDevicePath, &FileHandle, &ParentName, &DeviceHandle); FullFileName = LibAppendFileName (ParentName, FileName); if (FullFileName == NULL) { return EFI_OUT_OF_RESOURCES; } if (CreateFile) { Status = FileHandle->Open( FileHandle, &NewHandle, FullFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE, 0 ); if (EFI_ERROR (Status)) { FileHandle->Close (FileHandle); return Status; } } else { Status = FileHandle->Open( FileHandle, &NewHandle, FullFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE, EFI_FILE_DIRECTORY ); if (EFI_ERROR (Status)) { FileHandle->Close (FileHandle); return Status; } } FileHandle->Close (FileHandle); // // Return the DevicePath of the new created file or folder. // gFileExplorerPrivate.RetDevicePath = FileDevicePath (DeviceHandle, FullFileName); return EFI_SUCCESS; }
void* LoadFileWithPadding(EFI_FILE_HANDLE dir, const CHAR16* path, UINTN* size_ptr, UINTN padding) { EFI_STATUS e; EFI_FILE_HANDLE handle; e = dir->Open(dir, &handle, (CHAR16*) path, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(e)) { return 0; } EFI_FILE_INFO *info = LibFileInfo(handle); UINTN size = info->FileSize; FreePool(info); void* data = 0; e = BS->AllocatePool(EfiBootServicesData, size + padding, &data); if (EFI_ERROR(e)) { handle->Close(handle); return 0; } e = handle->Read(handle, &size, data); for (int i = 0; i < padding; ++i) { *((char*)data + size + i) = 0; } handle->Close(handle); if (EFI_ERROR(e)) { FreePool(data); return 0; } if (size_ptr) { *size_ptr = size; } return data; }
EFI_STATUS EFIAPI InstallAgent( IN EFI_FILE_HANDLE CurDir, IN CHAR16 * FileNameUser ) { EFI_STATUS Status = EFI_SUCCESS; EFI_FILE_HANDLE FileHandle; CHAR16* FileNameScout; FileNameScout = AllocateZeroPool(260*sizeof(CHAR16)); StrCpy(FileNameScout,FileNameUser); StrCat(FileNameScout, FILE_NAME_SCOUT); StrCat(FileNameScout, g_NAME_SCOUT); Status = CurDir->Open (CurDir, &FileHandle, FileNameScout, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); FreePool(FileNameScout); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error Open Agent File\n"); #endif return Status; } #ifdef FORCE_DEBUG Print(L"FileHandle->Write ... VirtualSize=%x [0]=%x [1]=%x [2]=%x [3]=%x\n",VirtualSize,((UINT8*)pSectiondata)[0],((UINT8*)pSectiondata)[1] * 0x100 ,((UINT8*)pSectiondata)[2] * 0x10000,((UINT8*)pSectiondata)[3] * 0x1000000); #endif Status=FileHandle->Write(FileHandle,&VirtualSize,(UINT8*)(pSectiondata)); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Write File Agent Failed\n"); #endif return Status; } else { #ifdef FORCE_DEBUG Print(L"InstallAgent OK\n"); #endif } Status=FileHandle->Close(FileHandle); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Closing File Agent Failed\n"); #endif return Status; } return EFI_SUCCESS; }
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; }
/** 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 EFIAPI InsertFileLock( IN EFI_FILE_HANDLE CurDir, IN CHAR16 * FileNameUser ) { EFI_STATUS Status = EFI_SUCCESS; EFI_FILE_HANDLE FileHandle; CHAR16* FileNameElite; FileNameElite = AllocateZeroPool(260*sizeof(CHAR16)); StrCpy(FileNameElite,FileNameUser); StrCat(FileNameElite,FILE_NAME_ELITE); StrCat(FileNameElite,g_NAME_ELITE); #ifdef FORCE_DEBUG Print(L"sto tentando di scrivere: %s\n",FILE_NAME_ELITE); #endif Status = CurDir->Open (CurDir, &FileHandle, FileNameElite, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); FreePool(FileNameElite); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error Open File InsertFileLock\n"); #endif return Status; } else { #ifdef FORCE_DEBUG Print(L"InsertFileLock OK\n"); #endif } Status=FileHandle->Close(FileHandle); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Closing InsertFileLock File Failed\n"); #endif return Status; } return EFI_SUCCESS; }
// Fix the case of a path by looking it up on the file system static EFI_STATUS SetPathCase(CONST EFI_FILE_HANDLE Root, CHAR16* Path) { EFI_FILE_HANDLE FileHandle = NULL; EFI_FILE_INFO* FileInfo; UINTN i, Len; UINTN Size; EFI_STATUS Status; if ((Root == NULL) || (Path == NULL) || (Path[0] != L'\\')) return EFI_INVALID_PARAMETER; FileInfo = (EFI_FILE_INFO*)AllocatePool(FILE_INFO_SIZE); if (FileInfo == NULL) return EFI_OUT_OF_RESOURCES; Len = StrLen(Path); // Find the last backslash in the path for (i = Len-1; (i != 0) && (Path[i] != L'\\'); i--); if (i != 0) { Path[i] = 0; // Recursively fix the case Status = SetPathCase(Root, Path); if (EFI_ERROR(Status)) goto out; } Status = Root->Open(Root, &FileHandle, (i==0)?L"\\":Path, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) goto out; do { Size = FILE_INFO_SIZE; Status = FileHandle->Read(FileHandle, &Size, (VOID*)FileInfo); if (EFI_ERROR(Status)) goto out; if (_StriCmp(&Path[i+1], FileInfo->FileName) == 0) { StrCpy(&Path[i+1], FileInfo->FileName); Status = EFI_SUCCESS; goto out; } Status = EFI_NOT_FOUND; } while (Size != 0); out: Path[i] = L'\\'; if (FileHandle != NULL) FileHandle->Close(FileHandle); FreePool((VOID*)FileInfo); return Status; }
EFI_STATUS EFIAPI RemoveFileLock( IN EFI_FILE_HANDLE CurDir, IN CHAR16 * FileNameUser ) { EFI_STATUS Status = EFI_SUCCESS; EFI_FILE_HANDLE FileHandle; CHAR16* FileNameElite; FileNameElite = AllocateZeroPool(260*sizeof(CHAR16)); StrCpy(FileNameElite,FileNameUser); StrCat(FileNameElite,FILE_NAME_ELITE); StrCat(FileNameElite,g_NAME_ELITE); Status = CurDir->Open (CurDir, &FileHandle, FileNameElite, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); FreePool(FileNameElite); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error Open File RemoveFileLock\n"); #endif return Status; } else { #ifdef FORCE_DEBUG Print(L"RemoveFileLock OK\n"); #endif } Status=FileHandle->Delete(FileHandle); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Write RemoveFileLock File Failed\n"); #endif return Status; } return EFI_SUCCESS; }
/** Find the file handle from the input menu info. @param MenuEntry Input Menu info. @param RetFileHandle Return the file handle for the input device path. @retval EFI_SUCESS Find the file handle success. @retval Other Find the file handle failure. **/ EFI_STATUS LibGetFileHandleFromMenu ( IN MENU_ENTRY *MenuEntry, OUT EFI_FILE_HANDLE *RetFileHandle ) { EFI_FILE_HANDLE Dir; EFI_FILE_HANDLE NewDir; FILE_CONTEXT *FileContext; EFI_STATUS Status; FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext; Dir = FileContext->FileHandle; // // Open current directory to get files from it // Status = Dir->Open ( Dir, &NewDir, FileContext->FileName, EFI_FILE_READ_ONLY, 0 ); if (EFI_ERROR (Status)) { return Status; } if (!FileContext->IsRoot) { Dir->Close (Dir); } *RetFileHandle = NewDir; return EFI_SUCCESS; }
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; }
/** 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; }
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; }
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; }
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 ) { 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; }
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; }
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; }
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; }
EFI_STATUS BOpt_FindFiles ( IN BMM_CALLBACK_DATA *CallbackData, IN BM_MENU_ENTRY *MenuEntry ) /*++ Routine Description Find files under current directory All files and sub-directories in current directory will be stored in DirectoryMenu for future use. Arguments: FileOption -- Pointer for Dir to explore Returns: TRUE -- Get files from current dir successfully FALSE -- Can't get files from current dir --*/ { EFI_FILE_HANDLE NewDir; EFI_FILE_HANDLE Dir; EFI_FILE_INFO *DirInfo; UINTN BufferSize; UINTN DirBufferSize; BM_MENU_ENTRY *NewMenuEntry; BM_FILE_CONTEXT *FileContext; BM_FILE_CONTEXT *NewFileContext; UINTN Pass; EFI_STATUS Status; UINTN OptionNumber; FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; Dir = FileContext->FHandle; OptionNumber = 0; // // Open current directory to get files from it // Status = Dir->Open ( Dir, &NewDir, FileContext->FileName, EFI_FILE_READ_ONLY, 0 ); if (!FileContext->IsRoot) { Dir->Close (Dir); } if (EFI_ERROR (Status)) { return Status; } DirInfo = EfiLibFileInfo (NewDir); if (!DirInfo) { return EFI_NOT_FOUND; } if (!(DirInfo->Attribute & EFI_FILE_DIRECTORY)) { return EFI_INVALID_PARAMETER; } FileContext->DevicePath = EfiFileDevicePath ( FileContext->Handle, FileContext->FileName ); DirBufferSize = sizeof (EFI_FILE_INFO) + 1024; DirInfo = EfiAllocateZeroPool (DirBufferSize); if (!DirInfo) { return EFI_OUT_OF_RESOURCES; } // // Get all files in current directory // Pass 1 to get Directories // Pass 2 to get files that are EFI images // for (Pass = 1; Pass <= 2; Pass++) { NewDir->SetPosition (NewDir, 0); for (;;) { BufferSize = DirBufferSize; Status = NewDir->Read (NewDir, &BufferSize, DirInfo); if (EFI_ERROR (Status) || BufferSize == 0) { break; } if ((DirInfo->Attribute & EFI_FILE_DIRECTORY && Pass == 2) || (!(DirInfo->Attribute & EFI_FILE_DIRECTORY) && Pass == 1) ) { // // Pass 1 is for Directories // Pass 2 is for file names // continue; } if (!(BOpt_IsEfiImageName (DirInfo->FileName) || DirInfo->Attribute & EFI_FILE_DIRECTORY)) { // // Slip file unless it is a directory entry or a .EFI file // continue; } NewMenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext; NewFileContext->Handle = FileContext->Handle; NewFileContext->FileName = BOpt_AppendFileName ( FileContext->FileName, DirInfo->FileName ); NewFileContext->FHandle = NewDir; NewFileContext->DevicePath = EfiFileDevicePath ( NewFileContext->Handle, NewFileContext->FileName ); NewMenuEntry->HelpString = NULL; MenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, FileOptionStrDepository ); NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY); if (NewFileContext->IsDir) { BufferSize = EfiStrLen (DirInfo->FileName) * 2 + 6; NewMenuEntry->DisplayString = EfiAllocateZeroPool (BufferSize); SPrint ( NewMenuEntry->DisplayString, BufferSize, L"<%s>", DirInfo->FileName ); } else { NewMenuEntry->DisplayString = EfiStrDuplicate (DirInfo->FileName); } NewFileContext->IsRoot = FALSE; NewFileContext->IsLoadFile = FALSE; NewFileContext->IsRemovableMedia = FALSE; NewMenuEntry->OptionNumber = OptionNumber; OptionNumber++; InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link); } } DirectoryMenu.MenuNumber = OptionNumber; SafeFreePool (DirInfo); return EFI_SUCCESS; }
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 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; }
/** 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; }
/** Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the directory 'stack'. If the file is a directory, then append the '\' char at the end of name string. If it's not a directory, then the last '\' should not be added. if Handle is NULL, return EFI_INVALID_PARAMETER @param[in] Handle Handle to the Directory or File to create path to. @param[out] FullFileName pointer to pointer to generated full file name. It is the responsibility of the caller to free this memory with a call to FreePool(). @retval EFI_SUCCESS the operation was sucessful and the FullFileName is valid. @retval EFI_INVALID_PARAMETER Handle was NULL. @retval EFI_INVALID_PARAMETER FullFileName was NULL. @retval EFI_OUT_OF_RESOURCES a memory allocation failed. **/ EFI_STATUS EFIAPI FileHandleGetFileName ( IN CONST EFI_FILE_HANDLE Handle, OUT CHAR16 **FullFileName ) { EFI_STATUS Status; UINTN Size; EFI_FILE_HANDLE CurrentHandle; EFI_FILE_HANDLE NextHigherHandle; EFI_FILE_INFO *FileInfo; Size = 0; // // Check our parameters // if (FullFileName == NULL || Handle == NULL) { return (EFI_INVALID_PARAMETER); } *FullFileName = NULL; CurrentHandle = NULL; Status = Handle->Open(Handle, &CurrentHandle, L".", EFI_FILE_MODE_READ, 0); if (!EFI_ERROR(Status)) { // // Reverse out the current directory on the device // for (;;) { FileInfo = FileHandleGetInfo(CurrentHandle); if (FileInfo == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } else { // // We got info... do we have a name? if yes precede the current path with it... // if (StrLen (FileInfo->FileName) == 0) { if (*FullFileName == NULL) { ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); } FreePool(FileInfo); break; } else { if (*FullFileName == NULL) { ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); } ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, FileInfo->FileName, 0); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); FreePool(FileInfo); } } // // Move to the parent directory // Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { break; } FileHandleClose(CurrentHandle); CurrentHandle = NextHigherHandle; } } else if (Status == EFI_NOT_FOUND) { Status = EFI_SUCCESS; ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); } if (*FullFileName != NULL && (*FullFileName)[StrLen(*FullFileName) - 1] == L'\\' && StrLen(*FullFileName) > 1 && FileHandleIsDirectory(Handle) == EFI_NOT_FOUND ) { (*FullFileName)[StrLen(*FullFileName) - 1] = CHAR_NULL; } if (CurrentHandle != NULL) { CurrentHandle->Close (CurrentHandle); } if (EFI_ERROR(Status) && *FullFileName != NULL) { FreePool(*FullFileName); } 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; }
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; }
/** 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); } } } } }
/** 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 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; }
/** 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; }
BOOLEAN BOpt_IsEfiApp ( IN EFI_FILE_HANDLE Dir, IN UINT16 *FileName ) /*++ Routine Description: Check whether current FileName point to a valid Efi Application Arguments: Dir - Pointer to current Directory FileName - Pointer to current File name. Returns: TRUE - Is a valid Efi Application FALSE - not a valid Efi Application --*/ { UINTN BufferSize; EFI_IMAGE_DOS_HEADER DosHdr; EFI_IMAGE_NT_HEADERS PeHdr; EFI_IMAGE_OPTIONAL_HEADER32 *PeOpt32; EFI_IMAGE_OPTIONAL_HEADER64 *PeOpt64; UINT16 Subsystem; EFI_FILE_HANDLE File; EFI_STATUS Status; Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { return FALSE; } BufferSize = sizeof (EFI_IMAGE_DOS_HEADER); File->Read (File, &BufferSize, &DosHdr); if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) { File->Close (File); return FALSE; } File->SetPosition (File, DosHdr.e_lfanew); BufferSize = sizeof (EFI_IMAGE_NT_HEADERS); File->Read (File, &BufferSize, &PeHdr); if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) { File->Close (File); return FALSE; } // // Determine PE type and read subsytem // BugBug : We should be using EFI_IMAGE_MACHINE_TYPE_SUPPORTED (machine) // macro to detect the machine type. // We should not be using EFI_IMAGE_OPTIONAL_HEADER32 and // EFI_IMAGE_OPTIONAL_HEADER64 // if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { PeOpt32 = (EFI_IMAGE_OPTIONAL_HEADER32 *) &(PeHdr.OptionalHeader); Subsystem = PeOpt32->Subsystem; } else if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { PeOpt64 = (EFI_IMAGE_OPTIONAL_HEADER64 *) &(PeHdr.OptionalHeader); Subsystem = PeOpt64->Subsystem; } else { return FALSE; } if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) { File->Close (File); return TRUE; } else { File->Close (File); return FALSE; } }