mirror of https://github.com/acidanthera/audk.git
Fix AutoUpdateLangVariable() logic to handle the case PlatformLang/Lang is set before PlatformLangCodes/LangCodes.
Pre-allocate pool for runtime phase. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11087 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
6c4986de2d
commit
1623ce4aad
|
@ -395,7 +395,6 @@ UpdateVariableInfo (
|
||||||
|
|
||||||
**/
|
**/
|
||||||
UINTN
|
UINTN
|
||||||
EFIAPI
|
|
||||||
GetIndexFromSupportedLangCodes(
|
GetIndexFromSupportedLangCodes(
|
||||||
IN CHAR8 *SupportedLang,
|
IN CHAR8 *SupportedLang,
|
||||||
IN CHAR8 *Lang,
|
IN CHAR8 *Lang,
|
||||||
|
@ -403,13 +402,11 @@ GetIndexFromSupportedLangCodes(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT32 CompareLength;
|
UINTN CompareLength;
|
||||||
CHAR8 *Supported;
|
UINTN LanguageLength;
|
||||||
|
|
||||||
Index = 0;
|
|
||||||
Supported = SupportedLang;
|
|
||||||
if (Iso639Language) {
|
if (Iso639Language) {
|
||||||
CompareLength = 3;
|
CompareLength = ISO_639_2_ENTRY_SIZE;
|
||||||
for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) {
|
for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) {
|
||||||
if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) {
|
if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) {
|
||||||
//
|
//
|
||||||
|
@ -425,20 +422,26 @@ GetIndexFromSupportedLangCodes(
|
||||||
//
|
//
|
||||||
// Compare RFC4646 language code
|
// Compare RFC4646 language code
|
||||||
//
|
//
|
||||||
while (*Supported != '\0') {
|
Index = 0;
|
||||||
|
for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++);
|
||||||
|
|
||||||
|
for (Index = 0; *SupportedLang != '\0'; Index++, SupportedLang += CompareLength) {
|
||||||
//
|
//
|
||||||
// take semicolon as delimitation, sequentially traverse supported language codes.
|
// Skip ';' characters in SupportedLang
|
||||||
//
|
//
|
||||||
for (CompareLength = 0; *Supported != ';' && *Supported != '\0'; CompareLength++) {
|
for (; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++);
|
||||||
Supported++;
|
//
|
||||||
}
|
// Determine the length of the next language code in SupportedLang
|
||||||
if (AsciiStrnCmp (Lang, Supported - CompareLength, CompareLength) == 0) {
|
//
|
||||||
|
for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++);
|
||||||
|
|
||||||
|
if ((CompareLength == LanguageLength) &&
|
||||||
|
(AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0)) {
|
||||||
//
|
//
|
||||||
// Successfully find the index of Lang string in SupportedLang string.
|
// Successfully find the index of Lang string in SupportedLang string.
|
||||||
//
|
//
|
||||||
return Index;
|
return Index;
|
||||||
}
|
}
|
||||||
Index++;
|
|
||||||
}
|
}
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -472,7 +475,6 @@ GetIndexFromSupportedLangCodes(
|
||||||
|
|
||||||
**/
|
**/
|
||||||
CHAR8 *
|
CHAR8 *
|
||||||
EFIAPI
|
|
||||||
GetLangFromSupportedLangCodes (
|
GetLangFromSupportedLangCodes (
|
||||||
IN CHAR8 *SupportedLang,
|
IN CHAR8 *SupportedLang,
|
||||||
IN UINTN Index,
|
IN UINTN Index,
|
||||||
|
@ -480,7 +482,7 @@ GetLangFromSupportedLangCodes (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN SubIndex;
|
UINTN SubIndex;
|
||||||
UINT32 CompareLength;
|
UINTN CompareLength;
|
||||||
CHAR8 *Supported;
|
CHAR8 *Supported;
|
||||||
|
|
||||||
SubIndex = 0;
|
SubIndex = 0;
|
||||||
|
@ -491,8 +493,8 @@ GetLangFromSupportedLangCodes (
|
||||||
// As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.
|
// As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.
|
||||||
// In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.
|
// In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.
|
||||||
//
|
//
|
||||||
CompareLength = 3;
|
CompareLength = ISO_639_2_ENTRY_SIZE;
|
||||||
SetMem (mVariableModuleGlobal->Lang, sizeof(mVariableModuleGlobal->Lang), 0);
|
mVariableModuleGlobal->Lang[CompareLength] = '\0';
|
||||||
return CopyMem (mVariableModuleGlobal->Lang, SupportedLang + Index * CompareLength, CompareLength);
|
return CopyMem (mVariableModuleGlobal->Lang, SupportedLang + Index * CompareLength, CompareLength);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -517,7 +519,7 @@ GetLangFromSupportedLangCodes (
|
||||||
// As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.
|
// As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.
|
||||||
// In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.
|
// In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.
|
||||||
//
|
//
|
||||||
SetMem (mVariableModuleGlobal->PlatformLang, sizeof (mVariableModuleGlobal->PlatformLang), 0);
|
mVariableModuleGlobal->PlatformLang[CompareLength] = '\0';
|
||||||
return CopyMem (mVariableModuleGlobal->PlatformLang, Supported - CompareLength, CompareLength);
|
return CopyMem (mVariableModuleGlobal->PlatformLang, Supported - CompareLength, CompareLength);
|
||||||
}
|
}
|
||||||
SubIndex++;
|
SubIndex++;
|
||||||
|
@ -525,6 +527,136 @@ GetLangFromSupportedLangCodes (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a pointer to an allocated buffer that contains the best matching language
|
||||||
|
from a set of supported languages.
|
||||||
|
|
||||||
|
This function supports both ISO 639-2 and RFC 4646 language codes, but language
|
||||||
|
code types may not be mixed in a single call to this function. This function
|
||||||
|
supports a variable argument list that allows the caller to pass in a prioritized
|
||||||
|
list of language codes to test against all the language codes in SupportedLanguages.
|
||||||
|
|
||||||
|
If SupportedLanguages is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
|
||||||
|
contains a set of language codes in the format
|
||||||
|
specified by Iso639Language.
|
||||||
|
@param[in] Iso639Language If TRUE, then all language codes are assumed to be
|
||||||
|
in ISO 639-2 format. If FALSE, then all language
|
||||||
|
codes are assumed to be in RFC 4646 language format
|
||||||
|
@param[in] ... A variable argument list that contains pointers to
|
||||||
|
Null-terminated ASCII strings that contain one or more
|
||||||
|
language codes in the format specified by Iso639Language.
|
||||||
|
The first language code from each of these language
|
||||||
|
code lists is used to determine if it is an exact or
|
||||||
|
close match to any of the language codes in
|
||||||
|
SupportedLanguages. Close matches only apply to RFC 4646
|
||||||
|
language codes, and the matching algorithm from RFC 4647
|
||||||
|
is used to determine if a close match is present. If
|
||||||
|
an exact or close match is found, then the matching
|
||||||
|
language code from SupportedLanguages is returned. If
|
||||||
|
no matches are found, then the next variable argument
|
||||||
|
parameter is evaluated. The variable argument list
|
||||||
|
is terminated by a NULL.
|
||||||
|
|
||||||
|
@retval NULL The best matching language could not be found in SupportedLanguages.
|
||||||
|
@retval NULL There are not enough resources available to return the best matching
|
||||||
|
language.
|
||||||
|
@retval Other A pointer to a Null-terminated ASCII string that is the best matching
|
||||||
|
language in SupportedLanguages.
|
||||||
|
|
||||||
|
**/
|
||||||
|
CHAR8 *
|
||||||
|
VariableGetBestLanguage (
|
||||||
|
IN CONST CHAR8 *SupportedLanguages,
|
||||||
|
IN BOOLEAN Iso639Language,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
VA_LIST Args;
|
||||||
|
CHAR8 *Language;
|
||||||
|
UINTN CompareLength;
|
||||||
|
UINTN LanguageLength;
|
||||||
|
CONST CHAR8 *Supported;
|
||||||
|
CHAR8 *Buffer;
|
||||||
|
|
||||||
|
ASSERT (SupportedLanguages != NULL);
|
||||||
|
|
||||||
|
VA_START (Args, Iso639Language);
|
||||||
|
while ((Language = VA_ARG (Args, CHAR8 *)) != NULL) {
|
||||||
|
//
|
||||||
|
// Default to ISO 639-2 mode
|
||||||
|
//
|
||||||
|
CompareLength = 3;
|
||||||
|
LanguageLength = MIN (3, AsciiStrLen (Language));
|
||||||
|
|
||||||
|
//
|
||||||
|
// If in RFC 4646 mode, then determine the length of the first RFC 4646 language code in Language
|
||||||
|
//
|
||||||
|
if (!Iso639Language) {
|
||||||
|
for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trim back the length of Language used until it is empty
|
||||||
|
//
|
||||||
|
while (LanguageLength > 0) {
|
||||||
|
//
|
||||||
|
// Loop through all language codes in SupportedLanguages
|
||||||
|
//
|
||||||
|
for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
|
||||||
|
//
|
||||||
|
// In RFC 4646 mode, then Loop through all language codes in SupportedLanguages
|
||||||
|
//
|
||||||
|
if (!Iso639Language) {
|
||||||
|
//
|
||||||
|
// Skip ';' characters in Supported
|
||||||
|
//
|
||||||
|
for (; *Supported != '\0' && *Supported == ';'; Supported++);
|
||||||
|
//
|
||||||
|
// Determine the length of the next language code in Supported
|
||||||
|
//
|
||||||
|
for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
|
||||||
|
//
|
||||||
|
// If Language is longer than the Supported, then skip to the next language
|
||||||
|
//
|
||||||
|
if (LanguageLength > CompareLength) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// See if the first LanguageLength characters in Supported match Language
|
||||||
|
//
|
||||||
|
if (AsciiStrnCmp (Supported, Language, LanguageLength) == 0) {
|
||||||
|
VA_END (Args);
|
||||||
|
|
||||||
|
Buffer = Iso639Language ? mVariableModuleGlobal->Lang : mVariableModuleGlobal->PlatformLang;
|
||||||
|
Buffer[CompareLength] = '\0';
|
||||||
|
return CopyMem (Buffer, Supported, CompareLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Iso639Language) {
|
||||||
|
//
|
||||||
|
// If ISO 639 mode, then each language can only be tested once
|
||||||
|
//
|
||||||
|
LanguageLength = 0;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// If RFC 4646 mode, then trim Language from the right to the next '-' character
|
||||||
|
//
|
||||||
|
for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VA_END (Args);
|
||||||
|
|
||||||
|
//
|
||||||
|
// No matches were found
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
|
Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
|
||||||
|
|
||||||
|
@ -539,101 +671,186 @@ GetLangFromSupportedLangCodes (
|
||||||
|
|
||||||
@param[in] DataSize Size of data. 0 means delete
|
@param[in] DataSize Size of data. 0 means delete
|
||||||
|
|
||||||
@retval EFI_SUCCESS auto update operation is successful.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
VOID
|
||||||
EFIAPI
|
|
||||||
AutoUpdateLangVariable(
|
AutoUpdateLangVariable(
|
||||||
IN CHAR16 *VariableName,
|
IN CHAR16 *VariableName,
|
||||||
IN VOID *Data,
|
IN VOID *Data,
|
||||||
IN UINTN DataSize
|
IN UINTN DataSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
CHAR8 *BestPlatformLang;
|
CHAR8 *BestPlatformLang;
|
||||||
CHAR8 *BestLang;
|
CHAR8 *BestLang;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT32 Attributes;
|
UINT32 Attributes;
|
||||||
VARIABLE_POINTER_TRACK Variable;
|
VARIABLE_POINTER_TRACK Variable;
|
||||||
|
BOOLEAN SetLanguageCodes;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Don't do updates for delete operation
|
||||||
|
//
|
||||||
|
if (DataSize == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLanguageCodes = FALSE;
|
||||||
|
|
||||||
|
if (StrCmp (VariableName, L"PlatformLangCodes") == 0) {
|
||||||
|
//
|
||||||
|
// PlatformLangCodes is a volatile variable, so it can not be updated at runtime.
|
||||||
|
//
|
||||||
|
if (EfiAtRuntime ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLanguageCodes = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// According to UEFI spec, PlatformLangCodes is only set once in firmware initialization, and is read-only
|
||||||
|
// Therefore, in variable driver, only store the original value for other use.
|
||||||
|
//
|
||||||
|
if (mVariableModuleGlobal->PlatformLangCodes != NULL) {
|
||||||
|
FreePool (mVariableModuleGlobal->PlatformLangCodes);
|
||||||
|
}
|
||||||
|
mVariableModuleGlobal->PlatformLangCodes = AllocateRuntimeCopyPool (DataSize, Data);
|
||||||
|
ASSERT (mVariableModuleGlobal->PlatformLangCodes != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// PlatformLang holds a single language from PlatformLangCodes,
|
||||||
|
// so the size of PlatformLangCodes is enough for the PlatformLang.
|
||||||
|
//
|
||||||
|
if (mVariableModuleGlobal->PlatformLang != NULL) {
|
||||||
|
FreePool (mVariableModuleGlobal->PlatformLang);
|
||||||
|
}
|
||||||
|
mVariableModuleGlobal->PlatformLang = AllocateRuntimePool (DataSize);
|
||||||
|
ASSERT (mVariableModuleGlobal->PlatformLang != NULL);
|
||||||
|
|
||||||
|
} else if (StrCmp (VariableName, L"LangCodes") == 0) {
|
||||||
|
//
|
||||||
|
// LangCodes is a volatile variable, so it can not be updated at runtime.
|
||||||
|
//
|
||||||
|
if (EfiAtRuntime ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLanguageCodes = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// According to UEFI spec, LangCodes is only set once in firmware initialization, and is read-only
|
||||||
|
// Therefore, in variable driver, only store the original value for other use.
|
||||||
|
//
|
||||||
|
if (mVariableModuleGlobal->LangCodes != NULL) {
|
||||||
|
FreePool (mVariableModuleGlobal->LangCodes);
|
||||||
|
}
|
||||||
|
mVariableModuleGlobal->LangCodes = AllocateRuntimeCopyPool (DataSize, Data);
|
||||||
|
ASSERT (mVariableModuleGlobal->LangCodes != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SetLanguageCodes
|
||||||
|
&& (mVariableModuleGlobal->PlatformLangCodes != NULL)
|
||||||
|
&& (mVariableModuleGlobal->LangCodes != NULL)) {
|
||||||
|
//
|
||||||
|
// Update Lang if PlatformLang is already set
|
||||||
|
// Update PlatformLang if Lang is already set
|
||||||
|
//
|
||||||
|
Status = FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *) mVariableModuleGlobal);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Update Lang
|
||||||
|
//
|
||||||
|
VariableName = L"PlatformLang";
|
||||||
|
Data = GetVariableDataPtr (Variable.CurrPtr);
|
||||||
|
DataSize = Variable.CurrPtr->DataSize;
|
||||||
|
} else {
|
||||||
|
Status = FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *) mVariableModuleGlobal);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Update PlatformLang
|
||||||
|
//
|
||||||
|
VariableName = L"Lang";
|
||||||
|
Data = GetVariableDataPtr (Variable.CurrPtr);
|
||||||
|
DataSize = Variable.CurrPtr->DataSize;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Neither PlatformLang nor Lang is set, directly return
|
||||||
|
//
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// According to UEFI spec, "Lang" and "PlatformLang" is NV|BS|RT attributions.
|
// According to UEFI spec, "Lang" and "PlatformLang" is NV|BS|RT attributions.
|
||||||
//
|
//
|
||||||
Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
|
Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
|
||||||
|
|
||||||
if (StrCmp (VariableName, L"PlatformLangCodes") == 0) {
|
if (StrCmp (VariableName, L"PlatformLang") == 0) {
|
||||||
//
|
//
|
||||||
// According to UEFI spec, PlatformLangCodes is only set once in firmware initialization, and is read-only
|
// Update Lang when PlatformLangCodes/LangCodes were set.
|
||||||
// Therefore, in variable driver, only store the original value for other use.
|
|
||||||
//
|
//
|
||||||
AsciiStrnCpy (mVariableModuleGlobal->PlatformLangCodes, Data, DataSize);
|
if ((mVariableModuleGlobal->PlatformLangCodes != NULL) && (mVariableModuleGlobal->LangCodes != NULL)) {
|
||||||
} else if (StrCmp (VariableName, L"LangCodes") == 0) {
|
//
|
||||||
//
|
// When setting PlatformLang, firstly get most matched language string from supported language codes.
|
||||||
// According to UEFI spec, LangCodes is only set once in firmware initialization, and is read-only
|
//
|
||||||
// Therefore, in variable driver, only store the original value for other use.
|
BestPlatformLang = VariableGetBestLanguage (mVariableModuleGlobal->PlatformLangCodes, FALSE, Data, NULL);
|
||||||
//
|
if (BestPlatformLang != NULL) {
|
||||||
AsciiStrnCpy (mVariableModuleGlobal->LangCodes, Data, DataSize);
|
//
|
||||||
} else if ((StrCmp (VariableName, L"PlatformLang") == 0) && (DataSize != 0)) {
|
// Get the corresponding index in language codes.
|
||||||
ASSERT (AsciiStrLen (mVariableModuleGlobal->PlatformLangCodes) != 0);
|
//
|
||||||
|
Index = GetIndexFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, BestPlatformLang, FALSE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// When setting PlatformLang, firstly get most matched language string from supported language codes.
|
// Get the corresponding ISO639 language tag according to RFC4646 language tag.
|
||||||
//
|
//
|
||||||
BestPlatformLang = GetBestLanguage(mVariableModuleGlobal->PlatformLangCodes, FALSE, Data, NULL);
|
BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the corresponding index in language codes.
|
// Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
|
||||||
//
|
//
|
||||||
Index = GetIndexFromSupportedLangCodes(mVariableModuleGlobal->PlatformLangCodes, BestPlatformLang, FALSE);
|
FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);
|
||||||
|
|
||||||
//
|
Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang, ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);
|
||||||
// Get the corresponding ISO639 language tag according to RFC4646 language tag.
|
|
||||||
//
|
|
||||||
BestLang = GetLangFromSupportedLangCodes(mVariableModuleGlobal->LangCodes, Index, TRUE);
|
|
||||||
|
|
||||||
//
|
DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang));
|
||||||
// Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
|
|
||||||
//
|
|
||||||
FindVariable(L"Lang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);
|
|
||||||
|
|
||||||
Status = UpdateVariable(L"Lang", &gEfiGlobalVariableGuid,
|
ASSERT_EFI_ERROR(Status);
|
||||||
BestLang, ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);
|
}
|
||||||
|
}
|
||||||
DEBUG((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang));
|
|
||||||
|
|
||||||
ASSERT_EFI_ERROR(Status);
|
|
||||||
|
|
||||||
} else if ((StrCmp (VariableName, L"Lang") == 0) && (DataSize != 0)) {
|
|
||||||
ASSERT (AsciiStrLen (mVariableModuleGlobal->LangCodes) != 0);
|
|
||||||
|
|
||||||
|
} else if (StrCmp (VariableName, L"Lang") == 0) {
|
||||||
//
|
//
|
||||||
// When setting Lang, firstly get most matched language string from supported language codes.
|
// Update PlatformLang when PlatformLangCodes/LangCodes were set.
|
||||||
//
|
//
|
||||||
BestLang = GetBestLanguage(mVariableModuleGlobal->LangCodes, TRUE, Data, NULL);
|
if ((mVariableModuleGlobal->PlatformLangCodes != NULL) && (mVariableModuleGlobal->LangCodes != NULL)) {
|
||||||
|
//
|
||||||
|
// When setting Lang, firstly get most matched language string from supported language codes.
|
||||||
|
//
|
||||||
|
BestLang = VariableGetBestLanguage (mVariableModuleGlobal->LangCodes, TRUE, Data, NULL);
|
||||||
|
if (BestLang != NULL) {
|
||||||
|
//
|
||||||
|
// Get the corresponding index in language codes.
|
||||||
|
//
|
||||||
|
Index = GetIndexFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, BestLang, TRUE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the corresponding index in language codes.
|
// Get the corresponding RFC4646 language tag according to ISO639 language tag.
|
||||||
//
|
//
|
||||||
Index = GetIndexFromSupportedLangCodes(mVariableModuleGlobal->LangCodes, BestLang, TRUE);
|
BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the corresponding RFC4646 language tag according to ISO639 language tag.
|
// Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
|
||||||
//
|
//
|
||||||
BestPlatformLang = GetLangFromSupportedLangCodes(mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
|
FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);
|
||||||
|
|
||||||
//
|
Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang,
|
||||||
// Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
|
AsciiStrSize (BestPlatformLang), Attributes, &Variable);
|
||||||
//
|
|
||||||
FindVariable(L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);
|
|
||||||
|
|
||||||
Status = UpdateVariable(L"PlatformLang", &gEfiGlobalVariableGuid,
|
DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));
|
||||||
BestPlatformLang, AsciiStrSize (BestPlatformLang), Attributes, &Variable);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
DEBUG((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));
|
}
|
||||||
ASSERT_EFI_ERROR(Status);
|
|
||||||
}
|
}
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Implment all four UEFI runtime variable services and
|
Implment all four UEFI runtime variable services and
|
||||||
install variable architeture protocol.
|
install variable architeture protocol.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -178,6 +178,9 @@ VariableClassAddressChangeEvent (
|
||||||
IN VOID *Context
|
IN VOID *Context
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);
|
||||||
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);
|
||||||
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
|
||||||
EfiConvertPointer (
|
EfiConvertPointer (
|
||||||
0x0,
|
0x0,
|
||||||
(VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase
|
(VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
The internal header file includes the common header files, defines
|
The internal header file includes the common header files, defines
|
||||||
internal structure and functions used by EmuVariable module.
|
internal structure and functions used by EmuVariable module.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -38,6 +38,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
#define GET_VARIABLE_NAME_PTR(a) (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER))
|
#define GET_VARIABLE_NAME_PTR(a) (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER))
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The size of a 3 character ISO639 language code.
|
||||||
|
///
|
||||||
|
#define ISO_639_2_ENTRY_SIZE 3
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Physical,
|
Physical,
|
||||||
Virtual
|
Virtual
|
||||||
|
@ -62,10 +67,10 @@ typedef struct {
|
||||||
UINTN NonVolatileLastVariableOffset;
|
UINTN NonVolatileLastVariableOffset;
|
||||||
UINTN CommonVariableTotalSize;
|
UINTN CommonVariableTotalSize;
|
||||||
UINTN HwErrVariableTotalSize;
|
UINTN HwErrVariableTotalSize;
|
||||||
CHAR8 PlatformLangCodes[256]; //Pre-allocate 256 bytes space to accommodate the PlatformlangCodes.
|
CHAR8 *PlatformLangCodes;
|
||||||
CHAR8 LangCodes[256]; //Pre-allocate 256 bytes space to accommodate the langCodes.
|
CHAR8 *LangCodes;
|
||||||
CHAR8 PlatformLang[8]; //Pre-allocate 8 bytes space to accommodate the Platformlang variable.
|
CHAR8 *PlatformLang;
|
||||||
CHAR8 Lang[4]; //Pre-allocate 4 bytes space to accommodate the lang variable.
|
CHAR8 Lang[ISO_639_2_ENTRY_SIZE + 1];
|
||||||
} ESAL_VARIABLE_GLOBAL;
|
} ESAL_VARIABLE_GLOBAL;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in New Issue