]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.c
Bug fixes for FrameworkHiiToUefiHiiThunk;
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Strings.c
index 0054ee43fc38dc64591fa0836a77e0588f0db1bd..318f9ee1be4a006636b83a35b46fdfc76a216c1b 100644 (file)
@@ -1,7 +1,6 @@
 /**@file\r
-\r
-  This file contains the keyboard processing code to the HII database.\r
-\r
+  This file implements the protocol functions related to string package.\r
+  \r
 Copyright (c) 2006 - 2008, 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
@@ -40,122 +39,202 @@ Returns:
 }\r
 \r
 EFI_STATUS\r
-GetTagGuidByFrameworkHiiHandle (\r
-  IN  CONST EFI_HII_THUNK_PRIVATE_DATA  *Private,\r
-  IN        FRAMEWORK_EFI_HII_HANDLE    FrameworkHiiHandle,\r
+GetTagGuidByFwHiiHandle (\r
+  IN  CONST HII_THUNK_PRIVATE_DATA      *Private,\r
+  IN        FRAMEWORK_EFI_HII_HANDLE    FwHiiHandle,\r
   OUT       EFI_GUID                    *TagGuid\r
   )\r
 {\r
-  LIST_ENTRY                                *ListEntry;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY  *HandleMapEntry;\r
+  LIST_ENTRY                                *Link;\r
+  HII_THUNK_CONTEXT                          *ThunkContext;\r
 \r
   ASSERT (TagGuid != NULL);\r
 \r
-  for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
-       ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
-       ListEntry = ListEntry->ForwardLink\r
-       ) {\r
+  Link = GetFirstNode (&Private->ThunkContextListHead);\r
+  while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
 \r
-    HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+    ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
 \r
-    if (FrameworkHiiHandle == HandleMapEntry->FrameworkHiiHandle) {\r
-      CopyGuid (TagGuid, &HandleMapEntry->TagGuid);\r
+    if (FwHiiHandle == ThunkContext->FwHiiHandle) {\r
+      CopyGuid (TagGuid, &ThunkContext->TagGuid);\r
       return EFI_SUCCESS;\r
     }\r
+\r
+    Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
   }\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
+\r
+\r
 EFI_STATUS\r
-HiiThunkNewStringForAllStringPackages (\r
-  IN  CONST EFI_HII_THUNK_PRIVATE_DATA  *Private,\r
-  OUT CONST EFI_GUID                    *TagGuid,\r
-  IN        CHAR16                     *Language,\r
-  IN OUT    STRING_REF                 *Reference,\r
-  IN        CHAR16                     *NewString\r
+EFIAPI\r
+HiiNewString (\r
+  IN     EFI_HII_PROTOCOL           *This,\r
+  IN     CHAR16                     *Language,\r
+  IN     FRAMEWORK_EFI_HII_HANDLE   Handle,\r
+  IN OUT STRING_REF                 *Reference,\r
+  IN     CHAR16                     *NewString\r
   )\r
+/*++\r
+\r
+Routine Description:\r
+  This function allows a new String to be added to an already existing String Package.\r
+  We will make a buffer the size of the package + StrSize of the new string.  We will\r
+  copy the string package that first gets changed and the following language packages until\r
+  we encounter the NULL string package.  All this time we will ensure that the offsets have\r
+  been adjusted.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
 {\r
   EFI_STATUS                                Status;\r
-  LIST_ENTRY                                *ListEntry;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY  *HandleMapEntry;\r
-  EFI_STRING_ID                             StringId1;\r
-  EFI_STRING_ID                             StringId2;\r
-  CHAR8                                     *UefiStringProtocolLanguage;\r
+  HII_THUNK_PRIVATE_DATA                    *Private;\r
+  EFI_GUID                                  TagGuid;\r
+  LIST_ENTRY                                *Link;\r
+  HII_THUNK_CONTEXT                          *ThunkContext;\r
+  EFI_STRING_ID                             StringId;\r
+  EFI_STRING_ID                             LastStringId;\r
+  CHAR8                                     *AsciiLanguage;\r
   BOOLEAN                                   Found;\r
 \r
-  ASSERT (TagGuid != NULL);\r
-\r
-  StringId1 = (EFI_STRING_ID) 0;\r
-  StringId2 = (EFI_STRING_ID) 0;\r
-  Found = FALSE;\r
-\r
   //\r
-  // BugBug: We will handle the case that Language is not NULL later.\r
+  // BugBug: Conver the language to 3066.\r
   //\r
-  ASSERT (Language == NULL);\r
-  \r
-  //if (Language == NULL) {\r
-    UefiStringProtocolLanguage = NULL;\r
-  //}\r
 \r
-  for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
-       ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
-       ListEntry = ListEntry->ForwardLink\r
-       ) {\r
+  LastStringId      = (EFI_STRING_ID) 0;\r
+  StringId          = (EFI_STRING_ID) 0;\r
+  Found             = FALSE;\r
+  AsciiLanguage     = NULL;\r
+\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-    HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+  Status = GetTagGuidByFwHiiHandle (Private, Handle, &TagGuid);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-    if (CompareGuid (TagGuid, &HandleMapEntry->TagGuid)) {\r
+  if (Language != NULL) {\r
+    AsciiLanguage = AllocateZeroPool (StrLen (Language) + 1);\r
+    UnicodeStrToAsciiStr (Language, AsciiLanguage);\r
+  }\r
+\r
+  Link = GetFirstNode (&Private->ThunkContextListHead);\r
+  while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+    ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+    if (CompareGuid (&TagGuid, &ThunkContext->TagGuid)) {\r
       Found = TRUE;\r
       if (*Reference == 0) {\r
-        Status = HiiLibNewString (HandleMapEntry->UefiHiiHandle, &StringId2, NewString);\r
+        //\r
+        // Create a new string token.\r
+        //\r
+        if (AsciiLanguage == NULL) {\r
+          //\r
+          // For all languages in the package list.\r
+          //\r
+          Status = HiiLibNewString (ThunkContext->UefiHiiHandle, &StringId, NewString);\r
+        } else {\r
+          //\r
+          // For specified language.\r
+          //\r
+          Status = mHiiStringProtocol->NewString (\r
+                                         mHiiStringProtocol,\r
+                                         ThunkContext->UefiHiiHandle,\r
+                                         &StringId,\r
+                                         AsciiLanguage,\r
+                                         NULL,\r
+                                         NewString,\r
+                                         NULL\r
+                                         );\r
+        }\r
       } else {\r
-        Status = HiiLibSetString (HandleMapEntry->UefiHiiHandle, *Reference, NewString);\r
+        //\r
+        // Update the existing string token.\r
+        //\r
+        if (AsciiLanguage == NULL) {\r
+          //\r
+          // For all languages in the package list.\r
+          //\r
+          Status = HiiLibSetString (ThunkContext->UefiHiiHandle, *Reference, NewString);\r
+        } else {\r
+          //\r
+          // For specified language.\r
+          //\r
+          Status = mHiiStringProtocol->SetString (\r
+                                       mHiiStringProtocol,\r
+                                       ThunkContext->UefiHiiHandle,\r
+                                       *Reference,\r
+                                       AsciiLanguage,\r
+                                       NewString,\r
+                                       NULL\r
+                                       );\r
+        }\r
       }\r
       if (EFI_ERROR (Status)) {\r
-        return Status;\r
+        //\r
+        // Only EFI_INVALID_PARAMETER is defined in HII 0.92 specification.\r
+        //\r
+        return EFI_INVALID_PARAMETER;\r
       }\r
+\r
       if (*Reference == 0) {\r
-        if (StringId1 == (EFI_STRING_ID) 0) {\r
-          StringId1 = StringId2;\r
+        //\r
+        // When creating new string token, make sure all created token is the same\r
+        // for all string packages registered using FW HII interface.\r
+        //\r
+        if (LastStringId == (EFI_STRING_ID) 0) {\r
+          LastStringId = StringId;\r
         } else {\r
-          if (StringId1 != StringId2) {\r
+          if (LastStringId != StringId) {\r
             ASSERT(FALSE);\r
             return EFI_INVALID_PARAMETER;\r
           }\r
         }\r
       }\r
     }\r
+\r
+    Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
   }\r
 \r
   if (Found) {\r
-    *Reference = StringId1;\r
+    if (*Reference == 0) {\r
+      *Reference = StringId;\r
+    }\r
     Status = EFI_SUCCESS;\r
   } else {\r
+    DEBUG((EFI_D_ERROR, "Thunk HiiNewString fails to find the String Packages to update\n"));\r
+    //\r
+    // BUGBUG: Remove ths ASSERT when development is done.\r
+    //\r
+    ASSERT (FALSE);\r
     Status = EFI_NOT_FOUND;\r
   }\r
   \r
+  //\r
+  // For UNI file, some String may not be defined for a language. This has been true for a lot of platform code.\r
+  // For this case, EFI_NOT_FOUND will be returned. To allow the old code to be run without porting, we don't assert \r
+  // on EFI_NOT_FOUND. The missing Strings will be shown if user select a differnt languages other than the default\r
+  // English language for the platform.\r
+  //\r
+  ASSERT_EFI_ERROR (EFI_ERROR (Status) && Status != EFI_NOT_FOUND);  \r
+\r
   return Status;\r
 }\r
 \r
 EFI_STATUS\r
 EFIAPI\r
-HiiNewString (\r
-  IN     EFI_HII_PROTOCOL           *This,\r
-  IN     CHAR16                     *Language,\r
-  IN     FRAMEWORK_EFI_HII_HANDLE   Handle,\r
-  IN OUT STRING_REF                 *Reference,\r
-  IN     CHAR16                     *NewString\r
+HiiResetStrings (\r
+  IN     EFI_HII_PROTOCOL   *This,\r
+  IN     FRAMEWORK_EFI_HII_HANDLE      Handle\r
   )\r
 /*++\r
 \r
 Routine Description:\r
-  This function allows a new String to be added to an already existing String Package.\r
-  We will make a buffer the size of the package + StrSize of the new string.  We will\r
-  copy the string package that first gets changed and the following language packages until\r
-  we encounter the NULL string package.  All this time we will ensure that the offsets have\r
-  been adjusted.\r
+\r
+    This function removes any new strings that were added after the initial string export for this handle.\r
 \r
 Arguments:\r
 \r
@@ -163,41 +242,33 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS                 Status;\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
-  EFI_GUID                   TagGuid;\r
-\r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
-\r
-  Status = GetTagGuidByFrameworkHiiHandle (Private, Handle, &TagGuid);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = HiiThunkNewStringForAllStringPackages (Private, &TagGuid, Language, Reference, NewString);\r
-  ASSERT_EFI_ERROR (Status);  \r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-HiiResetStrings (\r
-  IN     EFI_HII_PROTOCOL   *This,\r
-  IN     FRAMEWORK_EFI_HII_HANDLE      Handle\r
-  )\r
-/*++\r
+typedef struct {\r
+  CHAR8 *Iso639;\r
+  CHAR8 *Rfc3066;\r
+} ISO639TORFC3066MAP;\r
 \r
-Routine Description:\r
-\r
-    This function removes any new strings that were added after the initial string export for this handle.\r
+ISO639TORFC3066MAP Iso639ToRfc3066Map [] = {\r
+    {"eng", "en-US"},\r
+    {"fra", "fr-FR"},\r
+};\r
 \r
-Arguments:\r
+CHAR8 *\r
+ConvertIso639ToRfc3066 (\r
+  CHAR8 *Iso638Lang\r
+  )\r
+{\r
+  UINTN Index;\r
 \r
-Returns:\r
+  for (Index = 0; Index < sizeof (Iso639ToRfc3066Map) / sizeof (Iso639ToRfc3066Map[0]); Index++) {\r
+    if (AsciiStrnCmp (Iso638Lang, Iso639ToRfc3066Map[Index].Iso639, AsciiStrSize (Iso638Lang)) == 0) {\r
+      return Iso639ToRfc3066Map[Index].Rfc3066;\r
+    }\r
+  }\r
 \r
---*/\r
-{\r
-  ASSERT (FALSE);\r
-  return EFI_UNSUPPORTED;\r
+  return (CHAR8 *) NULL;\r
 }\r
 \r
 EFI_STATUS\r
