]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/UefiHiiLib/HiiString.c
Fix a bug in UefiHiiLib. The size for allocating a buffer is StrSize instead of StrLen.
[mirror_edk2.git] / MdeModulePkg / Library / UefiHiiLib / HiiString.c
1 /** @file
2 HII Library implementation that uses DXE protocols and services.
3
4 Copyright (c) 2006 - 2008, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15
16 #include "InternalHiiLib.h"
17
18 /**
19 This function create a new string in String Package or updates an existing
20 string in a String Package. If StringId is 0, then a new string is added to
21 a String Package. If StringId is not zero, then a string in String Package is
22 updated. If SupportedLanguages is NULL, then the string is added or updated
23 for all the languages that the String Package supports. If SupportedLanguages
24 is not NULL, then the string is added or updated for the set of languages
25 specified by SupportedLanguages.
26
27 If HiiHandle is NULL, then ASSERT().
28 If String is NULL, then ASSERT().
29
30 @param[in] HiiHandle A handle that was previously registered in the
31 HII Database.
32 @param[in] StringId If zero, then a new string is created in the
33 String Package associated with HiiHandle. If
34 non-zero, then the string specified by StringId
35 is updated in the String Package associated
36 with HiiHandle.
37 @param[in] String A pointer to the Null-terminated Unicode string
38 to add or update in the String Package associated
39 with HiiHandle.
40 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string of
41 language codes. If this parameter is NULL, then
42 String is added or updated in the String Package
43 associated with HiiHandle for all the languages
44 that the String Package supports. If this
45 parameter is not NULL, then then String is added
46 or updated in the String Package associated with
47 HiiHandle for the set oflanguages specified by
48 SupportedLanguages. The format of
49 SupportedLanguages must follow the language
50 format assumed the HII Database.
51
52 @retval 0 The string could not be added or updated in the String Package.
53 @retval Other The EFI_STRING_ID of the newly added or updated string.
54
55 **/
56 EFI_STRING_ID
57 EFIAPI
58 HiiSetString (
59 IN EFI_HII_HANDLE HiiHandle,
60 IN EFI_STRING_ID StringId, OPTIONAL
61 IN CONST EFI_STRING String,
62 IN CONST CHAR8 *SupportedLanguages OPTIONAL
63 )
64 {
65 EFI_STATUS Status;
66 CHAR8 *AllocatedLanguages;
67 CHAR8 *Supported;
68 CHAR8 *Language;
69 EFI_STRING_ID NewStringId;
70
71 ASSERT (HiiHandle != NULL);
72 ASSERT (String != NULL);
73
74 if (SupportedLanguages == NULL) {
75 //
76 // Retrieve the languages that the package specified by HiiHandle supports
77 //
78 AllocatedLanguages = HiiGetSupportedLanguages (HiiHandle);
79 } else {
80 //
81 // Allocate a copy of the SupportLanguages string that passed in
82 //
83 AllocatedLanguages = AllocateCopyPool (AsciiStrSize (SupportedLanguages), SupportedLanguages);
84 }
85
86 //
87 // If there are not enough resources for the supported languages string, then return a StringId of 0
88 //
89 if (AllocatedLanguages == NULL) {
90 return (EFI_STRING_ID)(0);
91 }
92
93 NewStringId = 0;
94 Status = EFI_INVALID_PARAMETER;
95 //
96 // Loop through each language that the string supports
97 //
98 for (Supported = AllocatedLanguages; *Supported != '\0'; ) {
99 //
100 // Cache a pointer to the beginning of the current language in the list of languages
101 //
102 Language = Supported;
103
104 //
105 // Search for the next language seperator and replace it with a Null-terminator
106 //
107 for (; *Supported != 0 && *Supported != ';'; Supported++);
108 if (*Supported != 0) {
109 *(Supported++) = '\0';
110 }
111
112 //
113 // If StringId is 0, then call NewString(). Otherwise, call SetString()
114 //
115 if (StringId == (EFI_STRING_ID)(0)) {
116 Status = gHiiString->NewString (gHiiString, HiiHandle, &NewStringId, Language, NULL, String, NULL);
117 } else {
118 Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL);
119 }
120
121 //
122 // If there was an error, then break out of the loop and return a StringId of 0
123 //
124 if (EFI_ERROR (Status)) {
125 break;
126 }
127 }
128
129 //
130 // Free the buffer of supported languages
131 //
132 FreePool (AllocatedLanguages);
133
134 if (EFI_ERROR (Status)) {
135 return (EFI_STRING_ID)(0);
136 } else if (StringId == (EFI_STRING_ID)(0)) {
137 return NewStringId;
138 } else {
139 return StringId;
140 }
141 }
142
143
144 /**
145 Retrieves a string from a string package names by GUID in a specific language.
146 If the language is not specified, then a string from a string package in the
147 current platform language is retrieved. If the string can not be retrieved
148 using the specified language or the current platform language, then the string
149 is retrieved from the string package in the first language the string package
150 supports. The returned string is allocated using AllocatePool(). The caller
151 is responsible for freeing the allocated buffer using FreePool().
152
153 If PackageListGuid is NULL, then ASSERT().
154 If StringId is 0, then ASSERT.
155
156 @param[in] PackageListGuid The GUID of a package list that was previously
157 registered in the HII Database.
158 @param[in] StringId The identifier of the string to retrieved from the
159 string package associated with PackageListGuid.
160 @param[in] Language The language of the string to retrieve. If this
161 parameter is NULL, then the current platform
162 language is used. The format of Language must
163 follow the language format assumed the HII Database.
164
165 @retval NULL The package list specified by PackageListGuid is not present in the
166 HII Database.
167 @retval NULL The string specified by StringId is not present in the string package.
168 @retval Other The string was returned.
169
170 **/
171 EFI_STRING
172 EFIAPI
173 HiiGetPackageString (
174 IN CONST EFI_GUID *PackageListGuid,
175 IN EFI_STRING_ID StringId,
176 IN CONST CHAR8 *Language OPTIONAL
177 )
178 {
179 EFI_HANDLE *HiiHandleBuffer;
180 EFI_HANDLE HiiHandle;
181
182 ASSERT (PackageListGuid != NULL);
183
184 HiiHandleBuffer = HiiGetHiiHandles (PackageListGuid);
185 if (HiiHandleBuffer == NULL) {
186 return NULL;
187 }
188
189 HiiHandle = HiiHandleBuffer[0];
190 FreePool (HiiHandleBuffer);
191
192 return HiiGetString (HiiHandle, StringId, Language);
193 }
194
195 /**
196 Retrieves a string from a string package in a specific language. If the language
197 is not specified, then a string from a string package in the current platform
198 language is retrieved. If the string can not be retrieved using the specified
199 language or the current platform language, then the string is retrieved from
200 the string package in the first language the string package supports. The
201 returned string is allocated using AllocatePool(). The caller is responsible
202 for freeing the allocated buffer using FreePool().
203
204 If HiiHandle is NULL, then ASSERT().
205 If StringId is 0, then ASSET.
206
207 @param[in] HiiHandle A handle that was previously registered in the HII Database.
208 @param[in] StringId The identifier of the string to retrieved from the string
209 package associated with HiiHandle.
210 @param[in] Language The language of the string to retrieve. If this parameter
211 is NULL, then the current platform language is used. The
212 format of Language must follow the language format assumed
213 the HII Database.
214
215 @retval NULL The string specified by StringId is not present in the string package.
216 @retval Other The string was returned.
217
218 **/
219 EFI_STRING
220 EFIAPI
221 HiiGetString (
222 IN EFI_HII_HANDLE HiiHandle,
223 IN EFI_STRING_ID StringId,
224 IN CONST CHAR8 *Language OPTIONAL
225 )
226 {
227 EFI_STATUS Status;
228 UINTN StringSize;
229 CHAR16 TempString;
230 EFI_STRING String;
231 CHAR8 *SupportedLanguages;
232 CHAR8 *PlatformLanguage;
233 CHAR8 *BestLanguage;
234
235 ASSERT (HiiHandle != NULL);
236 ASSERT (StringId != 0);
237
238 //
239 // Initialize all allocated buffers to NULL
240 //
241 SupportedLanguages = NULL;
242 PlatformLanguage = NULL;
243 BestLanguage = NULL;
244 String = NULL;
245
246 //
247 // Get the languages that the package specified by HiiHandle supports
248 //
249 SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
250 if (SupportedLanguages == NULL) {
251 goto Error;
252 }
253
254 //
255 // Get the current platform language setting
256 //
257 PlatformLanguage = GetEfiGlobalVariable (L"PlatformLang");
258
259 //
260 // If Languag is NULL, then set it to an empty string, so it will be
261 // skipped by GetBestLanguage()
262 //
263 if (Language == NULL) {
264 Language = "";
265 }
266
267 //
268 // Get the best matching language from SupportedLanguages
269 //
270 BestLanguage = GetBestLanguage (
271 SupportedLanguages,
272 FALSE, // RFC 4646 mode
273 Language, // Highest priority
274 PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority
275 SupportedLanguages, // Lowest priority
276 NULL
277 );
278 if (BestLanguage == NULL) {
279 goto Error;
280 }
281
282 //
283 // Retrieve the size of the string in the string package for the BestLanguage
284 //
285 StringSize = 0;
286 Status = gHiiString->GetString (
287 gHiiString,
288 BestLanguage,
289 HiiHandle,
290 StringId,
291 &TempString,
292 &StringSize,
293 NULL
294 );
295 //
296 // If GetString() returns EFI_SUCCESS for a zero size,
297 // then there are no supported languages registered for HiiHandle. If GetString()
298 // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
299 // in the HII Database
300 //
301 if (Status != EFI_BUFFER_TOO_SMALL) {
302 goto Error;
303 }
304
305 //
306 // Allocate a buffer for the return string
307 //
308 String = AllocateZeroPool (StringSize);
309 if (String == NULL) {
310 goto Error;
311 }
312
313 //
314 // Retrieve the string from the string package
315 //
316 Status = gHiiString->GetString (
317 gHiiString,
318 BestLanguage,
319 HiiHandle,
320 StringId,
321 String,
322 &StringSize,
323 NULL
324 );
325 if (EFI_ERROR (Status)) {
326 //
327 // Free the buffer and return NULL if the supported languages can not be retrieved.
328 //
329 FreePool (String);
330 String = NULL;
331 }
332
333 Error:
334 //
335 // Free allocated buffers
336 //
337 if (SupportedLanguages != NULL) {
338 FreePool (SupportedLanguages);
339 }
340 if (PlatformLanguage != NULL) {
341 FreePool (PlatformLanguage);
342 }
343 if (BestLanguage != NULL) {
344 FreePool (BestLanguage);
345 }
346
347 //
348 // Return the Null-terminated Unicode string
349 //
350 return String;
351 }
352