2 Internal file explorer functions for SecureBoot configuration module.
4 Copyright (c) 2012 - 2013, 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
&& FileContext
->DevicePath
!= NULL
) {
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 if (MenuEntry
->DisplayString
!= NULL
) {
344 FreePool (MenuEntry
->DisplayString
);
346 if (MenuEntry
->HelpString
!= NULL
) {
347 FreePool (MenuEntry
->HelpString
);
350 FreePool (MenuEntry
);
354 Free resources allocated in Allocate Rountine.
356 @param[in, out] MenuOption Menu to be freed
361 IN OUT SECUREBOOT_MENU_OPTION
*MenuOption
364 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
365 while (!IsListEmpty (&MenuOption
->Head
)) {
367 MenuOption
->Head
.ForwardLink
,
368 SECUREBOOT_MENU_ENTRY
,
370 SECUREBOOT_MENU_ENTRY_SIGNATURE
372 RemoveEntryList (&MenuEntry
->Link
);
373 DestroyMenuEntry (MenuEntry
);
375 MenuOption
->MenuNumber
= 0;
379 This function gets the file information from an open file descriptor, and stores it
380 in a buffer allocated from pool.
382 @param[in] FHand File Handle.
384 @return A pointer to a buffer with file information or NULL is returned
389 IN EFI_FILE_HANDLE FHand
393 EFI_FILE_INFO
*Buffer
;
397 // Initialize for GrowBuffer loop
400 BufferSize
= SIZE_OF_EFI_FILE_INFO
+ 200;
403 // Call the real function
405 while (GrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
406 Status
= FHand
->GetInfo (
418 This function gets the file system information from an open file descriptor,
419 and stores it in a buffer allocated from pool.
421 @param[in] FHand The file handle.
423 @return A pointer to a buffer with file information.
424 @retval NULL is returned if failed to get Vaolume Label Info.
427 EFI_FILE_SYSTEM_VOLUME_LABEL
*
428 FileSystemVolumeLabelInfo (
429 IN EFI_FILE_HANDLE FHand
433 EFI_FILE_SYSTEM_VOLUME_LABEL
*Buffer
;
436 // Initialize for GrowBuffer loop
439 BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
+ 200;
442 // Call the real function
444 while (GrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
445 Status
= FHand
->GetInfo (
447 &gEfiFileSystemVolumeLabelInfoIdGuid
,
457 This function will open a file or directory referenced by DevicePath.
459 This function opens a file with the open mode according to the file path. The
460 Attributes is valid only for EFI_FILE_MODE_CREATE.
462 @param[in, out] FilePath On input, the device path to the file.
463 On output, the remaining device path.
464 @param[out] FileHandle Pointer to the file handle.
465 @param[in] OpenMode The mode to open the file with.
466 @param[in] Attributes The file's file attributes.
468 @retval EFI_SUCCESS The information was set.
469 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
470 @retval EFI_UNSUPPORTED Could not open the file path.
471 @retval EFI_NOT_FOUND The specified file could not be found on the
472 device or the file system could not be found on
474 @retval EFI_NO_MEDIA The device has no medium.
475 @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
476 medium is no longer supported.
477 @retval EFI_DEVICE_ERROR The device reported an error.
478 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
479 @retval EFI_WRITE_PROTECTED The file or medium is write protected.
480 @retval EFI_ACCESS_DENIED The file was opened read only.
481 @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
483 @retval EFI_VOLUME_FULL The volume is full.
487 OpenFileByDevicePath(
488 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
,
489 OUT EFI_FILE_HANDLE
*FileHandle
,
495 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*EfiSimpleFileSystemProtocol
;
496 EFI_FILE_PROTOCOL
*Handle1
;
497 EFI_FILE_PROTOCOL
*Handle2
;
498 EFI_HANDLE DeviceHandle
;
500 if ((FilePath
== NULL
|| FileHandle
== NULL
)) {
501 return EFI_INVALID_PARAMETER
;
504 Status
= gBS
->LocateDevicePath (
505 &gEfiSimpleFileSystemProtocolGuid
,
509 if (EFI_ERROR (Status
)) {
513 Status
= gBS
->OpenProtocol(
515 &gEfiSimpleFileSystemProtocolGuid
,
516 (VOID
**)&EfiSimpleFileSystemProtocol
,
519 EFI_OPEN_PROTOCOL_GET_PROTOCOL
521 if (EFI_ERROR (Status
)) {
525 Status
= EfiSimpleFileSystemProtocol
->OpenVolume(EfiSimpleFileSystemProtocol
, &Handle1
);
526 if (EFI_ERROR (Status
)) {
532 // go down directories one node at a time.
534 while (!IsDevicePathEnd (*FilePath
)) {
536 // For file system access each node should be a file path component
538 if (DevicePathType (*FilePath
) != MEDIA_DEVICE_PATH
||
539 DevicePathSubType (*FilePath
) != MEDIA_FILEPATH_DP
542 return (EFI_INVALID_PARAMETER
);
545 // Open this file path node
551 // Try to test opening an existing file
553 Status
= Handle2
->Open (
556 ((FILEPATH_DEVICE_PATH
*)*FilePath
)->PathName
,
557 OpenMode
&~EFI_FILE_MODE_CREATE
,
562 // see if the error was that it needs to be created
564 if ((EFI_ERROR (Status
)) && (OpenMode
!= (OpenMode
&~EFI_FILE_MODE_CREATE
))) {
565 Status
= Handle2
->Open (
568 ((FILEPATH_DEVICE_PATH
*)*FilePath
)->PathName
,
574 // Close the last node
576 Handle2
->Close (Handle2
);
578 if (EFI_ERROR(Status
)) {
585 *FilePath
= NextDevicePathNode (*FilePath
);
589 // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
591 *FileHandle
= (VOID
*)Handle1
;
596 Function opens and returns a file handle to the root directory of a volume.
598 @param[in] DeviceHandle A handle for a device
600 @return A valid file handle or NULL if error happens.
605 IN EFI_HANDLE DeviceHandle
609 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
610 EFI_FILE_HANDLE File
;
615 // File the file system interface to the device
617 Status
= gBS
->HandleProtocol (
619 &gEfiSimpleFileSystemProtocolGuid
,
624 // Open the root directory of the volume
626 if (!EFI_ERROR (Status
)) {
627 Status
= Volume
->OpenVolume (
635 return EFI_ERROR (Status
) ? NULL
: File
;
639 This function builds the FsOptionMenu list which records all
640 available file system in the system. They include all instances
641 of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM
642 and all type of legacy boot device.
644 @retval EFI_SUCCESS Success find the file system
645 @retval EFI_OUT_OF_RESOURCES Can not create menu entry
653 UINTN NoBlkIoHandles
;
654 UINTN NoSimpleFsHandles
;
655 UINTN NoLoadFileHandles
;
656 EFI_HANDLE
*BlkIoHandle
;
657 EFI_HANDLE
*SimpleFsHandle
;
659 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
662 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
663 SECUREBOOT_FILE_CONTEXT
*FileContext
;
668 BOOLEAN RemovableMedia
;
671 NoSimpleFsHandles
= 0;
672 NoLoadFileHandles
= 0;
674 InitializeListHead (&FsOptionMenu
.Head
);
677 // Locate Handles that support BlockIo protocol
679 Status
= gBS
->LocateHandleBuffer (
681 &gEfiBlockIoProtocolGuid
,
686 if (!EFI_ERROR (Status
)) {
688 for (Index
= 0; Index
< NoBlkIoHandles
; Index
++) {
689 Status
= gBS
->HandleProtocol (
691 &gEfiBlockIoProtocolGuid
,
695 if (EFI_ERROR (Status
)) {
700 // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media
702 if (BlkIo
->Media
->RemovableMedia
) {
703 Buffer
= AllocateZeroPool (BlkIo
->Media
->BlockSize
);
704 if (NULL
== Buffer
) {
705 FreePool (BlkIoHandle
);
706 return EFI_OUT_OF_RESOURCES
;
711 BlkIo
->Media
->MediaId
,
713 BlkIo
->Media
->BlockSize
,
719 FreePool (BlkIoHandle
);
723 // Locate Handles that support Simple File System protocol
725 Status
= gBS
->LocateHandleBuffer (
727 &gEfiSimpleFileSystemProtocolGuid
,
732 if (!EFI_ERROR (Status
)) {
734 // Find all the instances of the File System prototocol
736 for (Index
= 0; Index
< NoSimpleFsHandles
; Index
++) {
737 Status
= gBS
->HandleProtocol (
738 SimpleFsHandle
[Index
],
739 &gEfiBlockIoProtocolGuid
,
742 if (EFI_ERROR (Status
)) {
744 // If no block IO exists assume it's NOT a removable media
746 RemovableMedia
= FALSE
;
749 // If block IO exists check to see if it's remobable media
751 RemovableMedia
= BlkIo
->Media
->RemovableMedia
;
755 // Allocate pool for this instance.
757 MenuEntry
= CreateMenuEntry ();
758 if (NULL
== MenuEntry
) {
759 FreePool (SimpleFsHandle
);
760 return EFI_OUT_OF_RESOURCES
;
763 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
765 FileContext
->Handle
= SimpleFsHandle
[Index
];
766 MenuEntry
->OptionNumber
= Index
;
767 FileContext
->FHandle
= OpenRoot (FileContext
->Handle
);
768 if (FileContext
->FHandle
== NULL
) {
769 DestroyMenuEntry (MenuEntry
);
773 MenuEntry
->HelpString
= DevicePathToStr (DevicePathFromHandle (FileContext
->Handle
));
774 FileContext
->Info
= FileSystemVolumeLabelInfo (FileContext
->FHandle
);
775 FileContext
->FileName
= StrDuplicate (L
"\\");
776 FileContext
->DevicePath
= FileDevicePath (
778 FileContext
->FileName
780 FileContext
->IsDir
= TRUE
;
781 FileContext
->IsRoot
= TRUE
;
782 FileContext
->IsRemovableMedia
= RemovableMedia
;
783 FileContext
->IsLoadFile
= FALSE
;
786 // Get current file system's Volume Label
788 if (FileContext
->Info
== NULL
) {
789 VolumeLabel
= L
"NO FILE SYSTEM INFO";
791 if (FileContext
->Info
->VolumeLabel
== NULL
) {
792 VolumeLabel
= L
"NULL VOLUME LABEL";
794 VolumeLabel
= FileContext
->Info
->VolumeLabel
;
795 if (*VolumeLabel
== 0x0000) {
796 VolumeLabel
= L
"NO VOLUME LABEL";
801 TempStr
= MenuEntry
->HelpString
;
802 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
803 ASSERT (MenuEntry
->DisplayString
!= NULL
);
805 MenuEntry
->DisplayString
,
812 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
816 if (NoSimpleFsHandles
!= 0) {
817 FreePool (SimpleFsHandle
);
821 // Remember how many file system options are here
823 FsOptionMenu
.MenuNumber
= OptionNumber
;
829 Find files under the current directory. All files and sub-directories
830 in current directory will be stored in DirectoryMenu for future use.
832 @param[in] MenuEntry The Menu Entry.
834 @retval EFI_SUCCESS Get files from current dir successfully.
835 @return Other Can't get files from current dir.
840 IN SECUREBOOT_MENU_ENTRY
*MenuEntry
843 EFI_FILE_HANDLE NewDir
;
845 EFI_FILE_INFO
*DirInfo
;
848 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
849 SECUREBOOT_FILE_CONTEXT
*FileContext
;
850 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
855 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
856 Dir
= FileContext
->FHandle
;
859 // Open current directory to get files from it
864 FileContext
->FileName
,
868 if (!FileContext
->IsRoot
) {
872 if (EFI_ERROR (Status
)) {
876 DirInfo
= FileInfo (NewDir
);
877 if (DirInfo
== NULL
) {
878 return EFI_NOT_FOUND
;
881 if ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0) {
882 return EFI_INVALID_PARAMETER
;
885 FileContext
->DevicePath
= FileDevicePath (
887 FileContext
->FileName
890 DirBufferSize
= sizeof (EFI_FILE_INFO
) + 1024;
891 DirInfo
= AllocateZeroPool (DirBufferSize
);
892 if (DirInfo
== NULL
) {
893 return EFI_OUT_OF_RESOURCES
;
897 // Get all files in current directory
898 // Pass 1 to get Directories
899 // Pass 2 to get files that are EFI images
901 for (Pass
= 1; Pass
<= 2; Pass
++) {
902 NewDir
->SetPosition (NewDir
, 0);
904 BufferSize
= DirBufferSize
;
905 Status
= NewDir
->Read (NewDir
, &BufferSize
, DirInfo
);
906 if (EFI_ERROR (Status
) || BufferSize
== 0) {
910 if (((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) != 0 && Pass
== 2) ||
911 ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0 && Pass
== 1)
914 // Pass 1 is for Directories
915 // Pass 2 is for file names
920 NewMenuEntry
= CreateMenuEntry ();
921 if (NULL
== NewMenuEntry
) {
922 return EFI_OUT_OF_RESOURCES
;
925 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
926 NewFileContext
->Handle
= FileContext
->Handle
;
927 NewFileContext
->FileName
= AppendFileName (
928 FileContext
->FileName
,
931 NewFileContext
->FHandle
= NewDir
;
932 NewFileContext
->DevicePath
= FileDevicePath (
933 NewFileContext
->Handle
,
934 NewFileContext
->FileName
936 NewMenuEntry
->HelpString
= NULL
;
938 NewFileContext
->IsDir
= (BOOLEAN
) ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
);
939 if (NewFileContext
->IsDir
) {
940 BufferSize
= StrLen (DirInfo
->FileName
) * 2 + 6;
941 NewMenuEntry
->DisplayString
= AllocateZeroPool (BufferSize
);
944 NewMenuEntry
->DisplayString
,
951 NewMenuEntry
->DisplayString
= StrDuplicate (DirInfo
->FileName
);
954 NewFileContext
->IsRoot
= FALSE
;
955 NewFileContext
->IsLoadFile
= FALSE
;
956 NewFileContext
->IsRemovableMedia
= FALSE
;
958 NewMenuEntry
->OptionNumber
= OptionNumber
;
960 InsertTailList (&DirectoryMenu
.Head
, &NewMenuEntry
->Link
);
964 DirectoryMenu
.MenuNumber
= OptionNumber
;
970 Refresh the global UpdateData structure.
979 // Free current updated date
981 if (mStartOpCodeHandle
!= NULL
) {
982 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
986 // Create new OpCode Handle
988 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
991 // Create Hii Extend Label OpCode as the start opcode
993 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
997 sizeof (EFI_IFR_GUID_LABEL
)
999 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1003 Update the File Explore page.
1005 @param[in] HiiHandle Hii Handle of the package to be updated.
1006 @param[in] MenuOption The Menu whose string tokens need to be updated.
1007 @param[in] FeCurrentState Current file explorer state.
1011 UpdateFileExplorePage (
1012 IN EFI_HII_HANDLE HiiHandle
,
1013 IN SECUREBOOT_MENU_OPTION
*MenuOption
,
1014 IN FILE_EXPLORER_STATE FeCurrentState
1018 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
1019 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
1021 EFI_FORM_ID FileFormId
;
1023 if (FeCurrentState
== FileExplorerStateEnrollPkFile
) {
1024 FormId
= SECUREBOOT_ADD_PK_FILE_FORM_ID
;
1025 FileFormId
= FORM_FILE_EXPLORER_ID_PK
;
1026 } else if (FeCurrentState
== FileExplorerStateEnrollKekFile
) {
1027 FormId
= FORMID_ENROLL_KEK_FORM
;
1028 FileFormId
= FORM_FILE_EXPLORER_ID_KEK
;
1029 } else if (FeCurrentState
== FileExplorerStateEnrollSignatureFileToDb
) {
1030 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
1031 FileFormId
= FORM_FILE_EXPLORER_ID_DB
;
1032 } else if (FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbx
) {
1033 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
1034 FileFormId
= FORM_FILE_EXPLORER_ID_DBX
;
1039 NewMenuEntry
= NULL
;
1040 NewFileContext
= NULL
;
1042 RefreshUpdateData ();
1043 mStartLabel
->Number
= FORM_FILE_EXPLORER_ID
;
1045 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
1046 NewMenuEntry
= GetMenuEntry (MenuOption
, Index
);
1047 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
1049 if (NewFileContext
->IsDir
) {
1051 // Create Text opcode for directory.
1053 HiiCreateActionOpCode (
1055 (UINT16
) (FILE_OPTION_OFFSET
+ Index
),
1056 NewMenuEntry
->DisplayStringToken
,
1057 STRING_TOKEN (STR_NULL
),
1058 EFI_IFR_FLAG_CALLBACK
,
1064 // Create Goto opcode for file.
1066 HiiCreateGotoOpCode (
1069 NewMenuEntry
->DisplayStringToken
,
1070 STRING_TOKEN (STR_NULL
),
1071 EFI_IFR_FLAG_CALLBACK
,
1072 (UINT16
) (FILE_OPTION_OFFSET
+ Index
)
1079 &gSecureBootConfigFormSetGuid
,
1081 mStartOpCodeHandle
, // Label FORM_FILE_EXPLORER_ID
1082 mEndOpCodeHandle
// LABEL_END
1087 Update the file explorer page with the refreshed file system.
1089 @param[in] PrivateData Module private data.
1090 @param[in] KeyValue Key value to identify the type of data to expect.
1092 @retval TRUE Inform the caller to create a callback packet to exit file explorer.
1093 @retval FALSE Indicate that there is no need to exit file explorer.
1097 UpdateFileExplorer (
1098 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
1102 UINT16 FileOptionMask
;
1103 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
1104 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
1106 BOOLEAN ExitFileExplorer
;
1108 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1110 NewMenuEntry
= NULL
;
1111 NewFileContext
= NULL
;
1112 ExitFileExplorer
= FALSE
;
1113 FileOptionMask
= (UINT16
) (FILE_OPTION_MASK
& KeyValue
);
1115 if (PrivateData
->FeDisplayContext
== FileExplorerDisplayUnknown
) {
1117 // First in, display file system.
1119 FreeMenu (&FsOptionMenu
);
1122 CreateMenuStringToken (PrivateData
->HiiHandle
, &FsOptionMenu
);
1123 UpdateFileExplorePage (PrivateData
->HiiHandle
, &FsOptionMenu
, PrivateData
->FeCurrentState
);
1125 PrivateData
->FeDisplayContext
= FileExplorerDisplayFileSystem
;
1127 if (PrivateData
->FeDisplayContext
== FileExplorerDisplayFileSystem
) {
1128 NewMenuEntry
= GetMenuEntry (&FsOptionMenu
, FileOptionMask
);
1129 } else if (PrivateData
->FeDisplayContext
== FileExplorerDisplayDirectory
) {
1130 NewMenuEntry
= GetMenuEntry (&DirectoryMenu
, FileOptionMask
);
1133 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
1135 if (NewFileContext
->IsDir
) {
1136 PrivateData
->FeDisplayContext
= FileExplorerDisplayDirectory
;
1138 RemoveEntryList (&NewMenuEntry
->Link
);
1139 FreeMenu (&DirectoryMenu
);
1140 Status
= FindFiles (NewMenuEntry
);
1141 if (EFI_ERROR (Status
)) {
1142 ExitFileExplorer
= TRUE
;
1145 CreateMenuStringToken (PrivateData
->HiiHandle
, &DirectoryMenu
);
1146 DestroyMenuEntry (NewMenuEntry
);
1148 UpdateFileExplorePage (PrivateData
->HiiHandle
, &DirectoryMenu
, PrivateData
->FeCurrentState
);
1151 if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollPkFile
) {
1152 FormId
= SECUREBOOT_ADD_PK_FILE_FORM_ID
;
1153 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollKekFile
) {
1154 FormId
= FORMID_ENROLL_KEK_FORM
;
1155 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollSignatureFileToDb
) {
1156 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
1157 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbx
) {
1158 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
1163 PrivateData
->MenuEntry
= NewMenuEntry
;
1164 PrivateData
->FileContext
->FileName
= NewFileContext
->FileName
;
1166 TmpDevicePath
= NewFileContext
->DevicePath
;
1167 OpenFileByDevicePath (
1169 &PrivateData
->FileContext
->FHandle
,
1175 // Create Subtitle op-code for the display string of the option.
1177 RefreshUpdateData ();
1178 mStartLabel
->Number
= FormId
;
1180 HiiCreateSubTitleOpCode (
1182 NewMenuEntry
->DisplayStringToken
,
1189 PrivateData
->HiiHandle
,
1190 &gSecureBootConfigFormSetGuid
,
1192 mStartOpCodeHandle
, // Label FormId
1193 mEndOpCodeHandle
// LABEL_END
1199 return ExitFileExplorer
;
1203 Clean up the dynamic opcode at label and form specified by both LabelId.
1205 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
1206 @param[in] PrivateData Module private data.
1212 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
1215 RefreshUpdateData ();
1218 // Remove all op-codes from dynamic page
1220 mStartLabel
->Number
= LabelId
;
1222 PrivateData
->HiiHandle
,
1223 &gSecureBootConfigFormSetGuid
,
1225 mStartOpCodeHandle
, // Label LabelId
1226 mEndOpCodeHandle
// LABEL_END