3 Copyright (c) 2006, 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 This file contains the form processing code to the HII database.
23 #include "HiiDatabase.h"
28 OUT CHAR16
*UnicodeStr
,
35 This function converts ASCII string to Unicode string.
39 UnicodeStr - NULL terminated Unicode output string.
40 AsciieStr - NULL terminated ASCII input string.
44 Start of the Unicode ouput string.
49 CHAR16
*Str
= UnicodeStr
;
51 *(UnicodeStr
++) = (CHAR16
) *AsciiStr
;
52 if (*(AsciiStr
++) == '\0') {
68 This function converts Unicode string to ASCII string.
72 AsciieStr - NULL terminated ASCII output string.
73 UnicodeStr - NULL terminated Unicode input string.
77 Start of the ASCII ouput string.
82 CHAR8
*Str
= AsciiStr
;
84 *(AsciiStr
++) = (CHAR8
) *UnicodeStr
;
85 if (*(UnicodeStr
++) == '\0') {
93 ExtractDevicePathData (
94 IN EFI_HII_DATA_TABLE
*DataTable
,
96 IN OUT UINT8
**ExportBufferPtr
110 ExportBuffer
= *ExportBufferPtr
;
113 // BUGBUG - don't have devicepath data yet, setting dummy value
116 ExportBuffer
= (UINT8
*) DataTable
;
117 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Type
= EFI_HII_DEVICE_PATH
;
118 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Length
= (UINT32
) (sizeof (EFI_HII_DEVICE_PATH_PACK
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
121 // BUGBUG - part of hack - skip the Device Path Pack.....place some data
123 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_DEVICE_PATH_PACK
);
125 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->Type
= EFI_END_ENTIRE_DEVICE_PATH
;
126 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->SubType
= EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
;
129 // BUGBUG - still part of hack....
131 ExportBuffer
= ExportBuffer
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
132 *ExportBufferPtr
= ExportBuffer
;
137 ExtractVariableData (
138 IN OUT EFI_HII_DATA_TABLE
*DataTable
,
140 IN OUT UINT8
**ExportBufferPtr
146 This function extract the EFI_HII_VARIABLE_PACK portion from the
147 each of the EFI_HII_PACKAGE_INSTANCE in HII handle database.
151 DataTable - On input, this parameter point to the EFI_HII_DATA_TABLE structure
152 of the final data buffer for the EFI_HII_EXPORT interface. This function
153 update the NumberOfVariableData attribute.
154 IfrData - It points to a staring address of a EFI_HII_IFR_PACK structure.
155 ExportBufferPtr - On input, it points the starting address of the data buffer to
156 host the variable pack. On output, it is the starting address
157 of data buffer for the next extraction operation.
164 EFI_HII_VARIABLE_PACK
*VariableContents
;
170 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
171 EFI_PHYSICAL_ADDRESS CallbackHandle
;
177 ExportBuffer
= *ExportBufferPtr
;
179 for (Index
= 0; IfrData
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
180 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
182 switch (IfrData
[Index
]) {
183 case EFI_IFR_FORM_SET_OP
:
184 TempValue
= EFI_HII_VARIABLE
;
185 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
186 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
189 // If the variable has 0 size, do not process it
191 if (TempValue
== 0) {
195 // Add the size of the variable pack overhead. Later, will also add the size of the
196 // name of the variable.
198 TempValue
= TempValue
+ sizeof (EFI_HII_VARIABLE_PACK
);
200 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
203 &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->CallbackHandle
,
204 sizeof (EFI_PHYSICAL_ADDRESS
)
206 if (CallbackHandle
!= 0) {
207 Status
= gBS
->HandleProtocol (
208 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
209 &gEfiFormCallbackProtocolGuid
,
210 (VOID
*) &FormCallback
212 ASSERT_EFI_ERROR (Status
);
215 // Since we have a "Setup" variable that wasn't specified by a variable op-code
216 // it will have a VariableId of 0. All other variable op-codes will have a designation
220 CopyMem (&VariableContents
->VariableId
, &TempValue
, sizeof (UINT16
));
221 CopyMem (&VariableContents
->VariableGuid
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->Guid
, sizeof (EFI_GUID
));
222 TempValue
= sizeof (SETUP_MAP_NAME
);
223 CopyMem (&VariableContents
->VariableNameLength
, &TempValue
, sizeof (UINT32
));
226 // Add the size of the name to the Header Length
229 CopyMem (&TempValue2
, &VariableContents
->Header
.Length
, sizeof (UINT32
));
230 TempValue2
= TempValue
+ TempValue2
;
231 CopyMem (&VariableContents
->Header
.Length
, &TempValue2
, sizeof (UINT32
));
233 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
234 CopyMem (ExportBuffer
, SETUP_MAP_NAME
, sizeof (SETUP_MAP_NAME
));
235 ExportBuffer
= ExportBuffer
+ sizeof (SETUP_MAP_NAME
);
237 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
239 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
240 Status
= FormCallback
->NvRead (
242 (CHAR16
*) SETUP_MAP_NAME
,
243 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
248 ASSERT_EFI_ERROR (Status
);
250 Status
= gRT
->GetVariable (
251 (CHAR16
*) SETUP_MAP_NAME
,
252 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
257 ASSERT_EFI_ERROR (Status
);
260 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + TempValue
);
261 DataTable
->NumberOfVariableData
++;
264 case EFI_IFR_VARSTORE_OP
:
265 TempValue
= EFI_HII_VARIABLE
;
266 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
267 CopyMem (&TempValue
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Size
, sizeof (UINT16
));
270 // If the variable has 0 size, do not process it
272 if (TempValue
== 0) {
276 // Add the size of the variable pack overhead. Later, will also add the size of the
277 // name of the variable.
279 TempValue
= TempValue
+ sizeof (EFI_HII_VARIABLE_PACK
);
281 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
282 CopyMem (&VariableContents
->VariableId
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->VarId
, sizeof (UINT16
));
283 CopyMem (&VariableContents
->VariableGuid
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Guid
, sizeof (EFI_GUID
));
284 TempValue
= (UINTN
) ((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Header
.Length
- sizeof (EFI_IFR_VARSTORE
);
285 TempValue
= TempValue
* 2;
286 CopyMem (&VariableContents
->VariableNameLength
, &TempValue
, sizeof (UINT32
));
289 // Add the size of the name to the Header Length
292 CopyMem (&TempValue2
, &VariableContents
->Header
.Length
, sizeof (UINT32
));
293 TempValue2
= TempValue
+ TempValue2
;
294 CopyMem (&VariableContents
->Header
.Length
, &TempValue2
, sizeof (UINT32
));
296 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
297 String
= (CHAR16
*) ExportBuffer
;
298 for (Index2
= 0; Index2
< TempValue
/ 2; Index2
++) {
299 ExportBuffer
[Index2
* 2] = IfrData
[Index
+ sizeof (EFI_IFR_VARSTORE
) + Index2
];
300 ExportBuffer
[Index2
* 2 + 1] = 0;
303 ExportBuffer
= ExportBuffer
+ TempValue
;
305 CopyMem (&TempValue
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Size
, sizeof (UINT16
));
307 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
308 Status
= FormCallback
->NvRead (
311 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
316 ASSERT_EFI_ERROR (Status
);
318 Status
= gRT
->GetVariable (
320 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
325 ASSERT_EFI_ERROR (Status
);
328 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + TempValue
);
329 DataTable
->NumberOfVariableData
++;
333 Index
= IfrData
[Index
+ 1] + Index
;
336 // If we have added a variable pack, add a dummy empty one to signify the end
338 if (ExportBuffer
!= *ExportBufferPtr
) {
339 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
340 TempValue
= EFI_HII_VARIABLE
;
341 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
342 TempValue
= sizeof (EFI_HII_VARIABLE_PACK
);
343 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
344 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
347 *ExportBufferPtr
= ExportBuffer
;
353 IN EFI_HII_PROTOCOL
*This
,
354 IN EFI_HII_HANDLE Handle
,
355 IN OUT UINTN
*BufferSize
,
362 This function allows a program to extract a form or form package that has
363 previously been registered with the EFI HII database.
371 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
372 EFI_HII_DATA
*HiiData
;
373 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
374 EFI_HII_IFR_PACK
*FormPack
;
377 EFI_HII_EXPORT_TABLE
*ExportTable
;
378 EFI_HII_DATA_TABLE
*DataTable
;
379 BOOLEAN VariableExist
;
380 UINT16 NumberOfHiiDataTables
;
387 return EFI_INVALID_PARAMETER
;
390 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
392 HandleDatabase
= HiiData
->DatabaseHead
;
396 PackageInstance
= NULL
;
397 NumberOfHiiDataTables
= 0;
400 SizeNeeded
= sizeof (EFI_HII_EXPORT_TABLE
);
403 // How many total tables are there?
405 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
406 if ((Handle
!= 0) && (Handle
!= HandleDatabase
->Handle
)) {
410 VariableExist
= FALSE
;
411 NumberOfHiiDataTables
++;
412 PackageInstance
= HandleDatabase
->Buffer
;
413 if (PackageInstance
== NULL
) {
417 // Extract Size of Export Package
419 SizeNeeded
= SizeNeeded
+ PackageInstance
->IfrSize
420 + PackageInstance
->StringSize
421 + sizeof (EFI_HII_DATA_TABLE
)
422 + sizeof (EFI_HII_DEVICE_PATH_PACK
);
425 // BUGBUG We aren't inserting Device path data yet
427 SizeNeeded
= SizeNeeded
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
430 // Extract Size of Variable Data
432 if (PackageInstance
->IfrSize
> 0) {
433 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
436 // No IFR? No variable information
441 RawData
= (UINT8
*) FormPack
;
443 for (Index
= 0; RawData
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
444 switch (RawData
[Index
]) {
445 case EFI_IFR_FORM_SET_OP
:
446 CopyMem (&VariableSize
, &((EFI_IFR_FORM_SET
*) &RawData
[Index
])->NvDataSize
, sizeof (UINT16
));
447 SizeNeeded
= SizeNeeded
+ VariableSize
+ sizeof (SETUP_MAP_NAME
) + sizeof (EFI_HII_VARIABLE_PACK
);
448 VariableExist
= TRUE
;
451 case EFI_IFR_VARSTORE_OP
:
452 CopyMem (&VariableSize
, &((EFI_IFR_VARSTORE
*) &RawData
[Index
])->Size
, sizeof (UINT16
));
453 SizeNeeded
= SizeNeeded
+ VariableSize
+ sizeof (EFI_HII_VARIABLE_PACK
);
455 // We will be expanding the stored ASCII name to a Unicode string. This will cause some memory overhead
456 // Since the VARSTORE size already takes in consideration the ASCII size, we need to size it and add another
457 // instance of it. Essentially, 2 ASCII strings == 1 Unicode string in size.
459 TempValue
= (UINTN
) ((EFI_IFR_VARSTORE
*) &RawData
[Index
])->Header
.Length
- sizeof (EFI_IFR_VARSTORE
);
460 SizeNeeded
= SizeNeeded
+ TempValue
* 2;
461 VariableExist
= TRUE
;
465 Index
= RawData
[Index
+ 1] + Index
;
468 // If a variable exists for this handle, add an additional variable pack overhead to
469 // indicate that we will have an extra null Variable Pack to signify the end of the Variable Packs
472 SizeNeeded
= SizeNeeded
+ sizeof (EFI_HII_VARIABLE_PACK
);
476 if (SizeNeeded
> *BufferSize
) {
477 *BufferSize
= SizeNeeded
;
478 return EFI_BUFFER_TOO_SMALL
;
481 // Zero out the incoming buffer
483 ZeroMem (Buffer
, *BufferSize
);
486 // Cast the Buffer to EFI_HII_EXPORT_TABLE
488 ExportTable
= (EFI_HII_EXPORT_TABLE
*) Buffer
;
491 // Set the Revision for the Export Table
493 CopyMem (&ExportTable
->Revision
, &gEfiHiiProtocolGuid
, sizeof (EFI_GUID
));
495 ExportBuffer
= (UINT8
*) (UINTN
) (((UINT8
*) ExportTable
) + sizeof (EFI_HII_EXPORT_TABLE
));
496 HandleDatabase
= HiiData
->DatabaseHead
;
499 // Check numeric value against the head of the database
501 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
502 DataTable
= (EFI_HII_DATA_TABLE
*) ExportBuffer
;
503 PackageInstance
= HandleDatabase
->Buffer
;
505 // If not asking for a specific handle, export the entire database
508 ExportTable
->NumberOfHiiDataTables
= NumberOfHiiDataTables
;
509 CopyMem (&DataTable
->PackageGuid
, &PackageInstance
->Guid
, sizeof (EFI_GUID
));
510 DataTable
->HiiHandle
= PackageInstance
->Handle
;
511 DataTable
->DevicePathOffset
= (UINT32
) (sizeof (EFI_HII_DATA_TABLE
));
514 // Start Dumping DevicePath
516 ExtractDevicePathData (DataTable
, RawData
, &ExportBuffer
);
518 if (((UINTN
) ExportBuffer
) == ((UINTN
) DataTable
)) {
520 // If there is no DevicePath information - set offset to 0 to signify the absence of data to parse
522 DataTable
->DevicePathOffset
= 0;
525 DataTable
->VariableDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
527 if (PackageInstance
->IfrSize
> 0) {
528 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
530 RawData
= (UINT8
*) FormPack
;
534 // Start dumping the Variable Data
536 ExtractVariableData (DataTable
, RawData
, &ExportBuffer
);
537 DataTable
->IfrDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
539 if (DataTable
->VariableDataOffset
== DataTable
->IfrDataOffset
) {
540 DataTable
->VariableDataOffset
= 0;
543 // Start dumping the IFR data (Note: It is in an IFR PACK)
545 CopyMem (ExportBuffer
, &PackageInstance
->IfrData
, PackageInstance
->IfrSize
);
546 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + PackageInstance
->IfrSize
);
547 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
550 // Start dumping the String data (Note: It is in a String PACK)
552 if (PackageInstance
->StringSize
> 0) {
553 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
554 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
555 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
557 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
558 for (; TempValue
!= 0;) {
559 DataTable
->NumberOfLanguages
++;
560 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
561 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
564 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
566 DataTable
->StringDataOffset
= 0;
570 // No IFR? No variable information. If Offset is 0, means there is none. (Hmm - this might be prunable - no strings to export if no IFR - we always have a stub)
572 DataTable
->VariableDataOffset
= 0;
573 DataTable
->IfrDataOffset
= 0;
574 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
577 // Start dumping the String data - NOTE: It is in String Pack form
579 if (PackageInstance
->StringSize
> 0) {
580 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
581 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
582 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
584 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
585 for (; TempValue
!= 0;) {
586 DataTable
->NumberOfLanguages
++;
587 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
588 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
591 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
593 DataTable
->StringDataOffset
= 0;
598 // Match the numeric value with the database entry - if matched, extract PackageInstance
600 if (Handle
== HandleDatabase
->Handle
) {
601 PackageInstance
= HandleDatabase
->Buffer
;
602 ExportTable
->NumberOfHiiDataTables
= NumberOfHiiDataTables
;
603 DataTable
->HiiHandle
= PackageInstance
->Handle
;
604 CopyMem (&DataTable
->PackageGuid
, &PackageInstance
->Guid
, sizeof (EFI_GUID
));
607 // Start Dumping DevicePath
609 ExtractDevicePathData (DataTable
, RawData
, &ExportBuffer
);
610 DataTable
->VariableDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
612 if (PackageInstance
->IfrSize
> 0) {
613 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
615 RawData
= (UINT8
*) FormPack
;
619 // Start dumping the Variable Data
621 ExtractVariableData (DataTable
, RawData
, &ExportBuffer
);
622 DataTable
->IfrDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
624 if (DataTable
->VariableDataOffset
== DataTable
->IfrDataOffset
) {
625 DataTable
->VariableDataOffset
= 0;
628 // Start dumping the IFR data
630 CopyMem (ExportBuffer
, &PackageInstance
->IfrData
, PackageInstance
->IfrSize
);
631 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + PackageInstance
->IfrSize
);
632 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
635 // Start dumping the String data - NOTE: It is in String Pack form
637 if (PackageInstance
->StringSize
> 0) {
638 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
639 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
640 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
642 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
643 for (; TempValue
!= 0;) {
644 DataTable
->NumberOfLanguages
++;
645 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
646 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
649 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
651 DataTable
->StringDataOffset
= 0;
655 // No IFR? No variable information. If Offset is 0, means there is none.
657 DataTable
->VariableDataOffset
= 0;
658 DataTable
->IfrDataOffset
= 0;
659 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
662 // Start dumping the String data - Note: It is in String Pack form
664 if (PackageInstance
->StringSize
> 0) {
665 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
666 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
667 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
669 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
670 for (; TempValue
!= 0;) {
671 DataTable
->NumberOfLanguages
++;
672 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
673 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
676 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
678 DataTable
->StringDataOffset
= 0;
692 IN EFI_HII_PROTOCOL
*This
,
693 IN EFI_HII_HANDLE Handle
,
694 IN EFI_FORM_ID FormId
,
695 IN OUT UINTN
*BufferLengthTemp
,
702 This function allows a program to extract a form or form package that has
703 previously been registered with the EFI HII database.
706 This - A pointer to the EFI_HII_PROTOCOL instance.
708 Handle - Handle on which the form resides. Type EFI_HII_HANDLE is defined in
709 EFI_HII_PROTOCOL.NewPack() in the Packages section.
711 FormId - The ID of the form to return. If the ID is zero, the entire form package is returned.
712 Type EFI_FORM_ID is defined in "Related Definitions" below.
714 BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if
715 the length was sufficient and, if it was not, the length that is required to fit the
718 Buffer - The buffer designed to receive the form(s).
722 EFI_SUCCESS - Buffer filled with the requested forms. BufferLength
725 EFI_INVALID_PARAMETER - The handle is unknown.
727 EFI_NOT_FOUND - A form on the requested handle cannot be found with the
730 EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.
734 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
735 EFI_HII_DATA
*HiiData
;
736 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
737 EFI_HII_IFR_PACK
*FormPack
;
739 EFI_IFR_OP_HEADER
*Location
;
740 UINT16
*BufferLength
= (UINT16
*) BufferLengthTemp
;
743 return EFI_INVALID_PARAMETER
;
746 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
748 HandleDatabase
= HiiData
->DatabaseHead
;
750 PackageInstance
= NULL
;
753 // Check numeric value against the head of the database
755 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
757 // Match the numeric value with the database entry - if matched, extract PackageInstance
759 if (Handle
== HandleDatabase
->Handle
) {
760 PackageInstance
= HandleDatabase
->Buffer
;
765 // No handle was found - error condition
767 if (PackageInstance
== NULL
) {
768 return EFI_NOT_FOUND
;
771 // Based on if there is IFR data in this package instance, determine
772 // what the location is of the beginning of the string data.
774 if (PackageInstance
->IfrSize
> 0) {
775 FormPack
= (EFI_HII_IFR_PACK
*) (&PackageInstance
->IfrData
);
778 // If there is no IFR data return an error
780 return EFI_NOT_FOUND
;
783 // If requesting the entire Form Package
787 // Return an error if buffer is too small
789 if (PackageInstance
->IfrSize
> *BufferLength
|| Buffer
== NULL
) {
790 *BufferLength
= (UINT16
) PackageInstance
->IfrSize
;
791 return EFI_BUFFER_TOO_SMALL
;
794 CopyMem (Buffer
, FormPack
, PackageInstance
->IfrSize
);
797 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
798 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
801 // Look for the FormId requested
803 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
804 switch (Location
->OpCode
) {
805 case EFI_IFR_FORM_OP
:
806 Form
= (EFI_IFR_FORM
*) Location
;
809 // If we found a Form Op-code and it is of the correct Id, copy it and return
811 if (Form
->FormId
== FormId
) {
812 if (Location
->Length
> *BufferLength
|| Buffer
== NULL
) {
813 *BufferLength
= Location
->Length
;
814 return EFI_BUFFER_TOO_SMALL
;
816 for (; Location
->OpCode
!= EFI_IFR_END_FORM_OP
;) {
817 CopyMem (Buffer
, Location
, Location
->Length
);
818 Buffer
= Buffer
+ Location
->Length
;
819 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
822 CopyMem (Buffer
, Location
, Location
->Length
);
831 // Go to the next Op-Code
833 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
841 // Helper functions to HiiGetDefaultImage()
846 HiiGetDefaultImageInitPack (
847 IN OUT EFI_HII_VARIABLE_PACK_LIST
*VariablePackItem
,
848 IN EFI_IFR_VARSTORE
*VarStore
854 Initialize the EFI_HII_VARIABLE_PACK_LIST structure and
855 prepare it ready to be used by HiiGetDefaultImagePopulateMap ().
859 VariablePackItem - Variable Package List.
860 VarStore - IFR variable storage.
864 Return the pointer to the Map space.
871 EFI_HII_VARIABLE_PACK
*VariablePack
;
874 // Set pointer the pack right after the node
876 VariablePackItem
->VariablePack
= (EFI_HII_VARIABLE_PACK
*) (VariablePackItem
+ 1);
877 VariablePack
= VariablePackItem
->VariablePack
;
880 // Copy the var name to VariablePackItem from VarStore
881 // Needs ASCII->Unicode conversion.
883 ASSERT (VarStore
->Header
.Length
> sizeof (*VarStore
));
884 Name8
= (CHAR8
*) (VarStore
+ 1);
885 Name16
= (CHAR16
*) (VariablePack
+ 1);
886 Ascii2Unicode (Name16
, Name8
);
889 // Compute the other fields of the VariablePackItem
891 VariablePack
->VariableId
= VarStore
->VarId
;
892 CopyMem (&VariablePack
->VariableGuid
, &VarStore
->Guid
, sizeof (EFI_GUID
));
893 VariablePack
->VariableNameLength
= (UINT32
) ((StrLen (Name16
) + 1) * 2);
894 VariablePack
->Header
.Length
= sizeof (*VariablePack
)
895 + VariablePack
->VariableNameLength
898 // Return the pointer to the Map space.
900 Map
= (CHAR8
*) Name16
+ VariablePack
->VariableNameLength
;
907 HiiGetDefaultImagePopulateMap (
909 IN EFI_IFR_OP_HEADER
*FormSet
,
910 IN EFI_IFR_VARSTORE
*VarStore
,
917 Fill the Map with all the default values either from NV or Hii database.
921 Map - Memory pointer to hold the default values.
922 FormSet - The starting EFI_IFR_OP_HEADER to begin retriving default values.
923 VarStore - IFR variable storage.
924 DefaultMask - The mask used to get the default variable.
933 EFI_IFR_OP_HEADER
*IfrItem
;
935 EFI_IFR_VARSTORE_SELECT
*VarSelect
;
936 EFI_IFR_ONE_OF_OPTION
*OneOfOpt
;
937 EFI_IFR_CHECKBOX
*CheckBox
;
938 EFI_IFR_NUMERIC
*Numeric
;
941 EFI_IFR_NV_DATA
*IfrNvData
;
945 EFI_HANDLE CallbackHandle
;
946 EFI_FORM_CALLBACK_PROTOCOL
*FormCallbackProt
;
949 // Get the Map's Name/Guid/Szie from the Varstore.
950 // VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.
952 ASSERT (VarStore
->Header
.Length
>= sizeof (*VarStore
));
953 Name8
= (CHAR8
*) (VarStore
+ 1);
954 Name16
= AllocateZeroPool ((VarStore
->Header
.Length
- sizeof (*VarStore
)) * sizeof (CHAR16
));
955 Ascii2Unicode (Name16
, Name8
);
956 CopyMem (&Guid
, &VarStore
->Guid
, sizeof(EFI_GUID
));
957 Size
= VarStore
->Size
;
960 // First, check if the map exists in the NV. If so, get it from NV and exit.
962 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
964 // Check if Manufaturing Defaults exist in the NV.
966 Status
= EfiLibHiiVariableOverrideBySuffix (
967 HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE
,
975 // All other cases default to Defaults. Check if Defaults exist in the NV.
977 Status
= EfiLibHiiVariableOverrideBySuffix (
978 HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE
,
985 if (!EFI_ERROR (Status
)) {
987 // Either Defaults/Manufacturing variable exists and appears to be valid.
988 // The map is read, exit w/ success now.
990 gBS
->FreePool (Name16
);
995 // First, prime the map with what already is in the NV.
996 // This is needed to cover a situation where the IFR does not contain all the
997 // defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.
998 // Ignore status. Either it gets read or not.
1000 FormCallbackProt
= NULL
;
1001 CopyMem (&CallbackHandle
, &((EFI_IFR_FORM_SET
*) FormSet
)->CallbackHandle
, sizeof (CallbackHandle
));
1002 if (CallbackHandle
!= NULL
) {
1003 Status
= gBS
->HandleProtocol (
1004 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
1005 &gEfiFormCallbackProtocolGuid
,
1006 (VOID
*) &FormCallbackProt
1009 if ((NULL
!= FormCallbackProt
) && (NULL
!= FormCallbackProt
->NvRead
)) {
1011 // Attempt to read using NvRead() callback. Probe first for existence and correct variable size.
1014 Status
= FormCallbackProt
->NvRead (
1022 if ((EFI_BUFFER_TOO_SMALL
== Status
) && (SizeTmp
== Size
)) {
1023 Status
= FormCallbackProt
->NvRead (
1031 ASSERT_EFI_ERROR (Status
);
1032 ASSERT (SizeTmp
== Size
);
1036 // No callback available for this formset, read straight from NV. Deliberately ignore the Status.
1037 // The buffer will only be written if variable exists nd has correct size.
1039 Status
= EfiLibHiiVariableRetrieveFromNv (
1048 // Iterate all IFR statements and for applicable, retrieve the default into the Map.
1050 for (IfrItem
= FormSet
, VarId
= 0;
1051 IfrItem
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;
1052 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
)
1056 // Observe VarStore switch.
1058 if (EFI_IFR_VARSTORE_SELECT_OP
== IfrItem
->OpCode
) {
1059 VarSelect
= (EFI_IFR_VARSTORE_SELECT
*) IfrItem
;
1060 VarId
= VarSelect
->VarId
;
1066 // Skip opcodes that reference other VarStore than that specific to current map.
1068 if (VarId
!= VarStore
->VarId
) {
1073 // Extract the default value from this opcode if applicable, and apply it to the map.
1075 IfrNvData
= (EFI_IFR_NV_DATA
*) IfrItem
;
1076 switch (IfrItem
->OpCode
) {
1078 case EFI_IFR_ONE_OF_OP
:
1079 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1081 // Get to the first EFI_IFR_ONE_OF_OPTION_OP
1083 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1084 ASSERT (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
);
1086 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1088 // In the worst case, the first will be the default.
1090 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1092 while (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
) {
1094 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1095 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1096 if (0 != (OneOfOpt
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1098 // In the worst case, the first will be the default.
1100 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1104 if (OneOfOpt
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1106 // In the worst case, the first will be the default.
1108 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1113 IfrItem
= (EFI_IFR_OP_HEADER
*)((UINT8
*)IfrItem
+ IfrItem
->Length
);
1118 case EFI_IFR_CHECKBOX_OP
:
1119 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1120 CheckBox
= (EFI_IFR_CHECK_BOX
*)IfrItem
;
1121 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1122 if (0 != (CheckBox
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1123 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1126 if (CheckBox
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1127 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1132 case EFI_IFR_NUMERIC_OP
:
1133 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1134 Numeric
= (EFI_IFR_NUMERIC
*) IfrItem
;
1135 CopyMem (Map
+ IfrNvData
->QuestionId
, &Numeric
->Default
, IfrNvData
->StorageWidth
);
1138 case EFI_IFR_ORDERED_LIST_OP
:
1139 case EFI_IFR_PASSWORD_OP
:
1140 case EFI_IFR_STRING_OP
:
1142 // No support for default value for these opcodes.
1148 gBS
->FreePool (Name16
);
1155 HiiGetDefaultImage (
1156 IN EFI_HII_PROTOCOL
*This
,
1157 IN EFI_HII_HANDLE Handle
,
1158 IN UINTN DefaultMask
,
1159 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
1163 Routine Description:
1165 This function allows a program to extract the NV Image
1166 that represents the default storage image
1169 This - A pointer to the EFI_HII_PROTOCOL instance.
1170 Handle - The HII handle from which will have default data retrieved.
1171 UINTN - Mask used to retrieve the default image.
1172 VariablePackList - Callee allocated, tightly-packed, link list data
1173 structure that contain all default varaible packs
1174 from the Hii Database.
1177 EFI_NOT_FOUND - If Hii database does not contain any default images.
1178 EFI_INVALID_PARAMETER - Invalid input parameter.
1179 EFI_SUCCESS - Operation successful.
1183 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1184 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1185 EFI_IFR_OP_HEADER
*FormSet
;
1186 EFI_IFR_OP_HEADER
*IfrItem
;
1187 EFI_IFR_VARSTORE
*VarStore
;
1188 EFI_IFR_VARSTORE
*VarStoreDefault
;
1189 UINTN SetupMapNameSize
;
1191 EFI_HII_VARIABLE_PACK_LIST
*PackList
;
1192 EFI_HII_VARIABLE_PACK_LIST
*PackListNext
;
1193 EFI_HII_VARIABLE_PACK_LIST
*PackListLast
;
1198 // Find the IFR pack from the handle. Then get the formset from the pack.
1200 PackageInstance
= NULL
;
1201 HandleDatabase
= (EFI_HII_DATA_FROM_THIS (This
))->DatabaseHead
;
1202 for ( ; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1203 if (Handle
== HandleDatabase
->Handle
) {
1204 PackageInstance
= HandleDatabase
->Buffer
;
1208 if (PackageInstance
== NULL
) {
1209 return EFI_INVALID_PARAMETER
;
1211 FormSet
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) &PackageInstance
->IfrData
+ sizeof (EFI_HII_IFR_PACK
));
1214 // Get the sizes of all the VARSTOREs in this VFR.
1215 // Then allocate enough space for all of them plus all maps
1219 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1221 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1222 VarStore
= (EFI_IFR_VARSTORE
*) IfrItem
;
1226 SizeOfMaps
+= VarStore
->Size
;
1228 // add the size of the string, in Unicode
1230 SizeOfMaps
+= (VarStore
->Header
.Length
- sizeof (*VarStore
)) * 2;
1234 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1236 // Space for linked list node
1238 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1241 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1245 // If the FormSet OpCode has a non-zero NvDataSize. There is a default
1246 // NvMap with ID=0, GUID that of the formset itself and "Setup" as name.
1248 SetupMapNameSize
= StrLen (SETUP_MAP_NAME
) + 1;
1249 VarStoreDefault
= AllocateZeroPool (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1251 if (0 != ((EFI_IFR_FORM_SET
*)FormSet
)->NvDataSize
) {
1253 VarStoreDefault
->Header
.OpCode
= EFI_IFR_VARSTORE_OP
;
1254 VarStoreDefault
->Header
.Length
= (UINT8
) (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1255 Unicode2Ascii ((CHAR8
*) (VarStoreDefault
+ 1), SETUP_MAP_NAME
);
1256 CopyMem (&VarStoreDefault
->Guid
, &((EFI_IFR_FORM_SET
*) FormSet
)->Guid
, sizeof (EFI_GUID
));
1257 VarStoreDefault
->VarId
= 0;
1258 VarStoreDefault
->Size
= ((EFI_IFR_FORM_SET
*) FormSet
)->NvDataSize
;
1263 SizeOfMaps
+= VarStoreDefault
->Size
;
1265 // add the size of the string
1267 SizeOfMaps
+= sizeof (SETUP_MAP_NAME
);
1271 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1273 // Space for linked list node
1275 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1278 if (0 == SizeOfMaps
) {
1280 // The IFR does not have any explicit or default map(s).
1282 return EFI_NOT_FOUND
;
1286 // Allocate the return buffer
1288 PackList
= AllocateZeroPool (SizeOfMaps
);
1289 ASSERT (NULL
!= PackList
);
1291 PackListNext
= PackList
;
1292 PackListLast
= PackList
;
1295 // Handle the default map first, if any.
1297 if (0 != VarStoreDefault
->Size
) {
1299 Map
= HiiGetDefaultImageInitPack (PackListNext
, VarStoreDefault
);
1301 HiiGetDefaultImagePopulateMap (Map
, FormSet
, VarStoreDefault
, DefaultMask
);
1303 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1304 PackListLast
= PackListNext
;
1305 PackListNext
= PackListNext
->NextVariablePack
;
1310 // Handle the explicit varstore(s)
1313 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1315 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1317 Map
= HiiGetDefaultImageInitPack (PackListNext
, (EFI_IFR_VARSTORE
*) IfrItem
);
1319 HiiGetDefaultImagePopulateMap (Map
, FormSet
, (EFI_IFR_VARSTORE
*) IfrItem
, DefaultMask
);
1321 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1322 PackListLast
= PackListNext
;
1323 PackListNext
= PackListNext
->NextVariablePack
;
1326 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1329 PackListLast
->NextVariablePack
= NULL
;
1330 *VariablePackList
= PackList
;
1339 IN EFI_HII_PROTOCOL
*This
,
1340 IN EFI_HII_HANDLE Handle
,
1341 IN EFI_FORM_LABEL Label
,
1343 IN EFI_HII_UPDATE_DATA
*Data
1347 Routine Description:
1348 This function allows the caller to update a form that has
1349 previously been registered with the EFI HII database.
1352 Handle - Hii Handle associated with the Formset to modify
1353 Label - Update information starting immediately after this label in the IFR
1354 AddData - If TRUE, add data. If FALSE, remove data
1355 Data - If adding data, this is the pointer to the data to add
1358 EFI_SUCCESS - Update success.
1359 Other - Update fail.
1363 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1364 EFI_HII_DATA
*HiiData
;
1365 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1366 EFI_HII_IFR_PACK
*FormPack
;
1367 EFI_IFR_OP_HEADER
*Location
;
1368 EFI_IFR_OP_HEADER
*DataLocation
;
1371 UINT8
*OrigTempBuffer
;
1372 UINTN TempBufferSize
;
1378 return EFI_INVALID_PARAMETER
;
1381 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
1383 HandleDatabase
= HiiData
->DatabaseHead
;
1385 PackageInstance
= NULL
;
1388 // Check numeric value against the head of the database
1390 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1392 // Match the numeric value with the database entry - if matched, extract PackageInstance
1394 if (Handle
== HandleDatabase
->Handle
) {
1395 PackageInstance
= HandleDatabase
->Buffer
;
1400 // No handle was found - error condition
1402 if (PackageInstance
== NULL
) {
1403 return EFI_INVALID_PARAMETER
;
1406 // Calculate and allocate space for retrieval of IFR data
1408 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1409 TempBufferSize
= (CHAR8
*) (&PackageInstance
->IfrData
) - (CHAR8
*) (PackageInstance
);
1411 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1412 TempBufferSize
+= DataLocation
->Length
;
1413 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1416 TempBufferSize
+= PackageInstance
->IfrSize
+ PackageInstance
->StringSize
;
1418 TempBuffer
= AllocateZeroPool (TempBufferSize
);
1419 ASSERT (TempBuffer
!= NULL
);
1421 OrigTempBuffer
= TempBuffer
;
1424 // We update only packages with IFR information in it
1426 if (PackageInstance
->IfrSize
== 0) {
1427 return EFI_INVALID_PARAMETER
;
1433 ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
))
1436 TempBuffer
= TempBuffer
+ ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
));
1439 // Based on if there is IFR data in this package instance, determine
1440 // what the location is of the beginning of the string data.
1442 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
1443 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
1446 // Look for the FormId requested
1448 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
1449 switch (Location
->OpCode
) {
1450 case EFI_IFR_FORM_SET_OP
:
1452 // If the FormSet has an update pending, pay attention.
1454 if (Data
->FormSetUpdate
) {
1455 ((EFI_IFR_FORM_SET
*) Location
)->CallbackHandle
= Data
->FormCallbackHandle
;
1458 CopyMem (TempBuffer
, Location
, Location
->Length
);
1459 TempBuffer
= TempBuffer
+ Location
->Length
;
1462 case EFI_IFR_FORM_OP
:
1464 // If the Form has an update pending, pay attention.
1466 if (Data
->FormUpdate
) {
1467 ((EFI_IFR_FORM
*) Location
)->FormTitle
= Data
->FormTitle
;
1470 CopyMem (TempBuffer
, Location
, Location
->Length
);
1471 TempBuffer
= TempBuffer
+ Location
->Length
;
1474 case EFI_IFR_LABEL_OP
:
1476 // If the label does not match the requested update point, ignore it
1478 if (((EFI_IFR_LABEL
*) Location
)->LabelId
!= Label
) {
1482 CopyMem (TempBuffer
, Location
, Location
->Length
);
1483 TempBuffer
= TempBuffer
+ Location
->Length
;
1486 // Go to the next Op-Code
1488 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1496 CopyMem (TempBuffer
, Location
, Location
->Length
);
1497 TempBuffer
= TempBuffer
+ Location
->Length
;
1500 // Add the DataCount amount of opcodes to TempBuffer
1502 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1503 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1504 CopyMem (TempBuffer
, DataLocation
, DataLocation
->Length
);
1505 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
+= DataLocation
->Length
;
1506 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1507 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1508 TempBuffer
= TempBuffer
+ DataLocation
->Length
;
1509 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1512 // Go to the next Op-Code
1514 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1520 CopyMem (TempBuffer
, Location
, Location
->Length
);
1521 TempBuffer
= TempBuffer
+ Location
->Length
;
1522 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1525 // Remove the DataCount amount of opcodes unless we run into an end of form or a label
1527 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1529 // If we are about to skip an end form - bail out, since that is illegal
1531 if ((Location
->OpCode
== EFI_IFR_END_FORM_OP
) || (Location
->OpCode
== EFI_IFR_LABEL_OP
)) {
1535 // By skipping Location entries, we are in effect not copying what was previously there
1537 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
-= Location
->Length
;
1538 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1539 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1540 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1545 CopyMem (TempBuffer
, Location
, Location
->Length
);
1546 TempBuffer
= TempBuffer
+ Location
->Length
;
1550 // Go to the next Op-Code
1552 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1555 // Copy the last op-code left behind from the for loop
1557 CopyMem (TempBuffer
, Location
, Location
->Length
);
1560 // Advance to beginning of strings and copy them
1562 TempBuffer
= TempBuffer
+ Location
->Length
;
1563 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1564 CopyMem (TempBuffer
, Location
, PackageInstance
->StringSize
);
1567 // Free the old buffer, and assign into our database the latest buffer
1569 gBS
->FreePool (HandleDatabase
->Buffer
);
1570 HandleDatabase
->Buffer
= OrigTempBuffer
;