]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c
Port DriverSample.inf, HiiDatabase.inf and SetupBrowser.inf
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / HiiDataBaseDxe / HiiDatabase.c
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c
new file mode 100644 (file)
index 0000000..cac37e5
--- /dev/null
@@ -0,0 +1,412 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  HiiDatabase.c\r
+\r
+Abstract:\r
+\r
+  This file contains the entry code to the HII database.\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeHiiDatabase (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Initialize HII Database\r
+  \r
+Arguments:\r
+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
+\r
+Returns: \r
+  EFI_SUCCESS - Setup loaded.\r
+  other       - Setup Error\r
+\r
+--*/\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_HII_DATA        *HiiData;\r
+  EFI_HII_GLOBAL_DATA *GlobalData;\r
+  EFI_HANDLE          *HandleBuffer;\r
+  EFI_HANDLE          Handle;\r
+  UINTN               HandleCount;\r
+  UINTN               Index;\r
+\r
+  //\r
+  // There will be only one HII Database in the system\r
+  // If there is another out there, someone is trying to install us\r
+  // again.  Fail that scenario.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiHiiProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
+\r
+  //\r
+  // If there was no error, assume there is an installation and fail to load\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    if (HandleBuffer != NULL) {\r
+      FreePool (HandleBuffer);\r
+    }\r
+\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  HiiData = AllocatePool (sizeof (EFI_HII_DATA));\r
+\r
+  ASSERT (HiiData);\r
+\r
+  GlobalData = AllocateZeroPool (sizeof (EFI_HII_GLOBAL_DATA));\r
+\r
+  ASSERT (GlobalData);\r
+\r
+  //\r
+  // Seed the Font Database with a known non-character glyph\r
+  //\r
+  for (Index = 0; Index <= MAX_GLYPH_COUNT; Index++) {\r
+    //\r
+    // Seeding the UnicodeWeight with 0 signifies that it is uninitialized\r
+    //\r
+    GlobalData->NarrowGlyphs[Index].UnicodeWeight = 0;\r
+    GlobalData->WideGlyphs[Index].UnicodeWeight   = 0;\r
+    GlobalData->NarrowGlyphs[Index].Attributes    = 0;\r
+    GlobalData->WideGlyphs[Index].Attributes      = 0;\r
+    CopyMem (GlobalData->NarrowGlyphs[Index].GlyphCol1, &mUnknownGlyph, NARROW_GLYPH_ARRAY_SIZE);\r
+    CopyMem (GlobalData->WideGlyphs[Index].GlyphCol1, &mUnknownGlyph, WIDE_GLYPH_ARRAY_SIZE);\r
+  }\r
+  //\r
+  // Fill in HII data\r
+  //\r
+  HiiData->Signature                        = EFI_HII_DATA_SIGNATURE;\r
+  HiiData->GlobalData                       = GlobalData;\r
+  HiiData->GlobalData->SystemKeyboardUpdate = FALSE;\r
+  HiiData->DatabaseHead                     = NULL;\r
+  HiiData->Hii.NewPack                      = HiiNewPack;\r
+  HiiData->Hii.RemovePack                   = HiiRemovePack;\r
+  HiiData->Hii.FindHandles                  = HiiFindHandles;\r
+  HiiData->Hii.ExportDatabase               = HiiExportDatabase;\r
+  HiiData->Hii.GetGlyph                     = HiiGetGlyph;\r
+  HiiData->Hii.GetPrimaryLanguages          = HiiGetPrimaryLanguages;\r
+  HiiData->Hii.GetSecondaryLanguages        = HiiGetSecondaryLanguages;\r
+  HiiData->Hii.NewString                    = HiiNewString;\r
+  HiiData->Hii.GetString                    = HiiGetString;\r
+  HiiData->Hii.ResetStrings                 = HiiResetStrings;\r
+  HiiData->Hii.TestString                   = HiiTestString;\r
+  HiiData->Hii.GetLine                      = HiiGetLine;\r
+  HiiData->Hii.GetForms                     = HiiGetForms;\r
+  HiiData->Hii.GetDefaultImage              = HiiGetDefaultImage;\r
+  HiiData->Hii.UpdateForm                   = HiiUpdateForm;\r
+  HiiData->Hii.GetKeyboardLayout            = HiiGetKeyboardLayout;\r
+  HiiData->Hii.GlyphToBlt                   = HiiGlyphToBlt;\r
+\r
+  //\r
+  // Install protocol interface\r
+  //\r
+  Handle = NULL;\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &Handle,\r
+                  &gEfiHiiProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &HiiData->Hii\r
+                  );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiFindHandles (\r
+  IN     EFI_HII_PROTOCOL *This,\r
+  IN OUT UINT16           *HandleBufferLength,\r
+  OUT    EFI_HII_HANDLE   Handle[1]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Determines the handles that are currently active in the database.\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_HANDLE_DATABASE *Database;\r
+  EFI_HII_DATA            *HiiData;\r
+  UINTN                   HandleCount;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData     = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  Database    = HiiData->DatabaseHead;\r
+\r
+  if (Database == NULL) {\r
+    *HandleBufferLength = 0;\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  for (HandleCount = 0; Database != NULL; HandleCount++) {\r
+    Database = Database->NextHandleDatabase;\r
+  }\r
+  //\r
+  // Is there a sufficient buffer for the data being passed back?\r
+  //\r
+  if (*HandleBufferLength >= (sizeof (EFI_HII_HANDLE) * HandleCount)) {\r
+    Database = HiiData->DatabaseHead;\r
+\r
+    //\r
+    // Copy the Head information\r
+    //\r
+    if (Database->Handle != 0) {\r
+      CopyMem (&Handle[0], &Database->Handle, sizeof (EFI_HII_HANDLE));\r
+      Database = Database->NextHandleDatabase;\r
+    }\r
+    //\r
+    // Copy more data if appropriate\r
+    //\r
+    for (HandleCount = 1; Database != NULL; HandleCount++) {\r
+      CopyMem (&Handle[HandleCount], &Database->Handle, sizeof (EFI_HII_HANDLE));\r
+      Database = Database->NextHandleDatabase;\r
+    }\r
+\r
+    *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    //\r
+    // Insufficient buffer length\r
+    //\r
+    *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetPrimaryLanguages (\r
+  IN  EFI_HII_PROTOCOL      *This,\r
+  IN  EFI_HII_HANDLE        Handle,\r
+  OUT EFI_STRING            *LanguageString\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  This function allows a program to determine what the primary languages that are supported on a given handle.\r
+\r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINTN                     Count;\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  EFI_HII_STRING_PACK       *Location;\r
+  UINT32                    Length;\r
+  RELOFST                   Token;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  PackageInstance = NULL;\r
+  //\r
+  // Find matching handle in the handle database. Then get the package instance.\r
+  //\r
+  for (HandleDatabase = HiiData->DatabaseHead;\r
+       HandleDatabase != NULL;\r
+       HandleDatabase = HandleDatabase->NextHandleDatabase\r
+      ) {\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
+  } else {\r
+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
+  }\r
+\r
+  Location = StringPack;\r
+  //\r
+  // Remember that the string packages are formed into contiguous blocks of language data.\r
+  //\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (Count = 0; Length != 0; Count = Count + 3) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  }\r
+\r
+  *LanguageString = AllocateZeroPool (2 * (Count + 1));\r
+\r
+  ASSERT (*LanguageString);\r
+\r
+  StringPack = (EFI_HII_STRING_PACK *) Location;\r
+\r
+  //\r
+  // Copy the 6 bytes to LanguageString - keep concatenating it.  Shouldn't we just store uint8's since the ISO\r
+  // standard defines the lettering as all US English characters anyway?  Save a few bytes.\r
+  //\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (Count = 0; Length != 0; Count = Count + 3) {\r
+    CopyMem (&Token, &StringPack->LanguageNameString, sizeof (RELOFST));\r
+    CopyMem (*LanguageString + Count, (VOID *) ((CHAR8 *) (StringPack) + Token), 6);\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetSecondaryLanguages (\r
+  IN  EFI_HII_PROTOCOL      *This,\r
+  IN  EFI_HII_HANDLE        Handle,\r
+  IN  CHAR16                *PrimaryLanguage,\r
+  OUT EFI_STRING            *LanguageString\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  This function allows a program to determine which secondary languages are supported \r
+  on a given handle for a given primary language.\r
+\r
+  Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINTN                     Count;\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  RELOFST                   Token;\r
+  UINT32                    Length;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData = EFI_HII_DATA_FROM_THIS (This);\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  PackageInstance = NULL;\r
+  for (HandleDatabase = HiiData->DatabaseHead;\r
+       HandleDatabase != NULL;\r
+       HandleDatabase = HandleDatabase->NextHandleDatabase\r
+      ) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
+  } else {\r
+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
+  }\r
+\r
+  //\r
+  // Remember that the string packages are formed into contiguous blocks of language data.\r
+  //\r
+  for (; StringPack->Header.Length != 0;) {\r
+    //\r
+    // Find the PrimaryLanguage being requested\r
+    //\r
+    Token = StringPack->LanguageNameString;\r
+    if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + Token), PrimaryLanguage, 3) == 0) {\r
+      //\r
+      // Now that we found the primary, the secondary languages will follow immediately\r
+      // or the next character is a NULL if there are no secondary languages.  We determine\r
+      // the number by getting the stringsize based on the StringPack origination + the LanguageNameString\r
+      // offset + 6 (which is the size of the first 3 letter ISO primary language name).  If we get 2, there\r
+      // are no secondary languages (2 = null-terminator).\r
+      //\r
+      Count           = StrSize ((VOID *) ((CHAR8 *) (StringPack) + Token + 6));\r
+\r
+      *LanguageString = AllocateZeroPool (2 * (Count + 1));\r
+\r
+      ASSERT (*LanguageString);\r
+\r
+      CopyMem (*LanguageString, (VOID *) ((CHAR8 *) (StringPack) + Token + 6), Count);\r
+      break;\r
+    }\r
+\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r