]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiDriverLib / EfiDriverLib.c
index 3de6c59dc28810c8bea1f9e04dc60b67b420cf17..ef10d41702d02c56c86b2c8f735c330e14c55232 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
 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
@@ -21,6 +21,18 @@ Abstract:
 \r
 #include "Tiano.h"\r
 #include "EfiDriverLib.h"\r
+#include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)\r
+\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+\r
+VOID\r
+EFIAPI\r
+OnStatusCodeInstall (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  );\r
+\r
+#endif\r
 \r
 //\r
 // Global Interface for Debug Mask Protocol\r
@@ -50,6 +62,10 @@ Returns:
 \r
 --*/\r
 {\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+  VOID *Registration;\r
+#endif\r
+  \r
   gST = SystemTable;\r
 \r
   ASSERT (gST != NULL);\r
@@ -70,6 +86,21 @@ Returns:
         (VOID *) &gDebugMaskInterface\r
         );\r
 #endif\r
+\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+  //\r
+  // Register EFI_STATUS_CODE_PROTOCOL notify function\r
+  //\r
+  EfiLibCreateProtocolNotifyEvent (\r
+    &gEfiStatusCodeRuntimeProtocolGuid,\r
+    EFI_TPL_CALLBACK,\r
+    OnStatusCodeInstall,\r
+    NULL,\r
+    &Registration\r
+    );\r
+\r
+#endif\r
+\r
   //\r
   // Should be at EFI_D_INFO, but lets us know things are running\r
   //\r
