]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/FileExplorer.c
Unix version of EFI emulator
[mirror_edk2.git] / EdkUnixPkg / Dxe / PlatformBds / Generic / BootMaint / FileExplorer.c
diff --git a/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/FileExplorer.c b/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/FileExplorer.c
new file mode 100644 (file)
index 0000000..db835cf
--- /dev/null
@@ -0,0 +1,340 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  FileExplorer.c\r
+    \r
+AgBStract:\r
+\r
+  File explorer related functions.\r
+\r
+--*/\r
+\r
+#include "Generic/Bds.h"\r
+#include "BootMaint.h"\r
+#include "BdsPlatform.h"\r
+\r
+VOID\r
+UpdateFileExplorePage (\r
+  IN BMM_CALLBACK_DATA            *CallbackData,\r
+  BM_MENU_OPTION                  *MenuOption\r
+  )\r
+/*++\r
+Routine Description:\r
+  Update the File Explore page.\r
+\r
+Arguments:\r
+  MenuOption      - Pointer to menu options to display.\r
+\r
+Returns:\r
+  None.\r
+\r
+--*/\r
+{\r
+  UINT8           *Location;\r
+  UINTN           Index;\r
+  BM_MENU_ENTRY   *NewMenuEntry;\r
+  BM_FILE_CONTEXT *NewFileContext;\r
+  FORM_ID         FormId;\r
+\r
+  NewMenuEntry    = NULL;\r
+  NewFileContext  = NULL;\r
+  FormId          = 0;\r
+\r
+  //\r
+  // Clean up file explore page.\r
+  //\r
+  RefreshUpdateData (FALSE, 0, FALSE, 0, 0xff);\r
+\r
+  //\r
+  // Remove all op-codes from dynamic page\r
+  //\r
+  CallbackData->Hii->UpdateForm (\r
+                      CallbackData->Hii,\r
+                      CallbackData->FeHiiHandle,\r
+                      FORM_FILE_EXPLORER_ID,\r
+                      FALSE,\r
+                      UpdateData\r
+                      );\r
+\r
+  RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 0);\r
+\r
+  Location = (UINT8 *) &UpdateData->Data;\r
+\r
+  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
+    NewMenuEntry    = BOpt_GetMenuEntry (MenuOption, Index);\r
+    NewFileContext  = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+    if (NewFileContext->IsBootLegacy) {\r
+      continue;\r
+    }\r
+\r
+    if ((NewFileContext->IsDir) || (BOOT_FROM_FILE_STATE == CallbackData->FeCurrentState)) {\r
+      //\r
+      // Create Text opcode for directory, also create Text opcode for file in BOOT_FROM_FILE_STATE.\r
+      //\r
+      CreateTextOpCode (\r
+        NewMenuEntry->DisplayStringToken,\r
+        STR_NULL_STRING,\r
+        STR_NULL_STRING,\r
+        EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+        (UINT16) (FILE_OPTION_OFFSET + Index),\r
+        Location\r
+        );\r
+    } else {\r
+      //\r
+      // Create Goto opcode for file in ADD_BOOT_OPTION_STATE or ADD_DRIVER_OPTION_STATE.\r
+      //\r
+      if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {\r
+        FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
+      } else if (ADD_DRIVER_OPTION_STATE == CallbackData->FeCurrentState) {\r
+        FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
+      }\r
+\r
+      CreateGotoOpCode (\r
+        FormId,\r
+        NewMenuEntry->DisplayStringToken,\r
+        STRING_TOKEN (STR_NULL_STRING),\r
+        EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+        (UINT16) (FILE_OPTION_OFFSET + Index),\r
+        Location\r
+        );\r
+    }\r
+\r
+    UpdateData->DataCount++;\r
+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  }\r
+\r
+  CallbackData->Hii->UpdateForm (\r
+                      CallbackData->Hii,\r
+                      CallbackData->FeHiiHandle,\r
+                      FORM_FILE_EXPLORER_ID,\r
+                      TRUE,\r
+                      UpdateData\r
+                      );\r
+}\r
+\r
+BOOLEAN\r
+UpdateFileExplorer (\r
+  IN BMM_CALLBACK_DATA            *CallbackData,\r
+  IN UINT16                       KeyValue\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Update the file explower page with the refershed file system.\r
+\r
+Arguments:\r
+  CallbackData  -   BMM context data\r
+  KeyValue        - Key value to identify the type of data to expect.\r
+\r
+Returns:\r
+  TRUE          - Inform the caller to create a callback packet to exit file explorer.\r
+  FALSE         - Indicate that there is no need to exit file explorer.\r
+\r
+--*/\r
+{\r
+  UINT16          FileOptionMask;\r
+  BM_MENU_ENTRY   *NewMenuEntry;\r
+  BM_FILE_CONTEXT *NewFileContext;\r
+  FORM_ID         FormId;\r
+  BOOLEAN         ExitFileExplorer;\r
+  EFI_STATUS      Status;\r
+  \r
+  NewMenuEntry      = NULL;\r
+  NewFileContext    = NULL;\r
+  ExitFileExplorer  = FALSE;\r
+\r
+  FileOptionMask    = (UINT16) (FILE_OPTION_MASK & KeyValue);\r
+\r
+  if (UNKNOWN_CONTEXT == CallbackData->FeDisplayContext) {\r
+    //\r
+    // First in, display file system.\r
+    //\r
+    BOpt_FreeMenu (&FsOptionMenu);\r
+    BOpt_FindFileSystem (CallbackData);\r
+    CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu);\r
+\r
+    UpdateFileExplorePage (CallbackData, &FsOptionMenu);\r
+\r
+    CallbackData->FeDisplayContext = FILE_SYSTEM;\r
+  } else {\r
+    if (FILE_SYSTEM == CallbackData->FeDisplayContext) {\r
+      NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);\r
+    } else if (DIRECTORY == CallbackData->FeDisplayContext) {\r
+      NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);\r
+    }\r
+\r
+    CallbackData->FeDisplayContext  = DIRECTORY;\r
+\r
+    NewFileContext                  = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+    if (NewFileContext->IsDir ) {\r
+      RemoveEntryList (&NewMenuEntry->Link);\r
+      BOpt_FreeMenu (&DirectoryMenu);\r
+      Status = BOpt_FindFiles (CallbackData, NewMenuEntry);\r
+       if (EFI_ERROR (Status)) {\r
+         ExitFileExplorer = TRUE;\r
+         goto exit;\r
+       }\r
+      CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu);\r
+      BOpt_DestroyMenuEntry (NewMenuEntry);\r
+\r
+      UpdateFileExplorePage (CallbackData, &DirectoryMenu);\r
+\r
+    } else {\r
+      switch (CallbackData->FeCurrentState) {\r
+      case BOOT_FROM_FILE_STATE:\r
+        //\r
+        // Here boot from file\r
+        //\r
+        BootThisFile (NewFileContext);\r
+        ExitFileExplorer = TRUE;\r
+        break;\r
+\r
+      case ADD_BOOT_OPTION_STATE:\r
+      case ADD_DRIVER_OPTION_STATE:\r
+        if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {\r
+          FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
+        } else {\r
+          FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
+        }\r
+\r
+        CallbackData->MenuEntry = NewMenuEntry;\r
+        CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;\r
+\r
+        //\r
+        // Clean up file explore page.\r
+        //\r
+        RefreshUpdateData (FALSE, 0, FALSE, 0, 1);\r
+\r
+        //\r
+        // Remove the Subtitle op-code.\r
+        //\r
+        CallbackData->Hii->UpdateForm (\r
+                            CallbackData->Hii,\r
+                            CallbackData->FeHiiHandle,\r
+                            FormId,\r
+                            FALSE,\r
+                            UpdateData\r
+                            );\r
+\r
+        //\r
+        // Create Subtitle op-code for the display string of the option.\r
+        //\r
+        RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 1);\r
+\r
+        CreateSubTitleOpCode (\r
+          NewMenuEntry->DisplayStringToken,\r
+          &UpdateData->Data\r
+          );\r
+\r
+        CallbackData->Hii->UpdateForm (\r
+                            CallbackData->Hii,\r
+                            CallbackData->FeHiiHandle,\r
+                            FormId,\r
+                            TRUE,\r
+                            UpdateData\r
+                            );\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+    }\r
+  }\r
+exit:\r
+  return ExitFileExplorer;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FileExplorerCallback (\r
+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,\r
+  IN UINT16                           KeyValue,\r
+  IN EFI_IFR_DATA_ARRAY               *Data,\r
+  OUT EFI_HII_CALLBACK_PACKET         **Packet\r
+  )\r
+/*++\r
+Routine Description:\r
+  Callback Function for file exploration and file interaction.\r
+\r
+Arguments:\r
+  This            - File explorer callback protocol pointer.     \r
+  KeyValue        - Key value to identify the type of data to expect.\r
+  Data            - A pointer to the data being sent to the original exporting driver.\r
+  Packet          - A pointer to a packet of information which a driver passes back to the browser.\r
+\r
+Returns:\r
+  EFI_SUCCESS     - Callback ended successfully.\r
+  Others          - Contain some errors.\r
+  \r
+--*/\r
+{\r
+  BMM_CALLBACK_DATA     *Private;\r
+  FILE_EXPLORER_NV_DATA *NvRamMap;\r
+  EFI_STATUS            Status;\r
+\r
+  Status                          = EFI_SUCCESS;\r
+  Private                         = FE_CALLBACK_DATA_FROM_THIS (This);\r
+  UpdateData->FormCallbackHandle  = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->FeCallbackHandle;\r
+  NvRamMap                        = (FILE_EXPLORER_NV_DATA *) Data->NvRamMap;\r
+\r
+  if (KEY_VALUE_SAVE_AND_EXIT == KeyValue) {\r
+    //\r
+    // Apply changes and exit formset.\r
+    //\r
+    if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) {\r
+      Status = Var_UpdateBootOption (Private, NvRamMap);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      BOpt_GetBootOptions (Private);\r
+      CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);\r
+    } else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) {\r
+      Status = Var_UpdateDriverOption (\r
+                Private,\r
+                Private->FeHiiHandle,\r
+                NvRamMap->DescriptionData,\r
+                NvRamMap->OptionalData,\r
+                NvRamMap->ForceReconnect\r
+                );\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      BOpt_GetDriverOptions (Private);\r
+      CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);\r
+    }\r
+\r
+    CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);\r
+  } else if (KEY_VALUE_NO_SAVE_AND_EXIT == KeyValue) {\r
+    //\r
+    // Discard changes and exit formset.\r
+    //\r
+    NvRamMap->OptionalData[0]     = 0x0000;\r
+    NvRamMap->DescriptionData[0]  = 0x0000;\r
+    CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);\r
+  } else if (KeyValue < FILE_OPTION_OFFSET) {\r
+    //\r
+    // Exit File Explorer formset.\r
+    //\r
+    CreateCallbackPacket (Packet, EXIT_REQUIRED);\r
+  } else {\r
+    if (UpdateFileExplorer (Private, KeyValue)) {\r
+      CreateCallbackPacket (Packet, EXIT_REQUIRED);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r