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.
463 UINTN DimensionsWidth
;
464 UINTN DimensionsHeight
;
472 CHAR16
**StringArray
;
473 EFI_EVENT TimerEvent
;
474 EFI_EVENT WaitList
[2];
475 UINTN CurrentAttribute
;
476 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*ConOut
;
478 if ((KeyValue
== NULL
) || (String
== NULL
)) {
479 return EFI_INVALID_PARAMETER
;
487 ConOut
= gST
->ConOut
;
488 ConOut
->QueryMode (ConOut
, ConOut
->Mode
->Mode
, &RightColumn
, &BottomRow
);
490 DimensionsWidth
= RightColumn
- LeftColumn
;
491 DimensionsHeight
= BottomRow
- TopRow
;
493 CurrentAttribute
= ConOut
->Mode
->Attribute
;
495 LineBuffer
= EfiLibAllocateZeroPool (DimensionsWidth
* sizeof (CHAR16
));
496 ASSERT (LineBuffer
!= NULL
);
499 // Determine the largest string in the dialog box
500 // Notice we are starting with 1 since String is the first string
502 StringArray
= EfiLibAllocateZeroPool (NumberOfLines
* sizeof (CHAR16
*));
503 LargestString
= EfiStrLen (String
);
504 StringArray
[0] = String
;
506 VA_START (Marker
, String
);
507 for (Index
= 1; Index
< NumberOfLines
; Index
++) {
508 StackString
= VA_ARG (Marker
, CHAR16
*);
510 if (StackString
== NULL
) {
512 return EFI_INVALID_PARAMETER
;
515 StringArray
[Index
] = StackString
;
516 StringLen
= EfiStrLen (StackString
);
517 if (StringLen
> LargestString
) {
518 LargestString
= StringLen
;
523 if ((LargestString
+ 2) > DimensionsWidth
) {
524 LargestString
= DimensionsWidth
- 2;
528 // Subtract the PopUp width from total Columns, allow for one space extra on
529 // each end plus a border.
531 Start
= (DimensionsWidth
- LargestString
- 2) / 2 + LeftColumn
+ 1;
532 End
= Start
+ LargestString
+ 1;
534 Top
= ((DimensionsHeight
- NumberOfLines
- 2) / 2) + TopRow
- 1;
535 Bottom
= Top
+ NumberOfLines
+ 2;
540 ConOut
->EnableCursor (ConOut
, FALSE
);
541 ConOut
->SetAttribute (ConOut
, EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
);
543 StringPtr
= &LineBuffer
[0];
544 *StringPtr
++ = BOXDRAW_DOWN_RIGHT
;
545 for (Index
= 0; Index
< LargestString
; Index
++) {
546 *StringPtr
++ = BOXDRAW_HORIZONTAL
;
548 *StringPtr
++ = BOXDRAW_DOWN_LEFT
;
551 ConOut
->SetCursorPosition (ConOut
, Start
, Top
);
552 ConOut
->OutputString (ConOut
, LineBuffer
);
554 for (Index
= 0; Index
< NumberOfLines
; Index
++) {
555 StringPtr
= &LineBuffer
[0];
556 *StringPtr
++ = BOXDRAW_VERTICAL
;
558 for (Count
= 0; Count
< LargestString
; Count
++) {
559 StringPtr
[Count
] = L
' ';
562 StringLen
= EfiStrLen (StringArray
[Index
]);
563 if (StringLen
> LargestString
) {
564 StringLen
= LargestString
;
567 StringPtr
+ ((LargestString
- StringLen
) / 2),
569 StringLen
* sizeof (CHAR16
)
571 StringPtr
+= LargestString
;
573 *StringPtr
++ = BOXDRAW_VERTICAL
;
576 ConOut
->SetCursorPosition (ConOut
, Start
, Top
+ 1 + Index
);
577 ConOut
->OutputString (ConOut
, LineBuffer
);
580 StringPtr
= &LineBuffer
[0];
581 *StringPtr
++ = BOXDRAW_UP_RIGHT
;
582 for (Index
= 0; Index
< LargestString
; Index
++) {
583 *StringPtr
++ = BOXDRAW_HORIZONTAL
;
585 *StringPtr
++ = BOXDRAW_UP_LEFT
;
588 ConOut
->SetCursorPosition (ConOut
, Start
, Top
+ NumberOfLines
+ 1);
589 ConOut
->OutputString (ConOut
, LineBuffer
);
592 Status
= gBS
->CreateEvent (EFI_EVENT_TIMER
, 0, NULL
, NULL
, &TimerEvent
);
595 // Set a timer event of 1 second expiration
604 // Wait for the keystroke event or the timer
606 WaitList
[0] = gST
->ConIn
->WaitForKey
;
607 WaitList
[1] = TimerEvent
;
608 Status
= gBS
->WaitForEvent (2, WaitList
, &Index
);
611 // Check for the timer expiration
613 if (!EFI_ERROR (Status
) && Index
== 1) {
614 Status
= EFI_TIMEOUT
;
617 gBS
->CloseEvent (TimerEvent
);
618 } while (Status
== EFI_TIMEOUT
);
620 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
621 EfiCopyMem (KeyValue
, &Key
, sizeof (EFI_INPUT_KEY
));
623 ConOut
->SetAttribute (ConOut
, CurrentAttribute
);
624 ConOut
->EnableCursor (ConOut
, TRUE
);
632 IN UINTN
*BufferSize
,
640 Configure the buffer accrording to ConfigBody strings.
643 DefaultId - the ID of default.
644 Buffer - the start address of buffer.
645 BufferSize - the size of buffer.
646 Number - the number of the strings.
649 EFI_BUFFER_TOO_SMALL - the BufferSize is too small to operate.
650 EFI_INVALID_PARAMETER - Buffer is NULL or BufferSize is 0.
651 EFI_SUCCESS - Operation successful.
664 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
665 return EFI_INVALID_PARAMETER
;
672 VA_START (Args
, Number
);
673 for (Index
= 0; Index
< Number
; Index
++) {
674 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
675 EfiCopyMem (&TotalLen
, BufCfgArray
, sizeof (UINT32
));
676 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
678 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
679 EfiCopyMem (&Offset
, BufferPos
, sizeof (UINT16
));
680 BufferPos
+= sizeof (UINT16
);
681 EfiCopyMem (&Width
, BufferPos
, sizeof (UINT16
));
682 BufferPos
+= sizeof (UINT16
);
686 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
688 return EFI_BUFFER_TOO_SMALL
;
691 EfiCopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
696 *BufferSize
= (UINTN
)Offset
;
704 OUT CHAR16
**BlockName
710 Extract block name from the array generated by VFR compiler. The name of
711 this array is "Vfr + <StorageName> + BlockName", e.g. "VfrMyIfrNVDataBlockName".
712 Format of this array is:
713 Array length | 4-bytes
721 Buffer - Array generated by VFR compiler.
722 BlockName - The returned <BlockName>
725 EFI_OUT_OF_RESOURCES - Run out of memory resource.
726 EFI_INVALID_PARAMETER - Buffer is NULL or BlockName is NULL.
727 EFI_SUCCESS - Operation successful.
733 UINT32 BlockNameNumber
;
734 UINTN HexStringBufferLen
;
737 if ((Buffer
== NULL
) || (BlockName
== NULL
)) {
738 return EFI_INVALID_PARAMETER
;
742 // Calculate number of Offset/Width pair
744 EfiCopyMem (&Length
, Buffer
, sizeof (UINT32
));
745 BlockNameNumber
= (Length
- sizeof (UINT32
)) / (sizeof (UINT16
) * 2);
748 // <BlockName> ::= &OFFSET=1234&WIDTH=1234
751 StringPtr
= EfiLibAllocateZeroPool ((BlockNameNumber
* (8 + 4 + 7 + 4) + 1) * sizeof (CHAR16
));
752 *BlockName
= StringPtr
;
753 if (StringPtr
== NULL
) {
754 return EFI_OUT_OF_RESOURCES
;
757 Buffer
+= sizeof (UINT32
);
758 for (Index
= 0; Index
< BlockNameNumber
; Index
++) {
759 EfiStrCpy (StringPtr
, L
"&OFFSET=");
762 HexStringBufferLen
= 5;
763 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
764 Buffer
+= sizeof (UINT16
);
767 EfiStrCpy (StringPtr
, L
"&WIDTH=");
770 HexStringBufferLen
= 5;
771 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
772 Buffer
+= sizeof (UINT16
);
782 OUT CHAR16
**BlockConfig
788 Extract block config from the array generated by VFR compiler. The name of
789 this array is "Vfr + <StorageName> + Default<HexCh>4", e.g. "VfrMyIfrNVDataDefault0000".
792 Buffer - Array generated by VFR compiler.
793 BlockConfig - The returned <BlockConfig>
796 EFI_OUT_OF_RESOURCES - Run out of memory resource.
797 EFI_INVALID_PARAMETER - Buffer is NULL or BlockConfig is NULL.
798 EFI_SUCCESS - Operation successful.
804 UINTN HexStringBufferLen
;
810 if ((Buffer
== NULL
) || (BlockConfig
== NULL
)) {
811 return EFI_INVALID_PARAMETER
;
815 // Calculate length of AltResp string
816 // Format of Default value array is:
817 // Array length | 4-bytes
820 // Value | Variable length
823 // Value | Variable length
825 // When value is 1 byte in length, overhead of AltResp string will be maximum,
826 // BlockConfig ::= <&OFFSET=1234&WIDTH=1234&VALUE=12>+
827 // | 8 | 4 | 7 | 4 | 7 |2|
828 // so the maximum length of BlockConfig could be calculated as:
829 // (ArrayLength / 5) * (8 + 4 + 7 + 4 + 7 + 2) = ArrayLength * 6.4 < ArrayLength * 7
831 EfiCopyMem (&Length
, Buffer
, sizeof (UINT32
));
832 BufferEnd
= Buffer
+ Length
;
833 StringPtr
= EfiLibAllocatePool (Length
* 7 * sizeof (CHAR16
));
834 *BlockConfig
= StringPtr
;
835 if (StringPtr
== NULL
) {
836 return EFI_OUT_OF_RESOURCES
;
838 StringEnd
= StringPtr
+ (Length
* 7);
840 Buffer
+= sizeof (UINT32
);
841 while (Buffer
< BufferEnd
) {
842 EfiStrCpy (StringPtr
, L
"&OFFSET=");
845 HexStringBufferLen
= 5;
846 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
847 Buffer
+= sizeof (UINT16
);
850 EfiStrCpy (StringPtr
, L
"&WIDTH=");
853 HexStringBufferLen
= 5;
854 BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, sizeof (UINT16
));
855 EfiCopyMem (&Width
, Buffer
, sizeof (UINT16
));
856 Buffer
+= sizeof (UINT16
);
859 EfiStrCpy (StringPtr
, L
"&VALUE=");
862 HexStringBufferLen
= StringEnd
- StringPtr
;
863 Status
= BufToHexString (StringPtr
, &HexStringBufferLen
, Buffer
, Width
);
864 if (EFI_ERROR (Status
)) {
868 StringPtr
+= (Width
* 2);
875 ConstructConfigAltResp (
876 IN EFI_STRING ConfigRequest
, OPTIONAL
877 OUT EFI_STRING
*Progress
,
878 OUT EFI_STRING
*ConfigAltResp
,
881 IN EFI_HANDLE
*DriverHandle
,
882 IN VOID
*BufferStorage
,
883 IN UINTN BufferStorageSize
,
884 IN VOID
*BlockNameArray
, OPTIONAL
885 IN UINTN NumberAltCfg
,
887 //IN UINT16 AltCfgId,
888 //IN VOID *DefaultValueArray,
894 Construct <ConfigAltResp> for a buffer storage.
897 ConfigRequest - The Config request string. If set to NULL, all the
898 configurable elements will be extracted from BlockNameArray.
899 ConfigAltResp - The returned <ConfigAltResp>.
900 Progress - On return, points to a character in the Request.
901 Guid - GUID of the buffer storage.
902 Name - Name of the buffer storage.
903 DriverHandle - The DriverHandle which is used to invoke HiiDatabase
904 protocol interface NewPackageList().
905 BufferStorage - Content of the buffer storage.
906 BufferStorageSize - Length in bytes of the buffer storage.
907 BlockNameArray - Array generated by VFR compiler.
908 NumberAltCfg - Number of Default value array generated by VFR compiler.
909 The sequential input parameters will be number of
910 AltCfgId and DefaultValueArray pairs. When set to 0,
911 there will be no <AltResp>.
914 EFI_OUT_OF_RESOURCES - Run out of memory resource.
915 EFI_INVALID_PARAMETER - ConfigAltResp is NULL.
916 EFI_SUCCESS - Operation successful.
927 VOID
*DefaultValueArray
;
929 EFI_STRING ConfigResp
;
934 BOOLEAN NeedFreeConfigRequest
;
935 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
937 if (ConfigAltResp
== NULL
) {
938 return EFI_INVALID_PARAMETER
;
942 // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
946 Status
= ConstructConfigHdr (
953 if (Status
== EFI_BUFFER_TOO_SMALL
) {
954 ConfigHdr
= EfiLibAllocateZeroPool (StrBufferLen
);
955 Status
= ConstructConfigHdr (
964 if (EFI_ERROR (Status
) || (ConfigHdr
== NULL
)) {
969 // Construct <ConfigResp>
971 NeedFreeConfigRequest
= FALSE
;
972 if (ConfigRequest
== NULL
) {
974 // If ConfigRequest is set to NULL, export all configurable elements in BlockNameArray
976 Status
= ExtractBlockName (BlockNameArray
, &BlockName
);
977 if (EFI_ERROR (Status
)) {
981 StrBufferLen
= EfiStrSize (ConfigHdr
);
982 StrBufferLen
= StrBufferLen
+ EfiStrSize (BlockName
) - sizeof (CHAR16
);
983 ConfigRequest
= EfiLibAllocateZeroPool (StrBufferLen
);
984 EfiStrCpy (ConfigRequest
, ConfigHdr
);
985 EfiStrCat (ConfigRequest
, BlockName
);
986 NeedFreeConfigRequest
= TRUE
;
989 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
990 if (EFI_ERROR (Status
)) {
994 Status
= HiiConfigRouting
->BlockToConfig (
1000 (Progress
== NULL
) ? &TempStr
: Progress
1002 if (EFI_ERROR (Status
)) {
1007 // Construct <AltResp>
1009 DescHdr
= EfiLibAllocateZeroPool (NumberAltCfg
* 16 * sizeof (CHAR16
));
1010 StringPtr
= DescHdr
;
1011 AltCfg
= EfiLibAllocateZeroPool (NumberAltCfg
* sizeof (CHAR16
*));
1013 VA_START (Args
, NumberAltCfg
);
1014 for (Index
= 0; Index
< NumberAltCfg
; Index
++) {
1015 AltCfgId
= (UINT16
) VA_ARG (Args
, UINT16
);
1016 DefaultValueArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
1021 AltRespLen
+= (EfiStrLen (ConfigHdr
) + 1);
1023 StringPtr
= DescHdr
+ Index
* 16;
1024 EfiStrCpy (StringPtr
, L
"&ALTCFG=");
1025 AltRespLen
+= (8 + sizeof (UINT16
) * 2);
1028 BufToHexString (StringPtr
+ 8, &StrBufferLen
, (UINT8
*) &AltCfgId
, sizeof (UINT16
));
1029 Status
= ExtractBlockConfig (DefaultValueArray
, &AltCfg
[Index
]);
1030 if (EFI_ERROR (Status
)) {
1034 AltRespLen
+= EfiStrLen (AltCfg
[Index
]);
1039 // Generate the final <ConfigAltResp>
1041 StrBufferLen
= (EfiStrLen ((CHAR16
*) ConfigResp
) + AltRespLen
+ 1) * sizeof (CHAR16
);
1042 TempStr
= EfiLibAllocateZeroPool (StrBufferLen
);
1043 *ConfigAltResp
= TempStr
;
1044 if (TempStr
== NULL
) {
1045 return EFI_OUT_OF_RESOURCES
;
1049 // <ConfigAltResp> ::= <ConfigResp> ['&' <AltResp>]*
1051 EfiStrCpy (TempStr
, ConfigResp
);
1052 for (Index
= 0; Index
< NumberAltCfg
; Index
++) {
1053 EfiStrCat (TempStr
, L
"&");
1054 EfiStrCat (TempStr
, ConfigHdr
);
1055 EfiStrCat (TempStr
, DescHdr
+ Index
* 16);
1056 EfiStrCat (TempStr
, AltCfg
[Index
]);
1058 gBS
->FreePool (AltCfg
[Index
]);
1061 if (NeedFreeConfigRequest
) {
1062 gBS
->FreePool (ConfigRequest
);
1064 gBS
->FreePool (ConfigHdr
);
1065 gBS
->FreePool (ConfigResp
);
1066 gBS
->FreePool (DescHdr
);
1067 gBS
->FreePool (AltCfg
);
1074 IN OUT UINT8
*Buffer
,
1079 Routine Description:
1080 Swap bytes in the buffer.
1083 Buffer - Binary buffer.
1084 BufferSize - Size of the buffer in bytes.
1095 SwapCount
= BufferSize
/ 2;
1096 for (Index
= 0; Index
< SwapCount
; Index
++) {
1097 Temp
= Buffer
[Index
];
1098 Buffer
[Index
] = Buffer
[BufferSize
- 1 - Index
];
1099 Buffer
[BufferSize
- 1 - Index
] = Temp
;
1109 Routine Description:
1110 Converts the unicode character of the string from uppercase to lowercase.
1113 Str - String to be converted
1121 for (Ptr
= Str
; *Ptr
!= L
'\0'; Ptr
++) {
1122 if (*Ptr
>= L
'A' && *Ptr
<= L
'Z') {
1123 *Ptr
= (CHAR16
) (*Ptr
- L
'A' + L
'a');
1136 Routine Description:
1137 Converts binary buffer to Unicode string in reversed byte order from BufToHexString().
1140 Str - String for output
1141 Buffer - Binary buffer.
1142 BufferSize - Size of the buffer in bytes.
1145 EFI_SUCCESS - The function completed successfully.
1153 NewBuffer
= EfiLibAllocateCopyPool (BufferSize
, Buffer
);
1154 SwapBuffer (NewBuffer
, BufferSize
);
1156 StrBufferLen
= BufferSize
* 2 + 1;
1157 Status
= BufToHexString (Str
, &StrBufferLen
, NewBuffer
, BufferSize
);
1159 gBS
->FreePool (NewBuffer
);
1161 // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
1170 IN OUT UINT8
*Buffer
,
1171 IN OUT UINTN
*BufferSize
,
1176 Routine Description:
1177 Converts Hex String to binary buffer in reversed byte order from HexStringToBuf().
1180 Buffer - Pointer to buffer that receives the data.
1181 BufferSize - Length in bytes of the buffer to hold converted data.
1182 If routine return with EFI_SUCCESS, containing length of converted data.
1183 If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
1184 Str - String to be converted from.
1187 EFI_SUCCESS - The function completed successfully.
1192 UINTN ConvertedStrLen
;
1194 ConvertedStrLen
= 0;
1195 Status
= HexStringToBuf (Buffer
, BufferSize
, Str
, &ConvertedStrLen
);
1196 if (!EFI_ERROR (Status
)) {
1197 SwapBuffer (Buffer
, (ConvertedStrLen
+ 1) / 2);
1204 ConfigStringToUnicode (
1205 IN OUT CHAR16
*UnicodeString
,
1206 IN OUT UINTN
*StrBufferLen
,
1207 IN CHAR16
*ConfigString
1211 Routine Description:
1212 Convert binary representation Config string (e.g. "0041004200430044") to the
1213 original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e.
1214 "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
1217 UnicodeString - Original Unicode string.
1218 StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
1219 Includes tailing '\0' character.
1221 If return EFI_SUCCESS, containing length of Unicode string buffer.
1222 If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
1223 ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
1226 EFI_SUCCESS - Routine success.
1227 EFI_BUFFER_TOO_SMALL - The string buffer is too small.
1236 Len
= EfiStrLen (ConfigString
) / 4;
1237 BufferSize
= (Len
+ 1) * sizeof (CHAR16
);
1239 if (*StrBufferLen
< BufferSize
) {
1240 *StrBufferLen
= BufferSize
;
1241 return EFI_BUFFER_TOO_SMALL
;
1244 *StrBufferLen
= BufferSize
;
1246 for (Index
= 0; Index
< Len
; Index
++) {
1247 BackupChar
= ConfigString
[4];
1248 ConfigString
[4] = L
'\0';
1250 HexStringToBuf ((UINT8
*) UnicodeString
, &BufferSize
, ConfigString
, NULL
);
1252 ConfigString
[4] = BackupChar
;
1259 // Add tailing '\0' character
1261 *UnicodeString
= L
'\0';
1267 UnicodeToConfigString (
1268 IN OUT CHAR16
*ConfigString
,
1269 IN OUT UINTN
*StrBufferLen
,
1270 IN CHAR16
*UnicodeString
1274 Routine Description:
1275 Convert Unicode string to binary representation Config string, e.g.
1276 "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
1277 "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
1280 ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
1281 StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
1282 Includes tailing '\0' character.
1284 If return EFI_SUCCESS, containing length of Unicode string buffer.
1285 If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
1286 UnicodeString - Original Unicode string.
1289 EFI_SUCCESS - Routine success.
1290 EFI_BUFFER_TOO_SMALL - The string buffer is too small.
1299 Len
= EfiStrLen (UnicodeString
);
1300 BufferSize
= (Len
* 4 + 1) * sizeof (CHAR16
);
1302 if (*StrBufferLen
< BufferSize
) {
1303 *StrBufferLen
= BufferSize
;
1304 return EFI_BUFFER_TOO_SMALL
;
1307 *StrBufferLen
= BufferSize
;
1308 String
= ConfigString
;
1310 for (Index
= 0; Index
< Len
; Index
++) {
1311 BufToHexString (ConfigString
, &BufferSize
, (UINT8
*) UnicodeString
, 2);
1318 // Add tailing '\0' character
1320 *ConfigString
= L
'\0';
1323 // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
1330 ConstructConfigHdr (
1331 IN OUT CHAR16
*ConfigHdr
,
1332 IN OUT UINTN
*StrBufferLen
,
1334 IN CHAR16
*Name
, OPTIONAL
1335 IN EFI_HANDLE
*DriverHandle
1339 Routine Description:
1340 Construct <ConfigHdr> using routing information GUID/NAME/PATH.
1343 ConfigHdr - Pointer to the ConfigHdr string.
1344 StrBufferLen - On input: Length in bytes of buffer to hold the ConfigHdr string.
1345 Includes tailing '\0' character.
1347 If return EFI_SUCCESS, containing length of ConfigHdr string buffer.
1348 If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
1349 Guid - Routing information: GUID.
1350 Name - Routing information: NAME.
1351 DriverHandle - Driver handle which contains the routing information: PATH.
1354 EFI_SUCCESS - Routine success.
1355 EFI_BUFFER_TOO_SMALL - The ConfigHdr string buffer is too small.
1361 UINTN DevicePathSize
;
1364 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1368 // There will be no "NAME" in <ConfigHdr> for Name/Value storage
1373 // For buffer storage
1375 NameStrLen
= EfiStrLen (Name
);
1379 // Retrieve DevicePath Protocol associated with this HiiPackageList
1381 Status
= gBS
->HandleProtocol (
1383 &gEfiDevicePathProtocolGuid
,
1384 (VOID
**) &DevicePath
1386 if (EFI_ERROR (Status
)) {
1390 DevicePathSize
= EfiDevicePathSize (DevicePath
);
1393 // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
1394 // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
1396 BufferSize
= (5 + 32 + 6 + NameStrLen
* 4 + 6 + DevicePathSize
* 2 + 1) * sizeof (CHAR16
);
1397 if (*StrBufferLen
< BufferSize
) {
1398 *StrBufferLen
= BufferSize
;
1399 return EFI_BUFFER_TOO_SMALL
;
1402 if (ConfigHdr
== NULL
) {
1403 return EFI_INVALID_PARAMETER
;
1406 *StrBufferLen
= BufferSize
;
1410 EfiStrCpy (StrPtr
, L
"GUID=");
1412 BufferToHexString (StrPtr
, (UINT8
*) Guid
, sizeof (EFI_GUID
));
1416 // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"
1418 EfiStrCpy (StrPtr
, L
"&NAME=");
1421 BufferSize
= (NameStrLen
* 4 + 1) * sizeof (CHAR16
);
1422 UnicodeToConfigString (StrPtr
, &BufferSize
, Name
);
1423 StrPtr
+= (NameStrLen
* 4);
1426 EfiStrCpy (StrPtr
, L
"&PATH=");
1428 BufferToHexString (StrPtr
, (UINT8
*) DevicePath
, DevicePathSize
);
1435 IN EFI_STRING ConfigString
,
1436 IN EFI_GUID
*StorageGuid
, OPTIONAL
1437 IN CHAR16
*StorageName OPTIONAL
1441 Routine Description:
1442 Determines if the Routing data (Guid and Name) is correct in <ConfigHdr>.
1445 ConfigString - Either <ConfigRequest> or <ConfigResp>.
1446 StorageGuid - GUID of the storage.
1447 StorageName - Name of the stoarge.
1450 TRUE - Routing information is correct in ConfigString.
1451 FALSE - Routing information is incorrect in ConfigString.
1464 // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
1465 // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
1467 if (EfiStrLen (ConfigString
) <= (5 + 32 + 6)) {
1474 if (StorageGuid
!= NULL
) {
1476 StrPtr
= ConfigString
+ 5 + 32;
1477 if (*StrPtr
!= L
'&') {
1482 BufferSize
= sizeof (EFI_GUID
);
1483 Status
= HexStringToBuffer (
1490 if (EFI_ERROR (Status
)) {
1494 if (!EfiCompareGuid (&Guid
, StorageGuid
)) {
1503 if (StorageName
!= NULL
) {
1504 StrPtr
= ConfigString
+ 5 + 32 + 6;
1505 while (*StrPtr
!= L
'\0' && *StrPtr
!= L
'&') {
1508 if (*StrPtr
!= L
'&') {
1513 BufferSize
= (EfiStrLen (ConfigString
+ 5 + 32 + 6) + 1) * sizeof (CHAR16
);
1514 Name
= EfiLibAllocatePool (BufferSize
);
1515 ASSERT (Name
!= NULL
);
1516 Status
= ConfigStringToUnicode (
1519 ConfigString
+ 5 + 32 + 6
1523 if (EFI_ERROR (Status
) || (EfiStrCmp (Name
, StorageName
) != 0)) {
1526 gBS
->FreePool (Name
);
1534 IN OUT CHAR16
*String
,
1540 Routine Description:
1541 Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
1544 String - The string to be searched in.
1545 Offset - Offset in BlockName.
1546 Width - Width in BlockName.
1549 TRUE - Block name found.
1550 FALSE - Block name not found.
1557 UINTN ConvertedStrLen
;
1559 while ((String
= EfiStrStr (String
, L
"&OFFSET=")) != NULL
) {
1563 String
= String
+ 8;
1566 BufferSize
= sizeof (UINTN
);
1567 Status
= HexStringToBuf ((UINT8
*) &Data
, &BufferSize
, String
, &ConvertedStrLen
);
1568 if (EFI_ERROR (Status
)) {
1571 String
= String
+ ConvertedStrLen
;
1573 if (Data
!= Offset
) {
1577 if (EfiStrnCmp (String
, L
"&WIDTH=", 7) != 0) {
1580 String
= String
+ 7;
1583 BufferSize
= sizeof (UINTN
);
1584 Status
= HexStringToBuf ((UINT8
*) &Data
, &BufferSize
, String
, &ConvertedStrLen
);
1585 if (EFI_ERROR (Status
)) {
1588 if (Data
== Width
) {
1592 String
= String
+ ConvertedStrLen
;
1600 EFI_GUID
*VariableGuid
, OPTIONAL
1601 CHAR16
*VariableName
, OPTIONAL
1607 Routine Description:
1608 This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser.
1611 VariableGuid - An optional field to indicate the target variable GUID name to use.
1612 VariableName - An optional field to indicate the target human-readable variable name.
1613 BufferSize - On input: Length in bytes of buffer to hold retrived data.
1615 If return EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
1616 Buffer - Buffer to hold retrived data.
1619 EFI_SUCCESS - Routine success.
1620 EFI_BUFFER_TOO_SMALL - The intput buffer is too small.
1631 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1632 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1635 // Locate protocols for use
1637 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1638 if (EFI_ERROR (Status
)) {
1642 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1643 if (EFI_ERROR (Status
)) {
1648 // Retrive formset storage data from Form Browser
1650 ConfigHdr
= mFakeConfigHdr
;
1651 HeaderLen
= EfiStrLen (ConfigHdr
);
1654 ConfigResp
= EfiLibAllocateZeroPool (BufferLen
+ (HeaderLen
+ 1) * sizeof (CHAR16
));
1656 StringPtr
= ConfigResp
+ HeaderLen
;
1660 Status
= FormBrowser2
->BrowserCallback (
1668 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1669 gBS
->FreePool (ConfigResp
);
1670 ConfigResp
= EfiLibAllocateZeroPool (BufferLen
+ (HeaderLen
+ 1) * sizeof (CHAR16
));
1672 StringPtr
= ConfigResp
+ HeaderLen
;
1676 Status
= FormBrowser2
->BrowserCallback (
1685 if (EFI_ERROR (Status
)) {
1686 gBS
->FreePool (ConfigResp
);
1689 EfiCopyMem (ConfigResp
, ConfigHdr
, HeaderLen
* sizeof (UINT16
));
1692 // Convert <ConfigResp> to buffer data
1694 Status
= HiiConfigRouting
->ConfigToBlock (
1701 gBS
->FreePool (ConfigResp
);
1708 EFI_GUID
*VariableGuid
, OPTIONAL
1709 CHAR16
*VariableName
, OPTIONAL
1712 CHAR16
*RequestElement OPTIONAL
1716 Routine Description:
1717 This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser.
1720 VariableGuid - An optional field to indicate the target variable GUID name to use.
1721 VariableName - An optional field to indicate the target human-readable variable name.
1722 BufferSize - Length in bytes of buffer to hold retrived data.
1723 Buffer - Buffer to hold retrived data.
1724 RequestElement - An optional field to specify which part of the buffer data
1725 will be send back to Browser. If NULL, the whole buffer of
1726 data will be committed to Browser.
1727 <RequestElement> ::= &OFFSET=<Number>&WIDTH=<Number>*
1730 EFI_SUCCESS - Routine success.
1731 Other - Updating Browser uncommitted data failed.
1742 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1743 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1744 CHAR16 BlockName
[33];
1745 CHAR16
*ConfigRequest
;
1749 // Locate protocols for use
1751 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1752 if (EFI_ERROR (Status
)) {
1756 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1757 if (EFI_ERROR (Status
)) {
1762 // Prepare <ConfigRequest>
1764 ConfigHdr
= mFakeConfigHdr
;
1765 HeaderLen
= EfiStrLen (ConfigHdr
);
1767 if (RequestElement
== NULL
) {
1769 // RequestElement not specified, use "&OFFSET=0&WIDTH=<BufferSize>" as <BlockName>
1771 BlockName
[0] = L
'\0';
1772 EfiStrCpy (BlockName
, L
"&OFFSET=0&WIDTH=");
1775 // String lenghth of L"&OFFSET=0&WIDTH=" is 16
1777 StringPtr
= BlockName
+ 16;
1778 BufferLen
= sizeof (BlockName
) - (16 * sizeof (CHAR16
));
1779 BufToHexString (StringPtr
, &BufferLen
, (UINT8
*) &BufferSize
, sizeof (UINTN
));
1781 Request
= BlockName
;
1783 Request
= RequestElement
;
1786 BufferLen
= HeaderLen
* sizeof (CHAR16
) + EfiStrSize (Request
);
1787 ConfigRequest
= EfiLibAllocateZeroPool (BufferLen
);
1789 EfiCopyMem (ConfigRequest
, ConfigHdr
, HeaderLen
* sizeof (CHAR16
));
1790 StringPtr
= ConfigRequest
+ HeaderLen
;
1791 EfiStrCpy (StringPtr
, Request
);
1794 // Convert buffer to <ConfigResp>
1796 Status
= HiiConfigRouting
->BlockToConfig (
1804 if (EFI_ERROR (Status
)) {
1805 gBS
->FreePool (ConfigRequest
);
1810 // Skip <ConfigHdr> and '&'
1812 StringPtr
= ConfigResp
+ HeaderLen
+ 1;
1815 // Change uncommitted data in Browser
1817 Status
= FormBrowser2
->BrowserCallback (
1825 gBS
->FreePool (ConfigResp
);
1826 gBS
->FreePool (ConfigRequest
);