3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. 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.
23 #include "UefiIfrLibraryInternal.h"
28 UINT16 mFakeConfigHdr
[] = L
"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";
32 GetPackageDataFromPackageList (
33 IN EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
,
34 IN UINT32 PackageIndex
,
35 OUT UINT32
*BufferLen
,
36 OUT EFI_HII_PACKAGE_HEADER
**Buffer
40 EFI_HII_PACKAGE_HEADER
*Package
;
42 UINT32 PackageListLength
;
43 EFI_HII_PACKAGE_HEADER PackageHeader
= {0, 0};
45 ASSERT(HiiPackageList
!= NULL
);
47 if ((BufferLen
== NULL
) || (Buffer
== NULL
)) {
48 return EFI_INVALID_PARAMETER
;
53 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
54 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
55 while (Offset
< PackageListLength
) {
56 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
57 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
58 if (Index
== PackageIndex
) {
61 Offset
+= PackageHeader
.Length
;
64 if (Offset
>= PackageListLength
) {
66 // no package found in this Package List
71 *BufferLen
= PackageHeader
.Length
;
78 UpdateFormPackageData (
79 IN EFI_GUID
*FormSetGuid
,
80 IN EFI_FORM_ID FormId
,
81 IN EFI_HII_PACKAGE_HEADER
*Package
,
82 IN UINT32 PackageLength
,
85 IN EFI_HII_UPDATE_DATA
*Data
,
86 OUT UINT8
**TempBuffer
,
87 OUT UINT32
*TempBufferSize
92 EFI_HII_PACKAGE_HEADER PackageHeader
;
94 EFI_IFR_OP_HEADER
*IfrOpHdr
;
100 EFI_IFR_OP_HEADER
*AddOpCode
;
102 if ((TempBuffer
== NULL
) || (TempBufferSize
== NULL
)) {
103 return EFI_INVALID_PARAMETER
;
106 *TempBufferSize
= PackageLength
;
108 *TempBufferSize
+= Data
->Offset
;
110 *TempBuffer
= AllocateZeroPool (*TempBufferSize
);
111 if (*TempBuffer
== NULL
) {
112 return EFI_OUT_OF_RESOURCES
;
115 CopyMem (*TempBuffer
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
116 *TempBufferSize
= sizeof (EFI_HII_PACKAGE_HEADER
);
117 BufferPos
= *TempBuffer
+ sizeof (EFI_HII_PACKAGE_HEADER
);
119 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
120 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
121 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
122 GetFormSet
= (BOOLEAN
) ((FormSetGuid
== NULL
) ? TRUE
: FALSE
);
126 while (Offset
< PackageHeader
.Length
) {
127 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
128 BufferPos
+= IfrOpHdr
->Length
;
129 *TempBufferSize
+= IfrOpHdr
->Length
;
131 switch (IfrOpHdr
->OpCode
) {
132 case EFI_IFR_FORM_SET_OP
:
133 if (FormSetGuid
!= NULL
) {
134 if (CompareMem (&((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, FormSetGuid
, sizeof (EFI_GUID
)) == 0) {
140 case EFI_IFR_FORM_OP
:
141 if (CompareMem (&((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, &FormId
, sizeof (EFI_FORM_ID
)) == 0) {
146 case EFI_IFR_GUID_OP
:
147 if (!GetFormSet
|| !GetForm
|| Updated
) {
149 // Go to the next Op-Code
151 Offset
+= IfrOpHdr
->Length
;
152 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
156 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
157 CopyMem (&LabelNumber
, &((EFI_IFR_GUID_LABEL
*)IfrOpHdr
)->Number
, sizeof (UINT16
));
158 if ((ExtendOpCode
!= EFI_IFR_EXTEND_OP_LABEL
) || (LabelNumber
!= Label
)) {
160 // Go to the next Op-Code
162 Offset
+= IfrOpHdr
->Length
;
163 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
167 if (Insert
&& (Data
!= NULL
)) {
169 // insert the DataCount amount of opcodes to TempBuffer if Data is NULL remove
170 // DataCount amount of opcodes unless runing into a label.
172 AddOpCode
= (EFI_IFR_OP_HEADER
*)Data
->Data
;
174 while (AddSize
< Data
->Offset
) {
175 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
176 BufferPos
+= AddOpCode
->Length
;
177 *TempBufferSize
+= AddOpCode
->Length
;
179 AddSize
+= AddOpCode
->Length
;
180 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (AddOpCode
) + AddOpCode
->Length
);
184 // Search the next Label.
187 Offset
+= IfrOpHdr
->Length
;
189 // Search the next label and Fail if not label found.
191 if (Offset
>= PackageHeader
.Length
) {
194 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
195 if (IfrOpHdr
->OpCode
== EFI_IFR_GUID_OP
) {
196 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
197 if (ExtendOpCode
== EFI_IFR_EXTEND_OP_LABEL
) {
204 AddOpCode
= (EFI_IFR_OP_HEADER
*)Data
->Data
;
206 while (AddSize
< Data
->Offset
) {
207 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
208 BufferPos
+= AddOpCode
->Length
;
209 *TempBufferSize
+= AddOpCode
->Length
;
211 AddSize
+= AddOpCode
->Length
;
212 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (AddOpCode
) + AddOpCode
->Length
);
217 // copy the next label
219 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
220 BufferPos
+= IfrOpHdr
->Length
;
221 *TempBufferSize
+= IfrOpHdr
->Length
;
231 // Go to the next Op-Code
233 Offset
+= IfrOpHdr
->Length
;
234 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
238 // Update the package length.
240 PackageHeader
.Length
= *TempBufferSize
;
241 CopyMem (*TempBuffer
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
245 gBS
->FreePool (*TempBuffer
);
247 return EFI_NOT_FOUND
;
255 This function allows the caller to update a form that has
256 previously been registered with the EFI HII database.
258 @param Handle Hii Handle
259 @param FormSetGuid The formset should be updated.
260 @param FormId The form should be updated.
261 @param Label Update information starting immediately after this
263 @param Insert If TRUE and Data is not NULL, insert data after
264 Label. If FALSE, replace opcodes between two
266 @param Data The adding data; If NULL, remove opcodes between
269 @retval EFI_SUCCESS Update success.
270 @retval Other Update fail.
275 IN EFI_HII_HANDLE Handle
,
276 IN EFI_GUID
*FormSetGuid
, OPTIONAL
277 IN EFI_FORM_ID FormId
,
280 IN EFI_HII_UPDATE_DATA
*Data
284 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
285 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
287 EFI_HII_PACKAGE_LIST_HEADER
*UpdateBuffer
;
289 UINT8
*UpdateBufferPos
;
290 EFI_HII_PACKAGE_HEADER PackageHeader
;
291 EFI_HII_PACKAGE_HEADER
*Package
;
292 UINT32 PackageLength
;
293 EFI_HII_PACKAGE_HEADER
*TempBuffer
;
294 UINT32 TempBufferSize
;
298 return EFI_INVALID_PARAMETER
;
301 LocateHiiProtocols ();
302 HiiDatabase
= gIfrLibHiiDatabase
;
305 // Get the orginal package list
308 HiiPackageList
= NULL
;
309 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
310 if (Status
== EFI_BUFFER_TOO_SMALL
) {
311 HiiPackageList
= AllocatePool (BufferSize
);
312 ASSERT (HiiPackageList
!= NULL
);
314 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
315 if (EFI_ERROR (Status
)) {
316 gBS
->FreePool (HiiPackageList
);
322 // Calculate and allocate space for retrieval of IFR data
324 BufferSize
+= Data
->Offset
;
325 UpdateBuffer
= AllocateZeroPool (BufferSize
);
326 if (UpdateBuffer
== NULL
) {
327 return EFI_OUT_OF_RESOURCES
;
330 UpdateBufferPos
= (UINT8
*) UpdateBuffer
;
333 // copy the package list header
335 CopyMem (UpdateBufferPos
, HiiPackageList
, sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
336 UpdateBufferPos
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
339 for (Index
= 0; ; Index
++) {
340 Status
= GetPackageDataFromPackageList (HiiPackageList
, Index
, &PackageLength
, &Package
);
341 if (Status
== EFI_SUCCESS
) {
342 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
343 if ((PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) && !Updated
) {
344 Status
= UpdateFormPackageData (FormSetGuid
, FormId
, Package
, PackageLength
, Label
, Insert
, Data
, (UINT8
**)&TempBuffer
, &TempBufferSize
);
345 if (!EFI_ERROR(Status
)) {
346 if (FormSetGuid
== NULL
) {
349 CopyMem (UpdateBufferPos
, TempBuffer
, TempBufferSize
);
350 UpdateBufferPos
+= TempBufferSize
;
351 gBS
->FreePool (TempBuffer
);
356 CopyMem (UpdateBufferPos
, Package
, PackageLength
);
357 UpdateBufferPos
+= PackageLength
;
358 } else if (Status
== EFI_NOT_FOUND
) {
361 gBS
->FreePool (HiiPackageList
);
367 // Update package list length
369 BufferSize
= UpdateBufferPos
- (UINT8
*) UpdateBuffer
;
370 CopyMem (&UpdateBuffer
->PackageLength
, &BufferSize
, sizeof (UINT32
));
372 gBS
->FreePool (HiiPackageList
);
374 return HiiDatabase
->UpdatePackageList (HiiDatabase
, Handle
, UpdateBuffer
);
379 Draw a dialog and return the selected key.
381 @param NumberOfLines The number of lines for the dialog box
382 @param KeyValue The EFI_KEY value returned if HotKey is TRUE..
383 @param String Pointer to the first string in the list
384 @param ... A series of (quantity == NumberOfLines) text
385 strings which will be used to construct the dialog
388 @retval EFI_SUCCESS Displayed dialog and received user interaction
389 @retval EFI_INVALID_PARAMETER One of the parameters was invalid.
394 IN UINTN NumberOfLines
,
395 OUT EFI_INPUT_KEY
*KeyValue
,
409 UINTN DimensionsWidth
;
410 UINTN DimensionsHeight
;
418 CHAR16
**StringArray
;
419 EFI_EVENT TimerEvent
;
420 EFI_EVENT WaitList
[2];
421 UINTN CurrentAttribute
;
422 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
424 if ((KeyValue
== NULL
) || (String
== NULL
)) {
425 return EFI_INVALID_PARAMETER
;
433 ConOut
= gST
->ConOut
;
434 ConOut
->QueryMode (ConOut
, ConOut
->Mode
->Mode
, &RightColumn
, &BottomRow
);
436 DimensionsWidth
= RightColumn
- LeftColumn
;
437 DimensionsHeight
= BottomRow
- TopRow
;
439 CurrentAttribute
= ConOut
->Mode
->Attribute
;
441 LineBuffer
= AllocateZeroPool (DimensionsWidth
* sizeof (CHAR16
));
442 ASSERT (LineBuffer
!= NULL
);
445 // Determine the largest string in the dialog box
446 // Notice we are starting with 1 since String is the first string
448 StringArray
= AllocateZeroPool (NumberOfLines
* sizeof (CHAR16
*));
449 LargestString
= StrLen (String
);
450 StringArray
[0] = String
;
452 VA_START (Marker
, String
);
453 for (Index
= 1; Index
< NumberOfLines
; Index
++) {
454 StackString
= VA_ARG (Marker
, CHAR16
*);
456 if (StackString
== NULL
) {
457 return EFI_INVALID_PARAMETER
;
460 StringArray
[Index
] = StackString
;
461 StringLen
= StrLen (StackString
);
462 if (StringLen
> LargestString
) {
463 LargestString
= StringLen
;
467 if ((LargestString
+ 2) > DimensionsWidth
) {
468 LargestString
= DimensionsWidth
- 2;
472 // Subtract the PopUp width from total Columns, allow for one space extra on
473 // each end plus a border.
475 Start
= (DimensionsWidth
- LargestString
- 2) / 2 + LeftColumn
+ 1;
477 Top
= ((DimensionsHeight
- NumberOfLines
- 2) / 2) + TopRow
- 1;
482 ConOut
->EnableCursor (ConOut
, FALSE
);
483 ConOut
->SetAttribute (ConOut
, EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
);
485 StringPtr
= &LineBuffer
[0];
486 *StringPtr
++ = BOXDRAW_DOWN_RIGHT
;
487 for (Index
= 0; Index
< LargestString
; Index
++) {
488 *StringPtr
++ = BOXDRAW_HORIZONTAL
;
490 *StringPtr
++ = BOXDRAW_DOWN_LEFT
;
493 ConOut
->SetCursorPosition (ConOut
, Start
, Top
);
494 ConOut
->OutputString (ConOut
, LineBuffer
);
496 for (Index
= 0; Index
< NumberOfLines
; Index
++) {
497 StringPtr
= &LineBuffer
[0];
498 *StringPtr
++ = BOXDRAW_VERTICAL
;
500 for (Count
= 0; Count
< LargestString
; Count
++) {
501 StringPtr
[Count
] = L
' ';
504 StringLen
= StrLen (StringArray
[Index
]);
505 if (StringLen
> LargestString
) {
506 StringLen
= LargestString
;
509 StringPtr
+ ((LargestString
- StringLen
) / 2),
511 StringLen
* sizeof (CHAR16
)
513 StringPtr
+= LargestString
;
515 *StringPtr
++ = BOXDRAW_VERTICAL
;
518 ConOut
->SetCursorPosition (ConOut
, Start
, Top
+ 1 + Index
);
519 ConOut
->OutputString (ConOut
, LineBuffer
);
522 StringPtr
= &LineBuffer
[0];
523 *StringPtr
++ = BOXDRAW_UP_RIGHT
;
524 for (Index
= 0; Index
< LargestString
; Index
++) {
525 *StringPtr
++ = BOXDRAW_HORIZONTAL
;
527 *StringPtr
++ = BOXDRAW_UP_LEFT
;
530 ConOut
->SetCursorPosition (ConOut
, Start
, Top
+ NumberOfLines
+ 1);
531 ConOut
->OutputString (ConOut
, LineBuffer
);
534 Status
= gBS
->CreateEvent (EVT_TIMER
, 0, NULL
, NULL
, &TimerEvent
);
537 // Set a timer event of 1 second expiration
546 // Wait for the keystroke event or the timer
548 WaitList
[0] = gST
->ConIn
->WaitForKey
;
549 WaitList
[1] = TimerEvent
;
550 Status
= gBS
->WaitForEvent (2, WaitList
, &Index
);
553 // Check for the timer expiration
555 if (!EFI_ERROR (Status
) && Index
== 1) {
556 Status
= EFI_TIMEOUT
;
559 gBS
->CloseEvent (TimerEvent
);
560 } while (Status
== EFI_TIMEOUT
);
562 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
563 CopyMem (KeyValue
, &Key
, sizeof (EFI_INPUT_KEY
));
565 ConOut
->SetAttribute (ConOut
, CurrentAttribute
);
566 ConOut
->EnableCursor (ConOut
, TRUE
);
573 Configure the buffer accrording to ConfigBody strings.
575 @param DefaultId the ID of default.
576 @param Buffer the start address of buffer.
577 @param BufferSize the size of buffer.
578 @param Number the number of the strings.
580 @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
581 @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
582 @retval EFI_SUCCESS Operation successful.
588 IN UINTN
*BufferSize
,
602 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
603 return EFI_INVALID_PARAMETER
;
610 VA_START (Args
, Number
);
611 for (Index
= 0; Index
< Number
; Index
++) {
612 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
613 CopyMem (&TotalLen
, BufCfgArray
, sizeof (UINT32
));
614 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
616 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
617 CopyMem (&Offset
, BufferPos
, sizeof (UINT16
));
618 BufferPos
+= sizeof (UINT16
);
619 CopyMem (&Width
, BufferPos
, sizeof (UINT16
));
620 BufferPos
+= sizeof (UINT16
);
624 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
625 return EFI_BUFFER_TOO_SMALL
;
628 CopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
633 *BufferSize
= (UINTN
)Offset
;
640 Swap bytes in the buffer.
642 @param Buffer Binary buffer.
643 @param BufferSize Size of the buffer in bytes.
651 IN OUT UINT8
*Buffer
,
659 SwapCount
= (BufferSize
- 1) / 2;
660 for (Index
= 0; Index
< SwapCount
; Index
++) {
661 Temp
= Buffer
[Index
];
662 Buffer
[Index
] = Buffer
[BufferSize
- 1 - Index
];
663 Buffer
[BufferSize
- 1 - Index
] = Temp
;
669 Converts binary buffer to Unicode string in reversed byte order from R8_BufToHexString().
671 @param Str String for output
672 @param Buffer Binary buffer.
673 @param BufferSize Size of the buffer in bytes.
675 @retval EFI_SUCCESS The function completed successfully.
689 NewBuffer
= AllocateCopyPool (BufferSize
, Buffer
);
690 SwapBuffer (NewBuffer
, BufferSize
);
692 StrBufferLen
= (BufferSize
+ 1) * sizeof (CHAR16
);
693 Status
= R8_BufToHexString (Str
, &StrBufferLen
, NewBuffer
, BufferSize
);
695 gBS
->FreePool (NewBuffer
);
702 Converts Hex String to binary buffer in reversed byte order from R8_HexStringToBuf().
704 @param Buffer Pointer to buffer that receives the data.
705 @param BufferSize Length in bytes of the buffer to hold converted
706 data. If routine return with EFI_SUCCESS,
707 containing length of converted data. If routine
708 return with EFI_BUFFER_TOO_SMALL, containg length
710 @param Str String to be converted from.
712 @retval EFI_SUCCESS The function completed successfully.
717 IN OUT UINT8
*Buffer
,
718 IN OUT UINTN
*BufferSize
,
723 UINTN ConvertedStrLen
;
726 Status
= R8_HexStringToBuf (Buffer
, BufferSize
, Str
, &ConvertedStrLen
);
727 if (!EFI_ERROR (Status
)) {
728 SwapBuffer (Buffer
, ConvertedStrLen
);
736 Construct <ConfigHdr> using routing information GUID/NAME/PATH.
738 @param ConfigHdr Pointer to the ConfigHdr string.
739 @param StrBufferLen On input: Length in bytes of buffer to hold the
740 ConfigHdr string. Includes tailing '\0' character.
741 On output: If return EFI_SUCCESS, containing
742 length of ConfigHdr string buffer. If return
743 EFI_BUFFER_TOO_SMALL, containg length of string
745 @param Guid Routing information: GUID.
746 @param Name Routing information: NAME.
747 @param DriverHandle Driver handle which contains the routing
750 @retval EFI_SUCCESS Routine success.
751 @retval EFI_BUFFER_TOO_SMALL The ConfigHdr string buffer is too small.
756 IN OUT CHAR16
*ConfigHdr
,
757 IN OUT UINTN
*StrBufferLen
,
759 IN CHAR16
*Name
, OPTIONAL
760 IN EFI_HANDLE
*DriverHandle
765 UINTN DevicePathSize
;
768 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
772 // There will be no "NAME" in <ConfigHdr> for Name/Value storage
777 // For buffer storage
779 NameStrLen
= StrLen (Name
);
783 // Retrieve DevicePath Protocol associated with this HiiPackageList
785 Status
= gBS
->HandleProtocol (
787 &gEfiDevicePathProtocolGuid
,
788 (VOID
**) &DevicePath
790 if (EFI_ERROR (Status
)) {
794 DevicePathSize
= GetDevicePathSize (DevicePath
);
797 // GUID=<HexCh>32&NAME=<Alpha>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
798 // | 5 | 32 | 6 | NameStrLen | 6 | DevicePathStrLen |
800 BufferSize
= (5 + 32 + 6 + NameStrLen
+ 6 + DevicePathSize
* 2 + 1) * sizeof (CHAR16
);
801 if (*StrBufferLen
< BufferSize
) {
802 *StrBufferLen
= BufferSize
;
803 return EFI_BUFFER_TOO_SMALL
;
806 *StrBufferLen
= BufferSize
;
810 StrCpy (StrPtr
, L
"GUID=");
812 BufferToHexString (StrPtr
, (UINT8
*) Guid
, sizeof (EFI_GUID
));
815 StrCpy (StrPtr
, L
"&NAME=");
818 StrCpy (StrPtr
, Name
);
819 StrPtr
+= NameStrLen
;
822 StrCpy (StrPtr
, L
"&PATH=");
824 BufferToHexString (StrPtr
, (UINT8
*) DevicePath
, DevicePathSize
);
831 Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
833 @param String The string to be searched in.
834 @param Offset Offset in BlockName.
835 @param Width Width in BlockName.
837 @retval TRUE Block name found.
838 @retval FALSE Block name not found.
843 IN OUT CHAR16
*String
,
851 UINTN ConvertedStrLen
;
853 while ((String
= StrStr (String
, L
"&OFFSET=")) != NULL
) {
860 BufferSize
= sizeof (UINTN
);
861 Status
= R8_HexStringToBuf ((UINT8
*) &Data
, &BufferSize
, String
, &ConvertedStrLen
);
862 if (EFI_ERROR (Status
)) {
865 String
= String
+ ConvertedStrLen
;
867 if (Data
!= Offset
) {
871 if (StrnCmp (String
, L
"&WIDTH=", 7) != 0) {
877 BufferSize
= sizeof (UINTN
);
878 Status
= R8_HexStringToBuf ((UINT8
*) &Data
, &BufferSize
, String
, &ConvertedStrLen
);
879 if (EFI_ERROR (Status
)) {
886 String
= String
+ ConvertedStrLen
;
894 This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser.
896 @param VariableGuid An optional field to indicate the target variable
898 @param VariableName An optional field to indicate the target
899 human-readable variable name.
900 @param BufferSize On input: Length in bytes of buffer to hold
901 retrived data. On output: If return
902 EFI_BUFFER_TOO_SMALL, containg length of buffer
904 @param Buffer Buffer to hold retrived data.
906 @retval EFI_SUCCESS Routine success.
907 @retval EFI_BUFFER_TOO_SMALL The intput buffer is too small.
912 EFI_GUID
*VariableGuid
, OPTIONAL
913 CHAR16
*VariableName
, OPTIONAL
925 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
926 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
929 // Locate protocols for use
931 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
932 if (EFI_ERROR (Status
)) {
936 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
937 if (EFI_ERROR (Status
)) {
942 // Retrive formset storage data from Form Browser
944 ConfigHdr
= mFakeConfigHdr
;
945 HeaderLen
= StrLen (ConfigHdr
);
948 ConfigResp
= AllocateZeroPool (BufferLen
+ HeaderLen
);
950 StringPtr
= ConfigResp
+ HeaderLen
;
954 Status
= FormBrowser2
->BrowserCallback (
962 if (Status
== EFI_BUFFER_TOO_SMALL
) {
963 gBS
->FreePool (ConfigResp
);
964 ConfigResp
= AllocateZeroPool (BufferLen
+ HeaderLen
);
966 StringPtr
= ConfigResp
+ HeaderLen
;
970 Status
= FormBrowser2
->BrowserCallback (
979 if (EFI_ERROR (Status
)) {
980 gBS
->FreePool (ConfigResp
);
983 CopyMem (ConfigResp
, ConfigHdr
, HeaderLen
* sizeof (UINT16
));
986 // Convert <ConfigResp> to buffer data
988 Status
= HiiConfigRouting
->ConfigToBlock (
995 gBS
->FreePool (ConfigResp
);
1002 This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser.
1004 @param VariableGuid An optional field to indicate the target variable
1006 @param VariableName An optional field to indicate the target
1007 human-readable variable name.
1008 @param BufferSize Length in bytes of buffer to hold retrived data.
1009 @param Buffer Buffer to hold retrived data.
1010 @param RequestElement An optional field to specify which part of the
1011 buffer data will be send back to Browser. If NULL,
1012 the whole buffer of data will be committed to
1013 Browser. <RequestElement> ::=
1014 &OFFSET=<Number>&WIDTH=<Number>*
1016 @retval EFI_SUCCESS Routine success.
1017 @retval Other Updating Browser uncommitted data failed.
1022 EFI_GUID
*VariableGuid
, OPTIONAL
1023 CHAR16
*VariableName
, OPTIONAL
1026 CHAR16
*RequestElement OPTIONAL
1036 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1037 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1038 CHAR16 BlockName
[33];
1039 CHAR16
*ConfigRequest
;
1043 // Locate protocols for use
1045 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1046 if (EFI_ERROR (Status
)) {
1050 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1051 if (EFI_ERROR (Status
)) {
1056 // Prepare <ConfigRequest>
1058 ConfigHdr
= mFakeConfigHdr
;
1059 HeaderLen
= StrLen (ConfigHdr
);
1061 if (RequestElement
== NULL
) {
1063 // RequestElement not specified, use "&OFFSET=0&WIDTH=<BufferSize>" as <BlockName>
1065 BlockName
[0] = L
'\0';
1066 StrCpy (BlockName
, L
"&OFFSET=0&WIDTH=");
1069 // String lenghth of L"&OFFSET=0&WIDTH=" is 16
1071 StringPtr
= BlockName
+ 16;
1072 BufferLen
= sizeof (BlockName
) - (16 * sizeof (CHAR16
));
1073 R8_BufToHexString (StringPtr
, &BufferLen
, (UINT8
*) &BufferSize
, sizeof (UINTN
));
1075 Request
= BlockName
;
1077 Request
= RequestElement
;
1080 BufferLen
= HeaderLen
* sizeof (CHAR16
) + StrSize (Request
);
1081 ConfigRequest
= AllocateZeroPool (BufferLen
);
1083 CopyMem (ConfigRequest
, ConfigHdr
, HeaderLen
* sizeof (CHAR16
));
1084 StringPtr
= ConfigRequest
+ HeaderLen
;
1085 StrCpy (StringPtr
, Request
);
1088 // Convert buffer to <ConfigResp>
1090 Status
= HiiConfigRouting
->BlockToConfig (
1098 if (EFI_ERROR (Status
)) {
1099 gBS
->FreePool (ConfigResp
);
1104 // Skip <ConfigHdr> and '&'
1106 StringPtr
= ConfigResp
+ HeaderLen
+ 1;
1109 // Change uncommitted data in Browser
1111 Status
= FormBrowser2
->BrowserCallback (
1119 gBS
->FreePool (ConfigResp
);