2 HII Library implementation that uses DXE protocols and services.
4 Copyright (c) 2006 - 2008, Intel Corporation<BR>
5 All rights reserved. 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.
17 #include <Protocol/DevicePath.h>
18 #include <Protocol/HiiDatabase.h>
19 #include <Protocol/HiiString.h>
20 #include <Protocol/FormBrowser2.h>
22 #include <Library/BaseLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/BaseMemoryLib.h>
25 #include <Library/MemoryAllocationLib.h>
26 #include <Library/UefiBootServicesTableLib.h>
27 #include <Library/UefiHiiServicesLib.h>
28 #include <Library/DevicePathLib.h>
29 #include <Library/PrintLib.h>
30 #include <Library/NewHiiLib.h>
31 #include <Library/UefiLib.h>
33 ////////////////////////////////////////////////////////
34 ////////////////////////////////////////////////////////
36 ////////////////////////////////////////////////////////
37 ////////////////////////////////////////////////////////
40 // Template used to mark the end of a list of packages
42 GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_HII_PACKAGE_HEADER mEndOfPakageList
= {
43 sizeof (EFI_HII_PACKAGE_HEADER
),
48 // <ConfigHdr> Template
50 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR16 mConfigHdrTemplate
[] = L
"GUID=00000000000000000000000000000000&NAME=0000&PATH=00";
53 // Form Browser2 Protocol
55 EFI_FORM_BROWSER2_PROTOCOL
*mFormBrowser2
= NULL
;
58 Registers a list of packages in the HII Database and returns the HII Handle
59 associated with that registration. If an HII Handle has already been registered
60 with the same PackageListGuid, then NULL is returned. If there are not enough
61 resources to perform the registration, then NULL is returned. If an empty list
62 of packages is passed in, then NULL is returned. If the size of the list of
63 package is 0, then NULL is returned.
65 @param[in] PackageListGuid An optional parameter that is used to identify
66 the GUID of the package list. If this parameter
67 is NULL, then gEfiCallerIdGuid is used.
68 @param[in] DeviceHandle Optional. If not NULL, the Device Handle on which
69 an instance of DEVICE_PATH_PROTOCOL is installed.
70 This Device Handle uniquely defines the device that
71 the added packages are associated with.
72 @param[in] ... The variable argument list that contains pointers
73 to packages terminated by a NULL.
75 @retval NULL A HII Handle has already been registered in the HII Database with
76 the same PackageListGuid.
77 @retval NULL The HII Handle could not be created.
78 @retval Other The HII Handle associated with the newly registered package list.
84 IN CONST EFI_GUID
*PackageListGuid
, OPTIONAL
85 IN EFI_HANDLE DeviceHandle
, OPTIONAL
90 EFI_HII_HANDLE
*HiiHandleBuffer
;
93 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
94 EFI_HII_HANDLE HiiHandle
;
99 // If PackageListGuid is NULL, then use gEfiCallerIdGuid as the PackageListGuid
101 if (PackageListGuid
== NULL
) {
102 PackageListGuid
= &gEfiCallerIdGuid
;
106 // Check to see if an HII Handle has already been registered with the same
109 HiiHandleBuffer
= HiiGetHiiHandles (PackageListGuid
);
110 if (HiiHandleBuffer
!= NULL
) {
111 FreePool (HiiHandleBuffer
);
116 // Calculate the length of all the packages in the variable argument list
118 for (Length
= 0, VA_START (Args
, DeviceHandle
); (Package
= VA_ARG (Args
, UINT32
*)) != NULL
; ) {
119 Length
+= (ReadUnaligned32 ((UINT32
*)Package
) - sizeof (UINT32
));
124 // If there are no packages in the variable argument list or all the packages
125 // are empty, then return a NULL HII Handle
132 // Add the length of the Package List Header and the terminating Package Header
134 Length
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
) + sizeof (EFI_HII_PACKAGE_HEADER
);
137 // Allocate the storage for the entire Package List
139 PackageListHeader
= AllocateZeroPool (Length
);
142 // If the Packahge List can not be allocated, then return a NULL HII Handle
144 if (PackageListHeader
== NULL
) {
149 // Fill in the GUID and Length of the Package List Header
151 CopyGuid (&PackageListHeader
->PackageListGuid
, PackageListGuid
);
152 PackageListHeader
->PackageLength
= Length
;
155 // Initialize a pointer to the beginning if the Package List data
157 Data
= (UINT8
*)(PackageListHeader
+ 1);
160 // Copy the data from each package in the variable argument list
162 for (VA_START (Args
, DeviceHandle
); (Package
= VA_ARG (Args
, UINT32
*)) != NULL
; ) {
163 Length
= ReadUnaligned32 ((UINT32
*)Package
) - sizeof (UINT32
);
164 CopyMem (Data
, Package
+ 1, Length
);
170 // Append a package of type EFI_HII_PACKAGE_END to mark the end of the package list
172 CopyMem (Data
, &mEndOfPakageList
, sizeof (mEndOfPakageList
));
175 // Register the package list with the HII Database
177 Status
= gHiiDatabase
->NewPackageList (
183 if (EFI_ERROR (Status
)) {
188 // Free the allocated package list
190 FreePool (PackageListHeader
);
193 // Return the new HII Handle
199 Removes a package list from the HII Database.
201 If HiiHandle is NULL, then ASSERT().
202 If HiiHandle is not a valid EFI_HII_HANDLE in the HII Database, then ASSERT().
204 @param[in] HiiHandle A handle that was previously registered in the HII Database.
210 IN EFI_HII_HANDLE HiiHandle
216 // ASSERT if HiiHandle is NULL
218 ASSERT (HiiHandle
!= NULL
);
221 // Remove the package list specific by HiiHandle from the HII Database
223 Status
= gHiiDatabase
->RemovePackageList (gHiiDatabase
, HiiHandle
);
226 // ASSERT if the remove request fails. Should only occur if the HiiHandle is not valid.
228 ASSERT_EFI_ERROR (Status
);
232 Retrieves the array of all the HII Handles in the HII Database.
233 This array is terminated with a NULL HII Handle.
234 This function allocates the returned array using AllocatePool().
235 The caller is responsible for freeing the array with FreePool().
237 @param[in] PackageListGuid An optional parameter that is used to request
238 an HII Handle that is associatd with a specific
239 Package List GUID. If this parameter is NULL
240 then all the HII Handles in the HII Database
241 are returned. If this parameter is not NULL
242 then at most 1 HII Handle is returned.
244 @retval NULL There are no HII handles in the HII database
245 @retval NULL The array of HII Handles could not be retrieved
246 @retval Other A pointer to the NULL terminated array of HII Handles
252 IN CONST EFI_GUID
*PackageListGuid OPTIONAL
257 UINTN HandleBufferLength
;
258 EFI_HII_HANDLE TempHiiHandleBuffer
;
259 EFI_HII_HANDLE
*HiiHandleBuffer
;
262 // Determine the PackageType for the ListPackageLists() request
264 if (PackageListGuid
== NULL
) {
265 PackageType
= EFI_HII_PACKAGE_TYPE_ALL
;
267 PackageType
= EFI_HII_PACKAGE_TYPE_GUID
;
271 // Retrieve the size required for the buffer of all HII handles.
273 HandleBufferLength
= 0;
274 Status
= gHiiDatabase
->ListPackageLists (
283 // If ListPackageLists() returns EFI_SUCCESS for a zero size,
284 // then there are no HII handles in the HII database. If ListPackageLists()
285 // returns an error other than EFI_BUFFER_TOO_SMALL, then there are no HII
286 // handles in the HII database.
288 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
290 // Return NULL if the size can not be retrieved, or if there are no HII
291 // handles in the HII Database
297 // Allocate the array of HII handles to hold all the HII Handles and a NULL terminator
299 HiiHandleBuffer
= AllocateZeroPool (HandleBufferLength
+ sizeof (EFI_HII_HANDLE
));
300 if (HiiHandleBuffer
== NULL
) {
302 // Return NULL if allocation fails.
308 // Retrieve the array of HII Handles in the HII Database
310 Status
= gHiiDatabase
->ListPackageLists (
317 if (EFI_ERROR (Status
)) {
319 // Free the buffer and return NULL if the HII handles can not be retrieved.
321 FreePool (HiiHandleBuffer
);
326 // Return the NULL terminated array of HII handles in the HII Database
328 return HiiHandleBuffer
;
332 Retrieves a pointer to the a Null-terminated ASCII string containing the list
333 of languages that an HII handle in the HII Database supports. The returned
334 string is allocated using AllocatePool(). The caller is responsible for freeing
335 the returned string using FreePool(). The format of the returned string follows
336 the language format assumed the HII Database.
338 If HiiHandle is NULL, then ASSERT().
340 @param[in] HiiHandle A handle that was previously registered in the HII Database.
342 @retval NULL HiiHandle is not registered in the HII database
343 @retval NULL There are not enough resources available to retrieve the suported
345 @retval NULL The list of suported languages could not be retrieved.
346 @retval Other A pointer to the Null-terminated ASCII string of supported languages.
351 HiiGetSupportedLanguages (
352 IN EFI_HII_HANDLE HiiHandle
357 CHAR8 TempSupportedLanguages
;
358 CHAR8
*SupportedLanguages
;
361 // ASSERT if HiiHandle is NULL
363 ASSERT (HiiHandle
!= NULL
);
366 // Retrieve the size required for the supported languages buffer.
369 Status
= gHiiString
->GetLanguages (gHiiString
, HiiHandle
, &TempSupportedLanguages
, &LanguageSize
);
372 // If GetLanguages() returns EFI_SUCCESS for a zero size,
373 // then there are no supported languages registered for HiiHandle. If GetLanguages()
374 // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
375 // in the HII Database
377 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
379 // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database
385 // Allocate the supported languages buffer.
387 SupportedLanguages
= AllocateZeroPool (LanguageSize
);
388 if (SupportedLanguages
== NULL
) {
390 // Return NULL if allocation fails.
396 // Retrieve the supported languages string
398 Status
= gHiiString
->GetLanguages (gHiiString
, HiiHandle
, SupportedLanguages
, &LanguageSize
);
399 if (EFI_ERROR (Status
)) {
401 // Free the buffer and return NULL if the supported languages can not be retrieved.
403 FreePool (SupportedLanguages
);
408 // Return the Null-terminated ASCII string of supported languages
410 return SupportedLanguages
;
414 Retrieves a string from a string package in a specific language. If the language
415 is not specified, then a string from a string package in the current platform
416 language is retrieved. If the string can not be retrieved using the specified
417 language or the current platform language, then the string is retrieved from
418 the string package in the first language the string package supports. The
419 returned string is allocated using AllocatePool(). The caller is responsible
420 for freeing the allocated buffer using FreePool().
422 If HiiHandle is NULL, then ASSERT().
423 If StringId is 0, then ASSET.
425 @param[in] HiiHandle A handle that was previously registered in the HII Database.
426 @param[in] StringId The identifier of the string to retrieved from the string
427 package associated with HiiHandle.
428 @param[in] Language The language of the string to retrieve. If this parameter
429 is NULL, then the current platform language is used. The
430 format of Language must follow the language format assumed
433 @retval NULL The string specified by StringId is not present in the string package.
434 @retval Other The string was returned.
440 IN EFI_HII_HANDLE HiiHandle
,
441 IN EFI_STRING_ID StringId
,
442 IN CONST CHAR8
*Language OPTIONAL
449 CHAR8
*SupportedLanguages
;
450 CHAR8
*PlatformLanguage
;
454 // If HiiHandle is NULL, then ASSERT()
456 ASSERT (HiiHandle
!=NULL
);
459 // If StringId is 0, then ASSERT()
461 ASSERT (StringId
!= 0);
464 // Initialize all allocated buffers to NULL
466 SupportedLanguages
= NULL
;
467 PlatformLanguage
= NULL
;
472 // Get the languages that the package specified by HiiHandle supports
474 SupportedLanguages
= HiiGetSupportedLanguages (HiiHandle
);
475 if (SupportedLanguages
== NULL
) {
480 // Get the current platform language setting
482 PlatformLanguage
= GetEfiGlobalVariable (L
"PlatformLang");
483 if (PlatformLanguage
== NULL
) {
488 // If Languag is NULL, then set it to an empty string, so it will be
489 // skipped by GetBestLanguage()
491 if (Language
== NULL
) {
496 // Get the best matching language from SupportedLanguages
498 BestLanguage
= GetBestLanguage (
500 FALSE
, // RFC 4646 mode
501 Language
, // Highest priority
502 PlatformLanguage
, // Next highest priority
503 SupportedLanguages
, // Lowest priority
506 if (BestLanguage
== NULL
) {
511 // Retrieve the size of the string in the string package for the BestLanguage
514 Status
= gHiiString
->GetString (
524 // If GetString() returns EFI_SUCCESS for a zero size,
525 // then there are no supported languages registered for HiiHandle. If GetString()
526 // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
527 // in the HII Database
529 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
534 // Allocate a buffer for the return string
536 String
= AllocateZeroPool (StringSize
);
537 if (String
== NULL
) {
542 // Retrieve the string from the string package
544 Status
= gHiiString
->GetString (
553 if (EFI_ERROR (Status
)) {
555 // Free the buffer and return NULL if the supported languages can not be retrieved.
563 // Free allocated buffers
565 if (SupportedLanguages
!= NULL
) {
566 FreePool (SupportedLanguages
);
568 if (PlatformLanguage
!= NULL
) {
569 FreePool (PlatformLanguage
);
571 if (BestLanguage
!= NULL
) {
572 FreePool (BestLanguage
);
576 // Return the Null-terminated Unicode string
582 Retrieves a string from a string package names by GUID in a specific language.
583 If the language is not specified, then a string from a string package in the
584 current platform language is retrieved. If the string can not be retrieved
585 using the specified language or the current platform language, then the string
586 is retrieved from the string package in the first language the string package
587 supports. The returned string is allocated using AllocatePool(). The caller
588 is responsible for freeing the allocated buffer using FreePool().
590 If PackageListGuid is NULL, then ASSERT().
591 If StringId is 0, then ASSET.
593 @param[in] PackageListGuid The GUID of a package list that was previously
594 registered in the HII Database.
595 @param[in] StringId The identifier of the string to retrieved from the
596 string package associated with PackageListGuid.
597 @param[in] Language The language of the string to retrieve. If this
598 parameter is NULL, then the current platform
599 language is used. The format of Language must
600 follow the language format assumed the HII Database.
602 @retval NULL The package list specified by PackageListGuid is not present in the
604 @retval NULL The string specified by StringId is not present in the string package.
605 @retval Other The string was returned.
610 HiiGetPackageString (
611 IN CONST EFI_GUID
*PackageListGuid
,
612 IN EFI_STRING_ID StringId
,
613 IN CONST CHAR8
*Language OPTIONAL
616 EFI_HANDLE
*HiiHandleBuffer
;
617 EFI_HANDLE HiiHandle
;
619 ASSERT (PackageListGuid
!= NULL
);
621 HiiHandleBuffer
= HiiGetHiiHandles (PackageListGuid
);
622 if (HiiHandleBuffer
== NULL
) {
625 HiiHandle
= HiiHandleBuffer
[0];
626 FreePool (HiiHandleBuffer
);
627 if (HiiHandle
== NULL
) {
630 return HiiGetString (HiiHandle
, StringId
, Language
);
634 This function create a new string in String Package or updates an existing
635 string in a String Package. If StringId is 0, then a new string is added to
636 a String Package. If StringId is not zero, then a string in String Package is
637 updated. If SupportedLanguages is NULL, then the string is added or updated
638 for all the languages that the String Package supports. If SupportedLanguages
639 is not NULL, then the string is added or updated for the set of languages
640 specified by SupportedLanguages.
642 If HiiHandle is NULL, then ASSERT().
643 If String is NULL, then ASSERT().
645 @param[in] HiiHandle A handle that was previously registered in the
647 @param[in] StringId If zero, then a new string is created in the
648 String Package associated with HiiHandle. If
649 non-zero, then the string specified by StringId
650 is updated in the String Package associated
652 @param[in] String A pointer to the Null-terminated Unicode string
653 to add or update in the String Package associated
655 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string of
656 language codes. If this parameter is NULL, then
657 String is added or updated in the String Package
658 associated with HiiHandle for all the languages
659 that the String Package supports. If this
660 parameter is not NULL, then then String is added
661 or updated in the String Package associated with
662 HiiHandle for the set oflanguages specified by
663 SupportedLanguages. The format of
664 SupportedLanguages must follow the language
665 format assumed the HII Database.
667 @retval 0 The string could not be added or updated in the String Package.
668 @retval Other The EFI_STRING_ID of the newly added or updated string.
674 IN EFI_HII_HANDLE HiiHandle
,
675 IN EFI_STRING_ID StringId
, OPTIONAL
676 IN CONST EFI_STRING String
,
677 IN CONST CHAR8
*SupportedLanguages OPTIONAL
681 CHAR8
*AllocatedLanguages
;
685 ASSERT (HiiHandle
!= NULL
);
686 ASSERT (String
!= NULL
);
688 if (SupportedLanguages
== NULL
) {
690 // Retrieve the languages that the package specified by HiiHandle supports
692 AllocatedLanguages
= HiiGetSupportedLanguages (HiiHandle
);
695 // Allocate a copy of the SupportLanguages string that passed in
697 AllocatedLanguages
= AllocateCopyPool (AsciiStrLen (SupportedLanguages
), SupportedLanguages
);
701 // If there are not enough resources for the supported languages string, then return a StringId of 0
703 if (AllocatedLanguages
== NULL
) {
704 return (EFI_STRING_ID
)(0);
708 // Loop through each language that the string supports
710 for (Supported
= AllocatedLanguages
; *Supported
!= '\0'; ) {
712 // Cache a pointer to the beginning of the current language in the list of languages
714 Language
= Supported
;
717 // Search for the next language seperator and replace it with a Null-terminator
719 for (; *Supported
!= 0 && *Supported
!= ';'; Supported
++);
720 *(Supported
++) = '\0';
723 // If StringId is 0, then call NewString(). Otherwise, call SetString()
725 if (StringId
== (EFI_STRING_ID
)(0)) {
726 Status
= gHiiString
->NewString (gHiiString
, HiiHandle
, &StringId
, Language
, NULL
, String
, NULL
);
728 Status
= gHiiString
->SetString (gHiiString
, HiiHandle
, StringId
, Language
, String
, NULL
);
732 // If there was an error, then break out of the loop and return a StringId of 0
734 if (EFI_ERROR (Status
)) {
735 StringId
= (EFI_STRING_ID
)(0);
741 // Free the buffer of supported languages
743 FreePool (AllocatedLanguages
);
746 // Return the StringId of the new or updated string
752 Validates the config data associated with an HII handle in the HII Database.
754 If HiiHandle is NULL, then ASSERT().
756 @param[in] HiiHandle A handle that was previously registered in the HII Database.
758 @retval TRUE The config data associated with HiiHandle passes all validation
760 @retval FALSE The config data associated with HiiHandle failed one or more
766 HiiValidateDataFromHiiHandle (
767 IN EFI_HII_HANDLE HiiHandle
770 ASSERT (HiiHandle
!= NULL
);
772 // Needs to be implemented.
778 Converts all hex dtring characters in range ['A'..'F'] to ['a'..'f'] for
779 hex digits that appear between a '=' and a '&' in a config string.
781 If String is NULL, then ASSERT().
783 @param[in] String Pointer to a Null-terminated Unicode string.
785 @return Pointer to the Null-terminated Unicode result string.
790 InternalHiiLowerConfigString (
791 IN EFI_STRING ConfigString
797 ASSERT (String
!= NULL
);
800 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
802 for (String
= ConfigString
, Lower
= FALSE
; *String
!= L
'\0'; String
++) {
803 if (*String
== L
'=') {
805 } else if (*String
== L
'&') {
807 } else if (Lower
&& *String
> L
'A' && *String
<= L
'F') {
808 *String
= *String
- L
'A' + L
'a';
816 Uses the BlockToConfig() service of the Config Routing Protocol to
817 convert <ConfigRequest> and a buffer to a <ConfigResp>
819 If ConfigRequest is NULL, then ASSERT().
820 If Block is NULL, then ASSERT().
822 @param[in] ConfigRequest Pointer to a Null-terminated Unicode string.
823 @param[in] Block Pointer to a block of data.
824 @param[in] BlockSize The zie, in bytes, of Block.
826 @retval NULL The <ConfigResp> string could not be generated.
827 @retval Other Pointer to the Null-terminated Unicode <ConfigResp> string.
832 InternalHiiBlockToConfig (
833 IN CONST EFI_STRING ConfigRequest
,
834 IN CONST UINT8
*Block
,
839 EFI_STRING ConfigResp
;
842 ASSERT (ConfigRequest
!= NULL
);
843 ASSERT (Block
!= NULL
);
846 // Convert <ConfigRequest> to <ConfigResp>
848 Status
= gHiiConfigRouting
->BlockToConfig (
856 if (EFI_ERROR (Status
)) {
863 Uses the ConfigToBlock() service of the Config Routing Protocol to
864 convert <ConfigResp> to a block. The block is allocated using
865 AllocatePool(). The caller is responsible for freeing the block
868 If ConfigResp is NULL, then ASSERT().
870 @param[in] ConfigResp Pointer to a Null-terminated Unicode string.
871 @param[in] BufferSize Length in bytes of buffer to hold retrived data.
873 @retval NULL The block could not be generated..
874 @retval Other Pointer to the allocated block.
879 InternalHiiConfigToBlock (
880 IN EFI_STRING ConfigResp
,
888 ASSERT (ConfigResp
!= NULL
);
891 // Allocate a buffer to hold the <ConfigResp> conversion
893 Block
= AllocateZeroPool (BlockSize
);
899 // Convert <ConfigResp> to a buffer
901 Status
= gHiiConfigRouting
->ConfigToBlock (
908 if (EFI_ERROR (Status
)) {
914 // Return converted buffer
920 Uses the BrowserCallback() service of the Form Browser Protocol to retrieve
921 or set uncommitted data. If sata i being retrieved, then the buffer is
922 allocated using AllocatePool(). The caller is then responsible for freeing
923 the buffer using FreePool().
925 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
926 is an optional parameter that may be NULL.
927 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
928 parameter that may be NULL.
929 @param[in] SetResultsData If not NULL, then this parameter specified the buffer
930 of uncommited data to set. If this parameter is NULL,
931 then the caller is requesting to get the uncommited data
932 from the Form Browser.
934 @retval NULL The uncommitted data could not be retrieved.
935 @retval Other A pointer to a buffer containing the uncommitted data.
940 InternalHiiBrowserCallback (
941 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
942 IN CONST CHAR16
*VariableName
, OPTIONAL
943 IN CONST EFI_STRING SetResultsData OPTIONAL
947 UINTN ResultsDataSize
;
948 EFI_STRING ResultsData
;
949 CHAR16 TempResultsData
;
954 if (mFormBrowser2
== NULL
) {
955 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &mFormBrowser2
);
956 if (EFI_ERROR (Status
) || mFormBrowser2
== NULL
) {
963 if (SetResultsData
!= NULL
) {
965 // Request to to set data in the uncommitted browser state information
967 ResultsData
= SetResultsData
;
970 // Retrieve the length of the buffer required ResultsData from the Browser Callback
972 Status
= mFormBrowser2
->BrowserCallback (
980 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
985 // Allocate the ResultsData buffer
987 ResultsData
= AllocateZeroPool (ResultsDataSize
);
988 if (ResultsData
== NULL
) {
994 // Retrieve or set the ResultsData from the Browser Callback
996 Status
= mFormBrowser2
->BrowserCallback (
1000 (BOOLEAN
)(SetResultsData
== NULL
),
1004 if (EFI_ERROR (Status
)) {
1012 Allocates and returns a Null-terminated Unicode <ConfigHdr> string using routing
1013 information that includes a GUID, an optional Unicode string name, and a device
1014 path. The string returned is allocated with AllocatePool(). The caller is
1015 responsible for freeing the allocated string with FreePool().
1017 The format of a <ConfigHdr> is as follows:
1019 GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize<Null>
1021 @param[in] Guid Pointer to an EFI_GUID that is the routing information
1022 GUID. Each of the 16 bytes in Guid is converted to
1023 a 2 Unicode character hexidecimal string. This is
1024 an optional parameter that may be NULL.
1025 @param[in] Name Pointer to a Null-terminated Unicode string that is
1026 the routing information NAME. This is an optional
1027 parameter that may be NULL. Each 16-bit Unicode
1028 character in Name is converted to a 4 character Unicode
1030 @param[in] DriverHandle The driver handle which supports a Device Path Protocol
1031 that is the routing information PATH. Each byte of
1032 the Device Path associated with DriverHandle is converted
1033 to a 2 Unicode character hexidecimal string.
1035 @retval NULL DriverHandle does not support the Device Path Protocol.
1036 @retval NULL DriverHandle does not support the Device Path Protocol.
1037 @retval Other A pointer to the Null-terminate Unicode <ConfigHdr> string
1042 HiiConstructConfigHdr (
1043 IN CONST EFI_GUID
*Guid
, OPTIONAL
1044 IN CONST CHAR16
*Name
, OPTIONAL
1045 IN EFI_HANDLE DriverHandle
1049 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1050 UINTN DevicePathSize
;
1052 CHAR16
*ReturnString
;
1057 // Compute the length of Name in Unicode characters.
1058 // If Name is NULL, then the length is 0.
1062 NameLength
= StrLen (Name
);
1066 // Retrieve DevicePath Protocol associated with DriverHandle
1068 DevicePath
= DevicePathFromHandle (DriverHandle
);
1069 if (DevicePath
== NULL
) {
1074 // Compute the size of the device path in bytes
1076 DevicePathSize
= GetDevicePathSize (DevicePath
);
1079 // GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize <Null>
1080 // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 |
1082 String
= AllocateZeroPool ((5 + sizeof (EFI_GUID
) * 2 + 6 + NameLength
* 4 + 6 + DevicePathSize
* 2 + 1) * sizeof (CHAR16
));
1083 if (String
== NULL
) {
1088 // Start with L"GUID="
1090 ReturnString
= StrCpy (String
, L
"GUID=");
1091 String
+= StrLen (String
);
1095 // Append Guid converted to <HexCh>32
1097 for (Index
= 0, Buffer
= (UINT8
*)Guid
; Index
< sizeof (EFI_GUID
); Index
++) {
1098 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(Buffer
++), 2);
1105 StrCpy (String
, L
"&NAME=");
1106 String
+= StrLen (String
);
1110 // Append Name converted to <Char>NameLength
1112 for (; *Name
!= L
'\0'; Name
++) {
1113 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *Name
, 4);
1120 StrCpy (String
, L
"&PATH=");
1121 String
+= StrLen (String
);
1124 // Append the device path associated with DriverHandle converted to <HexChar>DevicePathSize
1126 for (Index
= 0, Buffer
= (UINT8
*)DevicePath
; Index
< DevicePathSize
; Index
++) {
1127 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(Buffer
++), 2);
1131 // Null terminate the Unicode string
1136 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
1138 return InternalHiiLowerConfigString (ReturnString
);
1142 Allocates and returns a Null-terminated Unicode <ConfigAltResp> string.
1144 If Guid is NULL, then ASSERT().
1145 If Name is NULL, then ASSERT().
1146 If BlockNameArray is NULL, then ASSERT().
1148 @param[in] Guid GUID of the buffer storage.
1149 @param[in] Name Name of the buffer storage.
1150 @param[in] DriverHandle The DriverHandle that support a Device Path
1152 @param[in] BufferStorage Content of the buffer storage.
1153 @param[in] BufferStorageSize Length in bytes of the buffer storage.
1154 @param[in] BlockNameArray Array generated by VFR compiler. This array
1155 contains a UINT32 value that is the length
1156 of BlockNameArray in bytes, followed by pairs
1157 of 16-bit values that are the offset and length
1158 values used to contruct a <ConfigRequest> string.
1159 @param[in] ... A variable argument list that contains pairs of 16-bit
1160 ALTCFG identifiers and pointers to DefaultValueArrays.
1161 The variable argument list is terminated by a NULL
1162 DefaultValueArray pointer. A DefaultValueArray
1163 contains a UINT32 value that is the length, in bytes,
1164 of the DefaultValueArray. The UINT32 length value
1165 is followed by a series of records that contain
1166 a 16-bit WIDTH value followed by a byte array with
1167 WIDTH entries. The records must be parsed from
1168 beginning to end until the UINT32 length limit
1171 @retval NULL There are not enough resources to process the request.
1172 @retval NULL A <ConfigResp> could not be retrieved from the Config
1174 @retval Other A pointer to the Null-terminate Unicode <ConfigAltResp>
1180 HiiConstructConfigAltResp (
1181 IN CONST EFI_GUID
*Guid
,
1182 IN CONST CHAR16
*Name
,
1183 IN EFI_HANDLE DriverHandle
,
1184 IN CONST VOID
*BufferStorage
,
1185 IN UINTN BufferStorageSize
,
1186 IN CONST VOID
*BlockNameArray
,
1195 CHAR16
*ConfigRequest
;
1196 EFI_STRING ConfigResp
;
1197 EFI_STRING ConfigAltResp
;
1202 ASSERT (Guid
!= NULL
);
1203 ASSERT (Name
!= NULL
);
1204 ASSERT (BlockNameArray
!= NULL
);
1207 // Initialize local variables
1210 ConfigRequest
= NULL
;
1214 // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
1216 ConfigHdr
= HiiConstructConfigHdr (Guid
, Name
, DriverHandle
);
1217 if (ConfigHdr
== NULL
) {
1222 // Compute the length of the entire request starting with <ConfigHdr> and a
1225 Length
= StrLen (ConfigHdr
) + 1;
1228 // Determine the size <BlockName> Offset/Width pairs
1230 Buffer
= (UINT8
*)BlockNameArray
;
1231 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
1232 Buffer
+= sizeof (UINT32
);
1235 // Add <BlockName> length that is composed of one or more Offset/Width pairs
1237 // <BlockName> ::= &OFFSET=1234&WIDTH=1234
1238 // | 8 | 4 | 7 | 4 |
1240 Length
+= (((BufferEnd
- Buffer
) / (sizeof (UINT16
) + sizeof (UINT16
))) * (8 + 4 + 7 + 4));
1243 // Allocate buffer for the entire <ConfigRequest>
1245 ConfigRequest
= AllocateZeroPool (Length
* sizeof (CHAR16
));
1246 if (ConfigRequest
== NULL
) {
1249 String
= ConfigRequest
;
1252 // Start with <ConfigHdr>
1254 StrCpy (String
, ConfigHdr
);
1255 String
+= StrLen (String
);
1258 // Loop through all the Offset/Width pairs and append them to ConfigRequest
1260 while (Buffer
< BufferEnd
) {
1262 // Append &OFFSET=XXXX&WIDTH=YYYY
1266 (8 + 4 + 7 + 4) * sizeof (CHAR16
),
1267 L
"&OFFSET=%04X&WIDTH=%04X",
1268 ReadUnaligned16 ((UINT16
*)Buffer
),
1269 ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)))
1271 String
+= StrLen (String
);
1272 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
));
1276 // Get the <ConfigResp>
1278 ConfigResp
= InternalHiiBlockToConfig (ConfigRequest
, BufferStorage
, BufferStorageSize
);
1279 if (ConfigResp
== NULL
) {
1284 // Compute the length of the entire response starting with <ConfigResp> and a
1287 Length
= StrLen (ConfigResp
) + 1;
1290 // Add the length associated with each pair of variable argument parameters
1292 VA_START (Args
, BlockNameArray
);
1294 AltCfgId
= VA_ARG (Args
, UINT16
);
1295 Buffer
= VA_ARG (Args
, UINT8
*);
1296 if (Buffer
== NULL
) {
1301 // Add length for "&<ConfigHdr>&ALTCFG=XXXX"
1302 // |1| StrLen (ConfigHdr) | 8 | 4 |
1304 Length
+= (1 + StrLen (ConfigHdr
) + 8 + 4);
1306 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
1307 Buffer
+= sizeof (UINT32
);
1308 while (Buffer
< BufferEnd
) {
1310 // Extract Width field
1312 Width
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
1315 // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"
1316 // | 8 | 4 | 7 | 4 | 7 | Width * 2 |
1318 Length
+= (8 + 4 + 7 + 4 + 7 + Width
* 2);
1321 // Update Buffer to the next record
1323 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
) + Width
);
1329 // Allocate a buffer for the entire response
1331 ConfigAltResp
= AllocateZeroPool (Length
* sizeof (CHAR16
));
1332 if (ConfigAltResp
== NULL
) {
1335 String
= ConfigAltResp
;
1340 StrCpy (String
, ConfigResp
);
1341 String
+= StrLen (String
);
1344 // Add <AltResp> for each pair of variable argument parameters
1346 VA_START (Args
, BlockNameArray
);
1348 AltCfgId
= VA_ARG (Args
, UINT16
);
1349 Buffer
= VA_ARG (Args
, UINT8
*);
1350 if (Buffer
== NULL
) {
1355 // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX"
1356 // |1| StrLen (ConfigHdr) | 8 | 4 |
1360 (1 + StrLen (ConfigHdr
) + 8 + 4) * sizeof (CHAR16
),
1365 String
+= StrLen (String
);
1368 // Add <ConfigBody> ::= <ConfigElement>*
1370 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
1371 Buffer
+= sizeof (UINT32
);
1372 while (Buffer
< BufferEnd
) {
1374 // Extract Width field
1376 Width
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
1379 // Add <BlockConfig>
1383 (8 + 4 + 7 + 4 + 7 + Width
* 2) * sizeof (CHAR16
),
1384 L
"&OFFSET=%04X&WIDTH=%04X&VALUE=",
1385 ReadUnaligned16 ((UINT16
*)Buffer
),
1388 String
+= StrLen (String
);
1391 // Update Buffer to point to the value in the current record
1393 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
));
1396 // Convert Value to a hex string in "%x" format
1397 // NOTE: This is in the opposite byte that GUID and PATH use
1399 for (; Width
> 0; Width
--) {
1400 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, Buffer
[Width
- 1], 2);
1403 // Update Buffer to the next record
1411 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
1413 return InternalHiiLowerConfigString (ConfigAltResp
);
1416 if (ConfigHdr
!= NULL
) {
1417 FreePool (ConfigHdr
);
1419 if (ConfigRequest
!= NULL
) {
1420 FreePool (ConfigRequest
);
1422 if (ConfigResp
!= NULL
) {
1423 FreePool (ConfigResp
);
1430 Determines if two values in config strings match.
1432 Compares the substring between StartSearchString and StopSearchString in
1433 FirstString to the substring between StartSearchString and StopSearchString
1434 in SecondString. If the two substrings match, then TRUE is returned. If the
1435 two substrings do not match, then FALSE is returned.
1437 If FirstString is NULL, then ASSERT().
1438 If SecondString is NULL, then ASSERT().
1439 If StartSearchString is NULL, then ASSERT().
1440 If StopSearchString is NULL, then ASSERT().
1442 @param FirstString Pointer to the first Null-terminated Unicode string.
1443 @param SecondString Pointer to the second Null-terminated Unicode string.
1444 @param StartSearchString Pointer to the Null-terminated Unicode string that
1445 marks the start of the value string to compare.
1446 @param StopSearchString Pointer to the Null-terminated Unicode string that
1447 marks the end of the vakue string to compare.
1449 @retval FALSE StartSearchString is not present in FirstString.
1450 @retval FALSE StartSearchString is not present in SecondString.
1451 @retval FALSE StopSearchString is not present in FirstString.
1452 @retval FALSE StopSearchString is not present in SecondString.
1453 @retval FALSE The length of the substring in FirstString is not the
1454 same length as the substring in SecondString.
1455 @retval FALSE The value string in FirstString does not matche the
1456 value string in SecondString.
1457 @retval TRUE The value string in FirstString matches the value
1458 string in SecondString.
1463 InternalHiiCompareSubString (
1464 IN CHAR16
*FirstString
,
1465 IN CHAR16
*SecondString
,
1466 IN CHAR16
*StartSearchString
,
1467 IN CHAR16
*StopSearchString
1470 CHAR16
*EndFirstString
;
1471 CHAR16
*EndSecondString
;
1473 ASSERT (FirstString
!= NULL
);
1474 ASSERT (SecondString
!= NULL
);
1475 ASSERT (StartSearchString
!= NULL
);
1476 ASSERT (StopSearchString
!= NULL
);
1478 FirstString
= StrStr (FirstString
, StartSearchString
);
1479 if (FirstString
== NULL
) {
1483 SecondString
= StrStr (SecondString
, StartSearchString
);
1484 if (SecondString
== NULL
) {
1488 EndFirstString
= StrStr (FirstString
, StopSearchString
);
1489 if (EndFirstString
== NULL
) {
1493 EndSecondString
= StrStr (SecondString
, StopSearchString
);
1494 if (EndSecondString
== NULL
) {
1498 if ((EndFirstString
- FirstString
) != (EndSecondString
- SecondString
)) {
1502 return (BOOLEAN
)(StrnCmp (FirstString
, SecondString
, EndFirstString
- FirstString
) == 0);
1506 Determines if the routing data specified by GUID and NAME match a <ConfigHdr>.
1508 If ConfigHdr is NULL, then ASSERT().
1510 @param[in] ConfigHdr Either <ConfigRequest> or <ConfigResp>.
1511 @param[in] Guid GUID of the storage.
1512 @param[in] Name NAME of the storage.
1514 @retval TRUE Routing information matches <ConfigHdr>.
1515 @retval FALSE Routing information does not match <ConfigHdr>.
1520 HiiIsConfigHdrMatch (
1521 IN CONST EFI_STRING ConfigHdr
,
1522 IN CONST EFI_GUID
*Guid
, OPTIONAL
1523 IN CONST CHAR16
*Name OPTIONAL
1526 EFI_STRING CompareConfigHdr
;
1529 ASSERT (ConfigHdr
!= NULL
);
1532 // Use Guid and Name to generate a <ConfigHdr> string
1534 CompareConfigHdr
= HiiConstructConfigHdr (Guid
, Name
, NULL
);
1535 if (CompareConfigHdr
== NULL
) {
1542 // Compare GUID value strings
1544 Result
= InternalHiiCompareSubString (ConfigHdr
, CompareConfigHdr
, L
"GUID=", L
"&NAME=");
1547 if (Result
&& Name
!= NULL
) {
1549 // Compare NAME value strings
1551 Result
= InternalHiiCompareSubString (ConfigHdr
, CompareConfigHdr
, L
"&NAME=", L
"&PATH=");
1555 // Free the <ConfigHdr> string
1557 FreePool (CompareConfigHdr
);
1563 Retrieves uncommited data from the Form Browser and converts it to a binary
1564 buffer. The returned buffer is allocated using AllocatePool(). The caller
1565 is responsible for freeing the returned buffer using FreePool().
1567 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
1568 is an optional parameter that may be NULL.
1569 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
1570 parameter that may be NULL.
1571 @param[in] BufferSize Length in bytes of buffer to hold retrived data.
1573 @retval NULL The uncommitted data could not be retrieved.
1574 @retval Other A pointer to a buffer containing the uncommitted data.
1580 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
1581 IN CONST CHAR16
*VariableName
, OPTIONAL
1585 EFI_STRING ResultsData
;
1587 EFI_STRING ConfigResp
;
1591 // Retrieve the results data from the Browser Callback
1593 ResultsData
= InternalHiiBrowserCallback (VariableGuid
, VariableName
, NULL
);
1594 if (ResultsData
== NULL
) {
1599 // Construct <ConfigResp>
1601 Size
= (StrLen (mConfigHdrTemplate
) + 1 + StrLen (ResultsData
) + 1) * sizeof (CHAR16
);
1602 ConfigResp
= AllocateZeroPool (Size
);
1603 UnicodeSPrint (ConfigResp
, Size
, L
"%s&%s", mConfigHdrTemplate
, ResultsData
);
1606 // Free the allocated buffer
1608 FreePool (ResultsData
);
1609 if (ConfigResp
== NULL
) {
1614 // Convert <ConfigResp> to a buffer
1616 Block
= InternalHiiConfigToBlock (ConfigResp
, BlockSize
);
1617 FreePool (ConfigResp
);
1623 Updates uncommitted data in the Form Browser.
1625 If Buffer is NULL, then ASSERT().
1627 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
1628 is an optional parameter that may be NULL.
1629 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
1630 parameter that may be NULL.
1631 @param[in] BufferSize Length, in bytes, of Buffer.
1632 @param[in] Buffer Buffer of data to commit.
1633 @param[in] RequestElement An optional field to specify which part of the
1634 buffer data will be send back to Browser. If NULL,
1635 the whole buffer of data will be committed to
1637 <RequestElement> ::= &OFFSET=<Number>&WIDTH=<Number>*
1639 @retval FALSE The uncommitted data could not be updated.
1640 @retval TRUE The uncommitted data was updated.
1646 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
1647 IN CONST CHAR16
*VariableName
, OPTIONAL
1648 IN UINTN BufferSize
,
1649 IN CONST UINT8
*Buffer
,
1650 IN CONST CHAR16
*RequestElement OPTIONAL
1654 EFI_STRING ConfigRequest
;
1655 EFI_STRING ConfigResp
;
1656 EFI_STRING ResultsData
;
1658 ASSERT (Buffer
!= NULL
);
1661 // Construct <ConfigRequest>
1663 if (RequestElement
== NULL
) {
1665 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1666 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1668 Size
= (StrLen (mConfigHdrTemplate
) + 32 + 1) * sizeof (CHAR16
);
1669 ConfigRequest
= AllocateZeroPool (Size
);
1670 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", mConfigHdrTemplate
, (UINT64
)BufferSize
);
1673 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1674 // followed by <RequestElement> followed by a Null-terminator
1676 Size
= (StrLen (mConfigHdrTemplate
) + StrLen (RequestElement
) + 1) * sizeof (CHAR16
);
1677 ConfigRequest
= AllocateZeroPool (Size
);
1678 UnicodeSPrint (ConfigRequest
, Size
, L
"%s%s", mConfigHdrTemplate
, RequestElement
);
1680 if (ConfigRequest
== NULL
) {
1685 // Convert <ConfigRequest> to <ConfigResp>
1687 ConfigResp
= InternalHiiBlockToConfig (ConfigRequest
, Buffer
, BufferSize
);
1688 FreePool (ConfigRequest
);
1689 if (ConfigResp
== NULL
) {
1694 // Set data in the uncommitted browser state information
1696 ResultsData
= InternalHiiBrowserCallback (VariableGuid
, VariableName
, ConfigResp
+ StrLen(mConfigHdrTemplate
) + 1);
1697 FreePool (ConfigResp
);
1699 return (BOOLEAN
)(ResultsData
!= NULL
);
1702 /////////////////////////////////////////
1703 /////////////////////////////////////////
1705 /////////////////////////////////////////
1706 /////////////////////////////////////////
1708 #define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200
1714 } HII_LIB_OPCODE_BUFFER
;
1717 /// Lookup table that converts EFI_IFR_TYPE_X enum values to a width in bytes
1719 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth
[] = {
1720 1, // EFI_IFR_TYPE_NUM_SIZE_8
1721 2, // EFI_IFR_TYPE_NUM_SIZE_16
1722 4, // EFI_IFR_TYPE_NUM_SIZE_32
1723 8, // EFI_IFR_TYPE_NUM_SIZE_64
1724 1, // EFI_IFR_TYPE_BOOLEAN
1725 3, // EFI_IFR_TYPE_TIME
1726 4, // EFI_IFR_TYPE_DATE
1727 2 // EFI_IFR_TYPE_STRING
1731 Allocates and returns a new OpCode Handle. OpCode Handles must be freed with
1732 HiiFreeOpCodeHandle().
1734 @retval NULL There are not enough resources to allocate a new OpCode Handle.
1735 @retval Other A new OpCode handle.
1740 HiiAllocateOpCodeHandle (
1744 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1746 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)AllocatePool (sizeof (HII_LIB_OPCODE_BUFFER
));
1747 if (OpCodeBuffer
== NULL
) {
1750 OpCodeBuffer
->Buffer
= (UINT8
*)AllocatePool (HII_LIB_OPCODE_ALLOCATION_SIZE
);
1751 if (OpCodeBuffer
->Buffer
== NULL
) {
1752 FreePool (OpCodeBuffer
);
1755 OpCodeBuffer
->BufferSize
= HII_LIB_OPCODE_ALLOCATION_SIZE
;
1756 OpCodeBuffer
->Position
= 0;
1757 return (VOID
*)OpCodeBuffer
;
1761 Frees an OpCode Handle that was peviously allocated with HiiAllocateOpCodeHandle().
1762 When an OpCode Handle is freed, all of the opcodes associated with the OpCode
1763 Handle are also freed.
1765 If OpCodeHandle is NULL, then ASSERT().
1770 HiiFreeOpCodeHandle (
1774 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1776 ASSERT (OpCodeHandle
!= NULL
);
1778 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
;
1779 if (OpCodeBuffer
->Buffer
!= NULL
) {
1780 FreePool (OpCodeBuffer
->Buffer
);
1782 FreePool (OpCodeBuffer
);
1787 InternalHiiOpCodeHandlePosition (
1788 IN VOID
*OpCodeHandle
1791 return ((HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
)->Position
;
1796 InternalHiiOpCodeHandleBuffer (
1797 IN VOID
*OpCodeHandle
1800 return ((HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
)->Buffer
;
1805 InternalHiiGrowOpCodeHandle (
1810 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1813 ASSERT (OpCodeHandle
!= NULL
);
1815 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
;
1816 if (OpCodeBuffer
->Position
+ Size
> OpCodeBuffer
->BufferSize
) {
1817 Buffer
= ReallocatePool (
1818 OpCodeBuffer
->BufferSize
,
1819 OpCodeBuffer
->BufferSize
+ (Size
+ HII_LIB_OPCODE_ALLOCATION_SIZE
),
1820 OpCodeBuffer
->Buffer
1822 if (Buffer
== NULL
) {
1825 OpCodeBuffer
->Buffer
= Buffer
;
1826 OpCodeBuffer
->BufferSize
+= (Size
+ HII_LIB_OPCODE_ALLOCATION_SIZE
);
1828 Buffer
= OpCodeBuffer
->Buffer
+ OpCodeBuffer
->Position
;
1829 OpCodeBuffer
->Position
+= Size
;
1835 InternalHiiCreateOpCodeExtended (
1836 IN VOID
*OpCodeHandle
,
1837 IN VOID
*OpCodeTemplate
,
1839 IN UINTN OpCodeSize
,
1840 IN UINTN ExtensionSize
,
1844 EFI_IFR_OP_HEADER
*Header
;
1847 ASSERT (OpCodeTemplate
!= NULL
);
1848 ASSERT ((OpCodeSize
+ ExtensionSize
) <= 0x7F);
1850 Header
= (EFI_IFR_OP_HEADER
*)OpCodeTemplate
;
1851 Header
->OpCode
= OpCode
;
1852 Header
->Scope
= Scope
;
1853 Header
->Length
= (UINT8
)(OpCodeSize
+ ExtensionSize
);
1854 Buffer
= InternalHiiGrowOpCodeHandle (OpCodeHandle
, Header
->Length
);
1855 return (UINT8
*)CopyMem (Buffer
, Header
, OpCodeSize
);
1860 InternalHiiCreateOpCode (
1861 IN VOID
*OpCodeHandle
,
1862 IN VOID
*OpCodeTemplate
,
1867 return InternalHiiCreateOpCodeExtended (OpCodeHandle
, OpCodeTemplate
, OpCode
, OpCodeSize
, 0, 0);
1871 Append raw opcodes to an OpCodeHandle.
1873 If OpCodeHandle is NULL, then ASSERT().
1874 If RawBuffer is NULL, then ASSERT();
1876 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1877 @param[in] RawBuffer Buffer of opcodes to append.
1878 @param[in] RawBufferSize The size, in bytes, of Buffer.
1880 @retval NULL There is not enough space left in Buffer to add the opcode.
1881 @retval Other A pointer to the appended opcodes.
1886 InternalHiiCreateRawOpCodes (
1887 IN VOID
*OpCodeHandle
,
1888 IN UINT8
*RawBuffer
,
1889 IN UINTN RawBufferSize
1894 ASSERT (RawBuffer
!= NULL
);
1896 Buffer
= InternalHiiGrowOpCodeHandle (OpCodeHandle
, RawBufferSize
);
1897 return (UINT8
*)CopyMem (Buffer
, RawBuffer
, RawBufferSize
);
1901 Append opcodes from one OpCode Handle to another OpCode handle.
1903 If OpCodeHandle is NULL, then ASSERT().
1904 If RawOpCodeHandle is NULL, then ASSERT();
1906 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1907 @param[in] RawOpCodeHandle Handle to the buffer of opcodes.
1909 @retval NULL There is not enough space left in Buffer to add the opcode.
1910 @retval Other A pointer to the appended opcodes.
1915 InternalHiiAppendOpCodes (
1916 IN VOID
*OpCodeHandle
,
1917 IN VOID
*RawOpCodeHandle
1920 HII_LIB_OPCODE_BUFFER
*RawOpCodeBuffer
;
1922 ASSERT (RawOpCodeHandle
!= NULL
);
1924 RawOpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)RawOpCodeHandle
;
1925 return InternalHiiCreateRawOpCodes (OpCodeHandle
, RawOpCodeBuffer
->Buffer
, RawOpCodeBuffer
->Position
);
1929 Create EFI_IFR_END_OP opcode.
1931 If OpCodeHandle is NULL, then ASSERT().
1933 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1935 @retval NULL There is not enough space left in Buffer to add the opcode.
1936 @retval Other A pointer to the created opcode.
1941 HiiCreateEndOpCode (
1942 IN VOID
*OpCodeHandle
1947 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_END_OP
, sizeof (OpCode
));
1951 Create EFI_IFR_ONE_OF_OPTION_OP opcode.
1953 If OpCodeHandle is NULL, then ASSERT().
1954 If Type is invalid, then ASSERT().
1955 If Flags is invalid, then ASSERT().
1957 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1958 @param[in] StringId StringId for the option
1959 @param[in] Flags Flags for the option
1960 @param[in] Type Type for the option
1961 @param[in] Value Value for the option
1963 @retval NULL There is not enough space left in Buffer to add the opcode.
1964 @retval Other A pointer to the created opcode.
1969 HiiCreateOneOfOptionOpCode (
1970 IN VOID
*OpCodeHandle
,
1977 EFI_IFR_ONE_OF_OPTION OpCode
;
1979 ASSERT (Type
< EFI_IFR_TYPE_OTHER
);
1981 ZeroMem (&OpCode
, sizeof (OpCode
));
1982 OpCode
.Option
= StringId
;
1983 OpCode
.Flags
= (UINT8
) (Flags
& (EFI_IFR_OPTION_DEFAULT
| EFI_IFR_OPTION_DEFAULT_MFG
));
1985 CopyMem (&OpCode
.Value
, &Value
, mHiiDefaultTypeToWidth
[Type
]);
1987 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_ONE_OF_OPTION_OP
, sizeof (OpCode
));
1991 Create EFI_IFR_DEFAULT_OP opcode.
1993 If OpCodeHandle is NULL, then ASSERT().
1994 If Type is invalid, then ASSERT().
1996 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1997 @param[in] DefaultId DefaultId for the default
1998 @param[in] Type Type for the default
1999 @param[in] Value Value for the default
2001 @retval NULL There is not enough space left in Buffer to add the opcode.
2002 @retval Other A pointer to the created opcode.
2007 HiiCreateDefaultOpCode (
2008 IN VOID
*OpCodeHandle
,
2009 IN UINT16 DefaultId
,
2014 EFI_IFR_DEFAULT OpCode
;
2016 ASSERT (Type
< EFI_IFR_TYPE_OTHER
);
2018 ZeroMem (&OpCode
, sizeof (OpCode
));
2020 OpCode
.DefaultId
= DefaultId
;
2021 CopyMem (&OpCode
.Value
, &Value
, mHiiDefaultTypeToWidth
[Type
]);
2023 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_DEFAULT_OP
, sizeof (OpCode
));
2027 Create EFI_IFR_GUID opcode.
2029 If OpCodeHandle is NULL, then ASSERT().
2030 If Guid is NULL, then ASSERT().
2031 If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT().
2033 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2034 @param[in] Guid Pointer to EFI_GUID of this guided opcode.
2035 @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an
2036 optional parameter that may be NULL. If this
2037 parameter is NULL, then the GUID extension
2038 region of the created opcode is filled with zeros.
2039 If this parameter is not NULL, then the GUID
2040 extension region of GuidData will be copied to
2041 the GUID extension region of the created opcode.
2042 @param[in] OpCodeSize The size, in bytes, of created opcode. This value
2043 must be >= sizeof(EFI_IFR_GUID).
2045 @retval NULL There is not enough space left in Buffer to add the opcode.
2046 @retval Other A pointer to the created opcode.
2051 HiiCreateGuidOpCode (
2052 IN VOID
*OpCodeHandle
,
2053 IN CONST EFI_GUID
*Guid
,
2054 IN CONST VOID
*GuidOpCode
, OPTIONAL
2058 EFI_IFR_GUID OpCode
;
2059 EFI_IFR_GUID
*OpCodePointer
;
2061 ASSERT (Guid
!= NULL
);
2062 ASSERT (OpCodeSize
>= sizeof (OpCode
));
2064 ZeroMem (&OpCode
, sizeof (OpCode
));
2065 CopyGuid (&OpCode
.Guid
, Guid
);
2067 OpCodePointer
= (EFI_IFR_GUID
*)InternalHiiCreateOpCodeExtended (
2072 OpCodeSize
- sizeof (OpCode
),
2075 if (OpCodePointer
!= NULL
&& GuidOpCode
!= NULL
) {
2076 CopyMem (OpCodePointer
+ 1, (EFI_IFR_GUID
*)GuidOpCode
+ 1, OpCodeSize
- sizeof (OpCode
));
2078 return (UINT8
*)OpCodePointer
;
2082 Create EFI_IFR_ACTION_OP opcode.
2084 If OpCodeHandle is NULL, then ASSERT().
2085 If any reserved bits are set in QuestionFlags, then ASSERT().
2087 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2088 @param[in] QuestionId Question ID
2089 @param[in] Prompt String ID for Prompt
2090 @param[in] Help String ID for Help
2091 @param[in] QuestionFlags Flags in Question Header
2092 @param[in] QuestionConfig String ID for configuration
2094 @retval NULL There is not enough space left in Buffer to add the opcode.
2095 @retval Other A pointer to the created opcode.
2100 HiiCreateActionOpCode (
2101 IN VOID
*OpCodeHandle
,
2102 IN EFI_QUESTION_ID QuestionId
,
2103 IN EFI_STRING_ID Prompt
,
2104 IN EFI_STRING_ID Help
,
2105 IN UINT8 QuestionFlags
,
2106 IN EFI_STRING_ID QuestionConfig
2109 EFI_IFR_ACTION OpCode
;
2111 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2113 ZeroMem (&OpCode
, sizeof (OpCode
));
2114 OpCode
.Question
.QuestionId
= QuestionId
;
2115 OpCode
.Question
.Header
.Prompt
= Prompt
;
2116 OpCode
.Question
.Header
.Help
= Help
;
2117 OpCode
.Question
.Flags
= QuestionFlags
;
2118 OpCode
.QuestionConfig
= QuestionConfig
;
2120 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_ACTION_OP
, sizeof (OpCode
));
2124 Create EFI_IFR_SUBTITLE_OP opcode.
2126 If OpCodeHandle is NULL, then ASSERT().
2127 If any reserved bits are set in Flags, then ASSERT().
2128 If Scope > 1, then ASSERT().
2130 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2131 @param[in] Prompt String ID for Prompt
2132 @param[in] Help String ID for Help
2133 @param[in] Flags Subtitle opcode flags
2134 @param[in] Scope 1 if this opcpde is the beginning of a new scope.
2135 0 if this opcode is within the current scope.
2137 @retval NULL There is not enough space left in Buffer to add the opcode.
2138 @retval Other A pointer to the created opcode.
2143 HiiCreateSubTitleOpCode (
2144 IN VOID
*OpCodeHandle
,
2145 IN EFI_STRING_ID Prompt
,
2146 IN EFI_STRING_ID Help
,
2151 EFI_IFR_SUBTITLE OpCode
;
2153 ASSERT (Scope
<= 1);
2154 ASSERT ((Flags
& (~(EFI_IFR_FLAGS_HORIZONTAL
))) == 0);
2156 ZeroMem (&OpCode
, sizeof (OpCode
));
2157 OpCode
.Statement
.Prompt
= Prompt
;
2158 OpCode
.Statement
.Help
= Help
;
2159 OpCode
.Flags
= Flags
;
2161 return InternalHiiCreateOpCodeExtended (
2164 EFI_IFR_SUBTITLE_OP
,
2172 Create EFI_IFR_REF_OP opcode.
2174 If OpCodeHandle is NULL, then ASSERT().
2175 If any reserved bits are set in QuestionFlags, then ASSERT().
2177 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2178 @param[in] FormId Destination Form ID
2179 @param[in] Prompt String ID for Prompt
2180 @param[in] Help String ID for Help
2181 @param[in] QuestionFlags Flags in Question Header
2182 @param[in] QuestionId Question ID
2184 @retval NULL There is not enough space left in Buffer to add the opcode.
2185 @retval Other A pointer to the created opcode.
2190 HiiCreateGotoOpCode (
2191 IN VOID
*OpCodeHandle
,
2192 IN EFI_FORM_ID FormId
,
2193 IN EFI_STRING_ID Prompt
,
2194 IN EFI_STRING_ID Help
,
2195 IN UINT8 QuestionFlags
,
2196 IN EFI_QUESTION_ID QuestionId
2201 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2203 ZeroMem (&OpCode
, sizeof (OpCode
));
2204 OpCode
.Question
.Header
.Prompt
= Prompt
;
2205 OpCode
.Question
.Header
.Help
= Help
;
2206 OpCode
.Question
.QuestionId
= QuestionId
;
2207 OpCode
.Question
.Flags
= QuestionFlags
;
2208 OpCode
.FormId
= FormId
;
2210 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_REF_OP
, sizeof (OpCode
));
2214 Create EFI_IFR_CHECKBOX_OP opcode.
2216 If OpCodeHandle is NULL, then ASSERT().
2217 If any reserved bits are set in QuestionFlags, then ASSERT().
2218 If any reserved bits are set in CheckBoxFlags, then ASSERT().
2220 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2221 @param[in] QuestionId Question ID
2222 @param[in] VarStoreId Storage ID
2223 @param[in] VarOffset Offset in Storage
2224 @param[in] Prompt String ID for Prompt
2225 @param[in] Help String ID for Help
2226 @param[in] QuestionFlags Flags in Question Header
2227 @param[in] CheckBoxFlags Flags for checkbox opcode
2228 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2229 is an optional parameter that may be NULL.
2231 @retval NULL There is not enough space left in Buffer to add the opcode.
2232 @retval Other A pointer to the created opcode.
2237 HiiCreateCheckBoxOpCode (
2238 IN VOID
*OpCodeHandle
,
2239 IN EFI_QUESTION_ID QuestionId
,
2240 IN EFI_VARSTORE_ID VarStoreId
,
2241 IN UINT16 VarOffset
,
2242 IN EFI_STRING_ID Prompt
,
2243 IN EFI_STRING_ID Help
,
2244 IN UINT8 QuestionFlags
,
2245 IN UINT8 CheckBoxFlags
,
2246 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2249 EFI_IFR_CHECKBOX OpCode
;
2252 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2254 ZeroMem (&OpCode
, sizeof (OpCode
));
2255 OpCode
.Question
.QuestionId
= QuestionId
;
2256 OpCode
.Question
.VarStoreId
= VarStoreId
;
2257 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2258 OpCode
.Question
.Header
.Prompt
= Prompt
;
2259 OpCode
.Question
.Header
.Help
= Help
;
2260 OpCode
.Question
.Flags
= QuestionFlags
;
2261 OpCode
.Flags
= CheckBoxFlags
;
2263 if (DefaultsOpCodeHandle
== NULL
) {
2264 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_CHECKBOX_OP
, sizeof (OpCode
));
2267 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2268 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_CHECKBOX_OP
, sizeof (OpCode
), 0, 1);
2269 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2270 HiiCreateEndOpCode (OpCodeHandle
);
2271 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2275 Create EFI_IFR_NUMERIC_OP opcode.
2277 If OpCodeHandle is NULL, then ASSERT().
2278 If any reserved bits are set in QuestionFlags, then ASSERT().
2279 If any reserved bits are set in NumericFlags, then ASSERT().
2281 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2282 @param[in] QuestionId Question ID
2283 @param[in] VarStoreId Storage ID
2284 @param[in] VarOffset Offset in Storage
2285 @param[in] Prompt String ID for Prompt
2286 @param[in] Help String ID for Help
2287 @param[in] QuestionFlags Flags in Question Header
2288 @param[in] NumericFlags Flags for numeric opcode
2289 @param[in] Minimum Numeric minimum value
2290 @param[in] Maximum Numeric maximum value
2291 @param[in] Step Numeric step for edit
2292 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2293 is an optional parameter that may be NULL.
2295 @retval NULL There is not enough space left in Buffer to add the opcode.
2296 @retval Other A pointer to the created opcode.
2301 HiiCreateNumericOpCode (
2302 IN VOID
*OpCodeHandle
,
2303 IN EFI_QUESTION_ID QuestionId
,
2304 IN EFI_VARSTORE_ID VarStoreId
,
2305 IN UINT16 VarOffset
,
2306 IN EFI_STRING_ID Prompt
,
2307 IN EFI_STRING_ID Help
,
2308 IN UINT8 QuestionFlags
,
2309 IN UINT8 NumericFlags
,
2313 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2316 EFI_IFR_NUMERIC OpCode
;
2319 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2321 ZeroMem (&OpCode
, sizeof (OpCode
));
2322 OpCode
.Question
.QuestionId
= QuestionId
;
2323 OpCode
.Question
.VarStoreId
= VarStoreId
;
2324 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2325 OpCode
.Question
.Header
.Prompt
= Prompt
;
2326 OpCode
.Question
.Header
.Help
= Help
;
2327 OpCode
.Question
.Flags
= QuestionFlags
;
2328 OpCode
.Flags
= NumericFlags
;
2330 switch (NumericFlags
& EFI_IFR_NUMERIC_SIZE
) {
2331 case EFI_IFR_NUMERIC_SIZE_1
:
2332 OpCode
.data
.u8
.MinValue
= (UINT8
)Minimum
;
2333 OpCode
.data
.u8
.MaxValue
= (UINT8
)Maximum
;
2334 OpCode
.data
.u8
.Step
= (UINT8
)Step
;
2337 case EFI_IFR_NUMERIC_SIZE_2
:
2338 OpCode
.data
.u16
.MinValue
= (UINT16
)Minimum
;
2339 OpCode
.data
.u16
.MaxValue
= (UINT16
)Maximum
;
2340 OpCode
.data
.u16
.Step
= (UINT16
)Step
;
2343 case EFI_IFR_NUMERIC_SIZE_4
:
2344 OpCode
.data
.u32
.MinValue
= (UINT32
)Minimum
;
2345 OpCode
.data
.u32
.MaxValue
= (UINT32
)Maximum
;
2346 OpCode
.data
.u32
.Step
= (UINT32
)Step
;
2349 case EFI_IFR_NUMERIC_SIZE_8
:
2350 OpCode
.data
.u64
.MinValue
= Minimum
;
2351 OpCode
.data
.u64
.MaxValue
= Maximum
;
2352 OpCode
.data
.u64
.Step
= Step
;
2356 if (DefaultsOpCodeHandle
== NULL
) {
2357 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_NUMERIC_OP
, sizeof (OpCode
));
2360 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2361 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_NUMERIC_OP
, sizeof (OpCode
), 0, 1);
2362 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2363 HiiCreateEndOpCode (OpCodeHandle
);
2364 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2368 Create EFI_IFR_STRING_OP opcode.
2370 If OpCodeHandle is NULL, then ASSERT().
2371 If any reserved bits are set in QuestionFlags, then ASSERT().
2372 If any reserved bits are set in StringFlags, then ASSERT().
2374 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2375 @param[in] QuestionId Question ID
2376 @param[in] VarStoreId Storage ID
2377 @param[in] VarOffset Offset in Storage
2378 @param[in] Prompt String ID for Prompt
2379 @param[in] Help String ID for Help
2380 @param[in] QuestionFlags Flags in Question Header
2381 @param[in] StringFlags Flags for string opcode
2382 @param[in] MinSize String minimum length
2383 @param[in] MaxSize String maximum length
2384 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2385 is an optional parameter that may be NULL.
2387 @retval NULL There is not enough space left in Buffer to add the opcode.
2388 @retval Other A pointer to the created opcode.
2393 HiiCreateStringOpCode (
2394 IN VOID
*OpCodeHandle
,
2395 IN EFI_QUESTION_ID QuestionId
,
2396 IN EFI_VARSTORE_ID VarStoreId
,
2397 IN UINT16 VarOffset
,
2398 IN EFI_STRING_ID Prompt
,
2399 IN EFI_STRING_ID Help
,
2400 IN UINT8 QuestionFlags
,
2401 IN UINT8 StringFlags
,
2404 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2407 EFI_IFR_STRING OpCode
;
2410 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2412 ZeroMem (&OpCode
, sizeof (OpCode
));
2413 OpCode
.Question
.Header
.Prompt
= Prompt
;
2414 OpCode
.Question
.Header
.Help
= Help
;
2415 OpCode
.Question
.QuestionId
= QuestionId
;
2416 OpCode
.Question
.VarStoreId
= VarStoreId
;
2417 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2418 OpCode
.Question
.Flags
= QuestionFlags
;
2419 OpCode
.MinSize
= MinSize
;
2420 OpCode
.MaxSize
= MaxSize
;
2421 OpCode
.Flags
= (UINT8
) (StringFlags
& EFI_IFR_STRING_MULTI_LINE
);
2423 if (DefaultsOpCodeHandle
== NULL
) {
2424 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_STRING_OP
, sizeof (OpCode
));
2427 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2428 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_STRING_OP
, sizeof (OpCode
), 0, 1);
2429 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2430 HiiCreateEndOpCode (OpCodeHandle
);
2431 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2435 Create EFI_IFR_ONE_OF_OP opcode.
2437 If OpCodeHandle is NULL, then ASSERT().
2438 If any reserved bits are set in QuestionFlags, then ASSERT().
2439 If any reserved bits are set in OneOfFlags, then ASSERT().
2441 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2442 @param[in] QuestionId Question ID
2443 @param[in] VarStoreId Storage ID
2444 @param[in] VarOffset Offset in Storage
2445 @param[in] Prompt String ID for Prompt
2446 @param[in] Help String ID for Help
2447 @param[in] QuestionFlags Flags in Question Header
2448 @param[in] OneOfFlags Flags for oneof opcode
2449 @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
2450 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2451 is an optional parameter that may be NULL.
2453 @retval NULL There is not enough space left in Buffer to add the opcode.
2454 @retval Other A pointer to the created opcode.
2459 HiiCreateOneOfOpCode (
2460 IN VOID
*OpCodeHandle
,
2461 IN EFI_QUESTION_ID QuestionId
,
2462 IN EFI_VARSTORE_ID VarStoreId
,
2463 IN UINT16 VarOffset
,
2464 IN EFI_STRING_ID Prompt
,
2465 IN EFI_STRING_ID Help
,
2466 IN UINT8 QuestionFlags
,
2467 IN UINT8 OneOfFlags
,
2468 IN VOID
*OptionsOpCodeHandle
,
2469 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2472 EFI_IFR_ONE_OF OpCode
;
2475 ASSERT (OptionsOpCodeHandle
!= NULL
);
2476 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2478 ZeroMem (&OpCode
, sizeof (OpCode
));
2479 OpCode
.Question
.Header
.Prompt
= Prompt
;
2480 OpCode
.Question
.Header
.Help
= Help
;
2481 OpCode
.Question
.QuestionId
= QuestionId
;
2482 OpCode
.Question
.VarStoreId
= VarStoreId
;
2483 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2484 OpCode
.Question
.Flags
= QuestionFlags
;
2485 OpCode
.Flags
= OneOfFlags
;
2487 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2488 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_ONE_OF_OP
, sizeof (OpCode
), 0, 1);
2489 InternalHiiAppendOpCodes (OpCodeHandle
, OptionsOpCodeHandle
);
2490 if (DefaultsOpCodeHandle
!= NULL
) {
2491 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2493 HiiCreateEndOpCode (OpCodeHandle
);
2494 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2498 Create EFI_IFR_ORDERED_LIST_OP opcode.
2500 If OpCodeHandle is NULL, then ASSERT().
2501 If any reserved bits are set in QuestionFlags, then ASSERT().
2502 If any reserved bits are set in OrderedListFlags, then ASSERT().
2504 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2505 @param[in] QuestionId Question ID
2506 @param[in] VarStoreId Storage ID
2507 @param[in] VarOffset Offset in Storage
2508 @param[in] Prompt String ID for Prompt
2509 @param[in] Help String ID for Help
2510 @param[in] QuestionFlags Flags in Question Header
2511 @param[in] OrderedListFlags Flags for ordered list opcode
2512 @param[in] DataType Type for option value
2513 @param[in] MaxContainers Maximum count for options in this ordered list
2514 @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
2515 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2516 is an optional parameter that may be NULL.
2518 @retval NULL There is not enough space left in Buffer to add the opcode.
2519 @retval Other A pointer to the created opcode.
2524 HiiCreateOrderedListOpCode (
2525 IN VOID
*OpCodeHandle
,
2526 IN EFI_QUESTION_ID QuestionId
,
2527 IN EFI_VARSTORE_ID VarStoreId
,
2528 IN UINT16 VarOffset
,
2529 IN EFI_STRING_ID Prompt
,
2530 IN EFI_STRING_ID Help
,
2531 IN UINT8 QuestionFlags
,
2532 IN UINT8 OrderedListFlags
,
2534 IN UINT8 MaxContainers
,
2535 IN VOID
*OptionsOpCodeHandle
,
2536 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2539 EFI_IFR_ORDERED_LIST OpCode
;
2542 ASSERT (OptionsOpCodeHandle
!= NULL
);
2543 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2545 ZeroMem (&OpCode
, sizeof (OpCode
));
2546 OpCode
.Question
.Header
.Prompt
= Prompt
;
2547 OpCode
.Question
.Header
.Help
= Help
;
2548 OpCode
.Question
.QuestionId
= QuestionId
;
2549 OpCode
.Question
.VarStoreId
= VarStoreId
;
2550 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2551 OpCode
.Question
.Flags
= QuestionFlags
;
2552 OpCode
.MaxContainers
= MaxContainers
;
2553 OpCode
.Flags
= OrderedListFlags
;
2555 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2556 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_ORDERED_LIST_OP
, sizeof (OpCode
), 0, 1);
2557 InternalHiiAppendOpCodes (OpCodeHandle
, OptionsOpCodeHandle
);
2558 if (DefaultsOpCodeHandle
!= NULL
) {
2559 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2561 HiiCreateEndOpCode (OpCodeHandle
);
2562 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2566 This is the internal worker function to update the data in
2567 a form specified by FormSetGuid, FormId and Label.
2569 @param FormSetGuid The optional Formset GUID.
2570 @param FormId The Form ID.
2571 @param Package The package header.
2573 @param TempPacakge The resultant package.
2575 @retval EFI_SUCCESS The function completes successfully.
2580 InternalHiiUpdateFormPackageData (
2581 IN EFI_GUID
*FormSetGuid
, OPTIONAL
2582 IN EFI_FORM_ID FormId
,
2583 IN EFI_HII_PACKAGE_HEADER
*Package
,
2584 IN HII_LIB_OPCODE_BUFFER
*OpCodeBufferStart
,
2585 IN HII_LIB_OPCODE_BUFFER
*OpCodeBufferEnd
, OPTIONAL
2586 OUT EFI_HII_PACKAGE_HEADER
*TempPackage
2591 EFI_HII_PACKAGE_HEADER PackageHeader
;
2593 EFI_IFR_OP_HEADER
*IfrOpHdr
;
2594 EFI_IFR_OP_HEADER
*UpdateIfrOpHdr
;
2598 EFI_IFR_OP_HEADER
*AddOpCode
;
2599 UINT32 UpdatePackageLength
;
2601 CopyMem (TempPackage
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2602 UpdatePackageLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
2603 BufferPos
= (UINT8
*) (TempPackage
+ 1);
2605 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2606 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
2607 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
2608 GetFormSet
= (BOOLEAN
) ((FormSetGuid
== NULL
) ? TRUE
: FALSE
);
2612 while (Offset
< PackageHeader
.Length
) {
2613 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
2614 BufferPos
+= IfrOpHdr
->Length
;
2615 UpdatePackageLength
+= IfrOpHdr
->Length
;
2618 // Find the matched FormSet and Form
2620 if ((IfrOpHdr
->OpCode
== EFI_IFR_FORM_SET_OP
) && (FormSetGuid
!= NULL
)) {
2621 if (CompareGuid((GUID
*)(VOID
*)&((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, FormSetGuid
)) {
2626 } else if (IfrOpHdr
->OpCode
== EFI_IFR_FORM_OP
) {
2627 if (CompareMem (&((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, &FormId
, sizeof (EFI_FORM_ID
)) == 0) {
2635 // The matched Form is found, and Update data in this form
2637 if (GetFormSet
&& GetForm
&& !Updated
) {
2638 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferStart
->Buffer
;
2639 if ((UpdateIfrOpHdr
->Length
== IfrOpHdr
->Length
) && \
2640 (CompareMem (IfrOpHdr
, UpdateIfrOpHdr
, UpdateIfrOpHdr
->Length
) == 0)) {
2642 // Remove the original data when End OpCode buffer exist.
2644 if (OpCodeBufferEnd
!= NULL
) {
2645 Offset
+= IfrOpHdr
->Length
;
2646 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2647 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferEnd
->Buffer
;
2648 while (Offset
< PackageHeader
.Length
) {
2650 // Search the matched end opcode
2652 if ((UpdateIfrOpHdr
->Length
== IfrOpHdr
->Length
) && \
2653 (CompareMem (IfrOpHdr
, UpdateIfrOpHdr
, UpdateIfrOpHdr
->Length
) == 0)) {
2657 // Go to the next Op-Code
2659 Offset
+= IfrOpHdr
->Length
;
2660 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2663 if (Offset
>= PackageHeader
.Length
) {
2665 // The end opcode is not found.
2667 return EFI_NOT_FOUND
;
2671 // Insert the updated data
2673 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferStart
->Buffer
;
2674 AddOpCode
= (EFI_IFR_OP_HEADER
*) (OpCodeBufferStart
->Buffer
+ UpdateIfrOpHdr
->Length
);
2675 AddSize
= UpdateIfrOpHdr
->Length
;
2676 while (AddSize
< OpCodeBufferStart
->Position
) {
2677 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
2678 BufferPos
+= AddOpCode
->Length
;
2679 UpdatePackageLength
+= AddOpCode
->Length
;
2681 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (AddOpCode
) + AddOpCode
->Length
);
2682 AddSize
+= AddOpCode
->Length
;
2685 if (OpCodeBufferEnd
!= NULL
) {
2687 // Add the end opcode
2689 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
2690 BufferPos
+= IfrOpHdr
->Length
;
2691 UpdatePackageLength
+= IfrOpHdr
->Length
;
2701 // Go to the next Op-Code
2703 Offset
+= IfrOpHdr
->Length
;
2704 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2709 // The updated opcode buffer is not found.
2711 return EFI_NOT_FOUND
;
2714 // Update the package length.
2716 PackageHeader
.Length
= UpdatePackageLength
;
2717 CopyMem (TempPackage
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2723 This function updates a form that has previously been registered with the HII
2724 Database. This function will perform at most one update operation.
2726 The form to update is specified by Handle, FormSetGuid, and FormId. Binary
2727 comparisons of IFR opcodes are performed from the beginning of the form being
2728 updated until an IFR opcode is found that exactly matches the first IFR opcode
2729 specifed by StartOpCodeHandle. The following rules are used to determine if
2730 an insert, replace, or delete operation is performed.
2732 1) If no matches are found, then NULL is returned.
2733 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes
2734 from StartOpcodeHandle except the first opcode are inserted immediately after
2735 the matching IFR opcode in the form beng updated.
2736 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made
2737 from the matching IFR opcode until an IFR opcode exatly matches the first
2738 IFR opcode specified by EndOpCodeHandle. If no match is found for the first
2739 IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match
2740 is found, then all of the IFR opcodes between the start match and the end
2741 match are deleted from the form being updated and all of the IFR opcodes
2742 from StartOpcodeHandle except the first opcode are inserted immediately after
2743 the matching start IFR opcode. If StartOpCcodeHandle only contains one
2744 IFR instruction, then the result of ths operation will delete all of the IFR
2745 opcodes between the start end matches.
2747 If HiiHandle is NULL, then ASSERT().
2748 If StartOpCodeHandle is NULL, then ASSERT().
2750 @param[in] HiiHandle The HII Handle of the form to update.
2751 @param[in] FormSetGuid The Formset GUID of the form to update. This
2752 is an optional parameter that may be NULL.
2753 If it is NULL, all FormSet will be updated.
2754 @param[in] FormId The ID of the form to update.
2755 @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR
2756 opcodes to be inserted or replaced in the form.
2757 The first IFR instruction in StartOpCodeHandle
2758 is used to find matching IFR opcode in the
2760 @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode
2761 that marks the end of a replace operation in
2762 the form. This is an optional parameter that
2763 may be NULL. If it is NULL, then an the IFR
2764 opcodes specified by StartOpCodeHandle are
2765 inserted into the form.
2767 @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated.
2768 @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND.
2769 1) The form specified by HiiHandle, FormSetGuid,
2770 and FormId could not be found in the HII Database.
2771 2) No IFR opcodes in the target form match the first
2772 IFR opcode in StartOpCodeHandle.
2773 3) EndOpCOde is not NULL, and no IFR opcodes in the
2774 target form following a matching start opcode match
2775 the first IFR opcode in EndOpCodeHandle.
2776 @retval EFI_SUCCESS The matched form is updated by StartOpcode.
2782 IN EFI_HII_HANDLE HiiHandle
,
2783 IN EFI_GUID
*FormSetGuid
, OPTIONAL
2784 IN EFI_FORM_ID FormId
,
2785 IN VOID
*StartOpcodeHandle
,
2786 IN VOID
*EndOpcodeHandle OPTIONAL
2790 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2791 UINT32 PackageListLength
;
2793 EFI_HII_PACKAGE_LIST_HEADER
*UpdatePackageList
;
2795 UINT8
*UpdateBufferPos
;
2796 EFI_HII_PACKAGE_HEADER
*Package
;
2797 EFI_HII_PACKAGE_HEADER
*TempPacakge
;
2798 EFI_HII_PACKAGE_HEADER PackageHeader
;
2800 HII_LIB_OPCODE_BUFFER
*OpCodeBufferStart
;
2801 HII_LIB_OPCODE_BUFFER
*OpCodeBufferEnd
;
2804 // Input update data can't be NULL.
2806 ASSERT (HiiHandle
!= NULL
);
2807 ASSERT (StartOpcodeHandle
!= NULL
);
2808 UpdatePackageList
= NULL
;
2810 HiiPackageList
= NULL
;
2813 // Restrive buffer data from Opcode Handle
2815 OpCodeBufferStart
= (HII_LIB_OPCODE_BUFFER
*) StartOpcodeHandle
;
2816 OpCodeBufferEnd
= (HII_LIB_OPCODE_BUFFER
*) EndOpcodeHandle
;
2819 // Get the orginal package list
2822 HiiPackageList
= NULL
;
2823 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
2825 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
2827 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2831 HiiPackageList
= AllocatePool (BufferSize
);
2832 if (HiiPackageList
== NULL
) {
2833 Status
= EFI_OUT_OF_RESOURCES
;
2837 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
2838 if (EFI_ERROR (Status
)) {
2843 // Calculate and allocate space for retrieval of IFR data
2845 BufferSize
+= OpCodeBufferStart
->Position
;
2846 UpdatePackageList
= AllocateZeroPool (BufferSize
);
2847 if (UpdatePackageList
== NULL
) {
2848 Status
= EFI_OUT_OF_RESOURCES
;
2853 // Allocate temp buffer to store the temp updated package buffer
2855 TempPacakge
= AllocateZeroPool (BufferSize
);
2856 if (TempPacakge
== NULL
) {
2857 Status
= EFI_OUT_OF_RESOURCES
;
2861 UpdateBufferPos
= (UINT8
*) UpdatePackageList
;
2864 // Copy the package list header
2866 CopyMem (UpdateBufferPos
, HiiPackageList
, sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
2867 UpdateBufferPos
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2870 // Go through each package to find the matched pacakge and update one by one
2873 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2874 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
2875 while (Offset
< PackageListLength
) {
2876 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
2877 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2878 Offset
+= Package
->Length
;
2880 if (Package
->Type
== EFI_HII_PACKAGE_FORMS
) {
2882 // Check this package is the matched package.
2884 Status
= InternalHiiUpdateFormPackageData (FormSetGuid
, FormId
, Package
, OpCodeBufferStart
, OpCodeBufferEnd
, TempPacakge
);
2886 // The matched package is found. Its pacakge buffer will be updated by the input new data.
2888 if (!EFI_ERROR(Status
)) {
2894 // Add updated package buffer
2896 Package
= TempPacakge
;
2901 // Add pacakge buffer
2903 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2904 CopyMem (UpdateBufferPos
, Package
, PackageHeader
.Length
);
2905 UpdateBufferPos
+= PackageHeader
.Length
;
2910 // Update package list length
2912 BufferSize
= UpdateBufferPos
- (UINT8
*) UpdatePackageList
;
2913 WriteUnaligned32 (&UpdatePackageList
->PackageLength
, (UINT32
) BufferSize
);
2916 // Update Pacakge to show form
2918 Status
= gHiiDatabase
->UpdatePackageList (gHiiDatabase
, HiiHandle
, UpdatePackageList
);
2921 // Not matched form is found and updated.
2923 Status
= EFI_NOT_FOUND
;
2927 if (HiiPackageList
!= NULL
) {
2928 FreePool (HiiPackageList
);
2931 if (UpdatePackageList
!= NULL
) {
2932 FreePool (UpdatePackageList
);
2935 if (TempPacakge
!= NULL
) {
2936 FreePool (TempPacakge
);