@@ -239,12 +310,13 @@ Returns:
 \r
 --*/\r
 {\r
-  LIST_ENTRY                                *ListEntry;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY  *HandleMapEntry;\r
+  LIST_ENTRY                                *Link;\r
+  HII_THUNK_CONTEXT  *ThunkContext;\r
   CHAR8                                     *AsciiLanguage;\r
-  EFI_HII_THUNK_PRIVATE_DATA                *Private;\r
+  HII_THUNK_PRIVATE_DATA                *Private;\r
+  CHAR8                                     *Rfc3066AsciiLanguage;\r
 \r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
   if (LanguageString == NULL) {\r
     AsciiLanguage = NULL;\r
@@ -254,23 +326,39 @@ Returns:
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     UnicodeStrToAsciiStr  (LanguageString, AsciiLanguage);\r
+\r
+    Rfc3066AsciiLanguage = ConvertIso639ToRfc3066 (AsciiLanguage);\r
+\r
+    //\r
+    // If Rfc3066AsciiLanguage is NULL, more language mapping must be added to \r
+    // Iso639ToRfc3066Map.\r
+    //\r
+    ASSERT (Rfc3066AsciiLanguage != NULL);\r
+    //\r
+    // Caller of Framework HII Interface uses the Language Identification String defined \r
+    // in Iso639. So map it to the Language Identifier defined in RFC3066.\r
+    //\r
+    if (Rfc3066AsciiLanguage != NULL) {\r
+      FreePool (AsciiLanguage);\r
+      AsciiLanguage = AllocateCopyPool (AsciiStrSize (Rfc3066AsciiLanguage), Rfc3066AsciiLanguage);\r
+    }\r
+    \r
   }\r
 \r
-  for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
-       ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
-       ListEntry = ListEntry->ForwardLink\r
-       ) {\r
+  Link = GetFirstNode (&Private->ThunkContextListHead);\r
 \r
-    HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+  while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
 \r
-    if (Handle == HandleMapEntry->FrameworkHiiHandle) {\r
+    ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+    if (Handle == ThunkContext->FwHiiHandle) {\r
       if (AsciiLanguage == NULL) {\r
-        return HiiLibGetString (HandleMapEntry->UefiHiiHandle, Token, StringBuffer, BufferLengthTemp);\r
+        return HiiLibGetString (ThunkContext->UefiHiiHandle, Token, StringBuffer, BufferLengthTemp);\r
       } else {\r
-        return mUefiStringProtocol->GetString (\r
-                                     mUefiStringProtocol,\r
+        return mHiiStringProtocol->GetString (\r
+                                     mHiiStringProtocol,\r
                                      AsciiLanguage,\r
-                                     HandleMapEntry->UefiHiiHandle,\r
+                                     ThunkContext->UefiHiiHandle,\r
                                      Token,\r
                                      StringBuffer,\r
                                      BufferLengthTemp,\r
@@ -278,6 +366,9 @@ Returns:
                                      );\r
       }\r
     }\r
+    \r
+    \r
+    Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
   }\r
 \r
   return EFI_NOT_FOUND;\r
@@ -313,3 +404,4 @@ Returns:
   return EFI_UNSUPPORTED;\r
 }\r
 \r
+\r