MiscNumberOfInstallableLanguagesFunction.c 6.8 KB

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