summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe
diff options
context:
space:
mode:
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
commit878ddf1fc3540a715f63594ed22b6929e881afb4 (patch)
treec56c44dac138137b510e1fba7c3efe5e4d84bea2 /EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe
downloadedk2-platforms-878ddf1fc3540a715f63594ed22b6929e881afb4.tar.xz
Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe')
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Fonts.c263
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Forms.c1564
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.c413
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.dxs26
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.h302
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.mbd44
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa80
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Keyboard.c43
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c677
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c1276
-rw-r--r--EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/build.xml47
11 files changed, 4735 insertions, 0 deletions
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Fonts.c b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Fonts.c
new file mode 100644
index 0000000000..52dc12e877
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Fonts.c
@@ -0,0 +1,263 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Fonts.c
+
+Abstract:
+
+ This file contains the Glyph/Font processing code to the HII database.
+
+--*/
+
+
+#include "HiiDatabase.h"
+
+//
+// We only need to define a wide glyph, since we will seed the narrow glyph with EFI_NARROW_GLYPH size of
+// this data structure
+//
+UINT8 mUnknownGlyph[38] = {
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xAA,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xaa,
+ 0x55,
+ 0xAA
+};
+
+EFI_STATUS
+EFIAPI
+HiiGetGlyph (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Source,
+ IN OUT UINT16 *Index,
+ OUT UINT8 **GlyphBuffer,
+ OUT UINT16 *BitWidth,
+ IN OUT UINT32 *InternalStatus
+ )
+/*++
+
+Routine Description:
+ Translates a Unicode character into the corresponding font glyph.
+ If the Source was pointing to a non-spacing character, the next Source[*Index]
+ character will be parsed and OR'd to the GlyphBuffer until a spacing character
+ is found in the Source. Since non-spacing characters are considered to be the
+ same pixel width as a regular character their BitWidth will be reflected correctly
+ however due to their special attribute, they are considered to be zero advancing width.
+ This basically means that the cursor would not advance, thus the character that follows
+ it would overlay the non-spacing character. The Index is modified to reflect both the
+ incoming array entry into the Source string but also the outgoing array entry after having
+ parsed the equivalent of a single Glyph's worth of data.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_HII_GLOBAL_DATA *GlobalData;
+ EFI_HII_DATA *HiiData;
+ UINTN Count;
+ BOOLEAN Narrow;
+ UINTN Location;
+ UINTN SearchLocation;
+ UINTN Value;
+ CHAR16 Character;
+ UINTN Attributes;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ GlobalData = HiiData->GlobalData;
+ Count = sizeof (GlobalData->NarrowGlyphs->GlyphCol1);
+
+ Location = *Index;
+ SearchLocation = *Index;
+ Narrow = TRUE;
+
+ if (Source[Location] == NARROW_CHAR || Source[Location] == WIDE_CHAR) {
+ *InternalStatus = 0;
+ }
+ //
+ // We don't know what glyph database to look in - let's figure it out
+ //
+ if (*InternalStatus == 0) {
+ //
+ // Determine if we are looking for narrow or wide glyph data
+ //
+ do {
+ if (Source[SearchLocation] == NARROW_CHAR || Source[SearchLocation] == WIDE_CHAR) {
+ //
+ // We found something that identifies what glyph database to look in
+ //
+ if (Source[SearchLocation] == WIDE_CHAR) {
+ Narrow = FALSE;
+ *BitWidth = WIDE_WIDTH;
+ *InternalStatus = WIDE_CHAR;
+ Location++;
+ break;
+ } else {
+ Narrow = TRUE;
+ *BitWidth = NARROW_WIDTH;
+ *InternalStatus = NARROW_CHAR;
+ Location++;
+ break;
+ }
+ }
+ } while (SearchLocation-- > 0);
+ }
+
+ if (*InternalStatus == NARROW_CHAR) {
+ Narrow = TRUE;
+ *BitWidth = NARROW_WIDTH;
+ } else if (*InternalStatus == WIDE_CHAR) {
+ Narrow = FALSE;
+ *BitWidth = WIDE_WIDTH;
+ } else {
+ //
+ // Without otherwise knowing what the width is narrow (e.g. someone passed in a string with index of 0
+ // we wouldn't be able to determine the width of the data.)
+ // BUGBUG - do we go to wide database and if exist, ignore narrow? Check Unicode spec....
+ //
+ Narrow = TRUE;
+ *BitWidth = NARROW_WIDTH;
+ }
+
+ Character = Source[Location];
+
+ if (Narrow) {
+ if (GlobalData->NarrowGlyphs[Character].UnicodeWeight != 0x0000) {
+ *GlyphBuffer = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);
+ Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
+ } else {
+ //
+ // Glyph is uninitialized - return an error, but hand back the glyph
+ //
+ *GlyphBuffer = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);
+ *Index = (UINT16) (Location + 1);
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ //
+ // Wide character
+ //
+ if (GlobalData->WideGlyphs[Character].UnicodeWeight != 0x0000) {
+ *GlyphBuffer = (UINT8 *) (&GlobalData->WideGlyphs[Character]);
+ Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
+ } else {
+ //
+ // Glyph is uninitialized - return an error, but hand back the glyph
+ //
+ *GlyphBuffer = (UINT8 *) (&GlobalData->WideGlyphs[Character]);
+ *Index = (UINT16) (Location + 1);
+ return EFI_NOT_FOUND;
+ }
+ }
+ //
+ // This is a non-spacing character. It will be followed by either more non-spacing
+ // characters or a regular character. We need to OR together the data associated with each.
+ //
+ for (; Attributes != 0; Location++) {
+ //
+ // Character is the Unicode value which is the index into the Glyph array.
+ //
+ Character = Source[Location];
+
+ if (Narrow) {
+ for (Value = 0; Value != Count; Value++) {
+ *GlyphBuffer[Location + Value] |= GlobalData->NarrowGlyphs[Character].GlyphCol1[Value];
+ }
+
+ Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
+ } else {
+ for (Value = 0; Value != Count; Value++) {
+ *GlyphBuffer[Location + Value] |= GlobalData->WideGlyphs[Character].GlyphCol1[Value];
+ *GlyphBuffer[Location + Value + Count] |= GlobalData->WideGlyphs[Character].GlyphCol2[Value];
+ }
+
+ Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
+ }
+ }
+ //
+ // Source[*Index] should point to the next character to process
+ //
+ *Index = (UINT16) (Location + 1);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiiGlyphToBlt (
+ IN EFI_HII_PROTOCOL *This,
+ IN UINT8 *GlyphBuffer,
+ IN EFI_UGA_PIXEL Foreground,
+ IN EFI_UGA_PIXEL Background,
+ IN UINTN Count,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN OUT EFI_UGA_PIXEL *BltBuffer
+ )
+{
+ UINTN X;
+ UINTN Y;
+
+ //
+ // Convert Monochrome bitmap of the Glyph to BltBuffer structure
+ //
+ for (Y = 0; Y < Height; Y++) {
+ for (X = 0; X < Width; X++) {
+ if ((((EFI_NARROW_GLYPH *) GlyphBuffer)->GlyphCol1[Y] & (1 << X)) != 0) {
+ BltBuffer[Y * Width * Count + (Width - X - 1)] = Foreground;
+ } else {
+ BltBuffer[Y * Width * Count + (Width - X - 1)] = Background;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Forms.c b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Forms.c
new file mode 100644
index 0000000000..a0a9619197
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Forms.c
@@ -0,0 +1,1564 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Forms.c
+
+Abstract:
+
+ This file contains the form processing code to the HII database.
+
+--*/
+
+
+#include "HiiDatabase.h"
+
+CHAR16*
+Ascii2Unicode (
+ OUT CHAR16 *UnicodeStr,
+ IN CHAR8 *AsciiStr
+ )
+/*++
+
+ Routine Description:
+
+ This function converts ASCII string to Unicode string.
+
+ Arguments:
+
+ UnicodeStr - NULL terminated Unicode output string.
+ AsciieStr - NULL terminated ASCII input string.
+
+ Returns:
+
+ Start of the Unicode ouput string.
+
+--*/
+
+{
+ CHAR16 *Str = UnicodeStr;
+ while (TRUE) {
+ *(UnicodeStr++) = (CHAR16) *AsciiStr;
+ if (*(AsciiStr++) == '\0') {
+ return Str;
+ }
+ }
+}
+
+CHAR8*
+Unicode2Ascii (
+ OUT CHAR8 *AsciiStr,
+ IN CHAR16 *UnicodeStr
+ )
+/*++
+
+ Routine Description:
+
+ This function converts Unicode string to ASCII string.
+
+ Arguments:
+
+ AsciieStr - NULL terminated ASCII output string.
+ UnicodeStr - NULL terminated Unicode input string.
+
+ Returns:
+
+ Start of the ASCII ouput string.
+
+--*/
+
+{
+ CHAR8 *Str = AsciiStr;
+ while (TRUE) {
+ *(AsciiStr++) = (CHAR8) *UnicodeStr;
+ if (*(UnicodeStr++) == '\0') {
+ return Str;
+ }
+ }
+}
+
+VOID
+ExtractDevicePathData (
+ IN EFI_HII_DATA_TABLE *DataTable,
+ IN UINT8 *IfrData,
+ IN OUT UINT8 **ExportBufferPtr
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINT8 *ExportBuffer;
+
+ ExportBuffer = *ExportBufferPtr;
+
+ //
+ // BUGBUG - don't have devicepath data yet, setting dummy value
+ //
+ DataTable++;
+ ExportBuffer = (UINT8 *) DataTable;
+ ((EFI_HII_DEVICE_PATH_PACK *) ExportBuffer)->Header.Type = EFI_HII_DEVICE_PATH;
+ ((EFI_HII_DEVICE_PATH_PACK *) ExportBuffer)->Header.Length = (UINT32) (sizeof (EFI_HII_DEVICE_PATH_PACK) + sizeof (EFI_DEVICE_PATH_PROTOCOL));
+
+ //
+ // BUGBUG - part of hack - skip the Device Path Pack.....place some data
+ //
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_DEVICE_PATH_PACK);
+
+ ((EFI_DEVICE_PATH_PROTOCOL *) ExportBuffer)->Type = EFI_END_ENTIRE_DEVICE_PATH;
+ ((EFI_DEVICE_PATH_PROTOCOL *) ExportBuffer)->SubType = EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+
+ //
+ // BUGBUG - still part of hack....
+ //
+ ExportBuffer = ExportBuffer + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ *ExportBufferPtr = ExportBuffer;
+}
+
+VOID
+ExtractVariableData (
+ IN OUT EFI_HII_DATA_TABLE *DataTable,
+ IN UINT8 *IfrData,
+ IN OUT UINT8 **ExportBufferPtr
+ )
+/*++
+
+Routine Description:
+
+ This function extract the EFI_HII_VARIABLE_PACK portion from the
+ each of the EFI_HII_PACKAGE_INSTANCE in HII handle database.
+
+Arguments:
+
+ DataTable ¨C On input, this parameter point to the EFI_HII_DATA_TABLE structure
+ of the final data buffer for the EFI_HII_EXPORT interface. This function
+ update the NumberOfVariableData attribute.
+ IfrData - It points to a staring address of a EFI_HII_IFR_PACK structure.
+ ExportBufferPtr ¨C On input, it points the starting address of the data buffer to
+ host the variable pack. On output, it is the starting address
+ of data buffer for the next extraction operation.
+Returns:
+
+ VOID
+
+--*/
+{
+ EFI_HII_VARIABLE_PACK *VariableContents;
+ UINT8 *ExportBuffer;
+ UINTN Index;
+ UINTN Index2;
+ UINTN TempValue;
+ UINTN TempValue2;
+ EFI_FORM_CALLBACK_PROTOCOL *FormCallback;
+ EFI_PHYSICAL_ADDRESS CallbackHandle;
+ EFI_STATUS Status;
+ CHAR16 *String;
+
+ FormCallback = NULL;
+ CallbackHandle = 0;
+ ExportBuffer = *ExportBufferPtr;
+
+ for (Index = 0; IfrData[Index] != EFI_IFR_END_FORM_SET_OP;) {
+ VariableContents = (EFI_HII_VARIABLE_PACK *) ExportBuffer;
+
+ switch (IfrData[Index]) {
+ case EFI_IFR_FORM_SET_OP:
+ TempValue = EFI_HII_VARIABLE;
+ CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));
+ CopyMem (&TempValue, &((EFI_IFR_FORM_SET *) &IfrData[Index])->NvDataSize, sizeof (UINT16));
+
+ //
+ // If the variable has 0 size, do not process it
+ //
+ if (TempValue == 0) {
+ break;
+ }
+ //
+ // Add the size of the variable pack overhead. Later, will also add the size of the
+ // name of the variable.
+ //
+ TempValue = TempValue + sizeof (EFI_HII_VARIABLE_PACK);
+
+ CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));
+ CopyMem (
+ &CallbackHandle,
+ &((EFI_IFR_FORM_SET *) &IfrData[Index])->CallbackHandle,
+ sizeof (EFI_PHYSICAL_ADDRESS)
+ );
+ if (CallbackHandle != 0) {
+ Status = gBS->HandleProtocol (
+ (EFI_HANDLE) (UINTN) CallbackHandle,
+ &gEfiFormCallbackProtocolGuid,
+ (VOID *) &FormCallback
+ );
+ }
+ //
+ // Since we have a "Setup" variable that wasn't specified by a variable op-code
+ // it will have a VariableId of 0. All other variable op-codes will have a designation
+ // of VariableId 1+
+ //
+ TempValue = 0;
+ CopyMem (&VariableContents->VariableId, &TempValue, sizeof (UINT16));
+ CopyMem (&VariableContents->VariableGuid, &((EFI_IFR_FORM_SET *) &IfrData[Index])->Guid, sizeof (EFI_GUID));
+ TempValue = sizeof (SETUP_MAP_NAME);
+ CopyMem (&VariableContents->VariableNameLength, &TempValue, sizeof (UINT32));
+
+ //
+ // Add the size of the name to the Header Length
+ //
+ TempValue2 = 0;
+ CopyMem (&TempValue2, &VariableContents->Header.Length, sizeof (UINT32));
+ TempValue2 = TempValue + TempValue2;
+ CopyMem (&VariableContents->Header.Length, &TempValue2, sizeof (UINT32));
+
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);
+ CopyMem (ExportBuffer, SETUP_MAP_NAME, sizeof (SETUP_MAP_NAME));
+ ExportBuffer = ExportBuffer + sizeof (SETUP_MAP_NAME);
+
+ CopyMem (&TempValue, &((EFI_IFR_FORM_SET *) &IfrData[Index])->NvDataSize, sizeof (UINT16));
+
+ if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {
+ Status = FormCallback->NvRead (
+ FormCallback,
+ (CHAR16 *) SETUP_MAP_NAME,
+ (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,
+ NULL,
+ &TempValue,
+ ExportBuffer
+ );
+ } else {
+ Status = gRT->GetVariable (
+ (CHAR16 *) SETUP_MAP_NAME,
+ (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,
+ NULL,
+ &TempValue,
+ ExportBuffer
+ );
+ }
+
+ ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + TempValue);
+ DataTable->NumberOfVariableData++;
+ break;
+
+ case EFI_IFR_VARSTORE_OP:
+ TempValue = EFI_HII_VARIABLE;
+ CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));
+ CopyMem (&TempValue, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Size, sizeof (UINT16));
+
+ //
+ // If the variable has 0 size, do not process it
+ //
+ if (TempValue == 0) {
+ break;
+ }
+ //
+ // Add the size of the variable pack overhead. Later, will also add the size of the
+ // name of the variable.
+ //
+ TempValue = TempValue + sizeof (EFI_HII_VARIABLE_PACK);
+
+ CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));
+ CopyMem (&VariableContents->VariableId, &((EFI_IFR_VARSTORE *) &IfrData[Index])->VarId, sizeof (UINT16));
+ CopyMem (&VariableContents->VariableGuid, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Guid, sizeof (EFI_GUID));
+ TempValue = (UINTN) ((EFI_IFR_VARSTORE *) &IfrData[Index])->Header.Length - sizeof (EFI_IFR_VARSTORE);
+ TempValue = TempValue * 2;
+ CopyMem (&VariableContents->VariableNameLength, &TempValue, sizeof (UINT32));
+
+ //
+ // Add the size of the name to the Header Length
+ //
+ TempValue2 = 0;
+ CopyMem (&TempValue2, &VariableContents->Header.Length, sizeof (UINT32));
+ TempValue2 = TempValue + TempValue2;
+ CopyMem (&VariableContents->Header.Length, &TempValue2, sizeof (UINT32));
+
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);
+ String = (CHAR16 *) ExportBuffer;
+ for (Index2 = 0; Index2 < TempValue / 2; Index2++) {
+ ExportBuffer[Index2 * 2] = IfrData[Index + sizeof (EFI_IFR_VARSTORE) + Index2];
+ ExportBuffer[Index2 * 2 + 1] = 0;
+ }
+
+ ExportBuffer = ExportBuffer + TempValue;
+
+ CopyMem (&TempValue, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Size, sizeof (UINT16));
+
+ if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {
+ Status = FormCallback->NvRead (
+ FormCallback,
+ String,
+ (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,
+ NULL,
+ &TempValue,
+ ExportBuffer
+ );
+ } else {
+ Status = gRT->GetVariable (
+ String,
+ (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,
+ NULL,
+ &TempValue,
+ ExportBuffer
+ );
+ }
+
+ ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + TempValue);
+ DataTable->NumberOfVariableData++;
+ break;
+ }
+
+ Index = IfrData[Index + 1] + Index;
+ }
+ //
+ // If we have added a variable pack, add a dummy empty one to signify the end
+ //
+ if (ExportBuffer != *ExportBufferPtr) {
+ VariableContents = (EFI_HII_VARIABLE_PACK *) ExportBuffer;
+ TempValue = EFI_HII_VARIABLE;
+ CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));
+ TempValue = sizeof (EFI_HII_VARIABLE_PACK);
+ CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);
+ }
+
+ *ExportBufferPtr = ExportBuffer;
+}
+
+EFI_STATUS
+EFIAPI
+HiiExportDatabase (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ This function allows a program to extract a form or form package that has
+ previously been registered with the EFI HII database.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_IFR_PACK *FormPack;
+ UINT8 *RawData;
+ UINT8 *ExportBuffer;
+ EFI_HII_EXPORT_TABLE *ExportTable;
+ EFI_HII_DATA_TABLE *DataTable;
+ BOOLEAN InsufficientSize;
+ BOOLEAN VariableExist;
+ UINT16 NumberOfHiiDataTables;
+ UINTN SizeNeeded;
+ UINTN Index;
+ UINTN VariableSize;
+ UINTN TempValue;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ HandleDatabase = HiiData->DatabaseHead;
+
+ FormPack = NULL;
+ RawData = NULL;
+ PackageInstance = NULL;
+ InsufficientSize = FALSE;
+ NumberOfHiiDataTables = 0;
+ VariableSize = 0;
+ TempValue = 0;
+ SizeNeeded = sizeof (EFI_HII_EXPORT_TABLE);
+
+ //
+ // How many total tables are there?
+ //
+ for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ if ((Handle != 0) && (Handle != HandleDatabase->Handle)) {
+ continue;
+ }
+
+ VariableExist = FALSE;
+ NumberOfHiiDataTables++;
+ PackageInstance = HandleDatabase->Buffer;
+ if (PackageInstance == NULL) {
+ continue;
+ }
+ //
+ // Extract Size of Export Package
+ //
+ SizeNeeded = SizeNeeded + PackageInstance->IfrSize
+ + PackageInstance->StringSize
+ + sizeof (EFI_HII_DATA_TABLE)
+ + sizeof (EFI_HII_DEVICE_PATH_PACK);
+
+ //
+ // BUGBUG We aren't inserting Device path data yet
+ //
+ SizeNeeded = SizeNeeded + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ //
+ // Extract Size of Variable Data
+ //
+ if (PackageInstance->IfrSize > 0) {
+ FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
+ } else {
+ //
+ // No IFR? No variable information
+ //
+ continue;
+ }
+
+ RawData = (UINT8 *) FormPack;
+
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
+ switch (RawData[Index]) {
+ case EFI_IFR_FORM_SET_OP:
+ CopyMem (&VariableSize, &((EFI_IFR_FORM_SET *) &RawData[Index])->NvDataSize, sizeof (UINT16));
+ SizeNeeded = SizeNeeded + VariableSize + sizeof (SETUP_MAP_NAME) + sizeof (EFI_HII_VARIABLE_PACK);
+ VariableExist = TRUE;
+ break;
+
+ case EFI_IFR_VARSTORE_OP:
+ CopyMem (&VariableSize, &((EFI_IFR_VARSTORE *) &RawData[Index])->Size, sizeof (UINT16));
+ SizeNeeded = SizeNeeded + VariableSize + sizeof (EFI_HII_VARIABLE_PACK);
+ //
+ // We will be expanding the stored ASCII name to a Unicode string. This will cause some memory overhead
+ // Since the VARSTORE size already takes in consideration the ASCII size, we need to size it and add another
+ // instance of it. Essentially, 2 ASCII strings == 1 Unicode string in size.
+ //
+ TempValue = (UINTN) ((EFI_IFR_VARSTORE *) &RawData[Index])->Header.Length - sizeof (EFI_IFR_VARSTORE);
+ SizeNeeded = SizeNeeded + TempValue * 2;
+ VariableExist = TRUE;
+ break;
+ }
+
+ Index = RawData[Index + 1] + Index;
+ }
+ //
+ // If a variable exists for this handle, add an additional variable pack overhead to
+ // indicate that we will have an extra null Variable Pack to signify the end of the Variable Packs
+ //
+ if (VariableExist) {
+ SizeNeeded = SizeNeeded + sizeof (EFI_HII_VARIABLE_PACK);
+ }
+ }
+
+ if (SizeNeeded > *BufferSize) {
+ *BufferSize = SizeNeeded;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ //
+ // Zero out the incoming buffer
+ //
+ ZeroMem (Buffer, *BufferSize);
+
+ //
+ // Cast the Buffer to EFI_HII_EXPORT_TABLE
+ //
+ ExportTable = (EFI_HII_EXPORT_TABLE *) Buffer;
+
+ //
+ // Set the Revision for the Export Table
+ //
+ CopyMem (&ExportTable->Revision, &gEfiHiiProtocolGuid, sizeof (EFI_GUID));
+
+ ExportBuffer = (UINT8 *) (UINTN) (((UINT8 *) ExportTable) + sizeof (EFI_HII_EXPORT_TABLE));
+ HandleDatabase = HiiData->DatabaseHead;
+
+ //
+ // Check numeric value against the head of the database
+ //
+ for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ DataTable = (EFI_HII_DATA_TABLE *) ExportBuffer;
+ PackageInstance = HandleDatabase->Buffer;
+ //
+ // If not asking for a specific handle, export the entire database
+ //
+ if (Handle == 0) {
+ ExportTable->NumberOfHiiDataTables = NumberOfHiiDataTables;
+ CopyMem (&DataTable->PackageGuid, &PackageInstance->Guid, sizeof (EFI_GUID));
+ DataTable->HiiHandle = PackageInstance->Handle;
+ DataTable->DevicePathOffset = (UINT32) (sizeof (EFI_HII_DATA_TABLE));
+
+ //
+ // Start Dumping DevicePath
+ //
+ ExtractDevicePathData (DataTable, RawData, &ExportBuffer);
+
+ if (((UINTN) ExportBuffer) == ((UINTN) DataTable)) {
+ //
+ // If there is no DevicePath information - set offset to 0 to signify the absence of data to parse
+ //
+ DataTable->DevicePathOffset = 0;
+ }
+
+ DataTable->VariableDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ if (PackageInstance->IfrSize > 0) {
+ FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
+
+ RawData = (UINT8 *) FormPack;
+ TempValue = 0;
+
+ //
+ // Start dumping the Variable Data
+ //
+ ExtractVariableData (DataTable, RawData, &ExportBuffer);
+ DataTable->IfrDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ if (DataTable->VariableDataOffset == DataTable->IfrDataOffset) {
+ DataTable->VariableDataOffset = 0;
+ }
+ //
+ // Start dumping the IFR data (Note: It is in an IFR PACK)
+ //
+ CopyMem (ExportBuffer, &PackageInstance->IfrData, PackageInstance->IfrSize);
+ ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + PackageInstance->IfrSize);
+ DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ //
+ // Start dumping the String data (Note: It is in a String PACK)
+ //
+ if (PackageInstance->StringSize > 0) {
+ RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);
+ CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);
+ DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);
+
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ for (; TempValue != 0;) {
+ DataTable->NumberOfLanguages++;
+ ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ }
+
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);
+ } else {
+ DataTable->StringDataOffset = 0;
+ }
+ } else {
+ //
+ // No IFR? No variable information. If Offset is 0, means there is none. (Hmm - this might be prunable - no strings to export if no IFR - we always have a stub)
+ //
+ DataTable->VariableDataOffset = 0;
+ DataTable->IfrDataOffset = 0;
+ DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ //
+ // Start dumping the String data - NOTE: It is in String Pack form
+ //
+ if (PackageInstance->StringSize > 0) {
+ RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);
+ CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);
+ DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);
+
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ for (; TempValue != 0;) {
+ DataTable->NumberOfLanguages++;
+ ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ }
+
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);
+ } else {
+ DataTable->StringDataOffset = 0;
+ }
+ }
+ } else {
+ //
+ // Match the numeric value with the database entry - if matched, extract PackageInstance
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ ExportTable->NumberOfHiiDataTables = NumberOfHiiDataTables;
+ DataTable->HiiHandle = PackageInstance->Handle;
+ CopyMem (&DataTable->PackageGuid, &PackageInstance->Guid, sizeof (EFI_GUID));
+
+ //
+ // Start Dumping DevicePath
+ //
+ ExtractDevicePathData (DataTable, RawData, &ExportBuffer);
+ DataTable->VariableDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ if (PackageInstance->IfrSize > 0) {
+ FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
+
+ RawData = (UINT8 *) FormPack;
+ TempValue = 0;
+
+ //
+ // Start dumping the Variable Data
+ //
+ ExtractVariableData (DataTable, RawData, &ExportBuffer);
+ DataTable->IfrDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ if (DataTable->VariableDataOffset == DataTable->IfrDataOffset) {
+ DataTable->VariableDataOffset = 0;
+ }
+ //
+ // Start dumping the IFR data
+ //
+ CopyMem (ExportBuffer, &PackageInstance->IfrData, PackageInstance->IfrSize);
+ ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + PackageInstance->IfrSize);
+ DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ //
+ // Start dumping the String data - NOTE: It is in String Pack form
+ //
+ if (PackageInstance->StringSize > 0) {
+ RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);
+ CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);
+ DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);
+
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ for (; TempValue != 0;) {
+ DataTable->NumberOfLanguages++;
+ ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ }
+
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);
+ } else {
+ DataTable->StringDataOffset = 0;
+ }
+ } else {
+ //
+ // No IFR? No variable information. If Offset is 0, means there is none.
+ //
+ DataTable->VariableDataOffset = 0;
+ DataTable->IfrDataOffset = 0;
+ DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));
+
+ //
+ // Start dumping the String data - Note: It is in String Pack form
+ //
+ if (PackageInstance->StringSize > 0) {
+ RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);
+ CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);
+ DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);
+
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ for (; TempValue != 0;) {
+ DataTable->NumberOfLanguages++;
+ ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;
+ CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));
+ }
+
+ ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);
+ } else {
+ DataTable->StringDataOffset = 0;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiiGetForms (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_ID FormId,
+ IN OUT UINTN *BufferLengthTemp,
+ OUT UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+
+ This function allows a program to extract a form or form package that has
+ previously been registered with the EFI HII database.
+
+Arguments:
+ This - A pointer to the EFI_HII_PROTOCOL instance.
+
+ Handle - Handle on which the form resides. Type EFI_HII_HANDLE is defined in
+ EFI_HII_PROTOCOL.NewPack() in the Packages section.
+
+ FormId - The ID of the form to return. If the ID is zero, the entire form package is returned.
+ Type EFI_FORM_ID is defined in "Related Definitions" below.
+
+ BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if
+ the length was sufficient and, if it was not, the length that is required to fit the
+ requested form(s).
+
+ Buffer - The buffer designed to receive the form(s).
+
+Returns:
+
+ EFI_SUCCESS - Buffer filled with the requested forms. BufferLength
+ was updated.
+
+ EFI_INVALID_PARAMETER - The handle is unknown.
+
+ EFI_NOT_FOUND - A form on the requested handle cannot be found with the
+ requested FormId.
+
+ EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.
+
+--*/
+{
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_IFR_PACK *FormPack;
+ EFI_IFR_FORM *Form;
+ EFI_IFR_OP_HEADER *Location;
+ UINT16 *BufferLength = (UINT16 *) BufferLengthTemp;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ HandleDatabase = HiiData->DatabaseHead;
+
+ PackageInstance = NULL;
+
+ //
+ // Check numeric value against the head of the database
+ //
+ for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ //
+ // Match the numeric value with the database entry - if matched, extract PackageInstance
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ break;
+ }
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ if (PackageInstance->IfrSize > 0) {
+ FormPack = (EFI_HII_IFR_PACK *) (&PackageInstance->IfrData);
+ } else {
+ //
+ // If there is no IFR data return an error
+ //
+ return EFI_NOT_FOUND;
+ }
+ //
+ // If requesting the entire Form Package
+ //
+ if (FormId == 0) {
+ //
+ // Return an error if buffer is too small
+ //
+ if (PackageInstance->IfrSize > *BufferLength || Buffer == NULL) {
+ *BufferLength = (UINT16) PackageInstance->IfrSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CopyMem (Buffer, FormPack, PackageInstance->IfrSize);
+ return EFI_SUCCESS;
+ } else {
+ FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
+ Location = (EFI_IFR_OP_HEADER *) FormPack;
+
+ //
+ // Look for the FormId requested
+ //
+ for (; Location->OpCode != EFI_IFR_END_FORM_SET_OP;) {
+ switch (Location->OpCode) {
+ case EFI_IFR_FORM_OP:
+ Form = (EFI_IFR_FORM *) Location;
+
+ //
+ // If we found a Form Op-code and it is of the correct Id, copy it and return
+ //
+ if (Form->FormId == FormId) {
+ if (Location->Length > *BufferLength || Buffer == NULL) {
+ *BufferLength = Location->Length;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ for (; Location->OpCode != EFI_IFR_END_FORM_OP;) {
+ CopyMem (Buffer, Location, Location->Length);
+ Buffer = Buffer + Location->Length;
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+ }
+
+ CopyMem (Buffer, Location, Location->Length);
+ return EFI_SUCCESS;
+ }
+ }
+
+ default:
+ break;
+ }
+ //
+ // Go to the next Op-Code
+ //
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// Helper functions to HiiGetDefaultImage()
+//
+
+STATIC
+UINT8*
+HiiGetDefaultImageInitPack (
+ IN OUT EFI_HII_VARIABLE_PACK_LIST *VariablePackItem,
+ IN EFI_IFR_VARSTORE *VarStore
+ )
+/*++
+
+ Routine Description:
+
+ Initialize the EFI_HII_VARIABLE_PACK_LIST structure and
+ prepare it ready to be used by HiiGetDefaultImagePopulateMap ().
+
+ Arguments:
+
+ VariablePackItem - Variable Package List.
+ VarStore - IFR variable storage.
+
+ Returns:
+
+ Return the pointer to the Map space.
+
+--*/
+{
+ CHAR16 *Name16;
+ CHAR8 *Name8;
+ CHAR8 *Map;
+ EFI_HII_VARIABLE_PACK *VariablePack;
+
+ //
+ // Set pointer the pack right after the node
+ //
+ VariablePackItem->VariablePack = (EFI_HII_VARIABLE_PACK *) (VariablePackItem + 1);
+ VariablePack = VariablePackItem->VariablePack;
+
+ //
+ // Copy the var name to VariablePackItem from VarStore
+ // Needs ASCII->Unicode conversion.
+ //
+ ASSERT (VarStore->Header.Length > sizeof (*VarStore));
+ Name8 = (CHAR8 *) (VarStore + 1);
+ Name16 = (CHAR16 *) (VariablePack + 1);
+ Ascii2Unicode (Name16, Name8);
+
+ //
+ // Compute the other fields of the VariablePackItem
+ //
+ VariablePack->VariableId = VarStore->VarId;
+ CopyMem (&VariablePack->VariableGuid, &VarStore->Guid, sizeof (EFI_GUID));
+ VariablePack->VariableNameLength = (UINT32) ((StrLen (Name16) + 1) * 2);
+ VariablePack->Header.Length = sizeof (*VariablePack)
+ + VariablePack->VariableNameLength
+ + VarStore->Size;
+ //
+ // Return the pointer to the Map space.
+ //
+ Map = (CHAR8 *) Name16 + VariablePack->VariableNameLength;
+
+ return (UINT8 *)Map;
+}
+
+STATIC
+VOID
+HiiGetDefaultImagePopulateMap (
+ IN OUT UINT8 *Map,
+ IN EFI_IFR_OP_HEADER *FormSet,
+ IN EFI_IFR_VARSTORE *VarStore,
+ IN UINTN DefaultMask
+ )
+/*++
+
+ Routine Description:
+
+ Fill the Map with all the default values either from NV or Hii database.
+
+ Arguments:
+
+ Map - Memory pointer to hold the default values.
+ FormSet - The starting EFI_IFR_OP_HEADER to begin retriving default values.
+ VarStore - IFR variable storage.
+ DefaultMask - The mask used to get the default variable.
+
+ Returns:
+
+ VOID
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_IFR_OP_HEADER *IfrItem;
+ UINT16 VarId;
+ EFI_IFR_VARSTORE_SELECT *VarSelect;
+ EFI_IFR_ONE_OF_OPTION *OneOfOpt;
+ EFI_IFR_CHECKBOX *CheckBox;
+ EFI_IFR_NUMERIC *Numeric;
+ UINTN Size;
+ UINTN SizeTmp;
+ EFI_IFR_NV_DATA *IfrNvData;
+ EFI_GUID Guid;
+ CHAR16 *Name16;
+ CHAR8 *Name8;
+ EFI_HANDLE CallbackHandle;
+ EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProt;
+
+ //
+ // Get the Map's Name/Guid/Szie from the Varstore.
+ // VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.
+ //
+ ASSERT (VarStore->Header.Length >= sizeof (*VarStore));
+ Name8 = (CHAR8 *) (VarStore + 1);
+ Name16 = AllocateZeroPool ((VarStore->Header.Length - sizeof (*VarStore)) * sizeof (CHAR16));
+ Ascii2Unicode (Name16, Name8);
+ CopyMem (&Guid, &VarStore->Guid, sizeof(EFI_GUID));
+ Size = VarStore->Size;
+
+ //
+ // First, check if the map exists in the NV. If so, get it from NV and exit.
+ //
+ if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {
+ //
+ // Check if Manufaturing Defaults exist in the NV.
+ //
+ Status = EfiLibHiiVariableOverrideBySuffix (
+ HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE,
+ Name16,
+ &Guid,
+ Size,
+ Map
+ );
+ } else {
+ //
+ // All other cases default to Defaults. Check if Defaults exist in the NV.
+ //
+ Status = EfiLibHiiVariableOverrideBySuffix (
+ HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE,
+ Name16,
+ &Guid,
+ Size,
+ Map
+ );
+ }
+ if (!EFI_ERROR (Status)) {
+ //
+ // Either Defaults/Manufacturing variable exists and appears to be valid.
+ // The map is read, exit w/ success now.
+ //
+ gBS->FreePool (Name16);
+ return;
+ }
+
+ //
+ // First, prime the map with what already is in the NV.
+ // This is needed to cover a situation where the IFR does not contain all the
+ // defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.
+ // Ignore status. Either it gets read or not.
+ //
+ FormCallbackProt = NULL;
+ CopyMem (&CallbackHandle, &((EFI_IFR_FORM_SET*) FormSet)->CallbackHandle, sizeof (CallbackHandle));
+ if (CallbackHandle != NULL) {
+ Status = gBS->HandleProtocol (
+ (EFI_HANDLE) (UINTN) CallbackHandle,
+ &gEfiFormCallbackProtocolGuid,
+ (VOID *) &FormCallbackProt
+ );
+ }
+ if ((NULL != FormCallbackProt) && (NULL != FormCallbackProt->NvRead)) {
+ //
+ // Attempt to read using NvRead() callback. Probe first for existence and correct variable size.
+ //
+ SizeTmp = 0;
+ Status = FormCallbackProt->NvRead (
+ FormCallbackProt,
+ Name16,
+ &Guid,
+ 0,
+ &SizeTmp,
+ NULL
+ );
+ if ((EFI_BUFFER_TOO_SMALL == Status) && (SizeTmp == Size)) {
+ Status = FormCallbackProt->NvRead (
+ FormCallbackProt,
+ Name16,
+ &Guid,
+ 0,
+ &SizeTmp,
+ Map
+ );
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (SizeTmp == Size);
+ }
+ } else {
+ //
+ // No callback available for this formset, read straight from NV. Deliberately ignore the Status.
+ // The buffer will only be written if variable exists nd has correct size.
+ //
+ Status = EfiLibHiiVariableRetrieveFromNv (
+ Name16,
+ &Guid,
+ Size,
+ (VOID **) &Map
+ );
+ }
+
+ //
+ // Iterate all IFR statements and for applicable, retrieve the default into the Map.
+ //
+ for (IfrItem = FormSet, VarId = 0;
+ IfrItem->OpCode != EFI_IFR_END_FORM_SET_OP;
+ IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8*) IfrItem + IfrItem->Length)
+ ) {
+
+ //
+ // Observe VarStore switch.
+ //
+ if (EFI_IFR_VARSTORE_SELECT_OP == IfrItem->OpCode) {
+ VarSelect = (EFI_IFR_VARSTORE_SELECT *) IfrItem;
+ VarId = VarSelect->VarId;
+ continue;
+ }
+
+
+ //
+ // Skip opcodes that reference other VarStore than that specific to current map.
+ //
+ if (VarId != VarStore->VarId) {
+ continue;
+ }
+
+ //
+ // Extract the default value from this opcode if applicable, and apply it to the map.
+ //
+ IfrNvData = (EFI_IFR_NV_DATA *) IfrItem;
+ switch (IfrItem->OpCode) {
+
+ case EFI_IFR_ONE_OF_OP:
+ ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);
+ //
+ // Get to the first EFI_IFR_ONE_OF_OPTION_OP
+ //
+ IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8*) IfrItem + IfrItem->Length);
+ ASSERT (EFI_IFR_ONE_OF_OPTION_OP == IfrItem->OpCode);
+
+ OneOfOpt = (EFI_IFR_ONE_OF_OPTION *)IfrItem;
+ //
+ // In the worst case, the first will be the default.
+ //
+ CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);
+
+ while (EFI_IFR_ONE_OF_OPTION_OP == IfrItem->OpCode) {
+
+ OneOfOpt = (EFI_IFR_ONE_OF_OPTION *)IfrItem;
+ if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {
+ if (0 != (OneOfOpt->Flags & EFI_IFR_FLAG_MANUFACTURING)) {
+ //
+ // In the worst case, the first will be the default.
+ //
+ CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);
+ break;
+ }
+ } else {
+ if (OneOfOpt->Flags & EFI_IFR_FLAG_DEFAULT) {
+ //
+ // In the worst case, the first will be the default.
+ //
+ CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);
+ break;
+ }
+ }
+
+ IfrItem = (EFI_IFR_OP_HEADER *)((UINT8*)IfrItem + IfrItem->Length);
+ }
+ continue;
+ break;
+
+ case EFI_IFR_CHECKBOX_OP:
+ ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);
+ CheckBox = (EFI_IFR_CHECK_BOX *)IfrItem;
+ if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {
+ if (0 != (CheckBox->Flags & EFI_IFR_FLAG_MANUFACTURING)) {
+ *(UINT8 *) (Map + IfrNvData->QuestionId) = TRUE;
+ }
+ } else {
+ if (CheckBox->Flags & EFI_IFR_FLAG_DEFAULT) {
+ *(UINT8 *) (Map + IfrNvData->QuestionId) = TRUE;
+ }
+ }
+ break;
+
+ case EFI_IFR_NUMERIC_OP:
+ ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);
+ Numeric = (EFI_IFR_NUMERIC *) IfrItem;
+ CopyMem (Map + IfrNvData->QuestionId, &Numeric->Default, IfrNvData->StorageWidth);
+ break;
+
+ case EFI_IFR_ORDERED_LIST_OP:
+ case EFI_IFR_PASSWORD_OP:
+ case EFI_IFR_STRING_OP:
+ //
+ // No support for default value for these opcodes.
+ //
+ break;
+ }
+ }
+
+ gBS->FreePool (Name16);
+
+}
+
+
+EFI_STATUS
+EFIAPI
+HiiGetDefaultImage (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN UINTN DefaultMask,
+ OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
+ )
+/*++
+
+ Routine Description:
+
+ This function allows a program to extract the NV Image
+ that represents the default storage image
+
+ Arguments:
+ This - A pointer to the EFI_HII_PROTOCOL instance.
+ Handle - The HII handle from which will have default data retrieved.
+ UINTN - Mask used to retrieve the default image.
+ VariablePackList - Callee allocated, tightly-packed, link list data
+ structure that contain all default varaible packs
+ from the Hii Database.
+
+ Returns:
+ EFI_NOT_FOUND - If Hii database does not contain any default images.
+ EFI_INVALID_PARAMETER - Invalid input parameter.
+ EFI_SUCCESS - Operation successful.
+
+--*/
+{
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_IFR_OP_HEADER *FormSet;
+ EFI_IFR_OP_HEADER *IfrItem;
+ EFI_IFR_VARSTORE *VarStore;
+ EFI_IFR_VARSTORE *VarStoreDefault;
+ UINTN SetupMapNameSize;
+ UINTN SizeOfMaps;
+ EFI_HII_VARIABLE_PACK_LIST *PackList;
+ EFI_HII_VARIABLE_PACK_LIST *PackListNext;
+ EFI_HII_VARIABLE_PACK_LIST *PackListLast;
+ UINT8 *Map;
+
+
+ //
+ // Find the IFR pack from the handle. Then get the formset from the pack.
+ //
+ PackageInstance = NULL;
+ HandleDatabase = (EFI_HII_DATA_FROM_THIS (This))->DatabaseHead;
+ for ( ; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ break;
+ }
+ }
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ FormSet = (EFI_IFR_OP_HEADER *) ((UINT8 *) &PackageInstance->IfrData + sizeof (EFI_HII_IFR_PACK));
+
+ //
+ // Get the sizes of all the VARSTOREs in this VFR.
+ // Then allocate enough space for all of them plus all maps
+ //
+ SizeOfMaps = 0;
+ IfrItem = FormSet;
+ while (EFI_IFR_END_FORM_SET_OP != IfrItem->OpCode) {
+
+ if (EFI_IFR_VARSTORE_OP == IfrItem->OpCode) {
+ VarStore = (EFI_IFR_VARSTORE *) IfrItem;
+ //
+ // Size of the map
+ //
+ SizeOfMaps += VarStore->Size;
+ //
+ // add the size of the string, in Unicode
+ //
+ SizeOfMaps += (VarStore->Header.Length - sizeof (*VarStore)) * 2;
+ //
+ // Space for node
+ //
+ SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK);
+ //
+ // Space for linked list node
+ //
+ SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK_LIST);
+ }
+
+ IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrItem + IfrItem->Length);
+ }
+
+ //
+ // If the FormSet OpCode has a non-zero NvDataSize. There is a default
+ // NvMap with ID=0, GUID that of the formset itself and "Setup" as name.
+ //
+ SetupMapNameSize = StrLen (SETUP_MAP_NAME) + 1;
+ VarStoreDefault = AllocateZeroPool (sizeof (*VarStoreDefault) + SetupMapNameSize);
+
+ if (0 != ((EFI_IFR_FORM_SET*)FormSet)->NvDataSize) {
+
+ VarStoreDefault->Header.OpCode = EFI_IFR_VARSTORE_OP;
+ VarStoreDefault->Header.Length = (UINT8) (sizeof (*VarStoreDefault) + SetupMapNameSize);
+ Unicode2Ascii ((CHAR8 *) (VarStoreDefault + 1), SETUP_MAP_NAME);
+ CopyMem (&VarStoreDefault->Guid, &((EFI_IFR_FORM_SET*) FormSet)->Guid, sizeof (EFI_GUID));
+ VarStoreDefault->VarId = 0;
+ VarStoreDefault->Size = ((EFI_IFR_FORM_SET*) FormSet)->NvDataSize;
+
+ //
+ // Size of the map
+ //
+ SizeOfMaps += VarStoreDefault->Size;
+ //
+ // add the size of the string
+ //
+ SizeOfMaps += sizeof (SETUP_MAP_NAME);
+ //
+ // Space for node
+ //
+ SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK);
+ //
+ // Space for linked list node
+ //
+ SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK_LIST);
+ }
+
+ if (0 == SizeOfMaps) {
+ //
+ // The IFR does not have any explicit or default map(s).
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Allocate the return buffer
+ //
+ PackList = AllocateZeroPool (SizeOfMaps);
+ ASSERT (NULL != PackList);
+
+ PackListNext = PackList;
+ PackListLast = PackList;
+
+ //
+ // Handle the default map first, if any.
+ //
+ if (0 != VarStoreDefault->Size) {
+
+ Map = HiiGetDefaultImageInitPack (PackListNext, VarStoreDefault);
+
+ HiiGetDefaultImagePopulateMap (Map, FormSet, VarStoreDefault, DefaultMask);
+
+ PackListNext->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *) ((UINT8 *) PackListNext->VariablePack + PackListNext->VariablePack->Header.Length);
+ PackListLast = PackListNext;
+ PackListNext = PackListNext->NextVariablePack;
+ }
+
+
+ //
+ // Handle the explicit varstore(s)
+ //
+ IfrItem = FormSet;
+ while (EFI_IFR_END_FORM_SET_OP != IfrItem->OpCode) {
+
+ if (EFI_IFR_VARSTORE_OP == IfrItem->OpCode) {
+
+ Map = HiiGetDefaultImageInitPack (PackListNext, (EFI_IFR_VARSTORE *) IfrItem);
+
+ HiiGetDefaultImagePopulateMap (Map, FormSet, (EFI_IFR_VARSTORE *) IfrItem, DefaultMask);
+
+ PackListNext->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *) ((UINT8 *) PackListNext->VariablePack + PackListNext->VariablePack->Header.Length);
+ PackListLast = PackListNext;
+ PackListNext = PackListNext->NextVariablePack;
+ }
+
+ IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrItem + IfrItem->Length);
+ }
+
+ PackListLast->NextVariablePack = NULL;
+ *VariablePackList = PackList;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+HiiUpdateForm (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_LABEL Label,
+ IN BOOLEAN AddData,
+ IN EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ This function allows the caller to update a form that has
+ previously been registered with the EFI HII database.
+
+Arguments:
+ Handle - Hii Handle associated with the Formset to modify
+ Label - Update information starting immediately after this label in the IFR
+ AddData - If TRUE, add data. If FALSE, remove data
+ Data - If adding data, this is the pointer to the data to add
+
+Returns:
+ EFI_SUCCESS - Update success.
+ Other - Update fail.
+
+--*/
+{
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_IFR_PACK *FormPack;
+ EFI_IFR_OP_HEADER *Location;
+ EFI_IFR_OP_HEADER *DataLocation;
+ UINT8 *OtherBuffer;
+ UINT8 *TempBuffer;
+ UINT8 *OrigTempBuffer;
+ UINTN TempBufferSize;
+ UINTN Index;
+
+ OtherBuffer = NULL;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ HandleDatabase = HiiData->DatabaseHead;
+
+ PackageInstance = NULL;
+
+ //
+ // Check numeric value against the head of the database
+ //
+ for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ //
+ // Match the numeric value with the database entry - if matched, extract PackageInstance
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ break;
+ }
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Calculate and allocate space for retrieval of IFR data
+ //
+ DataLocation = (EFI_IFR_OP_HEADER *) &Data->Data;
+ TempBufferSize = (CHAR8 *) (&PackageInstance->IfrData) - (CHAR8 *) (PackageInstance);
+
+ for (Index = 0; Index < Data->DataCount; Index++) {
+ TempBufferSize += DataLocation->Length;
+ DataLocation = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (DataLocation) + DataLocation->Length);
+ }
+
+ TempBufferSize += PackageInstance->IfrSize + PackageInstance->StringSize;
+
+ TempBuffer = AllocateZeroPool (TempBufferSize);
+ OrigTempBuffer = TempBuffer;
+
+ //
+ // We update only packages with IFR information in it
+ //
+ if (PackageInstance->IfrSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem (
+ TempBuffer,
+ PackageInstance,
+ ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER) - (CHAR8 *) (PackageInstance))
+ );
+
+ TempBuffer = TempBuffer + ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER) - (CHAR8 *) (PackageInstance));
+
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
+ Location = (EFI_IFR_OP_HEADER *) FormPack;
+
+ //
+ // Look for the FormId requested
+ //
+ for (; Location->OpCode != EFI_IFR_END_FORM_SET_OP;) {
+ switch (Location->OpCode) {
+ case EFI_IFR_FORM_SET_OP:
+ //
+ // If the FormSet has an update pending, pay attention.
+ //
+ if (Data->FormSetUpdate) {
+ ((EFI_IFR_FORM_SET *) Location)->CallbackHandle = Data->FormCallbackHandle;
+ }
+
+ CopyMem (TempBuffer, Location, Location->Length);
+ TempBuffer = TempBuffer + Location->Length;
+ break;
+
+ case EFI_IFR_FORM_OP:
+ //
+ // If the Form has an update pending, pay attention.
+ //
+ if (Data->FormUpdate) {
+ ((EFI_IFR_FORM *) Location)->FormTitle = Data->FormTitle;
+ }
+
+ CopyMem (TempBuffer, Location, Location->Length);
+ TempBuffer = TempBuffer + Location->Length;
+ break;
+
+ case EFI_IFR_LABEL_OP:
+ //
+ // If the label does not match the requested update point, ignore it
+ //
+ if (((EFI_IFR_LABEL *) Location)->LabelId != Label) {
+ //
+ // Copy the label
+ //
+ CopyMem (TempBuffer, Location, Location->Length);
+ TempBuffer = TempBuffer + Location->Length;
+
+ //
+ // Go to the next Op-Code
+ //
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+ continue;
+ }
+
+ if (AddData) {
+ //
+ // Copy the label
+ //
+ CopyMem (TempBuffer, Location, Location->Length);
+ TempBuffer = TempBuffer + Location->Length;
+
+ //
+ // Add the DataCount amount of opcodes to TempBuffer
+ //
+ DataLocation = (EFI_IFR_OP_HEADER *) &Data->Data;
+ for (Index = 0; Index < Data->DataCount; Index++) {
+ CopyMem (TempBuffer, DataLocation, DataLocation->Length);
+ ((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize += DataLocation->Length;
+ OtherBuffer = ((UINT8 *) &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->StringSize + sizeof (UINTN));
+ CopyMem (OtherBuffer, &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize, 2);
+ TempBuffer = TempBuffer + DataLocation->Length;
+ DataLocation = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (DataLocation) + DataLocation->Length);
+ }
+ //
+ // Go to the next Op-Code
+ //
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+ continue;
+ } else {
+ //
+ // Copy the label
+ //
+ CopyMem (TempBuffer, Location, Location->Length);
+ TempBuffer = TempBuffer + Location->Length;
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+
+ //
+ // Remove the DataCount amount of opcodes unless we run into an end of form or a label
+ //
+ for (Index = 0; Index < Data->DataCount; Index++) {
+ //
+ // If we are about to skip an end form - bail out, since that is illegal
+ //
+ if ((Location->OpCode == EFI_IFR_END_FORM_OP) || (Location->OpCode == EFI_IFR_LABEL_OP)) {
+ break;
+ }
+ //
+ // By skipping Location entries, we are in effect not copying what was previously there
+ //
+ ((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize -= Location->Length;
+ OtherBuffer = ((UINT8 *) &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->StringSize + sizeof (UINTN));
+ CopyMem (OtherBuffer, &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize, 2);
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+ }
+ }
+
+ default:
+ CopyMem (TempBuffer, Location, Location->Length);
+ TempBuffer = TempBuffer + Location->Length;
+ break;
+ }
+ //
+ // Go to the next Op-Code
+ //
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+ }
+ //
+ // Copy the last op-code left behind from the for loop
+ //
+ CopyMem (TempBuffer, Location, Location->Length);
+
+ //
+ // Advance to beginning of strings and copy them
+ //
+ TempBuffer = TempBuffer + Location->Length;
+ Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);
+ CopyMem (TempBuffer, Location, PackageInstance->StringSize);
+
+ //
+ // Free the old buffer, and assign into our database the latest buffer
+ //
+ gBS->FreePool (HandleDatabase->Buffer);
+ HandleDatabase->Buffer = OrigTempBuffer;
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.c b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.c
new file mode 100644
index 0000000000..ce34eff5bd
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.c
@@ -0,0 +1,413 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ HiiDatabase.c
+
+Abstract:
+
+ This file contains the entry code to the HII database.
+
+--*/
+
+#include "HiiDatabase.h"
+
+EFI_STATUS
+EFIAPI
+InitializeHiiDatabase (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ Initialize HII Database
+
+Arguments:
+ (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+Returns:
+ EFI_SUCCESS - Setup loaded.
+ other - Setup Error
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_GLOBAL_DATA *GlobalData;
+ EFI_HANDLE *HandleBuffer;
+ EFI_HANDLE Handle;
+ UINTN HandleCount;
+ UINTN Index;
+
+ //
+ // There will be only one HII Database in the system
+ // If there is another out there, someone is trying to install us
+ // again. Fail that scenario.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiHiiProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+
+ //
+ // If there was no error, assume there is an installation and fail to load
+ //
+ if (!EFI_ERROR (Status)) {
+ if (HandleBuffer != NULL) {
+ gBS->FreePool (HandleBuffer);
+ }
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ HiiData = AllocatePool (sizeof (EFI_HII_DATA));
+
+ ASSERT (HiiData);
+
+ GlobalData = AllocateZeroPool (sizeof (EFI_HII_GLOBAL_DATA));
+
+ ASSERT (GlobalData);
+
+ //
+ // Seed the Font Database with a known non-character glyph
+ //
+ for (Index = 0; Index <= MAX_GLYPH_COUNT; Index++) {
+ //
+ // Seeding the UnicodeWeight with 0 signifies that it is uninitialized
+ //
+ GlobalData->NarrowGlyphs[Index].UnicodeWeight = 0;
+ GlobalData->WideGlyphs[Index].UnicodeWeight = 0;
+ GlobalData->NarrowGlyphs[Index].Attributes = 0;
+ GlobalData->WideGlyphs[Index].Attributes = 0;
+ CopyMem (GlobalData->NarrowGlyphs[Index].GlyphCol1, &mUnknownGlyph, NARROW_GLYPH_ARRAY_SIZE);
+ CopyMem (GlobalData->WideGlyphs[Index].GlyphCol1, &mUnknownGlyph, WIDE_GLYPH_ARRAY_SIZE);
+ }
+ //
+ // Fill in HII data
+ //
+ HiiData->Signature = EFI_HII_DATA_SIGNATURE;
+ HiiData->GlobalData = GlobalData;
+ HiiData->GlobalData->SystemKeyboardUpdate = FALSE;
+ HiiData->DatabaseHead = NULL;
+ HiiData->Hii.NewPack = HiiNewPack;
+ HiiData->Hii.RemovePack = HiiRemovePack;
+ HiiData->Hii.FindHandles = HiiFindHandles;
+ HiiData->Hii.ExportDatabase = HiiExportDatabase;
+ HiiData->Hii.GetGlyph = HiiGetGlyph;
+ HiiData->Hii.GetPrimaryLanguages = HiiGetPrimaryLanguages;
+ HiiData->Hii.GetSecondaryLanguages = HiiGetSecondaryLanguages;
+ HiiData->Hii.NewString = HiiNewString;
+ HiiData->Hii.GetString = HiiGetString;
+ HiiData->Hii.ResetStrings = HiiResetStrings;
+ HiiData->Hii.TestString = HiiTestString;
+ HiiData->Hii.GetLine = HiiGetLine;
+ HiiData->Hii.GetForms = HiiGetForms;
+ HiiData->Hii.GetDefaultImage = HiiGetDefaultImage;
+ HiiData->Hii.UpdateForm = HiiUpdateForm;
+ HiiData->Hii.GetKeyboardLayout = HiiGetKeyboardLayout;
+ HiiData->Hii.GlyphToBlt = HiiGlyphToBlt;
+
+ //
+ // Install protocol interface
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiHiiProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &HiiData->Hii
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+HiiFindHandles (
+ IN EFI_HII_PROTOCOL *This,
+ IN OUT UINT16 *HandleBufferLength,
+ OUT EFI_HII_HANDLE Handle[1]
+ )
+/*++
+
+Routine Description:
+ Determines the handles that are currently active in the database.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_HII_GLOBAL_DATA *GlobalData;
+ EFI_HII_HANDLE_DATABASE *Database;
+ EFI_HII_DATA *HiiData;
+ UINTN HandleCount;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ GlobalData = HiiData->GlobalData;
+
+ Database = HiiData->DatabaseHead;
+
+ if (Database == NULL) {
+ *HandleBufferLength = 0;
+ return EFI_NOT_FOUND;
+ }
+
+ for (HandleCount = 0; Database != NULL; HandleCount++) {
+ Database = Database->NextHandleDatabase;
+ }
+ //
+ // Is there a sufficient buffer for the data being passed back?
+ //
+ if (*HandleBufferLength >= (sizeof (EFI_HII_HANDLE) * HandleCount)) {
+ Database = HiiData->DatabaseHead;
+
+ //
+ // Copy the Head information
+ //
+ if (Database->Handle != 0) {
+ CopyMem (&Handle[0], &Database->Handle, sizeof (EFI_HII_HANDLE));
+ Database = Database->NextHandleDatabase;
+ }
+ //
+ // Copy more data if appropriate
+ //
+ for (HandleCount = 1; Database != NULL; HandleCount++) {
+ CopyMem (&Handle[HandleCount], &Database->Handle, sizeof (EFI_HII_HANDLE));
+ Database = Database->NextHandleDatabase;
+ }
+
+ *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Insufficient buffer length
+ //
+ *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+HiiGetPrimaryLanguages (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ OUT EFI_STRING *LanguageString
+ )
+/*++
+
+Routine Description:
+
+ This function allows a program to determine what the primary languages that are supported on a given handle.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN Count;
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_STRING_PACK *StringPack;
+ EFI_HII_STRING_PACK *Location;
+ UINT32 Length;
+ RELOFST Token;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ PackageInstance = NULL;
+ //
+ // Find matching handle in the handle database. Then get the package instance.
+ //
+ for (HandleDatabase = HiiData->DatabaseHead;
+ HandleDatabase != NULL;
+ HandleDatabase = HandleDatabase->NextHandleDatabase
+ ) {
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ }
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);
+
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ if (StringPackageInstance->IfrSize > 0) {
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);
+ } else {
+ StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);
+ }
+
+ Location = StringPack;
+ //
+ // Remember that the string packages are formed into contiguous blocks of language data.
+ //
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ for (Count = 0; Length != 0; Count = Count + 3) {
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ }
+
+ *LanguageString = AllocateZeroPool (2 * (Count + 1));
+
+ ASSERT (*LanguageString);
+
+ StringPack = (EFI_HII_STRING_PACK *) Location;
+
+ //
+ // Copy the 6 bytes to LanguageString - keep concatenating it. Shouldn't we just store uint8's since the ISO
+ // standard defines the lettering as all US English characters anyway? Save a few bytes.
+ //
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ for (Count = 0; Length != 0; Count = Count + 3) {
+ CopyMem (&Token, &StringPack->LanguageNameString, sizeof (RELOFST));
+ CopyMem (*LanguageString + Count, (VOID *) ((CHAR8 *) (StringPack) + Token), 6);
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiiGetSecondaryLanguages (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CHAR16 *PrimaryLanguage,
+ OUT EFI_STRING *LanguageString
+ )
+/*++
+
+Routine Description:
+
+ This function allows a program to determine which secondary languages are supported
+ on a given handle for a given primary language.
+
+ Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN Count;
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_STRING_PACK *StringPack;
+ EFI_HII_STRING_PACK *Location;
+ RELOFST Token;
+ UINT32 Length;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+ //
+ // Check numeric value against the head of the database
+ //
+ PackageInstance = NULL;
+ for (HandleDatabase = HiiData->DatabaseHead;
+ HandleDatabase != NULL;
+ HandleDatabase = HandleDatabase->NextHandleDatabase
+ ) {
+ //
+ // Match the numeric value with the database entry - if matched, extract PackageInstance
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ }
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);
+
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ if (StringPackageInstance->IfrSize > 0) {
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);
+ } else {
+ StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);
+ }
+
+ Location = StringPack;
+
+ //
+ // Remember that the string packages are formed into contiguous blocks of language data.
+ //
+ for (; StringPack->Header.Length != 0;) {
+ //
+ // Find the PrimaryLanguage being requested
+ //
+ Token = StringPack->LanguageNameString;
+ if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + Token), PrimaryLanguage, 3) == 0) {
+ //
+ // Now that we found the primary, the secondary languages will follow immediately
+ // or the next character is a NULL if there are no secondary languages. We determine
+ // the number by getting the stringsize based on the StringPack origination + the LanguageNameString
+ // offset + 6 (which is the size of the first 3 letter ISO primary language name). If we get 2, there
+ // are no secondary languages (2 = null-terminator).
+ //
+ Count = StrSize ((VOID *) ((CHAR8 *) (StringPack) + Token + 6));
+
+ *LanguageString = AllocateZeroPool (2 * (Count + 1));
+
+ ASSERT (*LanguageString);
+
+ CopyMem (*LanguageString, (VOID *) ((CHAR8 *) (StringPack) + Token + 6), Count);
+ break;
+ }
+
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.dxs b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.dxs
new file mode 100644
index 0000000000..86c8ac4ce2
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.dxs
@@ -0,0 +1,26 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ HiiDatabase.dxs
+
+Abstract:
+
+ Dependency expression source file.
+
+--*/
+#include <AutoGen.h>
+#include <DxeDepex.h>
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END \ No newline at end of file
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.h b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.h
new file mode 100644
index 0000000000..c50cd958a0
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.h
@@ -0,0 +1,302 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ HiiDatabase.h
+
+Abstract:
+
+ This file contains global defines and prototype definitions
+ for the HII database.
+
+--*/
+
+#ifndef _HIIDATABASE_H
+#define _HIIDATABASE_H
+
+//
+// HII Database Global data
+//
+#define EFI_HII_DATA_SIGNATURE EFI_SIGNATURE_32 ('H', 'i', 'i', 'P')
+
+#define MAX_GLYPH_COUNT 65535
+#define NARROW_GLYPH_ARRAY_SIZE 19
+#define WIDE_GLYPH_ARRAY_SIZE 38
+
+#define SETUP_MAP_NAME L"Setup"
+#define HII_VARIABLE_SUFFIX_USER_DATA L"UserSavedData"
+#define HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE L"DefaultOverride"
+#define HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE L"ManufacturingOverride"
+
+typedef struct _EFI_HII_HANDLE_DATABASE {
+ VOID *Buffer; // Actual buffer pointer
+ EFI_HII_HANDLE Handle; // Monotonically increasing value to signify the value returned to caller
+ UINT32 NumberOfTokens; // The initial number of tokens when first registered
+ struct _EFI_HII_HANDLE_DATABASE *NextHandleDatabase;
+} EFI_HII_HANDLE_DATABASE;
+
+typedef struct {
+ EFI_NARROW_GLYPH NarrowGlyphs[MAX_GLYPH_COUNT];
+ EFI_WIDE_GLYPH WideGlyphs[MAX_GLYPH_COUNT];
+ EFI_KEY_DESCRIPTOR SystemKeyboardLayout[106];
+ EFI_KEY_DESCRIPTOR OverrideKeyboardLayout[106];
+ BOOLEAN SystemKeyboardUpdate; // Has the SystemKeyboard been updated?
+} EFI_HII_GLOBAL_DATA;
+
+typedef struct {
+ UINTN Signature;
+
+ EFI_HII_GLOBAL_DATA *GlobalData;
+ EFI_HII_HANDLE_DATABASE *DatabaseHead; // Head of the Null-terminated singly-linked list of handles.
+ EFI_HII_PROTOCOL Hii;
+} EFI_HII_DATA;
+
+typedef struct {
+ EFI_HII_HANDLE Handle;
+ EFI_GUID Guid;
+ EFI_HII_HANDLE_PACK HandlePack;
+ UINTN IfrSize;
+ UINTN StringSize;
+ EFI_HII_IFR_PACK *IfrData; // All the IFR data stored here
+ EFI_HII_STRING_PACK *StringData; // All the String data stored at &IfrData + IfrSize (StringData is just a label - never referenced)
+} EFI_HII_PACKAGE_INSTANCE;
+
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+ EFI_IFR_FORM_SET FormSet;
+ EFI_IFR_END_FORM_SET EndFormSet;
+} EFI_FORM_SET_STUB;
+
+#define EFI_HII_DATA_FROM_THIS(a) CR (a, EFI_HII_DATA, Hii, EFI_HII_DATA_SIGNATURE)
+
+#define NARROW_WIDTH 8
+#define WIDE_WIDTH 16
+
+extern UINT8 mUnknownGlyph[38];
+
+//
+// Prototypes
+//
+EFI_STATUS
+GetPackSize (
+ IN VOID *Pack,
+ OUT UINTN *PackSize,
+ OUT UINT32 *NumberOfTokens
+ )
+;
+
+EFI_STATUS
+ValidatePack (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_PACKAGE_INSTANCE *PackageInstance,
+ OUT EFI_HII_PACKAGE_INSTANCE **StringPackageInstance,
+ OUT UINT32 *TotalStringCount
+ )
+;
+
+//
+// Public Interface Prototypes
+//
+EFI_STATUS
+EFIAPI
+InitializeHiiDatabase (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiNewPack (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_PACKAGES *PackageList,
+ OUT EFI_HII_HANDLE *Handle
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiRemovePack (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiFindHandles (
+ IN EFI_HII_PROTOCOL *This,
+ IN OUT UINT16 *HandleBufferLength,
+ OUT EFI_HII_HANDLE *Handle
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiExportDatabase (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetGlyph (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Source,
+ IN OUT UINT16 *Index,
+ OUT UINT8 **GlyphBuffer,
+ OUT UINT16 *BitWidth,
+ IN OUT UINT32 *InternalStatus
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGlyphToBlt (
+ IN EFI_HII_PROTOCOL *This,
+ IN UINT8 *GlyphBuffer,
+ IN EFI_UGA_PIXEL Foreground,
+ IN EFI_UGA_PIXEL Background,
+ IN UINTN Count,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN OUT EFI_UGA_PIXEL *BltBuffer
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiNewString (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Language,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT STRING_REF *Reference,
+ IN CHAR16 *NewString
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetString (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN BOOLEAN Raw,
+ IN CHAR16 *LanguageString,
+ IN OUT UINTN *BufferLength,
+ OUT EFI_STRING StringBuffer
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiResetStrings (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiTestString (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *StringToTest,
+ IN OUT UINT32 *FirstMissing,
+ OUT UINT32 *GlyphBufferSize
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetPrimaryLanguages (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ OUT EFI_STRING *LanguageString
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetSecondaryLanguages (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CHAR16 *PrimaryLanguage,
+ OUT EFI_STRING *LanguageString
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetLine (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN OUT UINT16 *Index,
+ IN UINT16 LineWidth,
+ IN CHAR16 *LanguageString,
+ IN OUT UINT16 *BufferLength,
+ OUT EFI_STRING StringBuffer
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetForms (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_ID FormId,
+ IN OUT UINTN *BufferLength,
+ OUT UINT8 *Buffer
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetDefaultImage (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN UINTN DefaultMask,
+ OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiUpdateForm (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_LABEL Label,
+ IN BOOLEAN AddData,
+ IN EFI_HII_UPDATE_DATA *Data
+ )
+;
+
+EFI_STATUS
+EFIAPI
+HiiGetKeyboardLayout (
+ IN EFI_HII_PROTOCOL *This,
+ OUT UINT16 *DescriptorCount,
+ OUT EFI_KEY_DESCRIPTOR *Descriptor
+ )
+;
+
+EFI_STATUS
+HiiCompareLanguage (
+ IN CHAR16 *LanguageStringLocation,
+ IN CHAR16 *Language
+ )
+;
+
+#endif
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.mbd b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.mbd
new file mode 100644
index 0000000000..03f2ed9463
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>HiiDatabase</BaseName>
+ <Guid>FCD337AB-B1D3-4EF8-957C-8048606FF670</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:19</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>UefiRuntimeServicesTableLib</Library>
+ <Library>BaseLib</Library>
+ <Library>BaseMemoryLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Library>EdkIfrSupportLib</Library>
+ </Libraries>
+ <BuildOptions ToolChain="MSFT">
+ <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+ </BuildOptions>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa
new file mode 100644
index 0000000000..3eb5332c81
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>HiiDatabase</BaseName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <ComponentType>BS_DRIVER</ComponentType>
+ <Guid>FCD337AB-B1D3-4EF8-957C-8048606FF670</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for DiskIo module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:19</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">EdkIfrSupportLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>HiiDatabase.c</Filename>
+ <Filename>HiiDatabase.h</Filename>
+ <Filename>Forms.c</Filename>
+ <Filename>Strings.c</Filename>
+ <Filename>Package.c</Filename>
+ <Filename>Fonts.c</Filename>
+ <Filename>Keyboard.c</Filename>
+ <Filename>HiiDatabase.dxs</Filename>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">Hii</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">FormCallback</Protocol>
+ </Protocols>
+ <Variables>
+ <Variable Usage="ALWAYS_CONSUMED">
+ <String>L"Lang"</String>
+ <Guid Usage="ALWAYS_CONSUMED">
+ 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }
+ </Guid>
+ </Variable>
+ </Variables>
+ <Guids>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>GlobalVariable</C_Name>
+ </GuidEntry>
+ </Guids>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>InitializeHiiDatabase</ModuleEntryPoint>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Keyboard.c b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Keyboard.c
new file mode 100644
index 0000000000..8e9417fc83
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Keyboard.c
@@ -0,0 +1,43 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Keyboard.c
+
+Abstract:
+
+ This file contains the keyboard processing code to the HII database.
+
+--*/
+
+
+#include "HiiDatabase.h"
+
+EFI_STATUS
+EFIAPI
+HiiGetKeyboardLayout (
+ IN EFI_HII_PROTOCOL *This,
+ OUT UINT16 *DescriptorCount,
+ OUT EFI_KEY_DESCRIPTOR *Descriptor
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c
new file mode 100644
index 0000000000..3e9e5364e9
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c
@@ -0,0 +1,677 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Package.c
+
+Abstract:
+
+ This file contains the package processing code to the HII database.
+
+--*/
+
+
+#include "HiiDatabase.h"
+
+EFI_STATUS
+GetPackSize (
+ IN VOID *Pack,
+ OUT UINTN *PackSize,
+ OUT UINT32 *NumberOfTokens
+ )
+/*++
+
+Routine Description:
+ Determines the passed in Pack's size and returns the value.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_HII_STRING_PACK *StringPack;
+ UINT16 Type;
+ UINT32 Length;
+
+ *PackSize = 0;
+
+ Type = EFI_HII_IFR;
+ if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {
+ //
+ // The header contains the full IFR length
+ //
+ CopyMem (&Length, &((EFI_HII_PACK_HEADER *) Pack)->Length, sizeof (Length));
+ *PackSize = (UINTN) Length;
+ return EFI_SUCCESS;
+ }
+
+ Type = EFI_HII_STRING;
+ if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {
+ //
+ // The header contains the STRING package length
+ // The assumption is that the strings for all languages
+ // are a contiguous block of data and there is a series of
+ // these package instances which will terminate with a NULL package
+ // instance.
+ //
+ StringPack = (EFI_HII_STRING_PACK *) Pack;
+
+ //
+ // There may be multiple instances packed together of strings
+ // so we must walk the self describing structures until we encounter
+ // the NULL structure to determine the full size.
+ //
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));
+ if (NumberOfTokens != NULL) {
+ CopyMem (NumberOfTokens, &StringPack->NumStringPointers, sizeof (UINT32));
+ }
+
+ while (Length != 0) {
+ *PackSize = *PackSize + Length;
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) StringPack + Length);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));
+ }
+ //
+ // Encountered a length of 0, so let's add the space for the NULL terminator
+ // pack's length and call it done.
+ //
+ *PackSize = *PackSize + sizeof (EFI_HII_STRING_PACK);
+ return EFI_SUCCESS;
+ }
+ //
+ // We only determine the size of the non-global Package types.
+ // If neither IFR or STRING data were found, return an error
+ //
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+ValidatePack (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_PACKAGE_INSTANCE *PackageInstance,
+ OUT EFI_HII_PACKAGE_INSTANCE **StringPackageInstance,
+ OUT UINT32 *TotalStringCount
+ )
+/*++
+
+Routine Description:
+ Verifies that the package instance is using the correct handle for string operations.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_PACKAGE_INSTANCE *HandlePackageInstance;
+ UINT8 *RawData;
+ EFI_GUID Guid;
+ EFI_HII_IFR_PACK *FormPack;
+ UINTN Index;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ HandleDatabase = HiiData->DatabaseHead;
+ ZeroMem (&Guid, sizeof (EFI_GUID));
+
+ *StringPackageInstance = PackageInstance;
+
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ if (PackageInstance->IfrSize > 0) {
+ FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
+ } else {
+ //
+ // If there is no IFR data assume the caller knows what they are doing.
+ //
+ return EFI_SUCCESS;
+ }
+
+ RawData = (UINT8 *) FormPack;
+
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
+ if (RawData[Index] == EFI_IFR_FORM_SET_OP) {
+ //
+ // Cache the guid for this formset
+ //
+ CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
+ break;
+ }
+
+ Index = RawData[Index + 1] + Index;
+ }
+ //
+ // If there is no string package, and the PackageInstance->IfrPack.Guid and PackageInstance->Guid are
+ // different, we should return the correct handle for the caller to use for strings.
+ //
+ if ((PackageInstance->StringSize == 0) && (!CompareGuid (&Guid, &PackageInstance->Guid))) {
+ //
+ // Search the database for a handle that matches the PackageInstance->Guid
+ //
+ for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ //
+ // Get Ifrdata and extract the Guid for it
+ //
+ HandlePackageInstance = HandleDatabase->Buffer;
+
+ ASSERT (HandlePackageInstance->IfrSize != 0);
+
+ FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&HandlePackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
+ RawData = (UINT8 *) FormPack;
+
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
+ if (RawData[Index] == EFI_IFR_FORM_SET_OP) {
+ //
+ // Cache the guid for this formset
+ //
+ CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
+ break;
+ }
+
+ Index = RawData[Index + 1] + Index;
+ }
+ //
+ // If the Guid from the new handle matches the original Guid referenced in the original package data
+ // return the appropriate package instance data to use.
+ //
+ if (CompareGuid (&Guid, &PackageInstance->Guid)) {
+ if (TotalStringCount != NULL) {
+ *TotalStringCount = HandleDatabase->NumberOfTokens;
+ }
+
+ *StringPackageInstance = HandlePackageInstance;
+ }
+ }
+ //
+ // end for
+ //
+ } else {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiiNewPack (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_PACKAGES *Packages,
+ OUT EFI_HII_HANDLE *Handle
+ )
+/*++
+
+Routine Description:
+
+ Extracts the various packs from a package list.
+
+Arguments:
+
+ This - Pointer of HII protocol.
+ Packages - Pointer of HII packages.
+ Handle - Handle value to be returned.
+
+Returns:
+
+ EFI_SUCCESS - Pacakges has added to HII database successfully.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+--*/
+{
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_HANDLE_DATABASE *Database;
+ EFI_HII_PACK_HEADER *PackageHeader;
+ EFI_HII_GLOBAL_DATA *GlobalData;
+ EFI_HII_IFR_PACK *IfrPack;
+ EFI_HII_STRING_PACK *StringPack;
+ EFI_HII_FONT_PACK *FontPack;
+ EFI_HII_KEYBOARD_PACK *KeyboardPack;
+ EFI_STATUS Status;
+ UINTN IfrSize;
+ UINTN StringSize;
+ UINTN TotalStringSize;
+ UINTN InstanceSize;
+ UINTN Count;
+ UINTN Index;
+ UINT16 Member;
+ EFI_GUID Guid;
+ EFI_FORM_SET_STUB FormSetStub;
+ UINT8 *Location;
+ UINT16 Unicode;
+ UINT16 NumWideGlyphs;
+ UINT16 NumNarrowGlyphs;
+ UINT32 NumberOfTokens;
+ UINT32 TotalTokenNumber;
+ UINT8 *Local;
+ EFI_NARROW_GLYPH *NarrowGlyph;
+ EFI_WIDE_GLYPH *WideGlyph;
+
+ if (Packages->NumberOfPackages == 0 || This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ GlobalData = HiiData->GlobalData;
+
+ Database = HiiData->DatabaseHead;
+
+ PackageInstance = NULL;
+ IfrPack = NULL;
+ StringPack = NULL;
+ InstanceSize = 0;
+ IfrSize = 0;
+ StringSize = 0;
+ TotalStringSize = 0;
+ NumberOfTokens = 0;
+ TotalTokenNumber = 0;
+
+ //
+ // Search through the passed in Packages for the IfrPack and any StringPack.
+ //
+ for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
+
+ PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));
+
+ switch (PackageHeader->Type) {
+ case EFI_HII_IFR:
+ //
+ // There shoule be only one Ifr package.
+ //
+ ASSERT (IfrPack == NULL);
+ IfrPack = (EFI_HII_IFR_PACK *) PackageHeader;
+ break;
+
+ case EFI_HII_STRING:
+ StringPack = (EFI_HII_STRING_PACK *) PackageHeader;
+ //
+ // Sending me a String Package. Get its size.
+ //
+ Status = GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);
+ ASSERT (!EFI_ERROR (Status));
+
+ //
+ // The size which GetPackSize() returns include the null terminator. So if multiple
+ // string packages are passed in, merge all these packages, and only pad one null terminator.
+ //
+ if (TotalStringSize > 0) {
+ TotalStringSize -= sizeof (EFI_HII_STRING_PACK);
+ }
+
+ TotalStringSize += StringSize;
+ TotalTokenNumber += NumberOfTokens;
+ break;
+ }
+ }
+ //
+ // If sending a StringPack without an IfrPack, you must include a GuidId
+ //
+ if ((StringPack != NULL) && (IfrPack == NULL)) {
+ if (Packages->GuidId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // If passing in an IfrPack and a GuidId is provided, ensure they are the same value.
+ //
+ if ((IfrPack != NULL) && (Packages->GuidId != NULL)) {
+ Location = ((UINT8 *) IfrPack);
+ Location = (UINT8 *) (((UINTN) Location) + sizeof (EFI_HII_PACK_HEADER));
+
+ //
+ // Advance to the Form Set Op-code
+ //
+ for (Count = 0; ((EFI_IFR_OP_HEADER *) &Location[Count])->OpCode != EFI_IFR_FORM_SET_OP;) {
+ Count = Count + ((EFI_IFR_OP_HEADER *) &Location[Count])->Length;
+ }
+ //
+ // Copy to local variable
+ //
+ CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &Location[Count])->Guid, sizeof (EFI_GUID));
+
+ //
+ // Check to see if IfrPack->Guid != GuidId
+ //
+ if (!CompareGuid (&Guid, Packages->GuidId)) {
+ //
+ // If a string package is present, the GUIDs should have agreed. Return an error
+ //
+ if (StringPack != NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+ //
+ // If someone is passing in a string only, create a dummy IfrPack with a Guid
+ // to enable future searching of this data.
+ //
+ if ((IfrPack == NULL) && (StringPack != NULL)) {
+ ZeroMem (&FormSetStub, sizeof (FormSetStub));
+
+ FormSetStub.Header.Type = EFI_HII_IFR;
+ FormSetStub.Header.Length = sizeof (EFI_FORM_SET_STUB);
+
+ FormSetStub.FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;
+ FormSetStub.FormSet.Header.Length = (UINT8) sizeof (EFI_IFR_FORM_SET);
+ //
+ // Dummy string
+ //
+ FormSetStub.FormSet.FormSetTitle = 0x02;
+ CopyMem (&FormSetStub.FormSet.Guid, Packages->GuidId, sizeof (EFI_GUID));
+
+ FormSetStub.EndFormSet.Header.OpCode = EFI_IFR_END_FORM_SET_OP;
+ FormSetStub.EndFormSet.Header.Length = (UINT8) sizeof (EFI_IFR_END_FORM_SET);
+ IfrPack = (EFI_HII_IFR_PACK *) &FormSetStub;
+ }
+
+ if (IfrPack != NULL) {
+ //
+ // Sending me an IFR Package. Get its size.
+ //
+ Status = GetPackSize ((VOID *) IfrPack, &IfrSize, NULL);
+ ASSERT (!EFI_ERROR (Status));
+ }
+ //
+ // Prepare the internal package instace buffer to store package data.
+ //
+ InstanceSize = IfrSize + TotalStringSize;
+
+ if (InstanceSize != 0) {
+ PackageInstance = AllocateZeroPool (InstanceSize + sizeof (EFI_HII_PACKAGE_INSTANCE));
+
+ ASSERT (PackageInstance);
+
+ //
+ // If there is no DatabaseHead allocated - allocate one
+ //
+ if (HiiData->DatabaseHead == NULL) {
+ HiiData->DatabaseHead = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));
+ ASSERT (HiiData->DatabaseHead);
+ }
+ //
+ // If the head is being used (Handle is non-zero), allocate next Database and
+ // add it to the linked-list
+ //
+ if (HiiData->DatabaseHead->Handle != 0) {
+ HandleDatabase = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));
+
+ ASSERT (HandleDatabase);
+
+ for (; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase)
+ ;
+
+ //
+ // We are sitting on the Database entry which contains the null Next pointer. Fix it.
+ //
+ Database->NextHandleDatabase = HandleDatabase;
+
+ }
+
+ Database = HiiData->DatabaseHead;
+
+ //
+ // Initialize this instance data
+ //
+ for (*Handle = 1; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase) {
+ //
+ // Since the first Database instance will have a passed back handle of 1, we will continue
+ // down the linked list of entries until we encounter the end of the linked list. Each time
+ // we go down one level deeper, increment the handle value that will be passed back.
+ //
+ if (Database->Handle >= *Handle) {
+ *Handle = Database->Handle + 1;
+ }
+ }
+
+ PackageInstance->Handle = *Handle;
+ PackageInstance->IfrSize = IfrSize;
+ PackageInstance->StringSize = TotalStringSize;
+ if (Packages->GuidId != NULL) {
+ CopyMem (&PackageInstance->Guid, Packages->GuidId, sizeof (EFI_GUID));
+ }
+
+ Database->Buffer = PackageInstance;
+ Database->Handle = PackageInstance->Handle;
+ Database->NumberOfTokens = TotalTokenNumber;
+ Database->NextHandleDatabase = NULL;
+ }
+ //
+ // Copy the Ifr package data into package instance.
+ //
+ if (IfrSize > 0) {
+ CopyMem (&PackageInstance->IfrData, IfrPack, IfrSize);
+ }
+ //
+ // Main loop to store package data into HII database.
+ //
+ StringSize = 0;
+ TotalStringSize = 0;
+
+ for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
+
+ PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));
+
+ switch (PackageHeader->Type) {
+ case EFI_HII_STRING:
+ StringPack = (EFI_HII_STRING_PACK *) PackageHeader;
+ //
+ // The size which GetPackSize() returns include the null terminator. So if multiple
+ // string packages are passed in, merge all these packages, and only pad one null terminator.
+ //
+ if (TotalStringSize > 0) {
+ TotalStringSize -= sizeof (EFI_HII_STRING_PACK);
+ }
+
+ GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);
+ CopyMem ((CHAR8 *) (&PackageInstance->IfrData) + IfrSize + TotalStringSize, StringPack, StringSize);
+
+ TotalStringSize += StringSize;
+ break;
+
+ case EFI_HII_HANDLES:
+ CopyMem (&PackageInstance->HandlePack, PackageHeader, sizeof (EFI_HII_HANDLE_PACK));
+ break;
+
+ case EFI_HII_FONT:
+ FontPack = (EFI_HII_FONT_PACK *) PackageHeader;
+ //
+ // Add whatever narrow glyphs were passed to us if undefined
+ //
+ CopyMem (&NumNarrowGlyphs, &FontPack->NumberOfNarrowGlyphs, sizeof (UINT16));
+ for (Count = 0; Count <= NumNarrowGlyphs; Count++) {
+ Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) + (sizeof (EFI_NARROW_GLYPH)) * Count;
+ NarrowGlyph = (EFI_NARROW_GLYPH *) Local;
+ CopyMem (&Member, &NarrowGlyph->UnicodeWeight, sizeof (UINT16));
+ //
+ // If the glyph is already defined, do not overwrite it. It is what it is.
+ //
+ CopyMem (&Unicode, &GlobalData->NarrowGlyphs[Member].UnicodeWeight, sizeof (UINT16));
+ if (Unicode == 0) {
+ CopyMem (&GlobalData->NarrowGlyphs[Member], Local, sizeof (EFI_NARROW_GLYPH));
+ }
+ }
+ //
+ // Add whatever wide glyphs were passed to us if undefined
+ //
+ CopyMem (&NumWideGlyphs, &FontPack->NumberOfWideGlyphs, sizeof (UINT16));
+ for (Count = 0; Count <= NumWideGlyphs; Count++) {
+ Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) +
+ (sizeof (EFI_NARROW_GLYPH)) *
+ NumNarrowGlyphs;
+ WideGlyph = (EFI_WIDE_GLYPH *) Local;
+ CopyMem (
+ &Member,
+ (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),
+ sizeof (UINT16)
+ );
+ //
+ // If the glyph is already defined, do not overwrite it. It is what it is.
+ //
+ CopyMem (&Unicode, &GlobalData->WideGlyphs[Member].UnicodeWeight, sizeof (UINT16));
+ if (Unicode == 0) {
+ Local = (UINT8*)(&FontPack->NumberOfWideGlyphs + sizeof(UINT8)) + (sizeof(EFI_NARROW_GLYPH)) * NumNarrowGlyphs;
+ WideGlyph = (EFI_WIDE_GLYPH *) Local;
+ CopyMem (
+ &GlobalData->WideGlyphs[Member],
+ (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),
+ sizeof (EFI_WIDE_GLYPH)
+ );
+ }
+ }
+ break;
+
+ case EFI_HII_KEYBOARD:
+ KeyboardPack = (EFI_HII_KEYBOARD_PACK *) PackageHeader;
+ //
+ // Sending me a Keyboard Package
+ //
+ if (KeyboardPack->DescriptorCount > 105) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // If someone updates the Descriptors with a count of 0, blow aware the overrides.
+ //
+ if (KeyboardPack->DescriptorCount == 0) {
+ ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
+ }
+
+ if (KeyboardPack->DescriptorCount < 106 && KeyboardPack->DescriptorCount > 0) {
+ //
+ // If SystemKeyboard was updated already, then steer changes to the override database
+ //
+ if (GlobalData->SystemKeyboardUpdate) {
+ ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
+ for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {
+ CopyMem (&Member, &KeyboardPack->Descriptor[Count].Key, sizeof (UINT16));
+ CopyMem (
+ &GlobalData->OverrideKeyboardLayout[Member],
+ &KeyboardPack->Descriptor[Count],
+ sizeof (EFI_KEY_DESCRIPTOR)
+ );
+ }
+ } else {
+ //
+ // SystemKeyboard was never updated, so this is likely the keyboard driver setting the System database.
+ //
+ ZeroMem (GlobalData->SystemKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
+ for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {
+ CopyMem (&Member, &KeyboardPack->Descriptor->Key, sizeof (UINT16));
+ CopyMem (
+ &GlobalData->SystemKeyboardLayout[Member],
+ &KeyboardPack->Descriptor[Count],
+ sizeof (EFI_KEY_DESCRIPTOR)
+ );
+ }
+ //
+ // Just updated the system keyboard database, reflect that in the global flag.
+ //
+ GlobalData->SystemKeyboardUpdate = TRUE;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiiRemovePack (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+ Removes the various packs from a Handle
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_HANDLE_DATABASE *PreviousHandleDatabase;
+ UINTN Count;
+
+ if (This == NULL || Handle == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ HandleDatabase = HiiData->DatabaseHead;
+ PackageInstance = NULL;
+
+ //
+ // Initialize the Previous with the Head of the Database
+ //
+ PreviousHandleDatabase = HandleDatabase;
+
+ for (Count = 0; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ //
+ // Match the numeric value with the database entry - if matched,
+ // free the package instance and apply fix-up to database linked list
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+
+ //
+ // Free the Package Instance
+ //
+ gBS->FreePool (PackageInstance);
+
+ //
+ // If this was the only Handle in the database
+ //
+ if (HiiData->DatabaseHead == HandleDatabase) {
+ HiiData->DatabaseHead = NULL;
+ }
+ //
+ // Make the parent->Next point to the current->Next
+ //
+ PreviousHandleDatabase->NextHandleDatabase = HandleDatabase->NextHandleDatabase;
+ gBS->FreePool (HandleDatabase);
+ return EFI_SUCCESS;
+ }
+ //
+ // If this was not the HandleDatabase entry we were looking for, cache it just in case the next one is
+ //
+ PreviousHandleDatabase = HandleDatabase;
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c
new file mode 100644
index 0000000000..742a01dc43
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c
@@ -0,0 +1,1276 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Strings.c
+
+Abstract:
+
+ This file contains the string processing code to the HII database.
+
+--*/
+
+
+#include "HiiDatabase.h"
+
+VOID
+AsciiToUnicode (
+ IN UINT8 *Lang,
+ IN UINT16 *Language
+ )
+{
+ UINT8 Count;
+
+ //
+ // Convert the ASCII Lang variable to a Unicode Language variable
+ //
+ for (Count = 0; Count < 3; Count++) {
+ Language[Count] = (CHAR16) Lang[Count];
+ }
+}
+
+EFI_STATUS
+EFIAPI
+HiiTestString (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *StringToTest,
+ IN OUT UINT32 *FirstMissing,
+ OUT UINT32 *GlyphBufferSize
+ )
+/*++
+
+Routine Description:
+ Test if all of the characters in a string have corresponding font characters.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_HII_GLOBAL_DATA *GlobalData;
+ EFI_HII_DATA *HiiData;
+ UINTN Count;
+ BOOLEAN Narrow;
+ UINTN Location;
+ UINT8 GlyphCol1[19];
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ GlobalData = HiiData->GlobalData;
+ Count = 0;
+ Narrow = TRUE;
+
+ ZeroMem (GlyphCol1, sizeof (GlyphCol1));
+
+ //
+ // Walk through the string until you hit the null terminator
+ //
+ for (; StringToTest[*FirstMissing] != 0x00; (*FirstMissing)++) {
+ Location = *FirstMissing;
+ //
+ // Rewind through the string looking for a glyph width identifier
+ //
+ for (; Location != 0; Location--) {
+ if (StringToTest[Location] == NARROW_CHAR || StringToTest[Location] == WIDE_CHAR) {
+ //
+ // We found something that identifies what glyph database to look in
+ //
+ if (StringToTest[Location] == WIDE_CHAR) {
+ Narrow = FALSE;
+ } else {
+ Narrow = TRUE;
+ }
+ }
+ }
+
+ if (Narrow) {
+ if (CompareMem (
+ GlobalData->NarrowGlyphs[StringToTest[*FirstMissing]].GlyphCol1,
+ &mUnknownGlyph,
+ NARROW_GLYPH_ARRAY_SIZE
+ ) == 0
+ ) {
+ //
+ // Break since this glyph isn't defined
+ //
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ //
+ // Can compare wide glyph against only GlyphCol1 since GlyphCol1 and GlyphCol2 are contiguous - just give correct size
+ //
+ if (CompareMem (
+ GlobalData->WideGlyphs[StringToTest[*FirstMissing]].GlyphCol1,
+ &mUnknownGlyph,
+ WIDE_GLYPH_ARRAY_SIZE
+ ) == 0
+ ) {
+ //
+ // Break since this glyph isn't defined
+ //
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ Count++;
+ }
+
+ if (Narrow) {
+ *GlyphBufferSize = (UINT32) (Count * sizeof (EFI_NARROW_GLYPH));
+ } else {
+ *GlyphBufferSize = (UINT32) (Count * sizeof (EFI_WIDE_GLYPH));
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HiiNewString2 (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Language,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT STRING_REF *Reference,
+ IN CHAR16 *NewString,
+ IN BOOLEAN ResetStrings
+ )
+/*++
+
+Routine Description:
+
+ This function allows a new String to be added to an already existing String Package.
+ We will make a buffer the size of the package + EfiStrSize of the new string. We will
+ copy the string package that first gets changed and the following language packages until
+ we encounter the NULL string package. All this time we will ensure that the offsets have
+ been adjusted.
+
+Arguments:
+
+ This - Pointer to the HII protocol.
+ Language - Pointer to buffer which contains the language code of this NewString.
+ Handle - Handle of the package instance to be processed.
+ Reference - The token number for the string. If 0, new string token to be returned through this parameter.
+ NewString - Buffer pointer for the new string.
+ ResetStrings - Indicate if we are resetting a string.
+
+Returns:
+
+ EFI_SUCCESS - The string has been added or reset to Hii database.
+ EFI_INVALID_PARAMETER - Some parameter passed in is invalid.
+
+--*/
+{
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_STRING_PACK *StringPack;
+ EFI_HII_STRING_PACK *NewStringPack;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_PACKAGE_INSTANCE *NewBuffer;
+ UINT8 *Location;
+ UINT8 *StringLocation;
+ RELOFST *StringPointer;
+ UINTN Count;
+ UINTN Size;
+ UINTN Index;
+ UINTN SecondIndex;
+ BOOLEAN AddString;
+ EFI_STATUS Status;
+ UINTN Increment;
+ UINTN StringCount;
+ UINT32 TotalStringCount;
+ UINT32 OriginalStringCount;
+ RELOFST StringSize;
+ UINT32 Length;
+ RELOFST Offset;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ HandleDatabase = HiiData->DatabaseHead;
+ PackageInstance = NULL;
+ AddString = FALSE;
+ Increment = 0;
+ StringCount = 0;
+ TotalStringCount = 0;
+ OriginalStringCount = 0;
+
+ //
+ // Check numeric value against the head of the database
+ //
+ for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ //
+ // Match the numeric value with the database entry - if matched, extract PackageInstance
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ if (ResetStrings) {
+ TotalStringCount = HandleDatabase->NumberOfTokens;
+ }
+ break;
+ }
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = ValidatePack (This, PackageInstance, &StringPackageInstance, &TotalStringCount);
+
+ //
+ // This sets Count to 0 or the size of the IfrData. We intend to use Count as an offset value
+ //
+ Count = StringPackageInstance->IfrSize;
+
+ //
+ // This is the size of the complete series of string packs
+ //
+ Size = StringPackageInstance->StringSize;
+
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ if (StringPackageInstance->IfrSize > 0) {
+ Location = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;
+ } else {
+ Location = (UINT8 *) (&StringPackageInstance->IfrData);
+ }
+ //
+ // We allocate a buffer which is big enough for both adding and resetting string.
+ // The size is slightly larger than the real size of the packages when we are resetting a string.
+ //
+ NewBuffer = AllocateZeroPool (
+ sizeof (EFI_HII_PACKAGE_INSTANCE) -
+ 2 * sizeof (VOID *) +
+ StringPackageInstance->IfrSize +
+ StringPackageInstance->StringSize +
+ sizeof (RELOFST) +
+ StrSize (NewString)
+ );
+ ASSERT (NewBuffer);
+
+ //
+ // Copy data to new buffer
+ //
+ NewBuffer->Handle = StringPackageInstance->Handle;
+ NewBuffer->IfrSize = StringPackageInstance->IfrSize;
+
+ //
+ // The worst case scenario for sizing is that we are adding a new string (not replacing one) and there was not a string
+ // package to begin with.
+ //
+ NewBuffer->StringSize = StringPackageInstance->StringSize + StrSize (NewString) + sizeof (EFI_HII_STRING_PACK);
+
+ if (StringPackageInstance->IfrSize > 0) {
+ CopyMem (&NewBuffer->IfrData, &StringPackageInstance->IfrData, StringPackageInstance->IfrSize);
+ }
+
+ StringPack = (EFI_HII_STRING_PACK *) Location;
+
+ //
+ // There may be multiple instances packed together of strings
+ // so we must walk the self describing structures until we encounter
+ // what we are looking for. In the meantime, copy everything we encounter
+ // to the new buffer.
+ //
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ for (; Length != 0;) {
+ //
+ // If passed in Language ISO value is in this string pack's language string
+ // then we are dealing with the strings we want.
+ //
+ CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));
+ Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);
+
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+
+ CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);
+
+ Count = Count + Length;
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ }
+ //
+ // Found the language pack to update on a particular handle
+ // We need to Copy the Contents of this pack and adjust the offset values associated
+ // with adding/changing a string. This is a particular piece of code that screams for
+ // it being prone to programming error.
+ //
+ //
+ // Copy the string package up to the string data
+ //
+ StringPointer = (RELOFST *) (StringPack + 1);
+ CopyMem (
+ ((CHAR8 *) (&NewBuffer->IfrData) + Count),
+ StringPack,
+ (UINTN) ((UINTN) (StringPointer) - (UINTN) (StringPack))
+ );
+
+ //
+ // Determine the number of StringPointers
+ //
+ if (!ResetStrings) {
+ CopyMem (&TotalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));
+ } else {
+ //
+ // If we are resetting the strings, use the original value when exported
+ //
+ CopyMem (&OriginalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));
+ ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString -=
+ (
+ (RELOFST) (OriginalStringCount - TotalStringCount) *
+ sizeof (RELOFST)
+ );
+ ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName -=
+ (
+ (RELOFST) (OriginalStringCount - TotalStringCount) *
+ sizeof (RELOFST)
+ );
+ ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers = TotalStringCount;
+ *Reference = (STRING_REF) (TotalStringCount);
+ }
+ //
+ // If the token value is not valid, error out
+ //
+ if ((*Reference >= TotalStringCount) && !ResetStrings) {
+ gBS->FreePool (NewBuffer);
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // If Reference is 0, update it with what the new token reference will be and turn the AddString flag on
+ //
+ if (*Reference == 0) {
+ *Reference = (STRING_REF) (TotalStringCount);
+ AddString = TRUE;
+ }
+
+ if (AddString) {
+ ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString += sizeof (RELOFST);
+ ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName += sizeof (RELOFST);
+ ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers++;
+ }
+ //
+ // Increment offset by amount of copied data
+ //
+ Count = Count + ((UINTN) (StringPointer) - (UINTN) StringPack);
+
+ for (Index = 0; Index < TotalStringCount; Index++) {
+ //
+ // If we are pointing to the size of the changing string value
+ // then cache the old string value so you know what the difference is
+ //
+ if (Index == *Reference) {
+ CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));
+
+ StringLocation = ((UINT8 *) (StringPack) + Offset);
+ for (SecondIndex = 0;
+ (StringLocation[SecondIndex] != 0) || (StringLocation[SecondIndex + 1] != 0);
+ SecondIndex = SecondIndex + 2
+ )
+ ;
+ SecondIndex = SecondIndex + 2;
+
+ Size = SecondIndex;
+
+ //
+ // NewString is a passed in local string which is assumed to be aligned
+ //
+ Size = StrSize (NewString) - Size;
+ }
+ //
+ // If we are about to copy the offset of the string that follows the changed string make
+ // sure that the offsets are adjusted accordingly
+ //
+ if ((Index > *Reference) && !ResetStrings) {
+ CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));
+ Offset = (RELOFST) (Offset + Size);
+ CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));
+ }
+ //
+ // If we are adding a string that means we will have an extra string pointer that will affect all string offsets
+ //
+ if (AddString) {
+ CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));
+ Offset = (UINT32) (Offset + sizeof (RELOFST));
+ CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));
+ }
+ //
+ // If resetting the strings, we need to reduce the offset by the difference in the strings
+ //
+ if (ResetStrings) {
+ CopyMem (&Length, &StringPointer[Index], sizeof (RELOFST));
+ Length = Length - ((RELOFST) (OriginalStringCount - TotalStringCount) * sizeof (RELOFST));
+ CopyMem (&StringPointer[Index], &Length, sizeof (RELOFST));
+ }
+ //
+ // Notice that if the string was being added as a new token, we don't have to worry about the
+ // offsets changing in the other indexes
+ //
+ CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringPointer[Index], sizeof (RELOFST));
+ Count = Count + sizeof (RELOFST);
+ StringCount++;
+ }
+ //
+ // If we are adding a new string the above for loop did not copy the offset for us
+ //
+ if (AddString) {
+ //
+ // Since the Index is pointing to the beginning of the first string, we need to gather the size of the previous
+ // offset's string and create an offset to our new string.
+ //
+ CopyMem (&Offset, &StringPointer[Index - 1], sizeof (RELOFST));
+ StringLocation = (UINT8 *) StringPack;
+ StringLocation = StringLocation + Offset - sizeof (RELOFST);
+
+ //
+ // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues
+ //
+ for (Length = 0;
+ (StringLocation[Length] != 0) || (StringLocation[Length + 1] != 0);
+ Length = (RELOFST) (Length + 2)
+ )
+ ;
+ Length = (RELOFST) (Length + 2);
+
+ StringSize = (RELOFST) (Offset + Length);
+
+ //
+ // Copy the new string offset
+ //
+ CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringSize, sizeof (RELOFST));
+ Count = Count + sizeof (RELOFST);
+
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ Length = Length + sizeof (RELOFST);
+ CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));
+ }
+ //
+ // Set Location to the First String
+ //
+ if (ResetStrings) {
+ Index = OriginalStringCount;
+ }
+ //
+ // Set Location to the First String
+ //
+ Location = (UINT8 *) &StringPointer[Index];
+ Index = 0;
+
+ //
+ // Keep copying strings until you run into two CHAR16's in a row that are NULL
+ //
+ do {
+ if ((*Reference == Increment) && !AddString) {
+ StringLocation = ((UINT8 *) (&NewBuffer->IfrData) + Count);
+ CopyMem (StringLocation, NewString, StrSize (NewString));
+
+ //
+ // Advance the destination location by Count number of bytes
+ //
+ Count = Count + StrSize (NewString);
+
+ //
+ // Add the difference between the new string and the old string to the length
+ //
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+
+ //
+ // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues
+ //
+ StringLocation = (UINT8 *) &Location[Index];
+ for (Offset = 0;
+ (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);
+ Offset = (RELOFST) (Offset + 2)
+ )
+ ;
+ Offset = (RELOFST) (Offset + 2);
+
+ Length = Length + (UINT32) StrSize (NewString) - Offset;
+
+ CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));
+ } else {
+ StringLocation = (UINT8 *) &Location[Index];
+ for (Offset = 0;
+ (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);
+ Offset = (RELOFST) (Offset + 2)
+ )
+ ;
+ Offset = (RELOFST) (Offset + 2);
+
+ CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringLocation, Offset);
+
+ //
+ // Advance the destination location by Count number of bytes
+ //
+ Count = Count + Offset;
+ }
+ //
+ // Retrieve the number of characters to advance the index - should land at beginning of next string
+ //
+ Index = Index + Offset;
+ Increment++;
+ StringCount--;
+ Offset = 0;
+ } while (StringCount > 0);
+
+ //
+ // If we are adding a new string, then the above do/while will not suffice
+ //
+ if (AddString) {
+ Offset = (RELOFST) StrSize (NewString);
+ CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), NewString, Offset);
+
+ Count = Count + StrSize (NewString);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ Length = Length + (UINT32) StrSize (NewString);
+ CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));
+ }
+
+ if (ResetStrings) {
+ //
+ // Skip the remainder of strings in the string package
+ //
+ StringCount = OriginalStringCount - TotalStringCount;
+
+ while (StringCount > 0) {
+ StringLocation = (UINT8 *) &Location[Index];
+ for (Offset = 0;
+ (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);
+ Offset = (RELOFST) (Offset + 2)
+ )
+ ;
+ Offset = (RELOFST) (Offset + 2);
+ Index = Index + Offset;
+ StringCount--;
+
+ //
+ // Adjust the size of the string pack by the string size we just skipped.
+ // Also reduce the length by the size of a RelativeOffset value since we
+ // obviously would have skipped that as well.
+ //
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ Length = Length - Offset - sizeof (RELOFST);
+ CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));
+ }
+ }
+
+ StringPack = (EFI_HII_STRING_PACK *) &Location[Index];
+
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ for (; Length != 0;) {
+
+ CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);
+
+ Count = Count + Length;
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ }
+ //
+ // Copy the null terminator to the new buffer
+ //
+ CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, sizeof (EFI_HII_STRING_PACK));
+
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ if (StringPackageInstance->IfrSize > 0) {
+ Location = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;
+ StringPack = (EFI_HII_STRING_PACK *) Location;
+ Location = (UINT8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize;
+ NewStringPack = (EFI_HII_STRING_PACK *) Location;
+ } else {
+ StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);
+ NewStringPack = (EFI_HII_STRING_PACK *) (&NewBuffer->IfrData);
+ }
+
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ for (; Length != 0;) {
+ //
+ // Since we updated the old version of the string data as we moved things over
+ // And we had a chicken-egg problem with the data we copied, let's post-fix the new
+ // buffer with accurate length data.
+ //
+ CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));
+ CopyMem (&NewStringPack->Header.Length, &StringPack->Header.Length, sizeof (UINT32));
+ CopyMem (&StringPack->Header.Length, &Count, sizeof (UINT32));
+
+ CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));
+ NewStringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (NewStringPack) + Count);
+ CopyMem (&Count, &StringPack->Header.Length, sizeof (UINT32));
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Count);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ }
+
+ GetPackSize ((VOID *) ((CHAR8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize), &NewBuffer->StringSize, NULL);
+
+ //
+ // Search through the handles until the requested handle is found.
+ //
+ for (HandleDatabase = HiiData->DatabaseHead;
+ HandleDatabase->Handle != 0;
+ HandleDatabase = HandleDatabase->NextHandleDatabase
+ ) {
+ if (HandleDatabase->Handle == StringPackageInstance->Handle) {
+ //
+ // Free the previous buffer associated with this handle, and assign the new buffer to the handle
+ //
+ gBS->FreePool (HandleDatabase->Buffer);
+ HandleDatabase->Buffer = NewBuffer;
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiiNewString (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Language,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT STRING_REF *Reference,
+ IN CHAR16 *NewString
+ )
+/*++
+
+Routine Description:
+ This function allows a new String to be added to an already existing String Package.
+ We will make a buffer the size of the package + StrSize of the new string. We will
+ copy the string package that first gets changed and the following language packages until
+ we encounter the NULL string package. All this time we will ensure that the offsets have
+ been adjusted.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN Index;
+ CHAR16 *LangCodes;
+ CHAR16 Lang[4];
+ STRING_REF OriginalValue;
+ EFI_STATUS Status;
+
+ //
+ // To avoid a warning 4 uninitialized variable warning
+ //
+ Status = EFI_SUCCESS;
+
+ Status = HiiGetPrimaryLanguages (
+ This,
+ Handle,
+ &LangCodes
+ );
+
+ if (!EFI_ERROR (Status)) {
+ OriginalValue = *Reference;
+
+ if (Language == NULL) {
+ for (Index = 0; LangCodes[Index] != 0; Index += 3) {
+ *Reference = OriginalValue;
+ CopyMem (Lang, &LangCodes[Index], 6);
+ Lang[3] = 0;
+ Status = HiiNewString2 (
+ This,
+ Lang,
+ Handle,
+ Reference,
+ NewString,
+ FALSE
+ );
+
+ }
+ } else {
+ Status = HiiNewString2 (
+ This,
+ Language,
+ Handle,
+ Reference,
+ NewString,
+ FALSE
+ );
+ }
+
+ gBS->FreePool (LangCodes);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+HiiResetStrings (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+
+ This function removes any new strings that were added after the initial string export for this handle.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN Index;
+ CHAR16 *LangCodes;
+ CHAR16 Lang[4];
+ STRING_REF Reference;
+ CHAR16 NewString;
+ EFI_STATUS Status;
+
+ Reference = 1;
+ NewString = 0;
+
+ HiiGetPrimaryLanguages (
+ This,
+ Handle,
+ &LangCodes
+ );
+
+ for (Index = 0; LangCodes[Index] != 0; Index += 3) {
+ CopyMem (Lang, &LangCodes[Index], 6);
+ Lang[3] = 0;
+ Status = HiiNewString2 (
+ This,
+ Lang,
+ Handle,
+ &Reference,
+ &NewString,
+ TRUE
+ );
+
+ }
+
+ gBS->FreePool (LangCodes);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiiGetString (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN BOOLEAN Raw,
+ IN CHAR16 *LanguageString,
+ IN OUT UINTN *BufferLengthTemp,
+ OUT EFI_STRING StringBuffer
+ )
+/*++
+
+Routine Description:
+
+ This function extracts a string from a package already registered with the EFI HII database.
+
+Arguments:
+ This - A pointer to the EFI_HII_PROTOCOL instance.
+ Handle - The HII handle on which the string resides.
+ Token - The string token assigned to the string.
+ Raw - If TRUE, the string is returned unedited in the internal storage format described
+ above. If false, the string returned is edited by replacing <cr> with <space>
+ and by removing special characters such as the <wide> prefix.
+ LanguageString - Pointer to a NULL-terminated string containing a single ISO 639-2 language
+ identifier, indicating the language to print. If the LanguageString is empty (starts
+ with a NULL), the default system language will be used to determine the language.
+ BufferLength - Length of the StringBuffer. If the status reports that the buffer width is too
+ small, this parameter is filled with the length of the buffer needed.
+ StringBuffer - The buffer designed to receive the characters in the string. Type EFI_STRING is
+ defined in String.
+
+Returns:
+ EFI_INVALID_PARAMETER - If input parameter is invalid.
+ EFI_BUFFER_TOO_SMALL - If the *BufferLength is too small.
+ EFI_SUCCESS - Operation is successful.
+
+--*/
+{
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_STRING_PACK *StringPack;
+ RELOFST *StringPointer;
+ EFI_STATUS Status;
+ UINTN DataSize;
+ CHAR8 Lang[3];
+ CHAR16 Language[3];
+ UINT32 Length;
+ UINTN Count;
+ RELOFST Offset;
+ UINT16 *Local;
+ UINT16 Zero;
+ UINT16 Narrow;
+ UINT16 Wide;
+ UINT16 NoBreak;
+ BOOLEAN LangFound;
+ UINT16 *BufferLength = (UINT16 *) BufferLengthTemp;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ LangFound = TRUE;
+
+ DataSize = sizeof (Lang);
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ PackageInstance = NULL;
+ Zero = 0;
+ Narrow = NARROW_CHAR;
+ Wide = WIDE_CHAR;
+ NoBreak = NON_BREAKING_CHAR;
+
+ //
+ // Check numeric value against the head of the database
+ //
+ for (HandleDatabase = HiiData->DatabaseHead;
+ HandleDatabase != NULL;
+ HandleDatabase = HandleDatabase->NextHandleDatabase
+ ) {
+ //
+ // Match the numeric value with the database entry - if matched, extract PackageInstance
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ break;
+ }
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);
+
+ //
+ // If there is no specified language, assume the system default language
+ //
+ if (LanguageString == NULL) {
+ //
+ // Get system default language
+ //
+ Status = gRT->GetVariable (
+ (CHAR16 *) L"Lang",
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ Lang
+ );
+
+ if (EFI_ERROR (Status)) {
+ //
+ // If Lang doesn't exist, just use the first language you find
+ //
+ LangFound = FALSE;
+ goto LangNotFound;
+ }
+ //
+ // Convert the ASCII Lang variable to a Unicode Language variable
+ //
+ AsciiToUnicode ((UINT8 *)Lang, Language);
+ } else {
+ //
+ // Copy input ISO value to Language variable
+ //
+ CopyMem (Language, LanguageString, 6);
+ }
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+LangNotFound:
+ if (StringPackageInstance->IfrSize > 0) {
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);
+ } else {
+ StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);
+ }
+ //
+ // If Token is 0, extract entire string package
+ //
+ if (Token == 0) {
+ //
+ // Compute the entire string pack length, including all languages' and the terminating pack's.
+ //
+ Length = 0;
+ while (0 != StringPack->Header.Length) {
+ Length += StringPack->Header.Length;
+ StringPack = (VOID*)(((UINT8*)StringPack) + StringPack->Header.Length);
+ }
+ //
+ // Back to the start of package.
+ //
+ StringPack = (VOID*)(((UINT8*)StringPack) - Length);
+ //
+ // Terminating zero sub-pack.
+ //
+ Length += sizeof (EFI_HII_STRING_PACK);
+
+ //
+ // If trying to get the entire string package and have insufficient space. Return error.
+ //
+ if (Length > *BufferLength || StringBuffer == NULL) {
+ *BufferLength = (UINT16)Length;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ //
+ // Copy the Pack to the caller's buffer.
+ //
+ *BufferLength = (UINT16)Length;
+ CopyMem (StringBuffer, StringPack, Length);
+
+ return EFI_SUCCESS;
+ }
+ //
+ // There may be multiple instances packed together of strings
+ // so we must walk the self describing structures until we encounter
+ // what we are looking for, and then extract the string we are looking for
+ //
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ for (; Length != 0;) {
+ //
+ // If passed in Language ISO value is in this string pack's language string
+ // then we are dealing with the strings we want.
+ //
+ CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));
+ Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);
+
+ //
+ // If we cannot find the lang variable, we skip this check and use the first language available
+ //
+ if (LangFound) {
+ if (EFI_ERROR (Status)) {
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
+ CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
+ continue;
+ }
+ }
+
+ StringPointer = (RELOFST *) (StringPack + 1);
+
+ //
+ // We have the right string package - size it, and copy it to the StringBuffer
+ //
+ if (Token >= StringPack->NumStringPointers) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ CopyMem (&Offset, &StringPointer[Token], sizeof (RELOFST));
+ }
+ //
+ // Since StringPack is a packed structure, we need to determine the string's
+ // size safely, thus byte-wise. Post-increment the size to include the null-terminator
+ //
+ Local = (UINT16 *) ((CHAR8 *) (StringPack) + Offset);
+ for (Count = 0; CompareMem (&Local[Count], &Zero, 2); Count++)
+ ;
+ Count++;
+
+ Count = Count * sizeof (CHAR16);;
+
+ if (*BufferLength >= Count && StringBuffer != NULL) {
+ //
+ // Copy the string to the user's buffer
+ //
+ if (Raw) {
+ CopyMem (StringBuffer, Local, Count);
+ } else {
+ for (Count = 0; CompareMem (Local, &Zero, 2); Local++) {
+ //
+ // Skip "Narraw, Wide, NoBreak"
+ //
+ if (CompareMem (Local, &Narrow, 2) &&
+ CompareMem (Local, &Wide, 2) &&
+ CompareMem (Local, &NoBreak, 2)) {
+ CopyMem (&StringBuffer[Count++], Local, 2);
+ }
+ }
+ //
+ // Add "NULL" at the end.
+ //
+ CopyMem (&StringBuffer[Count], &Zero, 2);
+ Count++;
+ Count *= sizeof (CHAR16);
+ }
+
+ *BufferLength = (UINT16) Count;
+ return EFI_SUCCESS;
+ } else {
+ *BufferLength = (UINT16) Count;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ }
+
+ LangFound = FALSE;
+ goto LangNotFound;
+}
+
+EFI_STATUS
+EFIAPI
+HiiGetLine (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN OUT UINT16 *Index,
+ IN UINT16 LineWidth,
+ IN CHAR16 *LanguageString,
+ IN OUT UINT16 *BufferLength,
+ OUT EFI_STRING StringBuffer
+ )
+/*++
+
+Routine Description:
+
+ This function allows a program to extract a part of a string of not more than a given width.
+ With repeated calls, this allows a calling program to extract "lines" of text that fit inside
+ columns. The effort of measuring the fit of strings inside columns is localized to this call.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN Count;
+ EFI_HII_PACKAGE_INSTANCE *PackageInstance;
+ EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;
+ EFI_HII_DATA *HiiData;
+ EFI_HII_HANDLE_DATABASE *HandleDatabase;
+ EFI_HII_STRING_PACK *StringPack;
+ RELOFST *StringPointer;
+ CHAR16 *Location;
+ EFI_STATUS Status;
+ UINTN DataSize;
+ CHAR8 Lang[3];
+ CHAR16 Language[3];
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiData = EFI_HII_DATA_FROM_THIS (This);
+
+ HandleDatabase = HiiData->DatabaseHead;
+
+ PackageInstance = NULL;
+ DataSize = 4;
+
+ //
+ // Check numeric value against the head of the database
+ //
+ for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
+ //
+ // Match the numeric value with the database entry - if matched, extract PackageInstance
+ //
+ if (Handle == HandleDatabase->Handle) {
+ PackageInstance = HandleDatabase->Buffer;
+ }
+ }
+ //
+ // No handle was found - error condition
+ //
+ if (PackageInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);
+
+ //
+ // If there is no specified language, assume the system default language
+ //
+ if (LanguageString == NULL) {
+ //
+ // Get system default language
+ //
+ Status = gRT->GetVariable (
+ (CHAR16 *) L"Lang",
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ Lang
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Convert the ASCII Lang variable to a Unicode Language variable
+ //
+ AsciiToUnicode ((UINT8 *)Lang, Language);
+ } else {
+ //
+ // Copy input ISO value to Language variable
+ //
+ CopyMem (Language, LanguageString, 6);
+ }
+ //
+ // Based on if there is IFR data in this package instance, determine
+ // what the location is of the beginning of the string data.
+ //
+ if (StringPackageInstance->IfrSize > 0) {
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);
+ } else {
+ StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);
+ }
+
+ StringPointer = (RELOFST *) (StringPack + 1);
+
+ //
+ // There may be multiple instances packed together of strings
+ // so we must walk the self describing structures until we encounter
+ // what we are looking for, and then extract the string we are looking for
+ //
+ for (; StringPack->Header.Length != 0;) {
+ //
+ // If passed in Language ISO value is in this string pack's language string
+ // then we are dealing with the strings we want.
+ //
+ Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language);
+
+ if (EFI_ERROR (Status)) {
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);
+ continue;
+ }
+
+ Location = (CHAR16 *) ((CHAR8 *) (StringPack) + StringPointer[Token] +*Index * 2);
+
+ //
+ // If the size of the remaining string is less than the LineWidth
+ // then copy the entire thing
+ //
+ if (StrSize (Location) <= LineWidth) {
+ if (*BufferLength >= StrSize (Location)) {
+ StrCpy (StringBuffer, Location);
+ return EFI_SUCCESS;
+ } else {
+ *BufferLength = (UINT16) StrSize (Location);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ } else {
+ //
+ // Rewind the string from the maximum size until we see a space the break the line
+ //
+ for (Count = LineWidth; Location[Count] != 0x0020; Count--)
+ ;
+
+ //
+ // Put the index at the next character
+ //
+ *Index = (UINT16) (Count + 1);
+
+ if (*BufferLength >= Count) {
+ StrnCpy (StringBuffer, Location, Count);
+ return EFI_SUCCESS;
+ } else {
+ *BufferLength = (UINT16) Count;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HiiCompareLanguage (
+ IN CHAR16 *LanguageStringLocation,
+ IN CHAR16 *Language
+ )
+{
+ UINT8 *Local;
+ UINTN Index;
+ CHAR16 *InputString;
+ CHAR16 *OriginalInputString;
+
+ //
+ // Allocate a temporary buffer for InputString
+ //
+ InputString = AllocateZeroPool (0x100);
+
+ ASSERT (InputString);
+
+ OriginalInputString = InputString;
+
+ Local = (UINT8 *) LanguageStringLocation;
+
+ //
+ // Determine the size of this packed string safely (e.g. access by byte), post-increment
+ // to include the null-terminator
+ //
+ for (Index = 0; Local[Index] != 0; Index = Index + 2)
+ ;
+ //
+ // MARMAR Index = Index + 2;
+ //
+ // This is a packed structure that this location comes from, so let's make sure
+ // the value is aligned by copying it to a local variable and working on it.
+ //
+ CopyMem (InputString, LanguageStringLocation, Index);
+
+ for (Index = 0; Index < 3; Index++) {
+ InputString[Index] = (CHAR16) (InputString[Index] | 0x20);
+ Language[Index] = (CHAR16) (Language[Index] | 0x20);
+ }
+ //
+ // If the Language is the same return success
+ //
+ if (CompareMem (LanguageStringLocation, Language, 6) == 0) {
+ gBS->FreePool (InputString);
+ return EFI_SUCCESS;
+ }
+ //
+ // Skip the first three letters that comprised the primary language,
+ // see if what is being compared against is a secondary language
+ //
+ InputString = InputString + 3;
+
+ //
+ // If the Language is not the same as the Primary language, see if there are any
+ // secondary languages, and if there are see if we have a match. If not, return an error.
+ //
+ for (Index = 0; InputString[Index] != 0; Index = Index + 3) {
+ //
+ // Getting in here means we have a secondary language
+ //
+ if (CompareMem (&InputString[Index], Language, 6) == 0) {
+ gBS->FreePool (InputString);
+ return EFI_SUCCESS;
+ }
+ }
+ //
+ // If nothing was found, return the error
+ //
+ gBS->FreePool (OriginalInputString);
+ return EFI_NOT_FOUND;
+
+}
diff --git a/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/build.xml b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/build.xml
new file mode 100644
index 0000000000..7ffdb7c013
--- /dev/null
+++ b/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
+<project basedir="." default="HiiDatabase"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Universal\UserInterface\HiiDataBase\Dxe"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="HiiDatabase">
+ <GenBuild baseName="HiiDatabase" mbdFilename="${MODULE_DIR}\HiiDatabase.mbd" msaFilename="${MODULE_DIR}\HiiDatabase.msa"/>
+ </target>
+ <target depends="HiiDatabase_clean" name="clean"/>
+ <target depends="HiiDatabase_cleanall" name="cleanall"/>
+ <target name="HiiDatabase_clean">
+ <OutputDirSetup baseName="HiiDatabase" mbdFilename="${MODULE_DIR}\HiiDatabase.mbd" msaFilename="${MODULE_DIR}\HiiDatabase.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\HiiDatabase_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\HiiDatabase_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="HiiDatabase_cleanall">
+ <OutputDirSetup baseName="HiiDatabase" mbdFilename="${MODULE_DIR}\HiiDatabase.mbd" msaFilename="${MODULE_DIR}\HiiDatabase.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\HiiDatabase_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\HiiDatabase_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**HiiDatabase*"/>
+ </delete>
+ </target>
+</project> \ No newline at end of file