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.
15 #include "InternalHiiLib.h"
18 // <ConfigHdr> Template
20 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR16 mConfigHdrTemplate
[] = L
"GUID=00000000000000000000000000000000&NAME=0000&PATH=00";
22 EFI_FORM_BROWSER2_PROTOCOL
*mUefiFormBrowser2
= NULL
;
25 // Template used to mark the end of a list of packages
27 GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_HII_PACKAGE_HEADER mEndOfPakageList
= {
28 sizeof (EFI_HII_PACKAGE_HEADER
),
33 Registers a list of packages in the HII Database and returns the HII Handle
34 associated with that registration. If an HII Handle has already been registered
35 with the same PackageListGuid, then NULL is returned. If there are not enough
36 resources to perform the registration, then NULL is returned. If an empty list
37 of packages is passed in, then NULL is returned. If the size of the list of
38 package is 0, then NULL is returned.
40 The variable arguments are pointers which point to package header that defined
41 by UEFI VFR compiler and StringGather tool.
43 #pragma pack (push, 1)
46 EFI_HII_PACKAGE_HEADER PackageHeader;
47 } EDKII_AUTOGEN_PACKAGES_HEADER;
50 @param[in] PackageListGuid The GUID of the package list.
51 @param[in] DeviceHandle If not NULL, the Device Handle on which
52 an instance of DEVICE_PATH_PROTOCOL is installed.
53 This Device Handle uniquely defines the device that
54 the added packages are associated with.
55 @param[in] ... The variable argument list that contains pointers
56 to packages terminated by a NULL.
58 @retval NULL A HII Handle has already been registered in the HII Database with
59 the same PackageListGuid.
60 @retval NULL The HII Handle could not be created.
61 @retval NULL An empty list of packages was passed in.
62 @retval NULL All packages are empty.
63 @retval Other The HII Handle associated with the newly registered package list.
69 IN CONST EFI_GUID
*PackageListGuid
,
70 IN EFI_HANDLE DeviceHandle OPTIONAL
,
75 EFI_HII_HANDLE
*HiiHandleBuffer
;
78 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
79 EFI_HII_HANDLE HiiHandle
;
83 ASSERT (PackageListGuid
!= NULL
);
86 // Check to see if an HII Handle has already been registered with the same
89 HiiHandleBuffer
= HiiGetHiiHandles (PackageListGuid
);
90 if (HiiHandleBuffer
!= NULL
) {
91 FreePool (HiiHandleBuffer
);
96 // Calculate the length of all the packages in the variable argument list
98 for (Length
= 0, VA_START (Args
, DeviceHandle
); (Package
= VA_ARG (Args
, UINT32
*)) != NULL
; ) {
99 Length
+= (ReadUnaligned32 (Package
) - sizeof (UINT32
));
104 // If there are no packages in the variable argument list or all the packages
105 // are empty, then return a NULL HII Handle
112 // Add the length of the Package List Header and the terminating Package Header
114 Length
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
) + sizeof (EFI_HII_PACKAGE_HEADER
);
117 // Allocate the storage for the entire Package List
119 PackageListHeader
= AllocateZeroPool (Length
);
122 // If the Packahge List can not be allocated, then return a NULL HII Handle
124 if (PackageListHeader
== NULL
) {
129 // Fill in the GUID and Length of the Package List Header
131 CopyGuid (&PackageListHeader
->PackageListGuid
, PackageListGuid
);
132 PackageListHeader
->PackageLength
= Length
;
135 // Initialize a pointer to the beginning if the Package List data
137 Data
= (UINT8
*)(PackageListHeader
+ 1);
140 // Copy the data from each package in the variable argument list
142 for (VA_START (Args
, DeviceHandle
); (Package
= VA_ARG (Args
, UINT32
*)) != NULL
; ) {
143 Length
= ReadUnaligned32 (Package
) - sizeof (UINT32
);
144 CopyMem (Data
, Package
+ 1, Length
);
150 // Append a package of type EFI_HII_PACKAGE_END to mark the end of the package list
152 CopyMem (Data
, &mEndOfPakageList
, sizeof (mEndOfPakageList
));
155 // Register the package list with the HII Database
157 Status
= gHiiDatabase
->NewPackageList (
163 if (EFI_ERROR (Status
)) {
168 // Free the allocated package list
170 FreePool (PackageListHeader
);
173 // Return the new HII Handle
179 Removes a package list from the HII database.
181 If HiiHandle is NULL, then ASSERT.
182 If HiiHandle is not a valid EFI_HII_HANDLE in the HII database, then ASSERT.
184 @param[in] HiiHandle The handle that was previously registered in the HII database
190 IN EFI_HII_HANDLE HiiHandle
195 ASSERT (HiiHandle
!= NULL
);
196 Status
= gHiiDatabase
->RemovePackageList (gHiiDatabase
, HiiHandle
);
197 ASSERT_EFI_ERROR (Status
);
202 Retrieves the array of all the HII Handles or the HII handle of a specific
203 package list in the HII Database.
204 This array is terminated with a NULL HII Handle.
205 This function allocates the returned array using AllocatePool().
206 The caller is responsible for freeing the array with FreePool().
208 @param[in] PackageListGuid An optional parameter that is used to request
209 an HII Handle that is associatd with a specific
210 Package List GUID. If this parameter is NULL
211 then all the HII Handles in the HII Database
212 are returned. If this parameter is not NULL
213 then at most 1 HII Handle is returned.
215 @retval NULL No HII handles were found in the HII database
216 @retval NULL The array of HII Handles could not be retrieved
217 @retval Other A pointer to the NULL terminated array of HII Handles
223 IN CONST EFI_GUID
*PackageListGuid OPTIONAL
227 UINTN HandleBufferLength
;
228 EFI_HII_HANDLE TempHiiHandleBuffer
;
229 EFI_HII_HANDLE
*HiiHandleBuffer
;
234 // Retrieve the size required for the buffer of all HII handles.
236 HandleBufferLength
= 0;
237 Status
= gHiiDatabase
->ListPackageLists (
239 EFI_HII_PACKAGE_TYPE_ALL
,
246 // If ListPackageLists() returns EFI_SUCCESS for a zero size,
247 // then there are no HII handles in the HII database. If ListPackageLists()
248 // returns an error other than EFI_BUFFER_TOO_SMALL, then there are no HII
249 // handles in the HII database.
251 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
253 // Return NULL if the size can not be retrieved, or if there are no HII
254 // handles in the HII Database
260 // Allocate the array of HII handles to hold all the HII Handles and a NULL terminator
262 HiiHandleBuffer
= AllocateZeroPool (HandleBufferLength
+ sizeof (EFI_HII_HANDLE
));
263 if (HiiHandleBuffer
== NULL
) {
265 // Return NULL if allocation fails.
271 // Retrieve the array of HII Handles in the HII Database
273 Status
= gHiiDatabase
->ListPackageLists (
275 EFI_HII_PACKAGE_TYPE_ALL
,
280 if (EFI_ERROR (Status
)) {
282 // Free the buffer and return NULL if the HII handles can not be retrieved.
284 FreePool (HiiHandleBuffer
);
288 if (PackageListGuid
== NULL
) {
290 // Return the NULL terminated array of HII handles in the HII Database
292 return HiiHandleBuffer
;
294 for (Index
= 0; HiiHandleBuffer
[Index
] != NULL
; Index
++) {
295 Status
= InternalHiiExtractGuidFromHiiHandle (HiiHandleBuffer
[Index
], &Guid
);
296 ASSERT_EFI_ERROR (Status
);
297 if (CompareGuid (&Guid
, PackageListGuid
)) {
298 HiiHandleBuffer
[0] = HiiHandleBuffer
[Index
];
299 HiiHandleBuffer
[1] = NULL
;
300 return HiiHandleBuffer
;
303 FreePool (HiiHandleBuffer
);
309 Extract Hii package list GUID for given HII handle.
311 If HiiHandle could not be found in the HII database, then ASSERT.
312 If Guid is NULL, then ASSERT.
314 @param Handle Hii handle
315 @param Guid Package list GUID
317 @retval EFI_SUCCESS Successfully extract GUID from Hii database.
322 InternalHiiExtractGuidFromHiiHandle (
323 IN EFI_HII_HANDLE Handle
,
329 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
331 ASSERT (Guid
!= NULL
);
332 ASSERT (Handle
!= NULL
);
335 // Get HII PackageList
338 HiiPackageList
= NULL
;
340 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
341 ASSERT (Status
!= EFI_NOT_FOUND
);
343 if (Status
== EFI_BUFFER_TOO_SMALL
) {
344 HiiPackageList
= AllocatePool (BufferSize
);
345 ASSERT (HiiPackageList
!= NULL
);
347 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
349 if (EFI_ERROR (Status
)) {
350 FreePool (HiiPackageList
);
357 CopyGuid (Guid
, &HiiPackageList
->PackageListGuid
);
359 FreePool (HiiPackageList
);
365 Converts all hex dtring characters in range ['A'..'F'] to ['a'..'f'] for
366 hex digits that appear between a '=' and a '&' in a config string.
368 If String is NULL, then ASSERT().
370 @param[in] String Pointer to a Null-terminated Unicode string.
372 @return Pointer to the Null-terminated Unicode result string.
377 InternalHiiLowerConfigString (
378 IN EFI_STRING ConfigString
384 ASSERT (ConfigString
!= NULL
);
387 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
389 for (String
= ConfigString
, Lower
= FALSE
; *String
!= L
'\0'; String
++) {
390 if (*String
== L
'=') {
392 } else if (*String
== L
'&') {
394 } else if (Lower
&& *String
>= L
'A' && *String
<= L
'F') {
395 *String
= (CHAR16
) (*String
- L
'A' + L
'a');
403 Uses the BlockToConfig() service of the Config Routing Protocol to
404 convert <ConfigRequest> and a buffer to a <ConfigResp>
406 If ConfigRequest is NULL, then ASSERT().
407 If Block is NULL, then ASSERT().
409 @param[in] ConfigRequest Pointer to a Null-terminated Unicode string.
410 @param[in] Block Pointer to a block of data.
411 @param[in] BlockSize The zie, in bytes, of Block.
413 @retval NULL The <ConfigResp> string could not be generated.
414 @retval Other Pointer to the Null-terminated Unicode <ConfigResp> string.
419 InternalHiiBlockToConfig (
420 IN CONST EFI_STRING ConfigRequest
,
421 IN CONST UINT8
*Block
,
426 EFI_STRING ConfigResp
;
429 ASSERT (ConfigRequest
!= NULL
);
430 ASSERT (Block
!= NULL
);
433 // Convert <ConfigRequest> to <ConfigResp>
435 Status
= gHiiConfigRouting
->BlockToConfig (
443 if (EFI_ERROR (Status
)) {
450 Uses the ConfigToBlock() service of the Config Routing Protocol to
451 convert <ConfigResp> to a block. The block is allocated using
452 AllocatePool(). The caller is responsible for freeing the block
455 If ConfigResp is NULL, then ASSERT().
457 @param[in] ConfigResp Pointer to a Null-terminated Unicode string.
458 @param[in] BufferSize Length in bytes of buffer to hold retrived data.
460 @retval NULL The block could not be generated..
461 @retval Other Pointer to the allocated block.
466 InternalHiiConfigToBlock (
467 IN EFI_STRING ConfigResp
,
475 ASSERT (ConfigResp
!= NULL
);
478 // Allocate a buffer to hold the <ConfigResp> conversion
480 Block
= AllocateZeroPool (BlockSize
);
486 // Convert <ConfigResp> to a buffer
488 Status
= gHiiConfigRouting
->ConfigToBlock (
495 if (EFI_ERROR (Status
)) {
501 // Return converted buffer
507 Uses the BrowserCallback() service of the Form Browser Protocol to retrieve
508 or set uncommitted data. If sata i being retrieved, then the buffer is
509 allocated using AllocatePool(). The caller is then responsible for freeing
510 the buffer using FreePool().
512 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
513 is an optional parameter that may be NULL.
514 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
515 parameter that may be NULL.
516 @param[in] SetResultsData If not NULL, then this parameter specified the buffer
517 of uncommited data to set. If this parameter is NULL,
518 then the caller is requesting to get the uncommited data
519 from the Form Browser.
521 @retval NULL The uncommitted data could not be retrieved.
522 @retval Other A pointer to a buffer containing the uncommitted data.
527 InternalHiiBrowserCallback (
528 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
529 IN CONST CHAR16
*VariableName
, OPTIONAL
530 IN CONST EFI_STRING SetResultsData OPTIONAL
534 UINTN ResultsDataSize
;
535 EFI_STRING ResultsData
;
536 CHAR16 TempResultsData
;
541 if (mUefiFormBrowser2
== NULL
) {
542 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &mUefiFormBrowser2
);
543 if (EFI_ERROR (Status
) || mUefiFormBrowser2
== NULL
) {
550 if (SetResultsData
!= NULL
) {
552 // Request to to set data in the uncommitted browser state information
554 ResultsData
= SetResultsData
;
557 // Retrieve the length of the buffer required ResultsData from the Browser Callback
559 Status
= mUefiFormBrowser2
->BrowserCallback (
568 if (!EFI_ERROR (Status
)) {
570 // No Resluts Data, only allocate one char for '\0'
572 ResultsData
= AllocateZeroPool (sizeof (CHAR16
));
576 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
581 // Allocate the ResultsData buffer
583 ResultsData
= AllocateZeroPool (ResultsDataSize
);
584 if (ResultsData
== NULL
) {
590 // Retrieve or set the ResultsData from the Browser Callback
592 Status
= mUefiFormBrowser2
->BrowserCallback (
596 (BOOLEAN
)(SetResultsData
== NULL
),
600 if (EFI_ERROR (Status
)) {
608 Allocates and returns a Null-terminated Unicode <ConfigHdr> string using routing
609 information that includes a GUID, an optional Unicode string name, and a device
610 path. The string returned is allocated with AllocatePool(). The caller is
611 responsible for freeing the allocated string with FreePool().
613 The format of a <ConfigHdr> is as follows:
615 GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize<Null>
617 @param[in] Guid Pointer to an EFI_GUID that is the routing information
618 GUID. Each of the 16 bytes in Guid is converted to
619 a 2 Unicode character hexidecimal string. This is
620 an optional parameter that may be NULL.
621 @param[in] Name Pointer to a Null-terminated Unicode string that is
622 the routing information NAME. This is an optional
623 parameter that may be NULL. Each 16-bit Unicode
624 character in Name is converted to a 4 character Unicode
626 @param[in] DriverHandle The driver handle which supports a Device Path Protocol
627 that is the routing information PATH. Each byte of
628 the Device Path associated with DriverHandle is converted
629 to a 2 Unicode character hexidecimal string.
631 @retval NULL DriverHandle does not support the Device Path Protocol.
632 @retval Other A pointer to the Null-terminate Unicode <ConfigHdr> string
637 HiiConstructConfigHdr (
638 IN CONST EFI_GUID
*Guid
, OPTIONAL
639 IN CONST CHAR16
*Name
, OPTIONAL
640 IN EFI_HANDLE DriverHandle
644 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
645 UINTN DevicePathSize
;
647 CHAR16
*ReturnString
;
652 // Compute the length of Name in Unicode characters.
653 // If Name is NULL, then the length is 0.
657 NameLength
= StrLen (Name
);
663 // Retrieve DevicePath Protocol associated with DriverHandle
665 if (DriverHandle
!= NULL
) {
666 DevicePath
= DevicePathFromHandle (DriverHandle
);
667 if (DevicePath
== NULL
) {
671 // Compute the size of the device path in bytes
673 DevicePathSize
= GetDevicePathSize (DevicePath
);
677 // GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize <Null>
678 // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 |
680 String
= AllocateZeroPool ((5 + sizeof (EFI_GUID
) * 2 + 6 + NameLength
* 4 + 6 + DevicePathSize
* 2 + 1) * sizeof (CHAR16
));
681 if (String
== NULL
) {
686 // Start with L"GUID="
688 ReturnString
= StrCpy (String
, L
"GUID=");
689 String
+= StrLen (String
);
693 // Append Guid converted to <HexCh>32
695 for (Index
= 0, Buffer
= (UINT8
*)Guid
; Index
< sizeof (EFI_GUID
); Index
++) {
696 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(Buffer
++), 2);
703 StrCpy (String
, L
"&NAME=");
704 String
+= StrLen (String
);
708 // Append Name converted to <Char>NameLength
710 for (; *Name
!= L
'\0'; Name
++) {
711 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *Name
, 4);
718 StrCpy (String
, L
"&PATH=");
719 String
+= StrLen (String
);
722 // Append the device path associated with DriverHandle converted to <HexChar>DevicePathSize
724 for (Index
= 0, Buffer
= (UINT8
*)DevicePath
; Index
< DevicePathSize
; Index
++) {
725 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(Buffer
++), 2);
729 // Null terminate the Unicode string
734 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
736 return InternalHiiLowerConfigString (ReturnString
);
740 Allocates and returns a Null-terminated Unicode <ConfigAltResp> string.
742 If Guid is NULL, then ASSERT().
743 If Name is NULL, then ASSERT().
744 If BlockNameArray is NULL, then ASSERT().
746 @param[in] Guid GUID of the buffer storage.
747 @param[in] Name Name of the buffer storage.
748 @param[in] DriverHandle The DriverHandle that support a Device Path
750 @param[in] BufferStorage Content of the buffer storage.
751 @param[in] BufferStorageSize Length in bytes of the buffer storage.
752 @param[in] BlockNameArray Array generated by VFR compiler. This array
753 contains a UINT32 value that is the length
754 of BlockNameArray in bytes, followed by pairs
755 of 16-bit values that are the offset and length
756 values used to contruct a <ConfigRequest> string.
757 @param[in] ... A variable argument list that contains pairs of 16-bit
758 ALTCFG identifiers and pointers to DefaultValueArrays.
759 The variable argument list is terminated by a NULL
760 DefaultValueArray pointer. A DefaultValueArray
761 contains a UINT32 value that is the length, in bytes,
762 of the DefaultValueArray. The UINT32 length value
763 is followed by a series of records that contain
764 a 16-bit WIDTH value followed by a byte array with
765 WIDTH entries. The records must be parsed from
766 beginning to end until the UINT32 length limit
769 @retval NULL There are not enough resources to process the request.
770 @retval NULL A <ConfigResp> could not be retrieved from the Config
772 @retval Other A pointer to the Null-terminate Unicode <ConfigAltResp>
778 HiiConstructConfigAltResp (
779 IN CONST EFI_GUID
*Guid
,
780 IN CONST CHAR16
*Name
,
781 IN EFI_HANDLE DriverHandle
,
782 IN CONST VOID
*BufferStorage
,
783 IN UINTN BufferStorageSize
,
784 IN CONST VOID
*BlockNameArray
,
793 CHAR16
*ConfigRequest
;
794 EFI_STRING ConfigResp
;
795 EFI_STRING ConfigAltResp
;
802 ASSERT (Guid
!= NULL
);
803 ASSERT (Name
!= NULL
);
804 ASSERT (BlockNameArray
!= NULL
);
807 // Initialize local variables
810 ConfigRequest
= NULL
;
814 // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
816 ConfigHdr
= HiiConstructConfigHdr (Guid
, Name
, DriverHandle
);
817 if (ConfigHdr
== NULL
) {
822 // Compute the length of the entire request starting with <ConfigHdr> and a
825 Length
= StrLen (ConfigHdr
) + 1;
828 // Determine the size <BlockName> Offset/Width pairs
830 Buffer
= (UINT8
*)BlockNameArray
;
831 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
832 Buffer
+= sizeof (UINT32
);
835 // Add <BlockName> length that is composed of one or more Offset/Width pairs
837 // <BlockName> ::= &OFFSET=1234&WIDTH=1234
840 Length
+= (((BufferEnd
- Buffer
) / (sizeof (UINT16
) + sizeof (UINT16
))) * (8 + 4 + 7 + 4));
843 // Allocate buffer for the entire <ConfigRequest>
845 ConfigRequest
= AllocateZeroPool (Length
* sizeof (CHAR16
));
846 if (ConfigRequest
== NULL
) {
849 String
= ConfigRequest
;
852 // Start with <ConfigHdr>
854 StrCpy (String
, ConfigHdr
);
855 String
+= StrLen (String
);
858 // Loop through all the Offset/Width pairs and append them to ConfigRequest
860 while (Buffer
< BufferEnd
) {
862 // Append &OFFSET=XXXX&WIDTH=YYYY
864 OffsetValue
= ReadUnaligned16 ((UINT16
*)Buffer
);
865 WidthValue
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
868 (8 + 4 + 7 + 4) * sizeof (CHAR16
),
869 L
"&OFFSET=%04X&WIDTH=%04X",
874 String
+= StrLen (String
);
875 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
));
879 // Get the <ConfigResp>
881 ConfigResp
= InternalHiiBlockToConfig (ConfigRequest
, BufferStorage
, BufferStorageSize
);
882 if (ConfigResp
== NULL
) {
887 // Compute the length of the entire response starting with <ConfigResp> and a
890 Length
= StrLen (ConfigResp
) + 1;
893 // Add the length associated with each pair of variable argument parameters
895 VA_START (Args
, BlockNameArray
);
897 AltCfgId
= VA_ARG (Args
, UINT16
);
898 Buffer
= VA_ARG (Args
, UINT8
*);
899 if (Buffer
== NULL
) {
904 // Add length for "&<ConfigHdr>&ALTCFG=XXXX"
905 // |1| StrLen (ConfigHdr) | 8 | 4 |
907 Length
+= (1 + StrLen (ConfigHdr
) + 8 + 4);
909 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
910 Buffer
+= sizeof (UINT32
);
911 while (Buffer
< BufferEnd
) {
913 // Extract Width field
915 Width
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
918 // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"
919 // | 8 | 4 | 7 | 4 | 7 | Width * 2 |
921 Length
+= (8 + 4 + 7 + 4 + 7 + Width
* 2);
924 // Update Buffer to the next record
926 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
) + Width
);
932 // Allocate a buffer for the entire response
934 ConfigAltResp
= AllocateZeroPool (Length
* sizeof (CHAR16
));
935 if (ConfigAltResp
== NULL
) {
938 String
= ConfigAltResp
;
943 StrCpy (String
, ConfigResp
);
944 String
+= StrLen (String
);
947 // Add <AltResp> for each pair of variable argument parameters
949 VA_START (Args
, BlockNameArray
);
951 AltCfgId
= VA_ARG (Args
, UINT16
);
952 Buffer
= VA_ARG (Args
, UINT8
*);
953 if (Buffer
== NULL
) {
958 // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX"
959 // |1| StrLen (ConfigHdr) | 8 | 4 |
963 (1 + StrLen (ConfigHdr
) + 8 + 4) * sizeof (CHAR16
),
968 String
+= StrLen (String
);
971 // Add <ConfigBody> ::= <ConfigElement>*
973 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
974 Buffer
+= sizeof (UINT32
);
975 while (Buffer
< BufferEnd
) {
977 // Extract Width field
979 Width
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
986 (8 + 4 + 7 + 4 + 7 + Width
* 2) * sizeof (CHAR16
),
987 L
"&OFFSET=%04X&WIDTH=%04X&VALUE=",
988 ReadUnaligned16 ((UINT16
*)Buffer
),
991 String
+= StrLen (String
);
994 // Update Buffer to point to the value in the current record
996 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
));
999 // Convert Value to a hex string in "%x" format
1000 // NOTE: This is in the opposite byte that GUID and PATH use
1002 for (; Width
> 0; Width
--) {
1003 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, Buffer
[Width
- 1], 2);
1006 // Update Buffer to the next record
1014 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
1016 return InternalHiiLowerConfigString (ConfigAltResp
);
1019 if (ConfigHdr
!= NULL
) {
1020 FreePool (ConfigHdr
);
1022 if (ConfigRequest
!= NULL
) {
1023 FreePool (ConfigRequest
);
1025 if (ConfigResp
!= NULL
) {
1026 FreePool (ConfigResp
);
1033 Determines if two values in config strings match.
1035 Compares the substring between StartSearchString and StopSearchString in
1036 FirstString to the substring between StartSearchString and StopSearchString
1037 in SecondString. If the two substrings match, then TRUE is returned. If the
1038 two substrings do not match, then FALSE is returned.
1040 If FirstString is NULL, then ASSERT().
1041 If SecondString is NULL, then ASSERT().
1042 If StartSearchString is NULL, then ASSERT().
1043 If StopSearchString is NULL, then ASSERT().
1045 @param FirstString Pointer to the first Null-terminated Unicode string.
1046 @param SecondString Pointer to the second Null-terminated Unicode string.
1047 @param StartSearchString Pointer to the Null-terminated Unicode string that
1048 marks the start of the value string to compare.
1049 @param StopSearchString Pointer to the Null-terminated Unicode string that
1050 marks the end of the vakue string to compare.
1052 @retval FALSE StartSearchString is not present in FirstString.
1053 @retval FALSE StartSearchString is not present in SecondString.
1054 @retval FALSE StopSearchString is not present in FirstString.
1055 @retval FALSE StopSearchString is not present in SecondString.
1056 @retval FALSE The length of the substring in FirstString is not the
1057 same length as the substring in SecondString.
1058 @retval FALSE The value string in FirstString does not matche the
1059 value string in SecondString.
1060 @retval TRUE The value string in FirstString matches the value
1061 string in SecondString.
1066 InternalHiiCompareSubString (
1067 IN CHAR16
*FirstString
,
1068 IN CHAR16
*SecondString
,
1069 IN CHAR16
*StartSearchString
,
1070 IN CHAR16
*StopSearchString
1073 CHAR16
*EndFirstString
;
1074 CHAR16
*EndSecondString
;
1076 ASSERT (FirstString
!= NULL
);
1077 ASSERT (SecondString
!= NULL
);
1078 ASSERT (StartSearchString
!= NULL
);
1079 ASSERT (StopSearchString
!= NULL
);
1081 FirstString
= StrStr (FirstString
, StartSearchString
);
1082 if (FirstString
== NULL
) {
1086 SecondString
= StrStr (SecondString
, StartSearchString
);
1087 if (SecondString
== NULL
) {
1091 EndFirstString
= StrStr (FirstString
, StopSearchString
);
1092 if (EndFirstString
== NULL
) {
1096 EndSecondString
= StrStr (SecondString
, StopSearchString
);
1097 if (EndSecondString
== NULL
) {
1101 if ((EndFirstString
- FirstString
) != (EndSecondString
- SecondString
)) {
1105 return (BOOLEAN
)(StrnCmp (FirstString
, SecondString
, EndFirstString
- FirstString
) == 0);
1109 Determines if the routing data specified by GUID and NAME match a <ConfigHdr>.
1111 If ConfigHdr is NULL, then ASSERT().
1113 @param[in] ConfigHdr Either <ConfigRequest> or <ConfigResp>.
1114 @param[in] Guid GUID of the storage.
1115 @param[in] Name NAME of the storage.
1117 @retval TRUE Routing information matches <ConfigHdr>.
1118 @retval FALSE Routing information does not match <ConfigHdr>.
1123 HiiIsConfigHdrMatch (
1124 IN CONST EFI_STRING ConfigHdr
,
1125 IN CONST EFI_GUID
*Guid
, OPTIONAL
1126 IN CONST CHAR16
*Name OPTIONAL
1129 EFI_STRING CompareConfigHdr
;
1132 ASSERT (ConfigHdr
!= NULL
);
1135 // Use Guid and Name to generate a <ConfigHdr> string
1137 CompareConfigHdr
= HiiConstructConfigHdr (Guid
, Name
, NULL
);
1138 if (CompareConfigHdr
== NULL
) {
1145 // Compare GUID value strings
1147 Result
= InternalHiiCompareSubString (ConfigHdr
, CompareConfigHdr
, L
"GUID=", L
"&NAME=");
1150 if (Result
&& Name
!= NULL
) {
1152 // Compare NAME value strings
1154 Result
= InternalHiiCompareSubString (ConfigHdr
, CompareConfigHdr
, L
"&NAME=", L
"&PATH=");
1158 // Free the <ConfigHdr> string
1160 FreePool (CompareConfigHdr
);
1166 Retrieves uncommited data from the Form Browser and converts it to a binary
1167 buffer. The returned buffer is allocated using AllocatePool(). The caller
1168 is responsible for freeing the returned buffer using FreePool().
1170 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
1171 parameter that may be NULL.
1172 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
1173 is an optional parameter that may be NULL.
1174 @param[in] BufferSize Length in bytes of buffer to hold retrived data.
1176 @retval NULL The uncommitted data could not be retrieved.
1177 @retval Other A pointer to a buffer containing the uncommitted data.
1183 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
1184 IN CONST CHAR16
*VariableName
, OPTIONAL
1188 EFI_STRING ResultsData
;
1190 EFI_STRING ConfigResp
;
1194 // Retrieve the results data from the Browser Callback
1196 ResultsData
= InternalHiiBrowserCallback (VariableGuid
, VariableName
, NULL
);
1197 if (ResultsData
== NULL
) {
1202 // Construct <ConfigResp> mConfigHdrTemplate L'&' ResultsData L'\0'
1204 Size
= (StrLen (mConfigHdrTemplate
) + 1) * sizeof (CHAR16
);
1205 Size
= Size
+ (StrLen (ResultsData
) + 1) * sizeof (CHAR16
);
1206 ConfigResp
= AllocateZeroPool (Size
);
1207 UnicodeSPrint (ConfigResp
, Size
, L
"%s&%s", mConfigHdrTemplate
, ResultsData
);
1210 // Free the allocated buffer
1212 FreePool (ResultsData
);
1213 if (ConfigResp
== NULL
) {
1218 // Convert <ConfigResp> to a buffer
1220 Block
= InternalHiiConfigToBlock (ConfigResp
, BlockSize
);
1221 FreePool (ConfigResp
);
1227 Updates uncommitted data in the Form Browser.
1229 If Buffer is NULL, then ASSERT().
1231 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
1232 is an optional parameter that may be NULL.
1233 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
1234 parameter that may be NULL.
1235 @param[in] BufferSize Length, in bytes, of Buffer.
1236 @param[in] Buffer Buffer of data to commit.
1237 @param[in] RequestElement An optional field to specify which part of the
1238 buffer data will be send back to Browser. If NULL,
1239 the whole buffer of data will be committed to
1241 <RequestElement> ::= &OFFSET=<Number>&WIDTH=<Number>*
1243 @retval FALSE The uncommitted data could not be updated.
1244 @retval TRUE The uncommitted data was updated.
1250 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
1251 IN CONST CHAR16
*VariableName
, OPTIONAL
1252 IN UINTN BufferSize
,
1253 IN CONST UINT8
*Buffer
,
1254 IN CONST CHAR16
*RequestElement OPTIONAL
1258 EFI_STRING ConfigRequest
;
1259 EFI_STRING ConfigResp
;
1260 EFI_STRING ResultsData
;
1262 ASSERT (Buffer
!= NULL
);
1265 // Construct <ConfigRequest>
1267 if (RequestElement
== NULL
) {
1269 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1270 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1272 Size
= (StrLen (mConfigHdrTemplate
) + 32 + 1) * sizeof (CHAR16
);
1273 ConfigRequest
= AllocateZeroPool (Size
);
1274 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", mConfigHdrTemplate
, (UINT64
)BufferSize
);
1277 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1278 // followed by <RequestElement> followed by a Null-terminator
1280 Size
= StrLen (mConfigHdrTemplate
) * sizeof (CHAR16
);
1281 Size
= Size
+ (StrLen (RequestElement
) + 1) * sizeof (CHAR16
);
1282 ConfigRequest
= AllocateZeroPool (Size
);
1283 UnicodeSPrint (ConfigRequest
, Size
, L
"%s%s", mConfigHdrTemplate
, RequestElement
);
1285 if (ConfigRequest
== NULL
) {
1290 // Convert <ConfigRequest> to <ConfigResp>
1292 ConfigResp
= InternalHiiBlockToConfig (ConfigRequest
, Buffer
, BufferSize
);
1293 FreePool (ConfigRequest
);
1294 if (ConfigResp
== NULL
) {
1299 // Set data in the uncommitted browser state information
1301 ResultsData
= InternalHiiBrowserCallback (VariableGuid
, VariableName
, ConfigResp
+ StrLen(mConfigHdrTemplate
) + 1);
1302 FreePool (ConfigResp
);
1304 return (BOOLEAN
)(ResultsData
!= NULL
);
1307 /////////////////////////////////////////
1308 /////////////////////////////////////////
1310 /////////////////////////////////////////
1311 /////////////////////////////////////////
1313 #define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200
1319 } HII_LIB_OPCODE_BUFFER
;
1322 /// Lookup table that converts EFI_IFR_TYPE_X enum values to a width in bytes
1324 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth
[] = {
1325 1, // EFI_IFR_TYPE_NUM_SIZE_8
1326 2, // EFI_IFR_TYPE_NUM_SIZE_16
1327 4, // EFI_IFR_TYPE_NUM_SIZE_32
1328 8, // EFI_IFR_TYPE_NUM_SIZE_64
1329 1, // EFI_IFR_TYPE_BOOLEAN
1330 3, // EFI_IFR_TYPE_TIME
1331 4, // EFI_IFR_TYPE_DATE
1332 2 // EFI_IFR_TYPE_STRING
1336 Allocates and returns a new OpCode Handle. OpCode Handles must be freed with
1337 HiiFreeOpCodeHandle().
1339 @retval NULL There are not enough resources to allocate a new OpCode Handle.
1340 @retval Other A new OpCode handle.
1345 HiiAllocateOpCodeHandle (
1349 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1351 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)AllocatePool (sizeof (HII_LIB_OPCODE_BUFFER
));
1352 if (OpCodeBuffer
== NULL
) {
1355 OpCodeBuffer
->Buffer
= (UINT8
*)AllocatePool (HII_LIB_OPCODE_ALLOCATION_SIZE
);
1356 if (OpCodeBuffer
->Buffer
== NULL
) {
1357 FreePool (OpCodeBuffer
);
1360 OpCodeBuffer
->BufferSize
= HII_LIB_OPCODE_ALLOCATION_SIZE
;
1361 OpCodeBuffer
->Position
= 0;
1362 return (VOID
*)OpCodeBuffer
;
1366 Frees an OpCode Handle that was peviously allocated with HiiAllocateOpCodeHandle().
1367 When an OpCode Handle is freed, all of the opcodes associated with the OpCode
1368 Handle are also freed.
1370 If OpCodeHandle is NULL, then ASSERT().
1375 HiiFreeOpCodeHandle (
1379 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1381 ASSERT (OpCodeHandle
!= NULL
);
1383 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
;
1384 if (OpCodeBuffer
->Buffer
!= NULL
) {
1385 FreePool (OpCodeBuffer
->Buffer
);
1387 FreePool (OpCodeBuffer
);
1392 InternalHiiOpCodeHandlePosition (
1393 IN VOID
*OpCodeHandle
1396 return ((HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
)->Position
;
1401 InternalHiiOpCodeHandleBuffer (
1402 IN VOID
*OpCodeHandle
1405 return ((HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
)->Buffer
;
1410 InternalHiiGrowOpCodeHandle (
1415 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1418 ASSERT (OpCodeHandle
!= NULL
);
1420 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
;
1421 if (OpCodeBuffer
->Position
+ Size
> OpCodeBuffer
->BufferSize
) {
1422 Buffer
= ReallocatePool (
1423 OpCodeBuffer
->BufferSize
,
1424 OpCodeBuffer
->BufferSize
+ (Size
+ HII_LIB_OPCODE_ALLOCATION_SIZE
),
1425 OpCodeBuffer
->Buffer
1427 if (Buffer
== NULL
) {
1430 OpCodeBuffer
->Buffer
= Buffer
;
1431 OpCodeBuffer
->BufferSize
+= (Size
+ HII_LIB_OPCODE_ALLOCATION_SIZE
);
1433 Buffer
= OpCodeBuffer
->Buffer
+ OpCodeBuffer
->Position
;
1434 OpCodeBuffer
->Position
+= Size
;
1440 InternalHiiCreateOpCodeExtended (
1441 IN VOID
*OpCodeHandle
,
1442 IN VOID
*OpCodeTemplate
,
1444 IN UINTN OpCodeSize
,
1445 IN UINTN ExtensionSize
,
1449 EFI_IFR_OP_HEADER
*Header
;
1452 ASSERT (OpCodeTemplate
!= NULL
);
1453 ASSERT ((OpCodeSize
+ ExtensionSize
) <= 0x7F);
1455 Header
= (EFI_IFR_OP_HEADER
*)OpCodeTemplate
;
1456 Header
->OpCode
= OpCode
;
1457 Header
->Scope
= Scope
;
1458 Header
->Length
= (UINT8
)(OpCodeSize
+ ExtensionSize
);
1459 Buffer
= InternalHiiGrowOpCodeHandle (OpCodeHandle
, Header
->Length
);
1460 return (UINT8
*)CopyMem (Buffer
, Header
, OpCodeSize
);
1465 InternalHiiCreateOpCode (
1466 IN VOID
*OpCodeHandle
,
1467 IN VOID
*OpCodeTemplate
,
1472 return InternalHiiCreateOpCodeExtended (OpCodeHandle
, OpCodeTemplate
, OpCode
, OpCodeSize
, 0, 0);
1476 Append raw opcodes to an OpCodeHandle.
1478 If OpCodeHandle is NULL, then ASSERT().
1479 If RawBuffer is NULL, then ASSERT();
1481 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1482 @param[in] RawBuffer Buffer of opcodes to append.
1483 @param[in] RawBufferSize The size, in bytes, of Buffer.
1485 @retval NULL There is not enough space left in Buffer to add the opcode.
1486 @retval Other A pointer to the appended opcodes.
1491 InternalHiiCreateRawOpCodes (
1492 IN VOID
*OpCodeHandle
,
1493 IN UINT8
*RawBuffer
,
1494 IN UINTN RawBufferSize
1499 ASSERT (RawBuffer
!= NULL
);
1501 Buffer
= InternalHiiGrowOpCodeHandle (OpCodeHandle
, RawBufferSize
);
1502 return (UINT8
*)CopyMem (Buffer
, RawBuffer
, RawBufferSize
);
1506 Append opcodes from one OpCode Handle to another OpCode handle.
1508 If OpCodeHandle is NULL, then ASSERT().
1509 If RawOpCodeHandle is NULL, then ASSERT();
1511 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1512 @param[in] RawOpCodeHandle Handle to the buffer of opcodes.
1514 @retval NULL There is not enough space left in Buffer to add the opcode.
1515 @retval Other A pointer to the appended opcodes.
1520 InternalHiiAppendOpCodes (
1521 IN VOID
*OpCodeHandle
,
1522 IN VOID
*RawOpCodeHandle
1525 HII_LIB_OPCODE_BUFFER
*RawOpCodeBuffer
;
1527 ASSERT (RawOpCodeHandle
!= NULL
);
1529 RawOpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)RawOpCodeHandle
;
1530 return InternalHiiCreateRawOpCodes (OpCodeHandle
, RawOpCodeBuffer
->Buffer
, RawOpCodeBuffer
->Position
);
1534 Create EFI_IFR_END_OP opcode.
1536 If OpCodeHandle is NULL, then ASSERT().
1538 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1540 @retval NULL There is not enough space left in Buffer to add the opcode.
1541 @retval Other A pointer to the created opcode.
1546 HiiCreateEndOpCode (
1547 IN VOID
*OpCodeHandle
1552 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_END_OP
, sizeof (OpCode
));
1556 Create EFI_IFR_ONE_OF_OPTION_OP opcode.
1558 If OpCodeHandle is NULL, then ASSERT().
1559 If Type is invalid, then ASSERT().
1560 If Flags is invalid, then ASSERT().
1562 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1563 @param[in] StringId StringId for the option
1564 @param[in] Flags Flags for the option
1565 @param[in] Type Type for the option
1566 @param[in] Value Value for the option
1568 @retval NULL There is not enough space left in Buffer to add the opcode.
1569 @retval Other A pointer to the created opcode.
1574 HiiCreateOneOfOptionOpCode (
1575 IN VOID
*OpCodeHandle
,
1582 EFI_IFR_ONE_OF_OPTION OpCode
;
1584 ASSERT (Type
< EFI_IFR_TYPE_OTHER
);
1586 ZeroMem (&OpCode
, sizeof (OpCode
));
1587 OpCode
.Option
= StringId
;
1588 OpCode
.Flags
= (UINT8
) (Flags
& (EFI_IFR_OPTION_DEFAULT
| EFI_IFR_OPTION_DEFAULT_MFG
));
1590 CopyMem (&OpCode
.Value
, &Value
, mHiiDefaultTypeToWidth
[Type
]);
1592 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_ONE_OF_OPTION_OP
, sizeof (OpCode
));
1596 Create EFI_IFR_DEFAULT_OP opcode.
1598 If OpCodeHandle is NULL, then ASSERT().
1599 If Type is invalid, then ASSERT().
1601 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1602 @param[in] DefaultId DefaultId for the default
1603 @param[in] Type Type for the default
1604 @param[in] Value Value for the default
1606 @retval NULL There is not enough space left in Buffer to add the opcode.
1607 @retval Other A pointer to the created opcode.
1612 HiiCreateDefaultOpCode (
1613 IN VOID
*OpCodeHandle
,
1614 IN UINT16 DefaultId
,
1619 EFI_IFR_DEFAULT OpCode
;
1621 ASSERT (Type
< EFI_IFR_TYPE_OTHER
);
1623 ZeroMem (&OpCode
, sizeof (OpCode
));
1625 OpCode
.DefaultId
= DefaultId
;
1626 CopyMem (&OpCode
.Value
, &Value
, mHiiDefaultTypeToWidth
[Type
]);
1628 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_DEFAULT_OP
, sizeof (OpCode
));
1632 Create EFI_IFR_GUID opcode.
1634 If OpCodeHandle is NULL, then ASSERT().
1635 If Guid is NULL, then ASSERT().
1636 If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT().
1638 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1639 @param[in] Guid Pointer to EFI_GUID of this guided opcode.
1640 @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an
1641 optional parameter that may be NULL. If this
1642 parameter is NULL, then the GUID extension
1643 region of the created opcode is filled with zeros.
1644 If this parameter is not NULL, then the GUID
1645 extension region of GuidData will be copied to
1646 the GUID extension region of the created opcode.
1647 @param[in] OpCodeSize The size, in bytes, of created opcode. This value
1648 must be >= sizeof(EFI_IFR_GUID).
1650 @retval NULL There is not enough space left in Buffer to add the opcode.
1651 @retval Other A pointer to the created opcode.
1656 HiiCreateGuidOpCode (
1657 IN VOID
*OpCodeHandle
,
1658 IN CONST EFI_GUID
*Guid
,
1659 IN CONST VOID
*GuidOpCode
, OPTIONAL
1663 EFI_IFR_GUID OpCode
;
1664 EFI_IFR_GUID
*OpCodePointer
;
1666 ASSERT (Guid
!= NULL
);
1667 ASSERT (OpCodeSize
>= sizeof (OpCode
));
1669 ZeroMem (&OpCode
, sizeof (OpCode
));
1670 CopyGuid ((EFI_GUID
*)(VOID
*)&OpCode
.Guid
, Guid
);
1672 OpCodePointer
= (EFI_IFR_GUID
*)InternalHiiCreateOpCodeExtended (
1677 OpCodeSize
- sizeof (OpCode
),
1680 if (OpCodePointer
!= NULL
&& GuidOpCode
!= NULL
) {
1681 CopyMem (OpCodePointer
+ 1, (EFI_IFR_GUID
*)GuidOpCode
+ 1, OpCodeSize
- sizeof (OpCode
));
1683 return (UINT8
*)OpCodePointer
;
1687 Create EFI_IFR_ACTION_OP opcode.
1689 If OpCodeHandle is NULL, then ASSERT().
1690 If any reserved bits are set in QuestionFlags, then ASSERT().
1692 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1693 @param[in] QuestionId Question ID
1694 @param[in] Prompt String ID for Prompt
1695 @param[in] Help String ID for Help
1696 @param[in] QuestionFlags Flags in Question Header
1697 @param[in] QuestionConfig String ID for configuration
1699 @retval NULL There is not enough space left in Buffer to add the opcode.
1700 @retval Other A pointer to the created opcode.
1705 HiiCreateActionOpCode (
1706 IN VOID
*OpCodeHandle
,
1707 IN EFI_QUESTION_ID QuestionId
,
1708 IN EFI_STRING_ID Prompt
,
1709 IN EFI_STRING_ID Help
,
1710 IN UINT8 QuestionFlags
,
1711 IN EFI_STRING_ID QuestionConfig
1714 EFI_IFR_ACTION OpCode
;
1716 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1718 ZeroMem (&OpCode
, sizeof (OpCode
));
1719 OpCode
.Question
.QuestionId
= QuestionId
;
1720 OpCode
.Question
.Header
.Prompt
= Prompt
;
1721 OpCode
.Question
.Header
.Help
= Help
;
1722 OpCode
.Question
.Flags
= QuestionFlags
;
1723 OpCode
.QuestionConfig
= QuestionConfig
;
1725 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_ACTION_OP
, sizeof (OpCode
));
1729 Create EFI_IFR_SUBTITLE_OP opcode.
1731 If OpCodeHandle is NULL, then ASSERT().
1732 If any reserved bits are set in Flags, then ASSERT().
1733 If Scope > 1, then ASSERT().
1735 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1736 @param[in] Prompt String ID for Prompt
1737 @param[in] Help String ID for Help
1738 @param[in] Flags Subtitle opcode flags
1739 @param[in] Scope 1 if this opcpde is the beginning of a new scope.
1740 0 if this opcode is within the current scope.
1742 @retval NULL There is not enough space left in Buffer to add the opcode.
1743 @retval Other A pointer to the created opcode.
1748 HiiCreateSubTitleOpCode (
1749 IN VOID
*OpCodeHandle
,
1750 IN EFI_STRING_ID Prompt
,
1751 IN EFI_STRING_ID Help
,
1756 EFI_IFR_SUBTITLE OpCode
;
1758 ASSERT (Scope
<= 1);
1759 ASSERT ((Flags
& (~(EFI_IFR_FLAGS_HORIZONTAL
))) == 0);
1761 ZeroMem (&OpCode
, sizeof (OpCode
));
1762 OpCode
.Statement
.Prompt
= Prompt
;
1763 OpCode
.Statement
.Help
= Help
;
1764 OpCode
.Flags
= Flags
;
1766 return InternalHiiCreateOpCodeExtended (
1769 EFI_IFR_SUBTITLE_OP
,
1777 Create EFI_IFR_REF_OP opcode.
1779 If OpCodeHandle is NULL, then ASSERT().
1780 If any reserved bits are set in QuestionFlags, then ASSERT().
1782 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1783 @param[in] FormId Destination Form ID
1784 @param[in] Prompt String ID for Prompt
1785 @param[in] Help String ID for Help
1786 @param[in] QuestionFlags Flags in Question Header
1787 @param[in] QuestionId Question ID
1789 @retval NULL There is not enough space left in Buffer to add the opcode.
1790 @retval Other A pointer to the created opcode.
1795 HiiCreateGotoOpCode (
1796 IN VOID
*OpCodeHandle
,
1797 IN EFI_FORM_ID FormId
,
1798 IN EFI_STRING_ID Prompt
,
1799 IN EFI_STRING_ID Help
,
1800 IN UINT8 QuestionFlags
,
1801 IN EFI_QUESTION_ID QuestionId
1806 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1808 ZeroMem (&OpCode
, sizeof (OpCode
));
1809 OpCode
.Question
.Header
.Prompt
= Prompt
;
1810 OpCode
.Question
.Header
.Help
= Help
;
1811 OpCode
.Question
.QuestionId
= QuestionId
;
1812 OpCode
.Question
.Flags
= QuestionFlags
;
1813 OpCode
.FormId
= FormId
;
1815 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_REF_OP
, sizeof (OpCode
));
1819 Create EFI_IFR_CHECKBOX_OP opcode.
1821 If OpCodeHandle is NULL, then ASSERT().
1822 If any reserved bits are set in QuestionFlags, then ASSERT().
1823 If any reserved bits are set in CheckBoxFlags, then ASSERT().
1825 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1826 @param[in] QuestionId Question ID
1827 @param[in] VarStoreId Storage ID
1828 @param[in] VarOffset Offset in Storage
1829 @param[in] Prompt String ID for Prompt
1830 @param[in] Help String ID for Help
1831 @param[in] QuestionFlags Flags in Question Header
1832 @param[in] CheckBoxFlags Flags for checkbox opcode
1833 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
1834 is an optional parameter that may be NULL.
1836 @retval NULL There is not enough space left in Buffer to add the opcode.
1837 @retval Other A pointer to the created opcode.
1842 HiiCreateCheckBoxOpCode (
1843 IN VOID
*OpCodeHandle
,
1844 IN EFI_QUESTION_ID QuestionId
,
1845 IN EFI_VARSTORE_ID VarStoreId
,
1846 IN UINT16 VarOffset
,
1847 IN EFI_STRING_ID Prompt
,
1848 IN EFI_STRING_ID Help
,
1849 IN UINT8 QuestionFlags
,
1850 IN UINT8 CheckBoxFlags
,
1851 IN VOID
*DefaultsOpCodeHandle OPTIONAL
1854 EFI_IFR_CHECKBOX OpCode
;
1857 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1859 ZeroMem (&OpCode
, sizeof (OpCode
));
1860 OpCode
.Question
.QuestionId
= QuestionId
;
1861 OpCode
.Question
.VarStoreId
= VarStoreId
;
1862 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
1863 OpCode
.Question
.Header
.Prompt
= Prompt
;
1864 OpCode
.Question
.Header
.Help
= Help
;
1865 OpCode
.Question
.Flags
= QuestionFlags
;
1866 OpCode
.Flags
= CheckBoxFlags
;
1868 if (DefaultsOpCodeHandle
== NULL
) {
1869 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_CHECKBOX_OP
, sizeof (OpCode
));
1872 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
1873 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_CHECKBOX_OP
, sizeof (OpCode
), 0, 1);
1874 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
1875 HiiCreateEndOpCode (OpCodeHandle
);
1876 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
1880 Create EFI_IFR_NUMERIC_OP opcode.
1882 If OpCodeHandle is NULL, then ASSERT().
1883 If any reserved bits are set in QuestionFlags, then ASSERT().
1884 If any reserved bits are set in NumericFlags, then ASSERT().
1886 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1887 @param[in] QuestionId Question ID
1888 @param[in] VarStoreId Storage ID
1889 @param[in] VarOffset Offset in Storage
1890 @param[in] Prompt String ID for Prompt
1891 @param[in] Help String ID for Help
1892 @param[in] QuestionFlags Flags in Question Header
1893 @param[in] NumericFlags Flags for numeric opcode
1894 @param[in] Minimum Numeric minimum value
1895 @param[in] Maximum Numeric maximum value
1896 @param[in] Step Numeric step for edit
1897 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
1898 is an optional parameter that may be NULL.
1900 @retval NULL There is not enough space left in Buffer to add the opcode.
1901 @retval Other A pointer to the created opcode.
1906 HiiCreateNumericOpCode (
1907 IN VOID
*OpCodeHandle
,
1908 IN EFI_QUESTION_ID QuestionId
,
1909 IN EFI_VARSTORE_ID VarStoreId
,
1910 IN UINT16 VarOffset
,
1911 IN EFI_STRING_ID Prompt
,
1912 IN EFI_STRING_ID Help
,
1913 IN UINT8 QuestionFlags
,
1914 IN UINT8 NumericFlags
,
1918 IN VOID
*DefaultsOpCodeHandle OPTIONAL
1921 EFI_IFR_NUMERIC OpCode
;
1924 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1926 ZeroMem (&OpCode
, sizeof (OpCode
));
1927 OpCode
.Question
.QuestionId
= QuestionId
;
1928 OpCode
.Question
.VarStoreId
= VarStoreId
;
1929 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
1930 OpCode
.Question
.Header
.Prompt
= Prompt
;
1931 OpCode
.Question
.Header
.Help
= Help
;
1932 OpCode
.Question
.Flags
= QuestionFlags
;
1933 OpCode
.Flags
= NumericFlags
;
1935 switch (NumericFlags
& EFI_IFR_NUMERIC_SIZE
) {
1936 case EFI_IFR_NUMERIC_SIZE_1
:
1937 OpCode
.data
.u8
.MinValue
= (UINT8
)Minimum
;
1938 OpCode
.data
.u8
.MaxValue
= (UINT8
)Maximum
;
1939 OpCode
.data
.u8
.Step
= (UINT8
)Step
;
1942 case EFI_IFR_NUMERIC_SIZE_2
:
1943 OpCode
.data
.u16
.MinValue
= (UINT16
)Minimum
;
1944 OpCode
.data
.u16
.MaxValue
= (UINT16
)Maximum
;
1945 OpCode
.data
.u16
.Step
= (UINT16
)Step
;
1948 case EFI_IFR_NUMERIC_SIZE_4
:
1949 OpCode
.data
.u32
.MinValue
= (UINT32
)Minimum
;
1950 OpCode
.data
.u32
.MaxValue
= (UINT32
)Maximum
;
1951 OpCode
.data
.u32
.Step
= (UINT32
)Step
;
1954 case EFI_IFR_NUMERIC_SIZE_8
:
1955 OpCode
.data
.u64
.MinValue
= Minimum
;
1956 OpCode
.data
.u64
.MaxValue
= Maximum
;
1957 OpCode
.data
.u64
.Step
= Step
;
1961 if (DefaultsOpCodeHandle
== NULL
) {
1962 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_NUMERIC_OP
, sizeof (OpCode
));
1965 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
1966 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_NUMERIC_OP
, sizeof (OpCode
), 0, 1);
1967 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
1968 HiiCreateEndOpCode (OpCodeHandle
);
1969 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
1973 Create EFI_IFR_STRING_OP opcode.
1975 If OpCodeHandle is NULL, then ASSERT().
1976 If any reserved bits are set in QuestionFlags, then ASSERT().
1977 If any reserved bits are set in StringFlags, then ASSERT().
1979 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1980 @param[in] QuestionId Question ID
1981 @param[in] VarStoreId Storage ID
1982 @param[in] VarOffset Offset in Storage
1983 @param[in] Prompt String ID for Prompt
1984 @param[in] Help String ID for Help
1985 @param[in] QuestionFlags Flags in Question Header
1986 @param[in] StringFlags Flags for string opcode
1987 @param[in] MinSize String minimum length
1988 @param[in] MaxSize String maximum length
1989 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
1990 is an optional parameter that may be NULL.
1992 @retval NULL There is not enough space left in Buffer to add the opcode.
1993 @retval Other A pointer to the created opcode.
1998 HiiCreateStringOpCode (
1999 IN VOID
*OpCodeHandle
,
2000 IN EFI_QUESTION_ID QuestionId
,
2001 IN EFI_VARSTORE_ID VarStoreId
,
2002 IN UINT16 VarOffset
,
2003 IN EFI_STRING_ID Prompt
,
2004 IN EFI_STRING_ID Help
,
2005 IN UINT8 QuestionFlags
,
2006 IN UINT8 StringFlags
,
2009 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2012 EFI_IFR_STRING OpCode
;
2015 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2017 ZeroMem (&OpCode
, sizeof (OpCode
));
2018 OpCode
.Question
.Header
.Prompt
= Prompt
;
2019 OpCode
.Question
.Header
.Help
= Help
;
2020 OpCode
.Question
.QuestionId
= QuestionId
;
2021 OpCode
.Question
.VarStoreId
= VarStoreId
;
2022 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2023 OpCode
.Question
.Flags
= QuestionFlags
;
2024 OpCode
.MinSize
= MinSize
;
2025 OpCode
.MaxSize
= MaxSize
;
2026 OpCode
.Flags
= (UINT8
) (StringFlags
& EFI_IFR_STRING_MULTI_LINE
);
2028 if (DefaultsOpCodeHandle
== NULL
) {
2029 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_STRING_OP
, sizeof (OpCode
));
2032 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2033 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_STRING_OP
, sizeof (OpCode
), 0, 1);
2034 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2035 HiiCreateEndOpCode (OpCodeHandle
);
2036 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2040 Create EFI_IFR_ONE_OF_OP opcode.
2042 If OpCodeHandle is NULL, then ASSERT().
2043 If any reserved bits are set in QuestionFlags, then ASSERT().
2044 If any reserved bits are set in OneOfFlags, then ASSERT().
2046 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2047 @param[in] QuestionId Question ID
2048 @param[in] VarStoreId Storage ID
2049 @param[in] VarOffset Offset in Storage
2050 @param[in] Prompt String ID for Prompt
2051 @param[in] Help String ID for Help
2052 @param[in] QuestionFlags Flags in Question Header
2053 @param[in] OneOfFlags Flags for oneof opcode
2054 @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
2055 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2056 is an optional parameter that may be NULL.
2058 @retval NULL There is not enough space left in Buffer to add the opcode.
2059 @retval Other A pointer to the created opcode.
2064 HiiCreateOneOfOpCode (
2065 IN VOID
*OpCodeHandle
,
2066 IN EFI_QUESTION_ID QuestionId
,
2067 IN EFI_VARSTORE_ID VarStoreId
,
2068 IN UINT16 VarOffset
,
2069 IN EFI_STRING_ID Prompt
,
2070 IN EFI_STRING_ID Help
,
2071 IN UINT8 QuestionFlags
,
2072 IN UINT8 OneOfFlags
,
2073 IN VOID
*OptionsOpCodeHandle
,
2074 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2077 EFI_IFR_ONE_OF OpCode
;
2080 ASSERT (OptionsOpCodeHandle
!= NULL
);
2081 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2083 ZeroMem (&OpCode
, sizeof (OpCode
));
2084 OpCode
.Question
.Header
.Prompt
= Prompt
;
2085 OpCode
.Question
.Header
.Help
= Help
;
2086 OpCode
.Question
.QuestionId
= QuestionId
;
2087 OpCode
.Question
.VarStoreId
= VarStoreId
;
2088 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2089 OpCode
.Question
.Flags
= QuestionFlags
;
2090 OpCode
.Flags
= OneOfFlags
;
2092 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2093 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_ONE_OF_OP
, sizeof (OpCode
), 0, 1);
2094 InternalHiiAppendOpCodes (OpCodeHandle
, OptionsOpCodeHandle
);
2095 if (DefaultsOpCodeHandle
!= NULL
) {
2096 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2098 HiiCreateEndOpCode (OpCodeHandle
);
2099 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2103 Create EFI_IFR_ORDERED_LIST_OP opcode.
2105 If OpCodeHandle is NULL, then ASSERT().
2106 If any reserved bits are set in QuestionFlags, then ASSERT().
2107 If any reserved bits are set in OrderedListFlags, then ASSERT().
2109 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2110 @param[in] QuestionId Question ID
2111 @param[in] VarStoreId Storage ID
2112 @param[in] VarOffset Offset in Storage
2113 @param[in] Prompt String ID for Prompt
2114 @param[in] Help String ID for Help
2115 @param[in] QuestionFlags Flags in Question Header
2116 @param[in] OrderedListFlags Flags for ordered list opcode
2117 @param[in] DataType Type for option value
2118 @param[in] MaxContainers Maximum count for options in this ordered list
2119 @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
2120 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2121 is an optional parameter that may be NULL.
2123 @retval NULL There is not enough space left in Buffer to add the opcode.
2124 @retval Other A pointer to the created opcode.
2129 HiiCreateOrderedListOpCode (
2130 IN VOID
*OpCodeHandle
,
2131 IN EFI_QUESTION_ID QuestionId
,
2132 IN EFI_VARSTORE_ID VarStoreId
,
2133 IN UINT16 VarOffset
,
2134 IN EFI_STRING_ID Prompt
,
2135 IN EFI_STRING_ID Help
,
2136 IN UINT8 QuestionFlags
,
2137 IN UINT8 OrderedListFlags
,
2139 IN UINT8 MaxContainers
,
2140 IN VOID
*OptionsOpCodeHandle
,
2141 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2144 EFI_IFR_ORDERED_LIST OpCode
;
2147 ASSERT (OptionsOpCodeHandle
!= NULL
);
2148 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2150 ZeroMem (&OpCode
, sizeof (OpCode
));
2151 OpCode
.Question
.Header
.Prompt
= Prompt
;
2152 OpCode
.Question
.Header
.Help
= Help
;
2153 OpCode
.Question
.QuestionId
= QuestionId
;
2154 OpCode
.Question
.VarStoreId
= VarStoreId
;
2155 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2156 OpCode
.Question
.Flags
= QuestionFlags
;
2157 OpCode
.MaxContainers
= MaxContainers
;
2158 OpCode
.Flags
= OrderedListFlags
;
2160 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2161 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_ORDERED_LIST_OP
, sizeof (OpCode
), 0, 1);
2162 InternalHiiAppendOpCodes (OpCodeHandle
, OptionsOpCodeHandle
);
2163 if (DefaultsOpCodeHandle
!= NULL
) {
2164 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2166 HiiCreateEndOpCode (OpCodeHandle
);
2167 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2171 This is the internal worker function to update the data in
2172 a form specified by FormSetGuid, FormId and Label.
2174 @param FormSetGuid The optional Formset GUID.
2175 @param FormId The Form ID.
2176 @param Package The package header.
2178 @param TempPacakge The resultant package.
2180 @retval EFI_SUCCESS The function completes successfully.
2185 InternalHiiUpdateFormPackageData (
2186 IN EFI_GUID
*FormSetGuid
, OPTIONAL
2187 IN EFI_FORM_ID FormId
,
2188 IN EFI_HII_PACKAGE_HEADER
*Package
,
2189 IN HII_LIB_OPCODE_BUFFER
*OpCodeBufferStart
,
2190 IN HII_LIB_OPCODE_BUFFER
*OpCodeBufferEnd
, OPTIONAL
2191 OUT EFI_HII_PACKAGE_HEADER
*TempPackage
2196 EFI_HII_PACKAGE_HEADER PackageHeader
;
2198 EFI_IFR_OP_HEADER
*IfrOpHdr
;
2199 EFI_IFR_OP_HEADER
*UpdateIfrOpHdr
;
2203 UINTN UpdatePackageLength
;
2205 CopyMem (TempPackage
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2206 UpdatePackageLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
2207 BufferPos
= (UINT8
*) (TempPackage
+ 1);
2209 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2210 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
2211 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
2212 GetFormSet
= (BOOLEAN
) ((FormSetGuid
== NULL
) ? TRUE
: FALSE
);
2216 while (Offset
< PackageHeader
.Length
) {
2217 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
2218 BufferPos
+= IfrOpHdr
->Length
;
2219 UpdatePackageLength
+= IfrOpHdr
->Length
;
2222 // Find the matched FormSet and Form
2224 if ((IfrOpHdr
->OpCode
== EFI_IFR_FORM_SET_OP
) && (FormSetGuid
!= NULL
)) {
2225 if (CompareGuid((GUID
*)(VOID
*)&((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, FormSetGuid
)) {
2230 } else if (IfrOpHdr
->OpCode
== EFI_IFR_FORM_OP
) {
2231 if (CompareMem (&((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, &FormId
, sizeof (EFI_FORM_ID
)) == 0) {
2239 // The matched Form is found, and Update data in this form
2241 if (GetFormSet
&& GetForm
) {
2242 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferStart
->Buffer
;
2243 if ((UpdateIfrOpHdr
->Length
== IfrOpHdr
->Length
) && \
2244 (CompareMem (IfrOpHdr
, UpdateIfrOpHdr
, UpdateIfrOpHdr
->Length
) == 0)) {
2246 // Remove the original data when End OpCode buffer exist.
2248 if (OpCodeBufferEnd
!= NULL
) {
2249 Offset
+= IfrOpHdr
->Length
;
2250 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2251 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferEnd
->Buffer
;
2252 while (Offset
< PackageHeader
.Length
) {
2254 // Search the matched end opcode
2256 if ((UpdateIfrOpHdr
->Length
== IfrOpHdr
->Length
) && \
2257 (CompareMem (IfrOpHdr
, UpdateIfrOpHdr
, UpdateIfrOpHdr
->Length
) == 0)) {
2261 // Go to the next Op-Code
2263 Offset
+= IfrOpHdr
->Length
;
2264 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2267 if (Offset
>= PackageHeader
.Length
) {
2269 // The end opcode is not found.
2271 return EFI_NOT_FOUND
;
2276 // Insert the updated data
2278 AddSize
= ((EFI_IFR_OP_HEADER
*) OpCodeBufferStart
->Buffer
)->Length
;
2279 CopyMem (BufferPos
, OpCodeBufferStart
->Buffer
+ AddSize
, OpCodeBufferStart
->Position
- AddSize
);
2280 BufferPos
+= OpCodeBufferStart
->Position
- AddSize
;
2281 UpdatePackageLength
+= OpCodeBufferStart
->Position
- AddSize
;
2283 if (OpCodeBufferEnd
!= NULL
) {
2285 // Add the end opcode
2287 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
2288 BufferPos
+= IfrOpHdr
->Length
;
2289 UpdatePackageLength
+= IfrOpHdr
->Length
;
2293 // Copy the left package data.
2295 Offset
+= IfrOpHdr
->Length
;
2296 CopyMem (BufferPos
, (UINT8
*) Package
+ Offset
, PackageHeader
.Length
- Offset
);
2297 UpdatePackageLength
+= PackageHeader
.Length
- Offset
;
2308 // Go to the next Op-Code
2310 Offset
+= IfrOpHdr
->Length
;
2311 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2316 // The updated opcode buffer is not found.
2318 return EFI_NOT_FOUND
;
2321 // Update the package length.
2323 PackageHeader
.Length
= (UINT32
) UpdatePackageLength
;
2324 CopyMem (TempPackage
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2330 This function updates a form that has previously been registered with the HII
2331 Database. This function will perform at most one update operation.
2333 The form to update is specified by Handle, FormSetGuid, and FormId. Binary
2334 comparisons of IFR opcodes are performed from the beginning of the form being
2335 updated until an IFR opcode is found that exactly matches the first IFR opcode
2336 specifed by StartOpCodeHandle. The following rules are used to determine if
2337 an insert, replace, or delete operation is performed.
2339 1) If no matches are found, then NULL is returned.
2340 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes
2341 from StartOpcodeHandle except the first opcode are inserted immediately after
2342 the matching IFR opcode in the form beng updated.
2343 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made
2344 from the matching IFR opcode until an IFR opcode exatly matches the first
2345 IFR opcode specified by EndOpCodeHandle. If no match is found for the first
2346 IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match
2347 is found, then all of the IFR opcodes between the start match and the end
2348 match are deleted from the form being updated and all of the IFR opcodes
2349 from StartOpcodeHandle except the first opcode are inserted immediately after
2350 the matching start IFR opcode. If StartOpCcodeHandle only contains one
2351 IFR instruction, then the result of ths operation will delete all of the IFR
2352 opcodes between the start end matches.
2354 If HiiHandle is NULL, then ASSERT().
2355 If StartOpCodeHandle is NULL, then ASSERT().
2357 @param[in] HiiHandle The HII Handle of the form to update.
2358 @param[in] FormSetGuid The Formset GUID of the form to update. This
2359 is an optional parameter that may be NULL.
2360 If it is NULL, all FormSet will be updated.
2361 @param[in] FormId The ID of the form to update.
2362 @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR
2363 opcodes to be inserted or replaced in the form.
2364 The first IFR instruction in StartOpCodeHandle
2365 is used to find matching IFR opcode in the
2367 @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode
2368 that marks the end of a replace operation in
2369 the form. This is an optional parameter that
2370 may be NULL. If it is NULL, then an the IFR
2371 opcodes specified by StartOpCodeHandle are
2372 inserted into the form.
2374 @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated.
2375 @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND.
2376 1) The form specified by HiiHandle, FormSetGuid,
2377 and FormId could not be found in the HII Database.
2378 2) No IFR opcodes in the target form match the first
2379 IFR opcode in StartOpCodeHandle.
2380 3) EndOpCOde is not NULL, and no IFR opcodes in the
2381 target form following a matching start opcode match
2382 the first IFR opcode in EndOpCodeHandle.
2383 @retval EFI_SUCCESS The matched form is updated by StartOpcode.
2389 IN EFI_HII_HANDLE HiiHandle
,
2390 IN EFI_GUID
*FormSetGuid
, OPTIONAL
2391 IN EFI_FORM_ID FormId
,
2392 IN VOID
*StartOpcodeHandle
,
2393 IN VOID
*EndOpcodeHandle OPTIONAL
2397 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2398 UINT32 PackageListLength
;
2400 EFI_HII_PACKAGE_LIST_HEADER
*UpdatePackageList
;
2402 UINT8
*UpdateBufferPos
;
2403 EFI_HII_PACKAGE_HEADER
*Package
;
2404 EFI_HII_PACKAGE_HEADER
*TempPacakge
;
2405 EFI_HII_PACKAGE_HEADER PackageHeader
;
2407 HII_LIB_OPCODE_BUFFER
*OpCodeBufferStart
;
2408 HII_LIB_OPCODE_BUFFER
*OpCodeBufferEnd
;
2411 // Input update data can't be NULL.
2413 ASSERT (HiiHandle
!= NULL
);
2414 ASSERT (StartOpcodeHandle
!= NULL
);
2415 UpdatePackageList
= NULL
;
2417 HiiPackageList
= NULL
;
2420 // Restrive buffer data from Opcode Handle
2422 OpCodeBufferStart
= (HII_LIB_OPCODE_BUFFER
*) StartOpcodeHandle
;
2423 OpCodeBufferEnd
= (HII_LIB_OPCODE_BUFFER
*) EndOpcodeHandle
;
2426 // Get the orginal package list
2429 HiiPackageList
= NULL
;
2430 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
2432 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
2434 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2438 HiiPackageList
= AllocatePool (BufferSize
);
2439 if (HiiPackageList
== NULL
) {
2440 Status
= EFI_OUT_OF_RESOURCES
;
2444 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
2445 if (EFI_ERROR (Status
)) {
2450 // Calculate and allocate space for retrieval of IFR data
2452 BufferSize
+= OpCodeBufferStart
->Position
;
2453 UpdatePackageList
= AllocateZeroPool (BufferSize
);
2454 if (UpdatePackageList
== NULL
) {
2455 Status
= EFI_OUT_OF_RESOURCES
;
2460 // Allocate temp buffer to store the temp updated package buffer
2462 TempPacakge
= AllocateZeroPool (BufferSize
);
2463 if (TempPacakge
== NULL
) {
2464 Status
= EFI_OUT_OF_RESOURCES
;
2468 UpdateBufferPos
= (UINT8
*) UpdatePackageList
;
2471 // Copy the package list header
2473 CopyMem (UpdateBufferPos
, HiiPackageList
, sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
2474 UpdateBufferPos
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2477 // Go through each package to find the matched pacakge and update one by one
2480 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2481 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
2482 while (Offset
< PackageListLength
) {
2483 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
2484 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2485 Offset
+= Package
->Length
;
2487 if (Package
->Type
== EFI_HII_PACKAGE_FORMS
) {
2489 // Check this package is the matched package.
2491 Status
= InternalHiiUpdateFormPackageData (FormSetGuid
, FormId
, Package
, OpCodeBufferStart
, OpCodeBufferEnd
, TempPacakge
);
2493 // The matched package is found. Its pacakge buffer will be updated by the input new data.
2495 if (!EFI_ERROR(Status
)) {
2501 // Add updated package buffer
2503 Package
= TempPacakge
;
2508 // Add pacakge buffer
2510 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2511 CopyMem (UpdateBufferPos
, Package
, PackageHeader
.Length
);
2512 UpdateBufferPos
+= PackageHeader
.Length
;
2517 // Update package list length
2519 BufferSize
= UpdateBufferPos
- (UINT8
*) UpdatePackageList
;
2520 WriteUnaligned32 (&UpdatePackageList
->PackageLength
, (UINT32
) BufferSize
);
2523 // Update Pacakge to show form
2525 Status
= gHiiDatabase
->UpdatePackageList (gHiiDatabase
, HiiHandle
, UpdatePackageList
);
2528 // Not matched form is found and updated.
2530 Status
= EFI_NOT_FOUND
;
2534 if (HiiPackageList
!= NULL
) {
2535 FreePool (HiiPackageList
);
2538 if (UpdatePackageList
!= NULL
) {
2539 FreePool (UpdatePackageList
);
2542 if (TempPacakge
!= NULL
) {
2543 FreePool (TempPacakge
);
2550 Configure the buffer accrording to ConfigBody strings in the format of
2551 <Length:4 bytes>, <Offset: 2 bytes>, <Width:2 bytes>, <Data:n bytes>.
2552 This ConfigBody strings is generated by UEFI VfrCompiler for the default
2553 values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000
2554 constructed following this rule:
2555 "Vfr" + varstore.name + "Default" + defaultstore.attributes.
2556 Check the generated C file in Output for details.
2558 @param Buffer The start address of buffer.
2559 @param BufferSize The size of buffer.
2560 @param Number The number of the strings.
2561 @param ... Variable argument list for default value in <AltResp> format
2562 generated by the tool.
2564 @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
2565 @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
2566 @retval EFI_SUCCESS Operation successful.
2571 HiiIfrLibExtractDefault(
2573 IN UINTN
*BufferSize
,
2587 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
2588 return EFI_INVALID_PARAMETER
;
2595 VA_START (Args
, Number
);
2596 for (Index
= 0; Index
< Number
; Index
++) {
2597 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
2598 TotalLen
= ReadUnaligned32 ((UINT32
*)BufCfgArray
);
2599 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
2601 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
2602 Offset
= ReadUnaligned16 ((UINT16
*)BufferPos
);
2603 BufferPos
+= sizeof (UINT16
);
2604 Width
= ReadUnaligned16 ((UINT16
*)BufferPos
);
2605 BufferPos
+= sizeof (UINT16
);
2609 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
2610 return EFI_BUFFER_TOO_SMALL
;
2613 CopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
2618 *BufferSize
= (UINTN
)Offset
;