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"
27 OUT CHAR16
*UnicodeStr
,
34 This function converts ASCII string to Unicode string.
38 UnicodeStr - NULL terminated Unicode output string.
39 AsciieStr - NULL terminated ASCII input string.
43 Start of the Unicode ouput string.
48 CHAR16
*Str
= UnicodeStr
;
50 *(UnicodeStr
++) = (CHAR16
) *AsciiStr
;
51 if (*(AsciiStr
++) == '\0') {
66 This function converts Unicode string to ASCII string.
70 AsciieStr - NULL terminated ASCII output string.
71 UnicodeStr - NULL terminated Unicode input string.
75 Start of the ASCII ouput string.
80 CHAR8
*Str
= AsciiStr
;
82 *(AsciiStr
++) = (CHAR8
) *UnicodeStr
;
83 if (*(UnicodeStr
++) == '\0') {
90 ExtractDevicePathData (
91 IN EFI_HII_DATA_TABLE
*DataTable
,
93 IN OUT UINT8
**ExportBufferPtr
107 ExportBuffer
= *ExportBufferPtr
;
110 // BUGBUG - don't have devicepath data yet, setting dummy value
113 ExportBuffer
= (UINT8
*) DataTable
;
114 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Type
= EFI_HII_DEVICE_PATH
;
115 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Length
= (UINT32
) (sizeof (EFI_HII_DEVICE_PATH_PACK
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
118 // BUGBUG - part of hack - skip the Device Path Pack.....place some data
120 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_DEVICE_PATH_PACK
);
122 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->Type
= EFI_END_ENTIRE_DEVICE_PATH
;
123 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->SubType
= EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
;
126 // BUGBUG - still part of hack....
128 ExportBuffer
= ExportBuffer
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
129 *ExportBufferPtr
= ExportBuffer
;
133 ExtractVariableData (
134 IN OUT EFI_HII_DATA_TABLE
*DataTable
,
136 IN OUT UINT8
**ExportBufferPtr
142 This function extract the EFI_HII_VARIABLE_PACK portion from the
143 each of the EFI_HII_PACKAGE_INSTANCE in HII handle database.
147 DataTable ¨C On input, this parameter point to the EFI_HII_DATA_TABLE structure
148 of the final data buffer for the EFI_HII_EXPORT interface. This function
149 update the NumberOfVariableData attribute.
150 IfrData - It points to a staring address of a EFI_HII_IFR_PACK structure.
151 ExportBufferPtr ¨C On input, it points the starting address of the data buffer to
152 host the variable pack. On output, it is the starting address
153 of data buffer for the next extraction operation.
160 EFI_HII_VARIABLE_PACK
*VariableContents
;
166 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
167 EFI_PHYSICAL_ADDRESS CallbackHandle
;
173 ExportBuffer
= *ExportBufferPtr
;
175 for (Index
= 0; IfrData
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
176 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
178 switch (IfrData
[Index
]) {
179 case EFI_IFR_FORM_SET_OP
:
180 TempValue
= EFI_HII_VARIABLE
;
181 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
182 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
185 // If the variable has 0 size, do not process it
187 if (TempValue
== 0) {
191 // Add the size of the variable pack overhead. Later, will also add the size of the
192 // name of the variable.
194 TempValue
= TempValue
+ sizeof (EFI_HII_VARIABLE_PACK
);
196 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
199 &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->CallbackHandle
,
200 sizeof (EFI_PHYSICAL_ADDRESS
)
202 if (CallbackHandle
!= 0) {
203 Status
= gBS
->HandleProtocol (
204 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
205 &gEfiFormCallbackProtocolGuid
,
206 (VOID
*) &FormCallback
210 // Since we have a "Setup" variable that wasn't specified by a variable op-code
211 // it will have a VariableId of 0. All other variable op-codes will have a designation
215 CopyMem (&VariableContents
->VariableId
, &TempValue
, sizeof (UINT16
));
216 CopyMem (&VariableContents
->VariableGuid
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->Guid
, sizeof (EFI_GUID
));
217 TempValue
= sizeof (SETUP_MAP_NAME
);
218 CopyMem (&VariableContents
->VariableNameLength
, &TempValue
, sizeof (UINT32
));
221 // Add the size of the name to the Header Length
224 CopyMem (&TempValue2
, &VariableContents
->Header
.Length
, sizeof (UINT32
));
225 TempValue2
= TempValue
+ TempValue2
;
226 CopyMem (&VariableContents
->Header
.Length
, &TempValue2
, sizeof (UINT32
));
228 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
229 CopyMem (ExportBuffer
, SETUP_MAP_NAME
, sizeof (SETUP_MAP_NAME
));
230 ExportBuffer
= ExportBuffer
+ sizeof (SETUP_MAP_NAME
);
232 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
234 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
235 Status
= FormCallback
->NvRead (
237 (CHAR16
*) SETUP_MAP_NAME
,
238 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
244 Status
= gRT
->GetVariable (
245 (CHAR16
*) SETUP_MAP_NAME
,
246 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
253 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + TempValue
);
254 DataTable
->NumberOfVariableData
++;
257 case EFI_IFR_VARSTORE_OP
:
258 TempValue
= EFI_HII_VARIABLE
;
259 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
260 CopyMem (&TempValue
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Size
, sizeof (UINT16
));
263 // If the variable has 0 size, do not process it
265 if (TempValue
== 0) {
269 // Add the size of the variable pack overhead. Later, will also add the size of the
270 // name of the variable.
272 TempValue
= TempValue
+ sizeof (EFI_HII_VARIABLE_PACK
);
274 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
275 CopyMem (&VariableContents
->VariableId
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->VarId
, sizeof (UINT16
));
276 CopyMem (&VariableContents
->VariableGuid
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Guid
, sizeof (EFI_GUID
));
277 TempValue
= (UINTN
) ((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Header
.Length
- sizeof (EFI_IFR_VARSTORE
);
278 TempValue
= TempValue
* 2;
279 CopyMem (&VariableContents
->VariableNameLength
, &TempValue
, sizeof (UINT32
));
282 // Add the size of the name to the Header Length
285 CopyMem (&TempValue2
, &VariableContents
->Header
.Length
, sizeof (UINT32
));
286 TempValue2
= TempValue
+ TempValue2
;
287 CopyMem (&VariableContents
->Header
.Length
, &TempValue2
, sizeof (UINT32
));
289 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
290 String
= (CHAR16
*) ExportBuffer
;
291 for (Index2
= 0; Index2
< TempValue
/ 2; Index2
++) {
292 ExportBuffer
[Index2
* 2] = IfrData
[Index
+ sizeof (EFI_IFR_VARSTORE
) + Index2
];
293 ExportBuffer
[Index2
* 2 + 1] = 0;
296 ExportBuffer
= ExportBuffer
+ TempValue
;
298 CopyMem (&TempValue
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Size
, sizeof (UINT16
));
300 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
301 Status
= FormCallback
->NvRead (
304 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
310 Status
= gRT
->GetVariable (
312 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
319 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + TempValue
);
320 DataTable
->NumberOfVariableData
++;
324 Index
= IfrData
[Index
+ 1] + Index
;
327 // If we have added a variable pack, add a dummy empty one to signify the end
329 if (ExportBuffer
!= *ExportBufferPtr
) {
330 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
331 TempValue
= EFI_HII_VARIABLE
;
332 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
333 TempValue
= sizeof (EFI_HII_VARIABLE_PACK
);
334 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
335 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
338 *ExportBufferPtr
= ExportBuffer
;
344 IN EFI_HII_PROTOCOL
*This
,
345 IN EFI_HII_HANDLE Handle
,
346 IN OUT UINTN
*BufferSize
,
353 This function allows a program to extract a form or form package that has
354 previously been registered with the EFI HII database.
362 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
363 EFI_HII_DATA
*HiiData
;
364 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
365 EFI_HII_IFR_PACK
*FormPack
;
368 EFI_HII_EXPORT_TABLE
*ExportTable
;
369 EFI_HII_DATA_TABLE
*DataTable
;
370 BOOLEAN InsufficientSize
;
371 BOOLEAN VariableExist
;
372 UINT16 NumberOfHiiDataTables
;
379 return EFI_INVALID_PARAMETER
;
382 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
384 HandleDatabase
= HiiData
->DatabaseHead
;
388 PackageInstance
= NULL
;
389 InsufficientSize
= FALSE
;
390 NumberOfHiiDataTables
= 0;
393 SizeNeeded
= sizeof (EFI_HII_EXPORT_TABLE
);
396 // How many total tables are there?
398 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
399 if ((Handle
!= 0) && (Handle
!= HandleDatabase
->Handle
)) {
403 VariableExist
= FALSE
;
404 NumberOfHiiDataTables
++;
405 PackageInstance
= HandleDatabase
->Buffer
;
406 if (PackageInstance
== NULL
) {
410 // Extract Size of Export Package
412 SizeNeeded
= SizeNeeded
+ PackageInstance
->IfrSize
413 + PackageInstance
->StringSize
414 + sizeof (EFI_HII_DATA_TABLE
)
415 + sizeof (EFI_HII_DEVICE_PATH_PACK
);
418 // BUGBUG We aren't inserting Device path data yet
420 SizeNeeded
= SizeNeeded
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
423 // Extract Size of Variable Data
425 if (PackageInstance
->IfrSize
> 0) {
426 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
429 // No IFR? No variable information
434 RawData
= (UINT8
*) FormPack
;
436 for (Index
= 0; RawData
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
437 switch (RawData
[Index
]) {
438 case EFI_IFR_FORM_SET_OP
:
439 CopyMem (&VariableSize
, &((EFI_IFR_FORM_SET
*) &RawData
[Index
])->NvDataSize
, sizeof (UINT16
));
440 SizeNeeded
= SizeNeeded
+ VariableSize
+ sizeof (SETUP_MAP_NAME
) + sizeof (EFI_HII_VARIABLE_PACK
);
441 VariableExist
= TRUE
;
444 case EFI_IFR_VARSTORE_OP
:
445 CopyMem (&VariableSize
, &((EFI_IFR_VARSTORE
*) &RawData
[Index
])->Size
, sizeof (UINT16
));
446 SizeNeeded
= SizeNeeded
+ VariableSize
+ sizeof (EFI_HII_VARIABLE_PACK
);
448 // We will be expanding the stored ASCII name to a Unicode string. This will cause some memory overhead
449 // Since the VARSTORE size already takes in consideration the ASCII size, we need to size it and add another
450 // instance of it. Essentially, 2 ASCII strings == 1 Unicode string in size.
452 TempValue
= (UINTN
) ((EFI_IFR_VARSTORE
*) &RawData
[Index
])->Header
.Length
- sizeof (EFI_IFR_VARSTORE
);
453 SizeNeeded
= SizeNeeded
+ TempValue
* 2;
454 VariableExist
= TRUE
;
458 Index
= RawData
[Index
+ 1] + Index
;
461 // If a variable exists for this handle, add an additional variable pack overhead to
462 // indicate that we will have an extra null Variable Pack to signify the end of the Variable Packs
465 SizeNeeded
= SizeNeeded
+ sizeof (EFI_HII_VARIABLE_PACK
);
469 if (SizeNeeded
> *BufferSize
) {
470 *BufferSize
= SizeNeeded
;
471 return EFI_BUFFER_TOO_SMALL
;
474 // Zero out the incoming buffer
476 ZeroMem (Buffer
, *BufferSize
);
479 // Cast the Buffer to EFI_HII_EXPORT_TABLE
481 ExportTable
= (EFI_HII_EXPORT_TABLE
*) Buffer
;
484 // Set the Revision for the Export Table
486 CopyMem (&ExportTable
->Revision
, &gEfiHiiProtocolGuid
, sizeof (EFI_GUID
));
488 ExportBuffer
= (UINT8
*) (UINTN
) (((UINT8
*) ExportTable
) + sizeof (EFI_HII_EXPORT_TABLE
));
489 HandleDatabase
= HiiData
->DatabaseHead
;
492 // Check numeric value against the head of the database
494 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
495 DataTable
= (EFI_HII_DATA_TABLE
*) ExportBuffer
;
496 PackageInstance
= HandleDatabase
->Buffer
;
498 // If not asking for a specific handle, export the entire database
501 ExportTable
->NumberOfHiiDataTables
= NumberOfHiiDataTables
;
502 CopyMem (&DataTable
->PackageGuid
, &PackageInstance
->Guid
, sizeof (EFI_GUID
));
503 DataTable
->HiiHandle
= PackageInstance
->Handle
;
504 DataTable
->DevicePathOffset
= (UINT32
) (sizeof (EFI_HII_DATA_TABLE
));
507 // Start Dumping DevicePath
509 ExtractDevicePathData (DataTable
, RawData
, &ExportBuffer
);
511 if (((UINTN
) ExportBuffer
) == ((UINTN
) DataTable
)) {
513 // If there is no DevicePath information - set offset to 0 to signify the absence of data to parse
515 DataTable
->DevicePathOffset
= 0;
518 DataTable
->VariableDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
520 if (PackageInstance
->IfrSize
> 0) {
521 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
523 RawData
= (UINT8
*) FormPack
;
527 // Start dumping the Variable Data
529 ExtractVariableData (DataTable
, RawData
, &ExportBuffer
);
530 DataTable
->IfrDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
532 if (DataTable
->VariableDataOffset
== DataTable
->IfrDataOffset
) {
533 DataTable
->VariableDataOffset
= 0;
536 // Start dumping the IFR data (Note: It is in an IFR PACK)
538 CopyMem (ExportBuffer
, &PackageInstance
->IfrData
, PackageInstance
->IfrSize
);
539 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + PackageInstance
->IfrSize
);
540 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
543 // Start dumping the String data (Note: It is in a String PACK)
545 if (PackageInstance
->StringSize
> 0) {
546 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
547 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
548 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
550 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
551 for (; TempValue
!= 0;) {
552 DataTable
->NumberOfLanguages
++;
553 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
554 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
557 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
559 DataTable
->StringDataOffset
= 0;
563 // 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)
565 DataTable
->VariableDataOffset
= 0;
566 DataTable
->IfrDataOffset
= 0;
567 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
570 // Start dumping the String data - NOTE: It is in String Pack form
572 if (PackageInstance
->StringSize
> 0) {
573 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
574 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
575 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
577 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
578 for (; TempValue
!= 0;) {
579 DataTable
->NumberOfLanguages
++;
580 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
581 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
584 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
586 DataTable
->StringDataOffset
= 0;
591 // Match the numeric value with the database entry - if matched, extract PackageInstance
593 if (Handle
== HandleDatabase
->Handle
) {
594 PackageInstance
= HandleDatabase
->Buffer
;
595 ExportTable
->NumberOfHiiDataTables
= NumberOfHiiDataTables
;
596 DataTable
->HiiHandle
= PackageInstance
->Handle
;
597 CopyMem (&DataTable
->PackageGuid
, &PackageInstance
->Guid
, sizeof (EFI_GUID
));
600 // Start Dumping DevicePath
602 ExtractDevicePathData (DataTable
, RawData
, &ExportBuffer
);
603 DataTable
->VariableDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
605 if (PackageInstance
->IfrSize
> 0) {
606 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
608 RawData
= (UINT8
*) FormPack
;
612 // Start dumping the Variable Data
614 ExtractVariableData (DataTable
, RawData
, &ExportBuffer
);
615 DataTable
->IfrDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
617 if (DataTable
->VariableDataOffset
== DataTable
->IfrDataOffset
) {
618 DataTable
->VariableDataOffset
= 0;
621 // Start dumping the IFR data
623 CopyMem (ExportBuffer
, &PackageInstance
->IfrData
, PackageInstance
->IfrSize
);
624 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + PackageInstance
->IfrSize
);
625 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
628 // Start dumping the String data - NOTE: It is in String Pack form
630 if (PackageInstance
->StringSize
> 0) {
631 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
632 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
633 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
635 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
636 for (; TempValue
!= 0;) {
637 DataTable
->NumberOfLanguages
++;
638 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
639 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
642 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
644 DataTable
->StringDataOffset
= 0;
648 // No IFR? No variable information. If Offset is 0, means there is none.
650 DataTable
->VariableDataOffset
= 0;
651 DataTable
->IfrDataOffset
= 0;
652 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
655 // Start dumping the String data - Note: It is in String Pack form
657 if (PackageInstance
->StringSize
> 0) {
658 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
659 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
660 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
662 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
663 for (; TempValue
!= 0;) {
664 DataTable
->NumberOfLanguages
++;
665 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
666 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
669 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
671 DataTable
->StringDataOffset
= 0;
685 IN EFI_HII_PROTOCOL
*This
,
686 IN EFI_HII_HANDLE Handle
,
687 IN EFI_FORM_ID FormId
,
688 IN OUT UINTN
*BufferLengthTemp
,
695 This function allows a program to extract a form or form package that has
696 previously been registered with the EFI HII database.
699 This - A pointer to the EFI_HII_PROTOCOL instance.
701 Handle - Handle on which the form resides. Type EFI_HII_HANDLE is defined in
702 EFI_HII_PROTOCOL.NewPack() in the Packages section.
704 FormId - The ID of the form to return. If the ID is zero, the entire form package is returned.
705 Type EFI_FORM_ID is defined in "Related Definitions" below.
707 BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if
708 the length was sufficient and, if it was not, the length that is required to fit the
711 Buffer - The buffer designed to receive the form(s).
715 EFI_SUCCESS - Buffer filled with the requested forms. BufferLength
718 EFI_INVALID_PARAMETER - The handle is unknown.
720 EFI_NOT_FOUND - A form on the requested handle cannot be found with the
723 EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.
727 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
728 EFI_HII_DATA
*HiiData
;
729 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
730 EFI_HII_IFR_PACK
*FormPack
;
732 EFI_IFR_OP_HEADER
*Location
;
733 UINT16
*BufferLength
= (UINT16
*) BufferLengthTemp
;
736 return EFI_INVALID_PARAMETER
;
739 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
741 HandleDatabase
= HiiData
->DatabaseHead
;
743 PackageInstance
= NULL
;
746 // Check numeric value against the head of the database
748 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
750 // Match the numeric value with the database entry - if matched, extract PackageInstance
752 if (Handle
== HandleDatabase
->Handle
) {
753 PackageInstance
= HandleDatabase
->Buffer
;
758 // No handle was found - error condition
760 if (PackageInstance
== NULL
) {
761 return EFI_NOT_FOUND
;
764 // Based on if there is IFR data in this package instance, determine
765 // what the location is of the beginning of the string data.
767 if (PackageInstance
->IfrSize
> 0) {
768 FormPack
= (EFI_HII_IFR_PACK
*) (&PackageInstance
->IfrData
);
771 // If there is no IFR data return an error
773 return EFI_NOT_FOUND
;
776 // If requesting the entire Form Package
780 // Return an error if buffer is too small
782 if (PackageInstance
->IfrSize
> *BufferLength
|| Buffer
== NULL
) {
783 *BufferLength
= (UINT16
) PackageInstance
->IfrSize
;
784 return EFI_BUFFER_TOO_SMALL
;
787 CopyMem (Buffer
, FormPack
, PackageInstance
->IfrSize
);
790 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
791 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
794 // Look for the FormId requested
796 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
797 switch (Location
->OpCode
) {
798 case EFI_IFR_FORM_OP
:
799 Form
= (EFI_IFR_FORM
*) Location
;
802 // If we found a Form Op-code and it is of the correct Id, copy it and return
804 if (Form
->FormId
== FormId
) {
805 if (Location
->Length
> *BufferLength
|| Buffer
== NULL
) {
806 *BufferLength
= Location
->Length
;
807 return EFI_BUFFER_TOO_SMALL
;
809 for (; Location
->OpCode
!= EFI_IFR_END_FORM_OP
;) {
810 CopyMem (Buffer
, Location
, Location
->Length
);
811 Buffer
= Buffer
+ Location
->Length
;
812 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
815 CopyMem (Buffer
, Location
, Location
->Length
);
824 // Go to the next Op-Code
826 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
834 // Helper functions to HiiGetDefaultImage()
839 HiiGetDefaultImageInitPack (
840 IN OUT EFI_HII_VARIABLE_PACK_LIST
*VariablePackItem
,
841 IN EFI_IFR_VARSTORE
*VarStore
847 Initialize the EFI_HII_VARIABLE_PACK_LIST structure and
848 prepare it ready to be used by HiiGetDefaultImagePopulateMap ().
852 VariablePackItem - Variable Package List.
853 VarStore - IFR variable storage.
857 Return the pointer to the Map space.
864 EFI_HII_VARIABLE_PACK
*VariablePack
;
867 // Set pointer the pack right after the node
869 VariablePackItem
->VariablePack
= (EFI_HII_VARIABLE_PACK
*) (VariablePackItem
+ 1);
870 VariablePack
= VariablePackItem
->VariablePack
;
873 // Copy the var name to VariablePackItem from VarStore
874 // Needs ASCII->Unicode conversion.
876 ASSERT (VarStore
->Header
.Length
> sizeof (*VarStore
));
877 Name8
= (CHAR8
*) (VarStore
+ 1);
878 Name16
= (CHAR16
*) (VariablePack
+ 1);
879 Ascii2Unicode (Name16
, Name8
);
882 // Compute the other fields of the VariablePackItem
884 VariablePack
->VariableId
= VarStore
->VarId
;
885 CopyMem (&VariablePack
->VariableGuid
, &VarStore
->Guid
, sizeof (EFI_GUID
));
886 VariablePack
->VariableNameLength
= (UINT32
) ((StrLen (Name16
) + 1) * 2);
887 VariablePack
->Header
.Length
= sizeof (*VariablePack
)
888 + VariablePack
->VariableNameLength
891 // Return the pointer to the Map space.
893 Map
= (CHAR8
*) Name16
+ VariablePack
->VariableNameLength
;
900 HiiGetDefaultImagePopulateMap (
902 IN EFI_IFR_OP_HEADER
*FormSet
,
903 IN EFI_IFR_VARSTORE
*VarStore
,
910 Fill the Map with all the default values either from NV or Hii database.
914 Map - Memory pointer to hold the default values.
915 FormSet - The starting EFI_IFR_OP_HEADER to begin retriving default values.
916 VarStore - IFR variable storage.
917 DefaultMask - The mask used to get the default variable.
926 EFI_IFR_OP_HEADER
*IfrItem
;
928 EFI_IFR_VARSTORE_SELECT
*VarSelect
;
929 EFI_IFR_ONE_OF_OPTION
*OneOfOpt
;
930 EFI_IFR_CHECKBOX
*CheckBox
;
931 EFI_IFR_NUMERIC
*Numeric
;
934 EFI_IFR_NV_DATA
*IfrNvData
;
938 EFI_HANDLE CallbackHandle
;
939 EFI_FORM_CALLBACK_PROTOCOL
*FormCallbackProt
;
942 // Get the Map's Name/Guid/Szie from the Varstore.
943 // VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.
945 ASSERT (VarStore
->Header
.Length
>= sizeof (*VarStore
));
946 Name8
= (CHAR8
*) (VarStore
+ 1);
947 Name16
= AllocateZeroPool ((VarStore
->Header
.Length
- sizeof (*VarStore
)) * sizeof (CHAR16
));
948 Ascii2Unicode (Name16
, Name8
);
949 CopyMem (&Guid
, &VarStore
->Guid
, sizeof(EFI_GUID
));
950 Size
= VarStore
->Size
;
953 // First, check if the map exists in the NV. If so, get it from NV and exit.
955 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
957 // Check if Manufaturing Defaults exist in the NV.
959 Status
= EfiLibHiiVariableOverrideBySuffix (
960 HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE
,
968 // All other cases default to Defaults. Check if Defaults exist in the NV.
970 Status
= EfiLibHiiVariableOverrideBySuffix (
971 HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE
,
978 if (!EFI_ERROR (Status
)) {
980 // Either Defaults/Manufacturing variable exists and appears to be valid.
981 // The map is read, exit w/ success now.
983 gBS
->FreePool (Name16
);
988 // First, prime the map with what already is in the NV.
989 // This is needed to cover a situation where the IFR does not contain all the
990 // defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.
991 // Ignore status. Either it gets read or not.
993 FormCallbackProt
= NULL
;
994 CopyMem (&CallbackHandle
, &((EFI_IFR_FORM_SET
*) FormSet
)->CallbackHandle
, sizeof (CallbackHandle
));
995 if (CallbackHandle
!= NULL
) {
996 Status
= gBS
->HandleProtocol (
997 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
998 &gEfiFormCallbackProtocolGuid
,
999 (VOID
*) &FormCallbackProt
1002 if ((NULL
!= FormCallbackProt
) && (NULL
!= FormCallbackProt
->NvRead
)) {
1004 // Attempt to read using NvRead() callback. Probe first for existence and correct variable size.
1007 Status
= FormCallbackProt
->NvRead (
1015 if ((EFI_BUFFER_TOO_SMALL
== Status
) && (SizeTmp
== Size
)) {
1016 Status
= FormCallbackProt
->NvRead (
1024 ASSERT_EFI_ERROR (Status
);
1025 ASSERT (SizeTmp
== Size
);
1029 // No callback available for this formset, read straight from NV. Deliberately ignore the Status.
1030 // The buffer will only be written if variable exists nd has correct size.
1032 Status
= EfiLibHiiVariableRetrieveFromNv (
1041 // Iterate all IFR statements and for applicable, retrieve the default into the Map.
1043 for (IfrItem
= FormSet
, VarId
= 0;
1044 IfrItem
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;
1045 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
)
1049 // Observe VarStore switch.
1051 if (EFI_IFR_VARSTORE_SELECT_OP
== IfrItem
->OpCode
) {
1052 VarSelect
= (EFI_IFR_VARSTORE_SELECT
*) IfrItem
;
1053 VarId
= VarSelect
->VarId
;
1059 // Skip opcodes that reference other VarStore than that specific to current map.
1061 if (VarId
!= VarStore
->VarId
) {
1066 // Extract the default value from this opcode if applicable, and apply it to the map.
1068 IfrNvData
= (EFI_IFR_NV_DATA
*) IfrItem
;
1069 switch (IfrItem
->OpCode
) {
1071 case EFI_IFR_ONE_OF_OP
:
1072 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1074 // Get to the first EFI_IFR_ONE_OF_OPTION_OP
1076 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1077 ASSERT (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
);
1079 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1081 // In the worst case, the first will be the default.
1083 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1085 while (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
) {
1087 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1088 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1089 if (0 != (OneOfOpt
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1091 // In the worst case, the first will be the default.
1093 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1097 if (OneOfOpt
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1099 // In the worst case, the first will be the default.
1101 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1106 IfrItem
= (EFI_IFR_OP_HEADER
*)((UINT8
*)IfrItem
+ IfrItem
->Length
);
1111 case EFI_IFR_CHECKBOX_OP
:
1112 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1113 CheckBox
= (EFI_IFR_CHECK_BOX
*)IfrItem
;
1114 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1115 if (0 != (CheckBox
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1116 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1119 if (CheckBox
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1120 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1125 case EFI_IFR_NUMERIC_OP
:
1126 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1127 Numeric
= (EFI_IFR_NUMERIC
*) IfrItem
;
1128 CopyMem (Map
+ IfrNvData
->QuestionId
, &Numeric
->Default
, IfrNvData
->StorageWidth
);
1131 case EFI_IFR_ORDERED_LIST_OP
:
1132 case EFI_IFR_PASSWORD_OP
:
1133 case EFI_IFR_STRING_OP
:
1135 // No support for default value for these opcodes.
1141 gBS
->FreePool (Name16
);
1148 HiiGetDefaultImage (
1149 IN EFI_HII_PROTOCOL
*This
,
1150 IN EFI_HII_HANDLE Handle
,
1151 IN UINTN DefaultMask
,
1152 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
1156 Routine Description:
1158 This function allows a program to extract the NV Image
1159 that represents the default storage image
1162 This - A pointer to the EFI_HII_PROTOCOL instance.
1163 Handle - The HII handle from which will have default data retrieved.
1164 UINTN - Mask used to retrieve the default image.
1165 VariablePackList - Callee allocated, tightly-packed, link list data
1166 structure that contain all default varaible packs
1167 from the Hii Database.
1170 EFI_NOT_FOUND - If Hii database does not contain any default images.
1171 EFI_INVALID_PARAMETER - Invalid input parameter.
1172 EFI_SUCCESS - Operation successful.
1176 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1177 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1178 EFI_IFR_OP_HEADER
*FormSet
;
1179 EFI_IFR_OP_HEADER
*IfrItem
;
1180 EFI_IFR_VARSTORE
*VarStore
;
1181 EFI_IFR_VARSTORE
*VarStoreDefault
;
1182 UINTN SetupMapNameSize
;
1184 EFI_HII_VARIABLE_PACK_LIST
*PackList
;
1185 EFI_HII_VARIABLE_PACK_LIST
*PackListNext
;
1186 EFI_HII_VARIABLE_PACK_LIST
*PackListLast
;
1191 // Find the IFR pack from the handle. Then get the formset from the pack.
1193 PackageInstance
= NULL
;
1194 HandleDatabase
= (EFI_HII_DATA_FROM_THIS (This
))->DatabaseHead
;
1195 for ( ; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1196 if (Handle
== HandleDatabase
->Handle
) {
1197 PackageInstance
= HandleDatabase
->Buffer
;
1201 if (PackageInstance
== NULL
) {
1202 return EFI_INVALID_PARAMETER
;
1204 FormSet
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) &PackageInstance
->IfrData
+ sizeof (EFI_HII_IFR_PACK
));
1207 // Get the sizes of all the VARSTOREs in this VFR.
1208 // Then allocate enough space for all of them plus all maps
1212 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1214 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1215 VarStore
= (EFI_IFR_VARSTORE
*) IfrItem
;
1219 SizeOfMaps
+= VarStore
->Size
;
1221 // add the size of the string, in Unicode
1223 SizeOfMaps
+= (VarStore
->Header
.Length
- sizeof (*VarStore
)) * 2;
1227 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1229 // Space for linked list node
1231 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1234 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1238 // If the FormSet OpCode has a non-zero NvDataSize. There is a default
1239 // NvMap with ID=0, GUID that of the formset itself and "Setup" as name.
1241 SetupMapNameSize
= StrLen (SETUP_MAP_NAME
) + 1;
1242 VarStoreDefault
= AllocateZeroPool (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1244 if (0 != ((EFI_IFR_FORM_SET
*)FormSet
)->NvDataSize
) {
1246 VarStoreDefault
->Header
.OpCode
= EFI_IFR_VARSTORE_OP
;
1247 VarStoreDefault
->Header
.Length
= (UINT8
) (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1248 Unicode2Ascii ((CHAR8
*) (VarStoreDefault
+ 1), SETUP_MAP_NAME
);
1249 CopyMem (&VarStoreDefault
->Guid
, &((EFI_IFR_FORM_SET
*) FormSet
)->Guid
, sizeof (EFI_GUID
));
1250 VarStoreDefault
->VarId
= 0;
1251 VarStoreDefault
->Size
= ((EFI_IFR_FORM_SET
*) FormSet
)->NvDataSize
;
1256 SizeOfMaps
+= VarStoreDefault
->Size
;
1258 // add the size of the string
1260 SizeOfMaps
+= sizeof (SETUP_MAP_NAME
);
1264 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1266 // Space for linked list node
1268 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1271 if (0 == SizeOfMaps
) {
1273 // The IFR does not have any explicit or default map(s).
1275 return EFI_NOT_FOUND
;
1279 // Allocate the return buffer
1281 PackList
= AllocateZeroPool (SizeOfMaps
);
1282 ASSERT (NULL
!= PackList
);
1284 PackListNext
= PackList
;
1285 PackListLast
= PackList
;
1288 // Handle the default map first, if any.
1290 if (0 != VarStoreDefault
->Size
) {
1292 Map
= HiiGetDefaultImageInitPack (PackListNext
, VarStoreDefault
);
1294 HiiGetDefaultImagePopulateMap (Map
, FormSet
, VarStoreDefault
, DefaultMask
);
1296 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1297 PackListLast
= PackListNext
;
1298 PackListNext
= PackListNext
->NextVariablePack
;
1303 // Handle the explicit varstore(s)
1306 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1308 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1310 Map
= HiiGetDefaultImageInitPack (PackListNext
, (EFI_IFR_VARSTORE
*) IfrItem
);
1312 HiiGetDefaultImagePopulateMap (Map
, FormSet
, (EFI_IFR_VARSTORE
*) IfrItem
, DefaultMask
);
1314 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1315 PackListLast
= PackListNext
;
1316 PackListNext
= PackListNext
->NextVariablePack
;
1319 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1322 PackListLast
->NextVariablePack
= NULL
;
1323 *VariablePackList
= PackList
;
1332 IN EFI_HII_PROTOCOL
*This
,
1333 IN EFI_HII_HANDLE Handle
,
1334 IN EFI_FORM_LABEL Label
,
1336 IN EFI_HII_UPDATE_DATA
*Data
1340 Routine Description:
1341 This function allows the caller to update a form that has
1342 previously been registered with the EFI HII database.
1345 Handle - Hii Handle associated with the Formset to modify
1346 Label - Update information starting immediately after this label in the IFR
1347 AddData - If TRUE, add data. If FALSE, remove data
1348 Data - If adding data, this is the pointer to the data to add
1351 EFI_SUCCESS - Update success.
1352 Other - Update fail.
1356 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1357 EFI_HII_DATA
*HiiData
;
1358 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1359 EFI_HII_IFR_PACK
*FormPack
;
1360 EFI_IFR_OP_HEADER
*Location
;
1361 EFI_IFR_OP_HEADER
*DataLocation
;
1364 UINT8
*OrigTempBuffer
;
1365 UINTN TempBufferSize
;
1371 return EFI_INVALID_PARAMETER
;
1374 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
1376 HandleDatabase
= HiiData
->DatabaseHead
;
1378 PackageInstance
= NULL
;
1381 // Check numeric value against the head of the database
1383 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1385 // Match the numeric value with the database entry - if matched, extract PackageInstance
1387 if (Handle
== HandleDatabase
->Handle
) {
1388 PackageInstance
= HandleDatabase
->Buffer
;
1393 // No handle was found - error condition
1395 if (PackageInstance
== NULL
) {
1396 return EFI_INVALID_PARAMETER
;
1399 // Calculate and allocate space for retrieval of IFR data
1401 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1402 TempBufferSize
= (CHAR8
*) (&PackageInstance
->IfrData
) - (CHAR8
*) (PackageInstance
);
1404 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1405 TempBufferSize
+= DataLocation
->Length
;
1406 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1409 TempBufferSize
+= PackageInstance
->IfrSize
+ PackageInstance
->StringSize
;
1411 TempBuffer
= AllocateZeroPool (TempBufferSize
);
1412 OrigTempBuffer
= TempBuffer
;
1415 // We update only packages with IFR information in it
1417 if (PackageInstance
->IfrSize
== 0) {
1418 return EFI_INVALID_PARAMETER
;
1424 ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
))
1427 TempBuffer
= TempBuffer
+ ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
));
1430 // Based on if there is IFR data in this package instance, determine
1431 // what the location is of the beginning of the string data.
1433 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
1434 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
1437 // Look for the FormId requested
1439 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
1440 switch (Location
->OpCode
) {
1441 case EFI_IFR_FORM_SET_OP
:
1443 // If the FormSet has an update pending, pay attention.
1445 if (Data
->FormSetUpdate
) {
1446 ((EFI_IFR_FORM_SET
*) Location
)->CallbackHandle
= Data
->FormCallbackHandle
;
1449 CopyMem (TempBuffer
, Location
, Location
->Length
);
1450 TempBuffer
= TempBuffer
+ Location
->Length
;
1453 case EFI_IFR_FORM_OP
:
1455 // If the Form has an update pending, pay attention.
1457 if (Data
->FormUpdate
) {
1458 ((EFI_IFR_FORM
*) Location
)->FormTitle
= Data
->FormTitle
;
1461 CopyMem (TempBuffer
, Location
, Location
->Length
);
1462 TempBuffer
= TempBuffer
+ Location
->Length
;
1465 case EFI_IFR_LABEL_OP
:
1467 // If the label does not match the requested update point, ignore it
1469 if (((EFI_IFR_LABEL
*) Location
)->LabelId
!= Label
) {
1473 CopyMem (TempBuffer
, Location
, Location
->Length
);
1474 TempBuffer
= TempBuffer
+ Location
->Length
;
1477 // Go to the next Op-Code
1479 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1487 CopyMem (TempBuffer
, Location
, Location
->Length
);
1488 TempBuffer
= TempBuffer
+ Location
->Length
;
1491 // Add the DataCount amount of opcodes to TempBuffer
1493 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1494 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1495 CopyMem (TempBuffer
, DataLocation
, DataLocation
->Length
);
1496 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
+= DataLocation
->Length
;
1497 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1498 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1499 TempBuffer
= TempBuffer
+ DataLocation
->Length
;
1500 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1503 // Go to the next Op-Code
1505 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1511 CopyMem (TempBuffer
, Location
, Location
->Length
);
1512 TempBuffer
= TempBuffer
+ Location
->Length
;
1513 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1516 // Remove the DataCount amount of opcodes unless we run into an end of form or a label
1518 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1520 // If we are about to skip an end form - bail out, since that is illegal
1522 if ((Location
->OpCode
== EFI_IFR_END_FORM_OP
) || (Location
->OpCode
== EFI_IFR_LABEL_OP
)) {
1526 // By skipping Location entries, we are in effect not copying what was previously there
1528 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
-= Location
->Length
;
1529 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1530 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1531 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1536 CopyMem (TempBuffer
, Location
, Location
->Length
);
1537 TempBuffer
= TempBuffer
+ Location
->Length
;
1541 // Go to the next Op-Code
1543 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1546 // Copy the last op-code left behind from the for loop
1548 CopyMem (TempBuffer
, Location
, Location
->Length
);
1551 // Advance to beginning of strings and copy them
1553 TempBuffer
= TempBuffer
+ Location
->Length
;
1554 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1555 CopyMem (TempBuffer
, Location
, PackageInstance
->StringSize
);
1558 // Free the old buffer, and assign into our database the latest buffer
1560 gBS
->FreePool (HandleDatabase
->Buffer
);
1561 HandleDatabase
->Buffer
= OrigTempBuffer
;