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.
17 // Include common header file for this module.
19 #include "CommonHeader.h"
21 #include "HiiDatabase.h"
26 OUT CHAR16
*UnicodeStr
,
33 This function converts ASCII string to Unicode string.
37 UnicodeStr - NULL terminated Unicode output string.
38 AsciieStr - NULL terminated ASCII input string.
42 Start of the Unicode ouput string.
47 CHAR16
*Str
= UnicodeStr
;
49 *(UnicodeStr
++) = (CHAR16
) *AsciiStr
;
50 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') {
91 ExtractDevicePathData (
92 IN EFI_HII_DATA_TABLE
*DataTable
,
94 IN OUT UINT8
**ExportBufferPtr
108 ExportBuffer
= *ExportBufferPtr
;
111 // BUGBUG - don't have devicepath data yet, setting dummy value
114 ExportBuffer
= (UINT8
*) DataTable
;
115 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Type
= EFI_HII_DEVICE_PATH
;
116 ((EFI_HII_DEVICE_PATH_PACK
*) ExportBuffer
)->Header
.Length
= (UINT32
) (sizeof (EFI_HII_DEVICE_PATH_PACK
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
119 // BUGBUG - part of hack - skip the Device Path Pack.....place some data
121 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_DEVICE_PATH_PACK
);
123 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->Type
= EFI_END_ENTIRE_DEVICE_PATH
;
124 ((EFI_DEVICE_PATH_PROTOCOL
*) ExportBuffer
)->SubType
= EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
;
127 // BUGBUG - still part of hack....
129 ExportBuffer
= ExportBuffer
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
130 *ExportBufferPtr
= ExportBuffer
;
135 ExtractVariableData (
136 IN OUT EFI_HII_DATA_TABLE
*DataTable
,
138 IN OUT UINT8
**ExportBufferPtr
144 This function extract the EFI_HII_VARIABLE_PACK portion from the
145 each of the EFI_HII_PACKAGE_INSTANCE in HII handle database.
149 DataTable - On input, this parameter point to the EFI_HII_DATA_TABLE structure
150 of the final data buffer for the EFI_HII_EXPORT interface. This function
151 update the NumberOfVariableData attribute.
152 IfrData - It points to a staring address of a EFI_HII_IFR_PACK structure.
153 ExportBufferPtr - On input, it points the starting address of the data buffer to
154 host the variable pack. On output, it is the starting address
155 of data buffer for the next extraction operation.
162 EFI_HII_VARIABLE_PACK
*VariableContents
;
168 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
169 EFI_PHYSICAL_ADDRESS CallbackHandle
;
175 ExportBuffer
= *ExportBufferPtr
;
177 for (Index
= 0; IfrData
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
178 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
180 switch (IfrData
[Index
]) {
181 case EFI_IFR_FORM_SET_OP
:
182 TempValue
= EFI_HII_VARIABLE
;
183 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
184 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
187 // If the variable has 0 size, do not process it
189 if (TempValue
== 0) {
193 // Add the size of the variable pack overhead. Later, will also add the size of the
194 // name of the variable.
196 TempValue
= TempValue
+ sizeof (EFI_HII_VARIABLE_PACK
);
198 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
201 &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->CallbackHandle
,
202 sizeof (EFI_PHYSICAL_ADDRESS
)
204 if (CallbackHandle
!= 0) {
205 Status
= gBS
->HandleProtocol (
206 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
207 &gEfiFormCallbackProtocolGuid
,
208 (VOID
*) &FormCallback
210 ASSERT_EFI_ERROR (Status
);
213 // Since we have a "Setup" variable that wasn't specified by a variable op-code
214 // it will have a VariableId of 0. All other variable op-codes will have a designation
218 CopyMem (&VariableContents
->VariableId
, &TempValue
, sizeof (UINT16
));
219 CopyMem (&VariableContents
->VariableGuid
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->Guid
, sizeof (EFI_GUID
));
220 TempValue
= sizeof (SETUP_MAP_NAME
);
221 CopyMem (&VariableContents
->VariableNameLength
, &TempValue
, sizeof (UINT32
));
224 // Add the size of the name to the Header Length
227 CopyMem (&TempValue2
, &VariableContents
->Header
.Length
, sizeof (UINT32
));
228 TempValue2
= TempValue
+ TempValue2
;
229 CopyMem (&VariableContents
->Header
.Length
, &TempValue2
, sizeof (UINT32
));
231 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
232 CopyMem (ExportBuffer
, SETUP_MAP_NAME
, sizeof (SETUP_MAP_NAME
));
233 ExportBuffer
= ExportBuffer
+ sizeof (SETUP_MAP_NAME
);
235 CopyMem (&TempValue
, &((EFI_IFR_FORM_SET
*) &IfrData
[Index
])->NvDataSize
, sizeof (UINT16
));
237 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
238 Status
= FormCallback
->NvRead (
240 (CHAR16
*) SETUP_MAP_NAME
,
241 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
246 ASSERT_EFI_ERROR (Status
);
248 Status
= gRT
->GetVariable (
249 (CHAR16
*) SETUP_MAP_NAME
,
250 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
255 ASSERT_EFI_ERROR (Status
);
258 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + TempValue
);
259 DataTable
->NumberOfVariableData
++;
262 case EFI_IFR_VARSTORE_OP
:
263 TempValue
= EFI_HII_VARIABLE
;
264 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
265 CopyMem (&TempValue
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Size
, sizeof (UINT16
));
268 // If the variable has 0 size, do not process it
270 if (TempValue
== 0) {
274 // Add the size of the variable pack overhead. Later, will also add the size of the
275 // name of the variable.
277 TempValue
= TempValue
+ sizeof (EFI_HII_VARIABLE_PACK
);
279 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
280 CopyMem (&VariableContents
->VariableId
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->VarId
, sizeof (UINT16
));
281 CopyMem (&VariableContents
->VariableGuid
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Guid
, sizeof (EFI_GUID
));
282 TempValue
= (UINTN
) ((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Header
.Length
- sizeof (EFI_IFR_VARSTORE
);
283 TempValue
= TempValue
* 2;
284 CopyMem (&VariableContents
->VariableNameLength
, &TempValue
, sizeof (UINT32
));
287 // Add the size of the name to the Header Length
290 CopyMem (&TempValue2
, &VariableContents
->Header
.Length
, sizeof (UINT32
));
291 TempValue2
= TempValue
+ TempValue2
;
292 CopyMem (&VariableContents
->Header
.Length
, &TempValue2
, sizeof (UINT32
));
294 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
295 String
= (CHAR16
*) ExportBuffer
;
296 for (Index2
= 0; Index2
< TempValue
/ 2; Index2
++) {
297 ExportBuffer
[Index2
* 2] = IfrData
[Index
+ sizeof (EFI_IFR_VARSTORE
) + Index2
];
298 ExportBuffer
[Index2
* 2 + 1] = 0;
301 ExportBuffer
= ExportBuffer
+ TempValue
;
303 CopyMem (&TempValue
, &((EFI_IFR_VARSTORE
*) &IfrData
[Index
])->Size
, sizeof (UINT16
));
305 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
306 Status
= FormCallback
->NvRead (
309 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
314 ASSERT_EFI_ERROR (Status
);
316 Status
= gRT
->GetVariable (
318 (EFI_GUID
*)(UINTN
)&VariableContents
->VariableGuid
,
323 ASSERT_EFI_ERROR (Status
);
326 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + TempValue
);
327 DataTable
->NumberOfVariableData
++;
331 Index
= IfrData
[Index
+ 1] + Index
;
334 // If we have added a variable pack, add a dummy empty one to signify the end
336 if (ExportBuffer
!= *ExportBufferPtr
) {
337 VariableContents
= (EFI_HII_VARIABLE_PACK
*) ExportBuffer
;
338 TempValue
= EFI_HII_VARIABLE
;
339 CopyMem (&VariableContents
->Header
.Type
, &TempValue
, sizeof (UINT16
));
340 TempValue
= sizeof (EFI_HII_VARIABLE_PACK
);
341 CopyMem (&VariableContents
->Header
.Length
, &TempValue
, sizeof (UINT32
));
342 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_VARIABLE_PACK
);
345 *ExportBufferPtr
= ExportBuffer
;
351 IN EFI_HII_PROTOCOL
*This
,
352 IN EFI_HII_HANDLE Handle
,
353 IN OUT UINTN
*BufferSize
,
360 This function allows a program to extract a form or form package that has
361 previously been registered with the EFI HII database.
369 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
370 EFI_HII_DATA
*HiiData
;
371 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
372 EFI_HII_IFR_PACK
*FormPack
;
375 EFI_HII_EXPORT_TABLE
*ExportTable
;
376 EFI_HII_DATA_TABLE
*DataTable
;
377 BOOLEAN VariableExist
;
378 UINT16 NumberOfHiiDataTables
;
385 return EFI_INVALID_PARAMETER
;
388 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
390 HandleDatabase
= HiiData
->DatabaseHead
;
394 PackageInstance
= NULL
;
395 NumberOfHiiDataTables
= 0;
398 SizeNeeded
= sizeof (EFI_HII_EXPORT_TABLE
);
401 // How many total tables are there?
403 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
404 if ((Handle
!= 0) && (Handle
!= HandleDatabase
->Handle
)) {
408 VariableExist
= FALSE
;
409 NumberOfHiiDataTables
++;
410 PackageInstance
= HandleDatabase
->Buffer
;
411 if (PackageInstance
== NULL
) {
415 // Extract Size of Export Package
417 SizeNeeded
= SizeNeeded
+ PackageInstance
->IfrSize
418 + PackageInstance
->StringSize
419 + sizeof (EFI_HII_DATA_TABLE
)
420 + sizeof (EFI_HII_DEVICE_PATH_PACK
);
423 // BUGBUG We aren't inserting Device path data yet
425 SizeNeeded
= SizeNeeded
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
428 // Extract Size of Variable Data
430 if (PackageInstance
->IfrSize
> 0) {
431 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
434 // No IFR? No variable information
439 RawData
= (UINT8
*) FormPack
;
441 for (Index
= 0; RawData
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
442 switch (RawData
[Index
]) {
443 case EFI_IFR_FORM_SET_OP
:
444 CopyMem (&VariableSize
, &((EFI_IFR_FORM_SET
*) &RawData
[Index
])->NvDataSize
, sizeof (UINT16
));
445 SizeNeeded
= SizeNeeded
+ VariableSize
+ sizeof (SETUP_MAP_NAME
) + sizeof (EFI_HII_VARIABLE_PACK
);
446 VariableExist
= TRUE
;
449 case EFI_IFR_VARSTORE_OP
:
450 CopyMem (&VariableSize
, &((EFI_IFR_VARSTORE
*) &RawData
[Index
])->Size
, sizeof (UINT16
));
451 SizeNeeded
= SizeNeeded
+ VariableSize
+ sizeof (EFI_HII_VARIABLE_PACK
);
453 // We will be expanding the stored ASCII name to a Unicode string. This will cause some memory overhead
454 // Since the VARSTORE size already takes in consideration the ASCII size, we need to size it and add another
455 // instance of it. Essentially, 2 ASCII strings == 1 Unicode string in size.
457 TempValue
= (UINTN
) ((EFI_IFR_VARSTORE
*) &RawData
[Index
])->Header
.Length
- sizeof (EFI_IFR_VARSTORE
);
458 SizeNeeded
= SizeNeeded
+ TempValue
* 2;
459 VariableExist
= TRUE
;
463 Index
= RawData
[Index
+ 1] + Index
;
466 // If a variable exists for this handle, add an additional variable pack overhead to
467 // indicate that we will have an extra null Variable Pack to signify the end of the Variable Packs
470 SizeNeeded
= SizeNeeded
+ sizeof (EFI_HII_VARIABLE_PACK
);
474 if (SizeNeeded
> *BufferSize
) {
475 *BufferSize
= SizeNeeded
;
476 return EFI_BUFFER_TOO_SMALL
;
479 // Zero out the incoming buffer
481 ZeroMem (Buffer
, *BufferSize
);
484 // Cast the Buffer to EFI_HII_EXPORT_TABLE
486 ExportTable
= (EFI_HII_EXPORT_TABLE
*) Buffer
;
489 // Set the Revision for the Export Table
491 CopyMem (&ExportTable
->Revision
, &gEfiHiiProtocolGuid
, sizeof (EFI_GUID
));
493 ExportBuffer
= (UINT8
*) (UINTN
) (((UINT8
*) ExportTable
) + sizeof (EFI_HII_EXPORT_TABLE
));
494 HandleDatabase
= HiiData
->DatabaseHead
;
497 // Check numeric value against the head of the database
499 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
500 DataTable
= (EFI_HII_DATA_TABLE
*) ExportBuffer
;
501 PackageInstance
= HandleDatabase
->Buffer
;
503 // If not asking for a specific handle, export the entire database
506 ExportTable
->NumberOfHiiDataTables
= NumberOfHiiDataTables
;
507 CopyMem (&DataTable
->PackageGuid
, &PackageInstance
->Guid
, sizeof (EFI_GUID
));
508 DataTable
->HiiHandle
= PackageInstance
->Handle
;
509 DataTable
->DevicePathOffset
= (UINT32
) (sizeof (EFI_HII_DATA_TABLE
));
512 // Start Dumping DevicePath
514 ExtractDevicePathData (DataTable
, RawData
, &ExportBuffer
);
516 if (((UINTN
) ExportBuffer
) == ((UINTN
) DataTable
)) {
518 // If there is no DevicePath information - set offset to 0 to signify the absence of data to parse
520 DataTable
->DevicePathOffset
= 0;
523 DataTable
->VariableDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
525 if (PackageInstance
->IfrSize
> 0) {
526 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
528 RawData
= (UINT8
*) FormPack
;
532 // Start dumping the Variable Data
534 ExtractVariableData (DataTable
, RawData
, &ExportBuffer
);
535 DataTable
->IfrDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
537 if (DataTable
->VariableDataOffset
== DataTable
->IfrDataOffset
) {
538 DataTable
->VariableDataOffset
= 0;
541 // Start dumping the IFR data (Note: It is in an IFR PACK)
543 CopyMem (ExportBuffer
, &PackageInstance
->IfrData
, PackageInstance
->IfrSize
);
544 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + PackageInstance
->IfrSize
);
545 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
548 // Start dumping the String data (Note: It is in a String PACK)
550 if (PackageInstance
->StringSize
> 0) {
551 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
552 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
553 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
555 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
556 for (; TempValue
!= 0;) {
557 DataTable
->NumberOfLanguages
++;
558 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
559 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
562 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
564 DataTable
->StringDataOffset
= 0;
568 // 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)
570 DataTable
->VariableDataOffset
= 0;
571 DataTable
->IfrDataOffset
= 0;
572 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
575 // Start dumping the String data - NOTE: It is in String Pack form
577 if (PackageInstance
->StringSize
> 0) {
578 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
579 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
580 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
582 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
583 for (; TempValue
!= 0;) {
584 DataTable
->NumberOfLanguages
++;
585 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
586 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
589 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
591 DataTable
->StringDataOffset
= 0;
596 // Match the numeric value with the database entry - if matched, extract PackageInstance
598 if (Handle
== HandleDatabase
->Handle
) {
599 PackageInstance
= HandleDatabase
->Buffer
;
600 ExportTable
->NumberOfHiiDataTables
= NumberOfHiiDataTables
;
601 DataTable
->HiiHandle
= PackageInstance
->Handle
;
602 CopyMem (&DataTable
->PackageGuid
, &PackageInstance
->Guid
, sizeof (EFI_GUID
));
605 // Start Dumping DevicePath
607 ExtractDevicePathData (DataTable
, RawData
, &ExportBuffer
);
608 DataTable
->VariableDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
610 if (PackageInstance
->IfrSize
> 0) {
611 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
613 RawData
= (UINT8
*) FormPack
;
617 // Start dumping the Variable Data
619 ExtractVariableData (DataTable
, RawData
, &ExportBuffer
);
620 DataTable
->IfrDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
622 if (DataTable
->VariableDataOffset
== DataTable
->IfrDataOffset
) {
623 DataTable
->VariableDataOffset
= 0;
626 // Start dumping the IFR data
628 CopyMem (ExportBuffer
, &PackageInstance
->IfrData
, PackageInstance
->IfrSize
);
629 ExportBuffer
= (UINT8
*) (UINTN
) (((UINTN
) ExportBuffer
) + PackageInstance
->IfrSize
);
630 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
633 // Start dumping the String data - NOTE: It is in String Pack form
635 if (PackageInstance
->StringSize
> 0) {
636 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
637 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
638 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
640 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
641 for (; TempValue
!= 0;) {
642 DataTable
->NumberOfLanguages
++;
643 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
644 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
647 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
649 DataTable
->StringDataOffset
= 0;
653 // No IFR? No variable information. If Offset is 0, means there is none.
655 DataTable
->VariableDataOffset
= 0;
656 DataTable
->IfrDataOffset
= 0;
657 DataTable
->StringDataOffset
= (UINT32
) (((UINTN
) ExportBuffer
) - ((UINTN
) DataTable
));
660 // Start dumping the String data - Note: It is in String Pack form
662 if (PackageInstance
->StringSize
> 0) {
663 RawData
= (UINT8
*) (((UINTN
) &PackageInstance
->IfrData
) + PackageInstance
->IfrSize
);
664 CopyMem (ExportBuffer
, RawData
, PackageInstance
->StringSize
);
665 DataTable
->DataTableSize
= (UINT32
) (DataTable
->StringDataOffset
+ PackageInstance
->StringSize
);
667 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
668 for (; TempValue
!= 0;) {
669 DataTable
->NumberOfLanguages
++;
670 ExportBuffer
= ExportBuffer
+ ((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
;
671 CopyMem (&TempValue
, &((EFI_HII_STRING_PACK
*) ExportBuffer
)->Header
.Length
, sizeof (UINT32
));
674 ExportBuffer
= ExportBuffer
+ sizeof (EFI_HII_STRING_PACK
);
676 DataTable
->StringDataOffset
= 0;
690 IN EFI_HII_PROTOCOL
*This
,
691 IN EFI_HII_HANDLE Handle
,
692 IN EFI_FORM_ID FormId
,
693 IN OUT UINTN
*BufferLengthTemp
,
700 This function allows a program to extract a form or form package that has
701 previously been registered with the EFI HII database.
704 This - A pointer to the EFI_HII_PROTOCOL instance.
706 Handle - Handle on which the form resides. Type EFI_HII_HANDLE is defined in
707 EFI_HII_PROTOCOL.NewPack() in the Packages section.
709 FormId - The ID of the form to return. If the ID is zero, the entire form package is returned.
710 Type EFI_FORM_ID is defined in "Related Definitions" below.
712 BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if
713 the length was sufficient and, if it was not, the length that is required to fit the
716 Buffer - The buffer designed to receive the form(s).
720 EFI_SUCCESS - Buffer filled with the requested forms. BufferLength
723 EFI_INVALID_PARAMETER - The handle is unknown.
725 EFI_NOT_FOUND - A form on the requested handle cannot be found with the
728 EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.
732 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
733 EFI_HII_DATA
*HiiData
;
734 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
735 EFI_HII_IFR_PACK
*FormPack
;
737 EFI_IFR_OP_HEADER
*Location
;
738 UINT16
*BufferLength
= (UINT16
*) BufferLengthTemp
;
742 return EFI_INVALID_PARAMETER
;
745 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
747 HandleDatabase
= HiiData
->DatabaseHead
;
749 PackageInstance
= NULL
;
754 // Check numeric value against the head of the database
756 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
758 // Match the numeric value with the database entry - if matched, extract PackageInstance
760 if (Handle
== HandleDatabase
->Handle
) {
761 PackageInstance
= HandleDatabase
->Buffer
;
766 // No handle was found - error condition
768 if (PackageInstance
== NULL
) {
769 return EFI_NOT_FOUND
;
772 // Based on if there is IFR data in this package instance, determine
773 // what the location is of the beginning of the string data.
775 if (PackageInstance
->IfrSize
> 0) {
776 FormPack
= (EFI_HII_IFR_PACK
*) (&PackageInstance
->IfrData
);
779 // If there is no IFR data return an error
781 return EFI_NOT_FOUND
;
784 // If requesting the entire Form Package
788 // Return an error if buffer is too small
790 if (PackageInstance
->IfrSize
> *BufferLength
|| Buffer
== NULL
) {
791 *BufferLength
= (UINT16
) PackageInstance
->IfrSize
;
792 return EFI_BUFFER_TOO_SMALL
;
795 CopyMem (Buffer
, FormPack
, PackageInstance
->IfrSize
);
798 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
799 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
802 // Look for the FormId requested
804 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
805 switch (Location
->OpCode
) {
806 case EFI_IFR_FORM_OP
:
807 Form
= (EFI_IFR_FORM
*) Location
;
810 // If we found a Form Op-code and it is of the correct Id, copy it and return
812 if (Form
->FormId
== FormId
) {
814 // Calculate the total size of form
816 for (FormLength
= 0; Location
->OpCode
!= EFI_IFR_END_FORM_OP
; ) {
817 FormLength
+= Location
->Length
;
818 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
820 FormLength
+= Location
->Length
;
821 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
823 if ((Buffer
== NULL
) || (FormLength
> *BufferLength
)) {
824 *BufferLengthTemp
= FormLength
;
825 return EFI_BUFFER_TOO_SMALL
;
829 // Rewind to start offset of the found Form
831 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*)Location
- FormLength
);
832 CopyMem (Buffer
, Location
, FormLength
);
840 // Go to the next Op-Code
842 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
846 return EFI_NOT_FOUND
;
850 // Helper functions to HiiGetDefaultImage()
855 HiiGetDefaultImageInitPack (
856 IN OUT EFI_HII_VARIABLE_PACK_LIST
*VariablePackItem
,
857 IN EFI_IFR_VARSTORE
*VarStore
863 Initialize the EFI_HII_VARIABLE_PACK_LIST structure and
864 prepare it ready to be used by HiiGetDefaultImagePopulateMap ().
868 VariablePackItem - Variable Package List.
869 VarStore - IFR variable storage.
873 Return the pointer to the Map space.
880 EFI_HII_VARIABLE_PACK
*VariablePack
;
883 // Set pointer the pack right after the node
885 VariablePackItem
->VariablePack
= (EFI_HII_VARIABLE_PACK
*) (VariablePackItem
+ 1);
886 VariablePack
= VariablePackItem
->VariablePack
;
889 // Copy the var name to VariablePackItem from VarStore
890 // Needs ASCII->Unicode conversion.
892 ASSERT (VarStore
->Header
.Length
> sizeof (*VarStore
));
893 Name8
= (CHAR8
*) (VarStore
+ 1);
894 Name16
= (CHAR16
*) (VariablePack
+ 1);
895 Ascii2Unicode (Name16
, Name8
);
898 // Compute the other fields of the VariablePackItem
900 VariablePack
->VariableId
= VarStore
->VarId
;
901 CopyMem (&VariablePack
->VariableGuid
, &VarStore
->Guid
, sizeof (EFI_GUID
));
902 VariablePack
->VariableNameLength
= (UINT32
) ((StrLen (Name16
) + 1) * 2);
903 VariablePack
->Header
.Length
= sizeof (*VariablePack
)
904 + VariablePack
->VariableNameLength
907 // Return the pointer to the Map space.
909 Map
= (CHAR8
*) Name16
+ VariablePack
->VariableNameLength
;
916 HiiGetDefaultImagePopulateMap (
918 IN EFI_IFR_OP_HEADER
*FormSet
,
919 IN EFI_IFR_VARSTORE
*VarStore
,
926 Fill the Map with all the default values either from NV or Hii database.
930 Map - Memory pointer to hold the default values.
931 FormSet - The starting EFI_IFR_OP_HEADER to begin retriving default values.
932 VarStore - IFR variable storage.
933 DefaultMask - The mask used to get the default variable.
942 EFI_IFR_OP_HEADER
*IfrItem
;
944 EFI_IFR_VARSTORE_SELECT
*VarSelect
;
945 EFI_IFR_ONE_OF_OPTION
*OneOfOpt
;
946 EFI_IFR_CHECKBOX
*CheckBox
;
947 EFI_IFR_NUMERIC
*Numeric
;
950 EFI_IFR_NV_DATA
*IfrNvData
;
954 EFI_HANDLE CallbackHandle
;
955 EFI_FORM_CALLBACK_PROTOCOL
*FormCallbackProt
;
958 // Get the Map's Name/Guid/Szie from the Varstore.
959 // VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.
961 ASSERT (VarStore
->Header
.Length
>= sizeof (*VarStore
));
962 Name8
= (CHAR8
*) (VarStore
+ 1);
963 Name16
= AllocateZeroPool ((VarStore
->Header
.Length
- sizeof (*VarStore
)) * sizeof (CHAR16
));
964 Ascii2Unicode (Name16
, Name8
);
965 CopyMem (&Guid
, &VarStore
->Guid
, sizeof(EFI_GUID
));
966 Size
= VarStore
->Size
;
969 // First, check if the map exists in the NV. If so, get it from NV and exit.
971 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
973 // Check if Manufaturing Defaults exist in the NV.
975 Status
= EfiLibHiiVariableOverrideBySuffix (
976 HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE
,
984 // All other cases default to Defaults. Check if Defaults exist in the NV.
986 Status
= EfiLibHiiVariableOverrideBySuffix (
987 HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE
,
994 if (!EFI_ERROR (Status
)) {
996 // Either Defaults/Manufacturing variable exists and appears to be valid.
997 // The map is read, exit w/ success now.
1004 // First, prime the map with what already is in the NV.
1005 // This is needed to cover a situation where the IFR does not contain all the
1006 // defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.
1007 // Ignore status. Either it gets read or not.
1009 FormCallbackProt
= NULL
;
1010 CopyMem (&CallbackHandle
, &((EFI_IFR_FORM_SET
*) FormSet
)->CallbackHandle
, sizeof (CallbackHandle
));
1011 if (CallbackHandle
!= NULL
) {
1012 Status
= gBS
->HandleProtocol (
1013 (EFI_HANDLE
) (UINTN
) CallbackHandle
,
1014 &gEfiFormCallbackProtocolGuid
,
1015 (VOID
*) &FormCallbackProt
1018 if ((NULL
!= FormCallbackProt
) && (NULL
!= FormCallbackProt
->NvRead
)) {
1020 // Attempt to read using NvRead() callback. Probe first for existence and correct variable size.
1023 Status
= FormCallbackProt
->NvRead (
1031 if ((EFI_BUFFER_TOO_SMALL
== Status
) && (SizeTmp
== Size
)) {
1032 Status
= FormCallbackProt
->NvRead (
1040 ASSERT_EFI_ERROR (Status
);
1041 ASSERT (SizeTmp
== Size
);
1045 // No callback available for this formset, read straight from NV. Deliberately ignore the Status.
1046 // The buffer will only be written if variable exists nd has correct size.
1048 Status
= EfiLibHiiVariableRetrieveFromNv (
1057 // Iterate all IFR statements and for applicable, retrieve the default into the Map.
1059 for (IfrItem
= FormSet
, VarId
= 0;
1060 IfrItem
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;
1061 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
)
1065 // Observe VarStore switch.
1067 if (EFI_IFR_VARSTORE_SELECT_OP
== IfrItem
->OpCode
) {
1068 VarSelect
= (EFI_IFR_VARSTORE_SELECT
*) IfrItem
;
1069 VarId
= VarSelect
->VarId
;
1075 // Skip opcodes that reference other VarStore than that specific to current map.
1077 if (VarId
!= VarStore
->VarId
) {
1082 // Extract the default value from this opcode if applicable, and apply it to the map.
1084 IfrNvData
= (EFI_IFR_NV_DATA
*) IfrItem
;
1085 switch (IfrItem
->OpCode
) {
1087 case EFI_IFR_ONE_OF_OP
:
1088 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1090 // Get to the first EFI_IFR_ONE_OF_OPTION_OP
1092 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1093 ASSERT (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
);
1095 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1097 // In the worst case, the first will be the default.
1099 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1101 while (EFI_IFR_ONE_OF_OPTION_OP
== IfrItem
->OpCode
) {
1103 OneOfOpt
= (EFI_IFR_ONE_OF_OPTION
*)IfrItem
;
1104 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1105 if (0 != (OneOfOpt
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1107 // In the worst case, the first will be the default.
1109 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1113 if (OneOfOpt
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1115 // In the worst case, the first will be the default.
1117 CopyMem (Map
+ IfrNvData
->QuestionId
, &OneOfOpt
->Value
, IfrNvData
->StorageWidth
);
1122 IfrItem
= (EFI_IFR_OP_HEADER
*)((UINT8
*)IfrItem
+ IfrItem
->Length
);
1127 case EFI_IFR_CHECKBOX_OP
:
1128 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1129 CheckBox
= (EFI_IFR_CHECK_BOX
*)IfrItem
;
1130 if (DefaultMask
== EFI_IFR_FLAG_MANUFACTURING
) {
1131 if (0 != (CheckBox
->Flags
& EFI_IFR_FLAG_MANUFACTURING
)) {
1132 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1135 if (CheckBox
->Flags
& EFI_IFR_FLAG_DEFAULT
) {
1136 *(UINT8
*) (Map
+ IfrNvData
->QuestionId
) = TRUE
;
1141 case EFI_IFR_NUMERIC_OP
:
1142 ASSERT (IfrNvData
->QuestionId
+ IfrNvData
->StorageWidth
<= VarStore
->Size
);
1143 Numeric
= (EFI_IFR_NUMERIC
*) IfrItem
;
1144 CopyMem (Map
+ IfrNvData
->QuestionId
, &Numeric
->Default
, IfrNvData
->StorageWidth
);
1147 case EFI_IFR_ORDERED_LIST_OP
:
1148 case EFI_IFR_PASSWORD_OP
:
1149 case EFI_IFR_STRING_OP
:
1151 // No support for default value for these opcodes.
1164 HiiGetDefaultImage (
1165 IN EFI_HII_PROTOCOL
*This
,
1166 IN EFI_HII_HANDLE Handle
,
1167 IN UINTN DefaultMask
,
1168 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
1172 Routine Description:
1174 This function allows a program to extract the NV Image
1175 that represents the default storage image
1178 This - A pointer to the EFI_HII_PROTOCOL instance.
1179 Handle - The HII handle from which will have default data retrieved.
1180 UINTN - Mask used to retrieve the default image.
1181 VariablePackList - Callee allocated, tightly-packed, link list data
1182 structure that contain all default varaible packs
1183 from the Hii Database.
1186 EFI_NOT_FOUND - If Hii database does not contain any default images.
1187 EFI_INVALID_PARAMETER - Invalid input parameter.
1188 EFI_SUCCESS - Operation successful.
1192 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1193 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1194 EFI_IFR_OP_HEADER
*FormSet
;
1195 EFI_IFR_OP_HEADER
*IfrItem
;
1196 EFI_IFR_VARSTORE
*VarStore
;
1197 EFI_IFR_VARSTORE
*VarStoreDefault
;
1198 UINTN SetupMapNameSize
;
1200 EFI_HII_VARIABLE_PACK_LIST
*PackList
;
1201 EFI_HII_VARIABLE_PACK_LIST
*PackListNext
;
1202 EFI_HII_VARIABLE_PACK_LIST
*PackListLast
;
1207 // Find the IFR pack from the handle. Then get the formset from the pack.
1209 PackageInstance
= NULL
;
1210 HandleDatabase
= (EFI_HII_DATA_FROM_THIS (This
))->DatabaseHead
;
1211 for ( ; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1212 if (Handle
== HandleDatabase
->Handle
) {
1213 PackageInstance
= HandleDatabase
->Buffer
;
1217 if (PackageInstance
== NULL
) {
1218 return EFI_INVALID_PARAMETER
;
1220 FormSet
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) &PackageInstance
->IfrData
+ sizeof (EFI_HII_IFR_PACK
));
1223 // Get the sizes of all the VARSTOREs in this VFR.
1224 // Then allocate enough space for all of them plus all maps
1228 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1230 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1231 VarStore
= (EFI_IFR_VARSTORE
*) IfrItem
;
1235 SizeOfMaps
+= VarStore
->Size
;
1237 // add the size of the string, in Unicode
1239 SizeOfMaps
+= (VarStore
->Header
.Length
- sizeof (*VarStore
)) * 2;
1243 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1245 // Space for linked list node
1247 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1250 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1254 // If the FormSet OpCode has a non-zero NvDataSize. There is a default
1255 // NvMap with ID=0, GUID that of the formset itself and "Setup" as name.
1257 SetupMapNameSize
= StrLen (SETUP_MAP_NAME
) + 1;
1258 VarStoreDefault
= AllocateZeroPool (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1260 if (0 != ((EFI_IFR_FORM_SET
*)FormSet
)->NvDataSize
) {
1262 VarStoreDefault
->Header
.OpCode
= EFI_IFR_VARSTORE_OP
;
1263 VarStoreDefault
->Header
.Length
= (UINT8
) (sizeof (*VarStoreDefault
) + SetupMapNameSize
);
1264 Unicode2Ascii ((CHAR8
*) (VarStoreDefault
+ 1), SETUP_MAP_NAME
);
1265 CopyMem (&VarStoreDefault
->Guid
, &((EFI_IFR_FORM_SET
*) FormSet
)->Guid
, sizeof (EFI_GUID
));
1266 VarStoreDefault
->VarId
= 0;
1267 VarStoreDefault
->Size
= ((EFI_IFR_FORM_SET
*) FormSet
)->NvDataSize
;
1272 SizeOfMaps
+= VarStoreDefault
->Size
;
1274 // add the size of the string
1276 SizeOfMaps
+= sizeof (SETUP_MAP_NAME
);
1280 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK
);
1282 // Space for linked list node
1284 SizeOfMaps
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
1287 if (0 == SizeOfMaps
) {
1289 // The IFR does not have any explicit or default map(s).
1291 return EFI_NOT_FOUND
;
1295 // Allocate the return buffer
1297 PackList
= AllocateZeroPool (SizeOfMaps
);
1298 ASSERT (NULL
!= PackList
);
1300 PackListNext
= PackList
;
1301 PackListLast
= PackList
;
1304 // Handle the default map first, if any.
1306 if (0 != VarStoreDefault
->Size
) {
1308 Map
= HiiGetDefaultImageInitPack (PackListNext
, VarStoreDefault
);
1310 HiiGetDefaultImagePopulateMap (Map
, FormSet
, VarStoreDefault
, DefaultMask
);
1312 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1313 PackListLast
= PackListNext
;
1314 PackListNext
= PackListNext
->NextVariablePack
;
1319 // Handle the explicit varstore(s)
1322 while (EFI_IFR_END_FORM_SET_OP
!= IfrItem
->OpCode
) {
1324 if (EFI_IFR_VARSTORE_OP
== IfrItem
->OpCode
) {
1326 Map
= HiiGetDefaultImageInitPack (PackListNext
, (EFI_IFR_VARSTORE
*) IfrItem
);
1328 HiiGetDefaultImagePopulateMap (Map
, FormSet
, (EFI_IFR_VARSTORE
*) IfrItem
, DefaultMask
);
1330 PackListNext
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*) ((UINT8
*) PackListNext
->VariablePack
+ PackListNext
->VariablePack
->Header
.Length
);
1331 PackListLast
= PackListNext
;
1332 PackListNext
= PackListNext
->NextVariablePack
;
1335 IfrItem
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrItem
+ IfrItem
->Length
);
1338 PackListLast
->NextVariablePack
= NULL
;
1339 *VariablePackList
= PackList
;
1348 IN EFI_HII_PROTOCOL
*This
,
1349 IN EFI_HII_HANDLE Handle
,
1350 IN EFI_FORM_LABEL Label
,
1352 IN EFI_HII_UPDATE_DATA
*Data
1356 Routine Description:
1357 This function allows the caller to update a form that has
1358 previously been registered with the EFI HII database.
1361 Handle - Hii Handle associated with the Formset to modify
1362 Label - Update information starting immediately after this label in the IFR
1363 AddData - If TRUE, add data. If FALSE, remove data
1364 Data - If adding data, this is the pointer to the data to add
1367 EFI_SUCCESS - Update success.
1368 Other - Update fail.
1372 EFI_HII_PACKAGE_INSTANCE
*PackageInstance
;
1373 EFI_HII_DATA
*HiiData
;
1374 EFI_HII_HANDLE_DATABASE
*HandleDatabase
;
1375 EFI_HII_IFR_PACK
*FormPack
;
1376 EFI_IFR_OP_HEADER
*Location
;
1377 EFI_IFR_OP_HEADER
*DataLocation
;
1380 UINT8
*OrigTempBuffer
;
1381 UINTN TempBufferSize
;
1387 return EFI_INVALID_PARAMETER
;
1390 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
1392 HandleDatabase
= HiiData
->DatabaseHead
;
1394 PackageInstance
= NULL
;
1397 // Check numeric value against the head of the database
1399 for (; HandleDatabase
!= NULL
; HandleDatabase
= HandleDatabase
->NextHandleDatabase
) {
1401 // Match the numeric value with the database entry - if matched, extract PackageInstance
1403 if (Handle
== HandleDatabase
->Handle
) {
1404 PackageInstance
= HandleDatabase
->Buffer
;
1409 // No handle was found - error condition
1411 if (PackageInstance
== NULL
) {
1412 return EFI_INVALID_PARAMETER
;
1415 // Calculate and allocate space for retrieval of IFR data
1417 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1418 TempBufferSize
= (CHAR8
*) (&PackageInstance
->IfrData
) - (CHAR8
*) (PackageInstance
);
1420 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1421 TempBufferSize
+= DataLocation
->Length
;
1422 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1425 TempBufferSize
+= PackageInstance
->IfrSize
+ PackageInstance
->StringSize
;
1427 TempBuffer
= AllocateZeroPool (TempBufferSize
);
1428 ASSERT (TempBuffer
!= NULL
);
1430 OrigTempBuffer
= TempBuffer
;
1433 // We update only packages with IFR information in it
1435 if (PackageInstance
->IfrSize
== 0) {
1436 return EFI_INVALID_PARAMETER
;
1442 ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
))
1445 TempBuffer
= TempBuffer
+ ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
) - (CHAR8
*) (PackageInstance
));
1448 // Based on if there is IFR data in this package instance, determine
1449 // what the location is of the beginning of the string data.
1451 FormPack
= (EFI_HII_IFR_PACK
*) ((CHAR8
*) (&PackageInstance
->IfrData
) + sizeof (EFI_HII_PACK_HEADER
));
1452 Location
= (EFI_IFR_OP_HEADER
*) FormPack
;
1455 // Look for the FormId requested
1457 for (; Location
->OpCode
!= EFI_IFR_END_FORM_SET_OP
;) {
1458 switch (Location
->OpCode
) {
1459 case EFI_IFR_FORM_SET_OP
:
1461 // If the FormSet has an update pending, pay attention.
1463 if (Data
->FormSetUpdate
) {
1464 ((EFI_IFR_FORM_SET
*) Location
)->CallbackHandle
= Data
->FormCallbackHandle
;
1467 CopyMem (TempBuffer
, Location
, Location
->Length
);
1468 TempBuffer
= TempBuffer
+ Location
->Length
;
1471 case EFI_IFR_FORM_OP
:
1473 // If the Form has an update pending, pay attention.
1475 if (Data
->FormUpdate
) {
1476 ((EFI_IFR_FORM
*) Location
)->FormTitle
= Data
->FormTitle
;
1479 CopyMem (TempBuffer
, Location
, Location
->Length
);
1480 TempBuffer
= TempBuffer
+ Location
->Length
;
1483 case EFI_IFR_LABEL_OP
:
1485 // If the label does not match the requested update point, ignore it
1487 if (((EFI_IFR_LABEL
*) Location
)->LabelId
!= Label
) {
1491 CopyMem (TempBuffer
, Location
, Location
->Length
);
1492 TempBuffer
= TempBuffer
+ Location
->Length
;
1495 // Go to the next Op-Code
1497 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1505 CopyMem (TempBuffer
, Location
, Location
->Length
);
1506 TempBuffer
= TempBuffer
+ Location
->Length
;
1509 // Add the DataCount amount of opcodes to TempBuffer
1511 DataLocation
= (EFI_IFR_OP_HEADER
*) &Data
->Data
;
1512 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1513 CopyMem (TempBuffer
, DataLocation
, DataLocation
->Length
);
1514 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
+= DataLocation
->Length
;
1515 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1516 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1517 TempBuffer
= TempBuffer
+ DataLocation
->Length
;
1518 DataLocation
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (DataLocation
) + DataLocation
->Length
);
1521 // Go to the next Op-Code
1523 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1529 CopyMem (TempBuffer
, Location
, Location
->Length
);
1530 TempBuffer
= TempBuffer
+ Location
->Length
;
1531 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1534 // Remove the DataCount amount of opcodes unless we run into an end of form or a label
1536 for (Index
= 0; Index
< Data
->DataCount
; Index
++) {
1538 // If we are about to skip an end form - bail out, since that is illegal
1540 if ((Location
->OpCode
== EFI_IFR_END_FORM_OP
) || (Location
->OpCode
== EFI_IFR_LABEL_OP
)) {
1544 // By skipping Location entries, we are in effect not copying what was previously there
1546 ((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
-= Location
->Length
;
1547 OtherBuffer
= ((UINT8
*) &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->StringSize
+ sizeof (UINTN
));
1548 CopyMem (OtherBuffer
, &((EFI_HII_PACKAGE_INSTANCE
*) OrigTempBuffer
)->IfrSize
, 2);
1549 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1554 CopyMem (TempBuffer
, Location
, Location
->Length
);
1555 TempBuffer
= TempBuffer
+ Location
->Length
;
1559 // Go to the next Op-Code
1561 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1564 // Copy the last op-code left behind from the for loop
1566 CopyMem (TempBuffer
, Location
, Location
->Length
);
1569 // Advance to beginning of strings and copy them
1571 TempBuffer
= TempBuffer
+ Location
->Length
;
1572 Location
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (Location
) + Location
->Length
);
1573 CopyMem (TempBuffer
, Location
, PackageInstance
->StringSize
);
1576 // Free the old buffer, and assign into our database the latest buffer
1578 FreePool (HandleDatabase
->Buffer
);
1579 HandleDatabase
->Buffer
= OrigTempBuffer
;