diff options
| author | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
|---|---|---|
| committer | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
| commit | 7e2ccccace24636f29ddc210b94606abd4c7e42b (patch) | |
| tree | 545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Library/FileExplorerLib | |
| parent | 27b044605cd5f6b33a3d231576003850b3fe305b (diff) | |
| download | edk2-trunk.tar.xz | |
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Library/FileExplorerLib')
| -rw-r--r-- | MdeModulePkg/Library/FileExplorerLib/FileExplorer.c | 3332 | ||||
| -rw-r--r-- | MdeModulePkg/Library/FileExplorerLib/FileExplorer.h | 464 | ||||
| -rw-r--r-- | MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf | 114 | ||||
| -rw-r--r-- | MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.uni | 40 | ||||
| -rw-r--r-- | MdeModulePkg/Library/FileExplorerLib/FileExplorerString.uni | 110 | ||||
| -rw-r--r-- | MdeModulePkg/Library/FileExplorerLib/FileExplorerVfr.vfr | 158 | ||||
| -rw-r--r-- | MdeModulePkg/Library/FileExplorerLib/FormGuid.h | 58 |
7 files changed, 2138 insertions, 2138 deletions
diff --git a/MdeModulePkg/Library/FileExplorerLib/FileExplorer.c b/MdeModulePkg/Library/FileExplorerLib/FileExplorer.c index 804a03d868..5710f2cd09 100644 --- a/MdeModulePkg/Library/FileExplorerLib/FileExplorer.c +++ b/MdeModulePkg/Library/FileExplorerLib/FileExplorer.c @@ -1,1666 +1,1666 @@ -/** @file
-File explorer related functions.
-
-Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "FileExplorer.h"
-
-EFI_GUID FileExplorerGuid = EFI_FILE_EXPLORE_FORMSET_GUID;
-
-///
-/// File system selection menu
-///
-MENU_OPTION mFsOptionMenu = {
- MENU_OPTION_SIGNATURE,
- { NULL },
- 0,
- FALSE
-};
-
-FILE_EXPLORER_CALLBACK_DATA gFileExplorerPrivate = {
- FILE_EXPLORER_CALLBACK_DATA_SIGNATURE,
- NULL,
- NULL,
- {
- LibExtractConfig,
- LibRouteConfig,
- LibCallback
- },
- NULL,
- &mFsOptionMenu,
- 0
-};
-
-HII_VENDOR_DEVICE_PATH *gHiiVendorDevicePath;
-
-HII_VENDOR_DEVICE_PATH FeHiiVendorDevicePath = {
- {
- {
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- {
- (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
- (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
- }
- },
- //
- // Will be replace with gEfiCallerIdGuid in code.
- //
- { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
- }
- },
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- (UINT8)(END_DEVICE_PATH_LENGTH),
- (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
- }
- }
-};
-
-VOID *mLibStartOpCodeHandle = NULL;
-VOID *mLibEndOpCodeHandle = NULL;
-EFI_IFR_GUID_LABEL *mLibStartLabel = NULL;
-EFI_IFR_GUID_LABEL *mLibEndLabel = NULL;
-UINT16 mQuestionIdUpdate;
-CHAR16 mNewFileName[MAX_FILE_NAME_LEN];
-CHAR16 mNewFolderName[MAX_FOLDER_NAME_LEN];
-UINTN mNewFileQuestionId = NEW_FILE_QUESTION_ID_BASE;
-UINTN mNewFolderQuestionId = NEW_FOLDER_QUESTION_ID_BASE;
-
-/**
- Create a new file or folder in current directory.
-
- @param FileName Point to the fileNmae or folder.
- @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
- );
-
-/**
- This function allows a caller to extract the current configuration for one
- or more named elements from the target driver.
-
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Request A null-terminated Unicode string in <ConfigRequest> format.
- @param Progress On return, points to a character in the Request string.
- Points to the string's null terminator if request was successful.
- Points to the most recent '&' before the first failing name/value
- pair (or the beginning of the string if the failure is in the
- first name/value pair) if the request was not successful.
- @param Results A null-terminated Unicode string in <ConfigAltResp> format which
- has all values filled in for the names in the Request string.
- String to be allocated by the called function.
-
- @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibExtractConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Request,
- OUT EFI_STRING *Progress,
- OUT EFI_STRING *Results
- )
-{
- if ((Progress == NULL) || (Results == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Progress = Request;
- return EFI_NOT_FOUND;
-}
-
-/**
- This function processes the results of changes in configuration.
-
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Configuration A null-terminated Unicode string in <ConfigResp> format.
- @param Progress A pointer to a string filled in with the offset of the most
- recent '&' before the first failing name/value pair (or the
- beginning of the string if the failure is in the first
- name/value pair) or the terminating NULL if all was successful.
-
- @retval EFI_INVALID_PARAMETER Configuration is NULL.
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibRouteConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Configuration,
- OUT EFI_STRING *Progress
- )
-{
- if ((Configuration == NULL) || (Progress == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Progress = Configuration;
- return EFI_NOT_FOUND;
-}
-
-/**
- This function processes the results of changes in configuration.
- When user select a interactive opcode, this callback will be triggered.
- Based on the Question(QuestionId) that triggers the callback, the corresponding
- actions is performed. It handles:
-
- 1) Process the axtra action or exit file explorer when user select one file .
- 2) update of file content if a dir is selected.
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Action Specifies the type of action taken by the browser.
- @param QuestionId A unique value which is sent to the original exporting driver
- so that it can identify the type of data to expect.
- @param Type The type of value for the question.
- @param Value A pointer to the data being sent to the original exporting driver.
- @param ActionRequest On return, points to the action requested by the callback function.
-
- @retval EFI_SUCCESS The callback successfully handled the action.
- @retval other error Error occur when parse one directory.
-**/
-EFI_STATUS
-EFIAPI
-LibCallback (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN EFI_BROWSER_ACTION Action,
- IN EFI_QUESTION_ID QuestionId,
- IN UINT8 Type,
- IN EFI_IFR_TYPE_VALUE *Value,
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
- )
-{
- EFI_STATUS Status;
- BOOLEAN NeedExit;
- CHAR16 *NewFileName;
- CHAR16 *NewFolderName;
-
- NeedExit = TRUE;
- NewFileName = NULL;
- NewFolderName = NULL;
-
- if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
- //
- // Do nothing for other UEFI Action. Only do call back when data is changed.
- //
- return EFI_UNSUPPORTED;
- }
-
- if (Action == EFI_BROWSER_ACTION_CHANGED) {
- if ((Value == NULL) || (ActionRequest == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (QuestionId == KEY_VALUE_CREATE_FILE_AND_EXIT) {
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- if (!IsZeroBuffer (mNewFileName, sizeof (mNewFileName))) {
- Status = LibCreateNewFile (mNewFileName, TRUE);
- ZeroMem (mNewFileName, sizeof (mNewFileName));
- }
- }
-
- if (QuestionId == KEY_VALUE_NO_CREATE_FILE_AND_EXIT) {
- ZeroMem (mNewFileName, sizeof (mNewFileName));
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- }
-
- if (QuestionId == KEY_VALUE_CREATE_FOLDER_AND_EXIT) {
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- if (!IsZeroBuffer (mNewFolderName, sizeof (mNewFolderName))) {
- Status = LibCreateNewFile (mNewFolderName, FALSE);
- ZeroMem (mNewFolderName, sizeof (mNewFolderName));
- }
- }
-
- if (QuestionId == KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT) {
- ZeroMem (mNewFolderName, sizeof (mNewFolderName));
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- }
-
- if (QuestionId == NEW_FILE_NAME_ID) {
- NewFileName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL);
- if (NewFileName != NULL) {
- StrCpyS (mNewFileName, MAX_FILE_NAME_LEN, NewFileName);
- FreePool (NewFileName);
- NewFileName = NULL;
- } else {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- if (QuestionId == NEW_FOLDER_NAME_ID) {
- NewFolderName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL);
- if (NewFolderName != NULL) {
- StrCpyS (mNewFolderName, MAX_FOLDER_NAME_LEN, NewFolderName);
- FreePool (NewFolderName);
- NewFolderName = NULL;
- } else {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- if (QuestionId >= FILE_OPTION_OFFSET) {
- LibGetDevicePath (QuestionId);
-
- //
- // Process the extra action.
- //
- if (gFileExplorerPrivate.ChooseHandler != NULL) {
- NeedExit = gFileExplorerPrivate.ChooseHandler (gFileExplorerPrivate.RetDevicePath);
- }
-
- if (NeedExit) {
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- }
- }
- } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
- if (Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (QuestionId >= FILE_OPTION_OFFSET) {
- LibGetDevicePath (QuestionId);
- Status = LibUpdateFileExplorer (QuestionId);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Create a menu entry by given menu type.
-
- @retval NULL If failed to create the menu.
- @return the new menu entry.
-
-**/
-MENU_ENTRY *
-LibCreateMenuEntry (
- VOID
- )
-{
- MENU_ENTRY *MenuEntry;
-
- //
- // Create new menu entry
- //
- MenuEntry = AllocateZeroPool (sizeof (MENU_ENTRY));
- if (MenuEntry == NULL) {
- return NULL;
- }
-
- MenuEntry->VariableContext = AllocateZeroPool (sizeof (FILE_CONTEXT));
- if (MenuEntry->VariableContext == NULL) {
- FreePool (MenuEntry);
- return NULL;
- }
-
- MenuEntry->Signature = MENU_ENTRY_SIGNATURE;
- return MenuEntry;
-}
-
-/**
- Get the Menu Entry from the list in Menu Entry List.
-
- If MenuNumber is great or equal to the number of Menu
- Entry in the list, then ASSERT.
-
- @param MenuOption The Menu Entry List to read the menu entry.
- @param MenuNumber The index of Menu Entry.
-
- @return The Menu Entry.
-
-**/
-MENU_ENTRY *
-LibGetMenuEntry (
- MENU_OPTION *MenuOption,
- UINTN MenuNumber
- )
-{
- MENU_ENTRY *NewMenuEntry;
- UINTN Index;
- LIST_ENTRY *List;
-
- ASSERT (MenuNumber < MenuOption->MenuNumber);
-
- List = MenuOption->Head.ForwardLink;
- for (Index = 0; Index < MenuNumber; Index++) {
- List = List->ForwardLink;
- }
-
- NewMenuEntry = CR (List, MENU_ENTRY, Link, MENU_ENTRY_SIGNATURE);
-
- return NewMenuEntry;
-}
-
-/**
- Free up all resource allocated for a BM_MENU_ENTRY.
-
- @param MenuEntry A pointer to BM_MENU_ENTRY.
-
-**/
-VOID
-LibDestroyMenuEntry (
- MENU_ENTRY *MenuEntry
- )
-{
- FILE_CONTEXT *FileContext;
-
- FileContext = (FILE_CONTEXT *)MenuEntry->VariableContext;
-
- if (!FileContext->IsRoot) {
- if (FileContext->DevicePath != NULL) {
- FreePool (FileContext->DevicePath);
- }
- } else {
- if (FileContext->FileHandle != NULL) {
- FileContext->FileHandle->Close (FileContext->FileHandle);
- }
- }
-
- if (FileContext->FileName != NULL) {
- FreePool (FileContext->FileName);
- }
-
- FreePool (FileContext);
-
- if (MenuEntry->DisplayString != NULL) {
- FreePool (MenuEntry->DisplayString);
- }
-
- if (MenuEntry->HelpString != NULL) {
- FreePool (MenuEntry->HelpString);
- }
-
- FreePool (MenuEntry);
-}
-
-/**
- Free resources allocated in Allocate Rountine.
-
- @param FreeMenu Menu to be freed
-**/
-VOID
-LibFreeMenu (
- MENU_OPTION *FreeMenu
- )
-{
- MENU_ENTRY *MenuEntry;
-
- while (!IsListEmpty (&FreeMenu->Head)) {
- MenuEntry = CR (
- FreeMenu->Head.ForwardLink,
- MENU_ENTRY,
- Link,
- MENU_ENTRY_SIGNATURE
- );
- RemoveEntryList (&MenuEntry->Link);
- LibDestroyMenuEntry (MenuEntry);
- }
-
- FreeMenu->MenuNumber = 0;
-}
-
-/**
-
- 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;
-}
-
-/**
- This function converts an input device structure to a Unicode string.
-
- @param DevPath A pointer to the device path structure.
-
- @return A new allocated Unicode string that represents the device path.
-
-**/
-CHAR16 *
-LibDevicePathToStr (
- IN EFI_DEVICE_PATH_PROTOCOL *DevPath
- )
-{
- EFI_STATUS Status;
- CHAR16 *ToText;
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
-
- if (DevPath == NULL) {
- return NULL;
- }
-
- Status = gBS->LocateProtocol (
- &gEfiDevicePathToTextProtocolGuid,
- NULL,
- (VOID **)&DevPathToText
- );
- ASSERT_EFI_ERROR (Status);
- ToText = DevPathToText->ConvertDevicePathToText (
- DevPath,
- FALSE,
- TRUE
- );
- ASSERT (ToText != NULL);
-
- return ToText;
-}
-
-/**
- Duplicate a string.
-
- @param Src The source.
-
- @return A new string which is duplicated copy of the source.
- @retval NULL If there is not enough memory.
-
-**/
-CHAR16 *
-LibStrDuplicate (
- IN CHAR16 *Src
- )
-{
- CHAR16 *Dest;
- UINTN Size;
-
- Size = StrSize (Src);
- Dest = AllocateZeroPool (Size);
- ASSERT (Dest != NULL);
- if (Dest != NULL) {
- CopyMem (Dest, Src, Size);
- }
-
- return Dest;
-}
-
-/**
-
- Function gets the file information from an open file descriptor, and stores it
- in a buffer allocated from pool.
-
- @param FHand File Handle.
- @param InfoType Info type need to get.
-
- @retval A pointer to a buffer with file information or NULL is returned
-
-**/
-VOID *
-LibFileInfo (
- IN EFI_FILE_HANDLE FHand,
- IN EFI_GUID *InfoType
- )
-{
- EFI_STATUS Status;
- EFI_FILE_INFO *Buffer;
- UINTN BufferSize;
-
- Buffer = NULL;
- BufferSize = 0;
-
- Status = FHand->GetInfo (
- FHand,
- InfoType,
- &BufferSize,
- Buffer
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- Buffer = AllocatePool (BufferSize);
- ASSERT (Buffer != NULL);
- }
-
- Status = FHand->GetInfo (
- FHand,
- InfoType,
- &BufferSize,
- Buffer
- );
-
- return Buffer;
-}
-
-/**
-
- Get file type base on the file name.
- Just cut the file name, from the ".". eg ".efi"
-
- @param FileName File need to be checked.
-
- @retval the file type string.
-
-**/
-CHAR16 *
-LibGetTypeFromName (
- IN CHAR16 *FileName
- )
-{
- UINTN Index;
-
- Index = StrLen (FileName) - 1;
- while ((FileName[Index] != L'.') && (Index != 0)) {
- Index--;
- }
-
- return Index == 0 ? NULL : &FileName[Index];
-}
-
-/**
- Converts the unicode character of the string from uppercase to lowercase.
- This is a internal function.
-
- @param ConfigString String to be converted
-
-**/
-VOID
-LibToLowerString (
- IN CHAR16 *String
- )
-{
- CHAR16 *TmpStr;
-
- for (TmpStr = String; *TmpStr != L'\0'; TmpStr++) {
- if ((*TmpStr >= L'A') && (*TmpStr <= L'Z')) {
- *TmpStr = (CHAR16)(*TmpStr - L'A' + L'a');
- }
- }
-}
-
-/**
-
- Check whether current FileName point to a valid
- Efi Image File.
-
- @param FileName File need to be checked.
-
- @retval TRUE Is Efi Image
- @retval FALSE Not a valid Efi Image
-
-**/
-BOOLEAN
-LibIsSupportedFileType (
- IN UINT16 *FileName
- )
-{
- CHAR16 *InputFileType;
- CHAR16 *TmpStr;
- BOOLEAN IsSupported;
-
- if (gFileExplorerPrivate.FileType == NULL) {
- return TRUE;
- }
-
- InputFileType = LibGetTypeFromName (FileName);
- //
- // If the file not has *.* style, always return TRUE.
- //
- if (InputFileType == NULL) {
- return TRUE;
- }
-
- TmpStr = AllocateCopyPool (StrSize (InputFileType), InputFileType);
- ASSERT (TmpStr != NULL);
- LibToLowerString (TmpStr);
-
- IsSupported = (StrStr (gFileExplorerPrivate.FileType, TmpStr) == NULL ? FALSE : TRUE);
-
- FreePool (TmpStr);
- return IsSupported;
-}
-
-/**
-
- Append file name to existing file name.
-
- @param Str1 The existing file name
- @param Str2 The file name to be appended
-
- @return Allocate a new string to hold the appended result.
- Caller is responsible to free the returned string.
-
-**/
-CHAR16 *
-LibAppendFileName (
- IN CHAR16 *Str1,
- IN CHAR16 *Str2
- )
-{
- UINTN Size1;
- UINTN Size2;
- UINTN MaxLen;
- CHAR16 *Str;
- CHAR16 *TmpStr;
- CHAR16 *Ptr;
- CHAR16 *LastSlash;
-
- Size1 = StrSize (Str1);
- Size2 = StrSize (Str2);
-
- //
- // Check overflow
- //
- if (((MAX_UINTN - Size1) < Size2) || ((MAX_UINTN - Size1 - Size2) < sizeof (CHAR16))) {
- return NULL;
- }
-
- MaxLen = (Size1 + Size2 + sizeof (CHAR16))/ sizeof (CHAR16);
- Str = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));
- ASSERT (Str != NULL);
-
- TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));
- ASSERT (TmpStr != NULL);
-
- StrCpyS (Str, MaxLen, Str1);
- if (!((*Str == '\\') && (*(Str + 1) == 0))) {
- StrCatS (Str, MaxLen, L"\\");
- }
-
- StrCatS (Str, MaxLen, Str2);
-
- Ptr = Str;
- LastSlash = Str;
- while (*Ptr != 0) {
- if ((*Ptr == '\\') && (*(Ptr + 1) == '.') && (*(Ptr + 2) == '.') && (*(Ptr + 3) == L'\\')) {
- //
- // Convert "\Name\..\" to "\"
- // DO NOT convert the .. if it is at the end of the string. This will
- // break the .. behavior in changing directories.
- //
-
- //
- // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings
- // that overlap.
- //
- StrCpyS (TmpStr, MaxLen, Ptr + 3);
- StrCpyS (LastSlash, MaxLen - ((UINTN)LastSlash - (UINTN)Str) / sizeof (CHAR16), TmpStr);
- Ptr = LastSlash;
- } else if ((*Ptr == '\\') && (*(Ptr + 1) == '.') && (*(Ptr + 2) == '\\')) {
- //
- // Convert a "\.\" to a "\"
- //
-
- //
- // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings
- // that overlap.
- //
- StrCpyS (TmpStr, MaxLen, Ptr + 2);
- StrCpyS (Ptr, MaxLen - ((UINTN)Ptr - (UINTN)Str) / sizeof (CHAR16), TmpStr);
- Ptr = LastSlash;
- } else if (*Ptr == '\\') {
- LastSlash = Ptr;
- }
-
- Ptr++;
- }
-
- FreePool (TmpStr);
-
- return Str;
-}
-
-/**
- This function build the FsOptionMenu list which records all
- available file system in the system. They includes all instances
- of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM.
-
-
- @retval EFI_SUCCESS Success find the file system
- @retval EFI_OUT_OF_RESOURCES Can not create menu entry
-
-**/
-EFI_STATUS
-LibFindFileSystem (
- VOID
- )
-{
- UINTN NoSimpleFsHandles;
- EFI_HANDLE *SimpleFsHandle;
- UINT16 *VolumeLabel;
- UINTN Index;
- EFI_STATUS Status;
- MENU_ENTRY *MenuEntry;
- FILE_CONTEXT *FileContext;
- UINTN OptionNumber;
- EFI_FILE_SYSTEM_VOLUME_LABEL *Info;
-
- NoSimpleFsHandles = 0;
- OptionNumber = 0;
-
- //
- // Locate Handles that support Simple File System protocol
- //
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiSimpleFileSystemProtocolGuid,
- NULL,
- &NoSimpleFsHandles,
- &SimpleFsHandle
- );
- if (!EFI_ERROR (Status)) {
- //
- // Find all the instances of the File System prototocol
- //
- for (Index = 0; Index < NoSimpleFsHandles; Index++) {
- //
- // Allocate pool for this load option
- //
- MenuEntry = LibCreateMenuEntry ();
- if (NULL == MenuEntry) {
- FreePool (SimpleFsHandle);
- return EFI_OUT_OF_RESOURCES;
- }
-
- FileContext = (FILE_CONTEXT *)MenuEntry->VariableContext;
- FileContext->DeviceHandle = SimpleFsHandle[Index];
- FileContext->FileHandle = LibOpenRoot (FileContext->DeviceHandle);
- if (FileContext->FileHandle == NULL) {
- LibDestroyMenuEntry (MenuEntry);
- continue;
- }
-
- MenuEntry->HelpString = LibDevicePathToStr (DevicePathFromHandle (FileContext->DeviceHandle));
- FileContext->FileName = LibStrDuplicate (L"\\");
- FileContext->DevicePath = FileDevicePath (FileContext->DeviceHandle, FileContext->FileName);
- FileContext->IsDir = TRUE;
- FileContext->IsRoot = TRUE;
-
- //
- // Get current file system's Volume Label
- //
- Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *)LibFileInfo (FileContext->FileHandle, &gEfiFileSystemVolumeLabelInfoIdGuid);
- if (Info == NULL) {
- VolumeLabel = L"NO FILE SYSTEM INFO";
- } else {
- VolumeLabel = Info->VolumeLabel;
- if (*VolumeLabel == 0x0000) {
- VolumeLabel = L"NO VOLUME LABEL";
- }
- }
-
- MenuEntry->DisplayString = AllocateZeroPool (MAX_CHAR);
- ASSERT (MenuEntry->DisplayString != NULL);
- UnicodeSPrint (
- MenuEntry->DisplayString,
- MAX_CHAR,
- L"%s, [%s]",
- VolumeLabel,
- MenuEntry->HelpString
- );
- MenuEntry->DisplayStringToken = HiiSetString (
- gFileExplorerPrivate.FeHiiHandle,
- 0,
- MenuEntry->DisplayString,
- NULL
- );
-
- if (Info != NULL) {
- FreePool (Info);
- }
-
- OptionNumber++;
- InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link);
- }
- }
-
- if (NoSimpleFsHandles != 0) {
- FreePool (SimpleFsHandle);
- }
-
- gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber;
-
- 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;
-}
-
-/**
- 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;
-}
-
-/**
- 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;
-
- if (EFI_ERROR (LibGetFileHandleFromDevicePath (gFileExplorerPrivate.RetDevicePath, &FileHandle, &ParentName, &DeviceHandle))) {
- return EFI_DEVICE_ERROR;
- }
-
- 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;
-}
-
-/**
- Find files under current directory.
-
- All files and sub-directories in current directory
- will be stored in DirectoryMenu for future use.
-
- @param FileHandle Parent file handle.
- @param FileName Parent file name.
- @param DeviceHandle Driver handle for this partition.
-
- @retval EFI_SUCCESS Get files from current dir successfully.
- @return Other value if can't get files from current dir.
-
-**/
-EFI_STATUS
-LibFindFiles (
- IN EFI_FILE_HANDLE FileHandle,
- IN UINT16 *FileName,
- IN EFI_HANDLE DeviceHandle
- )
-{
- EFI_FILE_INFO *DirInfo;
- UINTN BufferSize;
- UINTN DirBufferSize;
- MENU_ENTRY *NewMenuEntry;
- FILE_CONTEXT *NewFileContext;
- UINTN Pass;
- EFI_STATUS Status;
- UINTN OptionNumber;
-
- OptionNumber = 0;
-
- DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;
- DirInfo = AllocateZeroPool (DirBufferSize);
- if (DirInfo == NULL) {
- 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
- //
- Status = EFI_SUCCESS;
- for (Pass = 1; Pass <= 2; Pass++) {
- FileHandle->SetPosition (FileHandle, 0);
- for ( ; ;) {
- BufferSize = DirBufferSize;
- Status = FileHandle->Read (FileHandle, &BufferSize, DirInfo);
- if (EFI_ERROR (Status) || (BufferSize == 0)) {
- Status = EFI_SUCCESS;
- break;
- }
-
- if ((((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0) && (Pass == 2)) ||
- (((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) && (Pass == 1))
- )
- {
- //
- // Pass 1 is for Directories
- // Pass 2 is for file names
- //
- continue;
- }
-
- if (!(((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0) || LibIsSupportedFileType (DirInfo->FileName))) {
- //
- // Slip file unless it is a directory entry or a .EFI file
- //
- continue;
- }
-
- NewMenuEntry = LibCreateMenuEntry ();
- if (NULL == NewMenuEntry) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext;
- NewFileContext->DeviceHandle = DeviceHandle;
- NewFileContext->FileName = LibAppendFileName (FileName, DirInfo->FileName);
- if (NewFileContext->FileName == NULL) {
- LibDestroyMenuEntry (NewMenuEntry);
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- NewFileContext->FileHandle = FileHandle;
- NewFileContext->DevicePath = FileDevicePath (NewFileContext->DeviceHandle, NewFileContext->FileName);
- NewMenuEntry->HelpString = NULL;
- NewFileContext->IsDir = (BOOLEAN)((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);
-
- if (NewFileContext->IsDir) {
- BufferSize = StrLen (DirInfo->FileName) * 2 + 6;
- NewMenuEntry->DisplayString = AllocateZeroPool (BufferSize);
- UnicodeSPrint (
- NewMenuEntry->DisplayString,
- BufferSize,
- L"<%s>",
- DirInfo->FileName
- );
- } else {
- NewMenuEntry->DisplayString = LibStrDuplicate (DirInfo->FileName);
- }
-
- NewMenuEntry->DisplayStringToken = HiiSetString (
- gFileExplorerPrivate.FeHiiHandle,
- 0,
- NewMenuEntry->DisplayString,
- NULL
- );
-
- NewFileContext->IsRoot = FALSE;
-
- OptionNumber++;
- InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &NewMenuEntry->Link);
- }
- }
-
- gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber;
-
-Done:
-
- FreePool (DirInfo);
-
- return Status;
-}
-
-/**
- Refresh the global UpdateData structure.
-
-**/
-VOID
-LibRefreshUpdateData (
- VOID
- )
-{
- //
- // Free current updated date
- //
- if (mLibStartOpCodeHandle != NULL) {
- HiiFreeOpCodeHandle (mLibStartOpCodeHandle);
- }
-
- if (mLibEndOpCodeHandle != NULL) {
- HiiFreeOpCodeHandle (mLibEndOpCodeHandle);
- }
-
- //
- // Create new OpCode Handle
- //
- mLibStartOpCodeHandle = HiiAllocateOpCodeHandle ();
- mLibEndOpCodeHandle = HiiAllocateOpCodeHandle ();
-
- //
- // Create Hii Extend Label OpCode as the start opcode
- //
- mLibStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
- mLibStartOpCodeHandle,
- &gEfiIfrTianoGuid,
- NULL,
- sizeof (EFI_IFR_GUID_LABEL)
- );
- mLibStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
-
- mLibStartLabel->Number = FORM_FILE_EXPLORER_ID;
-
- //
- // Create Hii Extend Label OpCode as the start opcode
- //
- mLibEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
- mLibEndOpCodeHandle,
- &gEfiIfrTianoGuid,
- NULL,
- sizeof (EFI_IFR_GUID_LABEL)
- );
- mLibEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
-
- mLibEndLabel->Number = LABEL_END;
-}
-
-/**
-
- Update the File Explore page.
-
-**/
-VOID
-LibUpdateFileExplorePage (
- VOID
- )
-{
- UINTN Index;
- MENU_ENTRY *NewMenuEntry;
- FILE_CONTEXT *NewFileContext;
- MENU_OPTION *MenuOption;
- BOOLEAN CreateNewFile;
-
- NewMenuEntry = NULL;
- NewFileContext = NULL;
- CreateNewFile = FALSE;
-
- LibRefreshUpdateData ();
- MenuOption = gFileExplorerPrivate.FsOptionMenu;
-
- mQuestionIdUpdate += QUESTION_ID_UPDATE_STEP;
-
- for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
- NewMenuEntry = LibGetMenuEntry (MenuOption, Index);
- NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext;
-
- if (!NewFileContext->IsRoot && !CreateNewFile) {
- HiiCreateGotoOpCode (
- mLibStartOpCodeHandle,
- FORM_ADD_NEW_FILE_ID,
- STRING_TOKEN (STR_NEW_FILE),
- STRING_TOKEN (STR_NEW_FILE_HELP),
- EFI_IFR_FLAG_CALLBACK,
- (UINT16)(mNewFileQuestionId++)
- );
- HiiCreateGotoOpCode (
- mLibStartOpCodeHandle,
- FORM_ADD_NEW_FOLDER_ID,
- STRING_TOKEN (STR_NEW_FOLDER),
- STRING_TOKEN (STR_NEW_FOLDER_HELP),
- EFI_IFR_FLAG_CALLBACK,
- (UINT16)(mNewFolderQuestionId++)
- );
- HiiCreateTextOpCode (
- mLibStartOpCodeHandle,
- STRING_TOKEN (STR_NULL_STRING),
- STRING_TOKEN (STR_NULL_STRING),
- 0
- );
- CreateNewFile = TRUE;
- }
-
- if (!NewFileContext->IsDir) {
- //
- // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
- //
- HiiCreateActionOpCode (
- mLibStartOpCodeHandle,
- (UINT16)(FILE_OPTION_OFFSET + Index + mQuestionIdUpdate),
- NewMenuEntry->DisplayStringToken,
- STRING_TOKEN (STR_NULL_STRING),
- EFI_IFR_FLAG_CALLBACK,
- 0
- );
- } else {
- //
- // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.
- //
- HiiCreateGotoOpCode (
- mLibStartOpCodeHandle,
- FORM_FILE_EXPLORER_ID,
- NewMenuEntry->DisplayStringToken,
- STRING_TOKEN (STR_NULL_STRING),
- EFI_IFR_FLAG_CALLBACK,
- (UINT16)(FILE_OPTION_OFFSET + Index + mQuestionIdUpdate)
- );
- }
- }
-
- HiiUpdateForm (
- gFileExplorerPrivate.FeHiiHandle,
- &FileExplorerGuid,
- FORM_FILE_EXPLORER_ID,
- mLibStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID
- mLibEndOpCodeHandle // LABEL_END
- );
-}
-
-/**
- Update the file explower page with the refershed file system.
-
- @param KeyValue Key value to identify the type of data to expect.
-
- @retval EFI_SUCCESS Update the file explorer form success.
- @retval other errors Error occur when parse one directory.
-
-**/
-EFI_STATUS
-LibUpdateFileExplorer (
- IN UINT16 KeyValue
- )
-{
- UINT16 FileOptionMask;
- MENU_ENTRY *NewMenuEntry;
- FILE_CONTEXT *NewFileContext;
- EFI_STATUS Status;
- EFI_FILE_HANDLE FileHandle;
-
- Status = EFI_SUCCESS;
- FileOptionMask = (UINT16)(FILE_OPTION_MASK & KeyValue) - mQuestionIdUpdate;
- NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);
- NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext;
-
- if (NewFileContext->IsDir) {
- RemoveEntryList (&NewMenuEntry->Link);
- LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);
- Status = LibGetFileHandleFromMenu (NewMenuEntry, &FileHandle);
- if (!EFI_ERROR (Status)) {
- Status = LibFindFiles (FileHandle, NewFileContext->FileName, NewFileContext->DeviceHandle);
- if (!EFI_ERROR (Status)) {
- LibUpdateFileExplorePage ();
- } else {
- LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);
- }
- }
-
- LibDestroyMenuEntry (NewMenuEntry);
- }
-
- return Status;
-}
-
-/**
- Get the device path info saved in the menu structure.
-
- @param KeyValue Key value to identify the type of data to expect.
-
-**/
-VOID
-LibGetDevicePath (
- IN UINT16 KeyValue
- )
-{
- UINT16 FileOptionMask;
- MENU_ENTRY *NewMenuEntry;
- FILE_CONTEXT *NewFileContext;
-
- FileOptionMask = (UINT16)(FILE_OPTION_MASK & KeyValue) - mQuestionIdUpdate;
-
- NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);
-
- NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext;
-
- if (gFileExplorerPrivate.RetDevicePath != NULL) {
- FreePool (gFileExplorerPrivate.RetDevicePath);
- }
-
- gFileExplorerPrivate.RetDevicePath = DuplicateDevicePath (NewFileContext->DevicePath);
-}
-
-/**
- Choose a file in the specified directory.
-
- If user input NULL for the RootDirectory, will choose file in the system.
-
- If user input *File != NULL, function will return the allocate device path
- info for the choosed file, caller has to free the memory after use it.
-
- @param RootDirectory Pointer to the root directory.
- @param FileType The file type need to choose.
- @param ChooseHandler Function pointer to the extra task need to do
- after choose one file.
- @param File Return the device path for the last time chosed file.
-
- @retval EFI_SUCESS Choose file success.
- @retval EFI_INVALID_PARAMETER Both ChooseHandler and return device path are NULL
- One of them must not NULL.
- @retval Other errors Choose file failed.
-**/
-EFI_STATUS
-EFIAPI
-ChooseFile (
- IN EFI_DEVICE_PATH_PROTOCOL *RootDirectory,
- IN CHAR16 *FileType OPTIONAL,
- IN CHOOSE_HANDLER ChooseHandler OPTIONAL,
- OUT EFI_DEVICE_PATH_PROTOCOL **File OPTIONAL
- )
-{
- EFI_FILE_HANDLE FileHandle;
- EFI_STATUS Status;
- UINT16 *FileName;
- EFI_HANDLE DeviceHandle;
-
- if ((ChooseHandler == NULL) && (File == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- mQuestionIdUpdate = 0;
- FileName = NULL;
-
- gFileExplorerPrivate.RetDevicePath = NULL;
- gFileExplorerPrivate.ChooseHandler = ChooseHandler;
- if (FileType != NULL) {
- gFileExplorerPrivate.FileType = AllocateCopyPool (StrSize (FileType), FileType);
- ASSERT (gFileExplorerPrivate.FileType != NULL);
- LibToLowerString (gFileExplorerPrivate.FileType);
- } else {
- gFileExplorerPrivate.FileType = NULL;
- }
-
- if (RootDirectory == NULL) {
- Status = LibFindFileSystem ();
- } else {
- Status = LibGetFileHandleFromDevicePath (RootDirectory, &FileHandle, &FileName, &DeviceHandle);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- Status = LibFindFiles (FileHandle, FileName, DeviceHandle);
- }
-
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- LibUpdateFileExplorePage ();
-
- gFileExplorerPrivate.FormBrowser2->SendForm (
- gFileExplorerPrivate.FormBrowser2,
- &gFileExplorerPrivate.FeHiiHandle,
- 1,
- &FileExplorerGuid,
- 0,
- NULL,
- NULL
- );
-
-Done:
- if ((Status == EFI_SUCCESS) && (File != NULL)) {
- *File = gFileExplorerPrivate.RetDevicePath;
- } else if (gFileExplorerPrivate.RetDevicePath != NULL) {
- FreePool (gFileExplorerPrivate.RetDevicePath);
- }
-
- if (gFileExplorerPrivate.FileType != NULL) {
- FreePool (gFileExplorerPrivate.FileType);
- }
-
- LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);
-
- if (FileName != NULL) {
- FreePool (FileName);
- }
-
- return Status;
-}
-
-/**
-
- Install Boot Manager Menu driver.
-
- @param ImageHandle The image handle.
- @param SystemTable The system table.
-
- @retval EFI_SUCEESS Install File explorer library success.
-
-**/
-EFI_STATUS
-EFIAPI
-FileExplorerLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- gHiiVendorDevicePath = (HII_VENDOR_DEVICE_PATH *)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)&FeHiiVendorDevicePath);
- ASSERT (gHiiVendorDevicePath != NULL);
- CopyGuid (&gHiiVendorDevicePath->VendorDevicePath.Guid, &gEfiCallerIdGuid);
-
- //
- // Install Device Path Protocol and Config Access protocol to driver handle
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &gFileExplorerPrivate.FeDriverHandle,
- &gEfiDevicePathProtocolGuid,
- gHiiVendorDevicePath,
- &gEfiHiiConfigAccessProtocolGuid,
- &gFileExplorerPrivate.FeConfigAccess,
- NULL
- );
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Post our File Explorer VFR binary to the HII database.
- //
- gFileExplorerPrivate.FeHiiHandle = HiiAddPackages (
- &FileExplorerGuid,
- gFileExplorerPrivate.FeDriverHandle,
- FileExplorerVfrBin,
- FileExplorerLibStrings,
- NULL
- );
- ASSERT (gFileExplorerPrivate.FeHiiHandle != NULL);
-
- //
- // Locate Formbrowser2 protocol
- //
- Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&gFileExplorerPrivate.FormBrowser2);
- ASSERT_EFI_ERROR (Status);
-
- InitializeListHead (&gFileExplorerPrivate.FsOptionMenu->Head);
-
- return EFI_SUCCESS;
-}
-
-/**
- Unloads the application and its installed protocol.
-
- @param[in] ImageHandle Handle that identifies the image to be unloaded.
- @param[in] SystemTable The system table.
-
- @retval EFI_SUCCESS The image has been unloaded.
-**/
-EFI_STATUS
-EFIAPI
-FileExplorerLibDestructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- ASSERT (gHiiVendorDevicePath != NULL);
-
- if (gFileExplorerPrivate.FeDriverHandle != NULL) {
- Status = gBS->UninstallMultipleProtocolInterfaces (
- gFileExplorerPrivate.FeDriverHandle,
- &gEfiDevicePathProtocolGuid,
- gHiiVendorDevicePath,
- &gEfiHiiConfigAccessProtocolGuid,
- &gFileExplorerPrivate.FeConfigAccess,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- HiiRemovePackages (gFileExplorerPrivate.FeHiiHandle);
- gFileExplorerPrivate.FeDriverHandle = NULL;
- }
-
- FreePool (gHiiVendorDevicePath);
-
- return EFI_SUCCESS;
-}
+/** @file +File explorer related functions. + +Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "FileExplorer.h" + +EFI_GUID FileExplorerGuid = EFI_FILE_EXPLORE_FORMSET_GUID; + +/// +/// File system selection menu +/// +MENU_OPTION mFsOptionMenu = { + MENU_OPTION_SIGNATURE, + { NULL }, + 0, + FALSE +}; + +FILE_EXPLORER_CALLBACK_DATA gFileExplorerPrivate = { + FILE_EXPLORER_CALLBACK_DATA_SIGNATURE, + NULL, + NULL, + { + LibExtractConfig, + LibRouteConfig, + LibCallback + }, + NULL, + &mFsOptionMenu, + 0 +}; + +HII_VENDOR_DEVICE_PATH *gHiiVendorDevicePath; + +HII_VENDOR_DEVICE_PATH FeHiiVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + // + // Will be replace with gEfiCallerIdGuid in code. + // + { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + } + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8)(END_DEVICE_PATH_LENGTH), + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +VOID *mLibStartOpCodeHandle = NULL; +VOID *mLibEndOpCodeHandle = NULL; +EFI_IFR_GUID_LABEL *mLibStartLabel = NULL; +EFI_IFR_GUID_LABEL *mLibEndLabel = NULL; +UINT16 mQuestionIdUpdate; +CHAR16 mNewFileName[MAX_FILE_NAME_LEN]; +CHAR16 mNewFolderName[MAX_FOLDER_NAME_LEN]; +UINTN mNewFileQuestionId = NEW_FILE_QUESTION_ID_BASE; +UINTN mNewFolderQuestionId = NEW_FOLDER_QUESTION_ID_BASE; + +/** + Create a new file or folder in current directory. + + @param FileName Point to the fileNmae or folder. + @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 + ); + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Request A null-terminated Unicode string in <ConfigRequest> format. + @param Progress On return, points to a character in the Request string. + Points to the string's null terminator if request was successful. + Points to the most recent '&' before the first failing name/value + pair (or the beginning of the string if the failure is in the + first name/value pair) if the request was not successful. + @param Results A null-terminated Unicode string in <ConfigAltResp> format which + has all values filled in for the names in the Request string. + String to be allocated by the called function. + + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. + +**/ +EFI_STATUS +EFIAPI +LibExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + if ((Progress == NULL) || (Results == NULL)) { + return EFI_INVALID_PARAMETER; + } + + *Progress = Request; + return EFI_NOT_FOUND; +} + +/** + This function processes the results of changes in configuration. + + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Configuration A null-terminated Unicode string in <ConfigResp> format. + @param Progress A pointer to a string filled in with the offset of the most + recent '&' before the first failing name/value pair (or the + beginning of the string if the failure is in the first + name/value pair) or the terminating NULL if all was successful. + + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. + +**/ +EFI_STATUS +EFIAPI +LibRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + if ((Configuration == NULL) || (Progress == NULL)) { + return EFI_INVALID_PARAMETER; + } + + *Progress = Configuration; + return EFI_NOT_FOUND; +} + +/** + This function processes the results of changes in configuration. + When user select a interactive opcode, this callback will be triggered. + Based on the Question(QuestionId) that triggers the callback, the corresponding + actions is performed. It handles: + + 1) Process the axtra action or exit file explorer when user select one file . + 2) update of file content if a dir is selected. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original exporting driver + so that it can identify the type of data to expect. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original exporting driver. + @param ActionRequest On return, points to the action requested by the callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval other error Error occur when parse one directory. +**/ +EFI_STATUS +EFIAPI +LibCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + EFI_STATUS Status; + BOOLEAN NeedExit; + CHAR16 *NewFileName; + CHAR16 *NewFolderName; + + NeedExit = TRUE; + NewFileName = NULL; + NewFolderName = NULL; + + if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) { + // + // Do nothing for other UEFI Action. Only do call back when data is changed. + // + return EFI_UNSUPPORTED; + } + + if (Action == EFI_BROWSER_ACTION_CHANGED) { + if ((Value == NULL) || (ActionRequest == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (QuestionId == KEY_VALUE_CREATE_FILE_AND_EXIT) { + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + if (!IsZeroBuffer (mNewFileName, sizeof (mNewFileName))) { + Status = LibCreateNewFile (mNewFileName, TRUE); + ZeroMem (mNewFileName, sizeof (mNewFileName)); + } + } + + if (QuestionId == KEY_VALUE_NO_CREATE_FILE_AND_EXIT) { + ZeroMem (mNewFileName, sizeof (mNewFileName)); + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + } + + if (QuestionId == KEY_VALUE_CREATE_FOLDER_AND_EXIT) { + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + if (!IsZeroBuffer (mNewFolderName, sizeof (mNewFolderName))) { + Status = LibCreateNewFile (mNewFolderName, FALSE); + ZeroMem (mNewFolderName, sizeof (mNewFolderName)); + } + } + + if (QuestionId == KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT) { + ZeroMem (mNewFolderName, sizeof (mNewFolderName)); + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + } + + if (QuestionId == NEW_FILE_NAME_ID) { + NewFileName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL); + if (NewFileName != NULL) { + StrCpyS (mNewFileName, MAX_FILE_NAME_LEN, NewFileName); + FreePool (NewFileName); + NewFileName = NULL; + } else { + return EFI_INVALID_PARAMETER; + } + } + + if (QuestionId == NEW_FOLDER_NAME_ID) { + NewFolderName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL); + if (NewFolderName != NULL) { + StrCpyS (mNewFolderName, MAX_FOLDER_NAME_LEN, NewFolderName); + FreePool (NewFolderName); + NewFolderName = NULL; + } else { + return EFI_INVALID_PARAMETER; + } + } + + if (QuestionId >= FILE_OPTION_OFFSET) { + LibGetDevicePath (QuestionId); + + // + // Process the extra action. + // + if (gFileExplorerPrivate.ChooseHandler != NULL) { + NeedExit = gFileExplorerPrivate.ChooseHandler (gFileExplorerPrivate.RetDevicePath); + } + + if (NeedExit) { + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + } + } + } else if (Action == EFI_BROWSER_ACTION_CHANGING) { + if (Value == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (QuestionId >= FILE_OPTION_OFFSET) { + LibGetDevicePath (QuestionId); + Status = LibUpdateFileExplorer (QuestionId); + if (EFI_ERROR (Status)) { + return Status; + } + } + } + + return EFI_SUCCESS; +} + +/** + Create a menu entry by given menu type. + + @retval NULL If failed to create the menu. + @return the new menu entry. + +**/ +MENU_ENTRY * +LibCreateMenuEntry ( + VOID + ) +{ + MENU_ENTRY *MenuEntry; + + // + // Create new menu entry + // + MenuEntry = AllocateZeroPool (sizeof (MENU_ENTRY)); + if (MenuEntry == NULL) { + return NULL; + } + + MenuEntry->VariableContext = AllocateZeroPool (sizeof (FILE_CONTEXT)); + if (MenuEntry->VariableContext == NULL) { + FreePool (MenuEntry); + return NULL; + } + + MenuEntry->Signature = MENU_ENTRY_SIGNATURE; + return MenuEntry; +} + +/** + Get the Menu Entry from the list in Menu Entry List. + + If MenuNumber is great or equal to the number of Menu + Entry in the list, then ASSERT. + + @param MenuOption The Menu Entry List to read the menu entry. + @param MenuNumber The index of Menu Entry. + + @return The Menu Entry. + +**/ +MENU_ENTRY * +LibGetMenuEntry ( + MENU_OPTION *MenuOption, + UINTN MenuNumber + ) +{ + MENU_ENTRY *NewMenuEntry; + UINTN Index; + LIST_ENTRY *List; + + ASSERT (MenuNumber < MenuOption->MenuNumber); + + List = MenuOption->Head.ForwardLink; + for (Index = 0; Index < MenuNumber; Index++) { + List = List->ForwardLink; + } + + NewMenuEntry = CR (List, MENU_ENTRY, Link, MENU_ENTRY_SIGNATURE); + + return NewMenuEntry; +} + +/** + Free up all resource allocated for a BM_MENU_ENTRY. + + @param MenuEntry A pointer to BM_MENU_ENTRY. + +**/ +VOID +LibDestroyMenuEntry ( + MENU_ENTRY *MenuEntry + ) +{ + FILE_CONTEXT *FileContext; + + FileContext = (FILE_CONTEXT *)MenuEntry->VariableContext; + + if (!FileContext->IsRoot) { + if (FileContext->DevicePath != NULL) { + FreePool (FileContext->DevicePath); + } + } else { + if (FileContext->FileHandle != NULL) { + FileContext->FileHandle->Close (FileContext->FileHandle); + } + } + + if (FileContext->FileName != NULL) { + FreePool (FileContext->FileName); + } + + FreePool (FileContext); + + if (MenuEntry->DisplayString != NULL) { + FreePool (MenuEntry->DisplayString); + } + + if (MenuEntry->HelpString != NULL) { + FreePool (MenuEntry->HelpString); + } + + FreePool (MenuEntry); +} + +/** + Free resources allocated in Allocate Rountine. + + @param FreeMenu Menu to be freed +**/ +VOID +LibFreeMenu ( + MENU_OPTION *FreeMenu + ) +{ + MENU_ENTRY *MenuEntry; + + while (!IsListEmpty (&FreeMenu->Head)) { + MenuEntry = CR ( + FreeMenu->Head.ForwardLink, + MENU_ENTRY, + Link, + MENU_ENTRY_SIGNATURE + ); + RemoveEntryList (&MenuEntry->Link); + LibDestroyMenuEntry (MenuEntry); + } + + FreeMenu->MenuNumber = 0; +} + +/** + + 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; +} + +/** + This function converts an input device structure to a Unicode string. + + @param DevPath A pointer to the device path structure. + + @return A new allocated Unicode string that represents the device path. + +**/ +CHAR16 * +LibDevicePathToStr ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath + ) +{ + EFI_STATUS Status; + CHAR16 *ToText; + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText; + + if (DevPath == NULL) { + return NULL; + } + + Status = gBS->LocateProtocol ( + &gEfiDevicePathToTextProtocolGuid, + NULL, + (VOID **)&DevPathToText + ); + ASSERT_EFI_ERROR (Status); + ToText = DevPathToText->ConvertDevicePathToText ( + DevPath, + FALSE, + TRUE + ); + ASSERT (ToText != NULL); + + return ToText; +} + +/** + Duplicate a string. + + @param Src The source. + + @return A new string which is duplicated copy of the source. + @retval NULL If there is not enough memory. + +**/ +CHAR16 * +LibStrDuplicate ( + IN CHAR16 *Src + ) +{ + CHAR16 *Dest; + UINTN Size; + + Size = StrSize (Src); + Dest = AllocateZeroPool (Size); + ASSERT (Dest != NULL); + if (Dest != NULL) { + CopyMem (Dest, Src, Size); + } + + return Dest; +} + +/** + + Function gets the file information from an open file descriptor, and stores it + in a buffer allocated from pool. + + @param FHand File Handle. + @param InfoType Info type need to get. + + @retval A pointer to a buffer with file information or NULL is returned + +**/ +VOID * +LibFileInfo ( + IN EFI_FILE_HANDLE FHand, + IN EFI_GUID *InfoType + ) +{ + EFI_STATUS Status; + EFI_FILE_INFO *Buffer; + UINTN BufferSize; + + Buffer = NULL; + BufferSize = 0; + + Status = FHand->GetInfo ( + FHand, + InfoType, + &BufferSize, + Buffer + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = AllocatePool (BufferSize); + ASSERT (Buffer != NULL); + } + + Status = FHand->GetInfo ( + FHand, + InfoType, + &BufferSize, + Buffer + ); + + return Buffer; +} + +/** + + Get file type base on the file name. + Just cut the file name, from the ".". eg ".efi" + + @param FileName File need to be checked. + + @retval the file type string. + +**/ +CHAR16 * +LibGetTypeFromName ( + IN CHAR16 *FileName + ) +{ + UINTN Index; + + Index = StrLen (FileName) - 1; + while ((FileName[Index] != L'.') && (Index != 0)) { + Index--; + } + + return Index == 0 ? NULL : &FileName[Index]; +} + +/** + Converts the unicode character of the string from uppercase to lowercase. + This is a internal function. + + @param ConfigString String to be converted + +**/ +VOID +LibToLowerString ( + IN CHAR16 *String + ) +{ + CHAR16 *TmpStr; + + for (TmpStr = String; *TmpStr != L'\0'; TmpStr++) { + if ((*TmpStr >= L'A') && (*TmpStr <= L'Z')) { + *TmpStr = (CHAR16)(*TmpStr - L'A' + L'a'); + } + } +} + +/** + + Check whether current FileName point to a valid + Efi Image File. + + @param FileName File need to be checked. + + @retval TRUE Is Efi Image + @retval FALSE Not a valid Efi Image + +**/ +BOOLEAN +LibIsSupportedFileType ( + IN UINT16 *FileName + ) +{ + CHAR16 *InputFileType; + CHAR16 *TmpStr; + BOOLEAN IsSupported; + + if (gFileExplorerPrivate.FileType == NULL) { + return TRUE; + } + + InputFileType = LibGetTypeFromName (FileName); + // + // If the file not has *.* style, always return TRUE. + // + if (InputFileType == NULL) { + return TRUE; + } + + TmpStr = AllocateCopyPool (StrSize (InputFileType), InputFileType); + ASSERT (TmpStr != NULL); + LibToLowerString (TmpStr); + + IsSupported = (StrStr (gFileExplorerPrivate.FileType, TmpStr) == NULL ? FALSE : TRUE); + + FreePool (TmpStr); + return IsSupported; +} + +/** + + Append file name to existing file name. + + @param Str1 The existing file name + @param Str2 The file name to be appended + + @return Allocate a new string to hold the appended result. + Caller is responsible to free the returned string. + +**/ +CHAR16 * +LibAppendFileName ( + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ) +{ + UINTN Size1; + UINTN Size2; + UINTN MaxLen; + CHAR16 *Str; + CHAR16 *TmpStr; + CHAR16 *Ptr; + CHAR16 *LastSlash; + + Size1 = StrSize (Str1); + Size2 = StrSize (Str2); + + // + // Check overflow + // + if (((MAX_UINTN - Size1) < Size2) || ((MAX_UINTN - Size1 - Size2) < sizeof (CHAR16))) { + return NULL; + } + + MaxLen = (Size1 + Size2 + sizeof (CHAR16))/ sizeof (CHAR16); + Str = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); + ASSERT (Str != NULL); + + TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); + ASSERT (TmpStr != NULL); + + StrCpyS (Str, MaxLen, Str1); + if (!((*Str == '\\') && (*(Str + 1) == 0))) { + StrCatS (Str, MaxLen, L"\\"); + } + + StrCatS (Str, MaxLen, Str2); + + Ptr = Str; + LastSlash = Str; + while (*Ptr != 0) { + if ((*Ptr == '\\') && (*(Ptr + 1) == '.') && (*(Ptr + 2) == '.') && (*(Ptr + 3) == L'\\')) { + // + // Convert "\Name\..\" to "\" + // DO NOT convert the .. if it is at the end of the string. This will + // break the .. behavior in changing directories. + // + + // + // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings + // that overlap. + // + StrCpyS (TmpStr, MaxLen, Ptr + 3); + StrCpyS (LastSlash, MaxLen - ((UINTN)LastSlash - (UINTN)Str) / sizeof (CHAR16), TmpStr); + Ptr = LastSlash; + } else if ((*Ptr == '\\') && (*(Ptr + 1) == '.') && (*(Ptr + 2) == '\\')) { + // + // Convert a "\.\" to a "\" + // + + // + // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings + // that overlap. + // + StrCpyS (TmpStr, MaxLen, Ptr + 2); + StrCpyS (Ptr, MaxLen - ((UINTN)Ptr - (UINTN)Str) / sizeof (CHAR16), TmpStr); + Ptr = LastSlash; + } else if (*Ptr == '\\') { + LastSlash = Ptr; + } + + Ptr++; + } + + FreePool (TmpStr); + + return Str; +} + +/** + This function build the FsOptionMenu list which records all + available file system in the system. They includes all instances + of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM. + + + @retval EFI_SUCCESS Success find the file system + @retval EFI_OUT_OF_RESOURCES Can not create menu entry + +**/ +EFI_STATUS +LibFindFileSystem ( + VOID + ) +{ + UINTN NoSimpleFsHandles; + EFI_HANDLE *SimpleFsHandle; + UINT16 *VolumeLabel; + UINTN Index; + EFI_STATUS Status; + MENU_ENTRY *MenuEntry; + FILE_CONTEXT *FileContext; + UINTN OptionNumber; + EFI_FILE_SYSTEM_VOLUME_LABEL *Info; + + NoSimpleFsHandles = 0; + OptionNumber = 0; + + // + // Locate Handles that support Simple File System protocol + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &NoSimpleFsHandles, + &SimpleFsHandle + ); + if (!EFI_ERROR (Status)) { + // + // Find all the instances of the File System prototocol + // + for (Index = 0; Index < NoSimpleFsHandles; Index++) { + // + // Allocate pool for this load option + // + MenuEntry = LibCreateMenuEntry (); + if (NULL == MenuEntry) { + FreePool (SimpleFsHandle); + return EFI_OUT_OF_RESOURCES; + } + + FileContext = (FILE_CONTEXT *)MenuEntry->VariableContext; + FileContext->DeviceHandle = SimpleFsHandle[Index]; + FileContext->FileHandle = LibOpenRoot (FileContext->DeviceHandle); + if (FileContext->FileHandle == NULL) { + LibDestroyMenuEntry (MenuEntry); + continue; + } + + MenuEntry->HelpString = LibDevicePathToStr (DevicePathFromHandle (FileContext->DeviceHandle)); + FileContext->FileName = LibStrDuplicate (L"\\"); + FileContext->DevicePath = FileDevicePath (FileContext->DeviceHandle, FileContext->FileName); + FileContext->IsDir = TRUE; + FileContext->IsRoot = TRUE; + + // + // Get current file system's Volume Label + // + Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *)LibFileInfo (FileContext->FileHandle, &gEfiFileSystemVolumeLabelInfoIdGuid); + if (Info == NULL) { + VolumeLabel = L"NO FILE SYSTEM INFO"; + } else { + VolumeLabel = Info->VolumeLabel; + if (*VolumeLabel == 0x0000) { + VolumeLabel = L"NO VOLUME LABEL"; + } + } + + MenuEntry->DisplayString = AllocateZeroPool (MAX_CHAR); + ASSERT (MenuEntry->DisplayString != NULL); + UnicodeSPrint ( + MenuEntry->DisplayString, + MAX_CHAR, + L"%s, [%s]", + VolumeLabel, + MenuEntry->HelpString + ); + MenuEntry->DisplayStringToken = HiiSetString ( + gFileExplorerPrivate.FeHiiHandle, + 0, + MenuEntry->DisplayString, + NULL + ); + + if (Info != NULL) { + FreePool (Info); + } + + OptionNumber++; + InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link); + } + } + + if (NoSimpleFsHandles != 0) { + FreePool (SimpleFsHandle); + } + + gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber; + + 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; +} + +/** + 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; +} + +/** + 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; + + if (EFI_ERROR (LibGetFileHandleFromDevicePath (gFileExplorerPrivate.RetDevicePath, &FileHandle, &ParentName, &DeviceHandle))) { + return EFI_DEVICE_ERROR; + } + + 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; +} + +/** + Find files under current directory. + + All files and sub-directories in current directory + will be stored in DirectoryMenu for future use. + + @param FileHandle Parent file handle. + @param FileName Parent file name. + @param DeviceHandle Driver handle for this partition. + + @retval EFI_SUCCESS Get files from current dir successfully. + @return Other value if can't get files from current dir. + +**/ +EFI_STATUS +LibFindFiles ( + IN EFI_FILE_HANDLE FileHandle, + IN UINT16 *FileName, + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_FILE_INFO *DirInfo; + UINTN BufferSize; + UINTN DirBufferSize; + MENU_ENTRY *NewMenuEntry; + FILE_CONTEXT *NewFileContext; + UINTN Pass; + EFI_STATUS Status; + UINTN OptionNumber; + + OptionNumber = 0; + + DirBufferSize = sizeof (EFI_FILE_INFO) + 1024; + DirInfo = AllocateZeroPool (DirBufferSize); + if (DirInfo == NULL) { + 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 + // + Status = EFI_SUCCESS; + for (Pass = 1; Pass <= 2; Pass++) { + FileHandle->SetPosition (FileHandle, 0); + for ( ; ;) { + BufferSize = DirBufferSize; + Status = FileHandle->Read (FileHandle, &BufferSize, DirInfo); + if (EFI_ERROR (Status) || (BufferSize == 0)) { + Status = EFI_SUCCESS; + break; + } + + if ((((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0) && (Pass == 2)) || + (((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) && (Pass == 1)) + ) + { + // + // Pass 1 is for Directories + // Pass 2 is for file names + // + continue; + } + + if (!(((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0) || LibIsSupportedFileType (DirInfo->FileName))) { + // + // Slip file unless it is a directory entry or a .EFI file + // + continue; + } + + NewMenuEntry = LibCreateMenuEntry (); + if (NULL == NewMenuEntry) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext; + NewFileContext->DeviceHandle = DeviceHandle; + NewFileContext->FileName = LibAppendFileName (FileName, DirInfo->FileName); + if (NewFileContext->FileName == NULL) { + LibDestroyMenuEntry (NewMenuEntry); + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + NewFileContext->FileHandle = FileHandle; + NewFileContext->DevicePath = FileDevicePath (NewFileContext->DeviceHandle, NewFileContext->FileName); + NewMenuEntry->HelpString = NULL; + NewFileContext->IsDir = (BOOLEAN)((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY); + + if (NewFileContext->IsDir) { + BufferSize = StrLen (DirInfo->FileName) * 2 + 6; + NewMenuEntry->DisplayString = AllocateZeroPool (BufferSize); + UnicodeSPrint ( + NewMenuEntry->DisplayString, + BufferSize, + L"<%s>", + DirInfo->FileName + ); + } else { + NewMenuEntry->DisplayString = LibStrDuplicate (DirInfo->FileName); + } + + NewMenuEntry->DisplayStringToken = HiiSetString ( + gFileExplorerPrivate.FeHiiHandle, + 0, + NewMenuEntry->DisplayString, + NULL + ); + + NewFileContext->IsRoot = FALSE; + + OptionNumber++; + InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &NewMenuEntry->Link); + } + } + + gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber; + +Done: + + FreePool (DirInfo); + + return Status; +} + +/** + Refresh the global UpdateData structure. + +**/ +VOID +LibRefreshUpdateData ( + VOID + ) +{ + // + // Free current updated date + // + if (mLibStartOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (mLibStartOpCodeHandle); + } + + if (mLibEndOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (mLibEndOpCodeHandle); + } + + // + // Create new OpCode Handle + // + mLibStartOpCodeHandle = HiiAllocateOpCodeHandle (); + mLibEndOpCodeHandle = HiiAllocateOpCodeHandle (); + + // + // Create Hii Extend Label OpCode as the start opcode + // + mLibStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + mLibStartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + mLibStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + + mLibStartLabel->Number = FORM_FILE_EXPLORER_ID; + + // + // Create Hii Extend Label OpCode as the start opcode + // + mLibEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + mLibEndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + mLibEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + + mLibEndLabel->Number = LABEL_END; +} + +/** + + Update the File Explore page. + +**/ +VOID +LibUpdateFileExplorePage ( + VOID + ) +{ + UINTN Index; + MENU_ENTRY *NewMenuEntry; + FILE_CONTEXT *NewFileContext; + MENU_OPTION *MenuOption; + BOOLEAN CreateNewFile; + + NewMenuEntry = NULL; + NewFileContext = NULL; + CreateNewFile = FALSE; + + LibRefreshUpdateData (); + MenuOption = gFileExplorerPrivate.FsOptionMenu; + + mQuestionIdUpdate += QUESTION_ID_UPDATE_STEP; + + for (Index = 0; Index < MenuOption->MenuNumber; Index++) { + NewMenuEntry = LibGetMenuEntry (MenuOption, Index); + NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext; + + if (!NewFileContext->IsRoot && !CreateNewFile) { + HiiCreateGotoOpCode ( + mLibStartOpCodeHandle, + FORM_ADD_NEW_FILE_ID, + STRING_TOKEN (STR_NEW_FILE), + STRING_TOKEN (STR_NEW_FILE_HELP), + EFI_IFR_FLAG_CALLBACK, + (UINT16)(mNewFileQuestionId++) + ); + HiiCreateGotoOpCode ( + mLibStartOpCodeHandle, + FORM_ADD_NEW_FOLDER_ID, + STRING_TOKEN (STR_NEW_FOLDER), + STRING_TOKEN (STR_NEW_FOLDER_HELP), + EFI_IFR_FLAG_CALLBACK, + (UINT16)(mNewFolderQuestionId++) + ); + HiiCreateTextOpCode ( + mLibStartOpCodeHandle, + STRING_TOKEN (STR_NULL_STRING), + STRING_TOKEN (STR_NULL_STRING), + 0 + ); + CreateNewFile = TRUE; + } + + if (!NewFileContext->IsDir) { + // + // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile. + // + HiiCreateActionOpCode ( + mLibStartOpCodeHandle, + (UINT16)(FILE_OPTION_OFFSET + Index + mQuestionIdUpdate), + NewMenuEntry->DisplayStringToken, + STRING_TOKEN (STR_NULL_STRING), + EFI_IFR_FLAG_CALLBACK, + 0 + ); + } else { + // + // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState. + // + HiiCreateGotoOpCode ( + mLibStartOpCodeHandle, + FORM_FILE_EXPLORER_ID, + NewMenuEntry->DisplayStringToken, + STRING_TOKEN (STR_NULL_STRING), + EFI_IFR_FLAG_CALLBACK, + (UINT16)(FILE_OPTION_OFFSET + Index + mQuestionIdUpdate) + ); + } + } + + HiiUpdateForm ( + gFileExplorerPrivate.FeHiiHandle, + &FileExplorerGuid, + FORM_FILE_EXPLORER_ID, + mLibStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID + mLibEndOpCodeHandle // LABEL_END + ); +} + +/** + Update the file explower page with the refershed file system. + + @param KeyValue Key value to identify the type of data to expect. + + @retval EFI_SUCCESS Update the file explorer form success. + @retval other errors Error occur when parse one directory. + +**/ +EFI_STATUS +LibUpdateFileExplorer ( + IN UINT16 KeyValue + ) +{ + UINT16 FileOptionMask; + MENU_ENTRY *NewMenuEntry; + FILE_CONTEXT *NewFileContext; + EFI_STATUS Status; + EFI_FILE_HANDLE FileHandle; + + Status = EFI_SUCCESS; + FileOptionMask = (UINT16)(FILE_OPTION_MASK & KeyValue) - mQuestionIdUpdate; + NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask); + NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext; + + if (NewFileContext->IsDir) { + RemoveEntryList (&NewMenuEntry->Link); + LibFreeMenu (gFileExplorerPrivate.FsOptionMenu); + Status = LibGetFileHandleFromMenu (NewMenuEntry, &FileHandle); + if (!EFI_ERROR (Status)) { + Status = LibFindFiles (FileHandle, NewFileContext->FileName, NewFileContext->DeviceHandle); + if (!EFI_ERROR (Status)) { + LibUpdateFileExplorePage (); + } else { + LibFreeMenu (gFileExplorerPrivate.FsOptionMenu); + } + } + + LibDestroyMenuEntry (NewMenuEntry); + } + + return Status; +} + +/** + Get the device path info saved in the menu structure. + + @param KeyValue Key value to identify the type of data to expect. + +**/ +VOID +LibGetDevicePath ( + IN UINT16 KeyValue + ) +{ + UINT16 FileOptionMask; + MENU_ENTRY *NewMenuEntry; + FILE_CONTEXT *NewFileContext; + + FileOptionMask = (UINT16)(FILE_OPTION_MASK & KeyValue) - mQuestionIdUpdate; + + NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask); + + NewFileContext = (FILE_CONTEXT *)NewMenuEntry->VariableContext; + + if (gFileExplorerPrivate.RetDevicePath != NULL) { + FreePool (gFileExplorerPrivate.RetDevicePath); + } + + gFileExplorerPrivate.RetDevicePath = DuplicateDevicePath (NewFileContext->DevicePath); +} + +/** + Choose a file in the specified directory. + + If user input NULL for the RootDirectory, will choose file in the system. + + If user input *File != NULL, function will return the allocate device path + info for the choosed file, caller has to free the memory after use it. + + @param RootDirectory Pointer to the root directory. + @param FileType The file type need to choose. + @param ChooseHandler Function pointer to the extra task need to do + after choose one file. + @param File Return the device path for the last time chosed file. + + @retval EFI_SUCESS Choose file success. + @retval EFI_INVALID_PARAMETER Both ChooseHandler and return device path are NULL + One of them must not NULL. + @retval Other errors Choose file failed. +**/ +EFI_STATUS +EFIAPI +ChooseFile ( + IN EFI_DEVICE_PATH_PROTOCOL *RootDirectory, + IN CHAR16 *FileType OPTIONAL, + IN CHOOSE_HANDLER ChooseHandler OPTIONAL, + OUT EFI_DEVICE_PATH_PROTOCOL **File OPTIONAL + ) +{ + EFI_FILE_HANDLE FileHandle; + EFI_STATUS Status; + UINT16 *FileName; + EFI_HANDLE DeviceHandle; + + if ((ChooseHandler == NULL) && (File == NULL)) { + return EFI_INVALID_PARAMETER; + } + + mQuestionIdUpdate = 0; + FileName = NULL; + + gFileExplorerPrivate.RetDevicePath = NULL; + gFileExplorerPrivate.ChooseHandler = ChooseHandler; + if (FileType != NULL) { + gFileExplorerPrivate.FileType = AllocateCopyPool (StrSize (FileType), FileType); + ASSERT (gFileExplorerPrivate.FileType != NULL); + LibToLowerString (gFileExplorerPrivate.FileType); + } else { + gFileExplorerPrivate.FileType = NULL; + } + + if (RootDirectory == NULL) { + Status = LibFindFileSystem (); + } else { + Status = LibGetFileHandleFromDevicePath (RootDirectory, &FileHandle, &FileName, &DeviceHandle); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = LibFindFiles (FileHandle, FileName, DeviceHandle); + } + + if (EFI_ERROR (Status)) { + goto Done; + } + + LibUpdateFileExplorePage (); + + gFileExplorerPrivate.FormBrowser2->SendForm ( + gFileExplorerPrivate.FormBrowser2, + &gFileExplorerPrivate.FeHiiHandle, + 1, + &FileExplorerGuid, + 0, + NULL, + NULL + ); + +Done: + if ((Status == EFI_SUCCESS) && (File != NULL)) { + *File = gFileExplorerPrivate.RetDevicePath; + } else if (gFileExplorerPrivate.RetDevicePath != NULL) { + FreePool (gFileExplorerPrivate.RetDevicePath); + } + + if (gFileExplorerPrivate.FileType != NULL) { + FreePool (gFileExplorerPrivate.FileType); + } + + LibFreeMenu (gFileExplorerPrivate.FsOptionMenu); + + if (FileName != NULL) { + FreePool (FileName); + } + + return Status; +} + +/** + + Install Boot Manager Menu driver. + + @param ImageHandle The image handle. + @param SystemTable The system table. + + @retval EFI_SUCEESS Install File explorer library success. + +**/ +EFI_STATUS +EFIAPI +FileExplorerLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + gHiiVendorDevicePath = (HII_VENDOR_DEVICE_PATH *)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)&FeHiiVendorDevicePath); + ASSERT (gHiiVendorDevicePath != NULL); + CopyGuid (&gHiiVendorDevicePath->VendorDevicePath.Guid, &gEfiCallerIdGuid); + + // + // Install Device Path Protocol and Config Access protocol to driver handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &gFileExplorerPrivate.FeDriverHandle, + &gEfiDevicePathProtocolGuid, + gHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &gFileExplorerPrivate.FeConfigAccess, + NULL + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Post our File Explorer VFR binary to the HII database. + // + gFileExplorerPrivate.FeHiiHandle = HiiAddPackages ( + &FileExplorerGuid, + gFileExplorerPrivate.FeDriverHandle, + FileExplorerVfrBin, + FileExplorerLibStrings, + NULL + ); + ASSERT (gFileExplorerPrivate.FeHiiHandle != NULL); + + // + // Locate Formbrowser2 protocol + // + Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&gFileExplorerPrivate.FormBrowser2); + ASSERT_EFI_ERROR (Status); + + InitializeListHead (&gFileExplorerPrivate.FsOptionMenu->Head); + + return EFI_SUCCESS; +} + +/** + Unloads the application and its installed protocol. + + @param[in] ImageHandle Handle that identifies the image to be unloaded. + @param[in] SystemTable The system table. + + @retval EFI_SUCCESS The image has been unloaded. +**/ +EFI_STATUS +EFIAPI +FileExplorerLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + ASSERT (gHiiVendorDevicePath != NULL); + + if (gFileExplorerPrivate.FeDriverHandle != NULL) { + Status = gBS->UninstallMultipleProtocolInterfaces ( + gFileExplorerPrivate.FeDriverHandle, + &gEfiDevicePathProtocolGuid, + gHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &gFileExplorerPrivate.FeConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + + HiiRemovePackages (gFileExplorerPrivate.FeHiiHandle); + gFileExplorerPrivate.FeDriverHandle = NULL; + } + + FreePool (gHiiVendorDevicePath); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/FileExplorerLib/FileExplorer.h b/MdeModulePkg/Library/FileExplorerLib/FileExplorer.h index c7587c166b..0b844acf34 100644 --- a/MdeModulePkg/Library/FileExplorerLib/FileExplorer.h +++ b/MdeModulePkg/Library/FileExplorerLib/FileExplorer.h @@ -1,232 +1,232 @@ -/** @file
- File explorer lib.
-
-Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#ifndef _FILE_EXPLORER_H_
-#define _FILE_EXPLORER_H_
-
-#include <PiDxe.h>
-#include <Guid/FileSystemVolumeLabelInfo.h>
-#include <Guid/FileInfo.h>
-#include <Guid/MdeModuleHii.h>
-
-#include <Protocol/HiiConfigAccess.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/SimpleFileSystem.h>
-#include <Protocol/DevicePathToText.h>
-#include <Protocol/FormBrowser2.h>
-
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/BaseLib.h>
-#include <Library/UefiLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/FileExplorerLib.h>
-#include <Library/HiiLib.h>
-#include <Library/PrintLib.h>
-
-#include "FormGuid.h"
-
-#define FILE_EXPLORER_CALLBACK_DATA_SIGNATURE SIGNATURE_32 ('f', 'e', 'c', 'k')
-
-#pragma pack(1)
-
-///
-/// HII specific Vendor Device Path definition.
-///
-typedef struct {
- VENDOR_DEVICE_PATH VendorDevicePath;
- EFI_DEVICE_PATH_PROTOCOL End;
-} HII_VENDOR_DEVICE_PATH;
-
-#pragma pack()
-
-typedef struct {
- EFI_HANDLE DeviceHandle;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_FILE_HANDLE FileHandle;
- UINT16 *FileName;
-
- BOOLEAN IsRoot;
- BOOLEAN IsDir;
-} FILE_CONTEXT;
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
- UINT16 *DisplayString;
- UINT16 *HelpString;
- EFI_STRING_ID DisplayStringToken;
- EFI_STRING_ID HelpStringToken;
- VOID *VariableContext;
-} MENU_ENTRY;
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Head;
- UINTN MenuNumber;
- BOOLEAN Used;
-} MENU_OPTION;
-
-typedef struct {
- //
- // Shared callback data.
- //
- UINTN Signature;
-
- //
- // File explorer formset callback data.
- //
- EFI_HII_HANDLE FeHiiHandle;
- EFI_HANDLE FeDriverHandle;
- EFI_HII_CONFIG_ACCESS_PROTOCOL FeConfigAccess;
- EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
- MENU_OPTION *FsOptionMenu;
- CHAR16 *FileType;
- CHOOSE_HANDLER ChooseHandler;
- EFI_DEVICE_PATH_PROTOCOL *RetDevicePath;
-} FILE_EXPLORER_CALLBACK_DATA;
-
-#define FILE_EXPLORER_PRIVATE_FROM_THIS(a) CR (a, FILE_EXPLORER_CALLBACK_DATA, FeConfigAccess, FILE_EXPLORER_CALLBACK_DATA_SIGNATURE)
-
-extern UINT8 FileExplorerVfrBin[];
-
-#define MENU_OPTION_SIGNATURE SIGNATURE_32 ('m', 'e', 'n', 'u')
-#define MENU_ENTRY_SIGNATURE SIGNATURE_32 ('e', 'n', 't', 'r')
-
-///
-/// Define the maximum characters that will be accepted.
-///
-#define MAX_CHAR 480
-#define FILE_OPTION_OFFSET 0x8000
-#define FILE_OPTION_MASK 0x7FFF
-#define QUESTION_ID_UPDATE_STEP 200
-#define MAX_FILE_NAME_LEN 20
-#define MAX_FOLDER_NAME_LEN 20
-#define NEW_FILE_QUESTION_ID_BASE 0x5000;
-#define NEW_FOLDER_QUESTION_ID_BASE 0x6000;
-
-/**
- This function processes the results of changes in configuration.
- When user select a interactive opcode, this callback will be triggered.
- Based on the Question(QuestionId) that triggers the callback, the corresponding
- actions is performed. It handles:
-
- 1) the addition of boot option.
- 2) the addition of driver option.
- 3) exit from file browser
- 4) update of file content if a dir is selected.
- 5) boot the file if a file is selected in "boot from file"
-
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Action Specifies the type of action taken by the browser.
- @param QuestionId A unique value which is sent to the original exporting driver
- so that it can identify the type of data to expect.
- @param Type The type of value for the question.
- @param Value A pointer to the data being sent to the original exporting driver.
- @param ActionRequest On return, points to the action requested by the callback function.
-
- @retval EFI_SUCCESS The callback successfully handled the action.
- @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
- @retval EFI_DEVICE_ERROR The variable could not be saved.
- @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
-
-**/
-EFI_STATUS
-EFIAPI
-LibCallback (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN EFI_BROWSER_ACTION Action,
- IN EFI_QUESTION_ID QuestionId,
- IN UINT8 Type,
- IN EFI_IFR_TYPE_VALUE *Value,
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
- );
-
-/**
- This function allows a caller to extract the current configuration for one
- or more named elements from the target driver.
-
-
- @param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Request - A null-terminated Unicode string in <ConfigRequest> format.
- @param Progress - On return, points to a character in the Request string.
- Points to the string's null terminator if request was successful.
- Points to the most recent '&' before the first failing name/value
- pair (or the beginning of the string if the failure is in the
- first name/value pair) if the request was not successful.
- @param Results - A null-terminated Unicode string in <ConfigAltResp> format which
- has all values filled in for the names in the Request string.
- String to be allocated by the called function.
-
- @retval EFI_SUCCESS The Results is filled with the requested values.
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
- @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibExtractConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Request,
- OUT EFI_STRING *Progress,
- OUT EFI_STRING *Results
- );
-
-/**
- This function processes the results of changes in configuration.
-
-
- @param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Configuration - A null-terminated Unicode string in <ConfigResp> format.
- @param Progress - A pointer to a string filled in with the offset of the most
- recent '&' before the first failing name/value pair (or the
- beginning of the string if the failure is in the first
- name/value pair) or the terminating NULL if all was successful.
-
- @retval EFI_SUCCESS The Results is processed successfully.
- @retval EFI_INVALID_PARAMETER Configuration is NULL.
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibRouteConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Configuration,
- OUT EFI_STRING *Progress
- );
-
-/**
- Update the file explower page with the refershed file system.
-
- @param KeyValue Key value to identify the type of data to expect.
-
- @retval EFI_SUCCESS Update the file explorer form success.
- @retval other errors Error occur when parse one directory.
-
-**/
-EFI_STATUS
-LibUpdateFileExplorer (
- IN UINT16 KeyValue
- );
-
-/**
- Get the device path info saved in the menu structure.
-
- @param KeyValue Key value to identify the type of data to expect.
-
-**/
-VOID
-LibGetDevicePath (
- IN UINT16 KeyValue
- );
-
-#endif
+/** @file + File explorer lib. + +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _FILE_EXPLORER_H_ +#define _FILE_EXPLORER_H_ + +#include <PiDxe.h> +#include <Guid/FileSystemVolumeLabelInfo.h> +#include <Guid/FileInfo.h> +#include <Guid/MdeModuleHii.h> + +#include <Protocol/HiiConfigAccess.h> +#include <Protocol/DevicePath.h> +#include <Protocol/SimpleFileSystem.h> +#include <Protocol/DevicePathToText.h> +#include <Protocol/FormBrowser2.h> + +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/BaseLib.h> +#include <Library/UefiLib.h> +#include <Library/DevicePathLib.h> +#include <Library/FileExplorerLib.h> +#include <Library/HiiLib.h> +#include <Library/PrintLib.h> + +#include "FormGuid.h" + +#define FILE_EXPLORER_CALLBACK_DATA_SIGNATURE SIGNATURE_32 ('f', 'e', 'c', 'k') + +#pragma pack(1) + +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +#pragma pack() + +typedef struct { + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_FILE_HANDLE FileHandle; + UINT16 *FileName; + + BOOLEAN IsRoot; + BOOLEAN IsDir; +} FILE_CONTEXT; + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + UINT16 *DisplayString; + UINT16 *HelpString; + EFI_STRING_ID DisplayStringToken; + EFI_STRING_ID HelpStringToken; + VOID *VariableContext; +} MENU_ENTRY; + +typedef struct { + UINTN Signature; + LIST_ENTRY Head; + UINTN MenuNumber; + BOOLEAN Used; +} MENU_OPTION; + +typedef struct { + // + // Shared callback data. + // + UINTN Signature; + + // + // File explorer formset callback data. + // + EFI_HII_HANDLE FeHiiHandle; + EFI_HANDLE FeDriverHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL FeConfigAccess; + EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2; + MENU_OPTION *FsOptionMenu; + CHAR16 *FileType; + CHOOSE_HANDLER ChooseHandler; + EFI_DEVICE_PATH_PROTOCOL *RetDevicePath; +} FILE_EXPLORER_CALLBACK_DATA; + +#define FILE_EXPLORER_PRIVATE_FROM_THIS(a) CR (a, FILE_EXPLORER_CALLBACK_DATA, FeConfigAccess, FILE_EXPLORER_CALLBACK_DATA_SIGNATURE) + +extern UINT8 FileExplorerVfrBin[]; + +#define MENU_OPTION_SIGNATURE SIGNATURE_32 ('m', 'e', 'n', 'u') +#define MENU_ENTRY_SIGNATURE SIGNATURE_32 ('e', 'n', 't', 'r') + +/// +/// Define the maximum characters that will be accepted. +/// +#define MAX_CHAR 480 +#define FILE_OPTION_OFFSET 0x8000 +#define FILE_OPTION_MASK 0x7FFF +#define QUESTION_ID_UPDATE_STEP 200 +#define MAX_FILE_NAME_LEN 20 +#define MAX_FOLDER_NAME_LEN 20 +#define NEW_FILE_QUESTION_ID_BASE 0x5000; +#define NEW_FOLDER_QUESTION_ID_BASE 0x6000; + +/** + This function processes the results of changes in configuration. + When user select a interactive opcode, this callback will be triggered. + Based on the Question(QuestionId) that triggers the callback, the corresponding + actions is performed. It handles: + + 1) the addition of boot option. + 2) the addition of driver option. + 3) exit from file browser + 4) update of file content if a dir is selected. + 5) boot the file if a file is selected in "boot from file" + + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original exporting driver + so that it can identify the type of data to expect. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original exporting driver. + @param ActionRequest On return, points to the action requested by the callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. + +**/ +EFI_STATUS +EFIAPI +LibCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ); + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + + + @param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Request - A null-terminated Unicode string in <ConfigRequest> format. + @param Progress - On return, points to a character in the Request string. + Points to the string's null terminator if request was successful. + Points to the most recent '&' before the first failing name/value + pair (or the beginning of the string if the failure is in the + first name/value pair) if the request was not successful. + @param Results - A null-terminated Unicode string in <ConfigAltResp> format which + has all values filled in for the names in the Request string. + String to be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. + +**/ +EFI_STATUS +EFIAPI +LibExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ); + +/** + This function processes the results of changes in configuration. + + + @param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Configuration - A null-terminated Unicode string in <ConfigResp> format. + @param Progress - A pointer to a string filled in with the offset of the most + recent '&' before the first failing name/value pair (or the + beginning of the string if the failure is in the first + name/value pair) or the terminating NULL if all was successful. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. + +**/ +EFI_STATUS +EFIAPI +LibRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ); + +/** + Update the file explower page with the refershed file system. + + @param KeyValue Key value to identify the type of data to expect. + + @retval EFI_SUCCESS Update the file explorer form success. + @retval other errors Error occur when parse one directory. + +**/ +EFI_STATUS +LibUpdateFileExplorer ( + IN UINT16 KeyValue + ); + +/** + Get the device path info saved in the menu structure. + + @param KeyValue Key value to identify the type of data to expect. + +**/ +VOID +LibGetDevicePath ( + IN UINT16 KeyValue + ); + +#endif diff --git a/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf b/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf index 4e14cbc04c..ec0f6adf4b 100644 --- a/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf +++ b/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf @@ -1,57 +1,57 @@ -## @file
-# library defines a set of interfaces for how to do file explorer.
-#
-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = FileExplorerLib
- MODULE_UNI_FILE = FileExplorerLib.uni
- FILE_GUID = 4FC9C630-0F90-4053-8F13-264CBD22FC58
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = FileExplorerLib|DXE_DRIVER UEFI_APPLICATION
- CONSTRUCTOR = FileExplorerLibConstructor
- DESTRUCTOR = FileExplorerLibDestructor
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC
-#
-
-[Sources]
- FileExplorer.h
- FileExplorerVfr.vfr
- FileExplorerString.uni
- FileExplorer.c
- FormGuid.h
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- DevicePathLib
- BaseLib
- MemoryAllocationLib
- UefiBootServicesTableLib
- BaseMemoryLib
- DebugLib
- HiiLib
- UefiHiiServicesLib
-
-[Guids]
- gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## GUID (Indicate the information type is volume)
- gEfiIfrTianoGuid ## SOMETIMES_CONSUMES ## GUID (Extended IFR Guid Opcode)
-
-[Protocols]
- gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
- gEfiHiiConfigAccessProtocolGuid ## PRODUCES
- gEfiFormBrowser2ProtocolGuid ## CONSUMES
- gEfiDevicePathToTextProtocolGuid ## PRODUCES
-
-[Depex.common.DXE_DRIVER]
- gEfiFormBrowser2ProtocolGuid AND gEfiHiiDatabaseProtocolGuid
+## @file +# library defines a set of interfaces for how to do file explorer. +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FileExplorerLib + MODULE_UNI_FILE = FileExplorerLib.uni + FILE_GUID = 4FC9C630-0F90-4053-8F13-264CBD22FC58 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = FileExplorerLib|DXE_DRIVER UEFI_APPLICATION + CONSTRUCTOR = FileExplorerLibConstructor + DESTRUCTOR = FileExplorerLibDestructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + FileExplorer.h + FileExplorerVfr.vfr + FileExplorerString.uni + FileExplorer.c + FormGuid.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DevicePathLib + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + BaseMemoryLib + DebugLib + HiiLib + UefiHiiServicesLib + +[Guids] + gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## GUID (Indicate the information type is volume) + gEfiIfrTianoGuid ## SOMETIMES_CONSUMES ## GUID (Extended IFR Guid Opcode) + +[Protocols] + gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiFormBrowser2ProtocolGuid ## CONSUMES + gEfiDevicePathToTextProtocolGuid ## PRODUCES + +[Depex.common.DXE_DRIVER] + gEfiFormBrowser2ProtocolGuid AND gEfiHiiDatabaseProtocolGuid diff --git a/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.uni b/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.uni index 5e7a99cb92..fb33285e4e 100644 --- a/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.uni +++ b/MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.uni @@ -1,20 +1,20 @@ -// /** @file
-// library defines a set of interfaces for how to do file explorer.
-//
-// library defines a set of interfaces for how to do file explorer.
-//
-// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT
-#language en-US
-"library defines a set of interfaces for how to do file explorer."
-
-#string STR_MODULE_DESCRIPTION
-#language en-US
-"library defines a set of interfaces for how to do file explorer."
-
-
+// /** @file +// library defines a set of interfaces for how to do file explorer. +// +// library defines a set of interfaces for how to do file explorer. +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT +#language en-US +"library defines a set of interfaces for how to do file explorer." + +#string STR_MODULE_DESCRIPTION +#language en-US +"library defines a set of interfaces for how to do file explorer." + + diff --git a/MdeModulePkg/Library/FileExplorerLib/FileExplorerString.uni b/MdeModulePkg/Library/FileExplorerLib/FileExplorerString.uni index 070cdf38ea..7d58fd5923 100644 --- a/MdeModulePkg/Library/FileExplorerLib/FileExplorerString.uni +++ b/MdeModulePkg/Library/FileExplorerLib/FileExplorerString.uni @@ -1,55 +1,55 @@ -///** @file
-//
-// Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// Module Name:
-//
-// FileExplorerString.uni
-//
-// Abstract:
-//
-// String definitions for file explorer library.
-//
-// Revision History:
-//
-// --*/
-/=#
-
-#langdef en-US "English"
-#langdef fr-FR "Français"
-
-#string STR_NULL_STRING #language en-US " "
- #language fr-FR " "
-#string STR_FILE_EXPLORER_TITLE #language en-US "File Explorer"
- #language fr-FR "File Explorer"
-#string STR_NEW_FILE #language en-US "***NEW FILE***"
- #language fr-FR "***NEW FILE***"
-#string STR_NEW_FILE_HELP #language en-US "This menu used to create a new file in current directory, jump to next page to name the new file"
- #language fr-FR "This menu used to create a new file in current directory, jump to next page to name the new file"
-#string STR_ADD_NEW_FILE_TITLE #language en-US "Create a new file"
- #language fr-FR "Create a new file"
-#string STR_ADD_NEW_FOLDER_TITLE #language en-US "Create a new folder"
- #language fr-FR "Create a new folder"
-#string STR_NEW_FILE_NAME_PROMPT #language en-US "File Name"
- #language fr-FR "File Name"
-#string STR_NEW_FILE_NAME_HELP #language en-US "Please input a name for the new file"
- #language fr-FR "Please input a name for the new file"
-#string STR_CREATE_FILE_AND_EXIT #language en-US "Create File and Exit"
- #language fr-FR "Create File and Exit"
-#string STR_NO_CREATE_FILE_AND_EXIT #language en-US "Discard Create and Exit"
- #language fr-FR "Discard Create and Exit"
-#string STR_NEW_FOLDER #language en-US "***NEW FOLDER***"
- #language fr-FR "***NEW FOLDER***"
-#string STR_NEW_FOLDER_HELP #language en-US "This menu used to create a new folder in current directory, jump to next page to name the new folder"
- #language fr-FR "This menu used to create a new folder in current directory, jump to next page to name the new folder"
-#string STR_ADD_NEW_FOLDER_TITLE #language en-US "Create a new folder"
- #language fr-FR "Create a new folder"
-#string STR_NEW_FOLDER_NAME_PROMPT #language en-US "Folder Name"
- #language fr-FR "Folder Name"
-#string STR_NEW_FOLDER_NAME_HELP #language en-US "Please input a name for the new folder"
- #language fr-FR "Please input a name for the new folder"
-#string STR_CREATE_FOLDER_AND_EXIT #language en-US "Create Folder and Exit"
- #language fr-FR "Create Folder and Exit"
-#string STR_NO_CREATE_FOLDER_AND_EXIT #language en-US "Discard Create and Exit"
- #language fr-FR "Discard Create and Exit"
+///** @file +// +// Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// FileExplorerString.uni +// +// Abstract: +// +// String definitions for file explorer library. +// +// Revision History: +// +// --*/ +/=# + +#langdef en-US "English" +#langdef fr-FR "Français" + +#string STR_NULL_STRING #language en-US " " + #language fr-FR " " +#string STR_FILE_EXPLORER_TITLE #language en-US "File Explorer" + #language fr-FR "File Explorer" +#string STR_NEW_FILE #language en-US "***NEW FILE***" + #language fr-FR "***NEW FILE***" +#string STR_NEW_FILE_HELP #language en-US "This menu used to create a new file in current directory, jump to next page to name the new file" + #language fr-FR "This menu used to create a new file in current directory, jump to next page to name the new file" +#string STR_ADD_NEW_FILE_TITLE #language en-US "Create a new file" + #language fr-FR "Create a new file" +#string STR_ADD_NEW_FOLDER_TITLE #language en-US "Create a new folder" + #language fr-FR "Create a new folder" +#string STR_NEW_FILE_NAME_PROMPT #language en-US "File Name" + #language fr-FR "File Name" +#string STR_NEW_FILE_NAME_HELP #language en-US "Please input a name for the new file" + #language fr-FR "Please input a name for the new file" +#string STR_CREATE_FILE_AND_EXIT #language en-US "Create File and Exit" + #language fr-FR "Create File and Exit" +#string STR_NO_CREATE_FILE_AND_EXIT #language en-US "Discard Create and Exit" + #language fr-FR "Discard Create and Exit" +#string STR_NEW_FOLDER #language en-US "***NEW FOLDER***" + #language fr-FR "***NEW FOLDER***" +#string STR_NEW_FOLDER_HELP #language en-US "This menu used to create a new folder in current directory, jump to next page to name the new folder" + #language fr-FR "This menu used to create a new folder in current directory, jump to next page to name the new folder" +#string STR_ADD_NEW_FOLDER_TITLE #language en-US "Create a new folder" + #language fr-FR "Create a new folder" +#string STR_NEW_FOLDER_NAME_PROMPT #language en-US "Folder Name" + #language fr-FR "Folder Name" +#string STR_NEW_FOLDER_NAME_HELP #language en-US "Please input a name for the new folder" + #language fr-FR "Please input a name for the new folder" +#string STR_CREATE_FOLDER_AND_EXIT #language en-US "Create Folder and Exit" + #language fr-FR "Create Folder and Exit" +#string STR_NO_CREATE_FOLDER_AND_EXIT #language en-US "Discard Create and Exit" + #language fr-FR "Discard Create and Exit" diff --git a/MdeModulePkg/Library/FileExplorerLib/FileExplorerVfr.vfr b/MdeModulePkg/Library/FileExplorerLib/FileExplorerVfr.vfr index a8f273299c..9507aed53e 100644 --- a/MdeModulePkg/Library/FileExplorerLib/FileExplorerVfr.vfr +++ b/MdeModulePkg/Library/FileExplorerLib/FileExplorerVfr.vfr @@ -1,79 +1,79 @@ -///** @file
-//
-// File Explorer Formset
-//
-// Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-//**/
-
-#include "FormGuid.h"
-
-formset
- guid = EFI_FILE_EXPLORE_FORMSET_GUID,
- title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE),
- help = STRING_TOKEN(STR_NULL_STRING),
- classguid = EFI_FILE_EXPLORE_FORMSET_GUID,
-
- form formid = FORM_FILE_EXPLORER_ID,
- title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE);
-
- label FORM_FILE_EXPLORER_ID;
- label LABEL_END;
- endform;
-
- form formid = FORM_ADD_NEW_FILE_ID,
- title = STRING_TOKEN(STR_ADD_NEW_FILE_TITLE);
-
- string
- prompt = STRING_TOKEN(STR_NEW_FILE_NAME_PROMPT),
- help = STRING_TOKEN(STR_NEW_FILE_NAME_HELP),
- flags = INTERACTIVE,
- key = NEW_FILE_NAME_ID,
- minsize = 2,
- maxsize = 20,
- endstring;
-
- subtitle text = STRING_TOKEN(STR_NULL_STRING);
-
- text
- help = STRING_TOKEN(STR_CREATE_FILE_AND_EXIT),
- text = STRING_TOKEN(STR_CREATE_FILE_AND_EXIT),
- flags = INTERACTIVE,
- key = KEY_VALUE_CREATE_FILE_AND_EXIT;
-
- text
- help = STRING_TOKEN(STR_NO_CREATE_FILE_AND_EXIT),
- text = STRING_TOKEN(STR_NO_CREATE_FILE_AND_EXIT),
- flags = INTERACTIVE,
- key = KEY_VALUE_NO_CREATE_FILE_AND_EXIT;
- endform;
-
- form formid = FORM_ADD_NEW_FOLDER_ID,
- title = STRING_TOKEN(STR_ADD_NEW_FOLDER_TITLE);
-
- string
- prompt = STRING_TOKEN(STR_NEW_FOLDER_NAME_PROMPT),
- help = STRING_TOKEN(STR_NEW_FOLDER_NAME_HELP),
- flags = INTERACTIVE,
- key = NEW_FOLDER_NAME_ID,
- minsize = 2,
- maxsize = 20,
- endstring;
-
- subtitle text = STRING_TOKEN(STR_NULL_STRING);
-
- text
- help = STRING_TOKEN(STR_CREATE_FOLDER_AND_EXIT),
- text = STRING_TOKEN(STR_CREATE_FOLDER_AND_EXIT),
- flags = INTERACTIVE,
- key = KEY_VALUE_CREATE_FOLDER_AND_EXIT;
-
- text
- help = STRING_TOKEN(STR_NO_CREATE_FOLDER_AND_EXIT),
- text = STRING_TOKEN(STR_NO_CREATE_FOLDER_AND_EXIT),
- flags = INTERACTIVE,
- key = KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT;
- endform;
-
-endformset;
+///** @file +// +// File Explorer Formset +// +// Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//**/ + +#include "FormGuid.h" + +formset + guid = EFI_FILE_EXPLORE_FORMSET_GUID, + title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE), + help = STRING_TOKEN(STR_NULL_STRING), + classguid = EFI_FILE_EXPLORE_FORMSET_GUID, + + form formid = FORM_FILE_EXPLORER_ID, + title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE); + + label FORM_FILE_EXPLORER_ID; + label LABEL_END; + endform; + + form formid = FORM_ADD_NEW_FILE_ID, + title = STRING_TOKEN(STR_ADD_NEW_FILE_TITLE); + + string + prompt = STRING_TOKEN(STR_NEW_FILE_NAME_PROMPT), + help = STRING_TOKEN(STR_NEW_FILE_NAME_HELP), + flags = INTERACTIVE, + key = NEW_FILE_NAME_ID, + minsize = 2, + maxsize = 20, + endstring; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_CREATE_FILE_AND_EXIT), + text = STRING_TOKEN(STR_CREATE_FILE_AND_EXIT), + flags = INTERACTIVE, + key = KEY_VALUE_CREATE_FILE_AND_EXIT; + + text + help = STRING_TOKEN(STR_NO_CREATE_FILE_AND_EXIT), + text = STRING_TOKEN(STR_NO_CREATE_FILE_AND_EXIT), + flags = INTERACTIVE, + key = KEY_VALUE_NO_CREATE_FILE_AND_EXIT; + endform; + + form formid = FORM_ADD_NEW_FOLDER_ID, + title = STRING_TOKEN(STR_ADD_NEW_FOLDER_TITLE); + + string + prompt = STRING_TOKEN(STR_NEW_FOLDER_NAME_PROMPT), + help = STRING_TOKEN(STR_NEW_FOLDER_NAME_HELP), + flags = INTERACTIVE, + key = NEW_FOLDER_NAME_ID, + minsize = 2, + maxsize = 20, + endstring; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_CREATE_FOLDER_AND_EXIT), + text = STRING_TOKEN(STR_CREATE_FOLDER_AND_EXIT), + flags = INTERACTIVE, + key = KEY_VALUE_CREATE_FOLDER_AND_EXIT; + + text + help = STRING_TOKEN(STR_NO_CREATE_FOLDER_AND_EXIT), + text = STRING_TOKEN(STR_NO_CREATE_FOLDER_AND_EXIT), + flags = INTERACTIVE, + key = KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT; + endform; + +endformset; diff --git a/MdeModulePkg/Library/FileExplorerLib/FormGuid.h b/MdeModulePkg/Library/FileExplorerLib/FormGuid.h index 52a34dc283..fb35e084e2 100644 --- a/MdeModulePkg/Library/FileExplorerLib/FormGuid.h +++ b/MdeModulePkg/Library/FileExplorerLib/FormGuid.h @@ -1,29 +1,29 @@ -/** @file
-Formset guids, form id and VarStore data structure for File explorer library.
-
-Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _FILE_EXPLORER_FORM_GUID_H_
-#define _FILE_EXPLORER_FORM_GUID_H_
-
-#define EFI_FILE_EXPLORE_FORMSET_GUID \
- { \
- 0xfe561596, 0xe6bf, 0x41a6, {0x83, 0x76, 0xc7, 0x2b, 0x71, 0x98, 0x74, 0xd0} \
- }
-
-#define FORM_FILE_EXPLORER_ID 0x1000
-#define FORM_ADD_NEW_FILE_ID 0x2000
-#define NEW_FILE_NAME_ID 0x2001
-#define KEY_VALUE_CREATE_FILE_AND_EXIT 0x2002
-#define KEY_VALUE_NO_CREATE_FILE_AND_EXIT 0x2003
-#define FORM_ADD_NEW_FOLDER_ID 0x3000
-#define NEW_FOLDER_NAME_ID 0x3001
-#define KEY_VALUE_CREATE_FOLDER_AND_EXIT 0x3002
-#define KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT 0x3003
-
-#define LABEL_END 0xffff
-
-#endif
+/** @file +Formset guids, form id and VarStore data structure for File explorer library. + +Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _FILE_EXPLORER_FORM_GUID_H_ +#define _FILE_EXPLORER_FORM_GUID_H_ + +#define EFI_FILE_EXPLORE_FORMSET_GUID \ + { \ + 0xfe561596, 0xe6bf, 0x41a6, {0x83, 0x76, 0xc7, 0x2b, 0x71, 0x98, 0x74, 0xd0} \ + } + +#define FORM_FILE_EXPLORER_ID 0x1000 +#define FORM_ADD_NEW_FILE_ID 0x2000 +#define NEW_FILE_NAME_ID 0x2001 +#define KEY_VALUE_CREATE_FILE_AND_EXIT 0x2002 +#define KEY_VALUE_NO_CREATE_FILE_AND_EXIT 0x2003 +#define FORM_ADD_NEW_FOLDER_ID 0x3000 +#define NEW_FOLDER_NAME_ID 0x3001 +#define KEY_VALUE_CREATE_FOLDER_AND_EXIT 0x3002 +#define KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT 0x3003 + +#define LABEL_END 0xffff + +#endif |
