2 Internal file explorer functions for SecureBoot configuration module.
4 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "SecureBootConfigImpl.h"
18 /// File system selection menu
20 SECUREBOOT_MENU_OPTION FsOptionMenu
= {
21 SECUREBOOT_MENU_OPTION_SIGNATURE
,
27 /// Files and sub-directories in current directory menu
29 SECUREBOOT_MENU_OPTION DirectoryMenu
= {
30 SECUREBOOT_MENU_OPTION_SIGNATURE
,
35 VOID
*mStartOpCodeHandle
= NULL
;
36 VOID
*mEndOpCodeHandle
= NULL
;
37 EFI_IFR_GUID_LABEL
*mStartLabel
= NULL
;
38 EFI_IFR_GUID_LABEL
*mEndLabel
= NULL
;
43 @param[in] Src The source string.
45 @return A new string which is duplicated copy of the source,
46 or NULL if there is not enough memory.
58 Dest
= AllocateZeroPool (Size
);
59 ASSERT (Dest
!= NULL
);
61 CopyMem (Dest
, Src
, Size
);
68 Helper function called as part of the code needed to allocate
69 the proper sized buffer for various EFI interfaces.
71 @param[in, out] Status Current status
72 @param[in, out] Buffer Current allocated buffer, or NULL
73 @param[in] BufferSize Current buffer size needed
75 @retval TRUE If the buffer was reallocated and the caller
76 should try the API again.
77 @retval FALSE The caller should not call this function again.
82 IN OUT EFI_STATUS
*Status
,
90 // If this is an initial request, buffer will be null with a new buffer size
92 if ((*Buffer
== NULL
) && (BufferSize
!= 0)) {
93 *Status
= EFI_BUFFER_TOO_SMALL
;
96 // If the status code is "buffer too small", resize the buffer
99 if (*Status
== EFI_BUFFER_TOO_SMALL
) {
101 if (*Buffer
!= NULL
) {
105 *Buffer
= AllocateZeroPool (BufferSize
);
107 if (*Buffer
!= NULL
) {
110 *Status
= EFI_OUT_OF_RESOURCES
;
114 // If there's an error, free the buffer
116 if (!TryAgain
&& EFI_ERROR (*Status
) && (*Buffer
!= NULL
)) {
125 Append file name to existing file name, and allocate a new buffer
126 to hold the appended result.
128 @param[in] Str1 The existing file name
129 @param[in] Str2 The file name to be appended
131 @return A new string with appended result.
147 Size1
= StrSize (Str1
);
148 Size2
= StrSize (Str2
);
149 Str
= AllocateZeroPool (Size1
+ Size2
+ sizeof (CHAR16
));
150 ASSERT (Str
!= NULL
);
152 TmpStr
= AllocateZeroPool (Size1
+ Size2
+ sizeof (CHAR16
));
153 ASSERT (TmpStr
!= NULL
);
156 if (!((*Str
== '\\') && (*(Str
+ 1) == 0))) {
165 if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '.' && *(Ptr
+ 3) == L
'\\') {
167 // Convert "\Name\..\" to "\"
168 // DO NOT convert the .. if it is at the end of the string. This will
169 // break the .. behavior in changing directories.
173 // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings
176 StrCpy (TmpStr
, Ptr
+ 3);
177 StrCpy (LastSlash
, TmpStr
);
179 } else if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '\\') {
181 // Convert a "\.\" to a "\"
185 // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings
188 StrCpy (TmpStr
, Ptr
+ 2);
189 StrCpy (Ptr
, TmpStr
);
191 } else if (*Ptr
== '\\') {
204 Create a SECUREBOOT_MENU_ENTRY, and stores it in a buffer allocated from the pool.
206 @return The new menu entry or NULL of error happens.
209 SECUREBOOT_MENU_ENTRY
*
214 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
218 // Create new menu entry
220 MenuEntry
= AllocateZeroPool (sizeof (SECUREBOOT_MENU_ENTRY
));
221 if (MenuEntry
== NULL
) {
225 ContextSize
= sizeof (SECUREBOOT_FILE_CONTEXT
);
226 MenuEntry
->FileContext
= AllocateZeroPool (ContextSize
);
227 if (MenuEntry
->FileContext
== NULL
) {
228 FreePool (MenuEntry
);
232 MenuEntry
->Signature
= SECUREBOOT_MENU_ENTRY_SIGNATURE
;
238 Get Menu Entry from the Menu Entry List by MenuNumber.
240 If MenuNumber is great or equal to the number of Menu
241 Entry in the list, then ASSERT.
243 @param[in] MenuOption The Menu Entry List to read the menu entry.
244 @param[in] MenuNumber The index of Menu Entry.
246 @return The Menu Entry.
249 SECUREBOOT_MENU_ENTRY
*
251 IN SECUREBOOT_MENU_OPTION
*MenuOption
,
255 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
259 ASSERT (MenuNumber
< MenuOption
->MenuNumber
);
261 List
= MenuOption
->Head
.ForwardLink
;
262 for (Index
= 0; Index
< MenuNumber
; Index
++) {
263 List
= List
->ForwardLink
;
266 NewMenuEntry
= CR (List
, SECUREBOOT_MENU_ENTRY
, Link
, SECUREBOOT_MENU_ENTRY_SIGNATURE
);
272 Create string tokens for a menu from its help strings and display strings.
274 @param[in] HiiHandle Hii Handle of the package to be updated.
275 @param[in] MenuOption The Menu whose string tokens need to be created.
279 CreateMenuStringToken (
280 IN EFI_HII_HANDLE HiiHandle
,
281 IN SECUREBOOT_MENU_OPTION
*MenuOption
284 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
287 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
288 NewMenuEntry
= GetMenuEntry (MenuOption
, Index
);
290 NewMenuEntry
->DisplayStringToken
= HiiSetString (
293 NewMenuEntry
->DisplayString
,
297 if (NewMenuEntry
->HelpString
== NULL
) {
298 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
300 NewMenuEntry
->HelpStringToken
= HiiSetString (
303 NewMenuEntry
->HelpString
,
311 Free up all resources allocated for a SECUREBOOT_MENU_ENTRY.
313 @param[in, out] MenuEntry A pointer to SECUREBOOT_MENU_ENTRY.
318 IN OUT SECUREBOOT_MENU_ENTRY
*MenuEntry
321 SECUREBOOT_FILE_CONTEXT
*FileContext
;
324 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
326 if (!FileContext
->IsRoot
) {
327 FreePool (FileContext
->DevicePath
);
329 if (FileContext
->FHandle
!= NULL
) {
330 FileContext
->FHandle
->Close (FileContext
->FHandle
);
334 if (FileContext
->FileName
!= NULL
) {
335 FreePool (FileContext
->FileName
);
337 if (FileContext
->Info
!= NULL
) {
338 FreePool (FileContext
->Info
);
341 FreePool (FileContext
);
343 FreePool (MenuEntry
->DisplayString
);
344 if (MenuEntry
->HelpString
!= NULL
) {
345 FreePool (MenuEntry
->HelpString
);
348 FreePool (MenuEntry
);
352 Free resources allocated in Allocate Rountine.
354 @param[in, out] MenuOption Menu to be freed
359 IN OUT SECUREBOOT_MENU_OPTION
*MenuOption
362 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
363 while (!IsListEmpty (&MenuOption
->Head
)) {
365 MenuOption
->Head
.ForwardLink
,
366 SECUREBOOT_MENU_ENTRY
,
368 SECUREBOOT_MENU_ENTRY_SIGNATURE
370 RemoveEntryList (&MenuEntry
->Link
);
371 DestroyMenuEntry (MenuEntry
);
373 MenuOption
->MenuNumber
= 0;
377 This function gets the file information from an open file descriptor, and stores it
378 in a buffer allocated from pool.
380 @param[in] FHand File Handle.
382 @return A pointer to a buffer with file information or NULL is returned
387 IN EFI_FILE_HANDLE FHand
391 EFI_FILE_INFO
*Buffer
;
395 // Initialize for GrowBuffer loop
398 BufferSize
= SIZE_OF_EFI_FILE_INFO
+ 200;
401 // Call the real function
403 while (GrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
404 Status
= FHand
->GetInfo (
416 This function gets the file system information from an open file descriptor,
417 and stores it in a buffer allocated from pool.
419 @param[in] FHand The file handle.
421 @return A pointer to a buffer with file information.
422 @retval NULL is returned if failed to get Vaolume Label Info.
425 EFI_FILE_SYSTEM_VOLUME_LABEL
*
426 FileSystemVolumeLabelInfo (
427 IN EFI_FILE_HANDLE FHand
431 EFI_FILE_SYSTEM_VOLUME_LABEL
*Buffer
;
434 // Initialize for GrowBuffer loop
437 BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
+ 200;
440 // Call the real function
442 while (GrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
443 Status
= FHand
->GetInfo (
445 &gEfiFileSystemVolumeLabelInfoIdGuid
,
455 This function will open a file or directory referenced by DevicePath.
457 This function opens a file with the open mode according to the file path. The
458 Attributes is valid only for EFI_FILE_MODE_CREATE.
460 @param[in, out] FilePath On input, the device path to the file.
461 On output, the remaining device path.
462 @param[out] FileHandle Pointer to the file handle.
463 @param[in] OpenMode The mode to open the file with.
464 @param[in] Attributes The file's file attributes.
466 @retval EFI_SUCCESS The information was set.
467 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
468 @retval EFI_UNSUPPORTED Could not open the file path.
469 @retval EFI_NOT_FOUND The specified file could not be found on the
470 device or the file system could not be found on
472 @retval EFI_NO_MEDIA The device has no medium.
473 @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
474 medium is no longer supported.
475 @retval EFI_DEVICE_ERROR The device reported an error.
476 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
477 @retval EFI_WRITE_PROTECTED The file or medium is write protected.
478 @retval EFI_ACCESS_DENIED The file was opened read only.
479 @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
481 @retval EFI_VOLUME_FULL The volume is full.
485 OpenFileByDevicePath(
486 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
,
487 OUT EFI_FILE_HANDLE
*FileHandle
,
493 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*EfiSimpleFileSystemProtocol
;
494 EFI_FILE_PROTOCOL
*Handle1
;
495 EFI_FILE_PROTOCOL
*Handle2
;
496 EFI_HANDLE DeviceHandle
;
498 if ((FilePath
== NULL
|| FileHandle
== NULL
)) {
499 return EFI_INVALID_PARAMETER
;
502 Status
= gBS
->LocateDevicePath (
503 &gEfiSimpleFileSystemProtocolGuid
,
507 if (EFI_ERROR (Status
)) {
511 Status
= gBS
->OpenProtocol(
513 &gEfiSimpleFileSystemProtocolGuid
,
514 (VOID
**)&EfiSimpleFileSystemProtocol
,
517 EFI_OPEN_PROTOCOL_GET_PROTOCOL
519 if (EFI_ERROR (Status
)) {
523 Status
= EfiSimpleFileSystemProtocol
->OpenVolume(EfiSimpleFileSystemProtocol
, &Handle1
);
524 if (EFI_ERROR (Status
)) {
530 // go down directories one node at a time.
532 while (!IsDevicePathEnd (*FilePath
)) {
534 // For file system access each node should be a file path component
536 if (DevicePathType (*FilePath
) != MEDIA_DEVICE_PATH
||
537 DevicePathSubType (*FilePath
) != MEDIA_FILEPATH_DP
540 return (EFI_INVALID_PARAMETER
);
543 // Open this file path node
549 // Try to test opening an existing file
551 Status
= Handle2
->Open (
554 ((FILEPATH_DEVICE_PATH
*)*FilePath
)->PathName
,
555 OpenMode
&~EFI_FILE_MODE_CREATE
,
560 // see if the error was that it needs to be created
562 if ((EFI_ERROR (Status
)) && (OpenMode
!= (OpenMode
&~EFI_FILE_MODE_CREATE
))) {
563 Status
= Handle2
->Open (
566 ((FILEPATH_DEVICE_PATH
*)*FilePath
)->PathName
,
572 // Close the last node
574 Handle2
->Close (Handle2
);
576 if (EFI_ERROR(Status
)) {
583 *FilePath
= NextDevicePathNode (*FilePath
);
587 // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
589 *FileHandle
= (VOID
*)Handle1
;
594 Function opens and returns a file handle to the root directory of a volume.
596 @param[in] DeviceHandle A handle for a device
598 @return A valid file handle or NULL if error happens.
603 IN EFI_HANDLE DeviceHandle
607 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
608 EFI_FILE_HANDLE File
;
613 // File the file system interface to the device
615 Status
= gBS
->HandleProtocol (
617 &gEfiSimpleFileSystemProtocolGuid
,
622 // Open the root directory of the volume
624 if (!EFI_ERROR (Status
)) {
625 Status
= Volume
->OpenVolume (
633 return EFI_ERROR (Status
) ? NULL
: File
;
637 This function builds the FsOptionMenu list which records all
638 available file system in the system. They include all instances
639 of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM
640 and all type of legacy boot device.
642 @retval EFI_SUCCESS Success find the file system
643 @retval EFI_OUT_OF_RESOURCES Can not create menu entry
651 UINTN NoBlkIoHandles
;
652 UINTN NoSimpleFsHandles
;
653 UINTN NoLoadFileHandles
;
654 EFI_HANDLE
*BlkIoHandle
;
655 EFI_HANDLE
*SimpleFsHandle
;
657 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
660 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
661 SECUREBOOT_FILE_CONTEXT
*FileContext
;
666 BOOLEAN RemovableMedia
;
669 NoSimpleFsHandles
= 0;
670 NoLoadFileHandles
= 0;
672 InitializeListHead (&FsOptionMenu
.Head
);
675 // Locate Handles that support BlockIo protocol
677 Status
= gBS
->LocateHandleBuffer (
679 &gEfiBlockIoProtocolGuid
,
684 if (!EFI_ERROR (Status
)) {
686 for (Index
= 0; Index
< NoBlkIoHandles
; Index
++) {
687 Status
= gBS
->HandleProtocol (
689 &gEfiBlockIoProtocolGuid
,
693 if (EFI_ERROR (Status
)) {
698 // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media
700 if (BlkIo
->Media
->RemovableMedia
) {
701 Buffer
= AllocateZeroPool (BlkIo
->Media
->BlockSize
);
702 if (NULL
== Buffer
) {
703 FreePool (BlkIoHandle
);
704 return EFI_OUT_OF_RESOURCES
;
709 BlkIo
->Media
->MediaId
,
711 BlkIo
->Media
->BlockSize
,
717 FreePool (BlkIoHandle
);
721 // Locate Handles that support Simple File System protocol
723 Status
= gBS
->LocateHandleBuffer (
725 &gEfiSimpleFileSystemProtocolGuid
,
730 if (!EFI_ERROR (Status
)) {
732 // Find all the instances of the File System prototocol
734 for (Index
= 0; Index
< NoSimpleFsHandles
; Index
++) {
735 Status
= gBS
->HandleProtocol (
736 SimpleFsHandle
[Index
],
737 &gEfiBlockIoProtocolGuid
,
740 if (EFI_ERROR (Status
)) {
742 // If no block IO exists assume it's NOT a removable media
744 RemovableMedia
= FALSE
;
747 // If block IO exists check to see if it's remobable media
749 RemovableMedia
= BlkIo
->Media
->RemovableMedia
;
753 // Allocate pool for this instance.
755 MenuEntry
= CreateMenuEntry ();
756 if (NULL
== MenuEntry
) {
757 FreePool (SimpleFsHandle
);
758 return EFI_OUT_OF_RESOURCES
;
761 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
763 FileContext
->Handle
= SimpleFsHandle
[Index
];
764 MenuEntry
->OptionNumber
= Index
;
765 FileContext
->FHandle
= OpenRoot (FileContext
->Handle
);
766 if (FileContext
->FHandle
== NULL
) {
767 DestroyMenuEntry (MenuEntry
);
771 MenuEntry
->HelpString
= DevicePathToStr (DevicePathFromHandle (FileContext
->Handle
));
772 FileContext
->Info
= FileSystemVolumeLabelInfo (FileContext
->FHandle
);
773 FileContext
->FileName
= StrDuplicate (L
"\\");
774 FileContext
->DevicePath
= FileDevicePath (
776 FileContext
->FileName
778 FileContext
->IsDir
= TRUE
;
779 FileContext
->IsRoot
= TRUE
;
780 FileContext
->IsRemovableMedia
= RemovableMedia
;
781 FileContext
->IsLoadFile
= FALSE
;
784 // Get current file system's Volume Label
786 if (FileContext
->Info
== NULL
) {
787 VolumeLabel
= L
"NO FILE SYSTEM INFO";
789 if (FileContext
->Info
->VolumeLabel
== NULL
) {
790 VolumeLabel
= L
"NULL VOLUME LABEL";
792 VolumeLabel
= FileContext
->Info
->VolumeLabel
;
793 if (*VolumeLabel
== 0x0000) {
794 VolumeLabel
= L
"NO VOLUME LABEL";
799 TempStr
= MenuEntry
->HelpString
;
800 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
801 ASSERT (MenuEntry
->DisplayString
!= NULL
);
803 MenuEntry
->DisplayString
,
810 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
814 if (NoSimpleFsHandles
!= 0) {
815 FreePool (SimpleFsHandle
);
819 // Remember how many file system options are here
821 FsOptionMenu
.MenuNumber
= OptionNumber
;
827 Find files under the current directory. All files and sub-directories
828 in current directory will be stored in DirectoryMenu for future use.
830 @param[in] MenuEntry The Menu Entry.
832 @retval EFI_SUCCESS Get files from current dir successfully.
833 @return Other Can't get files from current dir.
838 IN SECUREBOOT_MENU_ENTRY
*MenuEntry
841 EFI_FILE_HANDLE NewDir
;
843 EFI_FILE_INFO
*DirInfo
;
846 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
847 SECUREBOOT_FILE_CONTEXT
*FileContext
;
848 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
853 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
854 Dir
= FileContext
->FHandle
;
857 // Open current directory to get files from it
862 FileContext
->FileName
,
866 if (!FileContext
->IsRoot
) {
870 if (EFI_ERROR (Status
)) {
874 DirInfo
= FileInfo (NewDir
);
875 if (DirInfo
== NULL
) {
876 return EFI_NOT_FOUND
;
879 if ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0) {
880 return EFI_INVALID_PARAMETER
;
883 FileContext
->DevicePath
= FileDevicePath (
885 FileContext
->FileName
888 DirBufferSize
= sizeof (EFI_FILE_INFO
) + 1024;
889 DirInfo
= AllocateZeroPool (DirBufferSize
);
890 if (DirInfo
== NULL
) {
891 return EFI_OUT_OF_RESOURCES
;
895 // Get all files in current directory
896 // Pass 1 to get Directories
897 // Pass 2 to get files that are EFI images
899 for (Pass
= 1; Pass
<= 2; Pass
++) {
900 NewDir
->SetPosition (NewDir
, 0);
902 BufferSize
= DirBufferSize
;
903 Status
= NewDir
->Read (NewDir
, &BufferSize
, DirInfo
);
904 if (EFI_ERROR (Status
) || BufferSize
== 0) {
908 if (((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) != 0 && Pass
== 2) ||
909 ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0 && Pass
== 1)
912 // Pass 1 is for Directories
913 // Pass 2 is for file names
918 NewMenuEntry
= CreateMenuEntry ();
919 if (NULL
== NewMenuEntry
) {
920 return EFI_OUT_OF_RESOURCES
;
923 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
924 NewFileContext
->Handle
= FileContext
->Handle
;
925 NewFileContext
->FileName
= AppendFileName (
926 FileContext
->FileName
,
929 NewFileContext
->FHandle
= NewDir
;
930 NewFileContext
->DevicePath
= FileDevicePath (
931 NewFileContext
->Handle
,
932 NewFileContext
->FileName
934 NewMenuEntry
->HelpString
= NULL
;
936 NewFileContext
->IsDir
= (BOOLEAN
) ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
);
937 if (NewFileContext
->IsDir
) {
938 BufferSize
= StrLen (DirInfo
->FileName
) * 2 + 6;
939 NewMenuEntry
->DisplayString
= AllocateZeroPool (BufferSize
);
942 NewMenuEntry
->DisplayString
,
949 NewMenuEntry
->DisplayString
= StrDuplicate (DirInfo
->FileName
);
952 NewFileContext
->IsRoot
= FALSE
;
953 NewFileContext
->IsLoadFile
= FALSE
;
954 NewFileContext
->IsRemovableMedia
= FALSE
;
956 NewMenuEntry
->OptionNumber
= OptionNumber
;
958 InsertTailList (&DirectoryMenu
.Head
, &NewMenuEntry
->Link
);
962 DirectoryMenu
.MenuNumber
= OptionNumber
;
968 Refresh the global UpdateData structure.
977 // Free current updated date
979 if (mStartOpCodeHandle
!= NULL
) {
980 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
984 // Create new OpCode Handle
986 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
989 // Create Hii Extend Label OpCode as the start opcode
991 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
995 sizeof (EFI_IFR_GUID_LABEL
)
997 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1001 Update the File Explore page.
1003 @param[in] HiiHandle Hii Handle of the package to be updated.
1004 @param[in] MenuOption The Menu whose string tokens need to be updated.
1005 @param[in] FeCurrentState Current file explorer state.
1009 UpdateFileExplorePage (
1010 IN EFI_HII_HANDLE HiiHandle
,
1011 IN SECUREBOOT_MENU_OPTION
*MenuOption
,
1012 IN FILE_EXPLORER_STATE FeCurrentState
1016 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
1017 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
1019 EFI_FORM_ID FileFormId
;
1021 if (FeCurrentState
== FileExplorerStateEnrollPkFile
) {
1022 FormId
= SECUREBOOT_ADD_PK_FILE_FORM_ID
;
1023 FileFormId
= FORM_FILE_EXPLORER_ID_PK
;
1024 } else if (FeCurrentState
== FileExplorerStateEnrollKekFile
) {
1025 FormId
= FORMID_ENROLL_KEK_FORM
;
1026 FileFormId
= FORM_FILE_EXPLORER_ID_KEK
;
1027 } else if (FeCurrentState
== FileExplorerStateEnrollSignatureFileToDb
) {
1028 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
1029 FileFormId
= FORM_FILE_EXPLORER_ID_DB
;
1030 } else if (FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbx
) {
1031 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
1032 FileFormId
= FORM_FILE_EXPLORER_ID_DBX
;
1037 NewMenuEntry
= NULL
;
1038 NewFileContext
= NULL
;
1040 RefreshUpdateData ();
1041 mStartLabel
->Number
= FORM_FILE_EXPLORER_ID
;
1043 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
1044 NewMenuEntry
= GetMenuEntry (MenuOption
, Index
);
1045 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
1047 if (NewFileContext
->IsDir
) {
1049 // Create Text opcode for directory.
1051 HiiCreateActionOpCode (
1053 (UINT16
) (FILE_OPTION_OFFSET
+ Index
),
1054 NewMenuEntry
->DisplayStringToken
,
1055 STRING_TOKEN (STR_NULL
),
1056 EFI_IFR_FLAG_CALLBACK
,
1062 // Create Goto opcode for file.
1064 HiiCreateGotoOpCode (
1067 NewMenuEntry
->DisplayStringToken
,
1068 STRING_TOKEN (STR_NULL
),
1069 EFI_IFR_FLAG_CALLBACK
,
1070 (UINT16
) (FILE_OPTION_OFFSET
+ Index
)
1077 &gSecureBootConfigFormSetGuid
,
1079 mStartOpCodeHandle
, // Label FORM_FILE_EXPLORER_ID
1080 mEndOpCodeHandle
// LABEL_END
1085 Update the file explorer page with the refreshed file system.
1087 @param[in] PrivateData Module private data.
1088 @param[in] KeyValue Key value to identify the type of data to expect.
1090 @retval TRUE Inform the caller to create a callback packet to exit file explorer.
1091 @retval FALSE Indicate that there is no need to exit file explorer.
1095 UpdateFileExplorer (
1096 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
1100 UINT16 FileOptionMask
;
1101 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
1102 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
1104 BOOLEAN ExitFileExplorer
;
1106 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1108 NewMenuEntry
= NULL
;
1109 NewFileContext
= NULL
;
1110 ExitFileExplorer
= FALSE
;
1111 FileOptionMask
= (UINT16
) (FILE_OPTION_MASK
& KeyValue
);
1113 if (PrivateData
->FeDisplayContext
== FileExplorerDisplayUnknown
) {
1115 // First in, display file system.
1117 FreeMenu (&FsOptionMenu
);
1120 CreateMenuStringToken (PrivateData
->HiiHandle
, &FsOptionMenu
);
1121 UpdateFileExplorePage (PrivateData
->HiiHandle
, &FsOptionMenu
, PrivateData
->FeCurrentState
);
1123 PrivateData
->FeDisplayContext
= FileExplorerDisplayFileSystem
;
1125 if (PrivateData
->FeDisplayContext
== FileExplorerDisplayFileSystem
) {
1126 NewMenuEntry
= GetMenuEntry (&FsOptionMenu
, FileOptionMask
);
1127 } else if (PrivateData
->FeDisplayContext
== FileExplorerDisplayDirectory
) {
1128 NewMenuEntry
= GetMenuEntry (&DirectoryMenu
, FileOptionMask
);
1131 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
1133 if (NewFileContext
->IsDir
) {
1134 PrivateData
->FeDisplayContext
= FileExplorerDisplayDirectory
;
1136 RemoveEntryList (&NewMenuEntry
->Link
);
1137 FreeMenu (&DirectoryMenu
);
1138 Status
= FindFiles (NewMenuEntry
);
1139 if (EFI_ERROR (Status
)) {
1140 ExitFileExplorer
= TRUE
;
1143 CreateMenuStringToken (PrivateData
->HiiHandle
, &DirectoryMenu
);
1144 DestroyMenuEntry (NewMenuEntry
);
1146 UpdateFileExplorePage (PrivateData
->HiiHandle
, &DirectoryMenu
, PrivateData
->FeCurrentState
);
1149 if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollPkFile
) {
1150 FormId
= SECUREBOOT_ADD_PK_FILE_FORM_ID
;
1151 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollKekFile
) {
1152 FormId
= FORMID_ENROLL_KEK_FORM
;
1153 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollSignatureFileToDb
) {
1154 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
1155 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbx
) {
1156 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
1161 PrivateData
->MenuEntry
= NewMenuEntry
;
1162 PrivateData
->FileContext
->FileName
= NewFileContext
->FileName
;
1164 TmpDevicePath
= NewFileContext
->DevicePath
;
1165 OpenFileByDevicePath (
1167 &PrivateData
->FileContext
->FHandle
,
1173 // Create Subtitle op-code for the display string of the option.
1175 RefreshUpdateData ();
1176 mStartLabel
->Number
= FormId
;
1178 HiiCreateSubTitleOpCode (
1180 NewMenuEntry
->DisplayStringToken
,
1187 PrivateData
->HiiHandle
,
1188 &gSecureBootConfigFormSetGuid
,
1190 mStartOpCodeHandle
, // Label FormId
1191 mEndOpCodeHandle
// LABEL_END
1197 return ExitFileExplorer
;
1201 Clean up the dynamic opcode at label and form specified by both LabelId.
1203 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
1204 @param[in] PrivateData Module private data.
1210 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
1213 RefreshUpdateData ();
1216 // Remove all op-codes from dynamic page
1218 mStartLabel
->Number
= LabelId
;
1220 PrivateData
->HiiHandle
,
1221 &gSecureBootConfigFormSetGuid
,
1223 mStartOpCodeHandle
, // Label LabelId
1224 mEndOpCodeHandle
// LABEL_END