@@ -78,55 +109,107 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+STATIC\r
+BOOLEAN\r
+IsIso639LanguageCode (\r
+  IN CHAR8                *Languages\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Tests whether a language code has format of ISO639-2.\r
+\r
+Arguments:\r
+\r
+  Languages - The language code to be tested.\r
+\r
+Returns:\r
+\r
+  TRUE      - Language code format is ISO 639-2.\r
+  FALSE     - Language code format is not ISO 639-2.\r
+\r
+--*/\r
+{\r
+  UINTN  Index;\r
+\r
+  //\r
+  // Find out format of Languages\r
+  //\r
+  for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';' && Languages[Index] != '-'; Index++);\r
+  if (Languages[Index] != 0) {\r
+    //\r
+    // RFC4646 language code\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // No ';' and '-', it's either ISO639-2 code (list) or single RFC4646 code\r
+  //\r
+  if (Index == 2) {\r
+    //\r
+    // Single RFC4646 language code without country code, e.g. "en"\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Languages in format of ISO639-2\r
+  //\r
+  return TRUE;\r
+}\r
+\r
 BOOLEAN\r
 EfiLibCompareLanguage (\r
-  IN  CHAR8  *Language1,\r
-  IN  CHAR8  *Language2\r
+  IN  CHAR8               *Language1,\r
+  IN  CHAR8               *Language2\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Compare whether two names of languages are identical.\r
+  Compare the first language instance of two language codes, either could be a\r
+  single language code or a language code list. This function assume Language1\r
+  and Language2 has the same language code format, i.e. either ISO639-2 or RFC4646.\r
 \r
 Arguments:\r
 \r
-  Language1 - Name of language 1\r
-  Language2 - Name of language 2\r
+  Language1 - The first language code to be tested.\r
+  Language2 - The second language code to be tested.\r
 \r
 Returns:\r
 \r
-  TRUE      - same\r
-  FALSE     - not same\r
+  TRUE      - Language code match.\r
+  FALSE     - Language code mismatch.\r
 \r
 --*/\r
 {\r
   UINTN Index;\r
 \r
-#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
-  for (Index = 0; (Language1[Index] != 0) && (Language2[Index] != 0); Index++) {\r
-    if (Language1[Index] != Language2[Index]) {\r
-      return FALSE;\r
-    }\r
+  //\r
+  // Compare first two bytes of language tag\r
+  //\r
+  if ((Language1[0] != Language2[0]) || (Language1[1] != Language2[1])) {\r
+    return FALSE;\r
   }\r
 \r
-  if (((Language1[Index] == 0) && (Language2[Index] == 0))   || \r
-         ((Language1[Index] == 0) && (Language2[Index] != ';')) ||\r
-         ((Language1[Index] == ';') && (Language2[Index] != 0)) ||\r
-         ((Language1[Index] == ';') && (Language2[Index] != ';'))) {\r
-    return TRUE;\r
+  if (IsIso639LanguageCode (Language1)) {\r
+    //\r
+    // ISO639-2 language code, compare the third byte of language tag\r
+    //\r
+    return (BOOLEAN) ((Language1[2] == Language2[2]) ? TRUE : FALSE);\r
   }\r
 \r
-  return FALSE;\r
-#else\r
-  for (Index = 0; Index < 3; Index++) {\r
-    if (Language1[Index] != Language2[Index]) {\r
-      return FALSE;\r
-    }\r
+  //\r
+  // RFC4646 language code\r
+  //\r
+  for (Index = 0; Language1[Index] != 0 && Language1[Index] != ';'; Index++);\r
+  if ((EfiAsciiStrnCmp (Language1, Language2, Index) == 0) && (Language2[Index] == 0 || Language2[Index] == ';')) {\r
+    return TRUE;\r
   }\r
 \r
-  return TRUE;\r
-#endif\r
+  return FALSE;\r
 }\r
 \r
 STATIC\r
@@ -134,19 +217,39 @@ CHAR8 *
 NextSupportedLanguage (\r
   IN CHAR8                *Languages\r
   )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Step to next language code of a language code list.\r
+\r
+Arguments:\r
+\r
+  Languages - The language code list to traverse.\r
+\r
+Returns:\r
+\r
+  Pointer to next language code or NULL terminator if it's the last one.\r
+\r
+--*/\r
 {\r
-#ifdef LANGUAGE_RFC_3066   // LANGUAGE_RFC_3066\r
-  for (; (*Languages != 0) && (*Languages != ';'); Languages++)\r
-    ;\r
+  UINTN    Index;\r
 \r
-  if (*Languages == ';') {\r
-    Languages++;\r
+  if (IsIso639LanguageCode (Languages)) {\r
+    //\r
+    // ISO639-2 language code\r
+    //\r
+    return (Languages + 3);\r
   }\r
 \r
-  return Languages;\r
-#else                      // LANGUAGE_ISO_639_2\r
-  return (Languages + 3);\r
-#endif\r
+  //\r
+  // Search in RFC4646 language code list\r
+  //\r
+  for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';'; Index++);\r
+  if (Languages[Index] == ';') {\r
+    Index++;\r
+  }\r
+  return (Languages + Index);\r
 }\r
 \r
 EFI_STATUS\r
@@ -217,7 +320,7 @@ Returns:
       return EFI_UNSUPPORTED;\r
     }\r
 \r
-    SupportedLanguages = NextSupportedLanguage(SupportedLanguages);\r
+    SupportedLanguages = NextSupportedLanguage (SupportedLanguages);\r
   }\r
 \r
   return EFI_UNSUPPORTED;\r
@@ -326,7 +429,7 @@ Returns:
       //\r
       // Allocate space for a copy of the Language specifier\r
       //\r
-      NewUnicodeStringTable[NumberOfEntries].Language = EfiLibAllocateCopyPool (EfiAsciiStrLen(Language) + 1, Language);\r
+      NewUnicodeStringTable[NumberOfEntries].Language = EfiLibAllocateCopyPool (EfiAsciiStrSize (Language), Language);\r
       if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {\r
         gBS->FreePool (NewUnicodeStringTable);\r
         return EFI_OUT_OF_RESOURCES;\r
@@ -372,7 +475,7 @@ Returns:
       return EFI_SUCCESS;\r
     }\r
 \r
-    SupportedLanguages = NextSupportedLanguage(SupportedLanguages);\r
+    SupportedLanguages = NextSupportedLanguage (SupportedLanguages);\r
   }\r
 \r
   return EFI_UNSUPPORTED;\r