2 This file contains the form processing code to the HII database.
4 Copyright (c) 2006 - 2007 Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "HiiDatabase.h"
21 OUT CHAR16
*UnicodeStr
,
28 This function converts ASCII string to Unicode string.
32 UnicodeStr - NULL terminated Unicode output string.
33 AsciieStr - NULL terminated ASCII input string.
37 Start of the Unicode ouput string.
42 CHAR16
*Str
= UnicodeStr
;
44 *(UnicodeStr
++) = (CHAR16
) *AsciiStr
;
45 if (*(AsciiStr
++) == '\0') {
61 This function converts Unicode string to ASCII string.
65 AsciieStr - NULL terminated ASCII output string.
66 UnicodeStr - NULL terminated Unicode input string.
70 Start of the ASCII ouput string.
75 CHAR8
*Str
= AsciiStr
;
77 *(AsciiStr
++) = (CHAR8
) *UnicodeStr
;
78 if (*(UnicodeStr
++) == '\0') {
86 ExtractDevicePathData (
87 IN EFI_HII_DATA_TABLE
*DataTable
,
89 IN OUT UINT8
**ExportBufferPtr
103 ExportBuffer
= *ExportBufferPtr
;
106 // BUGBUG - don't have devicepath data yet, setting dummy value
109 ExportBuffer
= (UINT8
*) DataTable
;
110 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Type
= EFI_HII_DEVICE_PATH
;
111 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Length
= (UINT32
) (sizeof (EFI_HII_DEVICE_PATH_PACK
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
114 // BUGBUG - part of hack - skip the Device Path Pack.....place some data
116 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_DEVICE_PATH_PACK
);
118 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->Type
= EFI_END_ENTIRE_DEVICE_PATH
;
119 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->SubType
= EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
;
122 // BUGBUG - still part of hack....
124 ExportBuffer
= ExportBuffer
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
125 *ExportBufferPtr
= ExportBuffer
;
130 ExtractVariableData (
131 IN OUT EFI_HII_DATA_TABLE
*DataTable
,
133 IN OUT UINT8
**ExportBufferPtr
139 This function extract the EFI_HII_VARIABLE_PACK portion from the
140 each of the EFI_HII_PACKAGE_INSTANCE in HII handle database.
144 DataTable - On input, this parameter point to the EFI_HII_DATA_TABLE structure
145 of the final data buffer for the EFI_HII_EXPORT interface. This function
146 update the NumberOfVariableData attribute.
147 IfrData - It points to a staring address of a EFI_HII_IFR_PACK structure.
148 ExportBufferPtr - On input, it points the starting address of the data buffer to
149 host the variable pack. On output, it is the starting address
150 of data buffer for the next extraction operation.
157 EFI_HII_VARIABLE_PACK
*VariableContents
;
163 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
164 EFI_PHYSICAL_ADDRESS CallbackHandle
;
170 ExportBuffer
= *ExportBufferPtr
;
172 for (Index
= 0; IfrData
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
173 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
175 switch (IfrData
[Index
]) {
176 case EFI_IFR_FORM_SET_OP
:
177 TempValue
= EFI_HII_VARIABLE
;
178 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
179 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
182 // If the variable has 0 size, do not process it
184 if (TempValue
== 0) {
188 // Add the size of the variable pack overhead. Later, will also add the size of the
189 // name of the variable.
191 TempValue
= TempValue
+ sizeof (EFI_HII_VARIABLE_PACK
);
193 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
196 &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->CallbackHandle
,
197 sizeof (EFI_PHYSICAL_ADDRESS
)
199 if (CallbackHandle
!= 0) {
200 Status
= gBS
->HandleProtocol (
201 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
202 &gEfiFormCallbackProtocolGuid
,
203 (VOID
*) &FormCallback
205 ASSERT_EFI_ERROR (Status
);
208 // Since we have a "Setup" variable that wasn't specified by a variable op-code
209 // it will have a VariableId of 0. All other variable op-codes will have a designation
213 CopyMem (&VariableContents
->VariableId
, &TempValue
, sizeof (UINT16
));
214 CopyMem (&VariableContents
->VariableGuid
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->Guid
, sizeof (EFI_GUID
));
215 TempValue
= sizeof (SETUP_MAP_NAME
);
216 CopyMem (&VariableContents
->VariableNameLength
, &TempValue
, sizeof (UINT32
));
219 // Add the size of the name to the Header Length
222 CopyMem (&TempValue2
, &VariableContents
->Header
.Length
, sizeof (UINT32
));
223 TempValue2
= TempValue
+ TempValue2
;
224 CopyMem (&VariableContents
->Header
.Length
, &TempValue2
, sizeof (UINT32
));
226 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
227 CopyMem (ExportBuffer
, SETUP_MAP_NAME
, sizeof (SETUP_MAP_NAME
));
228 ExportBuffer
= ExportBuffer
+ sizeof (SETUP_MAP_NAME
);
230 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
232 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
233 Status
= FormCallback
->NvRead (
235 (CHAR16
*) SETUP_MAP_NAME
,
236 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
241 ASSERT_EFI_ERROR (Status
);
243 Status
= gRT
->GetVariable (
244 (CHAR16
*) SETUP_MAP_NAME
,
245 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
250 ASSERT_EFI_ERROR (Status
);
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
,
309 ASSERT_EFI_ERROR (Status
);
311 Status
= gRT
->GetVariable (
313 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
318 ASSERT_EFI_ERROR (Status
);
321 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + TempValue
);
322 DataTable
->NumberOfVariableData
++;
326 Index
= IfrData
[Index
+ 1] + Index
;
329 // If we have added a variable pack, add a dummy empty one to signify the end
331 if (ExportBuffer
!= *ExportBufferPtr
) {
332 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
333 TempValue
= EFI_HII_VARIABLE
;
334 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
335 TempValue
= sizeof (EFI_HII_VARIABLE_PACK
);
336 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
337 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
340 *ExportBufferPtr
= ExportBuffer
;
346 IN EFI_HII_PROTOCOL
*This
,
347 IN EFI_HII_HANDLE Handle
,
348 IN OUT UINTN
*BufferSize
,
355 This function allows a program to extract a form or form package that has
356 previously been registered with the EFI HII database.
364 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
365 EFI_HII_DATA
*HiiData
;
366 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
367 EFI_HII_IFR_PACK
*FormPack
;
370 EFI_HII_EXPORT_TABLE
*ExportTable
;
371 EFI_HII_DATA_TABLE
*DataTable
;
372 BOOLEAN VariableExist
;
373 UINT16 NumberOfHiiDataTables
;
380 return EFI_INVALID_PARAMETER
;
383 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
385 HandleDatabase
= HiiData
->DatabaseHead
;
389 PackageInstance
= NULL
;
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
;
737 return EFI_INVALID_PARAMETER
;
740 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
742 HandleDatabase
= HiiData
->DatabaseHead
;
744 PackageInstance
= NULL
;
749 // Check numeric value against the head of the database
751 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
753 // Match the numeric value with the database entry - if matched, extract PackageInstance
755 if (Handle
== HandleDatabase
->Handle
) {
756 PackageInstance
= HandleDatabase
->Buffer
;
761 // No handle was found - error condition
763 if (PackageInstance
== NULL
) {
764 return EFI_NOT_FOUND
;
767 // Based on if there is IFR data in this package instance, determine
768 // what the location is of the beginning of the string data.
770 if (PackageInstance
->IfrSize
> 0) {
771 FormPack
= (EFI_HII_IFR_PACK
*) (&PackageInstance
->IfrData
);
774 // If there is no IFR data return an error
776 return EFI_NOT_FOUND
;
779 // If requesting the entire Form Package
783 // Return an error if buffer is too small
785 if (PackageInstance
->IfrSize
> *BufferLength
|| Buffer
== NULL
) {
786 *BufferLength
= (UINT16
) PackageInstance
->IfrSize
;
787 return EFI_BUFFER_TOO_SMALL
;
790 CopyMem (Buffer
, FormPack
, PackageInstance
->IfrSize
);
793 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
794 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
797 // Look for the FormId requested
799 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
800 switch (Location
->OpCode
) {
801 case EFI_IFR_FORM_OP
:
802 Form
= (EFI_IFR_FORM
*) Location
;
805 // If we found a Form Op-code and it is of the correct Id, copy it and return
807 if (Form
->FormId
== FormId
) {
809 // Calculate the total size of form
811 for (FormLength
= 0; Location
->OpCode
!= EFI_IFR_END_FORM_OP
; ) {
812 FormLength
+= Location
->Length
;
813 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
815 FormLength
+= Location
->Length
;
816 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
818 if ((Buffer
== NULL
) || (FormLength
> *BufferLength
)) {
819 *BufferLengthTemp
= FormLength
;
820 return EFI_BUFFER_TOO_SMALL
;
824 // Rewind to start offset of the found Form
826 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*)Location
- FormLength
);
827 CopyMem (Buffer
, Location
, FormLength
);
835 // Go to the next Op-Code
837 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
841 return EFI_NOT_FOUND
;
845 // Helper functions to HiiGetDefaultImage()
850 HiiGetDefaultImageInitPack (
851 IN OUT EFI_HII_VARIABLE_PACK_LIST
*VariablePackItem
,
852 IN EFI_IFR_VARSTORE
*VarStore
858 Initialize the EFI_HII_VARIABLE_PACK_LIST structure and
859 prepare it ready to be used by HiiGetDefaultImagePopulateMap ().
863 VariablePackItem - Variable Package List.
864 VarStore - IFR variable storage.
868 Return the pointer to the Map space.
875 EFI_HII_VARIABLE_PACK
*VariablePack
;
878 // Set pointer the pack right after the node
880 VariablePackItem
->VariablePack
= (EFI_HII_VARIABLE_PACK
*) (VariablePackItem
+ 1);
881 VariablePack
= VariablePackItem
->VariablePack
;
884 // Copy the var name to VariablePackItem from VarStore
885 // Needs ASCII->Unicode conversion.
887 ASSERT (VarStore
->Header
.Length
> sizeof (*VarStore
));
888 Name8
= (CHAR8
*) (VarStore
+ 1);
889 Name16
= (CHAR16
*) (VariablePack
+ 1);
890 Ascii2Unicode (Name16
, Name8
);
893 // Compute the other fields of the VariablePackItem
895 VariablePack
->VariableId
= VarStore
->VarId
;
896 CopyMem (&VariablePack
->VariableGuid
, &VarStore
->Guid
, sizeof (EFI_GUID
));
897 VariablePack
->VariableNameLength
= (UINT32
) ((StrLen (Name16
) + 1) * 2);
898 VariablePack
->Header
.Length
= sizeof (*VariablePack
)
899 + VariablePack
->VariableNameLength
902 // Return the pointer to the Map space.
904 Map
= (CHAR8
*) Name16
+ VariablePack
->VariableNameLength
;
911 HiiGetDefaultImagePopulateMap (
913 IN EFI_IFR_OP_HEADER
*FormSet
,
914 IN EFI_IFR_VARSTORE
*VarStore
,
921 Fill the Map with all the default values either from NV or Hii database.
925 Map - Memory pointer to hold the default values.
926 FormSet - The starting EFI_IFR_OP_HEADER to begin retriving default values.
927 VarStore - IFR variable storage.
928 DefaultMask - The mask used to get the default variable.
937 EFI_IFR_OP_HEADER
*IfrItem
;
939 EFI_IFR_VARSTORE_SELECT
*VarSelect
;
940 EFI_IFR_ONE_OF_OPTION
*OneOfOpt
;
941 EFI_IFR_CHECKBOX
*CheckBox
;
942 EFI_IFR_NUMERIC
*Numeric
;
945 EFI_IFR_NV_DATA
*IfrNvData
;
949 EFI_HANDLE CallbackHandle
;
950 EFI_FORM_CALLBACK_PROTOCOL
*FormCallbackProt
;
953 // Get the Map's Name/Guid/Szie from the Varstore.
954 // VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.
956 ASSERT (VarStore
->Header
.Length
>= sizeof (*VarStore
));
957 Name8
= (CHAR8
*) (VarStore
+ 1);
958 Name16
= AllocateZeroPool ((VarStore
->Header
.Length
- sizeof (*VarStore
)) * sizeof (CHAR16
));
959 Ascii2Unicode (Name16
, Name8
);
960 CopyMem (&Guid
, &VarStore
->Guid
, sizeof(EFI_GUID
));
961 Size
= VarStore
->Size
;
964 // First, check if the map exists in the NV. If so, get it from NV and exit.
966 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
968 // Check if Manufaturing Defaults exist in the NV.
970 Status
= EfiLibHiiVariableOverrideBySuffix (
971 HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE
,
979 // All other cases default to Defaults. Check if Defaults exist in the NV.
981 Status
= EfiLibHiiVariableOverrideBySuffix (
982 HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE
,
989 if (!EFI_ERROR (Status
)) {
991 // Either Defaults/Manufacturing variable exists and appears to be valid.
992 // The map is read, exit w/ success now.
999 // First, prime the map with what already is in the NV.
1000 // This is needed to cover a situation where the IFR does not contain all the
1001 // defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.
1002 // Ignore status. Either it gets read or not.
1004 FormCallbackProt
= NULL
;
1005 CopyMem (&CallbackHandle
, &((EFI_IFR_FORM_SET
*) FormSet
)->CallbackHandle
, sizeof (CallbackHandle
));
1006 if (CallbackHandle
!= NULL
) {
1007 Status
= gBS
->HandleProtocol (
1008 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
1009 &gEfiFormCallbackProtocolGuid
,
1010 (VOID
*) &FormCallbackProt
1013 if ((NULL
!= FormCallbackProt
) && (NULL
!= FormCallbackProt
->NvRead
)) {
1015 // Attempt to read using NvRead() callback. Probe first for existence and correct variable size.
1018 Status
= FormCallbackProt
->NvRead (
1026 if ((EFI_BUFFER_TOO_SMALL
== Status
) && (SizeTmp
== Size
)) {
1027 Status
= FormCallbackProt
->NvRead (
1035 ASSERT_EFI_ERROR (Status
);
1036 ASSERT (SizeTmp
== Size
);
1040 // No callback available for this formset, read straight from NV. Deliberately ignore the Status.
1041 // The buffer will only be written if variable exists nd has correct size.
1043 Status
= EfiLibHiiVariableRetrieveFromNv (
1052 // Iterate all IFR statements and for applicable, retrieve the default into the Map.
1054 for (IfrItem
= FormSet
, VarId
= 0;
1055 IfrItem
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;
1056 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
)
1060 // Observe VarStore switch.
1062 if (EFI_IFR_VARSTORE_SELECT_OP
== IfrItem
->OpCode
) {
1063 VarSelect
= (EFI_IFR_VARSTORE_SELECT
*) IfrItem
;
1064 VarId
= VarSelect
->VarId
;
1070 // Skip opcodes that reference other VarStore than that specific to current map.
1072 if (VarId
!= VarStore
->VarId
) {
1077 // Extract the default value from this opcode if applicable, and apply it to the map.
1079 IfrNvData
= (EFI_IFR_NV_DATA
*) IfrItem
;
1080 switch (IfrItem
->OpCode
) {
1082 case EFI_IFR_ONE_OF_OP
:
1083 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1085 // Get to the first EFI_IFR_ONE_OF_OPTION_OP
1087 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1088 ASSERT (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
);
1090 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1092 // In the worst case, the first will be the default.
1094 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1096 while (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
) {
1098 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1099 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1100 if (0 != (OneOfOpt
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1102 // In the worst case, the first will be the default.
1104 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1108 if (OneOfOpt
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1110 // In the worst case, the first will be the default.
1112 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1117 IfrItem
= (EFI_IFR_OP_HEADER
*)((UINT8
*)IfrItem
+ IfrItem
->Length
);
1122 case EFI_IFR_CHECKBOX_OP
:
1123 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1124 CheckBox
= (EFI_IFR_CHECK_BOX
*)IfrItem
;
1125 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1126 if (0 != (CheckBox
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1127 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1130 if (CheckBox
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1131 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1136 case EFI_IFR_NUMERIC_OP
:
1137 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1138 Numeric
= (EFI_IFR_NUMERIC
*) IfrItem
;
1139 CopyMem (Map
+ IfrNvData
->QuestionId
, &Numeric
->Default
, IfrNvData
->StorageWidth
);
1142 case EFI_IFR_ORDERED_LIST_OP
:
1143 case EFI_IFR_PASSWORD_OP
:
1144 case EFI_IFR_STRING_OP
:
1146 // No support for default value for these opcodes.
1159 HiiGetDefaultImage (
1160 IN EFI_HII_PROTOCOL
*This
,
1161 IN EFI_HII_HANDLE Handle
,
1162 IN UINTN DefaultMask
,
1163 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
1167 Routine Description:
1169 This function allows a program to extract the NV Image
1170 that represents the default storage image
1173 This - A pointer to the EFI_HII_PROTOCOL instance.
1174 Handle - The HII handle from which will have default data retrieved.
1175 UINTN - Mask used to retrieve the default image.
1176 VariablePackList - Callee allocated, tightly-packed, link list data
1177 structure that contain all default varaible packs
1178 from the Hii Database.
1181 EFI_NOT_FOUND - If Hii database does not contain any default images.
1182 EFI_INVALID_PARAMETER - Invalid input parameter.
1183 EFI_SUCCESS - Operation successful.
1187 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1188 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1189 EFI_IFR_OP_HEADER
*FormSet
;
1190 EFI_IFR_OP_HEADER
*IfrItem
;
1191 EFI_IFR_VARSTORE
*VarStore
;
1192 EFI_IFR_VARSTORE
*VarStoreDefault
;
1193 UINTN SetupMapNameSize
;
1195 EFI_HII_VARIABLE_PACK_LIST
*PackList
;
1196 EFI_HII_VARIABLE_PACK_LIST
*PackListNext
;
1197 EFI_HII_VARIABLE_PACK_LIST
*PackListLast
;
1202 // Find the IFR pack from the handle. Then get the formset from the pack.
1204 PackageInstance
= NULL
;
1205 HandleDatabase
= (EFI_HII_DATA_FROM_THIS (This
))->DatabaseHead
;
1206 for ( ; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1207 if (Handle
== HandleDatabase
->Handle
) {
1208 PackageInstance
= HandleDatabase
->Buffer
;
1212 if (PackageInstance
== NULL
) {
1213 return EFI_INVALID_PARAMETER
;
1215 FormSet
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) &PackageInstance
->IfrData
+ sizeof (EFI_HII_IFR_PACK
));
1218 // Get the sizes of all the VARSTOREs in this VFR.
1219 // Then allocate enough space for all of them plus all maps
1223 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1225 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1226 VarStore
= (EFI_IFR_VARSTORE
*) IfrItem
;
1230 SizeOfMaps
+= VarStore
->Size
;
1232 // add the size of the string, in Unicode
1234 SizeOfMaps
+= (VarStore
->Header
.Length
- sizeof (*VarStore
)) * 2;
1238 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1240 // Space for linked list node
1242 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1245 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1249 // If the FormSet OpCode has a non-zero NvDataSize. There is a default
1250 // NvMap with ID=0, GUID that of the formset itself and "Setup" as name.
1252 SetupMapNameSize
= StrLen (SETUP_MAP_NAME
) + 1;
1253 VarStoreDefault
= AllocateZeroPool (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1255 if (0 != ((EFI_IFR_FORM_SET
*)FormSet
)->NvDataSize
) {
1257 VarStoreDefault
->Header
.OpCode
= EFI_IFR_VARSTORE_OP
;
1258 VarStoreDefault
->Header
.Length
= (UINT8
) (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1259 Unicode2Ascii ((CHAR8
*) (VarStoreDefault
+ 1), SETUP_MAP_NAME
);
1260 CopyMem (&VarStoreDefault
->Guid
, &((EFI_IFR_FORM_SET
*) FormSet
)->Guid
, sizeof (EFI_GUID
));
1261 VarStoreDefault
->VarId
= 0;
1262 VarStoreDefault
->Size
= ((EFI_IFR_FORM_SET
*) FormSet
)->NvDataSize
;
1267 SizeOfMaps
+= VarStoreDefault
->Size
;
1269 // add the size of the string
1271 SizeOfMaps
+= sizeof (SETUP_MAP_NAME
);
1275 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1277 // Space for linked list node
1279 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1282 if (0 == SizeOfMaps
) {
1284 // The IFR does not have any explicit or default map(s).
1286 return EFI_NOT_FOUND
;
1290 // Allocate the return buffer
1292 PackList
= AllocateZeroPool (SizeOfMaps
);
1293 ASSERT (NULL
!= PackList
);
1295 PackListNext
= PackList
;
1296 PackListLast
= PackList
;
1299 // Handle the default map first, if any.
1301 if (0 != VarStoreDefault
->Size
) {
1303 Map
= HiiGetDefaultImageInitPack (PackListNext
, VarStoreDefault
);
1305 HiiGetDefaultImagePopulateMap (Map
, FormSet
, VarStoreDefault
, DefaultMask
);
1307 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1308 PackListLast
= PackListNext
;
1309 PackListNext
= PackListNext
->NextVariablePack
;
1314 // Handle the explicit varstore(s)
1317 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1319 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1321 Map
= HiiGetDefaultImageInitPack (PackListNext
, (EFI_IFR_VARSTORE
*) IfrItem
);
1323 HiiGetDefaultImagePopulateMap (Map
, FormSet
, (EFI_IFR_VARSTORE
*) IfrItem
, DefaultMask
);
1325 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1326 PackListLast
= PackListNext
;
1327 PackListNext
= PackListNext
->NextVariablePack
;
1330 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1333 PackListLast
->NextVariablePack
= NULL
;
1334 *VariablePackList
= PackList
;
1343 IN EFI_HII_PROTOCOL
*This
,
1344 IN EFI_HII_HANDLE Handle
,
1345 IN EFI_FORM_LABEL Label
,
1347 IN EFI_HII_UPDATE_DATA
*Data
1351 Routine Description:
1352 This function allows the caller to update a form that has
1353 previously been registered with the EFI HII database.
1356 Handle - Hii Handle associated with the Formset to modify
1357 Label - Update information starting immediately after this label in the IFR
1358 AddData - If TRUE, add data. If FALSE, remove data
1359 Data - If adding data, this is the pointer to the data to add
1362 EFI_SUCCESS - Update success.
1363 Other - Update fail.
1367 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1368 EFI_HII_DATA
*HiiData
;
1369 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1370 EFI_HII_IFR_PACK
*FormPack
;
1371 EFI_IFR_OP_HEADER
*Location
;
1372 EFI_IFR_OP_HEADER
*DataLocation
;
1375 UINT8
*OrigTempBuffer
;
1376 UINTN TempBufferSize
;
1382 return EFI_INVALID_PARAMETER
;
1385 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
1387 HandleDatabase
= HiiData
->DatabaseHead
;
1389 PackageInstance
= NULL
;
1392 // Check numeric value against the head of the database
1394 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1396 // Match the numeric value with the database entry - if matched, extract PackageInstance
1398 if (Handle
== HandleDatabase
->Handle
) {
1399 PackageInstance
= HandleDatabase
->Buffer
;
1404 // No handle was found - error condition
1406 if (PackageInstance
== NULL
) {
1407 return EFI_INVALID_PARAMETER
;
1410 // Calculate and allocate space for retrieval of IFR data
1412 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1413 TempBufferSize
= (CHAR8
*) (&PackageInstance
->IfrData
) - (CHAR8
*) (PackageInstance
);
1415 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1416 TempBufferSize
+= DataLocation
->Length
;
1417 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1420 TempBufferSize
+= PackageInstance
->IfrSize
+ PackageInstance
->StringSize
;
1422 TempBuffer
= AllocateZeroPool (TempBufferSize
);
1423 ASSERT (TempBuffer
!= NULL
);
1425 OrigTempBuffer
= TempBuffer
;
1428 // We update only packages with IFR information in it
1430 if (PackageInstance
->IfrSize
== 0) {
1431 return EFI_INVALID_PARAMETER
;
1437 ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
))
1440 TempBuffer
= TempBuffer
+ ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
));
1443 // Based on if there is IFR data in this package instance, determine
1444 // what the location is of the beginning of the string data.
1446 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
1447 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
1450 // Look for the FormId requested
1452 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
1453 switch (Location
->OpCode
) {
1454 case EFI_IFR_FORM_SET_OP
:
1456 // If the FormSet has an update pending, pay attention.
1458 if (Data
->FormSetUpdate
) {
1459 ((EFI_IFR_FORM_SET
*) Location
)->CallbackHandle
= Data
->FormCallbackHandle
;
1462 CopyMem (TempBuffer
, Location
, Location
->Length
);
1463 TempBuffer
= TempBuffer
+ Location
->Length
;
1466 case EFI_IFR_FORM_OP
:
1468 // If the Form has an update pending, pay attention.
1470 if (Data
->FormUpdate
) {
1471 ((EFI_IFR_FORM
*) Location
)->FormTitle
= Data
->FormTitle
;
1474 CopyMem (TempBuffer
, Location
, Location
->Length
);
1475 TempBuffer
= TempBuffer
+ Location
->Length
;
1478 case EFI_IFR_LABEL_OP
:
1480 // If the label does not match the requested update point, ignore it
1482 if (((EFI_IFR_LABEL
*) Location
)->LabelId
!= Label
) {
1486 CopyMem (TempBuffer
, Location
, Location
->Length
);
1487 TempBuffer
= TempBuffer
+ Location
->Length
;
1490 // Go to the next Op-Code
1492 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1500 CopyMem (TempBuffer
, Location
, Location
->Length
);
1501 TempBuffer
= TempBuffer
+ Location
->Length
;
1504 // Add the DataCount amount of opcodes to TempBuffer
1506 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1507 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1508 CopyMem (TempBuffer
, DataLocation
, DataLocation
->Length
);
1509 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
+= DataLocation
->Length
;
1510 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1511 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1512 TempBuffer
= TempBuffer
+ DataLocation
->Length
;
1513 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1516 // Go to the next Op-Code
1518 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1524 CopyMem (TempBuffer
, Location
, Location
->Length
);
1525 TempBuffer
= TempBuffer
+ Location
->Length
;
1526 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1529 // Remove the DataCount amount of opcodes unless we run into an end of form or a label
1531 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1533 // If we are about to skip an end form - bail out, since that is illegal
1535 if ((Location
->OpCode
== EFI_IFR_END_FORM_OP
) || (Location
->OpCode
== EFI_IFR_LABEL_OP
)) {
1539 // By skipping Location entries, we are in effect not copying what was previously there
1541 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
-= Location
->Length
;
1542 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1543 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1544 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1549 CopyMem (TempBuffer
, Location
, Location
->Length
);
1550 TempBuffer
= TempBuffer
+ Location
->Length
;
1554 // Go to the next Op-Code
1556 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1559 // Copy the last op-code left behind from the for loop
1561 CopyMem (TempBuffer
, Location
, Location
->Length
);
1564 // Advance to beginning of strings and copy them
1566 TempBuffer
= TempBuffer
+ Location
->Length
;
1567 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1568 CopyMem (TempBuffer
, Location
, PackageInstance
->StringSize
);
1571 // Free the old buffer, and assign into our database the latest buffer
1573 FreePool (HandleDatabase
->Buffer
);
1574 HandleDatabase
->Buffer
= OrigTempBuffer
;