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