2 Internal file explorer functions for SecureBoot configuration module.
4 Copyright (c) 2012 - 2015, 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.
148 Size1
= StrSize (Str1
);
149 Size2
= StrSize (Str2
);
150 BufferSize
= Size1
+ Size2
+ sizeof (CHAR16
);
151 Str
= AllocateZeroPool (BufferSize
);
152 ASSERT (Str
!= NULL
);
154 TmpStr
= AllocateZeroPool (BufferSize
);
155 ASSERT (TmpStr
!= NULL
);
157 StrCatS (Str
, BufferSize
/ sizeof (CHAR16
), Str1
);
159 if (!((*Str
== '\\') && (*(Str
+ 1) == 0))) {
160 StrCatS (Str
, BufferSize
/ sizeof (CHAR16
), L
"\\");
163 StrCatS (Str
, BufferSize
/ sizeof (CHAR16
), Str2
);
168 if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '.' && *(Ptr
+ 3) == L
'\\') {
170 // Convert "\Name\..\" to "\"
171 // DO NOT convert the .. if it is at the end of the string. This will
172 // break the .. behavior in changing directories.
176 // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings
179 StrCpyS (TmpStr
, BufferSize
/ sizeof (CHAR16
), Ptr
+ 3);
180 StrCpyS (LastSlash
, BufferSize
/ sizeof (CHAR16
), TmpStr
);
182 } else if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '\\') {
184 // Convert a "\.\" to a "\"
188 // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings
191 StrCpyS (TmpStr
, BufferSize
/ sizeof (CHAR16
), Ptr
+ 2);
192 StrCpyS (Ptr
, BufferSize
/ sizeof (CHAR16
), TmpStr
);
194 } else if (*Ptr
== '\\') {
207 Create a SECUREBOOT_MENU_ENTRY, and stores it in a buffer allocated from the pool.
209 @return The new menu entry or NULL of error happens.
212 SECUREBOOT_MENU_ENTRY
*
217 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
221 // Create new menu entry
223 MenuEntry
= AllocateZeroPool (sizeof (SECUREBOOT_MENU_ENTRY
));
224 if (MenuEntry
== NULL
) {
228 ContextSize
= sizeof (SECUREBOOT_FILE_CONTEXT
);
229 MenuEntry
->FileContext
= AllocateZeroPool (ContextSize
);
230 if (MenuEntry
->FileContext
== NULL
) {
231 FreePool (MenuEntry
);
235 MenuEntry
->Signature
= SECUREBOOT_MENU_ENTRY_SIGNATURE
;
241 Get Menu Entry from the Menu Entry List by MenuNumber.
243 If MenuNumber is great or equal to the number of Menu
244 Entry in the list, then ASSERT.
246 @param[in] MenuOption The Menu Entry List to read the menu entry.
247 @param[in] MenuNumber The index of Menu Entry.
249 @return The Menu Entry.
252 SECUREBOOT_MENU_ENTRY
*
254 IN SECUREBOOT_MENU_OPTION
*MenuOption
,
258 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
262 ASSERT (MenuNumber
< MenuOption
->MenuNumber
);
264 List
= MenuOption
->Head
.ForwardLink
;
265 for (Index
= 0; Index
< MenuNumber
; Index
++) {
266 List
= List
->ForwardLink
;
269 NewMenuEntry
= CR (List
, SECUREBOOT_MENU_ENTRY
, Link
, SECUREBOOT_MENU_ENTRY_SIGNATURE
);
275 Create string tokens for a menu from its help strings and display strings.
277 @param[in] HiiHandle Hii Handle of the package to be updated.
278 @param[in] MenuOption The Menu whose string tokens need to be created.
282 CreateMenuStringToken (
283 IN EFI_HII_HANDLE HiiHandle
,
284 IN SECUREBOOT_MENU_OPTION
*MenuOption
287 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
290 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
291 NewMenuEntry
= GetMenuEntry (MenuOption
, Index
);
293 NewMenuEntry
->DisplayStringToken
= HiiSetString (
296 NewMenuEntry
->DisplayString
,
300 if (NewMenuEntry
->HelpString
== NULL
) {
301 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
303 NewMenuEntry
->HelpStringToken
= HiiSetString (
306 NewMenuEntry
->HelpString
,
314 Free up all resources allocated for a SECUREBOOT_MENU_ENTRY.
316 @param[in, out] MenuEntry A pointer to SECUREBOOT_MENU_ENTRY.
321 IN OUT SECUREBOOT_MENU_ENTRY
*MenuEntry
324 SECUREBOOT_FILE_CONTEXT
*FileContext
;
327 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
329 if (!FileContext
->IsRoot
&& FileContext
->DevicePath
!= NULL
) {
330 FreePool (FileContext
->DevicePath
);
332 if (FileContext
->FHandle
!= NULL
) {
333 FileContext
->FHandle
->Close (FileContext
->FHandle
);
337 if (FileContext
->FileName
!= NULL
) {
338 FreePool (FileContext
->FileName
);
340 if (FileContext
->Info
!= NULL
) {
341 FreePool (FileContext
->Info
);
344 FreePool (FileContext
);
346 if (MenuEntry
->DisplayString
!= NULL
) {
347 FreePool (MenuEntry
->DisplayString
);
349 if (MenuEntry
->HelpString
!= NULL
) {
350 FreePool (MenuEntry
->HelpString
);
353 FreePool (MenuEntry
);
357 Free resources allocated in Allocate Rountine.
359 @param[in, out] MenuOption Menu to be freed
364 IN OUT SECUREBOOT_MENU_OPTION
*MenuOption
367 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
368 while (!IsListEmpty (&MenuOption
->Head
)) {
370 MenuOption
->Head
.ForwardLink
,
371 SECUREBOOT_MENU_ENTRY
,
373 SECUREBOOT_MENU_ENTRY_SIGNATURE
375 RemoveEntryList (&MenuEntry
->Link
);
376 DestroyMenuEntry (MenuEntry
);
378 MenuOption
->MenuNumber
= 0;
382 This function gets the file information from an open file descriptor, and stores it
383 in a buffer allocated from pool.
385 @param[in] FHand File Handle.
387 @return A pointer to a buffer with file information or NULL is returned
392 IN EFI_FILE_HANDLE FHand
396 EFI_FILE_INFO
*Buffer
;
400 // Initialize for GrowBuffer loop
403 BufferSize
= SIZE_OF_EFI_FILE_INFO
+ 200;
406 // Call the real function
408 while (GrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
409 Status
= FHand
->GetInfo (
421 This function gets the file system information from an open file descriptor,
422 and stores it in a buffer allocated from pool.
424 @param[in] FHand The file handle.
426 @return A pointer to a buffer with file information.
427 @retval NULL is returned if failed to get Vaolume Label Info.
430 EFI_FILE_SYSTEM_VOLUME_LABEL
*
431 FileSystemVolumeLabelInfo (
432 IN EFI_FILE_HANDLE FHand
436 EFI_FILE_SYSTEM_VOLUME_LABEL
*Buffer
;
439 // Initialize for GrowBuffer loop
442 BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
+ 200;
445 // Call the real function
447 while (GrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
448 Status
= FHand
->GetInfo (
450 &gEfiFileSystemVolumeLabelInfoIdGuid
,
460 This function will open a file or directory referenced by DevicePath.
462 This function opens a file with the open mode according to the file path. The
463 Attributes is valid only for EFI_FILE_MODE_CREATE.
465 @param[in, out] FilePath On input, the device path to the file.
466 On output, the remaining device path.
467 @param[out] FileHandle Pointer to the file handle.
468 @param[in] OpenMode The mode to open the file with.
469 @param[in] Attributes The file's file attributes.
471 @retval EFI_SUCCESS The information was set.
472 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
473 @retval EFI_UNSUPPORTED Could not open the file path.
474 @retval EFI_NOT_FOUND The specified file could not be found on the
475 device or the file system could not be found on
477 @retval EFI_NO_MEDIA The device has no medium.
478 @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
479 medium is no longer supported.
480 @retval EFI_DEVICE_ERROR The device reported an error.
481 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
482 @retval EFI_WRITE_PROTECTED The file or medium is write protected.
483 @retval EFI_ACCESS_DENIED The file was opened read only.
484 @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
486 @retval EFI_VOLUME_FULL The volume is full.
490 OpenFileByDevicePath(
491 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
,
492 OUT EFI_FILE_HANDLE
*FileHandle
,
498 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*EfiSimpleFileSystemProtocol
;
499 EFI_FILE_PROTOCOL
*Handle1
;
500 EFI_FILE_PROTOCOL
*Handle2
;
501 EFI_HANDLE DeviceHandle
;
503 if ((FilePath
== NULL
|| FileHandle
== NULL
)) {
504 return EFI_INVALID_PARAMETER
;
507 Status
= gBS
->LocateDevicePath (
508 &gEfiSimpleFileSystemProtocolGuid
,
512 if (EFI_ERROR (Status
)) {
516 Status
= gBS
->OpenProtocol(
518 &gEfiSimpleFileSystemProtocolGuid
,
519 (VOID
**)&EfiSimpleFileSystemProtocol
,
522 EFI_OPEN_PROTOCOL_GET_PROTOCOL
524 if (EFI_ERROR (Status
)) {
528 Status
= EfiSimpleFileSystemProtocol
->OpenVolume(EfiSimpleFileSystemProtocol
, &Handle1
);
529 if (EFI_ERROR (Status
)) {
535 // go down directories one node at a time.
537 while (!IsDevicePathEnd (*FilePath
)) {
539 // For file system access each node should be a file path component
541 if (DevicePathType (*FilePath
) != MEDIA_DEVICE_PATH
||
542 DevicePathSubType (*FilePath
) != MEDIA_FILEPATH_DP
545 return (EFI_INVALID_PARAMETER
);
548 // Open this file path node
554 // Try to test opening an existing file
556 Status
= Handle2
->Open (
559 ((FILEPATH_DEVICE_PATH
*)*FilePath
)->PathName
,
560 OpenMode
&~EFI_FILE_MODE_CREATE
,
565 // see if the error was that it needs to be created
567 if ((EFI_ERROR (Status
)) && (OpenMode
!= (OpenMode
&~EFI_FILE_MODE_CREATE
))) {
568 Status
= Handle2
->Open (
571 ((FILEPATH_DEVICE_PATH
*)*FilePath
)->PathName
,
577 // Close the last node
579 Handle2
->Close (Handle2
);
581 if (EFI_ERROR(Status
)) {
588 *FilePath
= NextDevicePathNode (*FilePath
);
592 // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
594 *FileHandle
= (VOID
*)Handle1
;
599 Function opens and returns a file handle to the root directory of a volume.
601 @param[in] DeviceHandle A handle for a device
603 @return A valid file handle or NULL if error happens.
608 IN EFI_HANDLE DeviceHandle
612 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
613 EFI_FILE_HANDLE File
;
618 // File the file system interface to the device
620 Status
= gBS
->HandleProtocol (
622 &gEfiSimpleFileSystemProtocolGuid
,
627 // Open the root directory of the volume
629 if (!EFI_ERROR (Status
)) {
630 Status
= Volume
->OpenVolume (
638 return EFI_ERROR (Status
) ? NULL
: File
;
642 This function builds the FsOptionMenu list which records all
643 available file system in the system. They include all instances
644 of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM
645 and all type of legacy boot device.
647 @retval EFI_SUCCESS Success find the file system
648 @retval EFI_OUT_OF_RESOURCES Can not create menu entry
656 UINTN NoBlkIoHandles
;
657 UINTN NoSimpleFsHandles
;
658 EFI_HANDLE
*BlkIoHandle
;
659 EFI_HANDLE
*SimpleFsHandle
;
661 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
664 SECUREBOOT_MENU_ENTRY
*MenuEntry
;
665 SECUREBOOT_FILE_CONTEXT
*FileContext
;
670 BOOLEAN RemovableMedia
;
673 NoSimpleFsHandles
= 0;
675 InitializeListHead (&FsOptionMenu
.Head
);
678 // Locate Handles that support BlockIo protocol
680 Status
= gBS
->LocateHandleBuffer (
682 &gEfiBlockIoProtocolGuid
,
687 if (!EFI_ERROR (Status
)) {
689 for (Index
= 0; Index
< NoBlkIoHandles
; Index
++) {
690 Status
= gBS
->HandleProtocol (
692 &gEfiBlockIoProtocolGuid
,
696 if (EFI_ERROR (Status
)) {
701 // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media
703 if (BlkIo
->Media
->RemovableMedia
) {
704 Buffer
= AllocateZeroPool (BlkIo
->Media
->BlockSize
);
705 if (NULL
== Buffer
) {
706 FreePool (BlkIoHandle
);
707 return EFI_OUT_OF_RESOURCES
;
712 BlkIo
->Media
->MediaId
,
714 BlkIo
->Media
->BlockSize
,
720 FreePool (BlkIoHandle
);
724 // Locate Handles that support Simple File System protocol
726 Status
= gBS
->LocateHandleBuffer (
728 &gEfiSimpleFileSystemProtocolGuid
,
733 if (!EFI_ERROR (Status
)) {
735 // Find all the instances of the File System prototocol
737 for (Index
= 0; Index
< NoSimpleFsHandles
; Index
++) {
738 Status
= gBS
->HandleProtocol (
739 SimpleFsHandle
[Index
],
740 &gEfiBlockIoProtocolGuid
,
743 if (EFI_ERROR (Status
)) {
745 // If no block IO exists assume it's NOT a removable media
747 RemovableMedia
= FALSE
;
750 // If block IO exists check to see if it's remobable media
752 RemovableMedia
= BlkIo
->Media
->RemovableMedia
;
756 // Allocate pool for this instance.
758 MenuEntry
= CreateMenuEntry ();
759 if (NULL
== MenuEntry
) {
760 FreePool (SimpleFsHandle
);
761 return EFI_OUT_OF_RESOURCES
;
764 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
766 FileContext
->Handle
= SimpleFsHandle
[Index
];
767 MenuEntry
->OptionNumber
= Index
;
768 FileContext
->FHandle
= OpenRoot (FileContext
->Handle
);
769 if (FileContext
->FHandle
== NULL
) {
770 DestroyMenuEntry (MenuEntry
);
774 MenuEntry
->HelpString
= DevicePathToStr (DevicePathFromHandle (FileContext
->Handle
));
775 FileContext
->Info
= FileSystemVolumeLabelInfo (FileContext
->FHandle
);
776 FileContext
->FileName
= StrDuplicate (L
"\\");
777 FileContext
->DevicePath
= FileDevicePath (
779 FileContext
->FileName
781 FileContext
->IsDir
= TRUE
;
782 FileContext
->IsRoot
= TRUE
;
783 FileContext
->IsRemovableMedia
= RemovableMedia
;
784 FileContext
->IsLoadFile
= FALSE
;
787 // Get current file system's Volume Label
789 if (FileContext
->Info
== NULL
) {
790 VolumeLabel
= L
"NO FILE SYSTEM INFO";
792 if (FileContext
->Info
->VolumeLabel
== NULL
) {
793 VolumeLabel
= L
"NULL VOLUME LABEL";
795 VolumeLabel
= FileContext
->Info
->VolumeLabel
;
796 if (*VolumeLabel
== 0x0000) {
797 VolumeLabel
= L
"NO VOLUME LABEL";
802 TempStr
= MenuEntry
->HelpString
;
803 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
804 ASSERT (MenuEntry
->DisplayString
!= NULL
);
806 MenuEntry
->DisplayString
,
813 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
817 if (NoSimpleFsHandles
!= 0) {
818 FreePool (SimpleFsHandle
);
822 // Remember how many file system options are here
824 FsOptionMenu
.MenuNumber
= OptionNumber
;
830 Find files under the current directory. All files and sub-directories
831 in current directory will be stored in DirectoryMenu for future use.
833 @param[in] MenuEntry The Menu Entry.
835 @retval EFI_SUCCESS Get files from current dir successfully.
836 @return Other Can't get files from current dir.
841 IN SECUREBOOT_MENU_ENTRY
*MenuEntry
844 EFI_FILE_HANDLE NewDir
;
846 EFI_FILE_INFO
*DirInfo
;
849 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
850 SECUREBOOT_FILE_CONTEXT
*FileContext
;
851 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
856 FileContext
= (SECUREBOOT_FILE_CONTEXT
*) MenuEntry
->FileContext
;
857 Dir
= FileContext
->FHandle
;
860 // Open current directory to get files from it
865 FileContext
->FileName
,
869 if (!FileContext
->IsRoot
) {
873 if (EFI_ERROR (Status
)) {
877 DirInfo
= FileInfo (NewDir
);
878 if (DirInfo
== NULL
) {
879 return EFI_NOT_FOUND
;
882 if ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0) {
883 return EFI_INVALID_PARAMETER
;
886 FileContext
->DevicePath
= FileDevicePath (
888 FileContext
->FileName
891 DirBufferSize
= sizeof (EFI_FILE_INFO
) + 1024;
892 DirInfo
= AllocateZeroPool (DirBufferSize
);
893 if (DirInfo
== NULL
) {
894 return EFI_OUT_OF_RESOURCES
;
898 // Get all files in current directory
899 // Pass 1 to get Directories
900 // Pass 2 to get files that are EFI images
902 for (Pass
= 1; Pass
<= 2; Pass
++) {
903 NewDir
->SetPosition (NewDir
, 0);
905 BufferSize
= DirBufferSize
;
906 Status
= NewDir
->Read (NewDir
, &BufferSize
, DirInfo
);
907 if (EFI_ERROR (Status
) || BufferSize
== 0) {
911 if (((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) != 0 && Pass
== 2) ||
912 ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0 && Pass
== 1)
915 // Pass 1 is for Directories
916 // Pass 2 is for file names
921 NewMenuEntry
= CreateMenuEntry ();
922 if (NULL
== NewMenuEntry
) {
923 return EFI_OUT_OF_RESOURCES
;
926 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
927 NewFileContext
->Handle
= FileContext
->Handle
;
928 NewFileContext
->FileName
= AppendFileName (
929 FileContext
->FileName
,
932 NewFileContext
->FHandle
= NewDir
;
933 NewFileContext
->DevicePath
= FileDevicePath (
934 NewFileContext
->Handle
,
935 NewFileContext
->FileName
937 NewMenuEntry
->HelpString
= NULL
;
939 NewFileContext
->IsDir
= (BOOLEAN
) ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
);
940 if (NewFileContext
->IsDir
) {
941 BufferSize
= StrLen (DirInfo
->FileName
) * 2 + 6;
942 NewMenuEntry
->DisplayString
= AllocateZeroPool (BufferSize
);
945 NewMenuEntry
->DisplayString
,
952 NewMenuEntry
->DisplayString
= StrDuplicate (DirInfo
->FileName
);
955 NewFileContext
->IsRoot
= FALSE
;
956 NewFileContext
->IsLoadFile
= FALSE
;
957 NewFileContext
->IsRemovableMedia
= FALSE
;
959 NewMenuEntry
->OptionNumber
= OptionNumber
;
961 InsertTailList (&DirectoryMenu
.Head
, &NewMenuEntry
->Link
);
965 DirectoryMenu
.MenuNumber
= OptionNumber
;
971 Refresh the global UpdateData structure.
980 // Free current updated date
982 if (mStartOpCodeHandle
!= NULL
) {
983 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
987 // Create new OpCode Handle
989 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
992 // Create Hii Extend Label OpCode as the start opcode
994 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
998 sizeof (EFI_IFR_GUID_LABEL
)
1000 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1004 Update the File Explore page.
1006 @param[in] HiiHandle Hii Handle of the package to be updated.
1007 @param[in] MenuOption The Menu whose string tokens need to be updated.
1008 @param[in] FeCurrentState Current file explorer state.
1012 UpdateFileExplorePage (
1013 IN EFI_HII_HANDLE HiiHandle
,
1014 IN SECUREBOOT_MENU_OPTION
*MenuOption
,
1015 IN FILE_EXPLORER_STATE FeCurrentState
1019 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
1020 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
1022 EFI_FORM_ID FileFormId
;
1024 if (FeCurrentState
== FileExplorerStateEnrollPkFile
) {
1025 FormId
= SECUREBOOT_ADD_PK_FILE_FORM_ID
;
1026 FileFormId
= FORM_FILE_EXPLORER_ID_PK
;
1027 } else if (FeCurrentState
== FileExplorerStateEnrollKekFile
) {
1028 FormId
= FORMID_ENROLL_KEK_FORM
;
1029 FileFormId
= FORM_FILE_EXPLORER_ID_KEK
;
1030 } else if (FeCurrentState
== FileExplorerStateEnrollSignatureFileToDb
) {
1031 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
1032 FileFormId
= FORM_FILE_EXPLORER_ID_DB
;
1033 } else if (FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbx
) {
1034 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
1035 FileFormId
= FORM_FILE_EXPLORER_ID_DBX
;
1036 } else if (FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbt
) {
1037 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBT
;
1038 FileFormId
= FORM_FILE_EXPLORER_ID_DBT
;
1043 NewMenuEntry
= NULL
;
1044 NewFileContext
= NULL
;
1046 RefreshUpdateData ();
1047 mStartLabel
->Number
= FORM_FILE_EXPLORER_ID
;
1049 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
1050 NewMenuEntry
= GetMenuEntry (MenuOption
, Index
);
1051 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
1053 if (NewFileContext
->IsDir
) {
1055 // Create Text opcode for directory.
1057 HiiCreateActionOpCode (
1059 (UINT16
) (FILE_OPTION_OFFSET
+ Index
),
1060 NewMenuEntry
->DisplayStringToken
,
1061 STRING_TOKEN (STR_NULL
),
1062 EFI_IFR_FLAG_CALLBACK
,
1068 // Create Goto opcode for file.
1070 HiiCreateGotoOpCode (
1073 NewMenuEntry
->DisplayStringToken
,
1074 STRING_TOKEN (STR_NULL
),
1075 EFI_IFR_FLAG_CALLBACK
,
1076 (UINT16
) (FILE_OPTION_GOTO_OFFSET
+ Index
)
1083 &gSecureBootConfigFormSetGuid
,
1085 mStartOpCodeHandle
, // Label FORM_FILE_EXPLORER_ID
1086 mEndOpCodeHandle
// LABEL_END
1091 Update the file explorer page with the refreshed file system.
1093 @param[in] PrivateData Module private data.
1094 @param[in] KeyValue Key value to identify the type of data to expect.
1096 @retval TRUE Inform the caller to create a callback packet to exit file explorer.
1097 @retval FALSE Indicate that there is no need to exit file explorer.
1101 UpdateFileExplorer (
1102 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
1106 UINT16 FileOptionMask
;
1107 SECUREBOOT_MENU_ENTRY
*NewMenuEntry
;
1108 SECUREBOOT_FILE_CONTEXT
*NewFileContext
;
1110 BOOLEAN ExitFileExplorer
;
1112 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1114 NewMenuEntry
= NULL
;
1115 NewFileContext
= NULL
;
1116 ExitFileExplorer
= FALSE
;
1117 FileOptionMask
= (UINT16
) (FILE_OPTION_MASK
& KeyValue
);
1119 if (PrivateData
->FeDisplayContext
== FileExplorerDisplayUnknown
) {
1121 // First in, display file system.
1123 FreeMenu (&FsOptionMenu
);
1126 CreateMenuStringToken (PrivateData
->HiiHandle
, &FsOptionMenu
);
1127 UpdateFileExplorePage (PrivateData
->HiiHandle
, &FsOptionMenu
, PrivateData
->FeCurrentState
);
1129 PrivateData
->FeDisplayContext
= FileExplorerDisplayFileSystem
;
1131 if (PrivateData
->FeDisplayContext
== FileExplorerDisplayFileSystem
) {
1132 NewMenuEntry
= GetMenuEntry (&FsOptionMenu
, FileOptionMask
);
1133 } else if (PrivateData
->FeDisplayContext
== FileExplorerDisplayDirectory
) {
1134 NewMenuEntry
= GetMenuEntry (&DirectoryMenu
, FileOptionMask
);
1137 NewFileContext
= (SECUREBOOT_FILE_CONTEXT
*) NewMenuEntry
->FileContext
;
1139 if (NewFileContext
->IsDir
) {
1140 PrivateData
->FeDisplayContext
= FileExplorerDisplayDirectory
;
1142 RemoveEntryList (&NewMenuEntry
->Link
);
1143 FreeMenu (&DirectoryMenu
);
1144 Status
= FindFiles (NewMenuEntry
);
1145 if (EFI_ERROR (Status
)) {
1146 ExitFileExplorer
= TRUE
;
1149 CreateMenuStringToken (PrivateData
->HiiHandle
, &DirectoryMenu
);
1150 DestroyMenuEntry (NewMenuEntry
);
1152 UpdateFileExplorePage (PrivateData
->HiiHandle
, &DirectoryMenu
, PrivateData
->FeCurrentState
);
1155 if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollPkFile
) {
1156 FormId
= SECUREBOOT_ADD_PK_FILE_FORM_ID
;
1157 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollKekFile
) {
1158 FormId
= FORMID_ENROLL_KEK_FORM
;
1159 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollSignatureFileToDb
) {
1160 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
1161 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbx
) {
1162 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
1163 } else if (PrivateData
->FeCurrentState
== FileExplorerStateEnrollSignatureFileToDbt
) {
1164 FormId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBT
;
1169 PrivateData
->MenuEntry
= NewMenuEntry
;
1170 PrivateData
->FileContext
->FileName
= NewFileContext
->FileName
;
1172 TmpDevicePath
= NewFileContext
->DevicePath
;
1173 OpenFileByDevicePath (
1175 &PrivateData
->FileContext
->FHandle
,
1181 // Create Subtitle op-code for the display string of the option.
1183 RefreshUpdateData ();
1184 mStartLabel
->Number
= FormId
;
1186 HiiCreateSubTitleOpCode (
1188 NewMenuEntry
->DisplayStringToken
,
1195 PrivateData
->HiiHandle
,
1196 &gSecureBootConfigFormSetGuid
,
1198 mStartOpCodeHandle
, // Label FormId
1199 mEndOpCodeHandle
// LABEL_END
1205 return ExitFileExplorer
;
1209 Clean up the dynamic opcode at label and form specified by both LabelId.
1211 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
1212 @param[in] PrivateData Module private data.
1218 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
1221 RefreshUpdateData ();
1224 // Remove all op-codes from dynamic page
1226 mStartLabel
->Number
= LabelId
;
1228 PrivateData
->HiiHandle
,
1229 &gSecureBootConfigFormSetGuid
,
1231 mStartOpCodeHandle
, // Label LabelId
1232 mEndOpCodeHandle
// LABEL_END