2006-04-22 00:54:32 +02:00
/*++
Copyright ( c ) 2006 , Intel Corporation
All rights reserved . This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution . The full text of the license may be found at
http : //opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN " AS IS " BASIS ,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND , EITHER EXPRESS OR IMPLIED .
Module Name :
Forms . c
Abstract :
This file contains the form processing code to the HII database .
- - */
# include "HiiDatabase.h"
CHAR16 *
Ascii2Unicode (
OUT CHAR16 * UnicodeStr ,
IN CHAR8 * AsciiStr
)
/*++
Routine Description :
This function converts ASCII string to Unicode string .
Arguments :
UnicodeStr - NULL terminated Unicode output string .
AsciieStr - NULL terminated ASCII input string .
Returns :
Start of the Unicode ouput string .
- - */
{
CHAR16 * Str = UnicodeStr ;
while ( TRUE ) {
* ( UnicodeStr + + ) = ( CHAR16 ) * AsciiStr ;
if ( * ( AsciiStr + + ) = = ' \0 ' ) {
return Str ;
}
}
}
CHAR8 *
Unicode2Ascii (
OUT CHAR8 * AsciiStr ,
IN CHAR16 * UnicodeStr
)
/*++
Routine Description :
This function converts Unicode string to ASCII string .
Arguments :
AsciieStr - NULL terminated ASCII output string .
UnicodeStr - NULL terminated Unicode input string .
Returns :
Start of the ASCII ouput string .
- - */
{
CHAR8 * Str = AsciiStr ;
while ( TRUE ) {
* ( AsciiStr + + ) = ( CHAR8 ) * UnicodeStr ;
if ( * ( UnicodeStr + + ) = = ' \0 ' ) {
return Str ;
}
}
}
VOID
ExtractDevicePathData (
IN EFI_HII_DATA_TABLE * DataTable ,
IN UINT8 * IfrData ,
IN OUT UINT8 * * ExportBufferPtr
)
/*++
Routine Description :
Arguments :
Returns :
- - */
{
UINT8 * ExportBuffer ;
ExportBuffer = * ExportBufferPtr ;
//
// BUGBUG - don't have devicepath data yet, setting dummy value
//
DataTable + + ;
ExportBuffer = ( UINT8 * ) DataTable ;
( ( EFI_HII_DEVICE_PATH_PACK * ) ExportBuffer ) - > Header . Type = EFI_HII_DEVICE_PATH ;
( ( EFI_HII_DEVICE_PATH_PACK * ) ExportBuffer ) - > Header . Length = ( UINT32 ) ( sizeof ( EFI_HII_DEVICE_PATH_PACK ) + sizeof ( EFI_DEVICE_PATH_PROTOCOL ) ) ;
//
// BUGBUG - part of hack - skip the Device Path Pack.....place some data
//
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_DEVICE_PATH_PACK ) ;
( ( EFI_DEVICE_PATH_PROTOCOL * ) ExportBuffer ) - > Type = EFI_END_ENTIRE_DEVICE_PATH ;
( ( EFI_DEVICE_PATH_PROTOCOL * ) ExportBuffer ) - > SubType = EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE ;
//
// BUGBUG - still part of hack....
//
ExportBuffer = ExportBuffer + sizeof ( EFI_DEVICE_PATH_PROTOCOL ) ;
* ExportBufferPtr = ExportBuffer ;
}
VOID
ExtractVariableData (
IN OUT EFI_HII_DATA_TABLE * DataTable ,
IN UINT8 * IfrData ,
IN OUT UINT8 * * ExportBufferPtr
)
/*++
Routine Description :
This function extract the EFI_HII_VARIABLE_PACK portion from the
each of the EFI_HII_PACKAGE_INSTANCE in HII handle database .
Arguments :
2006-11-03 03:47:43 +01:00
DataTable - On input , this parameter point to the EFI_HII_DATA_TABLE structure
2006-04-22 00:54:32 +02:00
of the final data buffer for the EFI_HII_EXPORT interface . This function
update the NumberOfVariableData attribute .
IfrData - It points to a staring address of a EFI_HII_IFR_PACK structure .
2006-11-03 03:47:43 +01:00
ExportBufferPtr - On input , it points the starting address of the data buffer to
2006-04-22 00:54:32 +02:00
host the variable pack . On output , it is the starting address
of data buffer for the next extraction operation .
Returns :
VOID
- - */
{
EFI_HII_VARIABLE_PACK * VariableContents ;
UINT8 * ExportBuffer ;
UINTN Index ;
UINTN Index2 ;
UINTN TempValue ;
UINTN TempValue2 ;
EFI_FORM_CALLBACK_PROTOCOL * FormCallback ;
EFI_PHYSICAL_ADDRESS CallbackHandle ;
EFI_STATUS Status ;
CHAR16 * String ;
FormCallback = NULL ;
CallbackHandle = 0 ;
ExportBuffer = * ExportBufferPtr ;
for ( Index = 0 ; IfrData [ Index ] ! = EFI_IFR_END_FORM_SET_OP ; ) {
VariableContents = ( EFI_HII_VARIABLE_PACK * ) ExportBuffer ;
switch ( IfrData [ Index ] ) {
case EFI_IFR_FORM_SET_OP :
TempValue = EFI_HII_VARIABLE ;
CopyMem ( & VariableContents - > Header . Type , & TempValue , sizeof ( UINT16 ) ) ;
CopyMem ( & TempValue , & ( ( EFI_IFR_FORM_SET * ) & IfrData [ Index ] ) - > NvDataSize , sizeof ( UINT16 ) ) ;
//
// If the variable has 0 size, do not process it
//
if ( TempValue = = 0 ) {
break ;
}
//
// Add the size of the variable pack overhead. Later, will also add the size of the
// name of the variable.
//
TempValue = TempValue + sizeof ( EFI_HII_VARIABLE_PACK ) ;
CopyMem ( & VariableContents - > Header . Length , & TempValue , sizeof ( UINT32 ) ) ;
CopyMem (
& CallbackHandle ,
& ( ( EFI_IFR_FORM_SET * ) & IfrData [ Index ] ) - > CallbackHandle ,
sizeof ( EFI_PHYSICAL_ADDRESS )
) ;
if ( CallbackHandle ! = 0 ) {
Status = gBS - > HandleProtocol (
( EFI_HANDLE ) ( UINTN ) CallbackHandle ,
& gEfiFormCallbackProtocolGuid ,
( VOID * ) & FormCallback
) ;
}
//
// Since we have a "Setup" variable that wasn't specified by a variable op-code
// it will have a VariableId of 0. All other variable op-codes will have a designation
// of VariableId 1+
//
TempValue = 0 ;
CopyMem ( & VariableContents - > VariableId , & TempValue , sizeof ( UINT16 ) ) ;
CopyMem ( & VariableContents - > VariableGuid , & ( ( EFI_IFR_FORM_SET * ) & IfrData [ Index ] ) - > Guid , sizeof ( EFI_GUID ) ) ;
TempValue = sizeof ( SETUP_MAP_NAME ) ;
CopyMem ( & VariableContents - > VariableNameLength , & TempValue , sizeof ( UINT32 ) ) ;
//
// Add the size of the name to the Header Length
//
TempValue2 = 0 ;
CopyMem ( & TempValue2 , & VariableContents - > Header . Length , sizeof ( UINT32 ) ) ;
TempValue2 = TempValue + TempValue2 ;
CopyMem ( & VariableContents - > Header . Length , & TempValue2 , sizeof ( UINT32 ) ) ;
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_VARIABLE_PACK ) ;
CopyMem ( ExportBuffer , SETUP_MAP_NAME , sizeof ( SETUP_MAP_NAME ) ) ;
ExportBuffer = ExportBuffer + sizeof ( SETUP_MAP_NAME ) ;
CopyMem ( & TempValue , & ( ( EFI_IFR_FORM_SET * ) & IfrData [ Index ] ) - > NvDataSize , sizeof ( UINT16 ) ) ;
if ( ( FormCallback ! = NULL ) & & ( FormCallback - > NvRead ! = NULL ) ) {
Status = FormCallback - > NvRead (
FormCallback ,
( CHAR16 * ) SETUP_MAP_NAME ,
( EFI_GUID * ) ( UINTN ) & VariableContents - > VariableGuid ,
NULL ,
& TempValue ,
ExportBuffer
) ;
} else {
Status = gRT - > GetVariable (
( CHAR16 * ) SETUP_MAP_NAME ,
( EFI_GUID * ) ( UINTN ) & VariableContents - > VariableGuid ,
NULL ,
& TempValue ,
ExportBuffer
) ;
}
ExportBuffer = ( UINT8 * ) ( UINTN ) ( ( ( UINTN ) ExportBuffer ) + TempValue ) ;
DataTable - > NumberOfVariableData + + ;
break ;
case EFI_IFR_VARSTORE_OP :
TempValue = EFI_HII_VARIABLE ;
CopyMem ( & VariableContents - > Header . Type , & TempValue , sizeof ( UINT16 ) ) ;
CopyMem ( & TempValue , & ( ( EFI_IFR_VARSTORE * ) & IfrData [ Index ] ) - > Size , sizeof ( UINT16 ) ) ;
//
// If the variable has 0 size, do not process it
//
if ( TempValue = = 0 ) {
break ;
}
//
// Add the size of the variable pack overhead. Later, will also add the size of the
// name of the variable.
//
TempValue = TempValue + sizeof ( EFI_HII_VARIABLE_PACK ) ;
CopyMem ( & VariableContents - > Header . Length , & TempValue , sizeof ( UINT32 ) ) ;
CopyMem ( & VariableContents - > VariableId , & ( ( EFI_IFR_VARSTORE * ) & IfrData [ Index ] ) - > VarId , sizeof ( UINT16 ) ) ;
CopyMem ( & VariableContents - > VariableGuid , & ( ( EFI_IFR_VARSTORE * ) & IfrData [ Index ] ) - > Guid , sizeof ( EFI_GUID ) ) ;
TempValue = ( UINTN ) ( ( EFI_IFR_VARSTORE * ) & IfrData [ Index ] ) - > Header . Length - sizeof ( EFI_IFR_VARSTORE ) ;
TempValue = TempValue * 2 ;
CopyMem ( & VariableContents - > VariableNameLength , & TempValue , sizeof ( UINT32 ) ) ;
//
// Add the size of the name to the Header Length
//
TempValue2 = 0 ;
CopyMem ( & TempValue2 , & VariableContents - > Header . Length , sizeof ( UINT32 ) ) ;
TempValue2 = TempValue + TempValue2 ;
CopyMem ( & VariableContents - > Header . Length , & TempValue2 , sizeof ( UINT32 ) ) ;
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_VARIABLE_PACK ) ;
String = ( CHAR16 * ) ExportBuffer ;
for ( Index2 = 0 ; Index2 < TempValue / 2 ; Index2 + + ) {
ExportBuffer [ Index2 * 2 ] = IfrData [ Index + sizeof ( EFI_IFR_VARSTORE ) + Index2 ] ;
ExportBuffer [ Index2 * 2 + 1 ] = 0 ;
}
ExportBuffer = ExportBuffer + TempValue ;
CopyMem ( & TempValue , & ( ( EFI_IFR_VARSTORE * ) & IfrData [ Index ] ) - > Size , sizeof ( UINT16 ) ) ;
if ( ( FormCallback ! = NULL ) & & ( FormCallback - > NvRead ! = NULL ) ) {
Status = FormCallback - > NvRead (
FormCallback ,
String ,
( EFI_GUID * ) ( UINTN ) & VariableContents - > VariableGuid ,
NULL ,
& TempValue ,
ExportBuffer
) ;
} else {
Status = gRT - > GetVariable (
String ,
( EFI_GUID * ) ( UINTN ) & VariableContents - > VariableGuid ,
NULL ,
& TempValue ,
ExportBuffer
) ;
}
ExportBuffer = ( UINT8 * ) ( UINTN ) ( ( ( UINTN ) ExportBuffer ) + TempValue ) ;
DataTable - > NumberOfVariableData + + ;
break ;
}
Index = IfrData [ Index + 1 ] + Index ;
}
//
// If we have added a variable pack, add a dummy empty one to signify the end
//
if ( ExportBuffer ! = * ExportBufferPtr ) {
VariableContents = ( EFI_HII_VARIABLE_PACK * ) ExportBuffer ;
TempValue = EFI_HII_VARIABLE ;
CopyMem ( & VariableContents - > Header . Type , & TempValue , sizeof ( UINT16 ) ) ;
TempValue = sizeof ( EFI_HII_VARIABLE_PACK ) ;
CopyMem ( & VariableContents - > Header . Length , & TempValue , sizeof ( UINT32 ) ) ;
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_VARIABLE_PACK ) ;
}
* ExportBufferPtr = ExportBuffer ;
}
EFI_STATUS
EFIAPI
HiiExportDatabase (
IN EFI_HII_PROTOCOL * This ,
IN EFI_HII_HANDLE Handle ,
IN OUT UINTN * BufferSize ,
OUT VOID * Buffer
)
/*++
Routine Description :
This function allows a program to extract a form or form package that has
previously been registered with the EFI HII database .
Arguments :
Returns :
- - */
{
EFI_HII_PACKAGE_INSTANCE * PackageInstance ;
EFI_HII_DATA * HiiData ;
EFI_HII_HANDLE_DATABASE * HandleDatabase ;
EFI_HII_IFR_PACK * FormPack ;
UINT8 * RawData ;
UINT8 * ExportBuffer ;
EFI_HII_EXPORT_TABLE * ExportTable ;
EFI_HII_DATA_TABLE * DataTable ;
BOOLEAN InsufficientSize ;
BOOLEAN VariableExist ;
UINT16 NumberOfHiiDataTables ;
UINTN SizeNeeded ;
UINTN Index ;
UINTN VariableSize ;
UINTN TempValue ;
if ( This = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
HiiData = EFI_HII_DATA_FROM_THIS ( This ) ;
HandleDatabase = HiiData - > DatabaseHead ;
FormPack = NULL ;
RawData = NULL ;
PackageInstance = NULL ;
InsufficientSize = FALSE ;
NumberOfHiiDataTables = 0 ;
VariableSize = 0 ;
TempValue = 0 ;
SizeNeeded = sizeof ( EFI_HII_EXPORT_TABLE ) ;
//
// How many total tables are there?
//
for ( ; HandleDatabase ! = NULL ; HandleDatabase = HandleDatabase - > NextHandleDatabase ) {
if ( ( Handle ! = 0 ) & & ( Handle ! = HandleDatabase - > Handle ) ) {
continue ;
}
VariableExist = FALSE ;
NumberOfHiiDataTables + + ;
PackageInstance = HandleDatabase - > Buffer ;
if ( PackageInstance = = NULL ) {
continue ;
}
//
// Extract Size of Export Package
//
SizeNeeded = SizeNeeded + PackageInstance - > IfrSize
+ PackageInstance - > StringSize
+ sizeof ( EFI_HII_DATA_TABLE )
+ sizeof ( EFI_HII_DEVICE_PATH_PACK ) ;
//
// BUGBUG We aren't inserting Device path data yet
//
SizeNeeded = SizeNeeded + sizeof ( EFI_DEVICE_PATH_PROTOCOL ) ;
//
// Extract Size of Variable Data
//
if ( PackageInstance - > IfrSize > 0 ) {
FormPack = ( EFI_HII_IFR_PACK * ) ( ( CHAR8 * ) ( & PackageInstance - > IfrData ) + sizeof ( EFI_HII_PACK_HEADER ) ) ;
} else {
//
// No IFR? No variable information
//
continue ;
}
RawData = ( UINT8 * ) FormPack ;
for ( Index = 0 ; RawData [ Index ] ! = EFI_IFR_END_FORM_SET_OP ; ) {
switch ( RawData [ Index ] ) {
case EFI_IFR_FORM_SET_OP :
CopyMem ( & VariableSize , & ( ( EFI_IFR_FORM_SET * ) & RawData [ Index ] ) - > NvDataSize , sizeof ( UINT16 ) ) ;
SizeNeeded = SizeNeeded + VariableSize + sizeof ( SETUP_MAP_NAME ) + sizeof ( EFI_HII_VARIABLE_PACK ) ;
VariableExist = TRUE ;
break ;
case EFI_IFR_VARSTORE_OP :
CopyMem ( & VariableSize , & ( ( EFI_IFR_VARSTORE * ) & RawData [ Index ] ) - > Size , sizeof ( UINT16 ) ) ;
SizeNeeded = SizeNeeded + VariableSize + sizeof ( EFI_HII_VARIABLE_PACK ) ;
//
// We will be expanding the stored ASCII name to a Unicode string. This will cause some memory overhead
// Since the VARSTORE size already takes in consideration the ASCII size, we need to size it and add another
// instance of it. Essentially, 2 ASCII strings == 1 Unicode string in size.
//
TempValue = ( UINTN ) ( ( EFI_IFR_VARSTORE * ) & RawData [ Index ] ) - > Header . Length - sizeof ( EFI_IFR_VARSTORE ) ;
SizeNeeded = SizeNeeded + TempValue * 2 ;
VariableExist = TRUE ;
break ;
}
Index = RawData [ Index + 1 ] + Index ;
}
//
// If a variable exists for this handle, add an additional variable pack overhead to
// indicate that we will have an extra null Variable Pack to signify the end of the Variable Packs
//
if ( VariableExist ) {
SizeNeeded = SizeNeeded + sizeof ( EFI_HII_VARIABLE_PACK ) ;
}
}
if ( SizeNeeded > * BufferSize ) {
* BufferSize = SizeNeeded ;
return EFI_BUFFER_TOO_SMALL ;
}
//
// Zero out the incoming buffer
//
ZeroMem ( Buffer , * BufferSize ) ;
//
// Cast the Buffer to EFI_HII_EXPORT_TABLE
//
ExportTable = ( EFI_HII_EXPORT_TABLE * ) Buffer ;
//
// Set the Revision for the Export Table
//
CopyMem ( & ExportTable - > Revision , & gEfiHiiProtocolGuid , sizeof ( EFI_GUID ) ) ;
ExportBuffer = ( UINT8 * ) ( UINTN ) ( ( ( UINT8 * ) ExportTable ) + sizeof ( EFI_HII_EXPORT_TABLE ) ) ;
HandleDatabase = HiiData - > DatabaseHead ;
//
// Check numeric value against the head of the database
//
for ( ; HandleDatabase ! = NULL ; HandleDatabase = HandleDatabase - > NextHandleDatabase ) {
DataTable = ( EFI_HII_DATA_TABLE * ) ExportBuffer ;
PackageInstance = HandleDatabase - > Buffer ;
//
// If not asking for a specific handle, export the entire database
//
if ( Handle = = 0 ) {
ExportTable - > NumberOfHiiDataTables = NumberOfHiiDataTables ;
CopyMem ( & DataTable - > PackageGuid , & PackageInstance - > Guid , sizeof ( EFI_GUID ) ) ;
DataTable - > HiiHandle = PackageInstance - > Handle ;
DataTable - > DevicePathOffset = ( UINT32 ) ( sizeof ( EFI_HII_DATA_TABLE ) ) ;
//
// Start Dumping DevicePath
//
ExtractDevicePathData ( DataTable , RawData , & ExportBuffer ) ;
if ( ( ( UINTN ) ExportBuffer ) = = ( ( UINTN ) DataTable ) ) {
//
// If there is no DevicePath information - set offset to 0 to signify the absence of data to parse
//
DataTable - > DevicePathOffset = 0 ;
}
DataTable - > VariableDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
if ( PackageInstance - > IfrSize > 0 ) {
FormPack = ( EFI_HII_IFR_PACK * ) ( ( CHAR8 * ) ( & PackageInstance - > IfrData ) + sizeof ( EFI_HII_PACK_HEADER ) ) ;
RawData = ( UINT8 * ) FormPack ;
TempValue = 0 ;
//
// Start dumping the Variable Data
//
ExtractVariableData ( DataTable , RawData , & ExportBuffer ) ;
DataTable - > IfrDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
if ( DataTable - > VariableDataOffset = = DataTable - > IfrDataOffset ) {
DataTable - > VariableDataOffset = 0 ;
}
//
// Start dumping the IFR data (Note: It is in an IFR PACK)
//
CopyMem ( ExportBuffer , & PackageInstance - > IfrData , PackageInstance - > IfrSize ) ;
ExportBuffer = ( UINT8 * ) ( UINTN ) ( ( ( UINTN ) ExportBuffer ) + PackageInstance - > IfrSize ) ;
DataTable - > StringDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
//
// Start dumping the String data (Note: It is in a String PACK)
//
if ( PackageInstance - > StringSize > 0 ) {
RawData = ( UINT8 * ) ( ( ( UINTN ) & PackageInstance - > IfrData ) + PackageInstance - > IfrSize ) ;
CopyMem ( ExportBuffer , RawData , PackageInstance - > StringSize ) ;
DataTable - > DataTableSize = ( UINT32 ) ( DataTable - > StringDataOffset + PackageInstance - > StringSize ) ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
for ( ; TempValue ! = 0 ; ) {
DataTable - > NumberOfLanguages + + ;
ExportBuffer = ExportBuffer + ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
}
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_STRING_PACK ) ;
} else {
DataTable - > StringDataOffset = 0 ;
}
} else {
//
// 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)
//
DataTable - > VariableDataOffset = 0 ;
DataTable - > IfrDataOffset = 0 ;
DataTable - > StringDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
//
// Start dumping the String data - NOTE: It is in String Pack form
//
if ( PackageInstance - > StringSize > 0 ) {
RawData = ( UINT8 * ) ( ( ( UINTN ) & PackageInstance - > IfrData ) + PackageInstance - > IfrSize ) ;
CopyMem ( ExportBuffer , RawData , PackageInstance - > StringSize ) ;
DataTable - > DataTableSize = ( UINT32 ) ( DataTable - > StringDataOffset + PackageInstance - > StringSize ) ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
for ( ; TempValue ! = 0 ; ) {
DataTable - > NumberOfLanguages + + ;
ExportBuffer = ExportBuffer + ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
}
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_STRING_PACK ) ;
} else {
DataTable - > StringDataOffset = 0 ;
}
}
} else {
//
// Match the numeric value with the database entry - if matched, extract PackageInstance
//
if ( Handle = = HandleDatabase - > Handle ) {
PackageInstance = HandleDatabase - > Buffer ;
ExportTable - > NumberOfHiiDataTables = NumberOfHiiDataTables ;
DataTable - > HiiHandle = PackageInstance - > Handle ;
CopyMem ( & DataTable - > PackageGuid , & PackageInstance - > Guid , sizeof ( EFI_GUID ) ) ;
//
// Start Dumping DevicePath
//
ExtractDevicePathData ( DataTable , RawData , & ExportBuffer ) ;
DataTable - > VariableDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
if ( PackageInstance - > IfrSize > 0 ) {
FormPack = ( EFI_HII_IFR_PACK * ) ( ( CHAR8 * ) ( & PackageInstance - > IfrData ) + sizeof ( EFI_HII_PACK_HEADER ) ) ;
RawData = ( UINT8 * ) FormPack ;
TempValue = 0 ;
//
// Start dumping the Variable Data
//
ExtractVariableData ( DataTable , RawData , & ExportBuffer ) ;
DataTable - > IfrDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
if ( DataTable - > VariableDataOffset = = DataTable - > IfrDataOffset ) {
DataTable - > VariableDataOffset = 0 ;
}
//
// Start dumping the IFR data
//
CopyMem ( ExportBuffer , & PackageInstance - > IfrData , PackageInstance - > IfrSize ) ;
ExportBuffer = ( UINT8 * ) ( UINTN ) ( ( ( UINTN ) ExportBuffer ) + PackageInstance - > IfrSize ) ;
DataTable - > StringDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
//
// Start dumping the String data - NOTE: It is in String Pack form
//
if ( PackageInstance - > StringSize > 0 ) {
RawData = ( UINT8 * ) ( ( ( UINTN ) & PackageInstance - > IfrData ) + PackageInstance - > IfrSize ) ;
CopyMem ( ExportBuffer , RawData , PackageInstance - > StringSize ) ;
DataTable - > DataTableSize = ( UINT32 ) ( DataTable - > StringDataOffset + PackageInstance - > StringSize ) ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
for ( ; TempValue ! = 0 ; ) {
DataTable - > NumberOfLanguages + + ;
ExportBuffer = ExportBuffer + ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
}
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_STRING_PACK ) ;
} else {
DataTable - > StringDataOffset = 0 ;
}
} else {
//
// No IFR? No variable information. If Offset is 0, means there is none.
//
DataTable - > VariableDataOffset = 0 ;
DataTable - > IfrDataOffset = 0 ;
DataTable - > StringDataOffset = ( UINT32 ) ( ( ( UINTN ) ExportBuffer ) - ( ( UINTN ) DataTable ) ) ;
//
// Start dumping the String data - Note: It is in String Pack form
//
if ( PackageInstance - > StringSize > 0 ) {
RawData = ( UINT8 * ) ( ( ( UINTN ) & PackageInstance - > IfrData ) + PackageInstance - > IfrSize ) ;
CopyMem ( ExportBuffer , RawData , PackageInstance - > StringSize ) ;
DataTable - > DataTableSize = ( UINT32 ) ( DataTable - > StringDataOffset + PackageInstance - > StringSize ) ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
for ( ; TempValue ! = 0 ; ) {
DataTable - > NumberOfLanguages + + ;
ExportBuffer = ExportBuffer + ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length ;
CopyMem ( & TempValue , & ( ( EFI_HII_STRING_PACK * ) ExportBuffer ) - > Header . Length , sizeof ( UINT32 ) ) ;
}
ExportBuffer = ExportBuffer + sizeof ( EFI_HII_STRING_PACK ) ;
} else {
DataTable - > StringDataOffset = 0 ;
}
}
break ;
}
}
}
return EFI_SUCCESS ;
}
EFI_STATUS
EFIAPI
HiiGetForms (
IN EFI_HII_PROTOCOL * This ,
IN EFI_HII_HANDLE Handle ,
IN EFI_FORM_ID FormId ,
IN OUT UINTN * BufferLengthTemp ,
OUT UINT8 * Buffer
)
/*++
Routine Description :
This function allows a program to extract a form or form package that has
previously been registered with the EFI HII database .
Arguments :
This - A pointer to the EFI_HII_PROTOCOL instance .
Handle - Handle on which the form resides . Type EFI_HII_HANDLE is defined in
EFI_HII_PROTOCOL . NewPack ( ) in the Packages section .
FormId - The ID of the form to return . If the ID is zero , the entire form package is returned .
Type EFI_FORM_ID is defined in " Related Definitions " below .
BufferLength - On input , the length of the Buffer . On output , the length of the returned buffer , if
the length was sufficient and , if it was not , the length that is required to fit the
requested form ( s ) .
Buffer - The buffer designed to receive the form ( s ) .
Returns :
EFI_SUCCESS - Buffer filled with the requested forms . BufferLength
was updated .
EFI_INVALID_PARAMETER - The handle is unknown .
EFI_NOT_FOUND - A form on the requested handle cannot be found with the
requested FormId .
EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored .
- - */
{
EFI_HII_PACKAGE_INSTANCE * PackageInstance ;
EFI_HII_DATA * HiiData ;
EFI_HII_HANDLE_DATABASE * HandleDatabase ;
EFI_HII_IFR_PACK * FormPack ;
EFI_IFR_FORM * Form ;
EFI_IFR_OP_HEADER * Location ;
UINT16 * BufferLength = ( UINT16 * ) BufferLengthTemp ;
if ( This = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
HiiData = EFI_HII_DATA_FROM_THIS ( This ) ;
HandleDatabase = HiiData - > DatabaseHead ;
PackageInstance = NULL ;
//
// Check numeric value against the head of the database
//
for ( ; HandleDatabase ! = NULL ; HandleDatabase = HandleDatabase - > NextHandleDatabase ) {
//
// Match the numeric value with the database entry - if matched, extract PackageInstance
//
if ( Handle = = HandleDatabase - > Handle ) {
PackageInstance = HandleDatabase - > Buffer ;
break ;
}
}
//
// No handle was found - error condition
//
if ( PackageInstance = = NULL ) {
return EFI_NOT_FOUND ;
}
//
// Based on if there is IFR data in this package instance, determine
// what the location is of the beginning of the string data.
//
if ( PackageInstance - > IfrSize > 0 ) {
FormPack = ( EFI_HII_IFR_PACK * ) ( & PackageInstance - > IfrData ) ;
} else {
//
// If there is no IFR data return an error
//
return EFI_NOT_FOUND ;
}
//
// If requesting the entire Form Package
//
if ( FormId = = 0 ) {
//
// Return an error if buffer is too small
//
if ( PackageInstance - > IfrSize > * BufferLength | | Buffer = = NULL ) {
* BufferLength = ( UINT16 ) PackageInstance - > IfrSize ;
return EFI_BUFFER_TOO_SMALL ;
}
CopyMem ( Buffer , FormPack , PackageInstance - > IfrSize ) ;
return EFI_SUCCESS ;
} else {
FormPack = ( EFI_HII_IFR_PACK * ) ( ( CHAR8 * ) ( & PackageInstance - > IfrData ) + sizeof ( EFI_HII_PACK_HEADER ) ) ;
Location = ( EFI_IFR_OP_HEADER * ) FormPack ;
//
// Look for the FormId requested
//
for ( ; Location - > OpCode ! = EFI_IFR_END_FORM_SET_OP ; ) {
switch ( Location - > OpCode ) {
case EFI_IFR_FORM_OP :
Form = ( EFI_IFR_FORM * ) Location ;
//
// If we found a Form Op-code and it is of the correct Id, copy it and return
//
if ( Form - > FormId = = FormId ) {
if ( Location - > Length > * BufferLength | | Buffer = = NULL ) {
* BufferLength = Location - > Length ;
return EFI_BUFFER_TOO_SMALL ;
} else {
for ( ; Location - > OpCode ! = EFI_IFR_END_FORM_OP ; ) {
CopyMem ( Buffer , Location , Location - > Length ) ;
Buffer = Buffer + Location - > Length ;
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
}
CopyMem ( Buffer , Location , Location - > Length ) ;
return EFI_SUCCESS ;
}
}
default :
break ;
}
//
// Go to the next Op-Code
//
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
}
}
return EFI_SUCCESS ;
}
//
// Helper functions to HiiGetDefaultImage()
//
STATIC
UINT8 *
HiiGetDefaultImageInitPack (
IN OUT EFI_HII_VARIABLE_PACK_LIST * VariablePackItem ,
IN EFI_IFR_VARSTORE * VarStore
)
/*++
Routine Description :
Initialize the EFI_HII_VARIABLE_PACK_LIST structure and
prepare it ready to be used by HiiGetDefaultImagePopulateMap ( ) .
Arguments :
VariablePackItem - Variable Package List .
VarStore - IFR variable storage .
Returns :
Return the pointer to the Map space .
- - */
{
CHAR16 * Name16 ;
CHAR8 * Name8 ;
CHAR8 * Map ;
EFI_HII_VARIABLE_PACK * VariablePack ;
//
// Set pointer the pack right after the node
//
VariablePackItem - > VariablePack = ( EFI_HII_VARIABLE_PACK * ) ( VariablePackItem + 1 ) ;
VariablePack = VariablePackItem - > VariablePack ;
//
// Copy the var name to VariablePackItem from VarStore
// Needs ASCII->Unicode conversion.
//
ASSERT ( VarStore - > Header . Length > sizeof ( * VarStore ) ) ;
Name8 = ( CHAR8 * ) ( VarStore + 1 ) ;
Name16 = ( CHAR16 * ) ( VariablePack + 1 ) ;
Ascii2Unicode ( Name16 , Name8 ) ;
//
// Compute the other fields of the VariablePackItem
//
VariablePack - > VariableId = VarStore - > VarId ;
CopyMem ( & VariablePack - > VariableGuid , & VarStore - > Guid , sizeof ( EFI_GUID ) ) ;
VariablePack - > VariableNameLength = ( UINT32 ) ( ( StrLen ( Name16 ) + 1 ) * 2 ) ;
VariablePack - > Header . Length = sizeof ( * VariablePack )
+ VariablePack - > VariableNameLength
+ VarStore - > Size ;
//
// Return the pointer to the Map space.
//
Map = ( CHAR8 * ) Name16 + VariablePack - > VariableNameLength ;
return ( UINT8 * ) Map ;
}
STATIC
VOID
HiiGetDefaultImagePopulateMap (
IN OUT UINT8 * Map ,
IN EFI_IFR_OP_HEADER * FormSet ,
IN EFI_IFR_VARSTORE * VarStore ,
IN UINTN DefaultMask
)
/*++
Routine Description :
Fill the Map with all the default values either from NV or Hii database .
Arguments :
Map - Memory pointer to hold the default values .
FormSet - The starting EFI_IFR_OP_HEADER to begin retriving default values .
VarStore - IFR variable storage .
DefaultMask - The mask used to get the default variable .
Returns :
VOID
- - */
{
EFI_STATUS Status ;
EFI_IFR_OP_HEADER * IfrItem ;
UINT16 VarId ;
EFI_IFR_VARSTORE_SELECT * VarSelect ;
EFI_IFR_ONE_OF_OPTION * OneOfOpt ;
EFI_IFR_CHECKBOX * CheckBox ;
EFI_IFR_NUMERIC * Numeric ;
UINTN Size ;
UINTN SizeTmp ;
EFI_IFR_NV_DATA * IfrNvData ;
EFI_GUID Guid ;
CHAR16 * Name16 ;
CHAR8 * Name8 ;
EFI_HANDLE CallbackHandle ;
EFI_FORM_CALLBACK_PROTOCOL * FormCallbackProt ;
//
// Get the Map's Name/Guid/Szie from the Varstore.
// VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.
//
ASSERT ( VarStore - > Header . Length > = sizeof ( * VarStore ) ) ;
Name8 = ( CHAR8 * ) ( VarStore + 1 ) ;
Name16 = AllocateZeroPool ( ( VarStore - > Header . Length - sizeof ( * VarStore ) ) * sizeof ( CHAR16 ) ) ;
Ascii2Unicode ( Name16 , Name8 ) ;
CopyMem ( & Guid , & VarStore - > Guid , sizeof ( EFI_GUID ) ) ;
Size = VarStore - > Size ;
//
// First, check if the map exists in the NV. If so, get it from NV and exit.
//
if ( DefaultMask = = EFI_IFR_FLAG_MANUFACTURING ) {
//
// Check if Manufaturing Defaults exist in the NV.
//
Status = EfiLibHiiVariableOverrideBySuffix (
HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE ,
Name16 ,
& Guid ,
Size ,
Map
) ;
} else {
//
// All other cases default to Defaults. Check if Defaults exist in the NV.
//
Status = EfiLibHiiVariableOverrideBySuffix (
HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE ,
Name16 ,
& Guid ,
Size ,
Map
) ;
}
if ( ! EFI_ERROR ( Status ) ) {
//
// Either Defaults/Manufacturing variable exists and appears to be valid.
// The map is read, exit w/ success now.
//
gBS - > FreePool ( Name16 ) ;
return ;
}
//
// First, prime the map with what already is in the NV.
// This is needed to cover a situation where the IFR does not contain all the
// defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.
// Ignore status. Either it gets read or not.
//
FormCallbackProt = NULL ;
CopyMem ( & CallbackHandle , & ( ( EFI_IFR_FORM_SET * ) FormSet ) - > CallbackHandle , sizeof ( CallbackHandle ) ) ;
if ( CallbackHandle ! = NULL ) {
Status = gBS - > HandleProtocol (
( EFI_HANDLE ) ( UINTN ) CallbackHandle ,
& gEfiFormCallbackProtocolGuid ,
( VOID * ) & FormCallbackProt
) ;
}
if ( ( NULL ! = FormCallbackProt ) & & ( NULL ! = FormCallbackProt - > NvRead ) ) {
//
// Attempt to read using NvRead() callback. Probe first for existence and correct variable size.
//
SizeTmp = 0 ;
Status = FormCallbackProt - > NvRead (
FormCallbackProt ,
Name16 ,
& Guid ,
0 ,
& SizeTmp ,
NULL
) ;
if ( ( EFI_BUFFER_TOO_SMALL = = Status ) & & ( SizeTmp = = Size ) ) {
Status = FormCallbackProt - > NvRead (
FormCallbackProt ,
Name16 ,
& Guid ,
0 ,
& SizeTmp ,
Map
) ;
ASSERT_EFI_ERROR ( Status ) ;
ASSERT ( SizeTmp = = Size ) ;
}
} else {
//
// No callback available for this formset, read straight from NV. Deliberately ignore the Status.
// The buffer will only be written if variable exists nd has correct size.
//
Status = EfiLibHiiVariableRetrieveFromNv (
Name16 ,
& Guid ,
Size ,
( VOID * * ) & Map
) ;
}
//
// Iterate all IFR statements and for applicable, retrieve the default into the Map.
//
for ( IfrItem = FormSet , VarId = 0 ;
IfrItem - > OpCode ! = EFI_IFR_END_FORM_SET_OP ;
IfrItem = ( EFI_IFR_OP_HEADER * ) ( ( UINT8 * ) IfrItem + IfrItem - > Length )
) {
//
// Observe VarStore switch.
//
if ( EFI_IFR_VARSTORE_SELECT_OP = = IfrItem - > OpCode ) {
VarSelect = ( EFI_IFR_VARSTORE_SELECT * ) IfrItem ;
VarId = VarSelect - > VarId ;
continue ;
}
//
// Skip opcodes that reference other VarStore than that specific to current map.
//
if ( VarId ! = VarStore - > VarId ) {
continue ;
}
//
// Extract the default value from this opcode if applicable, and apply it to the map.
//
IfrNvData = ( EFI_IFR_NV_DATA * ) IfrItem ;
switch ( IfrItem - > OpCode ) {
case EFI_IFR_ONE_OF_OP :
ASSERT ( IfrNvData - > QuestionId + IfrNvData - > StorageWidth < = VarStore - > Size ) ;
//
// Get to the first EFI_IFR_ONE_OF_OPTION_OP
//
IfrItem = ( EFI_IFR_OP_HEADER * ) ( ( UINT8 * ) IfrItem + IfrItem - > Length ) ;
ASSERT ( EFI_IFR_ONE_OF_OPTION_OP = = IfrItem - > OpCode ) ;
OneOfOpt = ( EFI_IFR_ONE_OF_OPTION * ) IfrItem ;
//
// In the worst case, the first will be the default.
//
CopyMem ( Map + IfrNvData - > QuestionId , & OneOfOpt - > Value , IfrNvData - > StorageWidth ) ;
while ( EFI_IFR_ONE_OF_OPTION_OP = = IfrItem - > OpCode ) {
OneOfOpt = ( EFI_IFR_ONE_OF_OPTION * ) IfrItem ;
if ( DefaultMask = = EFI_IFR_FLAG_MANUFACTURING ) {
if ( 0 ! = ( OneOfOpt - > Flags & EFI_IFR_FLAG_MANUFACTURING ) ) {
//
// In the worst case, the first will be the default.
//
CopyMem ( Map + IfrNvData - > QuestionId , & OneOfOpt - > Value , IfrNvData - > StorageWidth ) ;
break ;
}
} else {
if ( OneOfOpt - > Flags & EFI_IFR_FLAG_DEFAULT ) {
//
// In the worst case, the first will be the default.
//
CopyMem ( Map + IfrNvData - > QuestionId , & OneOfOpt - > Value , IfrNvData - > StorageWidth ) ;
break ;
}
}
IfrItem = ( EFI_IFR_OP_HEADER * ) ( ( UINT8 * ) IfrItem + IfrItem - > Length ) ;
}
continue ;
break ;
case EFI_IFR_CHECKBOX_OP :
ASSERT ( IfrNvData - > QuestionId + IfrNvData - > StorageWidth < = VarStore - > Size ) ;
CheckBox = ( EFI_IFR_CHECK_BOX * ) IfrItem ;
if ( DefaultMask = = EFI_IFR_FLAG_MANUFACTURING ) {
if ( 0 ! = ( CheckBox - > Flags & EFI_IFR_FLAG_MANUFACTURING ) ) {
* ( UINT8 * ) ( Map + IfrNvData - > QuestionId ) = TRUE ;
}
} else {
if ( CheckBox - > Flags & EFI_IFR_FLAG_DEFAULT ) {
* ( UINT8 * ) ( Map + IfrNvData - > QuestionId ) = TRUE ;
}
}
break ;
case EFI_IFR_NUMERIC_OP :
ASSERT ( IfrNvData - > QuestionId + IfrNvData - > StorageWidth < = VarStore - > Size ) ;
Numeric = ( EFI_IFR_NUMERIC * ) IfrItem ;
CopyMem ( Map + IfrNvData - > QuestionId , & Numeric - > Default , IfrNvData - > StorageWidth ) ;
break ;
case EFI_IFR_ORDERED_LIST_OP :
case EFI_IFR_PASSWORD_OP :
case EFI_IFR_STRING_OP :
//
// No support for default value for these opcodes.
//
break ;
}
}
gBS - > FreePool ( Name16 ) ;
}
EFI_STATUS
EFIAPI
HiiGetDefaultImage (
IN EFI_HII_PROTOCOL * This ,
IN EFI_HII_HANDLE Handle ,
IN UINTN DefaultMask ,
OUT EFI_HII_VARIABLE_PACK_LIST * * VariablePackList
)
/*++
Routine Description :
This function allows a program to extract the NV Image
that represents the default storage image
Arguments :
This - A pointer to the EFI_HII_PROTOCOL instance .
Handle - The HII handle from which will have default data retrieved .
UINTN - Mask used to retrieve the default image .
VariablePackList - Callee allocated , tightly - packed , link list data
structure that contain all default varaible packs
from the Hii Database .
Returns :
EFI_NOT_FOUND - If Hii database does not contain any default images .
EFI_INVALID_PARAMETER - Invalid input parameter .
EFI_SUCCESS - Operation successful .
- - */
{
EFI_HII_HANDLE_DATABASE * HandleDatabase ;
EFI_HII_PACKAGE_INSTANCE * PackageInstance ;
EFI_IFR_OP_HEADER * FormSet ;
EFI_IFR_OP_HEADER * IfrItem ;
EFI_IFR_VARSTORE * VarStore ;
EFI_IFR_VARSTORE * VarStoreDefault ;
UINTN SetupMapNameSize ;
UINTN SizeOfMaps ;
EFI_HII_VARIABLE_PACK_LIST * PackList ;
EFI_HII_VARIABLE_PACK_LIST * PackListNext ;
EFI_HII_VARIABLE_PACK_LIST * PackListLast ;
UINT8 * Map ;
//
// Find the IFR pack from the handle. Then get the formset from the pack.
//
PackageInstance = NULL ;
HandleDatabase = ( EFI_HII_DATA_FROM_THIS ( This ) ) - > DatabaseHead ;
for ( ; HandleDatabase ! = NULL ; HandleDatabase = HandleDatabase - > NextHandleDatabase ) {
if ( Handle = = HandleDatabase - > Handle ) {
PackageInstance = HandleDatabase - > Buffer ;
break ;
}
}
if ( PackageInstance = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
FormSet = ( EFI_IFR_OP_HEADER * ) ( ( UINT8 * ) & PackageInstance - > IfrData + sizeof ( EFI_HII_IFR_PACK ) ) ;
//
// Get the sizes of all the VARSTOREs in this VFR.
// Then allocate enough space for all of them plus all maps
//
SizeOfMaps = 0 ;
IfrItem = FormSet ;
while ( EFI_IFR_END_FORM_SET_OP ! = IfrItem - > OpCode ) {
if ( EFI_IFR_VARSTORE_OP = = IfrItem - > OpCode ) {
VarStore = ( EFI_IFR_VARSTORE * ) IfrItem ;
//
// Size of the map
//
SizeOfMaps + = VarStore - > Size ;
//
// add the size of the string, in Unicode
//
SizeOfMaps + = ( VarStore - > Header . Length - sizeof ( * VarStore ) ) * 2 ;
//
// Space for node
//
SizeOfMaps + = sizeof ( EFI_HII_VARIABLE_PACK ) ;
//
// Space for linked list node
//
SizeOfMaps + = sizeof ( EFI_HII_VARIABLE_PACK_LIST ) ;
}
IfrItem = ( EFI_IFR_OP_HEADER * ) ( ( UINT8 * ) IfrItem + IfrItem - > Length ) ;
}
//
// If the FormSet OpCode has a non-zero NvDataSize. There is a default
// NvMap with ID=0, GUID that of the formset itself and "Setup" as name.
//
SetupMapNameSize = StrLen ( SETUP_MAP_NAME ) + 1 ;
VarStoreDefault = AllocateZeroPool ( sizeof ( * VarStoreDefault ) + SetupMapNameSize ) ;
if ( 0 ! = ( ( EFI_IFR_FORM_SET * ) FormSet ) - > NvDataSize ) {
VarStoreDefault - > Header . OpCode = EFI_IFR_VARSTORE_OP ;
VarStoreDefault - > Header . Length = ( UINT8 ) ( sizeof ( * VarStoreDefault ) + SetupMapNameSize ) ;
Unicode2Ascii ( ( CHAR8 * ) ( VarStoreDefault + 1 ) , SETUP_MAP_NAME ) ;
CopyMem ( & VarStoreDefault - > Guid , & ( ( EFI_IFR_FORM_SET * ) FormSet ) - > Guid , sizeof ( EFI_GUID ) ) ;
VarStoreDefault - > VarId = 0 ;
VarStoreDefault - > Size = ( ( EFI_IFR_FORM_SET * ) FormSet ) - > NvDataSize ;
//
// Size of the map
//
SizeOfMaps + = VarStoreDefault - > Size ;
//
// add the size of the string
//
SizeOfMaps + = sizeof ( SETUP_MAP_NAME ) ;
//
// Space for node
//
SizeOfMaps + = sizeof ( EFI_HII_VARIABLE_PACK ) ;
//
// Space for linked list node
//
SizeOfMaps + = sizeof ( EFI_HII_VARIABLE_PACK_LIST ) ;
}
if ( 0 = = SizeOfMaps ) {
//
// The IFR does not have any explicit or default map(s).
//
return EFI_NOT_FOUND ;
}
//
// Allocate the return buffer
//
PackList = AllocateZeroPool ( SizeOfMaps ) ;
ASSERT ( NULL ! = PackList ) ;
PackListNext = PackList ;
PackListLast = PackList ;
//
// Handle the default map first, if any.
//
if ( 0 ! = VarStoreDefault - > Size ) {
Map = HiiGetDefaultImageInitPack ( PackListNext , VarStoreDefault ) ;
HiiGetDefaultImagePopulateMap ( Map , FormSet , VarStoreDefault , DefaultMask ) ;
PackListNext - > NextVariablePack = ( EFI_HII_VARIABLE_PACK_LIST * ) ( ( UINT8 * ) PackListNext - > VariablePack + PackListNext - > VariablePack - > Header . Length ) ;
PackListLast = PackListNext ;
PackListNext = PackListNext - > NextVariablePack ;
}
//
// Handle the explicit varstore(s)
//
IfrItem = FormSet ;
while ( EFI_IFR_END_FORM_SET_OP ! = IfrItem - > OpCode ) {
if ( EFI_IFR_VARSTORE_OP = = IfrItem - > OpCode ) {
Map = HiiGetDefaultImageInitPack ( PackListNext , ( EFI_IFR_VARSTORE * ) IfrItem ) ;
HiiGetDefaultImagePopulateMap ( Map , FormSet , ( EFI_IFR_VARSTORE * ) IfrItem , DefaultMask ) ;
PackListNext - > NextVariablePack = ( EFI_HII_VARIABLE_PACK_LIST * ) ( ( UINT8 * ) PackListNext - > VariablePack + PackListNext - > VariablePack - > Header . Length ) ;
PackListLast = PackListNext ;
PackListNext = PackListNext - > NextVariablePack ;
}
IfrItem = ( EFI_IFR_OP_HEADER * ) ( ( UINT8 * ) IfrItem + IfrItem - > Length ) ;
}
PackListLast - > NextVariablePack = NULL ;
* VariablePackList = PackList ;
return EFI_SUCCESS ;
}
EFI_STATUS
EFIAPI
HiiUpdateForm (
IN EFI_HII_PROTOCOL * This ,
IN EFI_HII_HANDLE Handle ,
IN EFI_FORM_LABEL Label ,
IN BOOLEAN AddData ,
IN EFI_HII_UPDATE_DATA * Data
)
/*++
Routine Description :
This function allows the caller to update a form that has
previously been registered with the EFI HII database .
Arguments :
Handle - Hii Handle associated with the Formset to modify
Label - Update information starting immediately after this label in the IFR
AddData - If TRUE , add data . If FALSE , remove data
Data - If adding data , this is the pointer to the data to add
Returns :
EFI_SUCCESS - Update success .
Other - Update fail .
- - */
{
EFI_HII_PACKAGE_INSTANCE * PackageInstance ;
EFI_HII_DATA * HiiData ;
EFI_HII_HANDLE_DATABASE * HandleDatabase ;
EFI_HII_IFR_PACK * FormPack ;
EFI_IFR_OP_HEADER * Location ;
EFI_IFR_OP_HEADER * DataLocation ;
UINT8 * OtherBuffer ;
UINT8 * TempBuffer ;
UINT8 * OrigTempBuffer ;
UINTN TempBufferSize ;
UINTN Index ;
OtherBuffer = NULL ;
if ( This = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
HiiData = EFI_HII_DATA_FROM_THIS ( This ) ;
HandleDatabase = HiiData - > DatabaseHead ;
PackageInstance = NULL ;
//
// Check numeric value against the head of the database
//
for ( ; HandleDatabase ! = NULL ; HandleDatabase = HandleDatabase - > NextHandleDatabase ) {
//
// Match the numeric value with the database entry - if matched, extract PackageInstance
//
if ( Handle = = HandleDatabase - > Handle ) {
PackageInstance = HandleDatabase - > Buffer ;
break ;
}
}
//
// No handle was found - error condition
//
if ( PackageInstance = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
//
// Calculate and allocate space for retrieval of IFR data
//
DataLocation = ( EFI_IFR_OP_HEADER * ) & Data - > Data ;
TempBufferSize = ( CHAR8 * ) ( & PackageInstance - > IfrData ) - ( CHAR8 * ) ( PackageInstance ) ;
for ( Index = 0 ; Index < Data - > DataCount ; Index + + ) {
TempBufferSize + = DataLocation - > Length ;
DataLocation = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( DataLocation ) + DataLocation - > Length ) ;
}
TempBufferSize + = PackageInstance - > IfrSize + PackageInstance - > StringSize ;
TempBuffer = AllocateZeroPool ( TempBufferSize ) ;
OrigTempBuffer = TempBuffer ;
//
// We update only packages with IFR information in it
//
if ( PackageInstance - > IfrSize = = 0 ) {
return EFI_INVALID_PARAMETER ;
}
CopyMem (
TempBuffer ,
PackageInstance ,
( ( CHAR8 * ) ( & PackageInstance - > IfrData ) + sizeof ( EFI_HII_PACK_HEADER ) - ( CHAR8 * ) ( PackageInstance ) )
) ;
TempBuffer = TempBuffer + ( ( CHAR8 * ) ( & PackageInstance - > IfrData ) + sizeof ( EFI_HII_PACK_HEADER ) - ( CHAR8 * ) ( PackageInstance ) ) ;
//
// Based on if there is IFR data in this package instance, determine
// what the location is of the beginning of the string data.
//
FormPack = ( EFI_HII_IFR_PACK * ) ( ( CHAR8 * ) ( & PackageInstance - > IfrData ) + sizeof ( EFI_HII_PACK_HEADER ) ) ;
Location = ( EFI_IFR_OP_HEADER * ) FormPack ;
//
// Look for the FormId requested
//
for ( ; Location - > OpCode ! = EFI_IFR_END_FORM_SET_OP ; ) {
switch ( Location - > OpCode ) {
case EFI_IFR_FORM_SET_OP :
//
// If the FormSet has an update pending, pay attention.
//
if ( Data - > FormSetUpdate ) {
( ( EFI_IFR_FORM_SET * ) Location ) - > CallbackHandle = Data - > FormCallbackHandle ;
}
CopyMem ( TempBuffer , Location , Location - > Length ) ;
TempBuffer = TempBuffer + Location - > Length ;
break ;
case EFI_IFR_FORM_OP :
//
// If the Form has an update pending, pay attention.
//
if ( Data - > FormUpdate ) {
( ( EFI_IFR_FORM * ) Location ) - > FormTitle = Data - > FormTitle ;
}
CopyMem ( TempBuffer , Location , Location - > Length ) ;
TempBuffer = TempBuffer + Location - > Length ;
break ;
case EFI_IFR_LABEL_OP :
//
// If the label does not match the requested update point, ignore it
//
if ( ( ( EFI_IFR_LABEL * ) Location ) - > LabelId ! = Label ) {
//
// Copy the label
//
CopyMem ( TempBuffer , Location , Location - > Length ) ;
TempBuffer = TempBuffer + Location - > Length ;
//
// Go to the next Op-Code
//
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
continue ;
}
if ( AddData ) {
//
// Copy the label
//
CopyMem ( TempBuffer , Location , Location - > Length ) ;
TempBuffer = TempBuffer + Location - > Length ;
//
// Add the DataCount amount of opcodes to TempBuffer
//
DataLocation = ( EFI_IFR_OP_HEADER * ) & Data - > Data ;
for ( Index = 0 ; Index < Data - > DataCount ; Index + + ) {
CopyMem ( TempBuffer , DataLocation , DataLocation - > Length ) ;
( ( EFI_HII_PACKAGE_INSTANCE * ) OrigTempBuffer ) - > IfrSize + = DataLocation - > Length ;
OtherBuffer = ( ( UINT8 * ) & ( ( EFI_HII_PACKAGE_INSTANCE * ) OrigTempBuffer ) - > StringSize + sizeof ( UINTN ) ) ;
CopyMem ( OtherBuffer , & ( ( EFI_HII_PACKAGE_INSTANCE * ) OrigTempBuffer ) - > IfrSize , 2 ) ;
TempBuffer = TempBuffer + DataLocation - > Length ;
DataLocation = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( DataLocation ) + DataLocation - > Length ) ;
}
//
// Go to the next Op-Code
//
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
continue ;
} else {
//
// Copy the label
//
CopyMem ( TempBuffer , Location , Location - > Length ) ;
TempBuffer = TempBuffer + Location - > Length ;
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
//
// Remove the DataCount amount of opcodes unless we run into an end of form or a label
//
for ( Index = 0 ; Index < Data - > DataCount ; Index + + ) {
//
// If we are about to skip an end form - bail out, since that is illegal
//
if ( ( Location - > OpCode = = EFI_IFR_END_FORM_OP ) | | ( Location - > OpCode = = EFI_IFR_LABEL_OP ) ) {
break ;
}
//
// By skipping Location entries, we are in effect not copying what was previously there
//
( ( EFI_HII_PACKAGE_INSTANCE * ) OrigTempBuffer ) - > IfrSize - = Location - > Length ;
OtherBuffer = ( ( UINT8 * ) & ( ( EFI_HII_PACKAGE_INSTANCE * ) OrigTempBuffer ) - > StringSize + sizeof ( UINTN ) ) ;
CopyMem ( OtherBuffer , & ( ( EFI_HII_PACKAGE_INSTANCE * ) OrigTempBuffer ) - > IfrSize , 2 ) ;
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
}
}
default :
CopyMem ( TempBuffer , Location , Location - > Length ) ;
TempBuffer = TempBuffer + Location - > Length ;
break ;
}
//
// Go to the next Op-Code
//
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
}
//
// Copy the last op-code left behind from the for loop
//
CopyMem ( TempBuffer , Location , Location - > Length ) ;
//
// Advance to beginning of strings and copy them
//
TempBuffer = TempBuffer + Location - > Length ;
Location = ( EFI_IFR_OP_HEADER * ) ( ( CHAR8 * ) ( Location ) + Location - > Length ) ;
CopyMem ( TempBuffer , Location , PackageInstance - > StringSize ) ;
//
// Free the old buffer, and assign into our database the latest buffer
//
gBS - > FreePool ( HandleDatabase - > Buffer ) ;
HandleDatabase - > Buffer = OrigTempBuffer ;
return EFI_SUCCESS ;
}