MiscNumberOfInstallableLanguagesFunction.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*++
  2. Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. Module Name:
  5. MiscNumberOfInstallableLanguagesFunction.c
  6. Abstract:
  7. This driver parses the mSmbiosMiscDataTable structure and reports
  8. any generated data.
  9. --*/
  10. #include "CommonHeader.h"
  11. #include "MiscSubclassDriver.h"
  12. /**
  13. Check whether the language is supported for given HII handle
  14. @param HiiHandle The HII package list handle.
  15. @param Offset The offest of current lanague in the supported languages.
  16. @param CurrentLang The language code.
  17. @retval TRUE Supported.
  18. @retval FALSE Not Supported.
  19. **/
  20. VOID
  21. EFIAPI
  22. CurrentLanguageMatch (
  23. IN EFI_HII_HANDLE HiiHandle,
  24. OUT UINT16 *Offset,
  25. OUT CHAR8 *CurrentLang
  26. )
  27. {
  28. CHAR8 *DefaultLang;
  29. CHAR8 *BestLanguage;
  30. CHAR8 *Languages;
  31. CHAR8 *MatchLang;
  32. CHAR8 *EndMatchLang;
  33. UINTN CompareLength;
  34. Languages = HiiGetSupportedLanguages (HiiHandle);
  35. if (Languages == NULL) {
  36. return;
  37. }
  38. GetEfiGlobalVariable2 (L"PlatformLang", &CurrentLang, NULL);
  39. DefaultLang = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
  40. BestLanguage = GetBestLanguage (
  41. Languages,
  42. FALSE,
  43. (CurrentLang != NULL) ? CurrentLang : "",
  44. DefaultLang,
  45. NULL
  46. );
  47. if (BestLanguage != NULL) {
  48. //
  49. // Find the best matching RFC 4646 language, compute the offset.
  50. //
  51. CompareLength = AsciiStrLen (BestLanguage);
  52. for (MatchLang = Languages, (*Offset) = 0; *MatchLang != '\0'; (*Offset)++) {
  53. //
  54. // Seek to the end of current match language.
  55. //
  56. for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++);
  57. if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) {
  58. //
  59. // Find the current best Language in the supported languages
  60. //
  61. break;
  62. }
  63. //
  64. // best language match be in the supported language.
  65. //
  66. ASSERT (*EndMatchLang == ';');
  67. MatchLang = EndMatchLang + 1;
  68. }
  69. FreePool (BestLanguage);
  70. }
  71. FreePool (Languages);
  72. if (CurrentLang != NULL) {
  73. FreePool (CurrentLang);
  74. }
  75. return ;
  76. }
  77. /**
  78. Get next language from language code list (with separator ';').
  79. @param LangCode Input: point to first language in the list. On
  80. Otput: point to next language in the list, or
  81. NULL if no more language in the list.
  82. @param Lang The first language in the list.
  83. **/
  84. VOID
  85. EFIAPI
  86. GetNextLanguage (
  87. IN OUT CHAR8 **LangCode,
  88. OUT CHAR8 *Lang
  89. )
  90. {
  91. UINTN Index;
  92. CHAR8 *StringPtr;
  93. ASSERT (LangCode != NULL);
  94. ASSERT (*LangCode != NULL);
  95. ASSERT (Lang != NULL);
  96. Index = 0;
  97. StringPtr = *LangCode;
  98. while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
  99. Index++;
  100. }
  101. CopyMem (Lang, StringPtr, Index);
  102. Lang[Index] = 0;
  103. if (StringPtr[Index] == ';') {
  104. Index++;
  105. }
  106. *LangCode = StringPtr + Index;
  107. }
  108. /**
  109. This function returns the number of supported languages on HiiHandle.
  110. @param HiiHandle The HII package list handle.
  111. @retval The number of supported languages.
  112. **/
  113. UINT16
  114. EFIAPI
  115. GetSupportedLanguageNumber (
  116. IN EFI_HII_HANDLE HiiHandle
  117. )
  118. {
  119. CHAR8 *Lang;
  120. CHAR8 *Languages;
  121. CHAR8 *LanguageString;
  122. UINT16 LangNumber;
  123. Languages = HiiGetSupportedLanguages (HiiHandle);
  124. if (Languages == NULL) {
  125. return 0;
  126. }
  127. LangNumber = 0;
  128. Lang = AllocatePool (AsciiStrSize (Languages));
  129. if (Lang != NULL) {
  130. LanguageString = Languages;
  131. while (*LanguageString != 0) {
  132. GetNextLanguage (&LanguageString, Lang);
  133. LangNumber++;
  134. }
  135. FreePool (Lang);
  136. }
  137. FreePool (Languages);
  138. return LangNumber;
  139. }
  140. /**
  141. This function makes boot time changes to the contents of the
  142. MiscNumberOfInstallableLanguages (Type 13).
  143. @param RecordData Pointer to copy of RecordData from the Data Table.
  144. @retval EFI_SUCCESS All parameters were valid.
  145. @retval EFI_UNSUPPORTED Unexpected RecordType value.
  146. @retval EFI_INVALID_PARAMETER Invalid parameter was found.
  147. **/
  148. MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)
  149. {
  150. UINTN LangStrLen;
  151. CHAR8 CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
  152. CHAR8 *OptionalStrStart;
  153. UINT16 Offset;
  154. EFI_STATUS Status;
  155. EFI_SMBIOS_HANDLE SmbiosHandle;
  156. SMBIOS_TABLE_TYPE13 *SmbiosRecord;
  157. EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *ForType13InputData;
  158. ForType13InputData = (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *)RecordData;
  159. //
  160. // First check for invalid parameters.
  161. //
  162. if (RecordData == NULL) {
  163. return EFI_INVALID_PARAMETER;
  164. }
  165. ForType13InputData->NumberOfInstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
  166. //
  167. // Try to check if current langcode matches with the langcodes in installed languages
  168. //
  169. ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1);
  170. CurrentLanguageMatch (mHiiHandle, &Offset, CurrentLang);
  171. LangStrLen = AsciiStrLen(CurrentLang);
  172. //
  173. // Two zeros following the last string.
  174. //
  175. SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
  176. ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
  177. SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
  178. SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
  179. //
  180. // Make handle chosen by smbios protocol.add automatically.
  181. //
  182. SmbiosRecord->Hdr.Handle = 0;
  183. SmbiosRecord->InstallableLanguages = (UINT8)ForType13InputData->NumberOfInstallableLanguages;
  184. SmbiosRecord->Flags = (UINT8)ForType13InputData->LanguageFlags.AbbreviatedLanguageFormat;
  185. SmbiosRecord->CurrentLanguages = 1;
  186. OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
  187. AsciiStrCpyS(OptionalStrStart, LangStrLen + 1 + 1, CurrentLang);
  188. //
  189. // Now we have got the full smbios record, call smbios protocol to add this record.
  190. //
  191. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  192. Status = Smbios-> Add(
  193. Smbios,
  194. NULL,
  195. &SmbiosHandle,
  196. (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
  197. );
  198. FreePool(SmbiosRecord);
  199. return Status;
  200. }