summaryrefslogtreecommitdiff
path: root/Core/CORE_DXE/UefiHii
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/CORE_DXE/UefiHii
downloadzprj-master.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/CORE_DXE/UefiHii')
-rw-r--r--Core/CORE_DXE/UefiHii/HiAccessConfig.c322
-rw-r--r--Core/CORE_DXE/UefiHii/Hii.chmbin0 -> 60152 bytes
-rw-r--r--Core/CORE_DXE/UefiHii/HiiConfig.c1263
-rw-r--r--Core/CORE_DXE/UefiHii/HiiDatabase.c1814
-rw-r--r--Core/CORE_DXE/UefiHii/HiiFont.c1035
-rw-r--r--Core/CORE_DXE/UefiHii/HiiFontEx.c1332
-rw-r--r--Core/CORE_DXE/UefiHii/HiiPrivate.h885
-rw-r--r--Core/CORE_DXE/UefiHii/HiiString.c1609
-rw-r--r--Core/CORE_DXE/UefiHii/UefiHii.cif18
-rw-r--r--Core/CORE_DXE/UefiHii/UefiHii.sdl15
-rw-r--r--Core/CORE_DXE/UefiHii/UefiHiiUtils.c750
-rw-r--r--Core/CORE_DXE/UefiHii/hii21ExportConfig.c1143
12 files changed, 10186 insertions, 0 deletions
diff --git a/Core/CORE_DXE/UefiHii/HiAccessConfig.c b/Core/CORE_DXE/UefiHii/HiAccessConfig.c
new file mode 100644
index 0000000..d165a1e
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiAccessConfig.c
@@ -0,0 +1,322 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiAccessConfig.c 7 5/04/11 12:08p Artems $
+//
+// $Revision: 7 $
+//
+// $Date: 5/04/11 12:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiAccessConfig.c $
+//
+// 7 5/04/11 12:08p Artems
+// Bug fix: when variable is absent attribute state was undefined
+//
+// 6 1/25/11 4:03p Artems
+// EIP 51298: Fixed corruption in buffer size after passing it to
+// ConfigToBlock function
+// Added check for correct syntax of request string in ExtractConfig
+// function
+//
+// 5 9/30/10 6:12p Artems
+// Removed unnecessary service functions
+//
+// 3 2/19/10 4:01p Felixp
+// Debug messages are removed.
+//
+// 2 11/25/09 11:25a Felixp
+// Action parameter of the Callback function is updated based on UEFI
+// errata
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HiiAccessConfig.c
+//
+// Description: Hii Config Access protocol implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
+
+#include "HiiPrivate.h"
+
+extern const NAME_PATTERN GuidPattern;
+extern const NAME_PATTERN NamePattern;
+extern const NAME_PATTERN PathPattern;
+extern const NAME_PATTERN AltCfgPattern;
+extern const NAME_PATTERN OffsetPattern;
+extern const NAME_PATTERN WidthPattern;
+extern const NAME_PATTERN ValuePattern;
+extern const CHAR16 HexDigit[];
+
+UINTN EfiStrLen (IN CHAR16 *String);
+UINTN EfiStrSize (IN CHAR16 *String);
+VOID EfiStrCat (IN CHAR16 *Destination, IN CHAR16 *Source);
+
+//**************************** Protocol functions implementation ***************************
+
+
+EFI_STATUS HiiAccessExtractConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+)
+{
+ EFI_STATUS Status;
+ UINTN Length;
+ EFI_GUID Guid;
+ CHAR16 Name[80];
+ CHAR16 *Pointer = Request;
+ UINT8 *Var = NULL;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
+ CHAR16 *ErrorMarker;
+
+ if(Request == NULL) {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &ConfigRouting);
+ if(EFI_ERROR(Status))
+ return Status;
+
+//check syntax for guid
+ if(!CheckPattern(Request, &GuidPattern)) {
+ *Progress = Request;
+ return EFI_INVALID_PARAMETER;
+ }
+//extract guid
+ ErrorMarker = Pointer;
+ Pointer += 5; //skip "GUID=" pattern
+ Length = 32; //length of guid in symbols
+ StringToBlock(Pointer, Length, (UINT8 *)&Guid);
+ Pointer += Length;
+ if(*Pointer != L'&') {
+ TRACE((TRACE_DXE_CORE, "HII Extract Config: Guid extraction failed\n"));
+ *Progress = ErrorMarker;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//check syntax for name
+ if(!CheckPattern(Pointer + 1, &NamePattern)) {
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+//extract name
+ ErrorMarker = Pointer;
+ Pointer += 6; //skip '&NAME=' pattern
+ Length = 80;
+ StringToChar16(Pointer, &Length, Name);
+ Pointer += (Length * 4);
+ if(*Pointer != L'&') {
+ TRACE((TRACE_DXE_CORE, "HII Extract Config: Name extraction failed\n"));
+ *Progress = ErrorMarker;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//get variable by name and guid from nvram
+
+ Length = 0;
+ Status = GetEfiVariable(Name, &Guid, NULL, &Length, &Var);
+ if(EFI_ERROR(Status)) {
+ *Progress = Request;
+ return Status;
+ }
+
+//find start of OFFSET/WIDTH/VALUE block
+ Pointer++; //skip '&'
+ while((*Pointer != L'&') && (*Pointer != 0)) //skip PATH
+ Pointer++;
+
+ if(*Pointer == 0) { //OFFSET/WIDTH blocks are missed
+ UINTN TempSize;
+ CHAR16 *TempString;
+ CHAR16 *TempString2;
+
+ TempSize = (EfiStrLen(L"&OFFSET=0&WIDTH=") + sizeof(Length) + 1) * sizeof(CHAR16);
+ TempString = MallocZ(TempSize);
+ if(TempString == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ Swprintf_s(TempString, TempSize, L"&OFFSET=0&WIDTH=%x", Length);
+
+ TempSize += EfiStrSize(Request);
+ TempString2 = MallocZ(TempSize);
+ if(TempString2 == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ EfiStrCat(TempString2, Request);
+ EfiStrCat(TempString2, TempString);
+
+ Status = ConfigRouting->BlockToConfig(ConfigRouting, TempString2, Var, Length, Results, Progress);
+ *Progress = Request + EfiStrLen(Request); //set Progress to end of ConfigHdr
+ pBS->FreePool(TempString);
+ pBS->FreePool(TempString2);
+ } else { //OFFSET/WIDTH block found, let's check if it's correct
+ if(!CheckPattern(Pointer + 1, &OffsetPattern)) {
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = ConfigRouting->BlockToConfig(ConfigRouting, Request, Var, Length, Results, Progress);
+ }
+
+ pBS->FreePool(Var);
+
+ return Status;
+}
+
+EFI_STATUS HiiAccessRouteConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+)
+{
+ EFI_STATUS Status;
+ UINTN Length;
+ UINTN VarSize;
+ EFI_GUID Guid;
+ CHAR16 Name[80];
+ CHAR16 *Pointer = Configuration;
+ UINT8 *Var = NULL;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
+ EFI_HANDLE Handle;
+ UINT32 Attributes;
+
+ if(Configuration == NULL)
+ {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &ConfigRouting);
+ if(EFI_ERROR(Status))
+ return Status;
+
+//check syntax for guid
+ if(!CheckPattern(Configuration, &GuidPattern))
+ {
+ *Progress = Configuration;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//check proper device path
+ Status = FindDeviceHandle(Configuration, &Handle);
+ if(EFI_ERROR(Status))
+ return EFI_NOT_FOUND;
+
+//extract guid
+ Pointer += 5; //skip "GUID=" pattern
+ Length = 32; //length of guid in bytes
+ StringToBlock(Pointer, Length, (UINT8 *)&Guid);
+ Pointer += Length;
+ if(*Pointer != L'&')
+ {
+ TRACE((TRACE_DXE_CORE, "HII Route Config: Guid extraction failed\n"));
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//check syntax for name
+ if(!CheckPattern(Pointer + 1, &NamePattern))
+ {
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+//extract name
+ Pointer += 6; //skip '&NAME=' pattern
+ Length = 80;
+ StringToChar16(Pointer, &Length, Name);
+ Pointer += (Length * 4);
+ if(*Pointer != L'&')
+ {
+ TRACE((TRACE_DXE_CORE, "HII Route Config: Name extraction failed\n"));
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//get variable by name and guid from nvram
+
+ Length = 0;
+ Status = GetEfiVariable(Name, &Guid, &Attributes, &Length, &Var);
+ if(EFI_ERROR(Status)) //requested variable not found
+ {
+ Var = NULL;
+ Length = 0;
+ Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ }
+ VarSize = Length;
+
+ Status = ConfigRouting->ConfigToBlock(ConfigRouting, Configuration, Var, &Length, Progress);
+ while(Status == EFI_DEVICE_ERROR) //block not large enough
+ {
+ if(Var != NULL)
+ pBS->FreePool(Var);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, Length, &Var);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ VarSize = Length;
+ Status = ConfigRouting->ConfigToBlock(ConfigRouting, Configuration, Var, &Length, Progress);
+ }
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ pRS->SetVariable(Name, &Guid, Attributes, VarSize, Var);
+
+ pBS->FreePool(Var);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiAccessFormCallback(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/Hii.chm b/Core/CORE_DXE/UefiHii/Hii.chm
new file mode 100644
index 0000000..b2affb3
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/Hii.chm
Binary files differ
diff --git a/Core/CORE_DXE/UefiHii/HiiConfig.c b/Core/CORE_DXE/UefiHii/HiiConfig.c
new file mode 100644
index 0000000..8a8b10a
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiConfig.c
@@ -0,0 +1,1263 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiConfig.c 10 6/16/11 12:52p Artems $
+//
+// $Revision: 10 $
+//
+// $Date: 6/16/11 12:52p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiConfig.c $
+//
+// 10 6/16/11 12:52p Artems
+// Bugfix: Handle situation when string passed to BlockToConfig function
+// doesn't have standard header
+//
+// 9 5/13/11 5:17p Artems
+// Function CompareGuid (native EdkII) renamed to HiiCompareGuid to avoid
+// collusion
+//
+// 8 5/09/11 6:40p Artems
+// Bugfix: Handle situation when config string passed to ConfigToBlock
+// function doesn't have standard header
+//
+// 7 1/25/11 3:26p Artems
+// EIP 47960 : Added functionality for ExportConfig function
+//
+// 6 11/05/10 5:17p Artems
+// EIP 46880: Fixed bug, where two functions referred to the same global
+// pointer
+//
+// 4 10/01/10 4:36p Artems
+// Added service function StripValuePattern
+//
+// 2 12/03/09 6:02p Artems
+// SCT test bug fix
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HiiConfig.c
+//
+// Description: Hii Config Routing protocol implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+
+const NAME_PATTERN GuidPattern = { 10, L"GUID=" };
+const NAME_PATTERN NamePattern = { 10, L"NAME=" };
+const NAME_PATTERN PathPattern = { 10, L"PATH=" };
+const NAME_PATTERN AltCfgPattern = { 14, L"ALTCFG=" };
+const NAME_PATTERN OffsetPattern = { 14, L"OFFSET=" };
+const NAME_PATTERN WidthPattern = { 12, L"WIDTH=" };
+const NAME_PATTERN ValuePattern = { 12, L"VALUE=" };
+
+const CHAR16 HexDigit[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
+ L'8', L'9', L'a', L'b', L'c', L'd', L'e', L'f' };
+
+EFI_GUID HiiConfigAccessProtocolGuid = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID;
+
+#define INITIAL_RESULT_STRING_SIZE 0x1000
+
+
+
+//**************************** Protocol functions implementation ***************************
+
+EFI_STATUS HiiExtractConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Request1,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+)
+{
+ EFI_STRING ConfigString;
+ EFI_STRING ErrorPointer;
+ EFI_STRING ResultPointer;
+ BOOLEAN LastString = FALSE;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_HANDLE Handle;
+ UINTN ProgressMarker = 0;
+ UINTN Gap;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_STRING Request = Request1;
+ RESULT_BLOCK Result;
+
+ if(Progress == NULL || Results == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(Request == NULL)
+ {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(!CheckPattern(Request, &GuidPattern))
+ {
+ *Progress = Request;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = InitResultBlock(&Result);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ do
+ {
+ Status = ExtractConfigString(Request, &Index, &ConfigString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(ConfigString != NULL)
+ {
+ Status = FindDeviceHandle(ConfigString, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Request[ProgressMarker];
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Request[ProgressMarker];
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = ConfigAccess->ExtractConfig(ConfigAccess, ConfigString,
+ &ErrorPointer, &ResultPointer);
+ if(EFI_ERROR(Status))
+ {
+ Gap = (UINTN)(ErrorPointer - ConfigString); //determine offset of error
+ pBS->FreePool(ConfigString);
+ *Progress = &Request[ProgressMarker + Gap];
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ ProgressMarker += Index; //shift to next config string
+ Request += Index;
+ pBS->FreePool(ConfigString);
+ Status = CollectResults(ResultPointer, 0, &Result);
+ if (EFI_ERROR(Status))
+ return Status;
+ pBS->FreePool(ResultPointer);
+ }
+ else //now we process last request
+ {
+ LastString = TRUE;
+ Status = FindDeviceHandle(Request, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ *Progress = Request;
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ *Progress = Request;
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = ConfigAccess->ExtractConfig(ConfigAccess, Request,
+ &ErrorPointer, &ResultPointer);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = ErrorPointer;
+ *Results = Result.ResultString;
+ return Status;
+ }
+ Status = CollectResults(ResultPointer, 0, &Result);
+ if (EFI_ERROR(Status))
+ return Status;
+ pBS->FreePool(ResultPointer);
+ }
+ } while(!LastString);
+
+ *Results = Result.ResultString;
+
+//set Progress to null-terminator
+ Index = StrSize16(Request) / 2;
+ *Progress = &Request[Index - 1];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS Hii21ExportConfigHelper (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+);
+
+EFI_STATUS HiiExportConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+)
+{
+ if(Results == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ return Hii21ExportConfigHelper (This, Results);
+}
+
+EFI_STATUS HiiRouteConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration1,
+ OUT EFI_STRING *Progress
+)
+{
+ EFI_STRING ConfigString;
+ EFI_STRING ErrorPointer;
+ BOOLEAN LastString = FALSE;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_HANDLE Handle;
+ UINTN ProgressMarker = 0;
+ UINTN Gap;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_STRING Configuration = Configuration1;
+
+ if(Progress == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(Configuration == NULL)
+ {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(!CheckPattern(Configuration, &GuidPattern))
+ {
+ *Progress = Configuration;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ do
+ {
+ Status = ExtractConfigString(Configuration, &Index, &ConfigString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(ConfigString != NULL)
+ {
+ Status = FindDeviceHandle(ConfigString, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Configuration[ProgressMarker];
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Configuration[ProgressMarker];
+ return Status;
+ }
+
+ Status = ConfigAccess->RouteConfig(ConfigAccess, ConfigString, &ErrorPointer);
+ if(EFI_ERROR(Status))
+ {
+ Gap = (UINTN)(ErrorPointer - ConfigString); //determine offset of error
+ pBS->FreePool(ConfigString);
+ *Progress = &Configuration[ProgressMarker + Gap];
+ return Status;
+ }
+
+ ProgressMarker += Index; //shift to next config string
+ Configuration += Index;
+ pBS->FreePool(ConfigString);
+ }
+ else //now we process last cofiguration
+ {
+ LastString = TRUE;
+ Status = FindDeviceHandle(Configuration, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ *Progress = Configuration;
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ *Progress = Configuration;
+ return Status;
+ }
+
+ Status = ConfigAccess->RouteConfig(ConfigAccess, Configuration, &ErrorPointer);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = ErrorPointer;
+ return Status;
+ }
+ }
+ } while(!LastString);
+
+//set Progress to null-terminator
+ Index = StrSize16(Configuration) / 2;
+ *Progress = &Configuration[Index - 1];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiBlockToConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigRequest,
+ IN CONST UINT8 *Block,
+ IN CONST UINTN BlockSize,
+ OUT EFI_STRING *Config,
+ OUT EFI_STRING *Progress
+)
+{
+ UINTN ProgressMarker;
+ UINTN i = 0;
+ UINTN Start;
+ UINT32 Offset;
+ UINT32 Width;
+ UINT32 ConfigStringSize;
+ EFI_STATUS Status;
+ RESULT_BLOCK Result;
+
+ if(Progress == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(ConfigRequest == NULL || Block == NULL || Config == NULL )
+ {
+ *Progress = ConfigRequest;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConfigStringSize = StrSize16(ConfigRequest) / 2;
+
+//Prepare result buffer for output
+ Status = InitResultBlock(&Result);
+ if (EFI_ERROR(Status))
+ return Status;
+
+//find start of OFFSET/WIDTH/VALUE block
+ if(!CheckPattern(ConfigRequest, &OffsetPattern)) { //for BlockToConfig function ConfigResp is allowed not to have standard header GUID=...NAME=.
+ do
+ {
+ while((ConfigRequest[i] != L'&') && (ConfigRequest[i] != 0))
+ i++;
+
+ if(ConfigRequest[i] == 0)
+ {
+ *Progress = ConfigRequest;
+ pBS->FreePool(Result.ResultString);
+ return EFI_NOT_FOUND;
+ }
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigRequest[i], &OffsetPattern))
+ break;
+ } while(1);
+ }
+
+ Status = CollectResults(ConfigRequest, i, &Result); //copy header
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+
+ do
+ {
+ ProgressMarker = i - 1; //set ProgressMarker to '&'
+
+ Start = i;
+ Status = GetPatternValue(ConfigRequest, &i, &OffsetPattern, &Offset);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigRequest[ProgressMarker];
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ else
+ {
+ Status = CollectResults(&ConfigRequest[Start], i - Start, &Result); //copy header
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ }
+
+ Start = i;
+ Status = GetPatternValue(ConfigRequest, &i, &WidthPattern, &Width);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigRequest[ProgressMarker];
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ else
+ {
+ Status = CollectResults(&ConfigRequest[Start], i - Start, &Result); //copy header
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ }
+
+ if(BlockSize < (Offset + Width))
+ {
+ pBS->FreePool(Result.ResultString);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = CollectValueResults(&Block[Offset], Width, &Result);
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+
+ } while(i < ConfigStringSize);
+
+ *Progress = &ConfigRequest[ConfigStringSize - 1]; //set Progress to null-terminator
+ *Config = Result.ResultString;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiConfigToBlock (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN OUT CONST UINT8 *Block,
+ IN OUT UINTN *BlockSize,
+ OUT EFI_STRING *Progress
+)
+{
+ UINTN ProgressMarker;
+ UINTN i = 0;
+ UINT32 Offset;
+ UINT32 Width;
+ UINT32 ConfigStringSize;
+ EFI_STATUS Status;
+
+ if(Progress == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(ConfigResp == NULL || BlockSize == NULL )
+ {
+ *Progress = ConfigResp;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(Block == NULL && *BlockSize != NULL )
+ {
+ *Progress = ConfigResp;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConfigStringSize = StrSize16(ConfigResp) / 2;
+
+//find start of OFFSET/WIDTH/VALUE block
+ if(!CheckPattern(ConfigResp, &OffsetPattern)) { //for ConfigToBlock function ConfigResp is allowed not to have standard header GUID=...NAME=.
+ do {
+ while((ConfigResp[i] != L'&') && (ConfigResp[i] != 0))
+ i++;
+
+ if(ConfigResp[i] == 0) {
+//TODO: should it be like this???
+//Intel's style - if there is no OFFSET/WIDTH/VALUE blocks - return EFI_SUCCESS
+/*
+ *Progress = ConfigResp;
+ return EFI_NOT_FOUND;
+*/
+ *Progress = &ConfigResp[i];
+ return EFI_SUCCESS;
+ }
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigResp[i], &OffsetPattern))
+ break;
+ } while(1);
+ }
+
+ do
+ {
+ ProgressMarker = i - 1; //set ProgressMarker to '&'
+
+ Status = GetPatternValue(ConfigResp, &i, &OffsetPattern, &Offset);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigResp[ProgressMarker];
+ return Status;
+ }
+
+ Status = GetPatternValue(ConfigResp, &i, &WidthPattern, &Width);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigResp[ProgressMarker];
+ return Status;
+ }
+
+//provided block is too small to accumulate value
+ if(*BlockSize < (Offset + Width))
+ {
+ *BlockSize = Offset + Width;
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = GetStringValue(ConfigResp, &i, &Block[Offset], Width);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigResp[ProgressMarker];
+ return Status;
+ }
+
+ } while(i < ConfigStringSize);
+
+ *BlockSize = Offset + Width - 1; //set index of last updated byte
+ *Progress = &ConfigResp[ConfigStringSize - 1]; //set Progress to null-terminator
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiGetAltConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId,
+ OUT EFI_STRING *AltCfgResp
+)
+{
+ BOOLEAN LastString = FALSE;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN StrSize;
+ EFI_STRING ConfigString = ConfigResp;
+
+
+ if(ConfigResp == NULL || AltCfgResp == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(!CheckPattern(ConfigString, &GuidPattern))
+ return EFI_INVALID_PARAMETER;
+
+ do {
+ Status = ExtractConfigString(ConfigString, &Index, AltCfgResp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(*AltCfgResp != NULL) {
+ Status = CheckAltCfg(*AltCfgResp, Guid, Name, DevicePath, AltCfgId);
+ if(!EFI_ERROR(Status))
+ return Status;
+
+ ConfigString += Index;
+ pBS->FreePool(*AltCfgResp);
+ } else {
+ LastString = TRUE;
+ StrSize = StrSize16(ConfigString);
+ Status = pBS->AllocatePool(EfiBootServicesData, StrSize, AltCfgResp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(*AltCfgResp, ConfigString, StrSize);
+ Status = CheckAltCfg(*AltCfgResp, Guid, Name, DevicePath, AltCfgId);
+ if(EFI_ERROR(Status))
+ pBS->FreePool(*AltCfgResp);
+
+ return Status;
+
+ }
+ } while(!LastString);
+
+ return EFI_NOT_FOUND;
+}
+
+// *************************** Service functions (not for public use) **********************
+
+VOID StringToBlock(
+ IN CHAR16 *String,
+ IN UINTN StringSize,
+ OUT UINT8 *Block)
+{
+ UINT8 LowNibble, HiNibble;
+ UINTN i, j;
+
+ j = 0;
+
+ for(i = 0; i < StringSize; i += 2)
+ {
+ if(i == StringSize - 1) { //odd number need to fill with zeroes
+ HiNibble = 0;
+ LowNibble = HexValue((UINT8)String[i]);
+ } else {
+ HiNibble = HexValue((UINT8)String[i]);
+ LowNibble = HexValue((UINT8)String[i + 1]);
+ }
+ Block[j] = (HiNibble << 4) | LowNibble;
+ j++;
+ }
+}
+
+BOOLEAN CheckIfHexDigit(CHAR16 Char)
+{
+ if(Char < 0x30 || Char > 0x66)
+ return FALSE;
+
+ if(Char > 0x39 && Char < 0x41)
+ return FALSE;
+
+ if(Char > 0x46 && Char < 0x61)
+ return FALSE;
+
+ return TRUE;
+}
+
+UINT8 HexValue(CHAR8 Char)
+{
+ if(Char >= 0x30 && Char <= 0x39) //symbols 0...9
+ return Char - 0x30;
+
+ if(Char >= 0x41 && Char <= 0x46) //symbols A...F
+ return Char - 0x37;
+
+ return Char - 0x57; //symbols a...f
+}
+
+
+UINT32 GetValue(CHAR16 *String, UINTN Start, UINTN End)
+{
+ UINT32 Result = 0;
+ UINTN i;
+ UINT8 Nibble;
+ UINT8 NibbleCount = 0;
+
+ for(i = Start; i < End; i++)
+ {
+ Nibble = HexValue((UINT8) String[i]);
+ if(Nibble == 0 && NibbleCount == 0) //skip leading zeros
+ continue;
+
+ if(NibbleCount >= 8) //provided value exceed 4 bytes
+ return 0xffffffff;
+
+ Result <<= 4;
+ Result |= Nibble;
+ NibbleCount++;
+ }
+ return Result;
+}
+
+EFI_STATUS GetStringValue(
+ CHAR16 *String,
+ UINTN *Index,
+ UINT8 *Output,
+ UINT32 Width)
+{
+ EFI_STATUS Status;
+ UINTN Start;
+ UINTN i;
+ UINT8 *Result;
+ UINTN HexSymbolsCount;
+ UINT8 SmallBuffer[20];
+ UINTN ResultBufferSize = 20;
+
+ Start = *Index;
+
+ if(!CheckPattern(&String[Start], &ValuePattern))
+ return EFI_INVALID_PARAMETER;
+
+ Start += ValuePattern.Length / 2;
+ i = Start;
+
+ while((String[i] != L'&') && (String[i] != 0)) {
+ if(!CheckIfHexDigit(String[i]))
+ return EFI_INVALID_PARAMETER;
+ i++;
+ }
+
+ HexSymbolsCount = i - Start;
+
+ if(Width > 20) {
+ Status = pBS->AllocatePool(EfiBootServicesData, Width, &Result);
+ if(EFI_ERROR(Status))
+ return Status;
+ ResultBufferSize = Width;
+ } else {
+ Result = SmallBuffer;
+ }
+
+ MemSet(Result, ResultBufferSize, 0);
+ StringToBlock(&String[Start], HexSymbolsCount, Result);
+
+//now write the result swapped(INTEL's style)
+ if(Width > 1)
+ WriteSwappedBuffer(Output, Result, Width);
+ else
+ *Output = *Result;
+
+ if(Width > 20)
+ pBS->FreePool(Result);
+
+ i++; //skip delimiter
+
+ *Index = i;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS GetPatternValue(
+ CHAR16 *String,
+ UINTN *Index,
+ NAME_PATTERN *Pattern,
+ UINT32 *Value)
+{
+ UINT32 Result;
+ UINTN Start;
+ UINTN i;
+ BOOLEAN EndPattern = FALSE;
+
+ if(Pattern->Tag[0] == L'V' || Pattern->Tag[0] == L'W')
+ EndPattern = TRUE;
+
+ Start = *Index;
+
+ if(!CheckPattern(&String[Start], Pattern))
+ return EFI_INVALID_PARAMETER;
+
+ Start += Pattern->Length / 2;
+ i = Start;
+
+ while((String[i] != L'&') && (String[i] != 0))
+ {
+ if(!CheckIfHexDigit(String[i]))
+ return EFI_INVALID_PARAMETER;
+ i++;
+ }
+
+ if(String[i] == 0 && !EndPattern) //unexpected end of string
+ return EFI_INVALID_PARAMETER;
+
+ Result = GetValue(String, Start, i);
+ i++; //skip delimiter
+
+ *Value = Result;
+ *Index = i;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS FindDeviceHandle(
+ IN CHAR16 *ConfigString,
+ OUT EFI_HANDLE *Handle)
+{
+ UINTN i = 0;
+ UINTN DpLength;
+ UINT8 *DevicePath;
+ EFI_STATUS Status;
+
+//scan config string to find PATH pattern
+ do
+ {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0)
+ return EFI_NOT_FOUND;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &PathPattern))
+ break;
+ } while(1);
+
+//if we get here, we have pointer set on PATH pattern
+ Status = ExtractDevicePath(&ConfigString[i], &DevicePath, &DpLength);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = SearchDevicePath(DevicePath, DpLength, Handle);
+ pBS->FreePool(DevicePath);
+
+ return Status;
+}
+
+EFI_STATUS ExtractDevicePath(CHAR16 *ConfigString, UINT8 **DevicePath, UINTN *DpLength)
+{
+ EFI_STATUS Status;
+ UINTN Length = 0;
+ UINTN i = 5; //set pointer to skip first four symbols "PATH="
+
+ while(CheckIfHexDigit(ConfigString[i])) //determine device path length in characters
+ {
+ Length++;
+ i++;
+ }
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ (Length / 2),
+ DevicePath);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ StringToBlock(&ConfigString[5], Length, *DevicePath);
+ *DpLength = Length / 2;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS SearchDevicePath(UINT8 *DevicePath, UINTN DpLength, EFI_HANDLE *Handle)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) PrivateData.PackList.pHead;
+ PACKAGE_LINK *PackageLink;
+
+ while(Record != NULL)
+ {
+ PackageLink = (PACKAGE_LINK *) Record->PackageList.pHead;
+ while(PackageLink != NULL)
+ {
+ if(PackageLink->Package.Type == EFI_HII_PACKAGE_DEVICE_PATH)
+ {
+ if(CheckDevicePath(DevicePath, DpLength, &PackageLink->Package))
+ {
+ *Handle = Record->DriverHandle;
+ return EFI_SUCCESS;
+ }
+ }
+ PackageLink = (PACKAGE_LINK *)PackageLink->Link.pNext;
+ }
+ Record = (PACKAGE_LIST_RECORD *)Record->Link.pNext;
+ }
+ return EFI_NOT_FOUND;
+}
+
+static BOOLEAN CheckDevicePath(
+ IN UINT8 *DevicePath,
+ IN UINTN DpLength,
+ IN EFI_HII_PACKAGE_HEADER *Package)
+{
+ UINTN Length;
+ UINT8 *Dp = (UINT8 *)Package;
+
+ Dp += sizeof(EFI_HII_PACKAGE_HEADER);
+
+ Length = Package->Length - sizeof(EFI_HII_PACKAGE_HEADER);
+ if(Length != DpLength)
+ return FALSE;
+ if(MemCmp(DevicePath, Dp, Length))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+EFI_STATUS ExtractConfigString(CHAR16 *String, UINTN *NextIndex, CHAR16 **NewString)
+{
+ EFI_STATUS Status;
+ UINTN i = 0;
+ CHAR16 *Eos;
+
+//scan config string to find next GUID pattern
+ do
+ {
+ while((String[i] != L'&') && (String[i] != 0))
+ i++;
+
+ if(String[i] == 0)
+ {
+ *NewString = NULL; //config string contains only one string
+ return EFI_SUCCESS;
+ }
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&String[i], &GuidPattern))
+ break;
+ } while(1);
+
+//as we are here i points to next config string
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * i,
+ NewString);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(*NewString, String, (i - 1) * 2);
+ Eos = *NewString;
+ Eos[i - 1] = 0; //put null terminator
+
+ *NextIndex = i;
+ return EFI_SUCCESS;
+}
+
+BOOLEAN CheckPattern(CHAR16 *String, NAME_PATTERN *Pattern)
+{
+ if(MemCmp(String, Pattern->Tag, Pattern->Length))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+EFI_STATUS CollectResults(CHAR16 *Result, UINTN Symbols, RESULT_BLOCK *ResultBlock)
+{
+ EFI_STATUS Status;
+ UINTN StrSize;
+ CHAR16 *Helper;
+
+ StrSize = (Symbols != 0) ? Symbols : StrSize16(Result) / 2; //we need size in CHAR16, not bytes
+
+ if(ResultBlock->MaxResultStringSize < (StrSize + ResultBlock->CurrentSize))
+ {
+ Status = ReallocResultString((StrSize + ResultBlock->CurrentSize) * 2, ResultBlock);
+ if (EFI_ERROR(Status))
+ return Status;
+ }
+
+ Helper = ResultBlock->ResultString;
+ if(ResultBlock->CurrentSize != 0) //we have to change null-terminator to '&' symbol
+ Helper[ResultBlock->CurrentSize - 1] = L'&';
+
+ MemCpy(&Helper[ResultBlock->CurrentSize], Result, StrSize * sizeof(CHAR16));
+ ResultBlock->CurrentSize += StrSize;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS ReallocResultString(UINTN NewSize, RESULT_BLOCK *ResultBlock)
+{
+ CHAR16 *Pointer;
+ EFI_STATUS Status;
+
+ ResultBlock->MaxResultStringSize = NewSize;
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * ResultBlock->MaxResultStringSize,
+ &Pointer);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(Pointer, ResultBlock->ResultString, ResultBlock->CurrentSize * sizeof(CHAR16));
+ pBS->FreePool(ResultBlock->ResultString);
+ ResultBlock->ResultString = Pointer;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS CollectValueResults(UINT8* Value, UINT32 Width, RESULT_BLOCK *ResultBlock)
+{
+ CHAR16 ValueHeader[] = L"VALUE=";
+ UINT32 i;
+ UINT8 Nibble;
+ EFI_STATUS Status;
+ CHAR16 *ValueString;
+ CHAR16 *Ptr;
+ UINTN StringSize;
+
+//first determine necessary string size, including null-terminator in CHAR16 symbols
+ StringSize = Width * 2 + 6 + 1; //each byte requires two symbols plus &VALUE= size plus null terminator
+
+ Status = pBS->AllocatePool(EfiBootServicesData, StringSize * 2, &ValueString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+//copy header
+ MemCpy(ValueString, ValueHeader, 12);
+ Ptr = ValueString + 6;
+
+//write value in reversed order
+ for(i = 0; i < Width; i++)
+ {
+ Nibble = Value[Width - i - 1] >> 4;
+ *Ptr++ = HexDigit[Nibble];
+ Nibble = Value[Width - i - 1] & 0xf;
+ *Ptr++ = HexDigit[Nibble];
+ }
+
+//set null-terminator
+ *Ptr = 0;
+ Status = CollectResults(ValueString, 0, ResultBlock);
+ pBS->FreePool(ValueString);
+ return Status;
+}
+
+VOID WriteSwappedBuffer(
+ OUT UINT8 *Output,
+ IN UINT8 *Input,
+ IN UINTN Size)
+{
+ UINTN i;
+
+ for(i = 0; i < Size; i++)
+ Output[i] = Input[Size - i - 1];
+}
+
+EFI_STATUS CheckAltCfg (
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId
+)
+{
+ EFI_STATUS Status;
+ UINTN i = 0;
+ UINTN j;
+ UINT32 Size;
+ UINT32 CfgId;
+
+//scan config string to find ALTCFG pattern
+ do {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0) //ALTCFG pattern not found
+ break;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &AltCfgPattern))
+ break;
+ } while(1);
+
+ if(ConfigString[i] == 0 && AltCfgId != NULL) //we have current config but needed alt one
+ return EFI_NOT_FOUND;
+
+ if(ConfigString[i] != 0 && AltCfgId == NULL) //we have alt config but needed current one
+ return EFI_NOT_FOUND;
+
+ if(ConfigString[i] != 0 && AltCfgId != NULL) {
+ j = i;
+ Status = GetPatternValue(ConfigString, &j, &AltCfgPattern, &CfgId);
+ if(EFI_ERROR(Status) || *AltCfgId != (UINT16)CfgId)
+ return EFI_NOT_FOUND; //we have alt config, but it's not matched
+
+//if we're here alt config is matched
+//we need to remove "ALTCFG=XXXX" from string as per spec but SCT expects "ALTCFG=" pattern in output string
+
+ //j already points to the next pattern
+ Size = StrSize16(&ConfigString[j]);
+ MemCpy(&ConfigString[i], &ConfigString[j], Size);
+
+ }
+
+ if(Guid != NULL && !HiiCompareGuid(ConfigString, Guid))
+ return EFI_NOT_FOUND; //guid not matched
+
+ if(Name != NULL && !CompareName(ConfigString, Name))
+ return EFI_NOT_FOUND; //name not matched
+
+ if(DevicePath != NULL && !CompareDevicePath(ConfigString, DevicePath))
+ return EFI_NOT_FOUND; //DevicePath not matched
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN HiiCompareGuid(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid
+)
+{
+ CHAR16 *Pointer = ConfigString;
+ UINTN Length;
+ EFI_GUID AltGuid;
+ EFI_GUID *VarGuid = Guid;
+
+ if(!CheckPattern(ConfigString, &GuidPattern))
+ return FALSE;
+
+ Pointer += 5; //skip "GUID=" pattern
+ Length = 32; //length of guid in symbols
+ StringToBlock(Pointer, Length, (UINT8 *)&AltGuid);
+
+ return !guidcmp(VarGuid, &AltGuid);
+}
+
+BOOLEAN CompareName(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_STRING Name
+)
+{
+ CHAR16 *Pointer = ConfigString;
+ UINTN Length;
+ CHAR16 AltName[80];
+ EFI_STRING VarName = Name;
+ UINTN i = 0;
+
+ do {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0) //NAME pattern not found
+ return FALSE;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &NamePattern))
+ break;
+ } while(1);
+
+ Pointer = &ConfigString[i];
+ Pointer += 5; //skip "NAME=" pattern
+ Length = 80; //length of name buffer
+ StringToChar16(Pointer, &Length, AltName);
+
+ return !StrCmp16(VarName, AltName);
+}
+
+BOOLEAN CompareDevicePath(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ UINTN Length;
+ EFI_DEVICE_PATH_PROTOCOL *AltDevicePath;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *VarDp = DevicePath;
+ BOOLEAN Result;
+ UINTN i = 0;
+
+ do {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0) //PATH pattern not found
+ return FALSE;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &PathPattern))
+ break;
+ } while(1);
+
+ Status = ExtractDevicePath(&ConfigString[i], (UINT8 **)&AltDevicePath, &Length);
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ Result = !DPCmp(VarDp, AltDevicePath);
+ pBS->FreePool(AltDevicePath);
+ return Result;
+}
+
+VOID StringToChar16(
+ IN CHAR16 *String,
+ IN OUT UINTN *Size,
+ OUT CHAR16 *Block
+)
+{
+ UINTN i, j;
+
+ i = 0;
+ j = 0;
+
+ while( CheckIfHexDigit(String[i]) && CheckIfHexDigit(String[i + 1]) &&
+ CheckIfHexDigit(String[i + 2]) && CheckIfHexDigit(String[i + 3]) &&
+ j < *Size - 1 )
+ {
+ Block[j] = HexValue((UINT8)String[i]) & 0x000f;
+ Block[j] <<= 4;
+ Block[j] |= HexValue((UINT8)String[i + 1]);
+ Block[j] <<= 4;
+ Block[j] |= HexValue((UINT8)String[i + 2]);
+ Block[j] <<= 4;
+ Block[j] |= HexValue((UINT8)String[i + 3]);
+
+ i += 4;
+ j++;
+ }
+ *Size = j; //number of words processed
+ Block[j] = 0; //put null-terminator
+}
+
+VOID StripValuePattern(
+ IN OUT EFI_STRING String,
+ IN UINTN Size
+)
+{
+ EFI_STATUS Status;
+ EFI_STRING NewString;
+ UINTN i = 0;
+ UINTN j = 0;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, &NewString);
+
+ while(String[i] != 0) {
+ if(String[i] == L'&') {
+ if(CheckPattern(&String[i + 1], &ValuePattern)) {
+ i++;
+ while((String[i] != L'&') && (String[i] != 0))
+ i++;
+ if(String[i] == 0)
+ break;
+ }
+ }
+
+ NewString[j++] = String[i++];
+ }
+
+ NewString[j] = 0;
+ MemCpy(String, NewString, (j + 1) * 2);
+ pBS->FreePool(NewString);
+}
+
+EFI_STATUS InitResultBlock(
+ IN OUT RESULT_BLOCK *ResultBlock
+)
+{
+ EFI_STATUS Status;
+ ResultBlock->MaxResultStringSize = INITIAL_RESULT_STRING_SIZE;
+ ResultBlock->CurrentSize = 0;
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * ResultBlock->MaxResultStringSize,
+ &(ResultBlock->ResultString));
+ return Status;
+}
+
+#pragma warning (default : 4090)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/UefiHii/HiiDatabase.c b/Core/CORE_DXE/UefiHii/HiiDatabase.c
new file mode 100644
index 0000000..fef10c6
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiDatabase.c
@@ -0,0 +1,1814 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiDatabase.c 14 5/21/12 4:55p Artems $
+//
+// $Revision: 14 $
+//
+// $Date: 5/21/12 4:55p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiDatabase.c $
+//
+// 14 5/21/12 4:55p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+//
+// 13 1/05/12 5:05p Artems
+// EIP 76735: Font FFS file is not loaded in framework mode, when in
+// nested FV
+//
+// 12 5/13/11 6:14p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 11 5/05/11 4:13p Artems
+// Add signal "layout changed" event if current layout is deleted
+//
+// 10 1/05/11 12:41p Artems
+// EIP 50995: Added checking of driver handle before adding packages to
+// HII database
+//
+// 9 6/23/10 5:06p Artems
+// Restored fix killed by previous check-in
+//
+// 8 6/10/10 4:35p Artems
+// EIP 39692 fix - call notification after adding package
+//
+// 7 3/09/10 6:41p Artems
+// EIP 35698: Removed DeleteSimpleFonts call
+//
+// 6 2/03/10 10:28a Artems
+// Fixed bug in HiiExportPacks function
+//
+// 5 1/29/10 5:43p Artems
+// EIP 34553 Updated function ExportPackageLists to support NULL pointer
+// as input
+//
+// 4 1/07/10 12:29p Felixp
+// Code updated to use library instances of the Protocol GUID variables.
+//
+// 3 12/04/09 11:16a Artems
+// Remove keyboard layout functionality added
+//
+// 2 11/09/09 11:51a Felixp
+// New package list function is updated to report error when package list
+// with existing GUID is passed.
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiDatabase.c
+//
+// Description: Hii database protocol functions implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+#include <Protocol/DevicePath.h>
+#include <Protocol/HiiUtilities.h>
+
+extern HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol;
+extern DBE_KEY_FIELD StringDbKeyField;
+
+EFI_GUID NullGuid = NULL_GUID;
+
+SIMPLE_FONT DefaultFont[0x10000];
+
+HII_DATABASE_PRIVATE_DATA PrivateData =
+{
+//Database protocol members
+ {
+ HiiNewPack,
+ HiiRemovePack,
+ HiiUpdatePack,
+ HiiListPacks,
+ HiiExportPacks,
+ HiiRegisterNotify,
+ HiiUnregisterNotify,
+ HiiFindKeyboardLayouts,
+ HiiGetKeyboardLayout,
+ HiiSetKeyboardLayout,
+ HiiGetPackageListHandle
+ },
+//String protocol members
+ {
+ HiiNewString,
+ AmiHiiGetString, //EdkII compatibility library already has function HiiGetString
+ AmiHiiSetString, //EdkII compatibility library already has function HiiSetString
+ HiiGetLanguages,
+ HiiGetSecondLanguages
+ },
+//Font protocol members
+ {
+ HiiStringToImage,
+ HiiStringIdToImage,
+ HiiGetGlyph,
+ HiiGetFontInfo
+ },
+//Config Routing protocol members
+ {
+ HiiExtractConfig,
+ HiiExportConfig,
+ HiiRouteConfig,
+ HiiBlockToConfig,
+ HiiConfigToBlock,
+ HiiGetAltConfig
+ },
+// Linked list of package lists
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Linked list of notify functions
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Linked list of keyboard layouts
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Linked list of global fonts
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Current KeyLayout
+ NULL
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiDatabaseEntryPoint
+//
+// Description:
+// This function is HII driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, HII protocols installed
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE HiiHandle = NULL;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ pBS = SystemTable->BootServices;
+
+ //install HII Protocols
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &HiiHandle,
+ &gEfiHiiDatabaseProtocolGuid,
+ &(PrivateData.DatabaseProtocol),
+ &gEfiHiiStringProtocolGuid,
+ &(PrivateData.StringProtocol),
+ &gEfiHiiFontProtocolGuid,
+ &(PrivateData.FontProtocol),
+ &gEfiHiiConfigRoutingProtocolGuid,
+ &(PrivateData.ConfigRoutingProtocol),
+ &gHiiUtilitiesProtocolGuid,
+ &HiiUtilitiesProtocol,
+ NULL);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiBdsEntryPoint
+//
+// Description:
+// This function is HII driver BDS entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, system font is loaded
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiBdsEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE HiiHandle = NULL;
+
+ InitAmiLib(ImageHandle,SystemTable);
+ Status = LoadSystemFont();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetPackHandle
+//
+// Description:
+// This function is HII Database protocol function GetPackageHandle implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageListHandle - PackageList handle
+// OUT EFI_HANDLE *DriverHandle - Pointer, where to store found Driver handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - PackageListHandle is invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetPackageListHandle (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageListHandle,
+ OUT EFI_HANDLE *DriverHandle)
+{
+ PACKAGE_LIST_RECORD *Record;
+
+ Record = (PACKAGE_LIST_RECORD *) PackageListHandle;
+
+ if (DriverHandle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_INVALID_PARAMETER;
+
+ *DriverHandle = Record->DriverHandle;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiRegisterNotify
+//
+// Description:
+// This function is HII Database protocol function RegisterPackageNotify implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN UINT8 PackageType - Package type
+// IN EFI_GUID *PackageGuid - Pointer to Package guid
+// IN EFI_HII_DATABASE_NOTIFY PackageNotifyFn - Function to be called
+// IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType - Notify type
+// OUT EFI_HANDLE *NotifyHandle - Pointer, where to store created Notify handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - PackageGuid is not NULL and PackageType is not Guid package
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiRegisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
+ OUT EFI_HANDLE *NotifyHandle)
+{
+ NOTIFY_RECORD *NewRecord;
+
+ if (NotifyHandle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
+ (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL))
+ return EFI_INVALID_PARAMETER;
+
+ NewRecord = NewNotifyRecord();
+ if (NewRecord == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ if(PackageType == EFI_HII_PACKAGE_TYPE_GUID)
+ NewRecord->PackageGuid = *PackageGuid;
+ else
+ NewRecord->PackageGuid = NullGuid;
+
+ NewRecord->PackageType = PackageType;
+ NewRecord->NotifyType = NotifyType;
+ NewRecord->PackageNotifyFn = PackageNotifyFn;
+
+ DListAdd(&(PrivateData.NotifyList), (DLINK *) NewRecord);
+
+ if(NotifyHandle != NULL)
+ *NotifyHandle = NewRecord;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiUnregisterNotify
+//
+// Description:
+// This function is HII Database protocol function UnregisterPackageNotify implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HANDLE NotificationHandle - Notify handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - NotificationHandle is not valid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiUnregisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle)
+{
+ NOTIFY_RECORD *Record;
+
+ Record = (NOTIFY_RECORD *) NotificationHandle;
+
+ if (Record->Signature != NOTIFY_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ DListDelete(&(PrivateData.NotifyList), (DLINK *) Record);
+ Record->Signature = 0xffffffff; //invalidate signature to avoid future use of this memory
+ pBS->FreePool(Record);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiRemovePack
+//
+// Description:
+// This function is HII Database protocol function RemovePackageList implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE Handle - Handle of package list to be removed from database
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle is not valid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiRemovePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ PACKAGE_LINK *Package;
+ PACKAGE_LINK *Link;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ Package = (PACKAGE_LINK *) Record->PackageList.pHead;
+
+ while(Package != NULL)
+ {
+ Link = Package;
+ Package = (PACKAGE_LINK *) Package->Link.pNext;
+ RemovePackage(Handle, Link);
+ }
+
+ DListDelete(&(PrivateData.PackList), (DLINK *) Record);
+ Record->Signature = 0xffffffff; //invalidate signature to avoid future collisions
+ pBS->FreePool(Record);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiNewPack
+//
+// Description:
+// This function is HII Database protocol function NewPackageList implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_PACKAGE_LIST_HEADER *PackageList - Pointer to package list to be added to database
+// IN EFI_HANDLE DriverHandle - Driver handle
+// OUT EFI_HII_HANDLE *Handle - Pointer to EFI_HII_HANDLE where to store created handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle or PackageList is NULL
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiNewPack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ IN CONST EFI_HANDLE DriverHandle,
+ OUT EFI_HII_HANDLE *Handle)
+{
+ PACKAGE_LIST_RECORD *NewRecord;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DpProtocol;
+ UINT32 DpPackageSize;
+ EFI_HII_PACKAGE_HEADER *Buffer;
+
+ if((PackageList == NULL) || (Handle == NULL))
+ return EFI_INVALID_PARAMETER;
+
+ // Check the Package list GUID and DriverHandle to guarantee this GUID is unique in database.
+ if(CheckIfPresent(&(PackageList->PackageListGuid), DriverHandle))
+ return EFI_ALREADY_STARTED; //package list already present
+
+ NewRecord = NewPackageListRecord();
+ if(NewRecord == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ NewRecord->DriverHandle = DriverHandle;
+ NewRecord->Guid = PackageList->PackageListGuid;
+
+ Status = AddPackages((EFI_HII_HANDLE)NewRecord, PackageList, FALSE);
+ if(EFI_ERROR(Status) && (NewRecord->PackageList.Size != 0))
+ {
+ DeleteList(&(NewRecord->PackageList));
+ pBS->FreePool(NewRecord);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+
+ Status = pBS->HandleProtocol(DriverHandle, &gEfiDevicePathProtocolGuid, &DpProtocol);
+ if(!EFI_ERROR(Status))
+ {
+ DpPackageSize = (UINT32)DPLength(DpProtocol);
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ DpPackageSize + sizeof(EFI_HII_PACKAGE_HEADER),
+ &Buffer);
+ if (EFI_ERROR(Status))
+ {
+ DeleteList(&(NewRecord->PackageList));
+ pBS->FreePool(NewRecord);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Buffer->Type = EFI_HII_PACKAGE_DEVICE_PATH;
+ Buffer->Length = DpPackageSize + sizeof(EFI_HII_PACKAGE_HEADER);
+
+ (UINT8 *)Buffer += sizeof(EFI_HII_PACKAGE_HEADER);
+ MemCpy(Buffer, DpProtocol, DpPackageSize);
+ (UINT8 *)Buffer -= sizeof(EFI_HII_PACKAGE_HEADER);
+
+ Status = AddPackage((EFI_HII_HANDLE)NewRecord, Buffer, EFI_HII_DATABASE_NOTIFY_NEW_PACK);
+ if (EFI_ERROR(Status))
+ {
+ DeleteList(&(NewRecord->PackageList));
+ pBS->FreePool(NewRecord);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ pBS->FreePool(Buffer);
+ }
+
+ DListAdd(&(PrivateData.PackList), (DLINK *)NewRecord);
+ *Handle = NewRecord;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiListPacks
+//
+// Description:
+// This function is HII Database protocol function ListPackageLists implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN UINT8 PackageType - Package type
+// IN EFI_GUID *PackageGuid - Pointer to package guid
+// IN OUT UINTN *HandleBufferLength - Pointer to allocated buffer size value
+// OUT EFI_HII_HANDLE *Handle - Pointer to EFI_HII_HANDLE buffer where to store found handles
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - HandleBufferLength is NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+// EFI_NOT_FOUND - No handles found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiListPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN OUT UINTN *HandleBufferLength,
+ OUT EFI_HII_HANDLE *Handle)
+{
+ UINTN RequiredSize = 0;
+ UINT32 i, Count = 0;
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *List;
+ BOOLEAN InternalBuffer = TRUE;
+ BOOLEAN Found;
+ EFI_HII_HANDLE *MatchedHandles;
+
+ if(HandleBufferLength == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (*HandleBufferLength > 0 && Handle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
+ (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL))
+ return EFI_INVALID_PARAMETER;
+
+ List = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ if(PackageType == EFI_HII_PACKAGE_TYPE_ALL)
+ {
+ RequiredSize = sizeof(EFI_HII_HANDLE) * PrivateData.PackList.Size;
+
+ if(*HandleBufferLength < RequiredSize)
+ {
+ *HandleBufferLength = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ for(i = 0; i < PrivateData.PackList.Size; i++)
+ {
+ Handle[i] = List;
+ List = (PACKAGE_LIST_RECORD *)List->Link.pNext;
+ }
+ }
+ else
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_HII_HANDLE) * PrivateData.PackList.Size,
+ (VOID **)&MatchedHandles);
+ if(EFI_ERROR(Status))
+ InternalBuffer = FALSE;
+
+ //parsing package lists to find matches. If internal buffer present found handles will be
+ //stored to avoid repeat parsing
+ for(i = 0; i < PrivateData.PackList.Size; i++)
+ {
+ Found = FindAndRemovePackages(
+ (EFI_HII_HANDLE)List,
+ PackageType,
+ PackageGuid,
+ TRUE);
+ if(Found)
+ {
+ if(InternalBuffer)
+ MatchedHandles[Count] = (EFI_HII_HANDLE)List;
+ Count++;
+ }
+ List = (PACKAGE_LIST_RECORD *) List->Link.pNext;
+ }
+
+ if(Count == 0)
+ return EFI_NOT_FOUND;
+
+ RequiredSize = Count * sizeof(EFI_HII_HANDLE);
+
+ if(*HandleBufferLength < RequiredSize)
+ {
+ *HandleBufferLength = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if(InternalBuffer)
+ {
+ for(i = 0; i < Count; i++)
+ Handle[i] = MatchedHandles[i];
+ pBS->FreePool(MatchedHandles);
+ }
+ else
+ {
+ Count = 0;
+ for(i = 0; i < PrivateData.PackList.Size; i++)
+ {
+ Found = FindAndRemovePackages(
+ (EFI_HII_HANDLE)List,
+ PackageType,
+ PackageGuid,
+ TRUE);
+ if(Found)
+ {
+ Handle[Count] = (EFI_HII_HANDLE)List;
+ Count++;
+ }
+ List = (PACKAGE_LIST_RECORD *) List->Link.pNext;
+ }
+ }
+ }
+
+ *HandleBufferLength = RequiredSize;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiUpdatePack
+//
+// Description:
+// This function is HII Database protocol function UpdatePackageList implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE Handle - Handle of package list to be updated
+// IN EFI_HII_PACKAGE_LIST_HEADER *PackageList - Pointer to new Package list
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle is invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiUpdatePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ EFI_STATUS Status;
+
+ if (PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ Status = AddPackages(Handle, PackageList, TRUE);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiExportPacks
+//
+// Description:
+// This function is HII Database protocol function ExportPackageLists implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE Handle - Handle of package list to be exported
+// IN OUT UINTN *BufferSize - Pointer to export buffer size value
+// OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer - Pointer to buffer where to export package lists
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle is invalid
+// EFI_BUFFER_TOO_SMALL - Export buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiExportPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer)
+{
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ UINT32 Size = 0;
+ UINTN PackageListSize;
+ UINTN RequiredSize = 0;
+ UINTN MaxPackageListSize = 0;
+ VOID *IntBuffer;
+
+//Conformance check, as required by SCT
+ if (BufferSize == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (*BufferSize > 0 && Buffer == NULL)
+ return EFI_INVALID_PARAMETER;
+//End of conformace check
+
+ if (Record != NULL) //we need to export only specific package list
+ return ExportPack(Handle, BufferSize, Buffer, TRUE);
+
+//we need to return all package lists
+ Record = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ while(Record != NULL) {
+ //first determine required buffer size
+ PackageListSize = 0;
+ Status = ExportPack((EFI_HII_HANDLE)Record, &PackageListSize, NULL, TRUE);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ RequiredSize += PackageListSize;
+ MaxPackageListSize = (MaxPackageListSize > PackageListSize) ? MaxPackageListSize : PackageListSize;
+ }
+ Record = (PACKAGE_LIST_RECORD *)(Record->Link.pNext);
+ }
+
+ if(*BufferSize < RequiredSize) {
+ *BufferSize = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData, MaxPackageListSize, &IntBuffer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Record = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ while(Record != NULL) {
+ //export all package lists one by one
+ PackageListSize = MaxPackageListSize;
+ Status = ExportPack((EFI_HII_HANDLE)Record, &PackageListSize, IntBuffer, FALSE);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(Buffer, IntBuffer, PackageListSize);
+ (UINT8 *)Buffer += PackageListSize;
+ }
+ Record = (PACKAGE_LIST_RECORD *)(Record->Link.pNext);
+ }
+
+ pBS->FreePool(IntBuffer);
+ *BufferSize = RequiredSize;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiFindKeyboardLayouts
+//
+// Description:
+// This function is HII Database protocol function FindKeyboardLayouts implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN OUT UINT16 *KeyGuidBufferLength - Pointer to allocated buffer size value
+// OUT EFI_GUID *KeyGuidBuffer - Pointer to EFI_GUID buffer where to store found layouts
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - KeyGuidBufferLength or KeyGuidBuffer is NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+// EFI_NOT_FOUND - No layouts found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiFindKeyboardLayouts (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_GUID *KeyGuidBuffer)
+{
+ UINT16 RequiredSize;
+ KEY_LAYOUT_LINK *Link;
+ UINT16 i;
+
+ if(KeyGuidBufferLength == NULL || KeyGuidBuffer == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(PrivateData.KeyLayoutList.Size == 0)
+ return EFI_NOT_FOUND;
+
+ RequiredSize = (UINT16) PrivateData.KeyLayoutList.Size * sizeof(EFI_GUID);
+ if(RequiredSize > *KeyGuidBufferLength)
+ {
+ *KeyGuidBufferLength = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Link = (KEY_LAYOUT_LINK *)PrivateData.KeyLayoutList.pHead;
+ for(i = 0; i < PrivateData.KeyLayoutList.Size; i++)
+ {
+ KeyGuidBuffer[i] = Link->Layout.Guid;
+ Link = (KEY_LAYOUT_LINK *) Link->Link.pNext;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiSetKeyboardLayout
+//
+// Description:
+// This function is HII Database protocol function SetKeyboardLayout implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_GUID *KeyGuid - Pointer to EFI_GUID of layout to set
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - KeyGuid is NULL
+// EFI_NOT_FOUND - Given layout not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+//dummy function for signal event procedure
+VOID SetKbLayoutNotifyFn(IN EFI_EVENT Event, IN VOID *Context) {}
+
+EFI_STATUS HiiSetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid)
+{
+ EFI_HII_KEYBOARD_LAYOUT* Layout;
+ EFI_STATUS Status;
+
+ if(KeyGuid == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Layout = FindLayoutByGuid(KeyGuid);
+ if(Layout == NULL)
+ return EFI_NOT_FOUND;
+
+ PrivateData.CurrentLayout = Layout;
+ Status = SignalKbLayoutChangedEvent();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetKeyboardLayout
+//
+// Description:
+// This function is HII Database protocol function GetKeyboardLayout implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_GUID *KeyGuid - Pointer to EFI_GUID of layout to set
+// IN OUT UINT16 *KeyGuidBufferLength - Pointer to allocated buffer size value
+// OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout - Pointer to EFI_HII_KEYBOARD_LAYOUT where to store layout
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - KeyboardLayout or KeyGuidBufferLength is NULL
+// EFI_NOT_FOUND - Given layout not found
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout)
+{
+ EFI_HII_KEYBOARD_LAYOUT *Layout;
+
+ if(KeyGuidBufferLength == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(*KeyGuidBufferLength != 0 && KeyboardLayout == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(KeyGuid == NULL)
+ Layout = PrivateData.CurrentLayout;
+ else
+ Layout = FindLayoutByGuid(KeyGuid);
+
+ if(Layout == NULL)
+ return EFI_NOT_FOUND;
+
+ if(Layout->LayoutLength > *KeyGuidBufferLength)
+ {
+ *KeyGuidBufferLength = Layout->LayoutLength;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ MemCpy(KeyboardLayout, Layout, Layout->LayoutLength);
+ return EFI_SUCCESS;
+}
+
+//********************** Service functions implementation ***************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddPackages
+//
+// Description:
+// This function adds packages from PackageList to package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to add packages
+// IN EFI_HII_PACKAGE_LIST_HEADER *PackageList - Pointer to package list which packages to add
+// IN BOOLEAN Update - Flag which defines packages should be added or updated
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+// Notes:
+// If Update is TRUE control flow goes as described in UpdatePackageList function definition (see UEFI
+// specification v2.1) Otherwise control flow goes as described in NewPackageList function definition
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddPackages(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ BOOLEAN Update)
+{
+ UINT8 Passes;
+ EFI_GUID *Guid;
+ UINT8 PackageType;
+ EFI_STATUS Status;
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType;
+ EFI_HII_PACKAGE_LIST_HEADER *SavePointer;
+ UINT32 ControlSize;
+
+ SavePointer = PackageList;
+ ControlSize = PackageList->PackageLength;
+
+ if(Update)
+ {
+ Passes = 2; //set number of passes
+ NotifyType = EFI_HII_DATABASE_NOTIFY_ADD_PACK;
+ }
+ else
+ {
+ Passes = 1; //set number of passes
+ NotifyType = EFI_HII_DATABASE_NOTIFY_NEW_PACK;
+ }
+
+ while(Passes--)
+ {
+ (UINT8 *)PackageList += sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+ ControlSize -= sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ while(((EFI_HII_PACKAGE_HEADER *)PackageList)->Type != EFI_HII_PACKAGE_END && ControlSize > 0)
+ {
+ if(Update)
+ {
+ PackageType = ((EFI_HII_PACKAGE_HEADER *)PackageList)->Type;
+ if(PackageType == EFI_HII_PACKAGE_TYPE_GUID)
+ Guid = (EFI_GUID *) &(((EFI_HII_GUID_PACKAGE_HDR *)PackageList)->Guid);
+ else
+ Guid = NULL;
+ FindAndRemovePackages(Handle, PackageType, Guid, FALSE);
+ }
+ else
+ {
+ Status = AddPackage(Handle, (EFI_HII_PACKAGE_HEADER *)PackageList, NotifyType);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ ControlSize -= ((EFI_HII_PACKAGE_HEADER *)PackageList)->Length;
+ (UINT8 *)PackageList += ((EFI_HII_PACKAGE_HEADER *)PackageList)->Length;
+ }
+ Update = FALSE;
+ PackageList = SavePointer;
+ ControlSize = PackageList->PackageLength;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddPackage
+//
+// Description:
+// This function adds package to package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to add package
+// IN EFI_HII_PACKAGE_HEADER *Package - Pointer to package to add
+// IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType - Notify type to be signalled
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddPackage(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType)
+{
+ PACKAGE_LINK *NewLink;
+ UINT32 Size;
+ DLIST *PackageList;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+
+ Size = Package->Length;
+ NewLink = (PACKAGE_LINK *) CreateNewLink(Size);
+ if(NewLink == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ MemCpy(&(NewLink->Package), Package, Size);
+
+ switch(Package->Type)
+ {
+ case EFI_HII_PACKAGE_STRINGS:
+ Status = ParseStringsPackage(
+ (PACKAGE_LIST_RECORD *)Handle,
+ (EFI_HII_STRING_PACKAGE_HDR *)Package);
+ break;
+ case EFI_HII_PACKAGE_SIMPLE_FONTS:
+ Status = ParseSimpleFontsPackage((EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)Package);
+ break;
+ case EFI_HII_PACKAGE_FONTS:
+ Status = ParseFontsPackage((EFI_HII_FONT_PACKAGE_HDR *)Package);
+ break;
+ case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
+ Status = ParseKeyLayoutPackage((EFI_HII_KEYBOARD_PACKAGE_HDR *)Package);
+ break;
+ default:
+ break;
+ }
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ DListAdd(PackageList, (DLINK *)NewLink);
+
+ if(PrivateData.NotifyList.Size > 0)
+ InvokeRegisteredNotify(Package, Handle, NotifyType);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindAndRemovePackages
+//
+// Description:
+// This function finds or removes packages from package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to find package
+// IN UINT8 PackageType - Package type to find
+// IN EFI_GUID *PackageGuid - Pointer to package guid to find
+// IN BOOLEAN FindOnly - Flag, which determines should package be found or removed
+//
+// Output:
+// TRUE - Package of given type found
+//
+// Notes:
+// If FindOnly is TRUE, function returns TRUE when first package of given type is found. Otherwise
+// function removes all packages of given type from package list and returns FALSE
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FindAndRemovePackages (
+ IN EFI_HII_HANDLE Handle,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN BOOLEAN FindOnly )
+{
+ DLIST *PackageList;
+ PACKAGE_LINK *Link;
+ PACKAGE_LINK *FoundLink;
+
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+ Link = (PACKAGE_LINK *)(PackageList->pHead);
+
+ while(Link != NULL)
+ {
+ if(MatchPackage(PackageType, PackageGuid, &(Link->Package)))
+ {
+ if(FindOnly)
+ return TRUE;
+ else
+ {
+ FoundLink = Link;
+ Link = (PACKAGE_LINK *)Link->Link.pPrev;
+ RemovePackage(Handle, FoundLink);
+ }
+ }
+ if(Link == NULL) //we removed first element from list
+ Link = (PACKAGE_LINK *)(PackageList->pHead);
+ else
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemovePackage
+//
+// Description:
+// This function removes package from package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to add package
+// IN PACKAGE_LINK *Package - Pointer to package to remove
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RemovePackage (
+ IN EFI_HII_HANDLE Handle,
+ IN PACKAGE_LINK *Package )
+{
+ DLIST *PackageList;
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+
+ if(PrivateData.NotifyList.Size > 0)
+ InvokeRegisteredNotify(&(Package->Package), Handle, EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);
+
+ switch(Package->Package.Type)
+ {
+ case EFI_HII_PACKAGE_STRINGS:
+ DeleteStringsFromDatabase(&(((PACKAGE_LIST_RECORD *)Handle)->StringDb));
+ DeleteList(&(((PACKAGE_LIST_RECORD *)Handle)->LanguageList));
+ break;
+ case EFI_HII_PACKAGE_SIMPLE_FONTS:
+// DeleteSimpleFonts((EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)&(Package->Package));
+ break;
+ case EFI_HII_PACKAGE_FONTS:
+// DeleteFonts((EFI_HII_FONT_PACKAGE_HDR *)&(Package->Package));
+ break;
+ case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
+ DeleteKeyboardLayout((EFI_HII_KEYBOARD_PACKAGE_HDR *)&(Package->Package));
+ break;
+ default:
+ break;
+ }
+ DListDelete(PackageList, (DLINK *)Package);
+ pBS->FreePool(Package);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InvokeRegisteredNotify
+//
+// Description:
+// This function invokes registered notify function if package types match
+//
+// Input:
+// IN EFI_HII_PACKAGE_HEADER *Package - Pointer to package to match
+// IN EFI_HII_HANDLE Handle - Handle of package list to whom given package belongs
+// IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType - Notification type
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InvokeRegisteredNotify (
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType)
+{
+ NOTIFY_RECORD *Record;
+
+ Record = (NOTIFY_RECORD *)(PrivateData.NotifyList.pHead);
+
+ while(Record != NULL)
+ {
+ if(MatchPackage(Record->PackageType, &(Record->PackageGuid), Package) &&
+ (NotifyType & Record->NotifyType))
+ Record->PackageNotifyFn(Record->PackageType,
+ &(Record->PackageGuid),
+ Package,
+ Handle,
+ NotifyType);
+ Record = (NOTIFY_RECORD *)(Record->Link.pNext);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NewPackageListRecord
+//
+// Description:
+// This function creates new PACKAGE_LIST_RECORD structure and returns pointer to it
+//
+// Input:
+// None
+//
+// Output:
+// PACKAGE_LIST_RECORD* - pointer to newly created structure
+// NULL - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+PACKAGE_LIST_RECORD* NewPackageListRecord( VOID )
+{
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *Record;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(PACKAGE_LIST_RECORD),
+ &Record);
+ if (EFI_ERROR(Status))
+ return NULL;
+
+ Record->Signature = PACKAGE_LIST_RECORD_SIGNATURE;
+
+ DListInit(&(Record->PackageList));
+ DListInit(&(Record->LanguageList));
+ DListInit(&(Record->StringFontList));
+
+ Record->StringDb.InitialCount = 20;
+ Record->StringDb.RecordCount = 0;
+ Record->StringDb.KeyField = &StringDbKeyField;
+ Record->StringDb.MemoryType = EfiBootServicesData;
+ Record->StringDb.KeyCount = 1;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(VOID *) * 20,
+ &(Record->StringDb.IndexArray));
+
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Record);
+ return NULL;
+ }
+
+ return Record;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NewNotifyRecord
+//
+// Description:
+// This function creates new NOTIFY_RECORD structure and returns pointer to it
+//
+// Input:
+// None
+//
+// Output:
+// NOTIFY_RECORD* - pointer to newly created structure
+// NULL - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NOTIFY_RECORD* NewNotifyRecord( VOID )
+{
+ EFI_STATUS Status;
+ NOTIFY_RECORD *Record;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(NOTIFY_RECORD),
+ &Record);
+ if (EFI_ERROR(Status))
+ return NULL;
+
+ Record->Signature = NOTIFY_LIST_RECORD_SIGNATURE;
+
+ return Record;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateNewLink
+//
+// Description:
+// This function creates new link structure for linked list and returns pointer to it
+//
+// Input:
+// IN UINT32 Size - size of the link stucture in bytes
+//
+// Output:
+// VOID* - pointer to newly created structure
+// NULL - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* CreateNewLink(UINT32 Size)
+{
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ Size + sizeof(DLINK),
+ &Buffer);
+ if (EFI_ERROR(Status))
+ return NULL;
+
+ return Buffer;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteList
+//
+// Description:
+// This function deletes linked list and frees allocated memory
+//
+// Input:
+// IN DLIST *List - Pointer to linked list to be deleted
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteList(DLIST *List)
+{
+ DLINK *Current;
+ DLINK *Next;
+
+ Current = List->pHead;
+
+ while(Current != NULL)
+ {
+ Next = Current->pNext;
+ pBS->FreePool(Current);
+ Current = Next;
+ }
+
+ List->pHead = NULL;
+ List->pTail = NULL;
+ List->Size = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchPackage
+//
+// Description:
+// This function checks if given package matches given type and guid
+//
+// Input:
+// IN UINT8 PackageType - Package type to match
+// IN EFI_GUID *PackageGuid - Pointer to package guid to match
+// IN EFI_HII_PACKAGE_HEADER *Package - Pointer to package to check
+//
+// Output:
+// TRUE - package matches given type and guid
+// FALSE - package don't match
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchPackage(
+ IN UINT8 PackageType,
+ IN EFI_GUID *PackageGuid,
+ IN EFI_HII_PACKAGE_HEADER *Package)
+{
+ if(PackageType != Package->Type)
+ return FALSE;
+
+ if(PackageType == EFI_HII_PACKAGE_TYPE_GUID)
+ {
+ if(guidcmp(PackageGuid, &(((EFI_HII_GUID_PACKAGE_HDR *)Package)->Guid)))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckIfPresent
+//
+// Description:
+// This function checks if package list with given guid already in database
+//
+// Input:
+// IN EFI_GUID *Guid - Pointer to package list guid to check
+// IN EFI_HANDLE DriverHandle - Driver handle
+//
+// Output:
+// TRUE - package list already present in database
+// FALSE - package list with given guid not found in database
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckIfPresent(
+ IN EFI_GUID *Guid,
+ IN EFI_HANDLE DriverHandle)
+{
+ PACKAGE_LIST_RECORD *Record;
+
+ Record = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ while(Record != NULL)
+ {
+ if((!guidcmp(Guid, &(Record->Guid))) && (DriverHandle == Record->DriverHandle))
+ return TRUE;
+ Record = (PACKAGE_LIST_RECORD *)(Record->Link.pNext);
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseKeyLayoutPackage
+//
+// Description:
+// This function extracts keyboard layout from package and saves it in private area
+//
+// Input:
+// IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package - Pointer to keyboard layout package
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseKeyLayoutPackage(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package)
+{
+ KEY_LAYOUT_LINK *Link;
+ UINT16 i;
+ UINT8 *Pointer;
+ UINT32 Size;
+
+ Pointer = (UINT8 *)Package;
+ Pointer += sizeof(EFI_HII_KEYBOARD_PACKAGE_HDR);
+
+ for(i = 0; i < Package->LayoutCount; i++)
+ {
+ Size = ((EFI_HII_KEYBOARD_LAYOUT *)Pointer)->LayoutLength;
+ Link = (KEY_LAYOUT_LINK *) CreateNewLink(Size);
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ MemCpy(&(Link->Layout), Pointer, Size);
+ DListAdd(&(PrivateData.KeyLayoutList), (DLINK *)Link);
+ Pointer += Size;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteKeyboardLayout
+//
+// Description:
+// This function removes keyboard layouts existing in package from HII database
+//
+// Input:
+// IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package - Pointer to keyboard layout package
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DeleteKeyboardLayout(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package)
+{
+ KEY_LAYOUT_LINK *Link;
+ UINT16 i;
+ UINT8 *Pointer;
+ UINT32 Size;
+
+ Pointer = (UINT8 *)Package;
+ Pointer += sizeof(EFI_HII_KEYBOARD_PACKAGE_HDR);
+
+ for(i = 0; i < Package->LayoutCount; i++)
+ {
+ Size = ((EFI_HII_KEYBOARD_LAYOUT *)Pointer)->LayoutLength;
+ Link = (KEY_LAYOUT_LINK *)PrivateData.KeyLayoutList.pHead;
+ while(Link != NULL)
+ {
+ if(!guidcmp(&(((EFI_HII_KEYBOARD_LAYOUT *)Pointer)->Guid), &(Link->Layout.Guid)))
+ break;
+ Link = (KEY_LAYOUT_LINK *)Link->Link.pNext;
+ }
+
+ if(Link != NULL) {
+ if(PrivateData.CurrentLayout == &(Link->Layout)) {
+ PrivateData.CurrentLayout = NULL;
+ SignalKbLayoutChangedEvent();
+ }
+
+ DListDelete(&(PrivateData.KeyLayoutList), (DLINK *)Link);
+ }
+ Pointer += Size;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindLayoutByGuid
+//
+// Description:
+// This function finds keyboard layout in private area by given guid
+//
+// Input:
+// IN EFI_GUID *Guid - Pointer to guid of keyboard layout
+//
+// Output:
+// EFI_HII_KEYBOARD_LAYOUT* - Pointer to found layout
+// NULL - layout not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_HII_KEYBOARD_LAYOUT* FindLayoutByGuid(
+ IN EFI_GUID *Guid)
+{
+ KEY_LAYOUT_LINK *Link;
+
+ Link = (KEY_LAYOUT_LINK *)PrivateData.KeyLayoutList.pHead;
+ while(Link != NULL)
+ {
+ if(!guidcmp(Guid, &(Link->Layout.Guid)))
+ return &(Link->Layout);
+ Link = (KEY_LAYOUT_LINK *)Link->Link.pNext;
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseSimpleFontsPackage
+//
+// Description:
+// This function extracts simple fonts from package and saves in private area
+//
+// Input:
+// IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package - Pointer to simple font package
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseSimpleFontsPackage(
+ IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package)
+{
+ EFI_STATUS Status;
+ UINT16 i;
+ UINT16 Symbol;
+ EFI_NARROW_GLYPH *NGlyph;
+ EFI_WIDE_GLYPH *WGlyph;
+
+ NGlyph = Package->NarrowGlyphs;
+ WGlyph = (EFI_WIDE_GLYPH *)NGlyph;
+ (UINT8 *)WGlyph += Package->NumberOfNarrowGlyphs * sizeof(EFI_NARROW_GLYPH);
+
+ for(i = 0; i < Package->NumberOfNarrowGlyphs; i++)
+ {
+ Symbol = NGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].NarrowGlyph == NULL)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_NARROW_GLYPH),
+ &(DefaultFont[Symbol].NarrowGlyph));
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ DefaultFont[Symbol].NarrowGlyph[0] = NGlyph[i];
+ }
+ }
+
+ for(i = 0; i < Package->NumberOfWideGlyphs; i++)
+ {
+ Symbol = WGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].WideGlyph == NULL)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_WIDE_GLYPH),
+ &(DefaultFont[Symbol].WideGlyph));
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ DefaultFont[Symbol].WideGlyph[0] = WGlyph[i];
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteStringsFromDatabase
+//
+// Description:
+// This function removes HII strings from private storage and frees allocated memory
+//
+// Input:
+// IN DBE_DATABASE *Database - Pointer to private strings storage
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteStringsFromDatabase(DBE_DATABASE *Database)
+{
+ VOID *FreeLink;
+ UINTN *Pointer;
+ UINTN i;
+
+ if(Database->RecordCount == 0)
+ return;
+
+ Pointer = (UINTN *)(Database->IndexArray);
+
+ for(i = 0; i < Database->RecordCount; i++)
+ {
+ FreeLink = (VOID *)(UINTN)(*Pointer);
+ pBS->FreePool(FreeLink);
+ Pointer++;
+ }
+
+ MemSet(Database->IndexArray, Database->RecordCount * Database->KeyCount, 0);
+ Database->RecordCount = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteSimpleFonts
+//
+// Description:
+// This function removes simple fonts from private area and frees allocated memory
+//
+// Input:
+// IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package - Pointer to simple font package which fonts
+// should be removed
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteSimpleFonts(IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package)
+{
+ UINT16 i;
+ UINT16 Symbol;
+ EFI_NARROW_GLYPH *NGlyph;
+ EFI_WIDE_GLYPH *WGlyph;
+
+ NGlyph = Package->NarrowGlyphs;
+ WGlyph = (EFI_WIDE_GLYPH *)NGlyph;
+ (UINT8 *)WGlyph += Package->NumberOfNarrowGlyphs * sizeof(EFI_NARROW_GLYPH);
+
+ for(i = 0; i < Package->NumberOfNarrowGlyphs; i++)
+ {
+ Symbol = NGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].NarrowGlyph != NULL)
+ {
+ pBS->FreePool(DefaultFont[Symbol].NarrowGlyph);
+ DefaultFont[Symbol].NarrowGlyph = NULL;
+ }
+ }
+
+ for(i = 0; i < Package->NumberOfWideGlyphs; i++)
+ {
+ Symbol = WGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].WideGlyph != NULL)
+ {
+ pBS->FreePool(DefaultFont[Symbol].WideGlyph);
+ DefaultFont[Symbol].WideGlyph = NULL;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExportPack
+//
+// Description:
+// This function exports the package list with given handle into provided buffer
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list to be exported
+// IN OUT UINTN *BufferSize - Pointer to export buffer size value
+// OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer - Pointer to buffer where to export package lists
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_BUFFER_TOO_SMALL - Export buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ExportPack (
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer,
+ IN BOOLEAN FirstCall )
+{
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ PACKAGE_LINK *Link;
+ UINT32 Size = 0;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE) //handle is not valid, return NOT FOUND as SCT requirement
+ return EFI_NOT_FOUND;
+
+ if(FirstCall) {
+ //on the subsequent call we don't need to update string packages again
+ Status = UpdateStringPackages(Handle);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ Link = (PACKAGE_LINK *)Record->PackageList.pHead;
+ while(Link != NULL)
+ {
+ Size += Link->Package.Length;
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+
+ Size += sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ if(Size > *BufferSize)
+ {
+ *BufferSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = Size;
+ Buffer->PackageListGuid = Record->Guid;
+ Buffer->PackageLength = Size;
+ (UINT8 *)Buffer += sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ Link = (PACKAGE_LINK *)Record->PackageList.pHead;
+ while(Link != NULL)
+ {
+ Size = Link->Package.Length;
+ MemCpy(Buffer, &(Link->Package), Size);
+ (UINT8 *)Buffer += Size;
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS SignalKbLayoutChangedEvent(
+ VOID)
+{
+ EFI_EVENT Event;
+ EFI_GUID SetKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID;
+ EFI_STATUS Status;
+
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ SetKbLayoutNotifyFn,
+ NULL,
+ &SetKeyboardLayoutEventGuid,
+ &Event);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ pBS->SignalEvent(Event);
+ pBS->CloseEvent(Event);
+
+ return EFI_SUCCESS;
+}
+
+#pragma warning (default : 4090)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/HiiFont.c b/Core/CORE_DXE/UefiHii/HiiFont.c
new file mode 100644
index 0000000..739520c
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiFont.c
@@ -0,0 +1,1035 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFont.c 3 3/18/13 8:31a Thomaschen $
+//
+// $Revision: 3 $
+//
+// $Date: 3/18/13 8:31a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFont.c $
+//
+// 3 3/18/13 8:31a Thomaschen
+// Update to rev.16.
+//
+// 16 3/11/13 4:40p Artems
+// [TAG] EIP110240
+// [Category] Improvement
+// [Description] Raise the TPL of StringToImage function to TPL_NOTIFY
+// to protect internal global data
+// [Files] HiiFont.c
+//
+// 15 1/24/13 11:12a Artems
+// [TAG] EIP112874
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System displays output in wrong colors
+// [RootCause] If system failed to find font, described in passed font
+// info structure it also ignored passed colors
+// [Solution] Preserve passed colors even if font not found
+// [Files] HiiFont.c
+//
+// 14 12/26/12 1:40p Artems
+// [TAG] EIP109050
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Memory leal in call to GetGlyph function
+// [RootCause] GetGlyph function called GetFontInfo function to obtain
+// proper font and didn't release font info buffer
+// [Solution] Fixed GetGlyph function
+// [Files] HiiFont.c
+//
+// 13 11/14/12 5:58p Artems
+// [TAG] EIP105534
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] system hangs during SCT execution
+// [RootCause] Incorrect handling of FORM_FEED escape character in
+// StringToImage function
+// [Solution] Graphics console - added flag to ignore line breaks
+// HiiFont - fixed multiline drawing logic
+// [Files] Gc.c HiiFont.c HiiFontEx.c
+//
+// 12 9/25/12 5:46p Artems
+// [TAG] EIP101224
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System freezes
+// [RootCause] Memory leak in StringToImage function. When called many
+// times may lead to memory exhaustion
+// [Solution] Fixed memory leak
+// [Files] HiiFont.c
+//
+// 11 6/27/12 4:16p Artems
+// [TAG] EIP93526
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Aptio 4 - Proportional Font EFI_HII_OUT_FLAG_WRAP issue
+// [RootCause] Passed drawing flags contained both Clip and Wrap. Clip
+// gets analyzed first so clipping control flow was enacted
+// [Solution] Changed order of drawind flags analysis
+// [Files] HiiFont.c
+//
+// 10 6/15/12 12:19p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] project doesn't build in 32-bit mode
+// [RootCause] Signed/Unsigned mismatch reported by 32-bit compiler
+// [Solution] typecasted one parameter to signed
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 9 6/14/12 6:31p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio fixed SCT reported
+// bugs
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 8 5/24/12 2:58p Artems
+// [TAG] EIP83593
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] No symbols are shown in GSE
+// [RootCause] Incorrect BaseLineOffset was set. Transparent drawing was
+// not supported
+// [Solution] Set correct BaseLineOffset. Add check for transparency
+// flag
+// [Files] HiiFont.c
+//
+// 7 5/22/12 4:14p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio. Removed unused
+// functions
+// [Files] HiiFont.c
+//
+// 6 5/21/12 6:28p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+//
+// 5 10/25/11 7:04p Artems
+// EIP 70530: Fixed bugs reported by SCT 2.3.1
+//
+// 4 5/17/11 4:05p Artems
+// EIP 59787: Bug fix - when drawing multi-line string X position wasn't
+// updated to start of new line
+//
+// 3 5/13/11 6:14p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 2 12/03/09 6:04p Artems
+// SCT bug fix
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiFont.c
+//
+// Description: Hii font protocol functions implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+const EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black = { 0, 0, 0, 0 };
+const EFI_GRAPHICS_OUTPUT_BLT_PIXEL White = { 0xff, 0xff, 0xff, 0 };
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+extern SIMPLE_FONT DefaultFont[0x10000];
+
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefForegroundColor;
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefBackgroundColor;
+
+static UINTN TextStartX;
+static UINTN TextStartY;
+static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ImageBlt; //buffer, where to draw
+
+EFI_FONT_HANDLE CurFont; //font to use
+CHAR16 *DrawString; //string to draw
+EFI_HII_OUT_FLAGS DrawFlags = 0;
+DLIST DrawLines = {0, NULL, NULL};
+UINTN ImageWidth;
+UINTN ImageHeight;
+
+#pragma optimize( "", off )
+EFI_STATUS CheckParameters(VOID *One, VOID *Two)
+{
+ return (One == NULL || Two == NULL) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
+}
+#pragma optimize( "", on )
+
+//**************************** Protocol functions implementation ***************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiStringToImage
+//
+// Description:
+// This function is HII Font protocol function StringToImage implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN EFI_HII_OUT_FLAGS Flags - Drawing flags
+// IN EFI_STRING String - String to draw
+// IN EFI_FONT_DISPLAY_INFO *StringInfo - Pointer to display info
+// IN OUT EFI_IMAGE_OUTPUT **Blt - Pointer to output buffer
+// IN UINTN BltX - start horizontal position
+// IN UINTN BltY - start vertical position
+// OUT EFI_HII_ROW_INFO **RowInfoArray - Pointer to returned row info array
+// OUT UINTN *RowInfoArraySize - Pointer to store row info array size
+// OUT UINTN *ColumnInfoArray - Pointer to returned column info array
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiStringToImage(
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL)
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewBlt = NULL;
+ EFI_IMAGE_OUTPUT *Io = *Blt;
+ EFI_HII_ROW_INFO *RowInfo;
+ UINTN i, j;
+ UINTN Offset;
+ DRAW_LINE *Link;
+ UINTN Delta = 0;
+ EFI_FONT_DISPLAY_INFO *Info = NULL;
+ EFI_TPL OldTpl;
+
+ Status = CheckParameters(String, Blt);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if (Io == NULL) {
+ //
+ // These two flag cannot be used if Blt is NULL upon entry.
+ //
+ if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT)
+ return EFI_INVALID_PARAMETER;
+
+ if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP)
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.
+ //
+ if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X)
+ return EFI_INVALID_PARAMETER;
+
+ if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)
+ return EFI_INVALID_PARAMETER;
+ //
+ // This flag cannot be used with EFI_HII_OUT_FLAG_CLIP_CLEAN_X.
+ //
+ if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X))
+ return EFI_INVALID_PARAMETER;
+
+//check string size - if two bytes - means empty string - do nothing
+ i = StrSize16(String);
+
+ if(i <= 2)
+ return EFI_SUCCESS;
+
+ OldTpl = pBS->RaiseTPL(TPL_NOTIFY);
+
+//first initialize global variables and split string
+/* SCT assumes that EFI_HII_OUT_FLAG_CLIP flag is implied when direct to screen output is performed
+ unless EFI_HII_OUT_FLAG_WRAP flag is set */
+ DrawFlags = Flags;
+ if(Flags & EFI_HII_IGNORE_LINE_BREAK ||
+ (Flags & EFI_HII_DIRECT_TO_SCREEN && !(Flags & EFI_HII_OUT_FLAG_WRAP)))
+ DrawFlags |= EFI_HII_OUT_FLAG_CLIP;
+
+ DrawString = String;
+ TextStartX = BltX;
+ TextStartY = BltY;
+ CurFont = NULL;
+ Status = HiiGetFontInfo(This, &CurFont, StringInfo, &Info, NULL);
+ if(EFI_ERROR(Status)) {
+ CurFont = (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE;
+ Info = NULL;
+ }
+
+ if (Info != NULL) {
+ DefForegroundColor = Info->ForegroundColor;
+ DefBackgroundColor = Info->BackgroundColor;
+ pBS->FreePool(Info); //it's no longer needed
+ } else {
+ if(StringInfo != NULL) { //even though correct font not found we preserve passed colors if any
+ DefForegroundColor = StringInfo->ForegroundColor;
+ DefBackgroundColor = StringInfo->BackgroundColor;
+ } else {
+ DefForegroundColor = White;
+ DefBackgroundColor = Black;
+ }
+ }
+
+ Status = SplitByLineBreaks(DrawString);
+ if(EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if(Io != NULL) {
+ if(!(Flags & EFI_HII_DIRECT_TO_SCREEN)) {
+ //if we're drawing on given bitmap - take its size
+ ImageWidth = Io->Width;
+ ImageHeight = Io->Height;
+ NewBlt = Io->Image.Bitmap;
+ } else {
+ //make sure we fit in screen resolution
+ ImageWidth = Io->Width - BltX;
+ ImageHeight = Io->Height - BltY;
+
+ //clear TextStartX and TextStartY
+ TextStartX = 0;
+ TextStartY = 0;
+ }
+ /* since bitmap size is fixed we have to adjust text to fit in */
+ Status = AdjustLineSize();
+ if(EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //calculate size of the image
+ GetDrawImageSize(&ImageWidth, &ImageHeight);
+ //add to required image size initial offset
+ ImageWidth += BltX;
+ ImageHeight += BltY;
+ }
+
+ if(NewBlt == NULL) {
+ /* buffer not initialized because of DirectToScreen flag or Io == NULL */
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ImageWidth * ImageHeight,
+ &NewBlt);
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemSet(NewBlt, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ImageWidth * ImageHeight, 0);
+ }
+
+ ImageBlt = NewBlt;
+ Draw();
+
+ if(Flags & EFI_HII_DIRECT_TO_SCREEN)
+ {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Screen;
+
+ if(ImageWidth < Io->Width) //we need to draw a subrectange, calculate Delta
+ Delta = ImageWidth * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+
+ Screen = (EFI_GRAPHICS_OUTPUT_PROTOCOL *)(Io->Image.Screen);
+ Status = Screen->Blt(Screen, ImageBlt, EfiBltBufferToVideo,
+ 0, 0, BltX, BltY, ImageWidth, ImageHeight, Delta);
+ pBS->FreePool(ImageBlt);
+ }
+
+//Prepare return info if needed
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ if(RowInfoArray != NULL && Link->LineHeight != 0) {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_HII_ROW_INFO) * DrawLines.Size,
+ &RowInfo);
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ i = 0;
+ while(Link != NULL) {
+ RowInfo[i].BaselineOffset = 0; //I'm still confused with this one, but SCT is happy
+ RowInfo[i].EndIndex = Link->EndIndex;
+ RowInfo[i].LineHeight = Link->LineHeight;
+ RowInfo[i].LineWidth = Link->LineWidth;
+ RowInfo[i].StartIndex = Link->StartIndex;
+
+ i++;
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ *RowInfoArray = RowInfo;
+ if(RowInfoArraySize != NULL)
+ *RowInfoArraySize = DrawLines.Size;
+ } else {
+ if(RowInfoArray != NULL)
+ *RowInfoArray = NULL;
+ if(RowInfoArraySize != NULL)
+ *RowInfoArraySize = 0;
+ }
+
+ if(Io == NULL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(EFI_IMAGE_OUTPUT), &Io);
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Io->Height = (UINT16)ImageHeight;
+ Io->Width = (UINT16)ImageWidth;
+ Io->Image.Bitmap = NewBlt;
+
+ *Blt = Io;
+ }
+
+ if(ColumnInfoArray != NULL) {
+ i = 0;
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL)
+ {
+ Offset = TextStartX;
+ for(j = Link->StartIndex; j <= Link->EndIndex; j++)
+ {
+ BOOLEAN Dummy;
+ EFI_HII_GLYPH_INFO Cell;
+ ColumnInfoArray[i] = Offset;
+ IntGetGlyph(CurFont, DrawString[j], &Cell, NULL, &Dummy);
+ i++;
+ Offset += Cell.AdvanceX;
+ }
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ }
+
+//clean up
+ DeleteList(&DrawLines);
+ pBS->RestoreTPL(OldTpl);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiStringIdToImage
+//
+// Description:
+// This function is HII Font protocol function StringIdToImage implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN EFI_HII_OUT_FLAGS Flags - Drawing flags
+// IN EFI_HII_HANDLE PackageList - Handle of package list where string resides
+// IN EFI_STRING_ID StringId - String Id
+// IN CHAR8 *Language - Language Id
+// IN EFI_FONT_DISPLAY_INFO *StringInfo - Pointer to display info
+// IN OUT EFI_IMAGE_OUTPUT **Blt - Pointer to output buffer
+// IN UINTN BltX - start horizontal position
+// IN UINTN BltY - start vertical position
+// OUT EFI_HII_ROW_INFO **RowInfoArray - Pointer to returned row info array
+// OUT UINTN *RowInfoArraySize - Pointer to store row info array size
+// OUT UINTN *ColumnInfoArray - Pointer to returned column info array
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiStringIdToImage (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8* Language,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL)
+{
+ CHAR16 String[0x100];
+ UINTN StringSize = 0x100;
+ EFI_STATUS Status;
+
+ Status = AmiHiiGetString(NULL, Language, PackageList, StringId, String, &StringSize, NULL);
+
+ if(EFI_ERROR(Status))
+ {
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * StringSize,
+ (VOID **)&String);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+ }
+ else
+ return Status;
+
+ Status = AmiHiiGetString(NULL, Language, PackageList, StringId, String, &StringSize, NULL);
+ }
+
+ Status = HiiStringToImage(This, Flags, String, StringInfo, Blt, BltX, BltY,
+ RowInfoArray, RowInfoArraySize, ColumnInfoArray);
+
+ if(StringSize > 0x100)
+ pBS->FreePool(String);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetGlyph
+//
+// Description:
+// This function is HII Font protocol function GetGlyph implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN CHAR16 Char - Symbol, which glyph to return
+// IN EFI_FONT_DISPLAY_INFO *StringInfo - Pointer to display info
+// IN OUT EFI_IMAGE_OUTPUT **Blt - Pointer to output buffer
+// OUT UINTN *Baseline - Pointer to baseline placeholder
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetGlyph (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN CHAR16 Char,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
+ OUT EFI_IMAGE_OUTPUT **Blt,
+ OUT UINTN *Baseline OPTIONAL
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN GlyphNotFound = FALSE;
+ EFI_IMAGE_OUTPUT *Output;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Bitmap;
+ EFI_FONT_HANDLE Font;
+ EFI_FONT_DISPLAY_INFO *Info = NULL;
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 *GlyphBlock;
+ BOOLEAN Free;
+
+ if(Blt == NULL || *Blt != NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Font = NULL;
+ Status = HiiGetFontInfo(This, &Font, StringInfo, &Info, NULL);
+ if(EFI_ERROR(Status)) {
+ Font = (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE;
+ Info = NULL;
+ }
+
+//prepare global data values, used in drawing
+ if(Info != NULL) {
+ DefForegroundColor = Info->ForegroundColor;
+ DefBackgroundColor = Info->BackgroundColor;
+ pBS->FreePool(Info);
+ } else {
+ if(StringInfo != NULL) {
+ DefForegroundColor = StringInfo->ForegroundColor;
+ DefBackgroundColor = StringInfo->BackgroundColor;
+ } else {
+ DefForegroundColor = White;
+ DefBackgroundColor = Black;
+ }
+ }
+
+ Status = IntGetGlyph(Font, Char, &Cell, &GlyphBlock, &Free);
+ if(EFI_ERROR(Status))
+ return Status;
+ if(Status == EFI_WARN_UNKNOWN_GLYPH)
+ GlyphNotFound = TRUE;
+
+//allocate memory for output bitmap
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Cell.Width * Cell.Height,
+ &Bitmap);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+//allocate memory for output data
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_IMAGE_OUTPUT),
+ &Output);
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(Bitmap);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Output->Width = Cell.Width;
+ Output->Height = Cell.Height;
+ Output->Image.Bitmap = Bitmap;
+
+ ImageWidth = Output->Width;
+ ImageHeight = Output->Height;
+
+//now we are ready to draw the glyph
+ DrawGlyph(0, 0, ImageWidth, ImageHeight, GlyphBlock, FALSE, Bitmap, Cell.Width);
+ if(Free)
+ pBS->FreePool(GlyphBlock);
+
+ *Blt = Output;
+
+ if(Baseline != NULL) {
+ if((UINTN)Font == DEFAULT_FONT_HANDLE)
+ *Baseline = (Cell.Width == EFI_GLYPH_WIDTH) ? 4 : 5; //fixed value for system font
+ else
+ *Baseline = (Cell.OffsetY < 0) ? -(Cell.OffsetY) : 0;
+ }
+
+ return (GlyphNotFound) ? EFI_WARN_UNKNOWN_GLYPH : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetFontInfo
+//
+// Description:
+// This function is HII Font protocol function GetFontInfo implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN OUT EFI_FONT_HANDLE *FontHandle - Pointer to font handle
+// IN EFI_FONT_DISPLAY_INFO *StringInfoIn - Pointer to display info
+// OUT EFI_FONT_DISPLAY_INFO *StringInfoOut - Pointer to output display info
+// IN EFI_STRING *String - Pointer to string to test
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetFontInfo (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
+ IN CONST EFI_STRING String OPTIONAL
+)
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fg;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Bg;
+ EFI_HII_FONT_STYLE FStyle;
+ UINT16 FSize;
+ CHAR16 *FName;
+ FONT_MATCH_MASK Fm;
+ EFI_STATUS Status;
+ EFI_FONT_DISPLAY_INFO FdInfo;
+
+ if (StringInfoIn == NULL) {
+ /* use default values */
+ FdInfo.FontInfoMask = EFI_FONT_INFO_SYS_FONT |
+ EFI_FONT_INFO_SYS_SIZE |
+ EFI_FONT_INFO_SYS_STYLE |
+ EFI_FONT_INFO_SYS_FORE_COLOR |
+ EFI_FONT_INFO_SYS_BACK_COLOR;
+ } else {
+ FdInfo = *StringInfoIn;
+ FName = (CHAR16 *)StringInfoIn->FontInfo.FontName;
+ }
+ //
+ // Check the font information mask to make sure it is valid.
+ //
+ if (((FdInfo.FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==
+ (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==
+ (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
+ (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==
+ (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==
+ (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))
+ return EFI_INVALID_PARAMETER;
+
+/* first deal with color attributes */
+ Fg = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) ? White : StringInfoIn->ForegroundColor;
+ Bg = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) ? Black : StringInfoIn->BackgroundColor;
+
+/* retrieve supplied information */
+ FStyle = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_STYLE) ? EFI_HII_FONT_STYLE_NORMAL : StringInfoIn->FontInfo.FontStyle;
+ FSize = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_SIZE) ? EFI_GLYPH_HEIGHT : StringInfoIn->FontInfo.FontSize;
+
+ if(FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_FONT) {
+ if(*FontHandle == (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE) {
+ /* we already returned system font, so no other matches for system font present */
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+ /* return system font information and handle */
+ *FontHandle = (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE;
+ if(StringInfoOut != NULL) {
+ Status = FillFontInfo(*FontHandle, StringInfoOut);
+ if(EFI_ERROR(Status))
+ return Status;
+ (*StringInfoOut)->ForegroundColor = Fg;
+ (*StringInfoOut)->BackgroundColor = Bg;
+ (*StringInfoOut)->FontInfoMask = FdInfo.FontInfoMask;
+ }
+ return EFI_SUCCESS;
+ }
+
+ Fm.MatchName = (FdInfo.FontInfoMask & EFI_FONT_INFO_ANY_FONT) ? MATCH_INGNORE : MATCH_STRICT;
+ Fm.MatchStyle = (FdInfo.FontInfoMask & EFI_FONT_INFO_ANY_STYLE) ? MATCH_INGNORE :
+ (FdInfo.FontInfoMask & EFI_FONT_INFO_RESTYLE) ? MATCH_LOOSE : MATCH_STRICT;
+ Fm.MatchSize = (FdInfo.FontInfoMask & EFI_FONT_INFO_ANY_SIZE) ? MATCH_INGNORE :
+ (FdInfo.FontInfoMask & EFI_FONT_INFO_RESIZE) ? MATCH_LOOSE : MATCH_STRICT;
+
+ Status = FindFont(FontHandle, FName, FStyle, FSize, Fm, String);
+ if(!EFI_ERROR(Status) && (StringInfoOut != NULL)) {
+ /* font found, prepare font info */
+ Status = FillFontInfo(*FontHandle, StringInfoOut);
+ if(EFI_ERROR(Status))
+ return Status;
+ (*StringInfoOut)->ForegroundColor = Fg;
+ (*StringInfoOut)->BackgroundColor = Bg;
+ (*StringInfoOut)->FontInfoMask = FdInfo.FontInfoMask;
+ }
+
+ return Status;
+}
+
+
+
+// *************************** Service functions (not for public use) **********************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsLineBreak
+//
+// Description:
+// This function checks if given symbol is a line break
+//
+// Input:
+// IN CHAR16 Char - Symbol to test
+//
+// Output:
+// TRUE - Symbol is a linebreak
+// FALSE - Symbol is not a linebreak
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsLineBreak(CHAR16 Char)
+{
+ switch(Char)
+ {
+ case 0x000c:
+ case 0x000d:
+ case 0x2028:
+ case 0x2029:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsLineBreakOpp
+//
+// Description:
+// This function checks if given symbol is a line break opportunity
+//
+// Input:
+// IN CHAR16 Char - Symbol to test
+//
+// Output:
+// TRUE - Symbol is a linebreak opportunity
+// FALSE - Symbol is not a linebreak opportunity
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsLineBreakOpp(CHAR16 Char)
+{
+ if(IsLineBreak(Char))
+ return TRUE;
+
+ if(Char >= 0x2000 && Char <= 0x200a)
+ return TRUE;
+
+ switch (Char)
+ {
+ case 0x0020:
+ case 0x1680:
+ case 0x2013:
+ case 0x205f:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SplitByLineBreaks
+//
+// Description:
+// This function splits given string into lines on linebreaks
+//
+// Input:
+// IN EFI_STRING String - string to split
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SplitByLineBreaks(EFI_STRING String)
+{
+ UINT32 Size;
+ UINT32 i;
+ DRAW_LINE *Link;
+
+ Size = StrSize16(String) / 2; //size in symbols
+ Link = (DRAW_LINE *)CreateNewLink(sizeof(UINTN) * 5);
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ Link->StartIndex = 0;
+ if(DrawFlags & EFI_HII_IGNORE_LINE_BREAK)
+ {
+ Link->EndIndex = Size - 2; //ignore null terminator
+ UpdateLineSize(Link);
+ DListAdd(&DrawLines, (DLINK *)Link);
+ return EFI_SUCCESS;
+ }
+
+ for(i = 0; i < (Size - 1); i++)
+ {
+ if(IsLineBreak(String[i]))
+ {
+ Link->EndIndex = i;
+ UpdateLineSize(Link);
+ DListAdd(&DrawLines, (DLINK *)Link);
+ Link = (DRAW_LINE *)CreateNewLink(sizeof(UINTN) * 5);
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ i++;
+ Link->StartIndex = i;
+ }
+ }
+ Link->EndIndex = Size - 2;
+ UpdateLineSize(Link);
+ DListAdd(&DrawLines, (DLINK *)Link);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustLineSize
+//
+// Description:
+// This function analyzes lines of the string and makes them fit into drawing area size
+//
+// Input:
+// None
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AdjustLineSize(VOID)
+{
+ DRAW_LINE *Link;
+ UINTN TextHeight = ImageHeight - TextStartY;
+ UINTN TextWidth = ImageWidth - TextStartX;
+ EFI_STATUS Status;
+
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL) {
+//first detect line height
+ if(TextHeight >= Link->LineHeight) {
+ /* line is visible entirely */
+ TextHeight -= Link->LineHeight;
+ } else {
+ /* line is visible partially */
+ if(DrawFlags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y || TextHeight == 0) {
+ Link->LineHeight = 0; //mark line as invisible and stop adjusting - all subsequent lines will be invisible
+ return EFI_SUCCESS;
+ } else {
+ Link->LineHeight = TextHeight;
+ TextHeight = 0;
+ }
+ }
+
+//second detect line width
+ if(Link->LineWidth > TextWidth) {
+ /* line needs clipping of wrapping */
+ if(DrawFlags & EFI_HII_OUT_FLAG_WRAP) {
+ /* wrapping mode */
+ Status = WrapLine(Link, TextWidth);
+ if(EFI_ERROR(Status))
+ return Status;
+ } else {
+ /* clipping mode */
+ ClipLine(Link, TextWidth, ((DrawFlags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) ? TRUE : FALSE));
+ }
+ }
+//proceed to next line
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Draw
+//
+// Description:
+// This function draws lines of the string
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Draw(VOID)
+{
+ DRAW_LINE *Link;
+ UINTN i;
+ CHAR16 CurrentSymbol;
+ BOOLEAN Transparent = FALSE;
+ EFI_STATUS Status;
+
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 *GlyphBlock;
+ BOOLEAN Free;
+
+ POINT_COORD gl_st;
+ POINT_COORD gl_size;
+ RECT_COORD glyph;
+
+ POINT_COORD ln_st;
+ POINT_COORD ln_size;
+ RECT_COORD line;
+
+ POINT_COORD origin;
+
+ glyph.st = &gl_st;
+ glyph.size = &gl_size;
+
+ line.st = &ln_st;
+ line.size = &ln_size;
+ ln_st.y = TextStartY; //line start coordinate Y
+
+ if(DrawFlags & EFI_HII_OUT_FLAG_TRANSPARENT)
+ Transparent = TRUE;
+
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL && Link->LineHeight != 0) //loop by strings
+ {
+ /* init line rectangle */
+ ln_st.x = TextStartX; //line start coordinate X
+ ln_size.x = Link->LineWidth; //line width
+ ln_size.y = Link->LineHeight; //line height
+
+ origin.x = ln_st.x;
+ origin.y = ln_st.y + Link->BaseLineOffset;
+
+ for(i = Link->StartIndex; i <= Link->EndIndex; i++)
+ {
+ CurrentSymbol = DrawString[i];
+ if((DrawFlags & EFI_HII_IGNORE_LINE_BREAK) && IsLineBreak(CurrentSymbol))
+ continue;
+
+ Status = IntGetGlyph(CurFont, CurrentSymbol, &Cell, &GlyphBlock, &Free);
+ if(EFI_ERROR(Status))
+ return;
+
+ if(Status == EFI_WARN_UNKNOWN_GLYPH && (DrawFlags & EFI_HII_IGNORE_IF_NO_GLYPH)) {
+ if(Free)
+ pBS->FreePool(GlyphBlock);
+ continue;
+ }
+ /* init glyph rectangle */
+ gl_st.x = origin.x + Cell.OffsetX;
+ gl_st.y = origin.y - (Cell.Height + Cell.OffsetY);
+ gl_size.x = Cell.Width;
+ gl_size.y = Cell.Height;
+
+ if(CheckVisible(&glyph, &line)) {
+ /* symbol is visible at least partially */
+ /* at this point symbol rect coordinates were adjusted to fit visible area */
+ DrawGlyph(gl_st.x, gl_st.y, gl_size.x, gl_size.y, GlyphBlock, Transparent, ImageBlt, Cell.Width);
+ }
+
+ ln_st.x += Cell.AdvanceX;
+ ln_size.x = ((INTN)ln_size.x <= Cell.AdvanceX) ? 0 : ln_size.x - Cell.AdvanceX;
+ origin.x += Cell.AdvanceX;
+
+ if(Free)
+ pBS->FreePool(GlyphBlock);
+ } //end of drawing line
+
+ ln_st.y += ln_size.y;
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/HiiFontEx.c b/Core/CORE_DXE/UefiHii/HiiFontEx.c
new file mode 100644
index 0000000..32557da
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiFontEx.c
@@ -0,0 +1,1332 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFontEx.c 2 9/17/13 10:19p Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/17/13 10:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFontEx.c $
+//
+// 2 9/17/13 10:19p Thomaschen
+// Update for EIP105534 and EIP126176.
+//
+// 1 11/21/12 4:08a Wesleychen
+// Update rev.6 for EIP105534.
+// 11 5/16/13 5:01p Artems
+// [TAG] EIP123904
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] HiiFont and HiiConfig SCT tests are failed
+// [RootCause] Regression bugs when implementing new features or spec
+// updates
+// [Solution] Fixed code logic
+// [Files] HiiConfig.c HiiFontEx.c
+//
+// 10 5/02/13 1:52p Artems
+// [TAG] EIP121673
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Incorrect line width returned by function StringToImage
+// [RootCause] When determine line width function ignored flag
+// "IGNORE_IF_NO_GLYPH"
+// so line width was bigger if some glyphs were absent
+// [Solution] Modified code logic to not count width of absent glyphs
+// [Files] HiiFontEx.c
+//
+// 9 5/02/13 1:43p Artems
+// [TAG] EIP113105
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Wording for proportional font display was vague. After
+// clarification
+// code logic was slightly changed
+// [Files] HiiFontEx.c HiiPrivate.h
+//
+// 8 3/26/13 3:18p Artems
+// [TAG] EIP119250
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang on Setup entry
+// [RootCause] Incorrect boundaries checking in HiiFontEx.c function
+// CheckVisible()
+// [Solution] Changed checking condition
+// [Files] HiiFontEx.c
+//
+// 7 2/25/13 4:44p Artems
+// [TAG] EIP101673
+// [Category] New Feature
+// [Description] Add support for AMI custom large fixed font
+// [Files] HiiDatabase.c HiiFontEx.c HiiPrivate.h UefiHiiUtils.c GC.c
+// new LargeFont Core modulePart
+//
+// 6 11/14/12 6:03p Artems
+// [TAG] EIP105534
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] system hangs during SCT execution
+// [RootCause] Incorrect handling of FORM_FEED escape character in
+// StringToImage function
+// [Solution] Graphics console - added flag to ignore line breaks
+// HiiFont - fixed multiline drawing logic
+// [Files] Gc.c HiiFont.c HiiFontEx.c
+//
+// 5 8/24/12 5:34p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] One character is not displayed properly
+// [RootCause] Never accounted for the case, where character is
+// completely below base line
+// [Solution] added check that character height is less than OffsetY
+// [Files] HiiFontEx.c
+//
+// 4 6/15/12 12:21p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] doesn't build in 32-bit mode
+// [RootCause] Signed/Unsigned mismatch reported by 32-bit compiler
+// [Solution] typecasted one parameter to INTN
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 3 6/14/12 6:32p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio fixed SCT reported
+// bugs
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 2 5/24/12 3:00p Artems
+// [TAG] EIP83593
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] system dead loops in HiiGetFontInfo function
+// [RootCause] When loop through linked list of installed fonts pointer
+// was not updated
+// [Solution] Added pointer update
+// [Files] HiiFontEx.c
+//
+// 1 5/22/12 3:29p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support
+// [Files] HiiFontEx.c HiiFont.c HiiDatabase.c HiiString.c HiiPrivate.h
+// UefiHii.h
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiFontEx.c
+//
+// Description: Proportional font support
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <UefiHii.h>
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+#define LOOSE_SIZE_MARGIN 4
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+extern SIMPLE_FONT DefaultFont[];
+extern EFI_FONT_HANDLE CurFont; //font to use
+extern CHAR16 *DrawString; //string to draw
+extern EFI_HII_OUT_FLAGS DrawFlags;
+extern DLIST DrawLines;
+extern UINTN ImageWidth;
+extern UINTN ImageHeight;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefForegroundColor;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefBackgroundColor;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DuplicateGlyph
+//
+// Description:
+// This function duplicates glyph from Origin and assigns it to the Char
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+// IN CHAR16 Char - character to assign glyph to
+// IN CHAR16 Origin - character to assign glyph from
+//
+// Output:
+// EFI_NOT_FOUND - glyph for Origin character not found
+// EFI_SUCCESS - glyph created successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to duplicate glyph
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DuplicateGlyph(
+ IN OUT FONT_LINK *Font,
+ IN CHAR16 Char,
+ IN CHAR16 Origin
+)
+{
+ EFI_STATUS Status;
+ GLYPH_LINK *Link = (GLYPH_LINK *)Font->Glyphs.pHead;
+ GLYPH_LINK *New;
+
+ while(Link != NULL) {
+ if(Link->Char == Origin)
+ break;
+ Link = (GLYPH_LINK *) Link->Link.pNext;
+ }
+
+ if(Link == NULL)
+ return EFI_NOT_FOUND;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(GLYPH_LINK), &New);
+ if(!EFI_ERROR(Status)) {
+ New->Char = Char;
+ New->Cell = Link->Cell;
+ New->GlyphBlock = Link->GlyphBlock;
+ DListAdd(&(Font->Glyphs), (DLINK *)New);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddGlyphs
+//
+// Description:
+// This function adds glyphs to specified font
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+// IN EFI_HII_GLYPH_INFO Cell - variable that contains font dimensions
+// IN UINT8 *GlyphBlock - pointer to glyph block
+// IN UINT16 Count - number of glyphs to add
+// IN CHAR16 Char - first character to assign glyph to
+// OUT UINTN *BytesProcessed - number of bytes from glyph block that were assigned
+//
+// Output:
+// EFI_SUCCESS - glyph created successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to add glyphs
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddGlyphs(
+ IN OUT FONT_LINK *Font,
+ IN EFI_HII_GLYPH_INFO Cell,
+ IN UINT8 *GlyphBlock,
+ IN UINT16 Count,
+ IN CHAR16 Char,
+ OUT UINTN *BytesProcessed
+)
+{
+ EFI_STATUS Status;
+ GLYPH_LINK *Glyph;
+ UINTN Bytes = ((Cell.Width + 7) / 8) * Cell.Height;
+ UINTN i;
+
+ for(i = 0; i < Count; i++) {
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(GLYPH_LINK), &Glyph);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Glyph->Cell = Cell;
+ Glyph->Char = Char;
+ Char++;
+ Glyph->GlyphBlock = GlyphBlock;
+ GlyphBlock += Bytes;
+ DListAdd(&(Font->Glyphs), (DLINK *)Glyph);
+ }
+
+ *BytesProcessed = Bytes * Count;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseGlyphs
+//
+// Description:
+// This function parses packed glyphs and creates glyphs for characters
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseGlyphs(
+ IN OUT FONT_LINK *Font
+)
+{
+ EFI_STATUS Status;
+ CHAR16 Current = 1;
+ EFI_HII_GLYPH_INFO Default = Font->FontPackage->Cell;
+ EFI_HII_GLYPH_INFO CurCell;
+ UINT8 *Walker = (UINT8 *)Font->FontPackage;
+ UINT8 *EndMarker;
+ UINTN Bytes;
+ UINT16 CurCount;
+ static const EFI_HII_GLYPH_INFO ZeroCell = { 0, 0, 0, 0, 0 };
+ EFI_HII_GLYPH_INFO ChangeCell;
+ UINTN BelowBaseLine;
+ UINTN AboveBaseLine;
+ UINTN MaxBelowBaseLine = 0;
+ UINTN MaxAboveBaseLine = 0;
+
+ EndMarker = Walker + Font->FontPackage->Header.Length;
+ Walker += Font->FontPackage->GlyphBlockOffset;
+ ChangeCell = Default;
+
+ do {
+ switch (*Walker) {
+ case EFI_HII_GIBT_SKIP1:
+ Current += ((EFI_HII_GIBT_SKIP1_BLOCK *)Walker)->SkipCount;
+ Walker += sizeof(EFI_HII_GIBT_SKIP1_BLOCK);
+ break;
+ case EFI_HII_GIBT_SKIP2:
+ Current += ((EFI_HII_GIBT_SKIP2_BLOCK *)Walker)->SkipCount;
+ Walker += sizeof(EFI_HII_GIBT_SKIP2_BLOCK);
+ break;
+ case EFI_HII_GIBT_EXT1:
+ Walker += sizeof(EFI_HII_GIBT_EXT1_BLOCK);
+ break;
+ case EFI_HII_GIBT_EXT2:
+ Walker += sizeof(EFI_HII_GIBT_EXT2_BLOCK);
+ break;
+ case EFI_HII_GIBT_EXT4:
+ Walker += sizeof(EFI_HII_GIBT_EXT4_BLOCK);
+ break;
+ case EFI_HII_GIBT_DEFAULTS:
+ Default = ((EFI_HII_GIBT_DEFAULTS_BLOCK *)Walker)->Cell;
+ ChangeCell = Default;
+ Walker += sizeof(EFI_HII_GIBT_DEFAULTS_BLOCK);
+ break;
+ case EFI_HII_GIBT_END:
+ break;
+ case EFI_HII_GIBT_GLYPH:
+ CurCell = ((EFI_HII_GIBT_GLYPH_BLOCK *)Walker)->Cell;
+ ChangeCell = CurCell;
+ Walker += sizeof(EFI_HII_GIBT_GLYPH_BLOCK);
+ Status = AddGlyphs(Font, CurCell, Walker, 1, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current++;
+ break;
+ case EFI_HII_GIBT_GLYPH_DEFAULT:
+ Walker += sizeof(EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK);
+ Status = AddGlyphs(Font, Default, Walker, 1, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current++;
+ break;
+ case EFI_HII_GIBT_GLYPHS:
+ CurCell = ((EFI_HII_GIBT_GLYPHS_BLOCK *)Walker)->Cell;
+ CurCount = ((EFI_HII_GIBT_GLYPHS_BLOCK *)Walker)->Count;
+ ChangeCell = CurCell;
+ Walker += sizeof(EFI_HII_GIBT_GLYPHS_BLOCK);
+ Status = AddGlyphs(Font, CurCell, Walker, CurCount, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current += CurCount;
+ break;
+ case EFI_HII_GIBT_GLYPHS_DEFAULT:
+ CurCount = ((EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK *)Walker)->Count;
+ Walker += sizeof(EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK);
+ Status = AddGlyphs(Font, Default, Walker, CurCount, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current += CurCount;
+ break;
+ case EFI_HII_GIBT_DUPLICATE:
+ Status = DuplicateGlyph(Font, Current, ((EFI_HII_GIBT_DUPLICATE_BLOCK *)Walker)->CharValue);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += sizeof(EFI_HII_GIBT_DUPLICATE_BLOCK);
+ Current++;
+ break;
+ default:
+ return EFI_NOT_FOUND;
+ }
+
+ if(MemCmp(&ChangeCell, (VOID *)&ZeroCell, sizeof(EFI_HII_GLYPH_INFO))) {
+ if(ChangeCell.OffsetY < 0) {
+ BelowBaseLine = (UINTN)(0 - ChangeCell.OffsetY);
+ AboveBaseLine = (ChangeCell.Height > BelowBaseLine) ? (ChangeCell.Height - BelowBaseLine) : 0;
+ } else {
+ AboveBaseLine = ChangeCell.Height + ChangeCell.OffsetY;
+ BelowBaseLine = 0;
+ }
+ MaxBelowBaseLine = (MaxBelowBaseLine >= BelowBaseLine) ? MaxBelowBaseLine : BelowBaseLine;
+ MaxAboveBaseLine = (MaxAboveBaseLine >= AboveBaseLine) ? MaxAboveBaseLine : AboveBaseLine;
+ ChangeCell = ZeroCell;
+ }
+
+ } while(*Walker != 0 && Walker <= EndMarker);
+
+ Font->FontHeight = MaxBelowBaseLine + MaxAboveBaseLine;
+ Font->FontBaseLine = MaxAboveBaseLine;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RepackGlyphBlock
+//
+// Description:
+// This function repacks glyph block of AMI custom font package to be similar
+// to proportional font glyph block for easier processing
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RepackGlyphBlock(
+ IN UINT8 *GlyphBlock,
+ IN UINT16 Width,
+ IN UINT16 Height
+)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT8 *Tmp;
+ UINT16 Line;
+ UINT16 i, j, k = 0;
+
+ Line = (Width + 7) / 8; //how many bytes describe one line of glyph
+ Size = Line * Height;
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, &Tmp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < Height; i++) {
+ for(j = 0; j < Line; j++) {
+ Tmp[k] = GlyphBlock[i + j * Height];
+ k++;
+ }
+ }
+ MemCpy(GlyphBlock, Tmp, Size);
+ pBS->FreePool(Tmp);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseAmiGlyphs
+//
+// Description:
+// This function parses custom AMI packed glyphs and creates glyphs for characters
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseAmiGlyphs(
+ IN OUT FONT_LINK *Font
+)
+{
+ EFI_STATUS Status;
+ EFI_NARROW_GLYPH *Walker;
+ EFI_HII_GLYPH_INFO CurCell;
+ AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *AmiHdr;
+ UINT16 i;
+ UINTN Bytes;
+
+ AmiHdr = (AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *)Font->FontPackage;
+ CurCell.Width = AmiHdr->Width;
+ CurCell.Height = AmiHdr->Height;
+ CurCell.OffsetX = 0;
+ CurCell.OffsetY = 0;
+ Walker = (EFI_NARROW_GLYPH *)(AmiHdr + 1);
+ for(i = 0; i < AmiHdr->NumberOfNarrowGlyphs; i++) {
+ CurCell.AdvanceX = (Walker->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : CurCell.Width;
+ Status = RepackGlyphBlock(Walker->GlyphCol1, CurCell.Width, CurCell.Height);
+ if(EFI_ERROR(Status))
+ return Status;
+ Status = AddGlyphs(Font, CurCell, Walker->GlyphCol1, 1, Walker->UnicodeWeight, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Walker = (EFI_NARROW_GLYPH *)(Walker->GlyphCol1 + Bytes);
+ }
+
+ Font->FontHeight = AmiHdr->Height;
+ Font->FontBaseLine = AmiHdr->Height;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseFontsPackage
+//
+// Description:
+// This function parses font package
+//
+// Input:
+// IN EFI_HII_FONT_PACKAGE_HDR *Package - pointer to font package
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseFontsPackage(
+ IN EFI_HII_FONT_PACKAGE_HDR *Package
+)
+{
+ EFI_STATUS Status;
+ EFI_HII_FONT_PACKAGE_HDR *Copy;
+ FONT_LINK *Font;
+
+/* first make global copy of the package */
+ Status = pBS->AllocatePool(EfiBootServicesData, Package->Header.Length, &Copy);
+ if(EFI_ERROR(Status))
+ return Status;
+ MemCpy(Copy, Package, Package->Header.Length);
+
+/* create Font link */
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(FONT_LINK), &Font);
+ if(EFI_ERROR(Status))
+ return Status;
+
+/* initialize font link */
+ Font->FontPackage = Copy;
+ DListInit(&(Font->Glyphs));
+
+ if(Package->Header.Type == AMI_HII_PACKAGE_FONTS)
+ Status = ParseAmiGlyphs(Font);
+ else
+ Status = ParseGlyphs(Font);
+
+ if(!EFI_ERROR(Status))
+ DListAdd(&(PrivateData.FontList), (DLINK *)Font);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchName
+//
+// Description:
+// This function checks whether passed name matches name of the passed font
+//
+// Input:
+// IN FONT_LINK *Font - pointer to font
+// IN CHAR16 *FontName - pointer to font name to match with
+// IN FONT_MATCH_MASK Mask - matching rules
+//
+// Output:
+// TRUE - names are matched
+// FALSE - names are not matched
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchName(
+ IN FONT_LINK *Font,
+ IN CHAR16 *FontName,
+ IN FONT_MATCH_MASK Mask
+)
+{
+ UINT8 *Walker;
+
+ if(Mask.MatchName == MATCH_INGNORE)
+ return TRUE;
+
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS &&
+ !Wcscmp(FontName, L"Ami font"))
+ return TRUE;
+
+ Walker = (UINT8 *)Font->FontPackage;
+ Walker += sizeof(EFI_HII_FONT_PACKAGE_HDR);
+ /* now Walker points to font name */
+ if(Wcscmp(FontName, (CHAR16 *)Walker))
+ return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchStyle
+//
+// Description:
+// This function checks whether passed style matches style of the passed font
+//
+// Input:
+// IN FONT_LINK *Font - pointer to font
+// IN EFI_HII_FONT_STYLE FontStyle - font style to match with
+// IN FONT_MATCH_MASK Mask - matching rules
+//
+// Output:
+// TRUE - styles are matched
+// FALSE - styles are not matched
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchStyle(
+ IN FONT_LINK *Font,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN FONT_MATCH_MASK Mask
+)
+{
+ EFI_HII_FONT_STYLE Cur;
+
+ if(Mask.MatchStyle == MATCH_INGNORE)
+ return TRUE;
+
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS)
+ Cur = EFI_HII_FONT_STYLE_NORMAL;
+ else
+ Cur = Font->FontPackage->FontStyle;
+
+ if(FontStyle == Cur)
+ return TRUE;
+
+/* when restyle is ordered we support interchange between Normal, Bold and Italic styles */
+ if(Mask.MatchStyle == MATCH_LOOSE &&
+ FontStyle <= 3 &&
+ Cur <= 3)
+ return TRUE;
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchSize
+//
+// Description:
+// This function checks whether passed size matches size of the passed font
+//
+// Input:
+// IN FONT_LINK *Font - pointer to font
+// IN UINT16 FontSize - font size to match with
+// IN FONT_MATCH_MASK Mask - matching rules
+//
+// Output:
+// TRUE - sizes are matched
+// FALSE - sizes are not matched
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchSize(
+ IN FONT_LINK *Font,
+ IN UINT16 FontSize,
+ IN FONT_MATCH_MASK Mask
+)
+{
+ UINT16 Cur;
+
+ if(Mask.MatchSize == MATCH_INGNORE)
+ return TRUE;
+
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS)
+ Cur = ((AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *)Font->FontPackage)->Height;
+ else
+ Cur = Font->FontPackage->Cell.Height;
+
+ if(FontSize == Cur)
+ return TRUE;
+
+/* when resize is ordered we support interchange sizes within +/- LOOSE_SIZE_MARGIN from given size */
+ if(Mask.MatchSize == MATCH_LOOSE &&
+ Cur <= FontSize + LOOSE_SIZE_MARGIN &&
+ Cur >= FontSize - LOOSE_SIZE_MARGIN)
+ return TRUE;
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindGlyph
+//
+// Description:
+// This function checks whether glyph for passed character is present, and returns it
+// if necessary
+//
+// Input:
+// IN DLIST Glyphs - linked list of glyphs to search within
+// IN CHAR16 Char - character value to return glyph for
+// OUT GLYPH_LINK **Match OPTIONAL - pointer to store returned glyph
+//
+// Output:
+// TRUE - glyph found
+// FALSE - glyph not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FindGlyph(
+ IN DLIST Glyphs,
+ IN CHAR16 Char,
+ OUT GLYPH_LINK **Match OPTIONAL
+)
+{
+ GLYPH_LINK *Link = (GLYPH_LINK *)Glyphs.pHead;
+
+ while(Link != NULL) {
+ if(Link->Char == Char) {
+ if(Match != NULL)
+ *Match = Link;
+ return TRUE;
+ }
+ Link = (GLYPH_LINK *)Link->Link.pNext;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchString
+//
+// Description:
+// This function checks whether all character glyphs are present for given string
+//
+// Input:
+// IN FONT_LINK *Font - pointer to the font
+// IN CONST EFI_STRING String - pointer to the string to check
+//
+// Output:
+// TRUE - all glyphs are present
+// FALSE - some glyphs are missing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchString(
+ IN FONT_LINK *Font,
+ IN CONST EFI_STRING String
+)
+{
+ CHAR16 *Tst;
+
+ if(String == NULL)
+ return TRUE;
+
+ Tst = String;
+
+ while(*Tst != 0) {
+ if(!FindGlyph(Font->Glyphs, *Tst, NULL))
+ return FALSE;
+ Tst++;
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFont
+//
+// Description:
+// This function tries to find font in database, that meets the criteria
+//
+// Input:
+// IN OUT EFI_FONT_HANDLE *FontHandle - handle in database to start search from
+// IN CHAR16 *FontName - pointer to the font name
+// IN EFI_HII_FONT_STYLE FontStyle - font style
+// IN UINT16 FontSize - font size
+// IN FONT_MATCH_MASK Mask - matching rules
+// IN CONST EFI_STRING String - pointer to string to verify glyphs presence
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindFont(
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CHAR16 *FontName,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN UINT16 FontSize,
+ IN FONT_MATCH_MASK Mask,
+ IN CONST EFI_STRING String
+)
+{
+ FONT_LINK *Font;
+
+ if(PrivateData.FontList.Size == 0)
+ /* no fonts in database */
+ return EFI_NOT_FOUND;
+
+ Font = (FONT_LINK *)PrivateData.FontList.pHead;
+
+/* check if handle passed is not NULL or dummy default font handle */
+ if((UINTN)(*FontHandle) != NULL && (UINTN)(*FontHandle) != DEFAULT_FONT_HANDLE) {
+ while(Font != NULL) {
+ if((VOID *)Font == *FontHandle)
+ break;
+ Font = (FONT_LINK *)Font->Link.pNext;
+ }
+ if(Font == NULL) {
+ /* end of font list - no matches */
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ /* match found, it was last returned font, move to the next */
+ Font = (FONT_LINK *)Font->Link.pNext;
+ if(Font == NULL) {
+ /* end of font list, last returned font was last indeed */
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ while(Font != NULL) {
+ /* loop through font list to find the match */
+ if(MatchName(Font, FontName, Mask) &&
+ MatchStyle(Font, FontStyle, Mask) &&
+ MatchSize(Font, FontSize, Mask) &&
+ MatchString(Font, String)) {
+ /* match is found */
+ *FontHandle = (EFI_FONT_HANDLE)Font;
+ return EFI_SUCCESS;
+ }
+ Font = (FONT_LINK *)Font->Link.pNext;
+ }
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillFontInfo
+//
+// Description:
+// This function returns EFI_FONT_DISPLAY_INFO data for given font
+//
+// Input:
+// IN EFI_FONT_HANDLE FontHandle - font handle to return info about
+// OUT EFI_FONT_DISPLAY_INFO **StringInfoOut - pointer where to store returned info
+//
+// Output:
+// EFI_SUCCESS - info returned
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FillFontInfo(
+ IN EFI_FONT_HANDLE FontHandle,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut
+)
+{
+ UINTN NameSize;
+ EFI_FONT_DISPLAY_INFO *Ret;
+ FONT_LINK *Font;
+ UINT8 *Walker;
+ EFI_STATUS Status;
+ static CHAR16 DefaultFontName[] = L"System font";
+
+ Font = (FONT_LINK *)FontHandle;
+ if((UINTN)Font != DEFAULT_FONT_HANDLE) {
+ Walker = (UINT8 *)Font->FontPackage;
+ Walker += sizeof(EFI_HII_FONT_PACKAGE_HDR);
+ } else {
+ Walker = (UINT8 *)DefaultFontName;
+ }
+
+ NameSize = Wcslen((CHAR16 *)Walker) * sizeof(CHAR16);
+
+/* font display info structure includes font info structure, where one CHAR16 already reserved
+ that's why Wcslen used instead fo Wcssize - null-terminator already accounted for */
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(EFI_FONT_DISPLAY_INFO) + NameSize, &Ret);
+ if(!EFI_ERROR(Status)) {
+ if((UINTN)Font != DEFAULT_FONT_HANDLE) {
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS) {
+ Ret->FontInfo.FontStyle = EFI_HII_FONT_STYLE_NORMAL;
+ Ret->FontInfo.FontSize = ((AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *)Font->FontPackage)->Height;
+ } else {
+ Ret->FontInfo.FontStyle = Font->FontPackage->FontStyle;
+ Ret->FontInfo.FontSize = Font->FontPackage->Cell.Height;
+ }
+ } else {
+ Ret->FontInfo.FontStyle = EFI_HII_FONT_STYLE_NORMAL;
+ Ret->FontInfo.FontSize = EFI_GLYPH_HEIGHT;
+ }
+ Wcscpy(Ret->FontInfo.FontName, (CHAR16 *)Walker);
+ *StringInfoOut = Ret;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IntGetGlyph
+//
+// Description:
+// This function returns glyph for given charactef from given font
+//
+// Input:
+// IN EFI_FONT_HANDLE FontHandle - font handle of the desired font
+// IN CHAR16 Char - character to return glyph for
+// OUT EFI_HII_GLYPH_INFO *Cell - pointer to store info about glyph dimensions
+// OUT UINT8 **GlyphBlock OPTIONAL - pointer to store glyph
+// OUT BOOLEAN *Free - pointer to return flag was memory allocated for glyph and
+// should be freed by caller
+//
+// Output:
+// EFI_SUCCESS - glyph returned
+// EFI_NOT_FOUND - glyph not found
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IntGetGlyph(
+ IN EFI_FONT_HANDLE FontHandle,
+ IN CHAR16 Char,
+ OUT EFI_HII_GLYPH_INFO *Cell,
+ OUT UINT8 **GlyphBlock OPTIONAL,
+ OUT BOOLEAN *Free
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_STATUS AllocStatus;
+ FONT_LINK *Font;
+ GLYPH_LINK *GlyphLink;
+ BOOLEAN Found;
+ SIMPLE_FONT Glyph;
+ UINT8 *WideGlyphBlock;
+ UINTN i;
+
+ *Free = FALSE;
+ Font = (FONT_LINK *)FontHandle;
+
+ if((UINTN)Font != DEFAULT_FONT_HANDLE) {
+ Found = FindGlyph(Font->Glyphs, Char, &GlyphLink);
+ if(!Found) {
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ Found = FindGlyph(Font->Glyphs, 0xfffd, &GlyphLink);
+ }
+ if(Found) {
+ *Cell = GlyphLink->Cell;
+ if(GlyphBlock)
+ *GlyphBlock = GlyphLink->GlyphBlock;
+ return Status;
+ }
+ Glyph = DefaultFont[0xfffd];
+ } else {
+ /* Default font requested */
+ Glyph = DefaultFont[(UINTN)Char];
+ if(Glyph.NarrowGlyph == NULL && Glyph.WideGlyph == NULL) {
+ Glyph = DefaultFont[0xfffd];
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ }
+ }
+/* if we're here we use system font - either because it was requested, or
+because supplied font doesn't have requested character or 0xfffd character
+!!!! It is assumed that system font always have 0xfffd character font */
+ Cell->Height = EFI_GLYPH_HEIGHT;
+ Cell->OffsetX = 0;
+ Cell->OffsetY = 0;
+ if(Glyph.NarrowGlyph != NULL) {
+ Cell->Width = EFI_GLYPH_WIDTH;
+ Cell->AdvanceX = ((Glyph.NarrowGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDTH;
+ if(GlyphBlock)
+ *GlyphBlock = (Glyph.NarrowGlyph)->GlyphCol1;
+ } else if(Glyph.WideGlyph != NULL) {
+ Cell->Width = EFI_GLYPH_WIDE_WIDTH;
+ Cell->AdvanceX = ((Glyph.WideGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDE_WIDTH;
+ if(GlyphBlock) {
+ AllocStatus = pBS->AllocatePool(EfiBootServicesData, sizeof(UINT8) * 2 * EFI_GLYPH_HEIGHT, &WideGlyphBlock);
+ if(EFI_ERROR(AllocStatus))
+ return AllocStatus;
+ for(i = 0; i < EFI_GLYPH_HEIGHT; i++) {
+ WideGlyphBlock[2 * i] = (Glyph.WideGlyph)->GlyphCol1[i];
+ WideGlyphBlock[2 * i + 1] = (Glyph.WideGlyph)->GlyphCol2[i];
+ }
+ *GlyphBlock = WideGlyphBlock;
+ *Free = TRUE;
+ }
+ } else {
+ Cell->AdvanceX = 0;
+ return EFI_NOT_FOUND;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateLineSize
+//
+// Description:
+// This function updates dimensions in pixels of given line based on glyphs of current font
+//
+// Input:
+// IN OUT DRAW_LINE *Line - pointer to the line structure
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateLineSize(
+ IN OUT DRAW_LINE *Line
+)
+{
+ EFI_STATUS Status;
+ UINTN Width = 0;
+ UINTN i;
+ EFI_HII_GLYPH_INFO Cell;
+ BOOLEAN Dummy;
+
+ for(i = Line->StartIndex; i <= Line->EndIndex; i++) {
+ if((DrawFlags & EFI_HII_IGNORE_LINE_BREAK) && IsLineBreak(DrawString[i]))
+ continue;
+
+ Status = IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if(Status == EFI_WARN_UNKNOWN_GLYPH && (DrawFlags & EFI_HII_IGNORE_IF_NO_GLYPH))
+ continue;
+
+ Width = (Cell.AdvanceX < 0) ? Width : Width + (UINT16)Cell.AdvanceX;
+ }
+ Line->LineWidth = Width;
+ Line->LineHeight = ((UINTN)CurFont == DEFAULT_FONT_HANDLE) ? Cell.Height : ((FONT_LINK *)CurFont)->FontHeight;
+ Line->BaseLineOffset = ((UINTN)CurFont == DEFAULT_FONT_HANDLE) ? Cell.Height : ((FONT_LINK *)CurFont)->FontBaseLine;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ClipLine
+//
+// Description:
+// This function updates dimensions in pixels of given line to fit given width
+//
+// Input:
+// IN OUT DRAW_LINE *Line - pointer to the line structure
+// IN UINTN Width - width to fit
+// IN BOOLEAN ClipClean - clipping mode
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ClipLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width,
+ IN BOOLEAN ClipClean
+)
+{
+ UINTN Excess;
+ UINTN i;
+ EFI_HII_GLYPH_INFO Cell;
+ BOOLEAN Dummy;
+
+ Excess = Line->LineWidth - Width;
+
+ for(i = Line->EndIndex; i >= Line->StartIndex; i--) {
+ IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if ((INTN)Excess <= Cell.AdvanceX)
+ break;
+ Excess -= Cell.AdvanceX;
+ Line->LineWidth -= Cell.AdvanceX;
+ }
+
+ if(Excess == Cell.AdvanceX || ClipClean) {
+ /* remove excess character */
+ i--;
+ Line->LineWidth -= Cell.AdvanceX;
+ IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if(Cell.AdvanceX == 0)
+ /* the previous character is non-spacing -remove it also */
+ i--;
+ } else {
+ /* perform partial clipping */
+ Line->LineWidth -= Excess;
+ }
+ Line->EndIndex = i;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WrapLine
+//
+// Description:
+// This function updates dimensions in pixels of given line to fit given width
+// and creates additional line if necessary
+//
+// Input:
+// IN OUT DRAW_LINE *Line - pointer to the line structure
+// IN UINTN Width - width to fit
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WrapLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width
+)
+{
+ UINTN Excess;
+ UINTN i;
+ UINTN NewEnd;
+ UINTN NewStart;
+ DRAW_LINE *NewLine;
+ EFI_HII_GLYPH_INFO Cell;
+ BOOLEAN Dummy;
+ UINTN Save;
+
+ Excess = Line->LineWidth - Width;
+
+ for(i = Line->EndIndex; (i >= Line->StartIndex && i != 0); i--) {
+ IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if ((INTN)Excess <= Cell.AdvanceX)
+ break;
+ Excess -= Cell.AdvanceX;
+ }
+ if(i == 0 || i == Line->StartIndex) {
+ Line->EndIndex = i;
+ Line->LineWidth = 0;
+ return EFI_SUCCESS;
+ } else {
+ Save = i; //save index of first excess character
+ } //we will you it if no break opp arises for clip_clean operation
+
+/* we skipped excessed characters - start search for line break opp */
+ for(; (i >= Line->StartIndex && i != 0); i--) {
+ if(IsLineBreakOpp(DrawString[i])) {
+ /* we found line break opportunity */
+ NewEnd = Line->EndIndex;
+ NewStart = i + 1;
+ Line->EndIndex = i;
+ UpdateLineSize(Line);
+ if(Line->LineWidth > Width)
+ /* case when line-break opp character is partially visible - skip it */
+ Line->EndIndex--;
+ /* add a new line */
+ NewLine = (DRAW_LINE *)CreateNewLink(sizeof(UINTN) * 5);
+ if(NewLine == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ NewLine->StartIndex = NewStart;
+ NewLine->EndIndex = NewEnd;
+ UpdateLineSize(NewLine);
+ DListInsert(&DrawLines, (DLINK *)NewLine, (DLINK *)Line);
+ return EFI_SUCCESS;
+ }
+ }
+/* if we're here, no line break opp present, use clip clean */
+ Line->EndIndex = Save - 1;
+ UpdateLineSize(Line);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDrawImageSize
+//
+// Description:
+// This function returns size of image necessary to fit processing string
+// including all wraps and clips
+//
+// Input:
+// OUT UINTN *Width - pointer to store required width
+// OUT UINTN *Height - pointer to store required height
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetDrawImageSize(
+ OUT UINTN *Width,
+ OUT UINTN *Height
+)
+{
+ DRAW_LINE *Link;
+ UINTN MaxWidth = 0;
+ UINTN MaxHeight = 0;
+
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL)
+ {
+ MaxWidth = (MaxWidth < Link->LineWidth) ? Link->LineWidth : MaxWidth;
+ MaxHeight += Link->LineHeight;
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ *Width = MaxWidth;
+ *Height = MaxHeight;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PixelSet
+//
+// Description:
+// This function checks whether pixel with given coordinates is set in given glyph
+//
+// Input:
+// IN UINTN PosX - X coordinate of pixel
+// IN UINTN PosY - Y coordinate of pixel
+// IN UINT8 *GlyphBlock - pointer to glyph array
+// IN UINT16 CharWidth - width of character described by glyph
+//
+// Output:
+// TRUE - pixel is set
+// FALSE - pixel is not set
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN PixelSet(
+ IN UINTN PosX,
+ IN UINTN PosY,
+ IN UINT8 *GlyphBlock,
+ IN UINT16 CharWidth
+)
+{
+ UINTN Step;
+ UINTN Index;
+ UINT8 Bit;
+
+ Step = (CharWidth + 7) / 8;
+ Index = (PosY * Step) + (PosX / 8);
+
+ Bit = (0x80 >> (PosX % 8));
+
+ return (Bit & GlyphBlock[Index]);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DrawGlyph
+//
+// Description:
+// This function draws given glyph on given bitmap
+//
+// Input:
+// IN UINTN StartX - start X coordinate of glyph
+// IN UINTN StartY - start Y coordinate of glyph
+// IN UINTN SizeX - width of glyph
+// IN UINTN SizeY - height of glyph
+// IN UINT8 *GlyphBlock - pointer to glyph array
+// IN BOOLEAN Transparent - flag if image should be transparent
+// IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt - bitmap to draw on
+// IN UINT16 CharWidth - width of character described by glyph
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DrawGlyph(
+ IN UINTN StartX,
+ IN UINTN StartY,
+ IN UINTN SizeX,
+ IN UINTN SizeY,
+ IN UINT8 *GlyphBlock,
+ IN BOOLEAN Transparent,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt,
+ IN UINT16 CharWidth
+)
+{
+ UINTN i;
+ UINTN j;
+ UINTN Index;
+ UINTN Base;
+
+ Base = StartX + StartY * ImageWidth;
+ for(i = 0; i < SizeY; i++ ) {
+ for(j = 0; j < SizeX; j++) {
+ Index = Base + i * ImageWidth + j;
+ if(PixelSet(j, i, GlyphBlock, CharWidth)) {
+ Blt[Index] = DefForegroundColor;
+ } else if (!Transparent) {
+ Blt[Index] = DefBackgroundColor;
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckVisible
+//
+// Description:
+// This function checks whether glyph is withing given image rectangle,
+// and clips glyph rectangle if necessary
+//
+// Input:
+// IN OUT RECT_COORD *Glyph - pointer to glyph rectangle
+// IN RECT_COORD *Image - pointer to image rectangle
+//
+// Output:
+// TRUE - glyph is visible (at least partially)
+// FALSE - glyph is out of image boundaries
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckVisible(
+ IN OUT RECT_COORD *Glyph,
+ IN RECT_COORD *Image
+)
+{
+ UINTN delta_x;
+ UINTN delta_y;
+
+/* check whether glyph within given image rectangle */
+ if(Glyph->st->x >= (Image->st->x + Image->size->x) ||
+ Glyph->st->y >= (Image->st->y + Image->size->y))
+ return FALSE;
+
+/* clip glyph size if necessary */
+ delta_x = (Image->st->x < Glyph->st->x) ? Glyph->st->x - Image->st->x : 0;
+ delta_y = (Image->st->y < Glyph->st->y) ? Glyph->st->y - Image->st->y : 0;
+
+ if(Glyph->size->x > (Image->size->x - delta_x))
+ Glyph->size->x = Image->size->x - delta_x;
+
+ if(Glyph->size->y > (Image->size->y - delta_y))
+ Glyph->size->y = Image->size->y - delta_y;
+ return TRUE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/HiiPrivate.h b/Core/CORE_DXE/UefiHii/HiiPrivate.h
new file mode 100644
index 0000000..9023189
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiPrivate.h
@@ -0,0 +1,885 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiPrivate.h 2 9/18/13 1:41a Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/18/13 1:41a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiPrivate.h $
+//
+// 2 9/18/13 1:41a Thomaschen
+// Update for EIP126176.
+//
+// 16 5/02/13 1:48p Artems
+// [TAG] EIP113105
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Wording for proportional font display was vague. After
+// clarification
+// code logic was slightly changed
+// [Files] HiiFontEx.c HiiPrivate.h
+//
+// 14 2/25/13 4:45p Artems
+// [TAG] EIP101673
+// [Category] New Feature
+// [Description] Add support for AMI custom large fixed font
+// [Files] HiiDatabase.c HiiFontEx.c HiiPrivate.h UefiHiiUtils.c GC.c
+// new LargeFont Core modulePart
+//
+// 13 8/15/12 3:36p Artems
+// [TAG] EIP96755
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Strings in new language added at runtime lost during export
+// [RootCause] Every language represented by its own string package.
+// When
+// strings of new language added at runtime, they're added to database,
+// but not to the list of packages. Export function is working with
+// list of packages, so new language strings will be missed
+// [Solution] Added code to create new string package at runtime when
+// new string
+// of new language is added to database
+// [Files] HiiPrivate.h HiiString.c
+//
+// 12 5/22/12 4:16p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+// UefiHii.h
+//
+// 11 1/05/12 5:05p Artems
+// EIP 76735: Font FFS file is not loaded in framework mode, when in
+// nested FV
+//
+// 10 5/13/11 6:14p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 9 5/13/11 5:17p Artems
+// Function CompareGuid (native EdkII) renamed to HiiCompareGuid to avoid
+// collusion
+//
+// 8 5/05/11 4:14p Artems
+// Add signal "layout changed" event if current layout is deleted
+//
+// 7 1/05/11 12:41p Artems
+// EIP 50995: Added checking of driver handle before adding packages to
+// HII database
+//
+// 6 11/05/10 5:17p Artems
+// EIP 46880: Fixed bug, where two functions referred to the same global
+// pointer
+//
+// 5 9/30/10 6:11p Artems
+// EIP 44657 Added GetAltConfig functionality
+//
+// 4 1/29/10 5:43p Artems
+// EIP 34553 Updated function ExportPackageLists to support NULL pointer
+// as input
+//
+// 3 12/04/09 11:16a Artems
+// Remove keyboard layout functionality added
+//
+// 2 12/03/09 6:04p Artems
+// SCT bug fix
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HiiPrivate.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __HII_PRIVATE__H__
+#define __HII_PRIVATE__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <AmiDxeLib.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/HiiFont.h>
+#include <Protocol/HiiConfigRouting.h>
+
+#define NULL_GUID \
+ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
+
+#define PACKAGE_LIST_RECORD_SIGNATURE 0x53524c80 //"PLRS"
+#define NOTIFY_LIST_RECORD_SIGNATURE 0x53524c4e //"NLRS"
+
+#define DEFAULT_FONT_HANDLE 0xDEADF000
+#define AMI_HII_PACKAGE_FONTS 0xE1
+
+#pragma pack (push,1)
+
+typedef struct _PACKAGE_LIST_RECORD {
+ DLINK Link;
+ UINT32 Signature;
+ EFI_GUID Guid;
+ EFI_HANDLE DriverHandle;
+ DLIST PackageList;
+ DLIST LanguageList;
+ DLIST StringFontList;
+ DBE_DATABASE StringDb;
+} PACKAGE_LIST_RECORD;
+
+typedef struct _NOTIFY_RECORD {
+ DLINK Link;
+ UINT32 Signature;
+ UINT8 PackageType;
+ EFI_GUID PackageGuid;
+ EFI_HII_DATABASE_NOTIFY PackageNotifyFn;
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType;
+} NOTIFY_RECORD;
+
+typedef struct _HII_DATABASE_PRIVATE_DATA {
+ EFI_HII_DATABASE_PROTOCOL DatabaseProtocol;
+ EFI_HII_STRING_PROTOCOL StringProtocol;
+ EFI_HII_FONT_PROTOCOL FontProtocol;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL ConfigRoutingProtocol;
+ DLIST PackList;
+ DLIST NotifyList;
+ DLIST KeyLayoutList;
+ DLIST FontList;
+ EFI_HII_KEYBOARD_LAYOUT *CurrentLayout;
+} HII_DATABASE_PRIVATE_DATA;
+
+typedef struct _PACKAGE_LINK {
+ DLINK Link;
+ EFI_HII_PACKAGE_HEADER Package;
+} PACKAGE_LINK;
+
+typedef struct _KEY_LAYOUT_LINK {
+ DLINK Link;
+ EFI_HII_KEYBOARD_LAYOUT Layout;
+} KEY_LAYOUT_LINK;
+
+typedef struct _SIMPLE_FONT {
+ EFI_NARROW_GLYPH *NarrowGlyph;
+ EFI_WIDE_GLYPH *WideGlyph;
+} SIMPLE_FONT;
+
+typedef struct _FONT_LINK {
+ DLINK Link;
+ EFI_HII_FONT_PACKAGE_HDR *FontPackage;
+ UINTN FontHeight;
+ UINTN FontBaseLine;
+ DLIST Glyphs;
+} FONT_LINK;
+
+typedef struct _STRING_FONT_LINK {
+ DLINK Link;
+ UINT16 FontId;
+ UINT32 FontInfoSize;
+// EFI_FONT_INFO FontInfo;
+} STRING_FONT_LINK;
+
+typedef struct _GLYPH_LINK {
+ DLINK Link;
+ CHAR16 Char;
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 *GlyphBlock;
+} GLYPH_LINK;
+
+typedef struct _LANGUAGE_LINK {
+ DLINK Link;
+ UINT16 LastStringId;
+ CHAR8 Language[1];
+} LANGUAGE_LINK;
+
+typedef struct _STRING_RECORD {
+ UINT16 StringId;
+ UINT16 LanguageId;
+ UINT16 FontId;
+ CHAR16 String[1];
+} STRING_RECORD;
+
+typedef struct _DRAW_LINE {
+ DLINK Link;
+ UINTN StartIndex;
+ UINTN EndIndex;
+ UINTN LineHeight;
+ UINTN LineWidth;
+ UINTN BaseLineOffset;
+} DRAW_LINE;
+
+typedef struct _NAME_PATTERN
+{
+ UINTN Length;
+ CHAR16 *Tag;
+} NAME_PATTERN;
+
+typedef struct {
+ CHAR16 *ResultString;
+ UINTN MaxResultStringSize;
+ UINTN CurrentSize;
+} RESULT_BLOCK;
+
+#define MATCH_INGNORE 0
+#define MATCH_STRICT 1
+#define MATCH_LOOSE 2
+
+typedef struct {
+ UINT32 MatchName : 1;
+ UINT32 MatchSize : 2;
+ UINT32 MatchStyle : 2;
+ UINT32 Reserved : 1;
+} FONT_MATCH_MASK;
+
+typedef struct {
+ UINTN x;
+ UINTN y;
+} POINT_COORD;
+
+typedef struct {
+ POINT_COORD *st;
+ POINT_COORD *size;
+} RECT_COORD;
+
+typedef struct {
+ EFI_HII_PACKAGE_HEADER Header;
+ UINT16 NumberOfNarrowGlyphs;
+ UINT8 Height;
+ UINT8 Width;
+// EFI_NARROW_GLYPH NarrowGlyphs[]; //based on height and width given
+} AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR;
+
+#pragma pack (pop)
+
+//************ Database Protocol functions definition **************************
+
+EFI_STATUS HiiNewPack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ IN CONST EFI_HANDLE DriverHandle,
+ OUT EFI_HII_HANDLE *Handle
+);
+
+EFI_STATUS HiiRemovePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+);
+
+EFI_STATUS HiiUpdatePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList
+);
+
+EFI_STATUS HiiListPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN OUT UINTN *HandleBufferLength,
+ OUT EFI_HII_HANDLE *Handle
+);
+
+EFI_STATUS HiiExportPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
+);
+
+EFI_STATUS HiiRegisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
+ OUT EFI_HANDLE *NotifyHandle
+);
+
+EFI_STATUS HiiUnregisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+);
+
+EFI_STATUS HiiFindKeyboardLayouts (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_GUID *KeyGuidBuffer
+);
+
+EFI_STATUS HiiGetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout
+);
+
+EFI_STATUS HiiSetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid
+);
+
+EFI_STATUS HiiGetPackageListHandle (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageListHandle,
+ OUT EFI_HANDLE *DriverHandle
+);
+
+//************************* String protocol functions definition **********
+
+EFI_STATUS HiiNewString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ OUT EFI_STRING_ID *StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST CHAR16 *LanguageName OPTIONAL,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo
+);
+
+EFI_STATUS AmiHiiGetString(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN CONST CHAR8 *Language,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING String,
+ IN OUT UINTN *StringSize,
+ OUT EFI_FONT_INFO **StringFontInfo OPTIONAL
+);
+
+EFI_STATUS AmiHiiSetString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL
+);
+
+EFI_STATUS HiiGetLanguages (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN OUT CHAR8 *Languages,
+ IN OUT UINTN *LanguagesSize
+);
+
+EFI_STATUS HiiGetSecondLanguages(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN CONST CHAR8* FirstLanguage,
+ IN OUT CHAR8 *SecondLanguages,
+ IN OUT UINTN *SecondLanguagesSize
+);
+
+//************************* Font protocol functions definition ****************
+
+EFI_STATUS HiiStringToImage(
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL
+);
+
+EFI_STATUS HiiStringIdToImage (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8* Language,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL
+);
+
+EFI_STATUS HiiGetGlyph (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN CHAR16 Char,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
+ OUT EFI_IMAGE_OUTPUT **Blt,
+ OUT UINTN *Baseline OPTIONAL
+);
+
+EFI_STATUS HiiGetFontInfo (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
+ IN CONST EFI_STRING String OPTIONAL
+);
+
+//************************* Config Routing protocol functions definition ******
+
+EFI_STATUS HiiExtractConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+);
+
+EFI_STATUS HiiExportConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+);
+
+EFI_STATUS HiiRouteConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+);
+
+EFI_STATUS HiiBlockToConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigRequest,
+ IN CONST UINT8 *Block,
+ IN CONST UINTN BlockSize,
+ OUT EFI_STRING *Config,
+ OUT EFI_STRING *Progress
+);
+
+EFI_STATUS HiiConfigToBlock (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN OUT CONST UINT8 *Block,
+ IN OUT UINTN *BlockSize,
+ OUT EFI_STRING *Progress
+);
+
+EFI_STATUS HiiGetAltConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId,
+ OUT EFI_STRING *AltCfgResp
+);
+
+//*************************Service functions (not for public use)**************
+
+VOID InvokeRegisteredNotify (
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+);
+
+BOOLEAN FindAndRemovePackages (
+ IN EFI_HII_HANDLE Handle,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN BOOLEAN FindOnly
+);
+
+VOID RemovePackage (
+ IN EFI_HII_HANDLE Handle,
+ IN PACKAGE_LINK *Package
+);
+
+EFI_STATUS AddPackage(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+);
+
+EFI_STATUS AddPackages(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ BOOLEAN Update
+);
+
+EFI_STATUS UpdateStringPackages(
+ IN EFI_HII_HANDLE Handle
+);
+
+UINTN GetStringBlockSize(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language
+);
+
+VOID GetStringBlock(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language,
+ IN UINT8 *Buffer
+);
+
+BOOLEAN MatchPackage(
+ IN UINT8 PackageType,
+ IN EFI_GUID *PackageGuid,
+ IN EFI_HII_PACKAGE_HEADER *Package
+);
+
+BOOLEAN CheckIfPresent(
+ IN EFI_GUID *Guid,
+ IN EFI_HANDLE DriverHandle
+);
+
+EFI_HII_KEYBOARD_LAYOUT* FindLayoutByGuid(
+ IN EFI_GUID *Guid
+);
+
+EFI_STATUS ParseKeyLayoutPackage(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package
+);
+
+EFI_STATUS DeleteKeyboardLayout(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package
+);
+
+EFI_STATUS ParseSimpleFontsPackage(
+ IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package
+);
+
+EFI_STATUS ParseFontsPackage(
+ IN EFI_HII_FONT_PACKAGE_HDR *Package
+);
+
+EFI_STATUS ParseStringsPackage(
+ PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_HII_STRING_PACKAGE_HDR *Package
+);
+
+PACKAGE_LIST_RECORD* NewPackageListRecord(
+ VOID
+);
+
+NOTIFY_RECORD* NewNotifyRecord(
+ VOID
+);
+
+VOID* CreateNewLink(
+ UINT32 Size
+);
+
+VOID DeleteList(
+ DLIST *List
+);
+
+VOID DeleteStringsFromDatabase(DBE_DATABASE *Database);
+VOID DeleteSimpleFonts(IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package);
+
+UINT32 StrSize8(CHAR8 *String);
+
+UINT32 StrSize16(CHAR16 *String);
+
+VOID StrCpy8(CHAR8 *Dest, CHAR8 *Src);
+
+VOID StrCpy16(CHAR16 *Dest, CHAR16 *Src);
+
+INTN StrCmp8(CHAR8 *Dest, CHAR8 *Src);
+
+INTN StrCmp16(CHAR16 *Dest, CHAR16 *Src);
+
+EFI_STATUS AddLanguage(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ CHAR16* LanguageName,
+ UINT16 LastStringId
+);
+
+EFI_STATUS GetLanguageId(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ UINT16 *LanguageId,
+ LANGUAGE_LINK **Found
+);
+
+EFI_STATUS AddString(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 StringId,
+ UINT16 FontId,
+ EFI_STRING String
+);
+
+EFI_STATUS ExtractStrings(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 *StringId,
+ UINT16 FontId,
+ UINT16 StringCount,
+ BOOLEAN Compressed,
+ VOID *StringBlock
+);
+
+BOOLEAN IsLineBreak(CHAR16 Char);
+
+BOOLEAN IsLineBreakOpp(CHAR16 Char);
+
+UINTN GetGlyphWidth(CHAR16 Char);
+
+UINTN GetLineLength(UINTN StartIndex, UINTN EndIndex);
+
+UINTN GetClipLineLength(
+ UINTN StartIndex,
+ UINTN MaxLength,
+ BOOLEAN ClipClean,
+ UINTN *EndIndex
+);
+
+UINTN GetWrapIndex(
+ UINTN StartIndex,
+ UINTN MaxLength,
+ UINTN *EndIndex,
+ UINTN *StartIndex2
+);
+
+UINTN GetMaxLineLength(VOID);
+
+EFI_STATUS SplitByLineBreaks(EFI_STRING String);
+
+EFI_STATUS AdjustLineSize(VOID);
+
+VOID DrawNarrowGlyph(
+ UINTN StartX,
+ UINTN StartY,
+ UINTN SizeX,
+ UINTN SizeY,
+ CHAR16 Char,
+ BOOLEAN Transparent,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt
+);
+
+VOID DrawWideGlyph(
+ UINTN StartX,
+ UINTN StartY,
+ UINTN SizeX,
+ UINTN SizeY,
+ CHAR16 Char,
+ BOOLEAN Transparent,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt
+);
+
+VOID Draw(VOID);
+
+BOOLEAN CheckPattern(CHAR16 *String, NAME_PATTERN *Pattern);
+
+EFI_STATUS ExtractConfigString(CHAR16 *String, UINTN *NextIndex, CHAR16 **NewString);
+
+BOOLEAN CheckDevicePath(
+ IN UINT8 *DevicePath,
+ IN UINTN DeviceLength,
+ IN EFI_HII_PACKAGE_HEADER *Package);
+
+EFI_STATUS SearchDevicePath(UINT8 *DevicePach, UINTN DpLength, EFI_HANDLE *Handle);
+
+EFI_STATUS ExtractDevicePath(CHAR16 *ConfigString, UINT8 **DevicePath, UINTN *DpLength);
+
+EFI_STATUS FindDeviceHandle(
+ IN CHAR16 *ConfigString,
+ OUT EFI_HANDLE *Handle);
+
+BOOLEAN IsHexDigit(CHAR16 Char);
+UINT8 HexValue(CHAR8 Char);
+
+VOID StringToBlock(
+ IN CHAR16 *String,
+ IN UINTN StringSize,
+ OUT UINT8 *Block);
+
+EFI_STATUS CollectResults(CHAR16 *Result, UINTN Symbols, RESULT_BLOCK *ResultBlock);
+
+UINT32 GetValue(CHAR16 *String, UINTN Start, UINTN End);
+
+EFI_STATUS GetPatternValue(
+ CHAR16 *String,
+ UINTN *Index,
+ NAME_PATTERN *Pattern,
+ UINT32 *Value);
+
+EFI_STATUS GetStringValue(
+ CHAR16 *String,
+ UINTN *Index,
+ UINT8 *Output,
+ UINT32 Width);
+
+EFI_STATUS ReallocResultString(UINTN NewSize, RESULT_BLOCK *ResultBlock);
+
+EFI_STATUS CollectValueResults(UINT8 *Value, UINT32 Width, RESULT_BLOCK *ResultBlock);
+
+EFI_STATUS InitResultBlock(RESULT_BLOCK *ResultBlock);
+
+VOID WriteSwappedBuffer(
+ OUT UINT8 *Output,
+ IN UINT8 *Input,
+ IN UINTN Size);
+
+EFI_STATUS LoadSystemFont();
+
+EFI_STATUS ExportPack(
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer,
+ IN BOOLEAN FirstCall
+);
+
+VOID StringToChar16(
+ IN CHAR16 *String,
+ IN OUT UINTN *Size,
+ OUT CHAR16 *Block
+);
+
+BOOLEAN CompareDevicePath(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+BOOLEAN CompareName(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_STRING Name
+);
+
+BOOLEAN HiiCompareGuid(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid
+);
+
+EFI_STATUS CheckAltCfg (
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId
+);
+
+EFI_STATUS SignalKbLayoutChangedEvent(
+ VOID
+);
+
+EFI_STATUS FillFontInfo(
+ IN EFI_FONT_HANDLE FontHandle,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut
+);
+
+EFI_STATUS FindFont(
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CHAR16 *FontName,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN UINT16 FontSize,
+ IN FONT_MATCH_MASK Mask,
+ IN CONST EFI_STRING String
+);
+
+EFI_STATUS IntGetGlyph(
+ IN EFI_FONT_HANDLE Font,
+ IN CHAR16 Char,
+ OUT EFI_HII_GLYPH_INFO *Cell,
+ OUT UINT8 **GlyphBlock OPTIONAL,
+ OUT BOOLEAN *Free
+);
+
+VOID UpdateLineSize(
+ IN OUT DRAW_LINE *Line
+);
+
+VOID ClipLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width,
+ IN BOOLEAN ClipClean
+);
+
+BOOLEAN CheckVisible(
+ IN OUT RECT_COORD *Glyph,
+ IN RECT_COORD *Image
+);
+
+VOID DrawGlyph(
+ IN UINTN StartX,
+ IN UINTN StartY,
+ IN UINTN SizeX,
+ IN UINTN SizeY,
+ IN UINT8 *GlyphBlock,
+ IN BOOLEAN Transparent,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt,
+ IN UINT16 CharWidth
+);
+
+VOID GetDrawImageSize(
+ OUT UINTN *Width,
+ OUT UINTN *Height
+);
+
+EFI_STATUS WrapLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width
+);
+
+EFI_STATUS AddStringFont(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ IN UINT16 FontSize,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN CHAR16 *FontName,
+ OUT UINT16 *NewFontId OPTIONAL
+);
+
+UINT16 GetAvailableFontId(
+ IN PACKAGE_LIST_RECORD *PackageList
+);
+
+EFI_STATUS FindStringFontInfoByTemplate(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_FONT_INFO *Template,
+ OUT UINT16 *FontId
+);
+
+EFI_STATUS FindStingFontInfoById(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ OUT EFI_FONT_INFO **Info
+);
+
+VOID CreateLanguageName(
+ IN CHAR8 *RfcName,
+ OUT CHAR16* OutName,
+ UINTN MaxSize
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/CORE_DXE/UefiHii/HiiString.c b/Core/CORE_DXE/UefiHii/HiiString.c
new file mode 100644
index 0000000..91f2708
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiString.c
@@ -0,0 +1,1609 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiString.c 7 8/15/12 3:45p Artems $
+//
+// $Revision: 7 $
+//
+// $Date: 8/15/12 3:45p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiString.c $
+//
+// 7 8/15/12 3:45p Artems
+// [TAG] EIP96755
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Strings in new language added at runtime lost during export
+// [RootCause] Every language represented by its own string package.
+// When
+// strings of new language added at runtime, they're added to database,
+// but not to the list of packages. Export function is working with
+// list of packages, so new language strings will be missed
+// [Solution] Added code to create new string package at runtime when
+// new string
+// of new language is added to database
+// [Files] HiiPrivate.h HiiString.c
+//
+// 6 5/22/12 4:34p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+// UefiHii.h
+//
+//
+// 5 10/24/11 5:40p Artems
+// EIP 70530: Bug reported by SCT 2.3.1. Languages shold be compared
+// ignoring case
+//
+// 4 5/13/11 6:15p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 3 12/03/09 12:02p Aaronp
+// Fix for SCT GetSecondLanguages failures.
+//
+// 2 11/23/09 7:38p Felixp
+// HiiGetLanguages is updated to accept NULL language buffer when
+// *LanguagesSize is zero.
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiString.c
+//
+// Description: Hii string protocol functions implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+#define DEFAULT_FONT 0x100
+#define INVALID_FONT_ID 0xFEFE
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+
+DBE_OFFSET_KEY_CONTEXT StringDbKeyContext = {EFI_FIELD_OFFSET(STRING_RECORD ,StringId), 4 };
+DBE_KEY_FIELD StringDbKeyField = OFFSET_KEY(StringDbKeyContext);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AmiHiiGetString
+//
+// Description:
+// This function is HII String protocol function GetString implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN CHAR8 *Language - Language definition
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN EFI_STRING_ID StringId - String Id
+// OUT EFI_STRING String - Pointer to output string
+// IN OUT UINTN *StringSize - Pointer to string size value
+// OUT EFI_FONT_INFO *StringFontInfo - Pointer to returned string font info
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - String or StringSize or Language is NULL
+// EFI_NOT_FOUND - String not found
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiHiiGetString(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN CONST CHAR8 *Language,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING String,
+ IN OUT UINTN *StringSize,
+ OUT EFI_FONT_INFO **StringFontInfo OPTIONAL)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ UINT32 Size;
+ EFI_STATUS Status;
+ LANGUAGE_LINK *Ptr;
+ UINT32 i;
+ UINT16 SaveLanguage;
+
+ if (Language == NULL || StringId < 1 || StringSize == NULL || PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (String == NULL && *StringSize != 0)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ DbKey.StringId = StringId;
+ Status = GetLanguageId(Record, Language, &(DbKey.LanguageId), &Ptr);
+ if(EFI_ERROR(Status))
+ return EFI_INVALID_LANGUAGE;
+
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(EFI_ERROR(Status))
+ {
+ //string not found in database, try different languages
+ SaveLanguage = DbKey.LanguageId;
+ for(i = 0; i < Record->LanguageList.Size; i++)
+ {
+ if (i == SaveLanguage)
+ continue;
+ DbKey.LanguageId = (UINT16)i;
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ return EFI_INVALID_LANGUAGE; //string exists but with different language
+ }
+
+ return EFI_NOT_FOUND;
+ }
+
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+
+ Size = StrSize16(Found->String);
+
+ if(Size > *StringSize)
+ {
+ *StringSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ StrCpy16(String, Found->String);
+ *StringSize = Size;
+
+ if(StringFontInfo != NULL)
+ Status = FindStingFontInfoById(Record, Found->FontId, StringFontInfo);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AmiHiiSetString
+//
+// Description:
+// This function is HII String protocol function SetString implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN EFI_STRING_ID StringId - String Id
+// IN CHAR8 *Language - Language definition
+// IN EFI_STRING String - String to set
+// IN EFI_FONT_INFO *StringFontInfo - Pointer to string font info
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - String or Language is NULL
+// EFI_NOT_FOUND - String not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiHiiSetString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ UINT32 i;
+ UINT16 SaveLanguage;
+ LANGUAGE_LINK *Ptr;
+ EFI_STATUS Status;
+
+ if(String == NULL || Language == NULL || PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ DbKey.StringId = StringId;
+ Status = GetLanguageId(Record, Language, &(DbKey.LanguageId), &Ptr);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ { //updated string found in database - retreive font info
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ DbKey.FontId = Found->FontId;
+ DbeDelete(&(Record->StringDb), Found, TRUE);
+ }
+ else //try same StringId with different languages
+ {
+ SaveLanguage = DbKey.LanguageId;
+ for(i = 0; i < Record->LanguageList.Size; i++)
+ {
+ if (i == SaveLanguage)
+ continue;
+ DbKey.LanguageId = i;
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ break;
+ }
+ if(i == Record->LanguageList.Size)
+ return EFI_NOT_FOUND;
+
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ DbKey.FontId = Found->FontId;
+ DbKey.LanguageId = SaveLanguage;
+ }
+
+ if(StringFontInfo != NULL) {
+ Status = FindStringFontInfoByTemplate(Record, StringFontInfo, &DbKey.FontId);
+ if(EFI_ERROR(Status)) {
+ Status = AddStringFont(Record, INVALID_FONT_ID, StringFontInfo->FontSize,
+ StringFontInfo->FontStyle, StringFontInfo->FontName, &DbKey.FontId);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ }
+
+ Status = AddString(Record, DbKey.LanguageId, DbKey.StringId, DbKey.FontId, String);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiNewString
+//
+// Description:
+// This function is HII String protocol function NewString implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// OUT EFI_STRING_ID *StringId - Pointer to returned string Id
+// IN CHAR8 *Language - Language definition
+// IN CHAR16 *LanguageName - Language human readable name
+// IN EFI_STRING String - String to set
+// IN EFI_FONT_INFO *StringFontInfo - Pointer to string font info
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - String or Language or StringId is NULL
+// EFI_NOT_FOUND - Package list handle is invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiNewString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ OUT EFI_STRING_ID *StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST CHAR16 *LanguageName OPTIONAL,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+ EFI_STATUS Status;
+ UINT16 LanguageId;
+ LANGUAGE_LINK *Link;
+ UINT16 FontId;
+ CHAR16 DefaultName[80];
+
+ if(String == NULL || StringId == NULL || Language == NULL || PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ Status = GetLanguageId(Record, Language, &LanguageId, &Link);
+ if(EFI_ERROR(Status))
+ {
+ Status = AddLanguage(Record, Language, LanguageName, 0);
+ if(EFI_ERROR(Status))
+ return Status;
+ Status = GetLanguageId(Record, Language, &LanguageId, &Link);
+ //language added, now add language name string to database
+ if(LanguageName == NULL) {
+ CreateLanguageName(Language, DefaultName, 80 * sizeof(CHAR16));
+ LanguageName = DefaultName;
+ }
+ //at this point LastStringId has value LanguageName + 1
+ Status = AmiHiiSetString(This, PackageList, Link->LastStringId - 1, Language, LanguageName, NULL);
+ }
+
+ if(StringFontInfo != NULL) {
+ Status = FindStringFontInfoByTemplate(Record, StringFontInfo, &FontId);
+ if(EFI_ERROR(Status)) {
+ Status = AddStringFont(Record, INVALID_FONT_ID, StringFontInfo->FontSize,
+ StringFontInfo->FontStyle, StringFontInfo->FontName, &FontId);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ } else {
+ FontId = DEFAULT_FONT;
+ }
+
+ Status = AddString(Record, LanguageId, Link->LastStringId, FontId, String);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ *StringId = Link->LastStringId;
+
+ Link->LastStringId++;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetLanguages
+//
+// Description:
+// This function is HII String protocol function GetLanguages implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN OUT CHAR8 *Languages - Pointer to returned language buffer
+// IN OUT UINTN *LanguagesSize - Pointer to language buffer size
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - LanguagesSize or Languages is NULL
+// EFI_NOT_FOUND - Package list handle is invalid or NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetLanguages (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN OUT CHAR8 *Languages,
+ IN OUT UINTN *LanguagesSize
+)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+// EFI_STATUS Status;
+ LANGUAGE_LINK *Link;
+ UINTN Size = 0;
+
+ if(PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ if(LanguagesSize == NULL || Languages == NULL && *LanguagesSize != 0)
+ return EFI_INVALID_PARAMETER;
+
+ if(Record->LanguageList.Size == 0)
+ {
+ *LanguagesSize = 0;
+ *Languages = 0;
+ return EFI_SUCCESS;
+ }
+
+ Link = (LANGUAGE_LINK *)Record->LanguageList.pHead;
+ while(Link != NULL)
+ {
+ Size += StrSize8(Link->Language);
+ Link = (LANGUAGE_LINK *)Link->Link.pNext;
+ }
+
+ if(Size > *LanguagesSize)
+ {
+ *LanguagesSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *LanguagesSize = Size;
+
+ Link = (LANGUAGE_LINK *)Record->LanguageList.pHead;
+ while(Link != NULL)
+ {
+ Size = StrSize8(Link->Language);
+ Size--; //skip NULL-terminator
+ MemCpy(Languages, Link->Language, Size);
+ Languages += Size; //shift pointer
+ *Languages = ';'; //add delimiter
+ Languages++;
+ Link = (LANGUAGE_LINK *)Link->Link.pNext;
+ }
+
+ Languages--; //change delimiter to NULL-terminator
+ *Languages = 0;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetSecondLanguages
+//
+// Description:
+// This function is HII String protocol function GetSecondaryLanguages implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN CHAR8 *FirstLanguage - First language definition
+// IN OUT CHAR8 *Languages - Pointer to returned language buffer
+// IN OUT UINTN *LanguagesSize - Pointer to language buffer size
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - LanguagesSize or Languages is NULL
+// EFI_NOT_FOUND - Package list handle is invalid or NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetSecondLanguages(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN CONST CHAR8 *FirstLanguage,
+ IN OUT CHAR8 *SecondLanguages,
+ IN OUT UINTN *SecondLanguagesSize
+)
+{
+ EFI_STATUS Status;
+ UINTN Size = 0;
+ UINTN i = 0;
+
+ CHAR8 *Langs = NULL;
+
+ if(FirstLanguage == NULL || SecondLanguages == NULL || SecondLanguagesSize == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Get the size of all the languages in the Hii Package
+ Status = HiiGetLanguages(This, PackageList, NULL, &Size);
+
+ if(EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL)
+ return Status;
+
+ // Allocate space for the languages
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, &Langs);
+
+ if(!EFI_ERROR(Status))
+ // Get the langues into the temp buffer
+ Status = HiiGetLanguages(This, PackageList, Langs, &Size);
+
+ // find and remove the primary language from the string
+ if(!EFI_ERROR(Status))
+ {
+ Status = EFI_INVALID_LANGUAGE;
+
+ for(; i < Size; i++)
+ {
+ // check if the current offset matches the first language
+ if(MemCmp(Langs+i,FirstLanguage,StrSize8(FirstLanguage)-1) == 0)
+ {
+ Status = EFI_SUCCESS;
+
+ // copy the rest of the string on top of the primary strings location
+ pBS->CopyMem(Langs+i,Langs+i+StrSize8(FirstLanguage),StrSize8(Langs)-i-StrSize8(FirstLanguage));
+ break;
+ }
+ }
+ }
+
+ if(!EFI_ERROR(Status))
+ {
+ Status = EFI_BUFFER_TOO_SMALL;
+
+ // Check if the buffer is large enough to fit the secondary langues
+ if(*SecondLanguagesSize >= StrSize8(Langs))
+ {
+ Status = EFI_SUCCESS;
+ MemCpy(SecondLanguages, Langs, StrSize8(Langs));
+ }
+
+ // fill in the size of the secondary langauges
+ *SecondLanguagesSize = StrSize8(Langs);
+ }
+
+ if(Langs != NULL)
+ pBS->FreePool(Langs);
+
+ return Status;
+}
+
+// *************************** Service functions (not for public use) ************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateLanguageName
+//
+// Description:
+// This function creates human-readable language name from RFC name
+//
+// Input:
+// IN CHAR8 *RfcName - pointer to RFC name
+// OUT CHAR16* OutName - pointer where to store human-readable name
+// UINTN MaxSize - max size of output buffer in bytes
+//
+// Output:
+// UINT16 - number of strings in package
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CreateLanguageName(
+ IN CHAR8 *RfcName,
+ OUT CHAR16* OutName,
+ UINTN MaxSize)
+{
+ UINTN i;
+
+ for(i = 0; (RfcName[i] != 0 && i < (MaxSize / 2 - 1)); i++)
+ OutName[i] = RfcName[i];
+ OutName[i] = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStringPackage
+//
+// Description:
+// This function creates string package for language not existed in package list
+// at the time of submission to database
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where language belongs
+// IN CHAR8 *Language - Language RFC name
+//
+// Output:
+// UINT16 - number of strings in package
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 AddStringPackage(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language)
+{
+ UINT32 Size;
+ PACKAGE_LINK *Template;
+ PACKAGE_LINK *NewLink;
+ DLIST *PackList;
+ UINT16 LanguageStringId;
+ UINT32 i;
+ EFI_HII_STRING_PACKAGE_HDR *Hdr;
+ EFI_HII_STRING_PACKAGE_HDR *NewHdr;
+
+ PackList = &(PackageList->PackageList);
+ Template = (PACKAGE_LINK *)PackList->pHead;
+ while(Template != NULL) {
+ if(Template->Package.Type == EFI_HII_PACKAGE_STRINGS)
+ break;
+ Template = (PACKAGE_LINK *)Template->Link.pNext;
+ }
+
+ if(Template == NULL) {//no string packages in this package list
+ LanguageStringId = 1;
+ } else {
+ Hdr = (EFI_HII_STRING_PACKAGE_HDR *)&(Template->Package);
+ LanguageStringId = Hdr->LanguageName;
+ }
+
+ Size = sizeof(EFI_HII_STRING_PACKAGE_HDR) - 1;
+ Size += StrSize8(Language);
+
+ NewLink = (PACKAGE_LINK *) CreateNewLink(Size);
+ if(NewLink == NULL)
+ return 0;
+
+ NewLink->Package.Type = EFI_HII_PACKAGE_STRINGS;
+ NewLink->Package.Length = Size; //this is technically incorrect, but it will be updated upon export
+ NewHdr = (EFI_HII_STRING_PACKAGE_HDR *)&(NewLink->Package);
+ NewHdr->HdrSize = Size;
+ NewHdr->StringInfoOffset = Size;
+ if(Template == NULL) {
+ for(i = 0; i < 16; i++)
+ NewHdr->LanguageWindow[i] = 0;
+ } else {
+ for(i = 0; i < 16; i++)
+ NewHdr->LanguageWindow[i] = Hdr->LanguageWindow[i];
+ }
+ NewHdr->LanguageName = LanguageStringId;
+ StrCpy8(NewHdr->Language, Language);
+ DListAdd(PackList, (DLINK *)NewLink);
+ return LanguageStringId + 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddLanguage
+//
+// Description:
+// This function adds language to private HII database
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where language belongs
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN CHAR8 *Language - Language Id
+// IN CHAR16 *LanguageName - Pointer to human readable language name
+// IN UINT16 LastStringId - Last string Id on this language
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddLanguage(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ CHAR16* LanguageName,
+ UINT16 LastStringId)
+{
+ UINT32 Size1, Size2 = 0;
+ LANGUAGE_LINK *Link;
+ CHAR16 DefaultName[80];
+ UINT8 *Ptr;
+
+ Size1 = StrSize8(Language);
+
+ if(LanguageName == NULL) {
+ CreateLanguageName(Language, DefaultName, 80 * sizeof(CHAR16));
+ LanguageName = DefaultName;
+ }
+
+ Size2 = StrSize16(LanguageName);
+
+ Link = (LANGUAGE_LINK *)CreateNewLink(Size1 + Size2 + sizeof(UINT32));
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ if(LastStringId != 0) {
+ Link->LastStringId = LastStringId;
+ } else {
+ //we're adding language, that wasn't in package list from the start
+ Link->LastStringId = AddStringPackage(PackageList, Language);
+ if(Link->LastStringId == 0)
+ return EFI_OUT_OF_RESOURCES;
+ }
+ StrCpy8(Link->Language, Language);
+
+ Ptr = (UINT8 *)Link->Language;
+ Ptr += Size1;
+ StrCpy16((CHAR16 *)Ptr, LanguageName);
+
+ DListAdd(&(PackageList->LanguageList), (DLINK *)Link);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLanguageId
+//
+// Description:
+// This function returns language private Id which corresponds with given language Id
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where language belongs
+// IN CHAR8 *Language - Language Id
+// OUT UINT16 *LanguageId - Pointer where to return private Id
+// OUT LANGUAGE_LINK **Found - Pointer where to return found language private data
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_NOT_FOUND - language not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetLanguageId(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ UINT16 *LanguageId,
+ LANGUAGE_LINK **Found OPTIONAL)
+{
+ LANGUAGE_LINK *Link = (LANGUAGE_LINK *)PackageList->LanguageList.pHead;
+ UINT8 Id;
+
+ Id = 0;
+ while(Link != NULL)
+ {
+ if(LanguageCodesEqual(Language, Link->Language))
+ {
+ *LanguageId = Id;
+
+ if(Found)
+ *Found = Link;
+
+ return EFI_SUCCESS;
+ }
+ Link = (LANGUAGE_LINK *)Link->Link.pNext;
+ Id++;
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddString
+//
+// Description:
+// This function adds string to private storage
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where string belongs
+// IN UINT16 LanguageId - Private language Id of the string
+// IN UINT16 StringId - Private string Id of the string
+// IN UINT16 FontId - Private font Id of the string
+// IN EFI_STRING String - String to add
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddString(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 StringId,
+ UINT16 FontId,
+ EFI_STRING String)
+{
+ STRING_RECORD *Record;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ Size = StrSize16(String);
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ Size + 6,
+ &Record);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Record->FontId = FontId;
+ Record->LanguageId = LanguageId;
+ Record->StringId = StringId;
+ StrCpy16(Record->String, String);
+
+ DbeInsert(&(PackageList->StringDb), Record);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseStringsPackage
+//
+// Description:
+// This function parses string package
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where string package belongs
+// IN EFI_HII_STRING_PACKAGE_HDR *Package - Pointer to package to parse
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseStringsPackage(
+ PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_HII_STRING_PACKAGE_HDR *Package)
+{
+ EFI_STATUS Status;
+ LANGUAGE_LINK *Link;
+ UINT16 LanguageId;
+ UINT16 StringId;
+ UINT16 FontId;
+ EFI_HII_STRING_BLOCK *ParsePointer;
+ UINT16 StringCount;
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ BOOLEAN NewLanguage = FALSE;
+ CHAR16 *FontName;
+
+ ParsePointer = (EFI_HII_STRING_BLOCK *)Package;
+ (UINT8 *)ParsePointer += Package->StringInfoOffset;
+
+ Status = GetLanguageId(PackageList, Package->Language, &LanguageId, &Link);
+ if(EFI_ERROR(Status))
+ {
+ LanguageId = (UINT16)PackageList->LanguageList.Size;
+ StringId = 1;
+ NewLanguage = TRUE;
+ }
+ else
+ StringId = Link->LastStringId;
+
+ while(ParsePointer->BlockType != EFI_HII_SIBT_END)
+ {
+ switch(ParsePointer->BlockType)
+ {
+ case EFI_HII_SIBT_SKIP1:
+ StringId += ((EFI_HII_SIBT_SKIP1_BLOCK *)ParsePointer)->SkipCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_SKIP1_BLOCK);
+ break;
+ case EFI_HII_SIBT_SKIP2:
+ StringId += ((EFI_HII_SIBT_SKIP2_BLOCK *)ParsePointer)->SkipCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ break;
+ case EFI_HII_SIBT_EXT1:
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_EXT1_BLOCK *)ParsePointer)->Length;
+ break;
+ case EFI_HII_SIBT_EXT2:
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_EXT2_BLOCK *)ParsePointer)->Length;
+ break;
+ case EFI_HII_SIBT_EXT4:
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_EXT4_BLOCK *)ParsePointer)->Length;
+ break;
+ case EFI_HII_SIBT_FONT:
+ FontName = (CHAR16 *)((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer + 1);
+ Status = AddStringFont(PackageList,
+ ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->FontId,
+ ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->FontSize,
+ ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->FontStyle,
+ FontName, NULL);
+ if(EFI_ERROR(Status))
+ return Status;
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->Header.Length;
+ break;
+ case EFI_HII_SIBT_STRING_SCSU:
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_SCSU_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ 1, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRING_SCSU_FONT:
+ FontId = ((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ 1, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_SCSU:
+ StringCount = ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ParsePointer)->StringCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_SCSU_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ StringCount, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:
+ StringCount = ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ParsePointer)->StringCount;
+ FontId = ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ StringCount, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ case EFI_HII_SIBT_STRING_UCS2:
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ 1, FALSE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRING_UCS2_FONT:
+ FontId = ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ 1, FALSE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_UCS2:
+ StringCount = ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *)ParsePointer)->StringCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_UCS2_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ StringCount, FALSE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:
+ StringCount = ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *)ParsePointer)->StringCount;
+ FontId = ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ StringCount, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ case EFI_HII_SIBT_DUPLICATE:
+ DbKey.LanguageId = LanguageId;
+ DbKey.StringId = ((EFI_HII_SIBT_DUPLICATE_BLOCK *)ParsePointer)->StringId;
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ {
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ Status = AddString(PackageList, Found->LanguageId, StringId, Found->FontId, Found->String);
+ if(EFI_ERROR(Status))
+ return Status;
+ StringId++;
+ }
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_DUPLICATE_BLOCK);
+ break;
+ default:
+ break;
+ }
+ }
+
+//Reconstruct full language name
+
+ if(NewLanguage)
+ {
+ DbKey.LanguageId = LanguageId;
+ DbKey.StringId = Package->LanguageName;
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+
+ if(!EFI_ERROR(Status))
+ {
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ Status = AddLanguage(PackageList, Package->Language, Found->String, StringId);
+ }
+ else
+ Status = AddLanguage(PackageList, Package->Language, NULL, StringId);
+
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+ else
+ Link->LastStringId = StringId;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExtractStrings
+//
+// Description:
+// This function extracts strings from given block of strings
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where strings belong
+// IN UINT16 LanguageId - Private language Id
+// IN OUT UINT16 *StringId - Pointer to string Id
+// IN UINT16 FontId - Font Id
+// IN UINT16 StringCount - Number of strings to extract
+// IN BOOLEAN Compressed - Flag, that determines whether string is compressed or not
+// IN OUT VOID **StringBlock - Pointer to block of strings to extract
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ExtractStrings(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 *StringId,
+ UINT16 FontId,
+ UINT16 StringCount,
+ BOOLEAN Compressed,
+ VOID **StringBlock
+)
+{
+ UINT16 i;
+ EFI_STATUS Status;
+ UINT32 StringSize;
+ UINT32 MaxSize = 0x100;
+ CHAR16 *String = NULL;
+ VOID *Pointer = *StringBlock;
+
+ if(Compressed)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * MaxSize,
+ &String);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ for(i = 0; i < StringCount; i++)
+ {
+ if(Compressed)
+ {
+ StringSize = StrSize8((CHAR8 *)Pointer);
+ if(StringSize > MaxSize)
+ {
+ MaxSize = StringSize;
+ pBS->FreePool(String);
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * MaxSize,
+ &String);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+// UncompressString(String, (CHAR8 *)Pointer);
+ Status = AddString(PackageList, LanguageId, *StringId, FontId, String);
+ }
+ else
+ {
+ StringSize = StrSize16(Pointer);
+ Status = AddString(PackageList, LanguageId, *StringId, FontId, (EFI_STRING)Pointer);
+ }
+
+ if(EFI_ERROR(Status))
+ return Status;
+ (*StringId)++;
+ (UINT8 *)Pointer += StringSize;
+ }
+ *StringBlock = Pointer;
+ if(String != NULL)
+ pBS->FreePool(String);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringBlockSize
+//
+// Description:
+// This function determines block size needed to pack strings into string package
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where strings belong
+// IN CHAR8 *Language - Language Id
+//
+// Output:
+// UINTN - String block size in bytes
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN GetStringBlockSize(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language)
+{
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ EFI_STATUS Status;
+ UINTN RecordIndex;
+ DBE_DATABASE *Database = &(PackageList->StringDb);
+ UINT16 StringCounter = 0;
+ UINT16 SkipBlock = 0; //number of skip blocks to add to string block
+ UINT16 CurrentStringId;
+ UINTN Size = 0;
+ UINTN i;
+
+ Status = GetLanguageId(PackageList, Language, &(DbKey.LanguageId), NULL);
+ if(EFI_ERROR(Status))
+ return 0;
+
+ DbKey.StringId = 1; //find first string with given language
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, &RecordIndex);
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ if(EFI_ERROR(Status))
+ { //there isn't string with string id = 1
+ if(Found->LanguageId != DbKey.LanguageId) //we got string from previous language
+ {
+ RecordIndex++;
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, RecordIndex, &Found);
+ }
+ SkipBlock++; //at least one skip block should be added as far as we don't have string with id=1
+ }
+ CurrentStringId = Found->StringId;
+ Size += StrSize16(Found->String);
+ StringCounter++;
+
+ for(i = RecordIndex + 1;
+ (i < PackageList->StringDb.RecordCount) && (Found->LanguageId == DbKey.LanguageId);
+ i++)
+ {
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, i, &Found);
+ Size += StrSize16(Found->String);
+ StringCounter++;
+ if(Found->StringId > (CurrentStringId + 1))
+ SkipBlock++;
+ CurrentStringId = Found->StringId;
+ }
+
+ Size += SkipBlock * sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ Size += StringCounter * sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Size += sizeof(EFI_HII_SIBT_END_BLOCK);
+
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringBlock
+//
+// Description:
+// This function packs strings from private storage into string package format
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where strings belong
+// IN CHAR8 *Language - Language Id
+// OUT UINT8 *Buffer - Pointer to output buffer
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetStringBlock(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language,
+ IN UINT8 *Buffer)
+{
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ EFI_STATUS Status;
+ UINTN RecordIndex;
+ DBE_DATABASE *Database = &(PackageList->StringDb);
+ UINT16 StringCounter = 0;
+ UINT16 SkipBlock = 0; //number of skip blocks to add to string block
+ UINT16 CurrentStringId = 1;
+ UINTN Size = 0;
+ UINTN i;
+
+ Status = GetLanguageId(PackageList, Language, &(DbKey.LanguageId), NULL);
+
+ DbKey.StringId = 1; //find first string with given language
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, &RecordIndex);
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ if(EFI_ERROR(Status))
+ { //there isn't string with string id = 1
+ if(Found->LanguageId != DbKey.LanguageId) //we got string from previous language
+ {
+ RecordIndex++;
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, RecordIndex, &Found);
+ }
+
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->SkipCount = Found->StringId - CurrentStringId - 1;
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_SKIP2;
+ Buffer += sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ }
+ CurrentStringId = Found->StringId;
+ ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_STRING_UCS2;
+ Buffer += sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Size = StrSize16(Found->String);
+ StrCpy16((CHAR16 *)Buffer, Found->String);
+ Buffer += Size;
+
+ for(i = RecordIndex + 1;
+ (i < PackageList->StringDb.RecordCount) && (Found->LanguageId == DbKey.LanguageId);
+ i++)
+ {
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, i, &Found);
+
+ if(Found->StringId > (CurrentStringId + 1)) //add skip block
+ {
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->SkipCount = Found->StringId - CurrentStringId - 1;
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_SKIP2;
+ Buffer += sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ }
+
+ ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_STRING_UCS2;
+ Buffer += sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Size = StrSize16(Found->String);
+ StrCpy16((CHAR16 *)Buffer, Found->String);
+ Buffer += Size;
+ CurrentStringId = Found->StringId;
+ }
+ ((EFI_HII_SIBT_END_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_END;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStringPackages
+//
+// Description:
+// This function updates string package with strings contained in private storage
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list to update
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateStringPackages(EFI_HII_HANDLE Handle)
+{
+ DLIST *PackageList;
+ PACKAGE_LINK *Link;
+ PACKAGE_LINK *NewLink;
+ EFI_HII_STRING_PACKAGE_HDR *StringPackage;
+ UINT8 *Buffer;
+ UINTN Size;
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+ Link = (PACKAGE_LINK *)(PackageList->pHead);
+
+ while(Link != NULL)
+ {
+ if(Link->Package.Type == EFI_HII_PACKAGE_STRINGS)
+ {
+ StringPackage = (EFI_HII_STRING_PACKAGE_HDR *) &(Link->Package);
+ Size = GetStringBlockSize((PACKAGE_LIST_RECORD *)Handle, StringPackage->Language);
+
+ if(Size != 0)
+ {
+ Size += StringPackage->HdrSize;
+ NewLink = (PACKAGE_LINK *) CreateNewLink((UINT32)Size);
+ if(NewLink == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ MemCpy((VOID *) &(NewLink->Package),
+ (VOID *) &(Link->Package),
+ StringPackage->HdrSize);
+ NewLink->Package.Length = (UINT32)Size;
+ Buffer = (UINT8 *) &(NewLink->Package);
+ Buffer += StringPackage->HdrSize;
+
+ GetStringBlock((PACKAGE_LIST_RECORD *)Handle, StringPackage->Language, Buffer);
+
+ DListInsert(PackageList, (DLINK *)NewLink, (DLINK *)Link);
+ DListDelete(PackageList, (DLINK *)Link);
+ pBS->FreePool(Link);
+ Link = NewLink;
+ }
+ }
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrSize8
+//
+// Description:
+// This function returns ASCII string size in bytes
+//
+// Input:
+// IN CHAR8 *String - Pointer to string
+//
+// Output:
+// UINT32 - Size of string in bytes including nul-terminator
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 StrSize8(CHAR8 *String)
+{
+ UINT32 Size = 1;
+ while(*String++)
+ Size++;
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrSize16
+//
+// Description:
+// This function returns UNICODE string size in bytes
+//
+// Input:
+// IN CHAR16 *String - Pointer to string
+//
+// Output:
+// UINT32 - Size of string in bytes including nul-terminator
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 StrSize16(CHAR16 *String)
+{
+ UINT32 Size = 2;
+ while(*String++)
+ Size += 2;
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCpy8
+//
+// Description:
+// This function copies one ASCII string into another
+//
+// Input:
+// IN CHAR8 *Dest - Pointer to destination string
+// IN CHAR8 *Src - Pointer to source string
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StrCpy8(CHAR8 *Dest, CHAR8 *Src)
+{
+ MemCpy(Dest, Src, StrSize8(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCpy16
+//
+// Description:
+// This function copies one UNICODE string into another
+//
+// Input:
+// IN CHAR16 *Dest - Pointer to destination string
+// IN CHAR16 *Src - Pointer to source string
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StrCpy16(CHAR16 *Dest, CHAR16 *Src)
+{
+ MemCpy(Dest, Src, StrSize16(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCmp8
+//
+// Description:
+// This function compares two ASCII strings
+//
+// Input:
+// IN CHAR8 *Dest - Pointer to destination string
+// IN CHAR8 *Src - Pointer to source string
+//
+// Output:
+// INTN - Zero if strings are equal, non-zero otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN StrCmp8(CHAR8 *Dest, CHAR8 *Src)
+{
+ return MemCmp(Dest, Src, StrSize8(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCmp16
+//
+// Description:
+// This function compares two UNICODE strings
+//
+// Input:
+// IN CHAR16 *Dest - Pointer to destination string
+// IN CHAR16 *Src - Pointer to source string
+//
+// Output:
+// INTN - Zero if strings are equal, non-zero otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN StrCmp16(CHAR16 *Dest, CHAR16 *Src)
+{
+ return MemCmp(Dest, Src, StrSize16(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAvailableFontId
+//
+// Description:
+// This function returns available font ID number
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+//
+// Output:
+// UINT16 - font ID number
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetAvailableFontId(
+ IN PACKAGE_LIST_RECORD *PackageList
+)
+{
+ UINT16 Id = 0;
+ STRING_FONT_LINK *Link = (STRING_FONT_LINK *)PackageList->StringFontList.pHead;
+ while(Link != NULL) {
+ Id = (Link->FontId > Id) ? Link->FontId : Id;
+ Link = (STRING_FONT_LINK *)Link->Link.pNext;
+ }
+ return Id + 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStringFontInfoByTemplate
+//
+// Description:
+// This function searches available fonts and returns font ID if match found
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+// IN EFI_FONT_INFO *Template - pointer to font description
+// OUT UINT16 *FontId - pointer where to return font ID
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindStringFontInfoByTemplate(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_FONT_INFO *Template,
+ OUT UINT16 *FontId
+)
+{
+ STRING_FONT_LINK *Link = (STRING_FONT_LINK *)PackageList->StringFontList.pHead;
+ EFI_FONT_INFO *Info;
+
+ while(Link != NULL) {
+ Info = (EFI_FONT_INFO *)(Link + 1);
+ if(!MemCmp(Info, Template, Link->FontInfoSize)) {
+ *FontId = Link->FontId;
+ return EFI_SUCCESS;
+ }
+ Link = (STRING_FONT_LINK *)Link->Link.pNext;
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStingFontInfoById
+//
+// Description:
+// This function searches available fonts and returns font description if match found
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+// IN UINT16 FontId - font ID to find
+// OUT EFI_FONT_INFO **Info - pointer where to store pointer to font description
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindStingFontInfoById(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ OUT EFI_FONT_INFO **Info
+)
+{
+ static CHAR16 DefaultFontName[] = L"System font";
+ STRING_FONT_LINK *Link = (STRING_FONT_LINK *)PackageList->StringFontList.pHead;
+ UINTN StrSize;
+ EFI_STATUS Status;
+
+ while(Link != NULL) {
+ if(Link->FontId == FontId) {
+ Status = pBS->AllocatePool(EfiBootServicesData, Link->FontInfoSize, Info);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(*Info, (VOID *)(Link + 1), Link->FontInfoSize);
+ return EFI_SUCCESS;
+ }
+ Link = (STRING_FONT_LINK *)Link->Link.pNext;
+ }
+//font not found, return default font
+ StrSize = Wcslen(DefaultFontName) * sizeof(CHAR16);
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(EFI_FONT_INFO) + StrSize, Info);
+ if(!EFI_ERROR(Status)) {
+ (*Info)->FontSize = EFI_GLYPH_HEIGHT;
+ (*Info)->FontStyle = EFI_HII_FONT_STYLE_NORMAL;
+ Wcscpy((*Info)->FontName, DefaultFontName);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStringFont
+//
+// Description:
+// This function adds font to font database and assigns font ID if latter was
+// not supplied
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+// IN UINT16 FontId - font ID
+// IN UINT16 FontSize - font size
+// IN EFI_HII_FONT_STYLE FontStyle - font style
+// IN CHAR16 *FontName - pointer to font name
+// OUT UINT16 *NewFontId OPTIONAL - pointer where to store assigned font ID
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddStringFont(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ IN UINT16 FontSize,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN CHAR16 *FontName,
+ OUT UINT16 *NewFontId OPTIONAL
+)
+{
+ UINT16 Fid;
+ UINT32 FontNameSize;
+ STRING_FONT_LINK *AddLink;
+ EFI_FONT_INFO *FontInfo;
+
+ Fid = (FontId == INVALID_FONT_ID) ? GetAvailableFontId(PackageList) : FontId;
+
+ FontNameSize = (UINT32)((Wcslen(FontName)) * sizeof(CHAR16)); //null-terminator already accounted for in EFI_FONT_INFO structure
+ AddLink = CreateNewLink((UINT32)(sizeof(STRING_FONT_LINK) + sizeof(EFI_FONT_INFO)) + FontNameSize);
+ if(AddLink == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ AddLink->FontId = Fid;
+ AddLink->FontInfoSize = (UINT32)sizeof(EFI_FONT_INFO) + FontNameSize;
+ FontInfo = (EFI_FONT_INFO *)(AddLink + 1);
+ FontInfo->FontSize = FontSize;
+ FontInfo->FontStyle = FontStyle;
+ Wcscpy(FontInfo->FontName, FontName);
+ DListAdd(&(PackageList->StringFontList), (DLINK *)AddLink);
+ if(NewFontId)
+ *NewFontId = Fid;
+ return EFI_SUCCESS;
+}
+
+#pragma warning (default : 4090)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/UefiHii.cif b/Core/CORE_DXE/UefiHii/UefiHii.cif
new file mode 100644
index 0000000..4e82128
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/UefiHii.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "UefiHii"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\UefiHii\"
+ RefName = "UefiHii"
+[files]
+"UefiHii.sdl"
+"HiiConfig.c"
+"HiiDatabase.c"
+"HiiFont.c"
+"HiiFontEx.c"
+"HiiPrivate.h"
+"HiiString.c"
+"Hii.chm"
+"UefiHiiUtils.c"
+"HiAccessConfig.c"
+"hii21ExportConfig.c"
+<endComponent>
diff --git a/Core/CORE_DXE/UefiHii/UefiHii.sdl b/Core/CORE_DXE/UefiHii/UefiHii.sdl
new file mode 100644
index 0000000..9bdae97
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/UefiHii.sdl
@@ -0,0 +1,15 @@
+TOKEN
+ Name = "UefiHii_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UefiHii support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "UefiHii_DIR"
+ Help = "Path to UefiHii Module in Project"
+End
+
diff --git a/Core/CORE_DXE/UefiHii/UefiHiiUtils.c b/Core/CORE_DXE/UefiHii/UefiHiiUtils.c
new file mode 100644
index 0000000..d58aed3
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/UefiHiiUtils.c
@@ -0,0 +1,750 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/UefiHiiUtils.c 16 5/22/12 4:38p Artems $
+//
+// $Revision: 16 $
+//
+// $Date: 5/22/12 4:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/UefiHiiUtils.c $
+//
+// 16 5/22/12 4:38p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] In certain cases system font is absent
+// [RootCause] When font FFS file is not found system doesn't publish
+// system font
+// [Solution] If font FFS file is not found, publish font supplied with
+// Core
+// [Files] UefiHiiUtils.c
+//
+// 15 4/30/12 3:52p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Modified GraphicsConsole driver to output whole string
+// instead of symbol-by-symbol output
+// [Files] Gc.c, AmiDxeLib.h, EfiLib.c, UefiHiiUtils.c
+//
+// 14 1/05/12 5:05p Artems
+// EIP 76735: Font FFS file is not loaded in framework mode, when in
+// nested FV
+//
+// 13 1/05/11 12:12p Artems
+// EIP 51298: BufferSize value gets corrupted after call to ConfigToBlock
+// function - fixed
+//
+// 12 10/07/10 12:18p Felixp
+// Minor bug fix in LoadSystemFont: don't call FreePool if font section
+// has not been read.
+//
+// 11 10/01/10 4:44p Artems
+// Added implementation of function SetBrowserData
+//
+// 10 3/22/10 3:25p Felixp
+// SetCallback bug fix (the bug introduced during previous check in).
+//
+// 9 3/12/10 2:21p Felixp
+// Enhencement: LoadResources is updated to properly publish the packages
+// when NumberOfCallbacks is zero.
+//
+// 7 2/23/10 10:30p Felixp
+// SetBrowserData function is added.
+//
+// 6 2/19/10 4:15p Felixp
+// GetString function is updated: if the string is not defined for the
+// PlatformLang , try with the default language.
+// If still no luck, try English.
+//
+// 5 2/12/10 5:47p Felixp
+// Bug fix in LoadResources and LoadString functions
+// (memory corruption in projects with more than one supported language).
+//
+// 4 11/25/09 11:27a Felixp
+// Action parameter of the Callback function is updated based on UEFI
+// errata
+//
+// 3 11/24/09 4:39p Felixp
+//
+// 2 11/24/09 11:27a Felixp
+// GetString udpated: if PlatformLang variable does not exist use default
+// language instead of English.
+//
+// 1 10/09/09 6:12p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: UefiHiiUtils.c
+//
+// Description: UEFI 2.1 HII Utilities Protocol Implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Protocol/HiiUtilities.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/FormBrowser2.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DevicePath.h>
+#include "HiiPrivate.h"
+
+EFI_STATUS HiiAccessExtractConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+);
+EFI_STATUS HiiAccessRouteConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+);
+EFI_STATUS HiiAccessFormCallback(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+);
+
+VOID StripValuePattern(
+ IN OUT EFI_STRING String,
+ IN UINTN Size
+);
+
+UINT32 StrSize16(
+ IN CHAR16 *String
+);
+
+static EFI_HII_DATABASE_PROTOCOL *HiiDatabase=NULL;
+static EFI_HII_STRING_PROTOCOL *HiiString=NULL;
+static EFI_FORM_BROWSER2_PROTOCOL *FormBrowser = NULL;
+static EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting = NULL;
+
+static EFI_GUID HiiResourcesFfsSectionGuid= HII_RESOURCES_FFS_SECTION_GUID;
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+static CHAR8 *PlatformLang = NULL;
+
+extern const char *DefaultLanguageCode;
+extern SIMPLE_FONT DefaultFont[];
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: SetCallback
+//
+// Description:
+// EFI_STATUS SetCallback(EFI_HII_IFR_PACK *pIfr,
+// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo,
+// CALLBACK_INFO **CallBackFound)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS SetCallback(
+ EFI_LOADED_IMAGE_PROTOCOL *Image,
+ EFI_IFR_FORM_SET *FormSet, UINTN NumberOfCallbacks,
+ CALLBACK_INFO *CallbackInfo, CALLBACK_INFO **CallBackFound,
+ EFI_HANDLE *CallbackHandle
+)
+{
+ UINTN i;
+ EFI_STATUS Status;
+ EFI_HANDLE Handle=NULL;
+ EFI_DEVICE_PATH_PROTOCOL *pPath, *pPath2;
+ CALLBACK_INFO *CallbackInfoPtr;
+
+ static EFI_HII_CONFIG_ACCESS_PROTOCOL DefaultConfigAccess = {
+ HiiAccessExtractConfig, HiiAccessRouteConfig, HiiAccessFormCallback
+ };
+ static CALLBACK_INFO DefaultCallbackInfo = {
+ NULL,&DefaultConfigAccess, 0, 0, NULL
+ };
+ static VENDOR_DEVICE_PATH FormSetDevicePathNode = {
+ {
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
+ sizeof(VENDOR_DEVICE_PATH)
+ },
+ {0}
+ };
+
+ for( i=0
+ ; i<NumberOfCallbacks
+ && ( CallbackInfo[i].pGuid == NULL
+ || guidcmp(&FormSet->Guid,CallbackInfo[i].pGuid) != 0
+ )
+ ; i++
+ );
+ if (i==NumberOfCallbacks){
+ CallbackInfoPtr = &DefaultCallbackInfo;
+ }else{
+ CallbackInfoPtr = &CallbackInfo[i];
+ if (CallbackInfoPtr->pFormCallback == NULL){
+ CallbackInfoPtr->pFormCallback = &DefaultConfigAccess;
+ }else{
+ if (CallbackInfoPtr->pFormCallback->ExtractConfig==NULL)
+ CallbackInfoPtr->pFormCallback->ExtractConfig =
+ HiiAccessExtractConfig;
+ if (CallbackInfoPtr->pFormCallback->RouteConfig==NULL)
+ CallbackInfoPtr->pFormCallback->RouteConfig =
+ HiiAccessRouteConfig;
+ if (CallbackInfoPtr->pFormCallback->Callback==NULL)
+ CallbackInfoPtr->pFormCallback->Callback =
+ HiiAccessFormCallback;
+ }
+ }
+ Status=pBS->HandleProtocol(Image->DeviceHandle, &guidDevicePath, &pPath);
+ if (EFI_ERROR(Status)) pPath=NULL;
+ pPath = DPAddNode(pPath, Image->FilePath);
+ FormSetDevicePathNode.Guid = FormSet->Guid;
+ pPath2 = DPAddNode(pPath, &FormSetDevicePathNode.Header);
+ pBS->FreePool(pPath);
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &guidDevicePath, pPath2,
+ &gEfiHiiConfigAccessProtocolGuid, CallbackInfoPtr->pFormCallback,
+ NULL
+ );
+ if (EFI_ERROR(Status)) return Status;
+ if (CallbackHandle) *CallbackHandle=Handle;
+ if (CallBackFound){
+ *CallBackFound= (CallbackInfoPtr == &DefaultCallbackInfo)
+ ? NULL
+ : CallbackInfoPtr;
+ }
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS PublishPackages(
+ IN VOID *PackagePointers, IN UINTN NumberOfPackages,
+ IN EFI_GUID *PackageGuid, IN EFI_HANDLE DriverHandle OPTIONAL,
+ OUT EFI_HII_HANDLE *HiiHandle
+){
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ UINTN i;
+ UINT32 PackageLength;
+ UINT8 *PackagePtr;
+ EFI_HII_PACKAGE_HEADER **Packages = PackagePointers;
+ if (NumberOfPackages==0) return EFI_SUCCESS;
+ if ( !HiiDatabase
+ && EFI_ERROR(Status=pBS->LocateProtocol(
+ &gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase
+ ))
+ ) return Status;
+ //calculate the package list length
+ PackageLength = sizeof(EFI_HII_PACKAGE_LIST_HEADER)
+ + sizeof(EFI_HII_PACKAGE_HEADER); //package list terminator
+ for(i=0; i<NumberOfPackages; i++){
+ PackageLength += Packages[i]->Length;
+ }
+ PackageList = Malloc(PackageLength);
+ if(PackageList==NULL) return EFI_OUT_OF_RESOURCES;
+ PackageList->PackageListGuid = *PackageGuid;
+ PackageList->PackageLength = PackageLength;
+
+ PackagePtr = (UINT8*)(PackageList+1);
+ for( i=0; i<NumberOfPackages; i++){
+ pBS->CopyMem(PackagePtr, Packages[i], Packages[i]->Length);
+ PackagePtr += Packages[i]->Length;
+ }
+ ((EFI_HII_PACKAGE_HEADER *)PackagePtr)->Length = sizeof(EFI_HII_PACKAGE_HEADER);
+ ((EFI_HII_PACKAGE_HEADER *)PackagePtr)->Type = EFI_HII_PACKAGE_END;
+
+ Status = HiiDatabase->NewPackageList(
+ HiiDatabase, PackageList, DriverHandle, HiiHandle
+ );
+ pBS->FreePool(PackageList);
+ return Status;
+}
+
+UINT32 GetNumerOfResourcePackages(
+ HII_RESOURCE_SECTION_HEADER *pSection, UINTN SectionSize
+){
+ EFI_HII_PACKAGE_HEADER *PackagePtr;
+ UINT32 NumberOfPackages = 0;
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)(pSection+1);
+ while(PackagePtr < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length);
+ NumberOfPackages++;
+ }
+ return NumberOfPackages;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: LoadStrings
+//
+// Description:
+// EFI_STATUS LoadStrings(EFI_HANDLE ImageHandle,
+// EFI_HII_HANDLE *HiiHandle)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS LoadStrings(
+ EFI_HANDLE ImageHandle, EFI_HII_HANDLE *HiiHandle
+)
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ HII_RESOURCE_SECTION_HEADER *pSection;
+ UINTN SectionSize;
+ EFI_HII_PACKAGE_HEADER *pPack;
+ EFI_HII_PACKAGE_HEADER **StringPackagPtr;
+ UINTN NumberOfStringPackages;
+ if (EFI_ERROR(Status=pBS->HandleProtocol(
+ ImageHandle, &gEfiLoadedImageProtocolGuid, &Image
+ ))
+ ) return Status;
+#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1
+{
+#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_
+ UINT8 *pData;
+ pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize);
+ if (!pData) return EFI_NOT_FOUND;
+ pSection = Malloc(SectionSize);
+ pBS->CopyMem(pSection,pData,SectionSize);
+ Status = EFI_SUCCESS;
+}
+#else
+{
+ Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize);
+ if (EFI_ERROR(Status)) return Status;
+}
+#endif
+ //Calculate number of packages.
+ //Original value of pSection->NumberOfPackages treats string packages
+ //for multiple languages as a single package. We need the real number of packages.
+ pSection->NumberOfPackages = GetNumerOfResourcePackages(pSection,SectionSize);
+
+ pPack = (EFI_HII_PACKAGE_HEADER *)(pSection + 1);
+
+ StringPackagPtr = Malloc(pSection->NumberOfPackages*sizeof(EFI_HII_PACKAGE_HEADER*));
+ NumberOfStringPackages=0;
+ while(pPack < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){
+ if (pPack->Type != EFI_HII_PACKAGE_STRINGS){
+ Status=EFI_INVALID_PARAMETER;
+ break;
+ }
+ StringPackagPtr[NumberOfStringPackages++]=pPack;
+ pPack = (EFI_HII_PACKAGE_HEADER*)((UINT8*)pPack+pPack->Length);
+ }
+ Status = PublishPackages(
+ StringPackagPtr, NumberOfStringPackages,
+ &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid,
+ NULL, HiiHandle
+ );
+ pBS->FreePool(StringPackagPtr);
+ pBS->FreePool(pSection);
+ return Status;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: LoadResources
+//
+// Description:
+// EFI_STATUS LoadResources(EFI_HANDLE ImageHandle,
+// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo,
+// INIT_HII_PACK InitFunction)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS LoadResources(
+ EFI_HANDLE ImageHandle, UINTN NumberOfCallbacks,
+ CALLBACK_INFO *CallbackInfo, INIT_HII_PACK InitFunction
+)
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ HII_RESOURCE_SECTION_HEADER *pSection;
+ UINTN SectionSize;
+ CALLBACK_INFO *pCallBackFound;
+ if (EFI_ERROR(Status=pBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, &Image))) return Status;
+#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1
+{
+#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_
+ UINT8 *pData;
+ pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize);
+ if (!pData) return EFI_NOT_FOUND;
+ pSection = Malloc(SectionSize);
+ pBS->CopyMem(pSection,pData,SectionSize);
+}
+#else
+{
+ Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize);
+ if (EFI_ERROR(Status)) return Status;
+}
+#endif
+{
+ EFI_HII_PACKAGE_HEADER **IfrPackagPtr, **GlobalPackagPtr, **SharedPackagPtr;
+ UINTN NumberOfIfrPackages, NumberOfGlobalPackages, NumberOfSharedPackages, i;
+ UINT8 *PackagePtrBuffer;
+ EFI_HII_PACKAGE_HEADER *PackagePtr;
+
+ //Calculate number of packages.
+ //Original value of pSection->NumberOfPackages treats string packages
+ //for multiple languages as a single package. We need the real number of packages.
+ pSection->NumberOfPackages = GetNumerOfResourcePackages(pSection,SectionSize);
+
+ PackagePtrBuffer = Malloc(3*pSection->NumberOfPackages*sizeof(EFI_HII_PACKAGE_HEADER*));
+ IfrPackagPtr = (EFI_HII_PACKAGE_HEADER**)PackagePtrBuffer;
+ GlobalPackagPtr = IfrPackagPtr+pSection->NumberOfPackages;
+ SharedPackagPtr = GlobalPackagPtr+pSection->NumberOfPackages;
+ NumberOfIfrPackages = 0;
+ NumberOfGlobalPackages = 0;
+ NumberOfSharedPackages = 0;
+
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)(pSection+1);
+ while(PackagePtr < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){
+ switch(PackagePtr->Type){
+ case EFI_HII_PACKAGE_FORMS:
+ IfrPackagPtr[NumberOfIfrPackages++]=PackagePtr;
+ break;
+ case EFI_HII_PACKAGE_FONTS: case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
+ GlobalPackagPtr[NumberOfGlobalPackages++]=PackagePtr;
+ break;
+ default:
+ SharedPackagPtr[NumberOfSharedPackages++]=PackagePtr;
+ break;
+ }
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length);
+ }
+ Status = PublishPackages(
+ GlobalPackagPtr, NumberOfGlobalPackages,
+ &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid,
+ NULL, &HiiHandle
+ );
+ for(i=0; i<NumberOfIfrPackages; i++){
+ EFI_HANDLE CallbackHandle;
+
+ SharedPackagPtr[NumberOfSharedPackages]=IfrPackagPtr[i];
+ SetCallback(
+ Image, (EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1),
+ NumberOfCallbacks,CallbackInfo,&pCallBackFound,&CallbackHandle
+ );
+ Status = PublishPackages(
+ SharedPackagPtr, NumberOfSharedPackages+1,
+ &((EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1))->Guid,
+ CallbackHandle, &HiiHandle
+ );
+ if (pCallBackFound) pCallBackFound->HiiHandle=HiiHandle;
+ if (InitFunction) InitFunction(HiiHandle,pCallBackFound);
+ pCallBackFound=NULL;
+ }
+ pBS->FreePool(PackagePtrBuffer);
+ pBS->FreePool(pSection);
+}
+ return EFI_SUCCESS;
+}
+
+//TODO: header
+static EFI_STATUS GetString(
+ IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId,
+ IN OUT UINTN *StringSize, OUT EFI_STRING String
+){
+ EFI_STATUS Status;
+
+ if ( !HiiString
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString))
+ ) return EFI_NOT_FOUND;
+ if (PlatformLang==NULL){
+ UINTN Size;
+ if (EFI_ERROR(GetEfiVariable(
+ L"PlatformLang", &EfiVariableGuid, NULL, &Size, &PlatformLang
+ ))) PlatformLang = (CHAR8*)DefaultLanguageCode;
+ }
+ Status = HiiString->GetString(
+ HiiString, PlatformLang, HiiHandle,StringId, String, StringSize, NULL
+ );
+ // If the string representation for the PlatformLang is not defined,
+ // try with the default language.
+ // If still no luck, try English
+ if (Status==EFI_INVALID_LANGUAGE){
+ Status = HiiString->GetString(
+ HiiString, (CHAR8*)DefaultLanguageCode, HiiHandle,
+ StringId, String, StringSize, NULL
+ );
+ if (Status==EFI_INVALID_LANGUAGE)
+ Status = HiiString->GetString(
+ HiiString, LANGUAGE_CODE_ENGLISH, HiiHandle,
+ StringId, String, StringSize, NULL
+ );
+ }
+ return Status;
+}
+
+//TODO header
+static EFI_STATUS SetString(
+ IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId, IN EFI_STRING String
+){
+ CHAR8 *LanguageList = NULL;
+ UINTN Size = 0;
+ EFI_STATUS Status;
+
+ if ( !HiiString
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString))
+ ) return EFI_NOT_FOUND;
+
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, LanguageList, &Size);
+ if (Status!=EFI_BUFFER_TOO_SMALL) return Status;
+ LanguageList = Malloc(Size);
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, LanguageList, &Size);
+ if (!EFI_ERROR(Status)){
+ CHAR8 *CurrentLang, *EndOfCurrentLang;
+ EndOfCurrentLang = LanguageList;
+ while(EndOfCurrentLang < LanguageList+Size){
+ CHAR8 OriginalChar;
+ CurrentLang = EndOfCurrentLang;
+ while(*EndOfCurrentLang!=';'&&*EndOfCurrentLang!=0) EndOfCurrentLang++;
+ OriginalChar = *EndOfCurrentLang;
+ *EndOfCurrentLang = 0;
+ Status = HiiString->SetString(
+ HiiString, HiiHandle, StringId, CurrentLang, String, NULL
+ );
+ if (EFI_ERROR(Status)) break;
+ *EndOfCurrentLang = OriginalChar;
+ EndOfCurrentLang++;
+ }
+ }
+ pBS->FreePool(LanguageList);
+ return Status;
+}
+
+static EFI_STATUS GetBrowserData(
+ IN UINTN *BufferSize, OUT VOID *Buffer,
+ IN CONST EFI_GUID *VarStoreGuid, OPTIONAL
+ IN CONST CHAR16 *VarStoreName OPTIONAL
+){
+ UINTN StringDataSize = 0;
+ CHAR16 *StringData = NULL;
+ EFI_STATUS Status;
+ EFI_STRING Progress;
+
+ if ( !FormBrowser
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser))
+ ) return EFI_NOT_FOUND;
+ if ( !HiiConfigRouting
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting))
+ ) return EFI_NOT_FOUND;
+
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (Status!=EFI_BUFFER_TOO_SMALL) return Status;
+ StringData = Malloc(StringDataSize);
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (!EFI_ERROR(Status)){
+ StringDataSize = *BufferSize; //preserve passed buffer size value, as
+ //ConfigToBlock may change it as per UEFI 2.1 spec
+ //it will contain index of last updated byte
+ Status = HiiConfigRouting->ConfigToBlock(
+ HiiConfigRouting, StringData, Buffer, BufferSize, &Progress
+ );
+ *BufferSize = StringDataSize; //restore original value
+ }
+ pBS->FreePool(StringData);
+ return Status;
+}
+
+static EFI_STATUS SetBrowserData(
+ IN UINTN BufferSize, IN VOID *Buffer,
+ IN CONST EFI_GUID *VarStoreGuid, OPTIONAL //TODO: Can it be optional???
+ IN CONST CHAR16 *VarStoreName OPTIONAL
+)
+{
+ UINTN StringDataSize = 0;
+ CHAR16 *StringData = NULL;
+ EFI_STATUS Status;
+ EFI_STRING Config;
+ EFI_STRING Progress;
+
+ if ( !FormBrowser
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser))
+ ) return EFI_NOT_FOUND;
+ if ( !HiiConfigRouting
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting))
+ ) return EFI_NOT_FOUND;
+
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (Status!=EFI_BUFFER_TOO_SMALL) return Status;
+ StringData = Malloc(StringDataSize);
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+//we have StringData in format &OFFSET=XXXX&WIDTH=XXXX&VALUE=XXXX&OFFSET=...
+//in order for function BlockToConfig to work we need to modify StringData as follows:
+//&OFFSET=XXXX&WIDTH=XXXX&OFFSET=... (i.e. remove all &VALUE=XXX patterns)
+
+ StripValuePattern(StringData, StringDataSize);
+
+ Status = HiiConfigRouting->BlockToConfig(
+ HiiConfigRouting, StringData, Buffer, BufferSize,
+ &Config, &Progress
+ );
+
+ if(!EFI_ERROR(Status)) {
+ StringDataSize = StrSize16(Config);
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, Config, FALSE,
+ VarStoreGuid, VarStoreName
+ );
+ pBS->FreePool(Config);
+ }
+
+ pBS->FreePool(StringData);
+ return Status;
+}
+
+EFI_STATUS LoadSystemFont(){
+///// Load Font Pack
+#define FONT_FFS_FILE_GUID { 0xdac2b117, 0xb5fb, 0x4964, { 0xa3, 0x12, 0xd, 0xcc, 0x77, 0x6, 0x1b, 0x9b } }
+static EFI_GUID FontFfsFileGuid = FONT_FFS_FILE_GUID;
+extern UINT8 UsStdNarrowGlyphData[];
+ EFI_FIRMWARE_VOLUME_PROTOCOL *pFV;
+ UINTN DataSize;
+ EFI_GUID *pSectionGuid = NULL;
+ UINT32 Authentication;
+ EFI_HANDLE *pHandle;
+ UINTN Number,i;
+ EFI_STATUS FontStatus;
+ EFI_HII_PACKAGE_HEADER *FontPackage;
+ EFI_HII_HANDLE HiiFontHandle;
+
+ FontPackage = (EFI_HII_PACKAGE_HEADER*)&UsStdNarrowGlyphData;
+ FontStatus = pBS->LocateHandleBuffer(ByProtocol,&guidFV, NULL, &Number, &pHandle);
+ for(i=0;i<Number; i++)
+ {
+ FontStatus=pBS->HandleProtocol(pHandle[i], &guidFV, &pFV);
+ if (EFI_ERROR(FontStatus)) continue;
+ pSectionGuid=NULL;
+ DataSize=0;
+ FontStatus=pFV->ReadSection (
+ pFV,&FontFfsFileGuid,
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID,0, &pSectionGuid, &DataSize,
+ &Authentication
+ );
+ if (!EFI_ERROR(FontStatus))
+ {
+ FontPackage=(EFI_HII_PACKAGE_HEADER*)((UINT32*)(pSectionGuid+1)+1);
+ break;
+ }
+ }
+
+ if (FontPackage->Type!=EFI_HII_PACKAGE_SIMPLE_FONTS){
+ //The font package is in the Framework HII format
+ //Convert the header to the UEFI HII format
+ DataSize=FontPackage->Length;
+ FontPackage = (EFI_HII_PACKAGE_HEADER*)((UINT8*)FontPackage+2);
+ FontPackage->Type=EFI_HII_PACKAGE_SIMPLE_FONTS;
+ FontPackage->Length=(UINT32)DataSize;
+ }
+ FontStatus = PublishPackages(&FontPackage, 1, &FontFfsFileGuid, NULL, &HiiFontHandle);
+ if (pSectionGuid!=NULL) pBS->FreePool(pSectionGuid);
+ return FontStatus;
+}
+
+static EFI_STATUS UtilGetGlyphWidth(
+ IN CHAR16 Char,
+ OUT UINT16 *Width
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if(DefaultFont[(UINTN)Char].NarrowGlyph != NULL) {
+ *Width = ((DefaultFont[(UINTN)Char].NarrowGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDTH;
+ } else if(DefaultFont[(UINTN)Char].WideGlyph != NULL) {
+ *Width = ((DefaultFont[(UINTN)Char].WideGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDE_WIDTH;
+ } else if(DefaultFont[0xfffd].NarrowGlyph != NULL) {
+ *Width = EFI_GLYPH_WIDTH;
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ } else if(DefaultFont[0xfffd].WideGlyph != NULL) {
+ *Width = EFI_GLYPH_WIDE_WIDTH;
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ } else {
+ *Width = 0;
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ }
+ return Status;
+}
+
+HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol = {
+ LoadResources, LoadStrings, PublishPackages,
+ GetBrowserData, SetBrowserData, GetString, SetString, UtilGetGlyphWidth
+};
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/UefiHii/hii21ExportConfig.c b/Core/CORE_DXE/UefiHii/hii21ExportConfig.c
new file mode 100644
index 0000000..91480c0
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/hii21ExportConfig.c
@@ -0,0 +1,1143 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/hii21ExportConfig.c $
+//
+// $Author: Artems $
+//
+// $Revision: 1 $
+//
+// $Date: 1/25/11 3:20p $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/hii21ExportConfig.c $
+//
+// 1 1/25/11 3:20p Artems
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: hii21ExportConfig.c
+//
+// Description: This file contains code to perform the ExportConfig Operation of Config
+// roughting protocol.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "token.h"
+#include "efi.h"
+//#include "devicepath.h"
+#include <AmiDxeLib.h>
+
+#ifndef EFI_PROTOCOL_DEFINITION
+#define TSE_STRINGIZE(a) #a
+#define EFI_PROTOCOL_DEFINITION(a) TSE_STRINGIZE(Protocol/a.h)
+#endif
+
+#include EFI_PROTOCOL_DEFINITION(HiiDatabase)
+#include EFI_PROTOCOL_DEFINITION(HiiConfigRouting)
+#include EFI_PROTOCOL_DEFINITION(devicepath)
+
+typedef struct _VARSTORE_INFO
+{
+ EFI_GUID VariableGuid; //Varies EFI_GUID for the NVRAM variable store for this data
+ VOID* VariableHandle; //Varies HII Handle to the formset that contains this VarStore
+ UINT16 VariableSize; //Varies The size of Buffer Varstore
+ struct _VARSTORE_INFO *Next;
+ char *VariableName; //Varies Variable store name
+}VARSTORE_INFO;
+
+
+// Helper Functions
+EFI_HII_DATABASE_PROTOCOL *gHiiDatabase;
+EFI_BOOT_SERVICES *gBS;
+EFI_HII_CONFIG_ROUTING_PROTOCOL * gHiiConfigRouting;
+
+VARSTORE_INFO *gVarInfoHead = NULL;
+VARSTORE_INFO *gpVarInfo;
+
+EFI_HII_HANDLE *HiiGetHandles(UINT16 *NumberOfHiiHandles);
+VOID * _HiiGetForm( EFI_HII_HANDLE Handle, UINTN *Length );
+VOID _HiiGetVariable(EFI_HII_HANDLE Handle, UINT8 * buff);
+EFI_STATUS GetVarStoreConfig(VARSTORE_INFO *VarInfo, EFI_STRING *result);
+EFI_STATUS GetConfigHeader(VARSTORE_INFO *VarInfo, EFI_STRING *Configuration, UINTN *Length);
+EFI_STATUS GetBlockName(EFI_STRING *Configuration, UINTN *Length, UINTN Size);
+EFI_STATUS _VerifyResponseString(EFI_STRING Configuration, BOOLEAN NameValue);
+EFI_STATUS _ConstructConfigHdr (
+ IN OUT CHAR16 *ConfigHdr,
+ IN OUT UINTN *StrBufferLen,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name, OPTIONAL
+ IN EFI_HANDLE *DriverHandle
+ );
+
+EFI_STATUS
+BufferToHexString (
+ IN OUT CHAR16 *Str,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ );
+EFI_STATUS
+UnicodeToConfigString (
+ IN OUT CHAR16 *ConfigString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *UnicodeString
+ );
+VOID
+SwapBuffer (
+ IN OUT UINT8 *Buffer,
+ IN UINTN BufferSize
+ );
+EFI_STATUS
+BufToHexString (
+ IN OUT CHAR16 *Str,
+ IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf,
+ IN UINTN Len
+ );
+CHAR16
+NibbleToHexChar (
+ IN UINT8 Nibble
+ );
+VOID
+ToLower (
+ IN OUT CHAR16 *Str
+ );
+VOID StrCpy8(CHAR8 *dest, CHAR8 *src);
+VOID
+EfiStrCpy (
+ IN CHAR16 *Destination,
+ IN CHAR16 *Source
+ );
+
+VOID
+EfiStrCat (
+ IN CHAR16 *Destination,
+ IN CHAR16 *Source
+ );
+
+
+//=== HELPER Functions ====================//
+VOID *
+EfiLibAllocatePool (
+ IN UINTN AllocationSize
+ )
+{
+ return Malloc(AllocationSize);
+}
+
+VOID *
+EfiLibAllocateZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return MallocZ(AllocationSize);
+}
+
+UINTN
+EfiStrLen (
+ IN CHAR16 *String
+ );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemFreePointer
+//
+// Description: function to free the pointers
+//
+// Input: VOID **ptr
+//
+// Output: void
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MemFreePointer( VOID **ptr )
+{
+ if ( ( ptr == NULL ) || ( *ptr == NULL ) )
+ return;
+
+ gBS->FreePool( *ptr );
+ *ptr = NULL;
+}
+
+UINTN StrLen8(CHAR8 *string)
+{
+ UINTN i=0;
+ while(string[i])
+ i++;
+
+ return i;
+}
+
+
+CHAR8 *StrDup8( CHAR8 *string )
+{
+ CHAR8 *text;
+
+ text = EfiLibAllocateZeroPool(1 + StrLen8( string ));
+ if ( text != NULL )
+ StrCpy8( text, string );
+
+ return text;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemCopy
+//
+// Description: function to copy a memory
+//
+// Input: VOID *dest, VOID *src, UINTN size
+//
+// Output: void
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MemCopy( VOID *dest, VOID *src, UINTN size )
+{
+ gBS->CopyMem( dest, src, size );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemReallocateZeroPool
+//
+// Description: function to reuse a allocated buffer
+//
+// Input: VOID *oldBuffer, UINTN oldSize, UINTN newSize
+//
+// Output: void
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *MemReallocateZeroPool( VOID *oldBuffer, UINTN oldSize, UINTN newSize )
+{
+ VOID *buffer;
+
+ buffer = EfiLibAllocateZeroPool( newSize );
+ if ( buffer == NULL )
+ return buffer;
+
+ if ( newSize < oldSize )
+ oldSize = newSize;
+
+ if ( oldBuffer != NULL )
+ MemCopy( buffer, oldBuffer, oldSize );
+
+ MemFreePointer( (VOID **)&oldBuffer );
+
+ return buffer;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+//
+// Name: StrDup8to16
+//
+// Description: Duplicates a String from CHAR8 to CHAR16
+//
+// Input: CHAR8* string
+//
+// Output: CHAR16 *
+//
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR16 *StrDup8to16( CHAR8 *string )
+{
+ CHAR16 *text;
+ UINTN i;
+
+ text = EfiLibAllocatePool( (1 + StrLen8( string )) * sizeof(CHAR16));
+ if ( text != NULL )
+ {
+ i=0;
+ while(text[i] = (CHAR16)string[i])
+ i++;
+ }
+
+ return text;
+}
+
+
+INTN
+EfiStrnCmp (
+ IN CHAR16 *String,
+ IN CHAR16 *String2,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+ This function compares the Unicode string String to the Unicode
+ string String2 for len characters. If the first len characters
+ of String is identical to the first len characters of String2,
+ then 0 is returned. If substring of String sorts lexicographically
+ after String2, the function returns a number greater than 0. If
+ substring of String sorts lexicographically before String2, the
+ function returns a number less than 0.
+
+Arguments:
+ String - Compare to String2
+ String2 - Compare to String
+ Length - Number of Unicode characters to compare
+
+Returns:
+ 0 - The substring of String and String2 is identical.
+ > 0 - The substring of String sorts lexicographically after String2
+ < 0 - The substring of String sorts lexicographically before String2
+
+--*/
+{
+ while (*String && Length != 0) {
+ if (*String != *String2) {
+ break;
+ }
+ String += 1;
+ String2 += 1;
+ Length -= 1;
+ }
+ return Length > 0 ? *String - *String2 : 0;
+}
+
+UINTN
+EfiDevicePathSize (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return DPLength(DevicePath);
+}
+
+
+VOID InitGlobels(VOID)
+{
+ gBS=pBS;
+ gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, &gHiiDatabase);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Hii21ExportConfigHelper
+//
+// Description: Helper function to perform ExportConfig Operation of Config
+// roughting protocol.
+//
+// Parameter: EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,
+// OUT EFI_STRING *Results
+//
+// Return value: Status
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Hii21ExportConfigHelper (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+)
+{
+ EFI_HII_HANDLE *HiiHandleList;
+ UINT16 NumberOfHiiHandles = 0;
+ UINTN i;
+ UINT8 *FormSet;
+ UINT8 *ifrData;
+ UINTN Length;
+ EFI_STRING result=NULL;
+ UINTN OldSize,NewSize;
+
+ if(Results == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *Results = NULL;
+ InitGlobels();
+ gHiiConfigRouting = (EFI_HII_CONFIG_ROUTING_PROTOCOL*)This;
+
+ // To get the All the Valid Hii Handles.
+ HiiHandleList = HiiGetHandles(&NumberOfHiiHandles);
+ gpVarInfo = gVarInfoHead = NULL;
+
+ for(i=0;i<NumberOfHiiHandles;i++)
+ {
+ Length = 0;
+ // To get the FormPackage
+ FormSet = _HiiGetForm( HiiHandleList[i], &Length);
+ // donot contain valid package.
+ if(FormSet == NULL)
+ continue;
+ ifrData = (UINT8*)(FormSet + sizeof(EFI_HII_PACKAGE_HEADER));
+ _HiiGetVariable(HiiHandleList[i], ifrData);
+
+ // Free the FormPackage
+ MemFreePointer(&FormSet);
+ }
+
+
+ gpVarInfo = gVarInfoHead;
+ OldSize = NewSize = 0;
+ while( gpVarInfo != NULL )
+ {
+ VARSTORE_INFO *tmpVarInfo;
+ EFI_STATUS Status;
+
+ Status = GetVarStoreConfig(gpVarInfo, &result);
+ if(!EFI_ERROR(Status))
+ {
+ NewSize = OldSize + (EfiStrLen(result)*2)+10;
+ *Results = MemReallocateZeroPool(*Results, OldSize, NewSize);
+ if(OldSize)
+ EfiStrCat(*Results,L"&");
+ EfiStrCat(*Results,result);
+ MemFreePointer(&result);
+ OldSize = NewSize;
+ }
+
+ MemFreePointer(&gpVarInfo->VariableName);
+ tmpVarInfo = gpVarInfo;
+ gpVarInfo = gpVarInfo->Next;
+ MemFreePointer(&tmpVarInfo);
+ }
+
+ // free the Hii Handles
+ MemFreePointer((VOID**)&HiiHandleList);
+ return EFI_SUCCESS;
+}
+
+
+BOOLEAN IsVarStoreFound(EFI_HII_HANDLE Handle, EFI_IFR_VARSTORE *varstore)
+{
+ VARSTORE_INFO * VarInfo;
+// EFI_GUID SetupGuid = SETUP_GUID;
+
+ VarInfo = gVarInfoHead;
+ while( VarInfo != NULL )
+ {
+ if( MemCmp( (UINT8*)&VarInfo->VariableGuid,(UINT8*) &(varstore->Guid) , sizeof(EFI_GUID)) == 0)
+ if(Strcmp(VarInfo->VariableName, (char*)varstore->Name) ==0)
+ {
+// In Aptio, There are many Variables used in multiple Vfr.
+
+/*
+// Setup Variable even if it differ handle the variable info is same.
+ if( (MemCmp( (UINT8*)&VarInfo->VariableGuid,(UINT8*) &SetupGuid , sizeof(EFI_GUID)) == 0) &&
+ (Strcmp(VarInfo->VariableName, "Setup") == 0) )
+ return TRUE;
+// For not SETUP_DATA if the Handle is different it can be different Variable
+ else if(VarInfo->VariableHandle == Handle)
+*/
+ return TRUE;
+
+ }
+ VarInfo = VarInfo->Next;
+ }
+ return FALSE;
+}
+
+VOID _HiiGetVariable(EFI_HII_HANDLE Handle, UINT8 * buff)
+{
+ EFI_IFR_OP_HEADER *Header;
+ UINTN ScopeCount = 0;
+ EFI_IFR_VARSTORE *varstore;
+
+ //go thru the forms get the variables.
+ do
+ {
+ Header = (EFI_IFR_OP_HEADER*)(buff);
+ switch(Header->OpCode )
+ {
+ case EFI_IFR_END_OP:
+ ScopeCount--;
+ break;
+
+ case EFI_IFR_VARSTORE_OP:
+ if(!IsVarStoreFound(Handle, (EFI_IFR_VARSTORE *)buff))
+ {
+ if( gVarInfoHead == NULL)
+ {
+ gVarInfoHead = EfiLibAllocateZeroPool(sizeof(VARSTORE_INFO));
+ gVarInfoHead->Next = NULL;
+ gpVarInfo = gVarInfoHead;
+ }
+ else
+ {
+ gpVarInfo->Next = EfiLibAllocateZeroPool(sizeof(VARSTORE_INFO));
+ gpVarInfo = gpVarInfo->Next;
+ gpVarInfo->Next = NULL;
+ }
+
+ varstore = (EFI_IFR_VARSTORE*)buff;
+
+ MemCopy(&gpVarInfo->VariableGuid, &(varstore->Guid), sizeof(EFI_GUID));
+ gpVarInfo->VariableHandle = (VOID*)Handle;
+ gpVarInfo->VariableSize = varstore->Size;
+ gpVarInfo->VariableName = StrDup8((char*)varstore->Name);
+ }
+ default:
+ if(Header->Scope)
+ {
+ ScopeCount++;
+ }
+ break;
+
+ }
+ buff += Header->Length;
+ }while(ScopeCount != 0);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _HiiGetForm
+//
+// Description:
+//
+// Parameter:
+//
+// Return value:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *_HiiGetForm( EFI_HII_HANDLE Handle, UINTN *Length )
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_HII_PACKAGE_HEADER *pkgHdr;
+ EFI_IFR_OP_HEADER *opHeader = NULL;
+ VOID *hiiFormPackage=NULL;
+ UINT8 *formPkBuffer = NULL;
+ UINT8 *pkgOffset;
+ UINT8 end = 0;
+ UINT32 offset = 0;
+ UINTN len=10;
+ //SETUP_LINK DummySetupLink;
+
+ if(Length == NULL)
+ Length = &len;
+
+ hiiFormPackage = EfiLibAllocateZeroPool(*Length);
+
+ status = gHiiDatabase->ExportPackageLists(gHiiDatabase, Handle, Length, hiiFormPackage);
+ if(status == EFI_BUFFER_TOO_SMALL)
+ {
+ MemFreePointer(&hiiFormPackage);
+ //
+ // Allocate space for retrieval of IFR data
+ //
+ hiiFormPackage = EfiLibAllocateZeroPool(*Length);
+
+ if (hiiFormPackage == NULL)
+ {
+ hiiFormPackage = NULL;
+ goto DONE;
+ }
+ //
+ // Get all the packages associated with this HiiHandle
+ //
+ status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, Length, hiiFormPackage);
+ if(EFI_ERROR(status))
+ {
+ MemFreePointer(&hiiFormPackage);
+ hiiFormPackage = NULL;
+ goto DONE;
+ }
+ }else if(EFI_ERROR(status))
+ {
+ hiiFormPackage = NULL;
+ goto DONE;
+ }
+
+ offset = sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ while(offset < ((EFI_HII_PACKAGE_LIST_HEADER*)hiiFormPackage)->PackageLength)
+ {
+ pkgOffset = ((UINT8*)hiiFormPackage) + offset;
+ pkgHdr = (EFI_HII_PACKAGE_HEADER*)pkgOffset;
+ switch(pkgHdr->Type)
+ {
+ case EFI_HII_PACKAGE_FORMS:
+ formPkBuffer = (UINT8*)EfiLibAllocateZeroPool(pkgHdr->Length);
+ if(formPkBuffer == NULL)
+ {
+ goto DONE;
+ }
+
+ MemCopy(formPkBuffer, pkgHdr, pkgHdr->Length);
+
+ opHeader = (EFI_IFR_OP_HEADER*)((UINT8*)formPkBuffer + sizeof(EFI_HII_PACKAGE_HEADER));
+ if(opHeader->OpCode != EFI_IFR_FORM_SET_OP)
+ {
+ MemFreePointer(&formPkBuffer);
+ formPkBuffer = NULL;
+ *Length = 0;
+ goto DONE;
+ }
+
+ end = 1;
+ break;
+ case EFI_HII_PACKAGE_END:
+ end = 1;
+ break;
+ default:
+ break;
+ }
+ if(end)
+ {
+ break;
+ }
+ offset += pkgHdr->Length;
+ }
+
+ MemFreePointer(&hiiFormPackage);
+
+DONE:
+ return formPkBuffer;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: HiiGetHandles
+//
+// Description: gets all the HII handles
+//
+// Parameter: No of handles
+//
+// Return value: EFI_HII_HANDLE *
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_HII_HANDLE *HiiGetHandles(UINT16 *NumberOfHiiHandles)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_HII_HANDLE *hiiHandleBuffer = NULL;
+ UINTN handleBufferLength = sizeof(EFI_HII_HANDLE);
+
+ hiiHandleBuffer = EfiLibAllocatePool(handleBufferLength);
+
+ status = gHiiDatabase->ListPackageLists (gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, NULL,
+ &handleBufferLength, hiiHandleBuffer);
+ if (status == EFI_BUFFER_TOO_SMALL)
+ {
+ //
+ // Free the old pool
+ //
+ MemFreePointer ((VOID**)&hiiHandleBuffer);
+ //
+ // Allocate new pool with correct value
+ //
+ hiiHandleBuffer = EfiLibAllocatePool(handleBufferLength);
+
+ //
+ // Get the Handles of the packages that were registered with Hii
+ //
+ gBS->SetMem(hiiHandleBuffer,handleBufferLength,0);
+ status = gHiiDatabase->ListPackageLists (gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL,
+ NULL, &handleBufferLength, hiiHandleBuffer);
+
+ if (EFI_ERROR (status))
+ {
+ MemFreePointer((VOID**)&hiiHandleBuffer);
+ hiiHandleBuffer = NULL;
+ goto DONE;
+ }
+ }else if(EFI_ERROR(status))
+ {
+ MemFreePointer((VOID**)&hiiHandleBuffer);
+ hiiHandleBuffer = NULL;
+ goto DONE;
+ }
+
+ *NumberOfHiiHandles = (UINT16)(handleBufferLength / sizeof(EFI_HII_HANDLE));
+
+DONE:
+ return hiiHandleBuffer;
+}
+
+
+
+
+EFI_STATUS GetVarStoreConfig(VARSTORE_INFO *VarInfo, EFI_STRING *result)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_STRING configuration = NULL;
+ EFI_STRING progress = NULL;
+ //EFI_STRING result = NULL;
+ //EFI_STRING stringPtr = NULL;
+ UINTN length = 1;
+ //UINT8 *buffer = NULL;
+
+ configuration = EfiLibAllocateZeroPool(length);
+ if(configuration == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ //
+ // Construct the Configuration Header String
+ //
+ status = GetConfigHeader(VarInfo, &configuration, &length);
+ if(EFI_ERROR(status))
+ {
+ //TSE_DEBUG ( (TSE_DBG_LEVEL, "\nGetConfigHeader FAIL\n" ));
+ goto DONE;
+ }
+
+/* if(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)
+ {
+ }else
+*/
+ {
+ status = GetBlockName(&configuration, &length, VarInfo->VariableSize);
+ if(EFI_ERROR(status))
+ {
+ //TSE_DEBUG ( (TSE_DBG_LEVEL, "\n GetBlockname FAIL\n" ));
+ goto DONE;
+ }
+ }
+
+ // Invoke Config Routing Route Config
+ status = gHiiConfigRouting->ExtractConfig(gHiiConfigRouting, configuration, &progress, result);
+
+ if(EFI_ERROR(status))
+ *result = NULL;
+
+ status = _VerifyResponseString(*result, /*(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)? TRUE :*/ FALSE);
+
+DONE:
+ if(configuration)
+ {
+ MemFreePointer(&configuration);
+ }
+
+ return status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: _VerifyResponseString
+//
+// Description: Verifies Correctness of Response String. This is to prevent
+// crashing if the result pointer is pointing to an invalid location.
+//
+// Parameter: EFI_STRING *Configuration
+//
+// Return value: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS _VerifyResponseString(EFI_STRING Configuration, BOOLEAN NameValue)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_STRING config = Configuration;
+ CHAR16 *keyWord[] = {L"GUID=", L"&NAME=", L"&PATH=", L"&OFFSET=0&WIDTH=", L"&VALUE="};
+ UINT32 i = 0;
+ UINT32 count = NameValue? 3 : 5; // If Name Value Check only upto &Path else check until &Value.
+
+ if(EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0)
+ {
+ status = EFI_NOT_FOUND;
+ goto DONE;
+ }
+
+ for(i = 1; i < count; i++)
+ {
+ for(;EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0 && (config != (Configuration + EfiStrLen(Configuration))); config++)
+ ;
+ if(EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0)
+ {
+ status = EFI_NOT_FOUND;
+ goto DONE;
+ }
+ }
+
+DONE:
+ return status;
+}
+
+
+
+EFI_STATUS GetConfigHeader(VARSTORE_INFO *VarInfo, EFI_STRING *Configuration, UINTN *Length)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_STRING configuration = NULL;
+ EFI_HANDLE driverHandle;
+ UINTN length = 0;
+ CHAR16 *VarName=NULL;
+
+ //
+ // Retrieve the Device Path from Handle
+ //
+ status = gHiiDatabase->GetPackageListHandle(gHiiDatabase, VarInfo->VariableHandle, &driverHandle);
+ if(EFI_ERROR(status))
+ {
+ goto DONE;
+ }
+
+ //
+ // Construct the Configuration Header String
+ //
+ VarName = StrDup8to16(VarInfo->VariableName);
+ status = _ConstructConfigHdr(configuration, &length, &VarInfo->VariableGuid, VarName, driverHandle);
+ if(EFI_ERROR(status))
+ {
+ if(status == EFI_BUFFER_TOO_SMALL)
+ {
+ MemFreePointer(&configuration);
+ configuration = (UINT16*)EfiLibAllocateZeroPool(length);
+ if(configuration == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ status = _ConstructConfigHdr(configuration, &length, &VarInfo->VariableGuid, VarName, driverHandle);
+ }
+ }
+
+ if(EFI_ERROR(status))
+ {
+ goto DONE;
+ }
+
+ if(*Configuration)
+ {
+ MemFreePointer(Configuration);
+ }
+ *Configuration = configuration;
+ *Length = length;
+
+DONE:
+ MemFreePointer(&VarName);
+ return status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: _ConstructConfigHdr
+//
+// Description: Construct <ConfigHdr> using routing information GUID/NAME/PATH.
+//
+// Parameter: IN OUT CHAR16 *ConfigHdr,
+// IN OUT UINTN *StrBufferLen,
+// IN EFI_GUID *Guid,
+// IN CHAR16 *Name, OPTIONAL
+// IN EFI_HANDLE *DriverHandle
+//
+// Return value: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS _ConstructConfigHdr (
+ IN OUT CHAR16 *ConfigHdr,
+ IN OUT UINTN *StrBufferLen,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name, OPTIONAL
+ IN EFI_HANDLE *DriverHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN NameStrLen;
+ UINTN DevicePathSize;
+ UINTN BufferSize;
+ CHAR16 *StrPtr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (Name == NULL)
+ {
+ //
+ // There will be no "NAME" in <ConfigHdr> for Name/Value storage
+ //
+ NameStrLen = 0;
+ } else
+ {
+ //
+ // For buffer storage
+ //
+ NameStrLen = EfiStrLen (Name);
+ }
+
+ //
+ // Retrieve DevicePath Protocol associated with this HiiPackageList
+ //
+ Status = gBS->HandleProtocol (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status))
+ {
+ return Status;
+ }
+
+ DevicePathSize = EfiDevicePathSize (DevicePath);
+
+ //
+ // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
+ // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
+ //
+ BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16);
+ if (*StrBufferLen < BufferSize)
+ {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+
+ StrPtr = ConfigHdr;
+
+ EfiStrCpy (StrPtr, L"GUID=");
+ StrPtr += 5;
+ BufferToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));
+ StrPtr += 32;
+
+ //
+ // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"
+ //
+ EfiStrCpy (StrPtr, L"&NAME=");
+ StrPtr += 6;
+ if (Name != NULL)
+ {
+ BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16);
+ UnicodeToConfigString (StrPtr, &BufferSize, Name);
+ StrPtr += (NameStrLen * 4);
+ }
+
+ EfiStrCpy (StrPtr, L"&PATH=");
+ StrPtr += 6;
+ BufferToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBlockName
+//
+// Description:
+//
+// Parameter: EFI_STRING *Configuration, UINTN *Length, UINTN Size
+//
+// Return value: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetBlockName(EFI_STRING *Configuration, UINTN *Length, UINTN Size)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ UINTN length = 0;
+ UINTN finalLen = 0;
+ CHAR16 *tempBuffer = NULL;
+
+ length = (EfiStrLen(L"&OFFSET=0&WIDTH=") + sizeof(Size) + 1) * sizeof(CHAR16);
+ tempBuffer = (CHAR16*)EfiLibAllocateZeroPool(length);
+ if(tempBuffer == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ Swprintf_s(tempBuffer, length, L"&OFFSET=0&WIDTH=%x", Size);
+
+ length = EfiStrLen(*Configuration) * sizeof(CHAR16);
+ finalLen = (EfiStrLen(*Configuration) + EfiStrLen(tempBuffer) + 1) * sizeof(CHAR16);
+ *Configuration = MemReallocateZeroPool(*Configuration, length, finalLen);
+ if(*Configuration == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ EfiStrCat(*Configuration, tempBuffer);
+
+ MemFreePointer(&tempBuffer);
+ *Length = finalLen;
+
+DONE:
+ return status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BufferToHexString
+//
+// Description: Converts binary buffer to Unicode string in reversed byte order from BufToHexString().
+//
+// Input: Str - String for output
+// Buffer - Binary buffer.
+// BufferSize - Size of the buffer in bytes.
+//
+// Output: EFI_SUCCESS - The function completed successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BufferToHexString (
+ IN OUT CHAR16 *Str,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *NewBuffer;
+ UINTN StrBufferLen;
+
+ NewBuffer = EfiLibAllocatePool (BufferSize);
+ MemCopy(NewBuffer, Buffer, BufferSize);
+
+ SwapBuffer (NewBuffer, BufferSize);
+
+ StrBufferLen = BufferSize * 2 + 1;
+ Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);
+
+ gBS->FreePool (NewBuffer);
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (Str);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UnicodeToConfigString
+//
+// Description: Convert Unicode string to binary representation Config string, e.g.
+// "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
+// "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+//
+// Input: ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
+// StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
+// Includes tailing '\0' character.
+// On output:
+// If return EFI_SUCCESS, containing length of Unicode string buffer.
+// If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+// UnicodeString - Original Unicode string.
+//
+// Output: EFI_SUCCESS - Routine success.
+// EFI_BUFFER_TOO_SMALL - The string buffer is too small.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UnicodeToConfigString (
+ IN OUT CHAR16 *ConfigString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *UnicodeString
+ )
+{
+ UINTN Index;
+ UINTN Len;
+ UINTN BufferSize;
+ CHAR16 *String;
+
+ Len = EfiStrLen (UnicodeString);
+ BufferSize = (Len * 4 + 1) * sizeof (CHAR16);
+
+ if (*StrBufferLen < BufferSize) {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+ String = ConfigString;
+
+ for (Index = 0; Index < Len; Index++) {
+ BufToHexString (ConfigString, &BufferSize, (UINT8 *) UnicodeString, 2);
+
+ ConfigString += 4;
+ UnicodeString += 1;
+ }
+
+ //
+ // Add tailing '\0' character
+ //
+ *ConfigString = L'\0';
+
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (String);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ToLower
+//
+// Description: Converts the unicode character of the string from uppercase to lowercase.
+//
+// Input: Str - String to be converted
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ToLower (
+ IN OUT CHAR16 *Str
+ )
+{
+ CHAR16 *Ptr;
+
+ for (Ptr = Str; *Ptr != L'\0'; Ptr++) {
+ if (*Ptr >= L'A' && *Ptr <= L'Z') {
+ *Ptr = (CHAR16) (*Ptr - L'A' + L'a');
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SwapBuffer
+//
+// Description: Swap bytes in the buffer.
+//
+// Input: Buffer - Binary buffer.
+// BufferSize - Size of the buffer in bytes.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SwapBuffer (
+ IN OUT UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Index;
+ UINT8 Temp;
+ UINTN SwapCount;
+
+ SwapCount = BufferSize / 2;
+ for (Index = 0; Index < SwapCount; Index++) {
+ Temp = Buffer[Index];
+ Buffer[Index] = Buffer[BufferSize - 1 - Index];
+ Buffer[BufferSize - 1 - Index] = Temp;
+ }
+}
+