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 (
567 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
572 // Allocate the ResultsData buffer
574 ResultsData
= AllocateZeroPool (ResultsDataSize
);
575 if (ResultsData
== NULL
) {
581 // Retrieve or set the ResultsData from the Browser Callback
583 Status
= mUefiFormBrowser2
->BrowserCallback (
587 (BOOLEAN
)(SetResultsData
== NULL
),
591 if (EFI_ERROR (Status
)) {
599 Allocates and returns a Null-terminated Unicode <ConfigHdr> string using routing
600 information that includes a GUID, an optional Unicode string name, and a device
601 path. The string returned is allocated with AllocatePool(). The caller is
602 responsible for freeing the allocated string with FreePool().
604 The format of a <ConfigHdr> is as follows:
606 GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize<Null>
608 @param[in] Guid Pointer to an EFI_GUID that is the routing information
609 GUID. Each of the 16 bytes in Guid is converted to
610 a 2 Unicode character hexidecimal string. This is
611 an optional parameter that may be NULL.
612 @param[in] Name Pointer to a Null-terminated Unicode string that is
613 the routing information NAME. This is an optional
614 parameter that may be NULL. Each 16-bit Unicode
615 character in Name is converted to a 4 character Unicode
617 @param[in] DriverHandle The driver handle which supports a Device Path Protocol
618 that is the routing information PATH. Each byte of
619 the Device Path associated with DriverHandle is converted
620 to a 2 Unicode character hexidecimal string.
622 @retval NULL DriverHandle does not support the Device Path Protocol.
623 @retval Other A pointer to the Null-terminate Unicode <ConfigHdr> string
628 HiiConstructConfigHdr (
629 IN CONST EFI_GUID
*Guid
, OPTIONAL
630 IN CONST CHAR16
*Name
, OPTIONAL
631 IN EFI_HANDLE DriverHandle
635 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
636 UINTN DevicePathSize
;
638 CHAR16
*ReturnString
;
643 // Compute the length of Name in Unicode characters.
644 // If Name is NULL, then the length is 0.
648 NameLength
= StrLen (Name
);
654 // Retrieve DevicePath Protocol associated with DriverHandle
656 if (DriverHandle
!= NULL
) {
657 DevicePath
= DevicePathFromHandle (DriverHandle
);
658 if (DevicePath
== NULL
) {
662 // Compute the size of the device path in bytes
664 DevicePathSize
= GetDevicePathSize (DevicePath
);
668 // GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize <Null>
669 // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 |
671 String
= AllocateZeroPool ((5 + sizeof (EFI_GUID
) * 2 + 6 + NameLength
* 4 + 6 + DevicePathSize
* 2 + 1) * sizeof (CHAR16
));
672 if (String
== NULL
) {
677 // Start with L"GUID="
679 ReturnString
= StrCpy (String
, L
"GUID=");
680 String
+= StrLen (String
);
684 // Append Guid converted to <HexCh>32
686 for (Index
= 0, Buffer
= (UINT8
*)Guid
; Index
< sizeof (EFI_GUID
); Index
++) {
687 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(Buffer
++), 2);
694 StrCpy (String
, L
"&NAME=");
695 String
+= StrLen (String
);
699 // Append Name converted to <Char>NameLength
701 for (; *Name
!= L
'\0'; Name
++) {
702 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *Name
, 4);
709 StrCpy (String
, L
"&PATH=");
710 String
+= StrLen (String
);
713 // Append the device path associated with DriverHandle converted to <HexChar>DevicePathSize
715 for (Index
= 0, Buffer
= (UINT8
*)DevicePath
; Index
< DevicePathSize
; Index
++) {
716 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(Buffer
++), 2);
720 // Null terminate the Unicode string
725 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
727 return InternalHiiLowerConfigString (ReturnString
);
731 Allocates and returns a Null-terminated Unicode <ConfigAltResp> string.
733 If Guid is NULL, then ASSERT().
734 If Name is NULL, then ASSERT().
735 If BlockNameArray is NULL, then ASSERT().
737 @param[in] Guid GUID of the buffer storage.
738 @param[in] Name Name of the buffer storage.
739 @param[in] DriverHandle The DriverHandle that support a Device Path
741 @param[in] BufferStorage Content of the buffer storage.
742 @param[in] BufferStorageSize Length in bytes of the buffer storage.
743 @param[in] BlockNameArray Array generated by VFR compiler. This array
744 contains a UINT32 value that is the length
745 of BlockNameArray in bytes, followed by pairs
746 of 16-bit values that are the offset and length
747 values used to contruct a <ConfigRequest> string.
748 @param[in] ... A variable argument list that contains pairs of 16-bit
749 ALTCFG identifiers and pointers to DefaultValueArrays.
750 The variable argument list is terminated by a NULL
751 DefaultValueArray pointer. A DefaultValueArray
752 contains a UINT32 value that is the length, in bytes,
753 of the DefaultValueArray. The UINT32 length value
754 is followed by a series of records that contain
755 a 16-bit WIDTH value followed by a byte array with
756 WIDTH entries. The records must be parsed from
757 beginning to end until the UINT32 length limit
760 @retval NULL There are not enough resources to process the request.
761 @retval NULL A <ConfigResp> could not be retrieved from the Config
763 @retval Other A pointer to the Null-terminate Unicode <ConfigAltResp>
769 HiiConstructConfigAltResp (
770 IN CONST EFI_GUID
*Guid
,
771 IN CONST CHAR16
*Name
,
772 IN EFI_HANDLE DriverHandle
,
773 IN CONST VOID
*BufferStorage
,
774 IN UINTN BufferStorageSize
,
775 IN CONST VOID
*BlockNameArray
,
784 CHAR16
*ConfigRequest
;
785 EFI_STRING ConfigResp
;
786 EFI_STRING ConfigAltResp
;
793 ASSERT (Guid
!= NULL
);
794 ASSERT (Name
!= NULL
);
795 ASSERT (BlockNameArray
!= NULL
);
798 // Initialize local variables
801 ConfigRequest
= NULL
;
805 // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
807 ConfigHdr
= HiiConstructConfigHdr (Guid
, Name
, DriverHandle
);
808 if (ConfigHdr
== NULL
) {
813 // Compute the length of the entire request starting with <ConfigHdr> and a
816 Length
= StrLen (ConfigHdr
) + 1;
819 // Determine the size <BlockName> Offset/Width pairs
821 Buffer
= (UINT8
*)BlockNameArray
;
822 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
823 Buffer
+= sizeof (UINT32
);
826 // Add <BlockName> length that is composed of one or more Offset/Width pairs
828 // <BlockName> ::= &OFFSET=1234&WIDTH=1234
831 Length
+= (((BufferEnd
- Buffer
) / (sizeof (UINT16
) + sizeof (UINT16
))) * (8 + 4 + 7 + 4));
834 // Allocate buffer for the entire <ConfigRequest>
836 ConfigRequest
= AllocateZeroPool (Length
* sizeof (CHAR16
));
837 if (ConfigRequest
== NULL
) {
840 String
= ConfigRequest
;
843 // Start with <ConfigHdr>
845 StrCpy (String
, ConfigHdr
);
846 String
+= StrLen (String
);
849 // Loop through all the Offset/Width pairs and append them to ConfigRequest
851 while (Buffer
< BufferEnd
) {
853 // Append &OFFSET=XXXX&WIDTH=YYYY
855 OffsetValue
= ReadUnaligned16 ((UINT16
*)Buffer
);
856 WidthValue
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
859 (8 + 4 + 7 + 4) * sizeof (CHAR16
),
860 L
"&OFFSET=%04X&WIDTH=%04X",
865 String
+= StrLen (String
);
866 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
));
870 // Get the <ConfigResp>
872 ConfigResp
= InternalHiiBlockToConfig (ConfigRequest
, BufferStorage
, BufferStorageSize
);
873 if (ConfigResp
== NULL
) {
878 // Compute the length of the entire response starting with <ConfigResp> and a
881 Length
= StrLen (ConfigResp
) + 1;
884 // Add the length associated with each pair of variable argument parameters
886 VA_START (Args
, BlockNameArray
);
888 AltCfgId
= VA_ARG (Args
, UINT16
);
889 Buffer
= VA_ARG (Args
, UINT8
*);
890 if (Buffer
== NULL
) {
895 // Add length for "&<ConfigHdr>&ALTCFG=XXXX"
896 // |1| StrLen (ConfigHdr) | 8 | 4 |
898 Length
+= (1 + StrLen (ConfigHdr
) + 8 + 4);
900 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
901 Buffer
+= sizeof (UINT32
);
902 while (Buffer
< BufferEnd
) {
904 // Extract Width field
906 Width
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
909 // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"
910 // | 8 | 4 | 7 | 4 | 7 | Width * 2 |
912 Length
+= (8 + 4 + 7 + 4 + 7 + Width
* 2);
915 // Update Buffer to the next record
917 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
) + Width
);
923 // Allocate a buffer for the entire response
925 ConfigAltResp
= AllocateZeroPool (Length
* sizeof (CHAR16
));
926 if (ConfigAltResp
== NULL
) {
929 String
= ConfigAltResp
;
934 StrCpy (String
, ConfigResp
);
935 String
+= StrLen (String
);
938 // Add <AltResp> for each pair of variable argument parameters
940 VA_START (Args
, BlockNameArray
);
942 AltCfgId
= VA_ARG (Args
, UINT16
);
943 Buffer
= VA_ARG (Args
, UINT8
*);
944 if (Buffer
== NULL
) {
949 // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX"
950 // |1| StrLen (ConfigHdr) | 8 | 4 |
954 (1 + StrLen (ConfigHdr
) + 8 + 4) * sizeof (CHAR16
),
959 String
+= StrLen (String
);
962 // Add <ConfigBody> ::= <ConfigElement>*
964 BufferEnd
= Buffer
+ ReadUnaligned32 ((UINT32
*)Buffer
);
965 Buffer
+= sizeof (UINT32
);
966 while (Buffer
< BufferEnd
) {
968 // Extract Width field
970 Width
= ReadUnaligned16 ((UINT16
*)(Buffer
+ sizeof (UINT16
)));
977 (8 + 4 + 7 + 4 + 7 + Width
* 2) * sizeof (CHAR16
),
978 L
"&OFFSET=%04X&WIDTH=%04X&VALUE=",
979 ReadUnaligned16 ((UINT16
*)Buffer
),
982 String
+= StrLen (String
);
985 // Update Buffer to point to the value in the current record
987 Buffer
+= (sizeof (UINT16
) + sizeof (UINT16
));
990 // Convert Value to a hex string in "%x" format
991 // NOTE: This is in the opposite byte that GUID and PATH use
993 for (; Width
> 0; Width
--) {
994 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, Buffer
[Width
- 1], 2);
997 // Update Buffer to the next record
1005 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
1007 return InternalHiiLowerConfigString (ConfigAltResp
);
1010 if (ConfigHdr
!= NULL
) {
1011 FreePool (ConfigHdr
);
1013 if (ConfigRequest
!= NULL
) {
1014 FreePool (ConfigRequest
);
1016 if (ConfigResp
!= NULL
) {
1017 FreePool (ConfigResp
);
1024 Determines if two values in config strings match.
1026 Compares the substring between StartSearchString and StopSearchString in
1027 FirstString to the substring between StartSearchString and StopSearchString
1028 in SecondString. If the two substrings match, then TRUE is returned. If the
1029 two substrings do not match, then FALSE is returned.
1031 If FirstString is NULL, then ASSERT().
1032 If SecondString is NULL, then ASSERT().
1033 If StartSearchString is NULL, then ASSERT().
1034 If StopSearchString is NULL, then ASSERT().
1036 @param FirstString Pointer to the first Null-terminated Unicode string.
1037 @param SecondString Pointer to the second Null-terminated Unicode string.
1038 @param StartSearchString Pointer to the Null-terminated Unicode string that
1039 marks the start of the value string to compare.
1040 @param StopSearchString Pointer to the Null-terminated Unicode string that
1041 marks the end of the vakue string to compare.
1043 @retval FALSE StartSearchString is not present in FirstString.
1044 @retval FALSE StartSearchString is not present in SecondString.
1045 @retval FALSE StopSearchString is not present in FirstString.
1046 @retval FALSE StopSearchString is not present in SecondString.
1047 @retval FALSE The length of the substring in FirstString is not the
1048 same length as the substring in SecondString.
1049 @retval FALSE The value string in FirstString does not matche the
1050 value string in SecondString.
1051 @retval TRUE The value string in FirstString matches the value
1052 string in SecondString.
1057 InternalHiiCompareSubString (
1058 IN CHAR16
*FirstString
,
1059 IN CHAR16
*SecondString
,
1060 IN CHAR16
*StartSearchString
,
1061 IN CHAR16
*StopSearchString
1064 CHAR16
*EndFirstString
;
1065 CHAR16
*EndSecondString
;
1067 ASSERT (FirstString
!= NULL
);
1068 ASSERT (SecondString
!= NULL
);
1069 ASSERT (StartSearchString
!= NULL
);
1070 ASSERT (StopSearchString
!= NULL
);
1072 FirstString
= StrStr (FirstString
, StartSearchString
);
1073 if (FirstString
== NULL
) {
1077 SecondString
= StrStr (SecondString
, StartSearchString
);
1078 if (SecondString
== NULL
) {
1082 EndFirstString
= StrStr (FirstString
, StopSearchString
);
1083 if (EndFirstString
== NULL
) {
1087 EndSecondString
= StrStr (SecondString
, StopSearchString
);
1088 if (EndSecondString
== NULL
) {
1092 if ((EndFirstString
- FirstString
) != (EndSecondString
- SecondString
)) {
1096 return (BOOLEAN
)(StrnCmp (FirstString
, SecondString
, EndFirstString
- FirstString
) == 0);
1100 Determines if the routing data specified by GUID and NAME match a <ConfigHdr>.
1102 If ConfigHdr is NULL, then ASSERT().
1104 @param[in] ConfigHdr Either <ConfigRequest> or <ConfigResp>.
1105 @param[in] Guid GUID of the storage.
1106 @param[in] Name NAME of the storage.
1108 @retval TRUE Routing information matches <ConfigHdr>.
1109 @retval FALSE Routing information does not match <ConfigHdr>.
1114 HiiIsConfigHdrMatch (
1115 IN CONST EFI_STRING ConfigHdr
,
1116 IN CONST EFI_GUID
*Guid
, OPTIONAL
1117 IN CONST CHAR16
*Name OPTIONAL
1120 EFI_STRING CompareConfigHdr
;
1123 ASSERT (ConfigHdr
!= NULL
);
1126 // Use Guid and Name to generate a <ConfigHdr> string
1128 CompareConfigHdr
= HiiConstructConfigHdr (Guid
, Name
, NULL
);
1129 if (CompareConfigHdr
== NULL
) {
1136 // Compare GUID value strings
1138 Result
= InternalHiiCompareSubString (ConfigHdr
, CompareConfigHdr
, L
"GUID=", L
"&NAME=");
1141 if (Result
&& Name
!= NULL
) {
1143 // Compare NAME value strings
1145 Result
= InternalHiiCompareSubString (ConfigHdr
, CompareConfigHdr
, L
"&NAME=", L
"&PATH=");
1149 // Free the <ConfigHdr> string
1151 FreePool (CompareConfigHdr
);
1157 Retrieves uncommited data from the Form Browser and converts it to a binary
1158 buffer. The returned buffer is allocated using AllocatePool(). The caller
1159 is responsible for freeing the returned buffer using FreePool().
1161 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
1162 is an optional parameter that may be NULL.
1163 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
1164 parameter that may be NULL.
1165 @param[in] BufferSize Length in bytes of buffer to hold retrived data.
1167 @retval NULL The uncommitted data could not be retrieved.
1168 @retval Other A pointer to a buffer containing the uncommitted data.
1174 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
1175 IN CONST CHAR16
*VariableName
, OPTIONAL
1179 EFI_STRING ResultsData
;
1181 EFI_STRING ConfigResp
;
1185 // Retrieve the results data from the Browser Callback
1187 ResultsData
= InternalHiiBrowserCallback (VariableGuid
, VariableName
, NULL
);
1188 if (ResultsData
== NULL
) {
1193 // Construct <ConfigResp> mConfigHdrTemplate L'&' ResultsData L'\0'
1195 Size
= (StrLen (mConfigHdrTemplate
) + 1) * sizeof (CHAR16
);
1196 Size
= Size
+ (StrLen (ResultsData
) + 1) * sizeof (CHAR16
);
1197 ConfigResp
= AllocateZeroPool (Size
);
1198 UnicodeSPrint (ConfigResp
, Size
, L
"%s&%s", mConfigHdrTemplate
, ResultsData
);
1201 // Free the allocated buffer
1203 FreePool (ResultsData
);
1204 if (ConfigResp
== NULL
) {
1209 // Convert <ConfigResp> to a buffer
1211 Block
= InternalHiiConfigToBlock (ConfigResp
, BlockSize
);
1212 FreePool (ConfigResp
);
1218 Updates uncommitted data in the Form Browser.
1220 If Buffer is NULL, then ASSERT().
1222 @param[in] VariableName Pointer to a Null-terminated Unicode string. This
1223 is an optional parameter that may be NULL.
1224 @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
1225 parameter that may be NULL.
1226 @param[in] BufferSize Length, in bytes, of Buffer.
1227 @param[in] Buffer Buffer of data to commit.
1228 @param[in] RequestElement An optional field to specify which part of the
1229 buffer data will be send back to Browser. If NULL,
1230 the whole buffer of data will be committed to
1232 <RequestElement> ::= &OFFSET=<Number>&WIDTH=<Number>*
1234 @retval FALSE The uncommitted data could not be updated.
1235 @retval TRUE The uncommitted data was updated.
1241 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
1242 IN CONST CHAR16
*VariableName
, OPTIONAL
1243 IN UINTN BufferSize
,
1244 IN CONST UINT8
*Buffer
,
1245 IN CONST CHAR16
*RequestElement OPTIONAL
1249 EFI_STRING ConfigRequest
;
1250 EFI_STRING ConfigResp
;
1251 EFI_STRING ResultsData
;
1253 ASSERT (Buffer
!= NULL
);
1256 // Construct <ConfigRequest>
1258 if (RequestElement
== NULL
) {
1260 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1261 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1263 Size
= (StrLen (mConfigHdrTemplate
) + 32 + 1) * sizeof (CHAR16
);
1264 ConfigRequest
= AllocateZeroPool (Size
);
1265 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", mConfigHdrTemplate
, (UINT64
)BufferSize
);
1268 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1269 // followed by <RequestElement> followed by a Null-terminator
1271 Size
= StrLen (mConfigHdrTemplate
) * sizeof (CHAR16
);
1272 Size
= Size
+ (StrLen (RequestElement
) + 1) * sizeof (CHAR16
);
1273 ConfigRequest
= AllocateZeroPool (Size
);
1274 UnicodeSPrint (ConfigRequest
, Size
, L
"%s%s", mConfigHdrTemplate
, RequestElement
);
1276 if (ConfigRequest
== NULL
) {
1281 // Convert <ConfigRequest> to <ConfigResp>
1283 ConfigResp
= InternalHiiBlockToConfig (ConfigRequest
, Buffer
, BufferSize
);
1284 FreePool (ConfigRequest
);
1285 if (ConfigResp
== NULL
) {
1290 // Set data in the uncommitted browser state information
1292 ResultsData
= InternalHiiBrowserCallback (VariableGuid
, VariableName
, ConfigResp
+ StrLen(mConfigHdrTemplate
) + 1);
1293 FreePool (ConfigResp
);
1295 return (BOOLEAN
)(ResultsData
!= NULL
);
1298 /////////////////////////////////////////
1299 /////////////////////////////////////////
1301 /////////////////////////////////////////
1302 /////////////////////////////////////////
1304 #define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200
1310 } HII_LIB_OPCODE_BUFFER
;
1313 /// Lookup table that converts EFI_IFR_TYPE_X enum values to a width in bytes
1315 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth
[] = {
1316 1, // EFI_IFR_TYPE_NUM_SIZE_8
1317 2, // EFI_IFR_TYPE_NUM_SIZE_16
1318 4, // EFI_IFR_TYPE_NUM_SIZE_32
1319 8, // EFI_IFR_TYPE_NUM_SIZE_64
1320 1, // EFI_IFR_TYPE_BOOLEAN
1321 3, // EFI_IFR_TYPE_TIME
1322 4, // EFI_IFR_TYPE_DATE
1323 2 // EFI_IFR_TYPE_STRING
1327 Allocates and returns a new OpCode Handle. OpCode Handles must be freed with
1328 HiiFreeOpCodeHandle().
1330 @retval NULL There are not enough resources to allocate a new OpCode Handle.
1331 @retval Other A new OpCode handle.
1336 HiiAllocateOpCodeHandle (
1340 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1342 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)AllocatePool (sizeof (HII_LIB_OPCODE_BUFFER
));
1343 if (OpCodeBuffer
== NULL
) {
1346 OpCodeBuffer
->Buffer
= (UINT8
*)AllocatePool (HII_LIB_OPCODE_ALLOCATION_SIZE
);
1347 if (OpCodeBuffer
->Buffer
== NULL
) {
1348 FreePool (OpCodeBuffer
);
1351 OpCodeBuffer
->BufferSize
= HII_LIB_OPCODE_ALLOCATION_SIZE
;
1352 OpCodeBuffer
->Position
= 0;
1353 return (VOID
*)OpCodeBuffer
;
1357 Frees an OpCode Handle that was peviously allocated with HiiAllocateOpCodeHandle().
1358 When an OpCode Handle is freed, all of the opcodes associated with the OpCode
1359 Handle are also freed.
1361 If OpCodeHandle is NULL, then ASSERT().
1366 HiiFreeOpCodeHandle (
1370 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1372 ASSERT (OpCodeHandle
!= NULL
);
1374 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
;
1375 if (OpCodeBuffer
->Buffer
!= NULL
) {
1376 FreePool (OpCodeBuffer
->Buffer
);
1378 FreePool (OpCodeBuffer
);
1383 InternalHiiOpCodeHandlePosition (
1384 IN VOID
*OpCodeHandle
1387 return ((HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
)->Position
;
1392 InternalHiiOpCodeHandleBuffer (
1393 IN VOID
*OpCodeHandle
1396 return ((HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
)->Buffer
;
1401 InternalHiiGrowOpCodeHandle (
1406 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
1409 ASSERT (OpCodeHandle
!= NULL
);
1411 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
;
1412 if (OpCodeBuffer
->Position
+ Size
> OpCodeBuffer
->BufferSize
) {
1413 Buffer
= ReallocatePool (
1414 OpCodeBuffer
->BufferSize
,
1415 OpCodeBuffer
->BufferSize
+ (Size
+ HII_LIB_OPCODE_ALLOCATION_SIZE
),
1416 OpCodeBuffer
->Buffer
1418 if (Buffer
== NULL
) {
1421 OpCodeBuffer
->Buffer
= Buffer
;
1422 OpCodeBuffer
->BufferSize
+= (Size
+ HII_LIB_OPCODE_ALLOCATION_SIZE
);
1424 Buffer
= OpCodeBuffer
->Buffer
+ OpCodeBuffer
->Position
;
1425 OpCodeBuffer
->Position
+= Size
;
1431 InternalHiiCreateOpCodeExtended (
1432 IN VOID
*OpCodeHandle
,
1433 IN VOID
*OpCodeTemplate
,
1435 IN UINTN OpCodeSize
,
1436 IN UINTN ExtensionSize
,
1440 EFI_IFR_OP_HEADER
*Header
;
1443 ASSERT (OpCodeTemplate
!= NULL
);
1444 ASSERT ((OpCodeSize
+ ExtensionSize
) <= 0x7F);
1446 Header
= (EFI_IFR_OP_HEADER
*)OpCodeTemplate
;
1447 Header
->OpCode
= OpCode
;
1448 Header
->Scope
= Scope
;
1449 Header
->Length
= (UINT8
)(OpCodeSize
+ ExtensionSize
);
1450 Buffer
= InternalHiiGrowOpCodeHandle (OpCodeHandle
, Header
->Length
);
1451 return (UINT8
*)CopyMem (Buffer
, Header
, OpCodeSize
);
1456 InternalHiiCreateOpCode (
1457 IN VOID
*OpCodeHandle
,
1458 IN VOID
*OpCodeTemplate
,
1463 return InternalHiiCreateOpCodeExtended (OpCodeHandle
, OpCodeTemplate
, OpCode
, OpCodeSize
, 0, 0);
1467 Append raw opcodes to an OpCodeHandle.
1469 If OpCodeHandle is NULL, then ASSERT().
1470 If RawBuffer is NULL, then ASSERT();
1472 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1473 @param[in] RawBuffer Buffer of opcodes to append.
1474 @param[in] RawBufferSize The size, in bytes, of Buffer.
1476 @retval NULL There is not enough space left in Buffer to add the opcode.
1477 @retval Other A pointer to the appended opcodes.
1482 InternalHiiCreateRawOpCodes (
1483 IN VOID
*OpCodeHandle
,
1484 IN UINT8
*RawBuffer
,
1485 IN UINTN RawBufferSize
1490 ASSERT (RawBuffer
!= NULL
);
1492 Buffer
= InternalHiiGrowOpCodeHandle (OpCodeHandle
, RawBufferSize
);
1493 return (UINT8
*)CopyMem (Buffer
, RawBuffer
, RawBufferSize
);
1497 Append opcodes from one OpCode Handle to another OpCode handle.
1499 If OpCodeHandle is NULL, then ASSERT().
1500 If RawOpCodeHandle is NULL, then ASSERT();
1502 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1503 @param[in] RawOpCodeHandle Handle to the buffer of opcodes.
1505 @retval NULL There is not enough space left in Buffer to add the opcode.
1506 @retval Other A pointer to the appended opcodes.
1511 InternalHiiAppendOpCodes (
1512 IN VOID
*OpCodeHandle
,
1513 IN VOID
*RawOpCodeHandle
1516 HII_LIB_OPCODE_BUFFER
*RawOpCodeBuffer
;
1518 ASSERT (RawOpCodeHandle
!= NULL
);
1520 RawOpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)RawOpCodeHandle
;
1521 return InternalHiiCreateRawOpCodes (OpCodeHandle
, RawOpCodeBuffer
->Buffer
, RawOpCodeBuffer
->Position
);
1525 Create EFI_IFR_END_OP opcode.
1527 If OpCodeHandle is NULL, then ASSERT().
1529 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1531 @retval NULL There is not enough space left in Buffer to add the opcode.
1532 @retval Other A pointer to the created opcode.
1537 HiiCreateEndOpCode (
1538 IN VOID
*OpCodeHandle
1543 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_END_OP
, sizeof (OpCode
));
1547 Create EFI_IFR_ONE_OF_OPTION_OP opcode.
1549 If OpCodeHandle is NULL, then ASSERT().
1550 If Type is invalid, then ASSERT().
1551 If Flags is invalid, then ASSERT().
1553 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1554 @param[in] StringId StringId for the option
1555 @param[in] Flags Flags for the option
1556 @param[in] Type Type for the option
1557 @param[in] Value Value for the option
1559 @retval NULL There is not enough space left in Buffer to add the opcode.
1560 @retval Other A pointer to the created opcode.
1565 HiiCreateOneOfOptionOpCode (
1566 IN VOID
*OpCodeHandle
,
1573 EFI_IFR_ONE_OF_OPTION OpCode
;
1575 ASSERT (Type
< EFI_IFR_TYPE_OTHER
);
1577 ZeroMem (&OpCode
, sizeof (OpCode
));
1578 OpCode
.Option
= StringId
;
1579 OpCode
.Flags
= (UINT8
) (Flags
& (EFI_IFR_OPTION_DEFAULT
| EFI_IFR_OPTION_DEFAULT_MFG
));
1581 CopyMem (&OpCode
.Value
, &Value
, mHiiDefaultTypeToWidth
[Type
]);
1583 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_ONE_OF_OPTION_OP
, sizeof (OpCode
));
1587 Create EFI_IFR_DEFAULT_OP opcode.
1589 If OpCodeHandle is NULL, then ASSERT().
1590 If Type is invalid, then ASSERT().
1592 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1593 @param[in] DefaultId DefaultId for the default
1594 @param[in] Type Type for the default
1595 @param[in] Value Value for the default
1597 @retval NULL There is not enough space left in Buffer to add the opcode.
1598 @retval Other A pointer to the created opcode.
1603 HiiCreateDefaultOpCode (
1604 IN VOID
*OpCodeHandle
,
1605 IN UINT16 DefaultId
,
1610 EFI_IFR_DEFAULT OpCode
;
1612 ASSERT (Type
< EFI_IFR_TYPE_OTHER
);
1614 ZeroMem (&OpCode
, sizeof (OpCode
));
1616 OpCode
.DefaultId
= DefaultId
;
1617 CopyMem (&OpCode
.Value
, &Value
, mHiiDefaultTypeToWidth
[Type
]);
1619 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_DEFAULT_OP
, sizeof (OpCode
));
1623 Create EFI_IFR_GUID opcode.
1625 If OpCodeHandle is NULL, then ASSERT().
1626 If Guid is NULL, then ASSERT().
1627 If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT().
1629 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1630 @param[in] Guid Pointer to EFI_GUID of this guided opcode.
1631 @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an
1632 optional parameter that may be NULL. If this
1633 parameter is NULL, then the GUID extension
1634 region of the created opcode is filled with zeros.
1635 If this parameter is not NULL, then the GUID
1636 extension region of GuidData will be copied to
1637 the GUID extension region of the created opcode.
1638 @param[in] OpCodeSize The size, in bytes, of created opcode. This value
1639 must be >= sizeof(EFI_IFR_GUID).
1641 @retval NULL There is not enough space left in Buffer to add the opcode.
1642 @retval Other A pointer to the created opcode.
1647 HiiCreateGuidOpCode (
1648 IN VOID
*OpCodeHandle
,
1649 IN CONST EFI_GUID
*Guid
,
1650 IN CONST VOID
*GuidOpCode
, OPTIONAL
1654 EFI_IFR_GUID OpCode
;
1655 EFI_IFR_GUID
*OpCodePointer
;
1657 ASSERT (Guid
!= NULL
);
1658 ASSERT (OpCodeSize
>= sizeof (OpCode
));
1660 ZeroMem (&OpCode
, sizeof (OpCode
));
1661 CopyGuid ((EFI_GUID
*)(VOID
*)&OpCode
.Guid
, Guid
);
1663 OpCodePointer
= (EFI_IFR_GUID
*)InternalHiiCreateOpCodeExtended (
1668 OpCodeSize
- sizeof (OpCode
),
1671 if (OpCodePointer
!= NULL
&& GuidOpCode
!= NULL
) {
1672 CopyMem (OpCodePointer
+ 1, (EFI_IFR_GUID
*)GuidOpCode
+ 1, OpCodeSize
- sizeof (OpCode
));
1674 return (UINT8
*)OpCodePointer
;
1678 Create EFI_IFR_ACTION_OP opcode.
1680 If OpCodeHandle is NULL, then ASSERT().
1681 If any reserved bits are set in QuestionFlags, then ASSERT().
1683 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1684 @param[in] QuestionId Question ID
1685 @param[in] Prompt String ID for Prompt
1686 @param[in] Help String ID for Help
1687 @param[in] QuestionFlags Flags in Question Header
1688 @param[in] QuestionConfig String ID for configuration
1690 @retval NULL There is not enough space left in Buffer to add the opcode.
1691 @retval Other A pointer to the created opcode.
1696 HiiCreateActionOpCode (
1697 IN VOID
*OpCodeHandle
,
1698 IN EFI_QUESTION_ID QuestionId
,
1699 IN EFI_STRING_ID Prompt
,
1700 IN EFI_STRING_ID Help
,
1701 IN UINT8 QuestionFlags
,
1702 IN EFI_STRING_ID QuestionConfig
1705 EFI_IFR_ACTION OpCode
;
1707 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1709 ZeroMem (&OpCode
, sizeof (OpCode
));
1710 OpCode
.Question
.QuestionId
= QuestionId
;
1711 OpCode
.Question
.Header
.Prompt
= Prompt
;
1712 OpCode
.Question
.Header
.Help
= Help
;
1713 OpCode
.Question
.Flags
= QuestionFlags
;
1714 OpCode
.QuestionConfig
= QuestionConfig
;
1716 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_ACTION_OP
, sizeof (OpCode
));
1720 Create EFI_IFR_SUBTITLE_OP opcode.
1722 If OpCodeHandle is NULL, then ASSERT().
1723 If any reserved bits are set in Flags, then ASSERT().
1724 If Scope > 1, then ASSERT().
1726 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1727 @param[in] Prompt String ID for Prompt
1728 @param[in] Help String ID for Help
1729 @param[in] Flags Subtitle opcode flags
1730 @param[in] Scope 1 if this opcpde is the beginning of a new scope.
1731 0 if this opcode is within the current scope.
1733 @retval NULL There is not enough space left in Buffer to add the opcode.
1734 @retval Other A pointer to the created opcode.
1739 HiiCreateSubTitleOpCode (
1740 IN VOID
*OpCodeHandle
,
1741 IN EFI_STRING_ID Prompt
,
1742 IN EFI_STRING_ID Help
,
1747 EFI_IFR_SUBTITLE OpCode
;
1749 ASSERT (Scope
<= 1);
1750 ASSERT ((Flags
& (~(EFI_IFR_FLAGS_HORIZONTAL
))) == 0);
1752 ZeroMem (&OpCode
, sizeof (OpCode
));
1753 OpCode
.Statement
.Prompt
= Prompt
;
1754 OpCode
.Statement
.Help
= Help
;
1755 OpCode
.Flags
= Flags
;
1757 return InternalHiiCreateOpCodeExtended (
1760 EFI_IFR_SUBTITLE_OP
,
1768 Create EFI_IFR_REF_OP opcode.
1770 If OpCodeHandle is NULL, then ASSERT().
1771 If any reserved bits are set in QuestionFlags, then ASSERT().
1773 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1774 @param[in] FormId Destination Form ID
1775 @param[in] Prompt String ID for Prompt
1776 @param[in] Help String ID for Help
1777 @param[in] QuestionFlags Flags in Question Header
1778 @param[in] QuestionId Question ID
1780 @retval NULL There is not enough space left in Buffer to add the opcode.
1781 @retval Other A pointer to the created opcode.
1786 HiiCreateGotoOpCode (
1787 IN VOID
*OpCodeHandle
,
1788 IN EFI_FORM_ID FormId
,
1789 IN EFI_STRING_ID Prompt
,
1790 IN EFI_STRING_ID Help
,
1791 IN UINT8 QuestionFlags
,
1792 IN EFI_QUESTION_ID QuestionId
1797 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1799 ZeroMem (&OpCode
, sizeof (OpCode
));
1800 OpCode
.Question
.Header
.Prompt
= Prompt
;
1801 OpCode
.Question
.Header
.Help
= Help
;
1802 OpCode
.Question
.QuestionId
= QuestionId
;
1803 OpCode
.Question
.Flags
= QuestionFlags
;
1804 OpCode
.FormId
= FormId
;
1806 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_REF_OP
, sizeof (OpCode
));
1810 Create EFI_IFR_CHECKBOX_OP opcode.
1812 If OpCodeHandle is NULL, then ASSERT().
1813 If any reserved bits are set in QuestionFlags, then ASSERT().
1814 If any reserved bits are set in CheckBoxFlags, then ASSERT().
1816 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1817 @param[in] QuestionId Question ID
1818 @param[in] VarStoreId Storage ID
1819 @param[in] VarOffset Offset in Storage
1820 @param[in] Prompt String ID for Prompt
1821 @param[in] Help String ID for Help
1822 @param[in] QuestionFlags Flags in Question Header
1823 @param[in] CheckBoxFlags Flags for checkbox opcode
1824 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
1825 is an optional parameter that may be NULL.
1827 @retval NULL There is not enough space left in Buffer to add the opcode.
1828 @retval Other A pointer to the created opcode.
1833 HiiCreateCheckBoxOpCode (
1834 IN VOID
*OpCodeHandle
,
1835 IN EFI_QUESTION_ID QuestionId
,
1836 IN EFI_VARSTORE_ID VarStoreId
,
1837 IN UINT16 VarOffset
,
1838 IN EFI_STRING_ID Prompt
,
1839 IN EFI_STRING_ID Help
,
1840 IN UINT8 QuestionFlags
,
1841 IN UINT8 CheckBoxFlags
,
1842 IN VOID
*DefaultsOpCodeHandle OPTIONAL
1845 EFI_IFR_CHECKBOX OpCode
;
1848 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1850 ZeroMem (&OpCode
, sizeof (OpCode
));
1851 OpCode
.Question
.QuestionId
= QuestionId
;
1852 OpCode
.Question
.VarStoreId
= VarStoreId
;
1853 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
1854 OpCode
.Question
.Header
.Prompt
= Prompt
;
1855 OpCode
.Question
.Header
.Help
= Help
;
1856 OpCode
.Question
.Flags
= QuestionFlags
;
1857 OpCode
.Flags
= CheckBoxFlags
;
1859 if (DefaultsOpCodeHandle
== NULL
) {
1860 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_CHECKBOX_OP
, sizeof (OpCode
));
1863 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
1864 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_CHECKBOX_OP
, sizeof (OpCode
), 0, 1);
1865 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
1866 HiiCreateEndOpCode (OpCodeHandle
);
1867 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
1871 Create EFI_IFR_NUMERIC_OP opcode.
1873 If OpCodeHandle is NULL, then ASSERT().
1874 If any reserved bits are set in QuestionFlags, then ASSERT().
1875 If any reserved bits are set in NumericFlags, then ASSERT().
1877 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1878 @param[in] QuestionId Question ID
1879 @param[in] VarStoreId Storage ID
1880 @param[in] VarOffset Offset in Storage
1881 @param[in] Prompt String ID for Prompt
1882 @param[in] Help String ID for Help
1883 @param[in] QuestionFlags Flags in Question Header
1884 @param[in] NumericFlags Flags for numeric opcode
1885 @param[in] Minimum Numeric minimum value
1886 @param[in] Maximum Numeric maximum value
1887 @param[in] Step Numeric step for edit
1888 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
1889 is an optional parameter that may be NULL.
1891 @retval NULL There is not enough space left in Buffer to add the opcode.
1892 @retval Other A pointer to the created opcode.
1897 HiiCreateNumericOpCode (
1898 IN VOID
*OpCodeHandle
,
1899 IN EFI_QUESTION_ID QuestionId
,
1900 IN EFI_VARSTORE_ID VarStoreId
,
1901 IN UINT16 VarOffset
,
1902 IN EFI_STRING_ID Prompt
,
1903 IN EFI_STRING_ID Help
,
1904 IN UINT8 QuestionFlags
,
1905 IN UINT8 NumericFlags
,
1909 IN VOID
*DefaultsOpCodeHandle OPTIONAL
1912 EFI_IFR_NUMERIC OpCode
;
1915 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
1917 ZeroMem (&OpCode
, sizeof (OpCode
));
1918 OpCode
.Question
.QuestionId
= QuestionId
;
1919 OpCode
.Question
.VarStoreId
= VarStoreId
;
1920 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
1921 OpCode
.Question
.Header
.Prompt
= Prompt
;
1922 OpCode
.Question
.Header
.Help
= Help
;
1923 OpCode
.Question
.Flags
= QuestionFlags
;
1924 OpCode
.Flags
= NumericFlags
;
1926 switch (NumericFlags
& EFI_IFR_NUMERIC_SIZE
) {
1927 case EFI_IFR_NUMERIC_SIZE_1
:
1928 OpCode
.data
.u8
.MinValue
= (UINT8
)Minimum
;
1929 OpCode
.data
.u8
.MaxValue
= (UINT8
)Maximum
;
1930 OpCode
.data
.u8
.Step
= (UINT8
)Step
;
1933 case EFI_IFR_NUMERIC_SIZE_2
:
1934 OpCode
.data
.u16
.MinValue
= (UINT16
)Minimum
;
1935 OpCode
.data
.u16
.MaxValue
= (UINT16
)Maximum
;
1936 OpCode
.data
.u16
.Step
= (UINT16
)Step
;
1939 case EFI_IFR_NUMERIC_SIZE_4
:
1940 OpCode
.data
.u32
.MinValue
= (UINT32
)Minimum
;
1941 OpCode
.data
.u32
.MaxValue
= (UINT32
)Maximum
;
1942 OpCode
.data
.u32
.Step
= (UINT32
)Step
;
1945 case EFI_IFR_NUMERIC_SIZE_8
:
1946 OpCode
.data
.u64
.MinValue
= Minimum
;
1947 OpCode
.data
.u64
.MaxValue
= Maximum
;
1948 OpCode
.data
.u64
.Step
= Step
;
1952 if (DefaultsOpCodeHandle
== NULL
) {
1953 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_NUMERIC_OP
, sizeof (OpCode
));
1956 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
1957 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_NUMERIC_OP
, sizeof (OpCode
), 0, 1);
1958 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
1959 HiiCreateEndOpCode (OpCodeHandle
);
1960 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
1964 Create EFI_IFR_STRING_OP opcode.
1966 If OpCodeHandle is NULL, then ASSERT().
1967 If any reserved bits are set in QuestionFlags, then ASSERT().
1968 If any reserved bits are set in StringFlags, then ASSERT().
1970 @param[in] OpCodeHandle Handle to the buffer of opcodes.
1971 @param[in] QuestionId Question ID
1972 @param[in] VarStoreId Storage ID
1973 @param[in] VarOffset Offset in Storage
1974 @param[in] Prompt String ID for Prompt
1975 @param[in] Help String ID for Help
1976 @param[in] QuestionFlags Flags in Question Header
1977 @param[in] StringFlags Flags for string opcode
1978 @param[in] MinSize String minimum length
1979 @param[in] MaxSize String maximum length
1980 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
1981 is an optional parameter that may be NULL.
1983 @retval NULL There is not enough space left in Buffer to add the opcode.
1984 @retval Other A pointer to the created opcode.
1989 HiiCreateStringOpCode (
1990 IN VOID
*OpCodeHandle
,
1991 IN EFI_QUESTION_ID QuestionId
,
1992 IN EFI_VARSTORE_ID VarStoreId
,
1993 IN UINT16 VarOffset
,
1994 IN EFI_STRING_ID Prompt
,
1995 IN EFI_STRING_ID Help
,
1996 IN UINT8 QuestionFlags
,
1997 IN UINT8 StringFlags
,
2000 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2003 EFI_IFR_STRING OpCode
;
2006 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2008 ZeroMem (&OpCode
, sizeof (OpCode
));
2009 OpCode
.Question
.Header
.Prompt
= Prompt
;
2010 OpCode
.Question
.Header
.Help
= Help
;
2011 OpCode
.Question
.QuestionId
= QuestionId
;
2012 OpCode
.Question
.VarStoreId
= VarStoreId
;
2013 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2014 OpCode
.Question
.Flags
= QuestionFlags
;
2015 OpCode
.MinSize
= MinSize
;
2016 OpCode
.MaxSize
= MaxSize
;
2017 OpCode
.Flags
= (UINT8
) (StringFlags
& EFI_IFR_STRING_MULTI_LINE
);
2019 if (DefaultsOpCodeHandle
== NULL
) {
2020 return InternalHiiCreateOpCode (OpCodeHandle
, &OpCode
, EFI_IFR_STRING_OP
, sizeof (OpCode
));
2023 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2024 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_STRING_OP
, sizeof (OpCode
), 0, 1);
2025 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2026 HiiCreateEndOpCode (OpCodeHandle
);
2027 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2031 Create EFI_IFR_ONE_OF_OP opcode.
2033 If OpCodeHandle is NULL, then ASSERT().
2034 If any reserved bits are set in QuestionFlags, then ASSERT().
2035 If any reserved bits are set in OneOfFlags, then ASSERT().
2037 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2038 @param[in] QuestionId Question ID
2039 @param[in] VarStoreId Storage ID
2040 @param[in] VarOffset Offset in Storage
2041 @param[in] Prompt String ID for Prompt
2042 @param[in] Help String ID for Help
2043 @param[in] QuestionFlags Flags in Question Header
2044 @param[in] OneOfFlags Flags for oneof opcode
2045 @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
2046 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2047 is an optional parameter that may be NULL.
2049 @retval NULL There is not enough space left in Buffer to add the opcode.
2050 @retval Other A pointer to the created opcode.
2055 HiiCreateOneOfOpCode (
2056 IN VOID
*OpCodeHandle
,
2057 IN EFI_QUESTION_ID QuestionId
,
2058 IN EFI_VARSTORE_ID VarStoreId
,
2059 IN UINT16 VarOffset
,
2060 IN EFI_STRING_ID Prompt
,
2061 IN EFI_STRING_ID Help
,
2062 IN UINT8 QuestionFlags
,
2063 IN UINT8 OneOfFlags
,
2064 IN VOID
*OptionsOpCodeHandle
,
2065 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2068 EFI_IFR_ONE_OF OpCode
;
2071 ASSERT (OptionsOpCodeHandle
!= NULL
);
2072 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2074 ZeroMem (&OpCode
, sizeof (OpCode
));
2075 OpCode
.Question
.Header
.Prompt
= Prompt
;
2076 OpCode
.Question
.Header
.Help
= Help
;
2077 OpCode
.Question
.QuestionId
= QuestionId
;
2078 OpCode
.Question
.VarStoreId
= VarStoreId
;
2079 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2080 OpCode
.Question
.Flags
= QuestionFlags
;
2081 OpCode
.Flags
= OneOfFlags
;
2083 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2084 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_ONE_OF_OP
, sizeof (OpCode
), 0, 1);
2085 InternalHiiAppendOpCodes (OpCodeHandle
, OptionsOpCodeHandle
);
2086 if (DefaultsOpCodeHandle
!= NULL
) {
2087 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2089 HiiCreateEndOpCode (OpCodeHandle
);
2090 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2094 Create EFI_IFR_ORDERED_LIST_OP opcode.
2096 If OpCodeHandle is NULL, then ASSERT().
2097 If any reserved bits are set in QuestionFlags, then ASSERT().
2098 If any reserved bits are set in OrderedListFlags, then ASSERT().
2100 @param[in] OpCodeHandle Handle to the buffer of opcodes.
2101 @param[in] QuestionId Question ID
2102 @param[in] VarStoreId Storage ID
2103 @param[in] VarOffset Offset in Storage
2104 @param[in] Prompt String ID for Prompt
2105 @param[in] Help String ID for Help
2106 @param[in] QuestionFlags Flags in Question Header
2107 @param[in] OrderedListFlags Flags for ordered list opcode
2108 @param[in] DataType Type for option value
2109 @param[in] MaxContainers Maximum count for options in this ordered list
2110 @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
2111 @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
2112 is an optional parameter that may be NULL.
2114 @retval NULL There is not enough space left in Buffer to add the opcode.
2115 @retval Other A pointer to the created opcode.
2120 HiiCreateOrderedListOpCode (
2121 IN VOID
*OpCodeHandle
,
2122 IN EFI_QUESTION_ID QuestionId
,
2123 IN EFI_VARSTORE_ID VarStoreId
,
2124 IN UINT16 VarOffset
,
2125 IN EFI_STRING_ID Prompt
,
2126 IN EFI_STRING_ID Help
,
2127 IN UINT8 QuestionFlags
,
2128 IN UINT8 OrderedListFlags
,
2130 IN UINT8 MaxContainers
,
2131 IN VOID
*OptionsOpCodeHandle
,
2132 IN VOID
*DefaultsOpCodeHandle OPTIONAL
2135 EFI_IFR_ORDERED_LIST OpCode
;
2138 ASSERT (OptionsOpCodeHandle
!= NULL
);
2139 ASSERT ((QuestionFlags
& (~(EFI_IFR_FLAG_READ_ONLY
| EFI_IFR_FLAG_CALLBACK
| EFI_IFR_FLAG_RESET_REQUIRED
| EFI_IFR_FLAG_OPTIONS_ONLY
))) == 0);
2141 ZeroMem (&OpCode
, sizeof (OpCode
));
2142 OpCode
.Question
.Header
.Prompt
= Prompt
;
2143 OpCode
.Question
.Header
.Help
= Help
;
2144 OpCode
.Question
.QuestionId
= QuestionId
;
2145 OpCode
.Question
.VarStoreId
= VarStoreId
;
2146 OpCode
.Question
.VarStoreInfo
.VarOffset
= VarOffset
;
2147 OpCode
.Question
.Flags
= QuestionFlags
;
2148 OpCode
.MaxContainers
= MaxContainers
;
2149 OpCode
.Flags
= OrderedListFlags
;
2151 Position
= InternalHiiOpCodeHandlePosition (OpCodeHandle
);
2152 InternalHiiCreateOpCodeExtended (OpCodeHandle
, &OpCode
, EFI_IFR_ORDERED_LIST_OP
, sizeof (OpCode
), 0, 1);
2153 InternalHiiAppendOpCodes (OpCodeHandle
, OptionsOpCodeHandle
);
2154 if (DefaultsOpCodeHandle
!= NULL
) {
2155 InternalHiiAppendOpCodes (OpCodeHandle
, DefaultsOpCodeHandle
);
2157 HiiCreateEndOpCode (OpCodeHandle
);
2158 return InternalHiiOpCodeHandleBuffer (OpCodeHandle
) + Position
;
2162 This is the internal worker function to update the data in
2163 a form specified by FormSetGuid, FormId and Label.
2165 @param FormSetGuid The optional Formset GUID.
2166 @param FormId The Form ID.
2167 @param Package The package header.
2169 @param TempPacakge The resultant package.
2171 @retval EFI_SUCCESS The function completes successfully.
2176 InternalHiiUpdateFormPackageData (
2177 IN EFI_GUID
*FormSetGuid
, OPTIONAL
2178 IN EFI_FORM_ID FormId
,
2179 IN EFI_HII_PACKAGE_HEADER
*Package
,
2180 IN HII_LIB_OPCODE_BUFFER
*OpCodeBufferStart
,
2181 IN HII_LIB_OPCODE_BUFFER
*OpCodeBufferEnd
, OPTIONAL
2182 OUT EFI_HII_PACKAGE_HEADER
*TempPackage
2187 EFI_HII_PACKAGE_HEADER PackageHeader
;
2189 EFI_IFR_OP_HEADER
*IfrOpHdr
;
2190 EFI_IFR_OP_HEADER
*UpdateIfrOpHdr
;
2194 EFI_IFR_OP_HEADER
*AddOpCode
;
2195 UINT32 UpdatePackageLength
;
2197 CopyMem (TempPackage
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2198 UpdatePackageLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
2199 BufferPos
= (UINT8
*) (TempPackage
+ 1);
2201 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2202 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
2203 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
2204 GetFormSet
= (BOOLEAN
) ((FormSetGuid
== NULL
) ? TRUE
: FALSE
);
2208 while (Offset
< PackageHeader
.Length
) {
2209 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
2210 BufferPos
+= IfrOpHdr
->Length
;
2211 UpdatePackageLength
+= IfrOpHdr
->Length
;
2214 // Find the matched FormSet and Form
2216 if ((IfrOpHdr
->OpCode
== EFI_IFR_FORM_SET_OP
) && (FormSetGuid
!= NULL
)) {
2217 if (CompareGuid((GUID
*)(VOID
*)&((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, FormSetGuid
)) {
2222 } else if (IfrOpHdr
->OpCode
== EFI_IFR_FORM_OP
) {
2223 if (CompareMem (&((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, &FormId
, sizeof (EFI_FORM_ID
)) == 0) {
2231 // The matched Form is found, and Update data in this form
2233 if (GetFormSet
&& GetForm
&& !Updated
) {
2234 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferStart
->Buffer
;
2235 if ((UpdateIfrOpHdr
->Length
== IfrOpHdr
->Length
) && \
2236 (CompareMem (IfrOpHdr
, UpdateIfrOpHdr
, UpdateIfrOpHdr
->Length
) == 0)) {
2238 // Remove the original data when End OpCode buffer exist.
2240 if (OpCodeBufferEnd
!= NULL
) {
2241 Offset
+= IfrOpHdr
->Length
;
2242 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2243 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferEnd
->Buffer
;
2244 while (Offset
< PackageHeader
.Length
) {
2246 // Search the matched end opcode
2248 if ((UpdateIfrOpHdr
->Length
== IfrOpHdr
->Length
) && \
2249 (CompareMem (IfrOpHdr
, UpdateIfrOpHdr
, UpdateIfrOpHdr
->Length
) == 0)) {
2253 // Go to the next Op-Code
2255 Offset
+= IfrOpHdr
->Length
;
2256 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2259 if (Offset
>= PackageHeader
.Length
) {
2261 // The end opcode is not found.
2263 return EFI_NOT_FOUND
;
2267 // Insert the updated data
2269 UpdateIfrOpHdr
= (EFI_IFR_OP_HEADER
*) OpCodeBufferStart
->Buffer
;
2270 AddOpCode
= (EFI_IFR_OP_HEADER
*) (OpCodeBufferStart
->Buffer
+ UpdateIfrOpHdr
->Length
);
2271 AddSize
= UpdateIfrOpHdr
->Length
;
2272 while (AddSize
< OpCodeBufferStart
->Position
) {
2273 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
2274 BufferPos
+= AddOpCode
->Length
;
2275 UpdatePackageLength
+= AddOpCode
->Length
;
2277 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) (AddOpCode
) + AddOpCode
->Length
);
2278 AddSize
+= AddOpCode
->Length
;
2281 if (OpCodeBufferEnd
!= NULL
) {
2283 // Add the end opcode
2285 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
2286 BufferPos
+= IfrOpHdr
->Length
;
2287 UpdatePackageLength
+= IfrOpHdr
->Length
;
2297 // Go to the next Op-Code
2299 Offset
+= IfrOpHdr
->Length
;
2300 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
2305 // The updated opcode buffer is not found.
2307 return EFI_NOT_FOUND
;
2310 // Update the package length.
2312 PackageHeader
.Length
= UpdatePackageLength
;
2313 CopyMem (TempPackage
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2319 This function updates a form that has previously been registered with the HII
2320 Database. This function will perform at most one update operation.
2322 The form to update is specified by Handle, FormSetGuid, and FormId. Binary
2323 comparisons of IFR opcodes are performed from the beginning of the form being
2324 updated until an IFR opcode is found that exactly matches the first IFR opcode
2325 specifed by StartOpCodeHandle. The following rules are used to determine if
2326 an insert, replace, or delete operation is performed.
2328 1) If no matches are found, then NULL is returned.
2329 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes
2330 from StartOpcodeHandle except the first opcode are inserted immediately after
2331 the matching IFR opcode in the form beng updated.
2332 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made
2333 from the matching IFR opcode until an IFR opcode exatly matches the first
2334 IFR opcode specified by EndOpCodeHandle. If no match is found for the first
2335 IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match
2336 is found, then all of the IFR opcodes between the start match and the end
2337 match are deleted from the form being updated and all of the IFR opcodes
2338 from StartOpcodeHandle except the first opcode are inserted immediately after
2339 the matching start IFR opcode. If StartOpCcodeHandle only contains one
2340 IFR instruction, then the result of ths operation will delete all of the IFR
2341 opcodes between the start end matches.
2343 If HiiHandle is NULL, then ASSERT().
2344 If StartOpCodeHandle is NULL, then ASSERT().
2346 @param[in] HiiHandle The HII Handle of the form to update.
2347 @param[in] FormSetGuid The Formset GUID of the form to update. This
2348 is an optional parameter that may be NULL.
2349 If it is NULL, all FormSet will be updated.
2350 @param[in] FormId The ID of the form to update.
2351 @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR
2352 opcodes to be inserted or replaced in the form.
2353 The first IFR instruction in StartOpCodeHandle
2354 is used to find matching IFR opcode in the
2356 @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode
2357 that marks the end of a replace operation in
2358 the form. This is an optional parameter that
2359 may be NULL. If it is NULL, then an the IFR
2360 opcodes specified by StartOpCodeHandle are
2361 inserted into the form.
2363 @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated.
2364 @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND.
2365 1) The form specified by HiiHandle, FormSetGuid,
2366 and FormId could not be found in the HII Database.
2367 2) No IFR opcodes in the target form match the first
2368 IFR opcode in StartOpCodeHandle.
2369 3) EndOpCOde is not NULL, and no IFR opcodes in the
2370 target form following a matching start opcode match
2371 the first IFR opcode in EndOpCodeHandle.
2372 @retval EFI_SUCCESS The matched form is updated by StartOpcode.
2378 IN EFI_HII_HANDLE HiiHandle
,
2379 IN EFI_GUID
*FormSetGuid
, OPTIONAL
2380 IN EFI_FORM_ID FormId
,
2381 IN VOID
*StartOpcodeHandle
,
2382 IN VOID
*EndOpcodeHandle OPTIONAL
2386 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2387 UINT32 PackageListLength
;
2389 EFI_HII_PACKAGE_LIST_HEADER
*UpdatePackageList
;
2391 UINT8
*UpdateBufferPos
;
2392 EFI_HII_PACKAGE_HEADER
*Package
;
2393 EFI_HII_PACKAGE_HEADER
*TempPacakge
;
2394 EFI_HII_PACKAGE_HEADER PackageHeader
;
2396 HII_LIB_OPCODE_BUFFER
*OpCodeBufferStart
;
2397 HII_LIB_OPCODE_BUFFER
*OpCodeBufferEnd
;
2400 // Input update data can't be NULL.
2402 ASSERT (HiiHandle
!= NULL
);
2403 ASSERT (StartOpcodeHandle
!= NULL
);
2404 UpdatePackageList
= NULL
;
2406 HiiPackageList
= NULL
;
2409 // Restrive buffer data from Opcode Handle
2411 OpCodeBufferStart
= (HII_LIB_OPCODE_BUFFER
*) StartOpcodeHandle
;
2412 OpCodeBufferEnd
= (HII_LIB_OPCODE_BUFFER
*) EndOpcodeHandle
;
2415 // Get the orginal package list
2418 HiiPackageList
= NULL
;
2419 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
2421 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
2423 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2427 HiiPackageList
= AllocatePool (BufferSize
);
2428 if (HiiPackageList
== NULL
) {
2429 Status
= EFI_OUT_OF_RESOURCES
;
2433 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
2434 if (EFI_ERROR (Status
)) {
2439 // Calculate and allocate space for retrieval of IFR data
2441 BufferSize
+= OpCodeBufferStart
->Position
;
2442 UpdatePackageList
= AllocateZeroPool (BufferSize
);
2443 if (UpdatePackageList
== NULL
) {
2444 Status
= EFI_OUT_OF_RESOURCES
;
2449 // Allocate temp buffer to store the temp updated package buffer
2451 TempPacakge
= AllocateZeroPool (BufferSize
);
2452 if (TempPacakge
== NULL
) {
2453 Status
= EFI_OUT_OF_RESOURCES
;
2457 UpdateBufferPos
= (UINT8
*) UpdatePackageList
;
2460 // Copy the package list header
2462 CopyMem (UpdateBufferPos
, HiiPackageList
, sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
2463 UpdateBufferPos
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2466 // Go through each package to find the matched pacakge and update one by one
2469 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2470 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
2471 while (Offset
< PackageListLength
) {
2472 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
2473 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2474 Offset
+= Package
->Length
;
2476 if (Package
->Type
== EFI_HII_PACKAGE_FORMS
) {
2478 // Check this package is the matched package.
2480 Status
= InternalHiiUpdateFormPackageData (FormSetGuid
, FormId
, Package
, OpCodeBufferStart
, OpCodeBufferEnd
, TempPacakge
);
2482 // The matched package is found. Its pacakge buffer will be updated by the input new data.
2484 if (!EFI_ERROR(Status
)) {
2490 // Add updated package buffer
2492 Package
= TempPacakge
;
2497 // Add pacakge buffer
2499 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2500 CopyMem (UpdateBufferPos
, Package
, PackageHeader
.Length
);
2501 UpdateBufferPos
+= PackageHeader
.Length
;
2506 // Update package list length
2508 BufferSize
= UpdateBufferPos
- (UINT8
*) UpdatePackageList
;
2509 WriteUnaligned32 (&UpdatePackageList
->PackageLength
, (UINT32
) BufferSize
);
2512 // Update Pacakge to show form
2514 Status
= gHiiDatabase
->UpdatePackageList (gHiiDatabase
, HiiHandle
, UpdatePackageList
);
2517 // Not matched form is found and updated.
2519 Status
= EFI_NOT_FOUND
;
2523 if (HiiPackageList
!= NULL
) {
2524 FreePool (HiiPackageList
);
2527 if (UpdatePackageList
!= NULL
) {
2528 FreePool (UpdatePackageList
);
2531 if (TempPacakge
!= NULL
) {
2532 FreePool (TempPacakge
);
2539 Configure the buffer accrording to ConfigBody strings in the format of
2540 <Length:4 bytes>, <Offset: 2 bytes>, <Width:2 bytes>, <Data:n bytes>.
2541 This ConfigBody strings is generated by UEFI VfrCompiler for the default
2542 values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000
2543 constructed following this rule:
2544 "Vfr" + varstore.name + "Default" + defaultstore.attributes.
2545 Check the generated C file in Output for details.
2547 @param Buffer The start address of buffer.
2548 @param BufferSize The size of buffer.
2549 @param Number The number of the strings.
2550 @param ... Variable argument list for default value in <AltResp> format
2551 generated by the tool.
2553 @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
2554 @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
2555 @retval EFI_SUCCESS Operation successful.
2560 HiiIfrLibExtractDefault(
2562 IN UINTN
*BufferSize
,
2576 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
2577 return EFI_INVALID_PARAMETER
;
2584 VA_START (Args
, Number
);
2585 for (Index
= 0; Index
< Number
; Index
++) {
2586 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
2587 TotalLen
= ReadUnaligned32 ((UINT32
*)BufCfgArray
);
2588 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
2590 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
2591 Offset
= ReadUnaligned16 ((UINT16
*)BufferPos
);
2592 BufferPos
+= sizeof (UINT16
);
2593 Width
= ReadUnaligned16 ((UINT16
*)BufferPos
);
2594 BufferPos
+= sizeof (UINT16
);
2598 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
2599 return EFI_BUFFER_TOO_SMALL
;
2602 CopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
2607 *BufferSize
= (UINTN
)Offset
;