3 Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Common Library Routines to assist handle HII elements.
22 #include "UefiIfrLibrary.h"
27 UINT16 mFakeConfigHdr
[] = L
"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";
30 GetPackageDataFromPackageList (
31 IN EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
,
32 IN UINT32 PackageIndex
,
33 OUT UINT32
*BufferLen
,
34 OUT EFI_HII_PACKAGE_HEADER
**Buffer
38 EFI_HII_PACKAGE_HEADER
*Package
;
40 UINT32 PackageListLength
;
41 EFI_HII_PACKAGE_HEADER PackageHeader
= {0, 0};
43 ASSERT(HiiPackageList
!= NULL
);
45 if ((BufferLen
== NULL
) || (Buffer
== NULL
)) {
46 return EFI_INVALID_PARAMETER
;
51 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
52 EfiCopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
53 while (Offset
< PackageListLength
) {
54 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
55 EfiCopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
56 if (Index
== PackageIndex
) {
59 Offset
+= PackageHeader
.Length
;
62 if (Offset
>= PackageListLength
) {
64 // no package found in this Package List
69 *BufferLen
= PackageHeader
.Length
;
75 UpdateFormPackageData (
76 IN EFI_GUID
*FormSetGuid
,
77 IN EFI_FORM_ID FormId
,
78 IN EFI_HII_PACKAGE_HEADER
*Package
,
79 IN UINT32 PackageLength
,
82 IN EFI_HII_UPDATE_DATA
*Data
,
83 OUT UINT8
**TempBuffer
,
84 OUT UINT32
*TempBufferSize
88 EFI_HII_PACKAGE_HEADER PackageHeader
;
90 EFI_IFR_OP_HEADER
*IfrOpHdr
;
97 if ((TempBuffer
== NULL
) || (TempBufferSize
== NULL
)) {
98 return EFI_INVALID_PARAMETER
;
101 *TempBufferSize
= PackageLength
;
103 *TempBufferSize
+= Data
->Offset
;
105 *TempBuffer
= EfiLibAllocateZeroPool (*TempBufferSize
);
106 if (*TempBuffer
== NULL
) {
107 return EFI_OUT_OF_RESOURCES
;
110 EfiCopyMem (*TempBuffer
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
111 *TempBufferSize
= sizeof (EFI_HII_PACKAGE_HEADER
);
112 BufferPos
= *TempBuffer
+ sizeof (EFI_HII_PACKAGE_HEADER
);
114 EfiCopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
115 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
116 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
117 GetFormSet
= (BOOLEAN
)((FormSetGuid
== NULL
) ? TRUE
: FALSE
);
121 while (!Updated
&& Offset
< PackageHeader
.Length
) {
122 EfiCopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
123 BufferPos
+= IfrOpHdr
->Length
;
124 *TempBufferSize
+= IfrOpHdr
->Length
;
126 switch (IfrOpHdr
->OpCode
) {
127 case EFI_IFR_FORM_SET_OP
:
128 if (FormSetGuid
!= NULL
) {
129 if (EfiCompareMem (&((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, FormSetGuid
, sizeof (EFI_GUID
)) == 0) {
137 case EFI_IFR_FORM_OP
:
138 if (EfiCompareMem (&((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, &FormId
, sizeof (EFI_FORM_ID
)) == 0) {
145 case EFI_IFR_GUID_OP
:
146 if (!GetFormSet
|| !GetForm
) {
148 // Go to the next Op-Code
153 if (!EfiCompareGuid (&((EFI_IFR_GUID
*) IfrOpHdr
)->Guid
, &mIfrVendorGuid
)) {
155 // GUID mismatch, skip this op-code
160 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
161 EfiCopyMem (&LabelNumber
, &((EFI_IFR_GUID_LABEL
*)IfrOpHdr
)->Number
, sizeof (UINT16
));
162 if ((ExtendOpCode
!= EFI_IFR_EXTEND_OP_LABEL
) || (LabelNumber
!= Label
)) {
164 // Go to the next Op-Code
171 // Insert data after current Label, skip myself
173 Offset
+= IfrOpHdr
->Length
;
174 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
177 // Replace data between two paired Label, try to find the next Label.
180 Offset
+= IfrOpHdr
->Length
;
182 // Search the next label and Fail if not label found.
184 if (Offset
>= PackageHeader
.Length
) {
187 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
188 if (IfrOpHdr
->OpCode
== EFI_IFR_GUID_OP
) {
189 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
190 if (EfiCompareGuid (&((EFI_IFR_GUID
*) IfrOpHdr
)->Guid
, &mIfrVendorGuid
) && ExtendOpCode
== EFI_IFR_EXTEND_OP_LABEL
) {
198 // Fill in the update data
201 EfiCopyMem (BufferPos
, Data
->Data
, Data
->Offset
);
202 BufferPos
+= Data
->Offset
;
203 *TempBufferSize
+= Data
->Offset
;
207 // Copy the reset data
209 EfiCopyMem (BufferPos
, IfrOpHdr
, PackageHeader
.Length
- Offset
);
210 *TempBufferSize
+= PackageHeader
.Length
- Offset
;
219 // Go to the next Op-Code
221 Offset
+= IfrOpHdr
->Length
;
222 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
226 // Update the package length.
228 PackageHeader
.Length
= *TempBufferSize
;
229 EfiCopyMem (*TempBuffer
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
233 gBS
->FreePool (*TempBuffer
);
235 return EFI_NOT_FOUND
;
242 IfrLibInitUpdateData (
243 IN OUT EFI_HII_UPDATE_DATA
*UpdateData
,
249 This function initialize the data structure for dynamic opcode.
252 UpdateData - The adding data;
253 BufferSize - Length of the buffer to fill dynamic opcodes.
256 EFI_SUCCESS - Update data is initialized.
257 EFI_INVALID_PARAMETER - UpdateData is NULL.
258 EFI_OUT_OF_RESOURCES - No enough memory to allocate.
262 if (UpdateData
== NULL
) {
263 return EFI_INVALID_PARAMETER
;
266 UpdateData
->BufferSize
= BufferSize
;
267 UpdateData
->Offset
= 0;
268 UpdateData
->Data
= EfiLibAllocatePool (BufferSize
);
270 return (UpdateData
->Data
!= NULL
) ? EFI_SUCCESS
: EFI_OUT_OF_RESOURCES
;
274 IfrLibFreeUpdateData (
275 IN EFI_HII_UPDATE_DATA
*UpdateData
280 This function free the resource of update data.
283 UpdateData - The adding data;
286 EFI_SUCCESS - Resource in UpdateData is released.
287 EFI_INVALID_PARAMETER - UpdateData is NULL.
293 if (UpdateData
== NULL
) {
294 return EFI_INVALID_PARAMETER
;
297 Status
= gBS
->FreePool (UpdateData
->Data
);
298 UpdateData
->Data
= NULL
;
305 IN EFI_HII_HANDLE Handle
,
306 IN EFI_GUID
*FormSetGuid
, OPTIONAL
307 IN EFI_FORM_ID FormId
,
310 IN EFI_HII_UPDATE_DATA
*Data
315 This function allows the caller to update a form that has
316 previously been registered with the EFI HII database.
320 FormSetGuid - The formset should be updated.
321 FormId - The form should be updated.
322 Label - Update information starting immediately after this label in the IFR
323 Insert - If TRUE and Data is not NULL, insert data after Label.
324 If FALSE, replace opcodes between two labels with Data
325 Data - The adding data; If NULL, remove opcodes between two Label.
328 EFI_SUCCESS - Update success.
334 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
335 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
337 EFI_HII_PACKAGE_LIST_HEADER
*UpdateBuffer
;
339 UINT8
*UpdateBufferPos
;
340 EFI_HII_PACKAGE_HEADER PackageHeader
;
341 EFI_HII_PACKAGE_HEADER
*Package
;
342 UINT32 PackageLength
;
343 EFI_HII_PACKAGE_HEADER
*TempBuffer
;
344 UINT32 TempBufferSize
;
348 return EFI_INVALID_PARAMETER
;
351 LocateHiiProtocols ();
352 HiiDatabase
= gIfrLibHiiDatabase
;
355 // Get the orginal package list
358 HiiPackageList
= NULL
;
359 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
360 if (Status
== EFI_BUFFER_TOO_SMALL
) {
361 HiiPackageList
= EfiLibAllocatePool (BufferSize
);
362 ASSERT (HiiPackageList
!= NULL
);
364 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
365 if (EFI_ERROR (Status
)) {
366 gBS
->FreePool (HiiPackageList
);
372 // Calculate and allocate space for retrieval of IFR data
374 BufferSize
+= Data
->Offset
;
375 UpdateBuffer
= EfiLibAllocateZeroPool (BufferSize
);
376 if (UpdateBuffer
== NULL
) {
377 return EFI_OUT_OF_RESOURCES
;
380 UpdateBufferPos
= (UINT8
*) UpdateBuffer
;
383 // copy the package list header
385 EfiCopyMem (UpdateBufferPos
, HiiPackageList
, sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
386 UpdateBufferPos
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
389 for (Index
= 0; ; Index
++) {
390 Status
= GetPackageDataFromPackageList (HiiPackageList
, Index
, &PackageLength
, &Package
);
391 if (Status
== EFI_SUCCESS
) {
392 EfiCopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
393 if ((PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) && !Updated
) {
394 Status
= UpdateFormPackageData (FormSetGuid
, FormId
, Package
, PackageLength
, Label
, Insert
, Data
, (UINT8
**)&TempBuffer
, &TempBufferSize
);
395 if (!EFI_ERROR(Status
)) {
396 if (FormSetGuid
== NULL
) {
399 EfiCopyMem (UpdateBufferPos
, TempBuffer
, TempBufferSize
);
400 UpdateBufferPos
+= TempBufferSize
;
401 gBS
->FreePool (TempBuffer
);
406 EfiCopyMem (UpdateBufferPos
, Package
, PackageLength
);
407 UpdateBufferPos
+= PackageLength
;
408 } else if (Status
== EFI_NOT_FOUND
) {
411 gBS
->FreePool (HiiPackageList
);
417 // Update package list length
419 BufferSize
= UpdateBufferPos
- (UINT8
*) UpdateBuffer
;
420 EfiCopyMem (&UpdateBuffer
->PackageLength
, &BufferSize
, sizeof (UINT32
));
422 gBS
->FreePool (HiiPackageList
);
424 return HiiDatabase
->UpdatePackageList (HiiDatabase
, Handle
, UpdateBuffer
);
429 IN UINTN NumberOfLines
,
430 OUT EFI_INPUT_KEY
*KeyValue
,
437 Draw a dialog and return the selected key.
440 NumberOfLines - The number of lines for the dialog box
441 KeyValue - The EFI_KEY value returned if HotKey is TRUE..
442 String - Pointer to the first string in the list
443 ... - A series of (quantity == NumberOfLines) text strings which
444 will be used to construct the dialog box
447 EFI_SUCCESS - Displayed dialog and received user interaction
448 EFI_INVALID_PARAMETER - One of the parameters was invalid.
461 UINTN DimensionsWidth
;
462 UINTN DimensionsHeight
;
470 CHAR16
**StringArray
;
471 EFI_EVENT TimerEvent
;
472 EFI_EVENT WaitList
[2];
473 UINTN CurrentAttribute
;
474 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*ConOut
;
476 if ((KeyValue
== NULL
) || (String
== NULL
)) {
477 return EFI_INVALID_PARAMETER
;
485 ConOut
= gST
->ConOut
;
486 ConOut
->QueryMode (ConOut
, ConOut
->Mode
->Mode
, &RightColumn
, &BottomRow
);
488 DimensionsWidth
= RightColumn
- LeftColumn
;
489 DimensionsHeight
= BottomRow
- TopRow
;
491 CurrentAttribute
= ConOut
->Mode
->Attribute
;
493 LineBuffer
= EfiLibAllocateZeroPool (DimensionsWidth
* sizeof (CHAR16
));
494 ASSERT (LineBuffer
!= NULL
);
497 // Determine the largest string in the dialog box
498 // Notice we are starting with 1 since String is the first string
500 StringArray
= EfiLibAllocateZeroPool (NumberOfLines
* sizeof (CHAR16
*));
501 LargestString
= EfiStrLen (String
);
502 StringArray
[0] = String
;
504 VA_START (Marker
, String
);
505 for (Index
= 1; Index
< NumberOfLines
; Index
++) {
506 StackString
= VA_ARG (Marker
, CHAR16
*);
508 if (StackString
== NULL
) {
510 return EFI_INVALID_PARAMETER
;
513 StringArray
[Index
] = StackString
;
514 StringLen
= EfiStrLen (StackString
);
515 if (StringLen
> LargestString
) {
516 LargestString
= StringLen
;
521 if ((LargestString
+ 2) > DimensionsWidth
) {
522 LargestString
= DimensionsWidth
- 2;
526 // Subtract the PopUp width from total Columns, allow for one space extra on
527 // each end plus a border.
529 Start
= (DimensionsWidth
- LargestString
- 2) / 2 + LeftColumn
+ 1;
531 Top
= ((DimensionsHeight
- NumberOfLines
- 2) / 2) + TopRow
- 1;
536 ConOut
->EnableCursor (ConOut
, FALSE
);
537 ConOut
->SetAttribute (ConOut
, EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
);
539 StringPtr
= &LineBuffer
[0];
540 *StringPtr
++ = BOXDRAW_DOWN_RIGHT
;
541 for (Index
= 0; Index
< LargestString
; Index
++) {
542 *StringPtr
++ = BOXDRAW_HORIZONTAL
;
544 *StringPtr
++ = BOXDRAW_DOWN_LEFT
;
547 ConOut
->SetCursorPosition (ConOut
, Start
, Top
);
548 ConOut
->OutputString (ConOut
, LineBuffer
);
550 for (Index
= 0; Index
< NumberOfLines
; Index
++) {
551 StringPtr
= &LineBuffer
[0];
552 *StringPtr
++ = BOXDRAW_VERTICAL
;
554 for (Count
= 0; Count
< LargestString
; Count
++) {
555 StringPtr
[Count
] = L
' ';
558 StringLen
= EfiStrLen (StringArray
[Index
]);
559 if (StringLen
> LargestString
) {
560 StringLen
= LargestString
;
563 StringPtr
+ ((LargestString
- StringLen
) / 2),
565 StringLen
* sizeof (CHAR16
)
567 StringPtr
+= LargestString
;
569 *StringPtr
++ = BOXDRAW_VERTICAL
;
572 ConOut
->SetCursorPosition (ConOut
, Start
, Top
+ 1 + Index
);
573 ConOut
->OutputString (ConOut
, LineBuffer
);
576 StringPtr
= &LineBuffer
[0];
577 *StringPtr
++ = BOXDRAW_UP_RIGHT
;
578 for (Index
= 0; Index
< LargestString
; Index
++) {
579 *StringPtr
++ = BOXDRAW_HORIZONTAL
;
581 *StringPtr
++ = BOXDRAW_UP_LEFT
;
584 ConOut
->SetCursorPosition (ConOut
, Start
, Top
+ NumberOfLines
+ 1);
585 ConOut
->OutputString (ConOut
, LineBuffer
);
588 Status
= gBS
->CreateEvent (EFI_EVENT_TIMER
, 0, NULL
, NULL
, &TimerEvent
);
591 // Set a timer event of 1 second expiration
600 // Wait for the keystroke event or the timer
602 WaitList
[0] = gST
->ConIn
->WaitForKey
;
603 WaitList
[1] = TimerEvent
;
604 Status
= gBS
->WaitForEvent (2, WaitList
, &Index
);
607 // Check for the timer expiration
609 if (!EFI_ERROR (Status
) && Index
== 1) {
610 Status
= EFI_TIMEOUT
;
613 gBS
->CloseEvent (TimerEvent
);
614 } while (Status
== EFI_TIMEOUT
);
616 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
617 EfiCopyMem (KeyValue
, &Key
, sizeof (EFI_INPUT_KEY
));
619 ConOut
->SetAttribute (ConOut
, CurrentAttribute
);
620 ConOut
->EnableCursor (ConOut
, TRUE
);
628 IN UINTN
*BufferSize
,
636 Configure the buffer accrording to ConfigBody strings.
639 DefaultId - the ID of default.
640 Buffer - the start address of buffer.
641 BufferSize - the size of buffer.
642 Number - the number of the strings.
645 EFI_BUFFER_TOO_SMALL - the BufferSize is too small to operate.
646 EFI_INVALID_PARAMETER - Buffer is NULL or BufferSize is 0.
647 EFI_SUCCESS - Operation successful.
660 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
661 return EFI_INVALID_PARAMETER
;
668 VA_START (Args
, Number
);
669 for (Index
= 0; Index
< Number
; Index
++) {
670 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
671 EfiCopyMem (&TotalLen
, BufCfgArray
, sizeof (UINT32
));
672 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
674 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
675 EfiCopyMem (&Offset
, BufferPos
, sizeof (UINT16
));
676 BufferPos
+= sizeof (UINT16
);
677 EfiCopyMem (&Width
, BufferPos
, sizeof (UINT16
));
678 BufferPos
+= sizeof (UINT16
);
682 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
684 return EFI_BUFFER_TOO_SMALL
;
687 EfiCopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
692 *BufferSize
= (UINTN
)Offset
;
700 OUT CHAR16
**BlockName
706 Extract block name from the array generated by VFR compiler. The name of
707 this array is "Vfr + <StorageName> + BlockName", e.g. "VfrMyIfrNVDataBlockName".
708 Format of this array is:
709 Array length | 4-bytes
717 Buffer - Array generated by VFR compiler.
718 BlockName - The returned <BlockName>
721 EFI_OUT_OF_RESOURCES - Run out of memory resource.
722 EFI_INVALID_PARAMETER - Buffer is NULL or BlockName is NULL.
723 EFI_SUCCESS - Operation successful.
729 UINT32 BlockNameNumber
;
730 UINTN HexStringBufferLen
;
733 if ((Buffer
== NULL
) || (BlockName
== NULL
)) {
734 return EFI_INVALID_PARAMETER
;
738 // Calculate number of Offset/Width pair
740 EfiCopyMem (&Length
, Buffer
, sizeof (UINT32
));
741 BlockNameNumber
= (Length
- sizeof (UINT32
)) / (sizeof (UINT16
) * 2);
744 // <BlockName> ::= &OFFSET=1234&WIDTH=1234
747 StringPtr
= EfiLibAllocateZeroPool ((BlockNameNumber
* (8 + 4 + 7 + 4) + 1) * sizeof (CHAR16
));
748 *BlockName
= StringPtr
;
749 if (StringPtr
== NULL
) {
750 return EFI_OUT_OF_RESOURCES
;
753 Buffer
+= sizeof (UINT32
);
754 for (Index
= 0; Index
< BlockNameNumber
; Index
++) {
755 EfiStrCpy (StringPtr
, L
"&OFFSET=");
758 HexStringBufferLen
= 5;
759 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
760 Buffer
+= sizeof (UINT16
);
763 EfiStrCpy (StringPtr
, L
"&WIDTH=");
766 HexStringBufferLen
= 5;
767 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
768 Buffer
+= sizeof (UINT16
);
778 OUT CHAR16
**BlockConfig
784 Extract block config from the array generated by VFR compiler. The name of
785 this array is "Vfr + <StorageName> + Default<HexCh>4", e.g. "VfrMyIfrNVDataDefault0000".
788 Buffer - Array generated by VFR compiler.
789 BlockConfig - The returned <BlockConfig>
792 EFI_OUT_OF_RESOURCES - Run out of memory resource.
793 EFI_INVALID_PARAMETER - Buffer is NULL or BlockConfig is NULL.
794 EFI_SUCCESS - Operation successful.
800 UINTN HexStringBufferLen
;
806 if ((Buffer
== NULL
) || (BlockConfig
== NULL
)) {
807 return EFI_INVALID_PARAMETER
;
811 // Calculate length of AltResp string
812 // Format of Default value array is:
813 // Array length | 4-bytes
816 // Value | Variable length
819 // Value | Variable length
821 // When value is 1 byte in length, overhead of AltResp string will be maximum,
822 // BlockConfig ::= <&OFFSET=1234&WIDTH=1234&VALUE=12>+
823 // | 8 | 4 | 7 | 4 | 7 |2|
824 // so the maximum length of BlockConfig could be calculated as:
825 // (ArrayLength / 5) * (8 + 4 + 7 + 4 + 7 + 2) = ArrayLength * 6.4 < ArrayLength * 7
827 EfiCopyMem (&Length
, Buffer
, sizeof (UINT32
));
828 BufferEnd
= Buffer
+ Length
;
829 StringPtr
= EfiLibAllocatePool (Length
* 7 * sizeof (CHAR16
));
830 *BlockConfig
= StringPtr
;
831 if (StringPtr
== NULL
) {
832 return EFI_OUT_OF_RESOURCES
;
834 StringEnd
= StringPtr
+ (Length
* 7);
836 Buffer
+= sizeof (UINT32
);
837 while (Buffer
< BufferEnd
) {
838 EfiStrCpy (StringPtr
, L
"&OFFSET=");
841 HexStringBufferLen
= 5;
842 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
843 Buffer
+= sizeof (UINT16
);
846 EfiStrCpy (StringPtr
, L
"&WIDTH=");
849 HexStringBufferLen
= 5;
850 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
851 EfiCopyMem (&Width
, Buffer
, sizeof (UINT16
));
852 Buffer
+= sizeof (UINT16
);
855 EfiStrCpy (StringPtr
, L
"&VALUE=");
858 HexStringBufferLen
= StringEnd
- StringPtr
;
859 Status
= BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, Width
);
860 if (EFI_ERROR (Status
)) {
864 StringPtr
+= (Width
* 2);
871 ConstructConfigAltResp (
872 IN EFI_STRING ConfigRequest
, OPTIONAL
873 OUT EFI_STRING
*Progress
,
874 OUT EFI_STRING
*ConfigAltResp
,
877 IN EFI_HANDLE
*DriverHandle
,
878 IN VOID
*BufferStorage
,
879 IN UINTN BufferStorageSize
,
880 IN VOID
*BlockNameArray
, OPTIONAL
881 IN UINTN NumberAltCfg
,
883 //IN UINT16 AltCfgId,
884 //IN VOID *DefaultValueArray,
890 Construct <ConfigAltResp> for a buffer storage.
893 ConfigRequest - The Config request string. If set to NULL, all the
894 configurable elements will be extracted from BlockNameArray.
895 ConfigAltResp - The returned <ConfigAltResp>.
896 Progress - On return, points to a character in the Request.
897 Guid - GUID of the buffer storage.
898 Name - Name of the buffer storage.
899 DriverHandle - The DriverHandle which is used to invoke HiiDatabase
900 protocol interface NewPackageList().
901 BufferStorage - Content of the buffer storage.
902 BufferStorageSize - Length in bytes of the buffer storage.
903 BlockNameArray - Array generated by VFR compiler.
904 NumberAltCfg - Number of Default value array generated by VFR compiler.
905 The sequential input parameters will be number of
906 AltCfgId and DefaultValueArray pairs. When set to 0,
907 there will be no <AltResp>.
910 EFI_OUT_OF_RESOURCES - Run out of memory resource.
911 EFI_INVALID_PARAMETER - ConfigAltResp is NULL.
912 EFI_SUCCESS - Operation successful.
923 VOID
*DefaultValueArray
;
925 EFI_STRING ConfigResp
;
930 BOOLEAN NeedFreeConfigRequest
;
931 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
933 if (ConfigAltResp
== NULL
) {
934 return EFI_INVALID_PARAMETER
;
938 // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
942 Status
= ConstructConfigHdr (
949 if (Status
== EFI_BUFFER_TOO_SMALL
) {
950 ConfigHdr
= EfiLibAllocateZeroPool (StrBufferLen
);
951 Status
= ConstructConfigHdr (
960 if (EFI_ERROR (Status
) || (ConfigHdr
== NULL
)) {
965 // Construct <ConfigResp>
967 NeedFreeConfigRequest
= FALSE
;
968 if (ConfigRequest
== NULL
) {
970 // If ConfigRequest is set to NULL, export all configurable elements in BlockNameArray
972 Status
= ExtractBlockName (BlockNameArray
, &BlockName
);
973 if (EFI_ERROR (Status
)) {
977 StrBufferLen
= EfiStrSize (ConfigHdr
);
978 StrBufferLen
= StrBufferLen
+ EfiStrSize (BlockName
) - sizeof (CHAR16
);
979 ConfigRequest
= EfiLibAllocateZeroPool (StrBufferLen
);
980 EfiStrCpy (ConfigRequest
, ConfigHdr
);
981 EfiStrCat (ConfigRequest
, BlockName
);
982 NeedFreeConfigRequest
= TRUE
;
985 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
986 if (EFI_ERROR (Status
)) {
990 Status
= HiiConfigRouting
->BlockToConfig (
996 (Progress
== NULL
) ? &TempStr
: Progress
998 if (EFI_ERROR (Status
)) {
1003 // Construct <AltResp>
1005 DescHdr
= EfiLibAllocateZeroPool (NumberAltCfg
* 16 * sizeof (CHAR16
));
1006 StringPtr
= DescHdr
;
1007 AltCfg
= EfiLibAllocateZeroPool (NumberAltCfg
* sizeof (CHAR16
*));
1009 VA_START (Args
, NumberAltCfg
);
1010 for (Index
= 0; Index
< NumberAltCfg
; Index
++) {
1011 AltCfgId
= (UINT16
) VA_ARG (Args
, UINT16
);
1012 DefaultValueArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
1017 AltRespLen
+= (EfiStrLen (ConfigHdr
) + 1);
1019 StringPtr
= DescHdr
+ Index
* 16;
1020 EfiStrCpy (StringPtr
, L
"&ALTCFG=");
1021 AltRespLen
+= (8 + sizeof (UINT16
) * 2);
1024 BufToHexString (StringPtr
+ 8, &StrBufferLen
, (UINT8
*) &AltCfgId
, sizeof (UINT16
));
1025 Status
= ExtractBlockConfig (DefaultValueArray
, &AltCfg
[Index
]);
1026 if (EFI_ERROR (Status
)) {
1030 AltRespLen
+= EfiStrLen (AltCfg
[Index
]);
1035 // Generate the final <ConfigAltResp>
1037 StrBufferLen
= (EfiStrLen ((CHAR16
*) ConfigResp
) + AltRespLen
+ 1) * sizeof (CHAR16
);
1038 TempStr
= EfiLibAllocateZeroPool (StrBufferLen
);
1039 *ConfigAltResp
= TempStr
;
1040 if (TempStr
== NULL
) {
1041 return EFI_OUT_OF_RESOURCES
;
1045 // <ConfigAltResp> ::= <ConfigResp> ['&' <AltResp>]*
1047 EfiStrCpy (TempStr
, ConfigResp
);
1048 for (Index
= 0; Index
< NumberAltCfg
; Index
++) {
1049 EfiStrCat (TempStr
, L
"&");
1050 EfiStrCat (TempStr
, ConfigHdr
);
1051 EfiStrCat (TempStr
, DescHdr
+ Index
* 16);
1052 EfiStrCat (TempStr
, AltCfg
[Index
]);
1054 gBS
->FreePool (AltCfg
[Index
]);
1057 if (NeedFreeConfigRequest
) {
1058 gBS
->FreePool (ConfigRequest
);
1060 gBS
->FreePool (ConfigHdr
);
1061 gBS
->FreePool (ConfigResp
);
1062 gBS
->FreePool (DescHdr
);
1063 gBS
->FreePool (AltCfg
);
1070 IN OUT UINT8
*Buffer
,
1075 Routine Description:
1076 Swap bytes in the buffer.
1079 Buffer - Binary buffer.
1080 BufferSize - Size of the buffer in bytes.
1091 SwapCount
= BufferSize
/ 2;
1092 for (Index
= 0; Index
< SwapCount
; Index
++) {
1093 Temp
= Buffer
[Index
];
1094 Buffer
[Index
] = Buffer
[BufferSize
- 1 - Index
];
1095 Buffer
[BufferSize
- 1 - Index
] = Temp
;
1105 Routine Description:
1106 Converts the unicode character of the string from uppercase to lowercase.
1109 Str - String to be converted
1117 for (Ptr
= Str
; *Ptr
!= L
'\0'; Ptr
++) {
1118 if (*Ptr
>= L
'A' && *Ptr
<= L
'Z') {
1119 *Ptr
= (CHAR16
) (*Ptr
- L
'A' + L
'a');
1132 Routine Description:
1133 Converts binary buffer to Unicode string in reversed byte order from BufToHexString().
1136 Str - String for output
1137 Buffer - Binary buffer.
1138 BufferSize - Size of the buffer in bytes.
1141 EFI_SUCCESS - The function completed successfully.
1149 NewBuffer
= EfiLibAllocateCopyPool (BufferSize
, Buffer
);
1150 SwapBuffer (NewBuffer
, BufferSize
);
1152 StrBufferLen
= BufferSize
* 2 + 1;
1153 Status
= BufToHexString (Str
, &StrBufferLen
, NewBuffer
, BufferSize
);
1155 gBS
->FreePool (NewBuffer
);
1157 // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
1166 IN OUT UINT8
*Buffer
,
1167 IN OUT UINTN
*BufferSize
,
1172 Routine Description:
1173 Converts Hex String to binary buffer in reversed byte order from HexStringToBuf().
1176 Buffer - Pointer to buffer that receives the data.
1177 BufferSize - Length in bytes of the buffer to hold converted data.
1178 If routine return with EFI_SUCCESS, containing length of converted data.
1179 If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
1180 Str - String to be converted from.
1183 EFI_SUCCESS - The function completed successfully.
1188 UINTN ConvertedStrLen
;
1190 ConvertedStrLen
= 0;
1191 Status
= HexStringToBuf (Buffer
, BufferSize
, Str
, &ConvertedStrLen
);
1192 if (!EFI_ERROR (Status
)) {
1193 SwapBuffer (Buffer
, (ConvertedStrLen
+ 1) / 2);
1200 ConfigStringToUnicode (
1201 IN OUT CHAR16
*UnicodeString
,
1202 IN OUT UINTN
*StrBufferLen
,
1203 IN CHAR16
*ConfigString
1207 Routine Description:
1208 Convert binary representation Config string (e.g. "0041004200430044") to the
1209 original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e.
1210 "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
1213 UnicodeString - Original Unicode string.
1214 StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
1215 Includes tailing '\0' character.
1217 If return EFI_SUCCESS, containing length of Unicode string buffer.
1218 If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
1219 ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
1222 EFI_SUCCESS - Routine success.
1223 EFI_BUFFER_TOO_SMALL - The string buffer is too small.
1232 Len
= EfiStrLen (ConfigString
) / 4;
1233 BufferSize
= (Len
+ 1) * sizeof (CHAR16
);
1235 if (*StrBufferLen
< BufferSize
) {
1236 *StrBufferLen
= BufferSize
;
1237 return EFI_BUFFER_TOO_SMALL
;
1240 *StrBufferLen
= BufferSize
;
1242 for (Index
= 0; Index
< Len
; Index
++) {
1243 BackupChar
= ConfigString
[4];
1244 ConfigString
[4] = L
'\0';
1246 HexStringToBuf ((UINT8
*) UnicodeString
, &BufferSize
, ConfigString
, NULL
);
1248 ConfigString
[4] = BackupChar
;
1255 // Add tailing '\0' character
1257 *UnicodeString
= L
'\0';
1263 UnicodeToConfigString (
1264 IN OUT CHAR16
*ConfigString
,
1265 IN OUT UINTN
*StrBufferLen
,
1266 IN CHAR16
*UnicodeString
1270 Routine Description:
1271 Convert Unicode string to binary representation Config string, e.g.
1272 "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
1273 "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
1276 ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
1277 StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
1278 Includes tailing '\0' character.
1280 If return EFI_SUCCESS, containing length of Unicode string buffer.
1281 If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
1282 UnicodeString - Original Unicode string.
1285 EFI_SUCCESS - Routine success.
1286 EFI_BUFFER_TOO_SMALL - The string buffer is too small.
1295 Len
= EfiStrLen (UnicodeString
);
1296 BufferSize
= (Len
* 4 + 1) * sizeof (CHAR16
);
1298 if (*StrBufferLen
< BufferSize
) {
1299 *StrBufferLen
= BufferSize
;
1300 return EFI_BUFFER_TOO_SMALL
;
1303 *StrBufferLen
= BufferSize
;
1304 String
= ConfigString
;
1306 for (Index
= 0; Index
< Len
; Index
++) {
1307 BufToHexString (ConfigString
, &BufferSize
, (UINT8
*) UnicodeString
, 2);
1314 // Add tailing '\0' character
1316 *ConfigString
= L
'\0';
1319 // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
1326 ConstructConfigHdr (
1327 IN OUT CHAR16
*ConfigHdr
,
1328 IN OUT UINTN
*StrBufferLen
,
1330 IN CHAR16
*Name
, OPTIONAL
1331 IN EFI_HANDLE
*DriverHandle
1335 Routine Description:
1336 Construct <ConfigHdr> using routing information GUID/NAME/PATH.
1339 ConfigHdr - Pointer to the ConfigHdr string.
1340 StrBufferLen - On input: Length in bytes of buffer to hold the ConfigHdr string.
1341 Includes tailing '\0' character.
1343 If return EFI_SUCCESS, containing length of ConfigHdr string buffer.
1344 If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
1345 Guid - Routing information: GUID.
1346 Name - Routing information: NAME.
1347 DriverHandle - Driver handle which contains the routing information: PATH.
1350 EFI_SUCCESS - Routine success.
1351 EFI_BUFFER_TOO_SMALL - The ConfigHdr string buffer is too small.
1357 UINTN DevicePathSize
;
1360 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1364 // There will be no "NAME" in <ConfigHdr> for Name/Value storage
1369 // For buffer storage
1371 NameStrLen
= EfiStrLen (Name
);
1375 // Retrieve DevicePath Protocol associated with this HiiPackageList
1377 Status
= gBS
->HandleProtocol (
1379 &gEfiDevicePathProtocolGuid
,
1380 (VOID
**) &DevicePath
1382 if (EFI_ERROR (Status
)) {
1386 DevicePathSize
= EfiDevicePathSize (DevicePath
);
1389 // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
1390 // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
1392 BufferSize
= (5 + 32 + 6 + NameStrLen
* 4 + 6 + DevicePathSize
* 2 + 1) * sizeof (CHAR16
);
1393 if (*StrBufferLen
< BufferSize
) {
1394 *StrBufferLen
= BufferSize
;
1395 return EFI_BUFFER_TOO_SMALL
;
1398 if (ConfigHdr
== NULL
) {
1399 return EFI_INVALID_PARAMETER
;
1402 *StrBufferLen
= BufferSize
;
1406 EfiStrCpy (StrPtr
, L
"GUID=");
1408 BufferToHexString (StrPtr
, (UINT8
*) Guid
, sizeof (EFI_GUID
));
1412 // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"
1414 EfiStrCpy (StrPtr
, L
"&NAME=");
1417 BufferSize
= (NameStrLen
* 4 + 1) * sizeof (CHAR16
);
1418 UnicodeToConfigString (StrPtr
, &BufferSize
, Name
);
1419 StrPtr
+= (NameStrLen
* 4);
1422 EfiStrCpy (StrPtr
, L
"&PATH=");
1424 BufferToHexString (StrPtr
, (UINT8
*) DevicePath
, DevicePathSize
);
1431 IN EFI_STRING ConfigString
,
1432 IN EFI_GUID
*StorageGuid
, OPTIONAL
1433 IN CHAR16
*StorageName OPTIONAL
1437 Routine Description:
1438 Determines if the Routing data (Guid and Name) is correct in <ConfigHdr>.
1441 ConfigString - Either <ConfigRequest> or <ConfigResp>.
1442 StorageGuid - GUID of the storage.
1443 StorageName - Name of the stoarge.
1446 TRUE - Routing information is correct in ConfigString.
1447 FALSE - Routing information is incorrect in ConfigString.
1460 // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
1461 // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
1463 if (EfiStrLen (ConfigString
) <= (5 + 32 + 6)) {
1470 if (StorageGuid
!= NULL
) {
1472 StrPtr
= ConfigString
+ 5 + 32;
1473 if (*StrPtr
!= L
'&') {
1478 BufferSize
= sizeof (EFI_GUID
);
1479 Status
= HexStringToBuffer (
1486 if (EFI_ERROR (Status
)) {
1490 if (!EfiCompareGuid (&Guid
, StorageGuid
)) {
1499 if (StorageName
!= NULL
) {
1500 StrPtr
= ConfigString
+ 5 + 32 + 6;
1501 while (*StrPtr
!= L
'\0' && *StrPtr
!= L
'&') {
1504 if (*StrPtr
!= L
'&') {
1509 BufferSize
= (EfiStrLen (ConfigString
+ 5 + 32 + 6) + 1) * sizeof (CHAR16
);
1510 Name
= EfiLibAllocatePool (BufferSize
);
1511 ASSERT (Name
!= NULL
);
1512 Status
= ConfigStringToUnicode (
1515 ConfigString
+ 5 + 32 + 6
1519 if (EFI_ERROR (Status
) || (EfiStrCmp (Name
, StorageName
) != 0)) {
1522 gBS
->FreePool (Name
);
1530 IN OUT CHAR16
*String
,
1536 Routine Description:
1537 Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
1540 String - The string to be searched in.
1541 Offset - Offset in BlockName.
1542 Width - Width in BlockName.
1545 TRUE - Block name found.
1546 FALSE - Block name not found.
1553 UINTN ConvertedStrLen
;
1555 while ((String
= EfiStrStr (String
, L
"&OFFSET=")) != NULL
) {
1559 String
= String
+ 8;
1562 BufferSize
= sizeof (UINTN
);
1563 Status
= HexStringToBuf ((UINT8
*) &Data
, &BufferSize
, String
, &ConvertedStrLen
);
1564 if (EFI_ERROR (Status
)) {
1567 String
= String
+ ConvertedStrLen
;
1569 if (Data
!= Offset
) {
1573 if (EfiStrnCmp (String
, L
"&WIDTH=", 7) != 0) {
1576 String
= String
+ 7;
1579 BufferSize
= sizeof (UINTN
);
1580 Status
= HexStringToBuf ((UINT8
*) &Data
, &BufferSize
, String
, &ConvertedStrLen
);
1581 if (EFI_ERROR (Status
)) {
1584 if (Data
== Width
) {
1588 String
= String
+ ConvertedStrLen
;
1596 EFI_GUID
*VariableGuid
, OPTIONAL
1597 CHAR16
*VariableName
, OPTIONAL
1603 Routine Description:
1604 This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser.
1607 VariableGuid - An optional field to indicate the target variable GUID name to use.
1608 VariableName - An optional field to indicate the target human-readable variable name.
1609 BufferSize - On input: Length in bytes of buffer to hold retrived data.
1611 If return EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
1612 Buffer - Buffer to hold retrived data.
1615 EFI_SUCCESS - Routine success.
1616 EFI_BUFFER_TOO_SMALL - The intput buffer is too small.
1627 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1628 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1631 // Locate protocols for use
1633 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1634 if (EFI_ERROR (Status
)) {
1638 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1639 if (EFI_ERROR (Status
)) {
1644 // Retrive formset storage data from Form Browser
1646 ConfigHdr
= mFakeConfigHdr
;
1647 HeaderLen
= EfiStrLen (ConfigHdr
);
1650 ConfigResp
= EfiLibAllocateZeroPool (BufferLen
+ (HeaderLen
+ 1) * sizeof (CHAR16
));
1652 StringPtr
= ConfigResp
+ HeaderLen
;
1656 Status
= FormBrowser2
->BrowserCallback (
1664 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1665 gBS
->FreePool (ConfigResp
);
1666 ConfigResp
= EfiLibAllocateZeroPool (BufferLen
+ (HeaderLen
+ 1) * sizeof (CHAR16
));
1668 StringPtr
= ConfigResp
+ HeaderLen
;
1672 Status
= FormBrowser2
->BrowserCallback (
1681 if (EFI_ERROR (Status
)) {
1682 gBS
->FreePool (ConfigResp
);
1685 EfiCopyMem (ConfigResp
, ConfigHdr
, HeaderLen
* sizeof (UINT16
));
1688 // Convert <ConfigResp> to buffer data
1690 Status
= HiiConfigRouting
->ConfigToBlock (
1697 gBS
->FreePool (ConfigResp
);
1704 EFI_GUID
*VariableGuid
, OPTIONAL
1705 CHAR16
*VariableName
, OPTIONAL
1708 CHAR16
*RequestElement OPTIONAL
1712 Routine Description:
1713 This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser.
1716 VariableGuid - An optional field to indicate the target variable GUID name to use.
1717 VariableName - An optional field to indicate the target human-readable variable name.
1718 BufferSize - Length in bytes of buffer to hold retrived data.
1719 Buffer - Buffer to hold retrived data.
1720 RequestElement - An optional field to specify which part of the buffer data
1721 will be send back to Browser. If NULL, the whole buffer of
1722 data will be committed to Browser.
1723 <RequestElement> ::= &OFFSET=<Number>&WIDTH=<Number>*
1726 EFI_SUCCESS - Routine success.
1727 Other - Updating Browser uncommitted data failed.
1738 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1739 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1740 CHAR16 BlockName
[33];
1741 CHAR16
*ConfigRequest
;
1745 // Locate protocols for use
1747 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1748 if (EFI_ERROR (Status
)) {
1752 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1753 if (EFI_ERROR (Status
)) {
1758 // Prepare <ConfigRequest>
1760 ConfigHdr
= mFakeConfigHdr
;
1761 HeaderLen
= EfiStrLen (ConfigHdr
);
1763 if (RequestElement
== NULL
) {
1765 // RequestElement not specified, use "&OFFSET=0&WIDTH=<BufferSize>" as <BlockName>
1767 BlockName
[0] = L
'\0';
1768 EfiStrCpy (BlockName
, L
"&OFFSET=0&WIDTH=");
1771 // String lenghth of L"&OFFSET=0&WIDTH=" is 16
1773 StringPtr
= BlockName
+ 16;
1774 BufferLen
= sizeof (BlockName
) - (16 * sizeof (CHAR16
));
1775 BufToHexString (StringPtr
, &BufferLen
, (UINT8
*) &BufferSize
, sizeof (UINTN
));
1777 Request
= BlockName
;
1779 Request
= RequestElement
;
1782 BufferLen
= HeaderLen
* sizeof (CHAR16
) + EfiStrSize (Request
);
1783 ConfigRequest
= EfiLibAllocateZeroPool (BufferLen
);
1785 EfiCopyMem (ConfigRequest
, ConfigHdr
, HeaderLen
* sizeof (CHAR16
));
1786 StringPtr
= ConfigRequest
+ HeaderLen
;
1787 EfiStrCpy (StringPtr
, Request
);
1790 // Convert buffer to <ConfigResp>
1792 Status
= HiiConfigRouting
->BlockToConfig (
1800 if (EFI_ERROR (Status
)) {
1801 gBS
->FreePool (ConfigRequest
);
1806 // Skip <ConfigHdr> and '&'
1808 StringPtr
= ConfigResp
+ HeaderLen
+ 1;
1811 // Change uncommitted data in Browser
1813 Status
= FormBrowser2
->BrowserCallback (
1821 gBS
->FreePool (ConfigResp
);
1822 gBS
->FreePool (ConfigRequest
);