]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c
Clean up the following module msa files.
[mirror_edk2.git] / EdkModulePkg / Universal / UserInterface / HiiDataBase / Dxe / Strings.c
CommitLineData
878ddf1f 1/*++\r
2\r
fad1794c 3Copyright (c) 2006 - 2007, Intel Corporation \r
878ddf1f 4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 Strings.c\r
15\r
16Abstract:\r
17\r
18 This file contains the string processing code to the HII database.\r
19\r
20--*/\r
21\r
22\r
23#include "HiiDatabase.h"\r
24\r
1cc8ee78 25STATIC\r
878ddf1f 26VOID\r
27AsciiToUnicode (\r
28 IN UINT8 *Lang,\r
29 IN UINT16 *Language\r
30 )\r
31{\r
32 UINT8 Count;\r
33\r
34 //\r
35 // Convert the ASCII Lang variable to a Unicode Language variable\r
36 //\r
37 for (Count = 0; Count < 3; Count++) {\r
38 Language[Count] = (CHAR16) Lang[Count];\r
39 }\r
40}\r
41\r
42EFI_STATUS\r
43EFIAPI\r
44HiiTestString (\r
45 IN EFI_HII_PROTOCOL *This,\r
46 IN CHAR16 *StringToTest,\r
47 IN OUT UINT32 *FirstMissing,\r
48 OUT UINT32 *GlyphBufferSize\r
49 )\r
50/*++\r
51\r
52Routine Description:\r
53 Test if all of the characters in a string have corresponding font characters.\r
54 \r
55Arguments:\r
56\r
57Returns: \r
58\r
59--*/\r
60{\r
61 EFI_HII_GLOBAL_DATA *GlobalData;\r
62 EFI_HII_DATA *HiiData;\r
fad1794c 63 BOOLEAN WideChar;\r
64 INT32 Location;\r
878ddf1f 65\r
66 if (This == NULL) {\r
67 return EFI_INVALID_PARAMETER;\r
68 }\r
69\r
70 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
878ddf1f 71 GlobalData = HiiData->GlobalData;\r
878ddf1f 72\r
fad1794c 73 \r
74 //\r
75 // Rewind through the string looking for a glyph width identifier\r
76 // If no width identifier exists, we assume string has narrow width identifier\r
77 //\r
78 for (WideChar = FALSE, Location = (INT32) *FirstMissing; Location >= 0; Location--) {\r
79 if ((StringToTest[Location] == NARROW_CHAR) || (StringToTest[Location] == WIDE_CHAR)) {\r
80 //\r
81 // We found something that identifies what glyph database to look in\r
82 //\r
83 WideChar = (BOOLEAN) (StringToTest[Location] == WIDE_CHAR);\r
84 break;\r
85 }\r
86 }\r
878ddf1f 87\r
88 //\r
89 // Walk through the string until you hit the null terminator\r
90 //\r
fad1794c 91 for (*GlyphBufferSize = 0; StringToTest[*FirstMissing] != CHAR_NULL; (*FirstMissing)++) {\r
878ddf1f 92 //\r
fad1794c 93 // We found something that identifies what glyph database to look in\r
878ddf1f 94 //\r
fad1794c 95 if ((StringToTest[*FirstMissing] == NARROW_CHAR) || (StringToTest[*FirstMissing] == WIDE_CHAR)) {\r
96 WideChar = (BOOLEAN) (StringToTest[*FirstMissing] == WIDE_CHAR);\r
97 continue;\r
878ddf1f 98 }\r
99\r
fad1794c 100 if (!WideChar) {\r
878ddf1f 101 if (CompareMem (\r
102 GlobalData->NarrowGlyphs[StringToTest[*FirstMissing]].GlyphCol1,\r
103 &mUnknownGlyph,\r
104 NARROW_GLYPH_ARRAY_SIZE\r
105 ) == 0\r
106 ) {\r
107 //\r
108 // Break since this glyph isn't defined\r
109 //\r
110 return EFI_NOT_FOUND;\r
111 }\r
112 } else {\r
113 //\r
114 // Can compare wide glyph against only GlyphCol1 since GlyphCol1 and GlyphCol2 are contiguous - just give correct size\r
115 //\r
116 if (CompareMem (\r
117 GlobalData->WideGlyphs[StringToTest[*FirstMissing]].GlyphCol1,\r
118 &mUnknownGlyph,\r
119 WIDE_GLYPH_ARRAY_SIZE\r
120 ) == 0\r
121 ) {\r
122 //\r
123 // Break since this glyph isn't defined\r
124 //\r
125 return EFI_NOT_FOUND;\r
126 }\r
127 }\r
128\r
fad1794c 129 *GlyphBufferSize += (WideChar ? sizeof (EFI_WIDE_GLYPH) : sizeof (EFI_NARROW_GLYPH));\r
878ddf1f 130 }\r
131\r
132 return EFI_SUCCESS;\r
133}\r
134\r
1cc8ee78 135STATIC\r
878ddf1f 136EFI_STATUS\r
137HiiNewString2 (\r
138 IN EFI_HII_PROTOCOL *This,\r
139 IN CHAR16 *Language,\r
140 IN EFI_HII_HANDLE Handle,\r
141 IN OUT STRING_REF *Reference,\r
142 IN CHAR16 *NewString,\r
143 IN BOOLEAN ResetStrings\r
144 )\r
145/*++\r
146\r
147Routine Description:\r
148\r
149 This function allows a new String to be added to an already existing String Package.\r
150 We will make a buffer the size of the package + EfiStrSize of the new string. We will\r
151 copy the string package that first gets changed and the following language packages until\r
152 we encounter the NULL string package. All this time we will ensure that the offsets have\r
153 been adjusted. \r
154\r
155Arguments:\r
156 \r
157 This - Pointer to the HII protocol.\r
158 Language - Pointer to buffer which contains the language code of this NewString.\r
159 Handle - Handle of the package instance to be processed.\r
160 Reference - The token number for the string. If 0, new string token to be returned through this parameter.\r
161 NewString - Buffer pointer for the new string. \r
162 ResetStrings - Indicate if we are resetting a string.\r
163 \r
164Returns: \r
165\r
166 EFI_SUCCESS - The string has been added or reset to Hii database.\r
167 EFI_INVALID_PARAMETER - Some parameter passed in is invalid.\r
168\r
169--*/\r
170{\r
171 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
172 EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;\r
173 EFI_HII_DATA *HiiData;\r
174 EFI_HII_STRING_PACK *StringPack;\r
175 EFI_HII_STRING_PACK *NewStringPack;\r
176 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
177 EFI_HII_PACKAGE_INSTANCE *NewBuffer;\r
178 UINT8 *Location;\r
179 UINT8 *StringLocation;\r
180 RELOFST *StringPointer;\r
181 UINTN Count;\r
182 UINTN Size;\r
183 UINTN Index;\r
184 UINTN SecondIndex;\r
185 BOOLEAN AddString;\r
186 EFI_STATUS Status;\r
187 UINTN Increment;\r
188 UINTN StringCount;\r
189 UINT32 TotalStringCount;\r
190 UINT32 OriginalStringCount;\r
191 RELOFST StringSize;\r
192 UINT32 Length;\r
193 RELOFST Offset;\r
194\r
195 if (This == NULL) {\r
196 return EFI_INVALID_PARAMETER;\r
197 }\r
198\r
199 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
200\r
201 HandleDatabase = HiiData->DatabaseHead;\r
202 PackageInstance = NULL;\r
203 AddString = FALSE;\r
204 Increment = 0;\r
205 StringCount = 0;\r
206 TotalStringCount = 0;\r
207 OriginalStringCount = 0;\r
208\r
209 //\r
210 // Check numeric value against the head of the database\r
211 //\r
212 for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
213 //\r
214 // Match the numeric value with the database entry - if matched, extract PackageInstance\r
215 //\r
216 if (Handle == HandleDatabase->Handle) {\r
217 PackageInstance = HandleDatabase->Buffer;\r
218 if (ResetStrings) {\r
219 TotalStringCount = HandleDatabase->NumberOfTokens;\r
220 }\r
221 break;\r
222 }\r
223 }\r
224 //\r
225 // No handle was found - error condition\r
226 //\r
227 if (PackageInstance == NULL) {\r
228 return EFI_INVALID_PARAMETER;\r
229 }\r
230\r
231 Status = ValidatePack (This, PackageInstance, &StringPackageInstance, &TotalStringCount);\r
232\r
233 //\r
234 // This sets Count to 0 or the size of the IfrData. We intend to use Count as an offset value\r
235 //\r
236 Count = StringPackageInstance->IfrSize;\r
237\r
238 //\r
239 // This is the size of the complete series of string packs\r
240 //\r
241 Size = StringPackageInstance->StringSize;\r
242\r
243 //\r
244 // Based on if there is IFR data in this package instance, determine\r
245 // what the location is of the beginning of the string data.\r
246 //\r
247 if (StringPackageInstance->IfrSize > 0) {\r
248 Location = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;\r
249 } else {\r
250 Location = (UINT8 *) (&StringPackageInstance->IfrData);\r
251 }\r
252 //\r
253 // We allocate a buffer which is big enough for both adding and resetting string.\r
254 // The size is slightly larger than the real size of the packages when we are resetting a string.\r
255 //\r
256 NewBuffer = AllocateZeroPool (\r
257 sizeof (EFI_HII_PACKAGE_INSTANCE) -\r
258 2 * sizeof (VOID *) +\r
259 StringPackageInstance->IfrSize +\r
260 StringPackageInstance->StringSize +\r
261 sizeof (RELOFST) +\r
262 StrSize (NewString)\r
263 );\r
264 ASSERT (NewBuffer);\r
265\r
266 //\r
267 // Copy data to new buffer\r
268 //\r
269 NewBuffer->Handle = StringPackageInstance->Handle;\r
270 NewBuffer->IfrSize = StringPackageInstance->IfrSize;\r
271\r
272 //\r
273 // The worst case scenario for sizing is that we are adding a new string (not replacing one) and there was not a string\r
274 // package to begin with.\r
275 //\r
276 NewBuffer->StringSize = StringPackageInstance->StringSize + StrSize (NewString) + sizeof (EFI_HII_STRING_PACK);\r
277\r
278 if (StringPackageInstance->IfrSize > 0) {\r
279 CopyMem (&NewBuffer->IfrData, &StringPackageInstance->IfrData, StringPackageInstance->IfrSize);\r
280 }\r
281\r
282 StringPack = (EFI_HII_STRING_PACK *) Location;\r
283\r
284 //\r
285 // There may be multiple instances packed together of strings\r
286 // so we must walk the self describing structures until we encounter\r
287 // what we are looking for. In the meantime, copy everything we encounter\r
288 // to the new buffer.\r
289 //\r
290 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
291 for (; Length != 0;) {\r
292 //\r
293 // If passed in Language ISO value is in this string pack's language string\r
294 // then we are dealing with the strings we want.\r
295 //\r
296 CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));\r
297 Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);\r
298\r
299 if (!EFI_ERROR (Status)) {\r
300 break;\r
301 }\r
302\r
303 CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);\r
304\r
305 Count = Count + Length;\r
306 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
307 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
308 }\r
309 //\r
310 // Found the language pack to update on a particular handle\r
311 // We need to Copy the Contents of this pack and adjust the offset values associated\r
312 // with adding/changing a string. This is a particular piece of code that screams for\r
313 // it being prone to programming error.\r
314 //\r
315 //\r
316 // Copy the string package up to the string data\r
317 //\r
318 StringPointer = (RELOFST *) (StringPack + 1);\r
319 CopyMem (\r
320 ((CHAR8 *) (&NewBuffer->IfrData) + Count),\r
321 StringPack,\r
322 (UINTN) ((UINTN) (StringPointer) - (UINTN) (StringPack))\r
323 );\r
324\r
325 //\r
326 // Determine the number of StringPointers\r
327 //\r
328 if (!ResetStrings) {\r
329 CopyMem (&TotalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));\r
330 } else {\r
331 //\r
332 // If we are resetting the strings, use the original value when exported\r
333 //\r
334 CopyMem (&OriginalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));\r
335 ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString -=\r
336 (\r
337 (RELOFST) (OriginalStringCount - TotalStringCount) *\r
338 sizeof (RELOFST)\r
339 );\r
340 ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName -=\r
341 (\r
342 (RELOFST) (OriginalStringCount - TotalStringCount) *\r
343 sizeof (RELOFST)\r
344 );\r
345 ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers = TotalStringCount;\r
346 *Reference = (STRING_REF) (TotalStringCount);\r
347 }\r
348 //\r
349 // If the token value is not valid, error out\r
350 //\r
351 if ((*Reference >= TotalStringCount) && !ResetStrings) {\r
627c1d22 352 FreePool (NewBuffer);\r
878ddf1f 353 return EFI_INVALID_PARAMETER;\r
354 }\r
355 //\r
356 // If Reference is 0, update it with what the new token reference will be and turn the AddString flag on\r
357 //\r
358 if (*Reference == 0) {\r
359 *Reference = (STRING_REF) (TotalStringCount);\r
360 AddString = TRUE;\r
361 }\r
362\r
363 if (AddString) {\r
364 ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString += sizeof (RELOFST);\r
365 ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName += sizeof (RELOFST);\r
366 ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers++;\r
367 }\r
368 //\r
369 // Increment offset by amount of copied data\r
370 //\r
371 Count = Count + ((UINTN) (StringPointer) - (UINTN) StringPack);\r
372\r
373 for (Index = 0; Index < TotalStringCount; Index++) {\r
374 //\r
375 // If we are pointing to the size of the changing string value\r
376 // then cache the old string value so you know what the difference is\r
377 //\r
378 if (Index == *Reference) {\r
379 CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));\r
380\r
381 StringLocation = ((UINT8 *) (StringPack) + Offset);\r
382 for (SecondIndex = 0;\r
383 (StringLocation[SecondIndex] != 0) || (StringLocation[SecondIndex + 1] != 0);\r
384 SecondIndex = SecondIndex + 2\r
385 )\r
386 ;\r
387 SecondIndex = SecondIndex + 2;\r
388\r
389 Size = SecondIndex;\r
390\r
391 //\r
392 // NewString is a passed in local string which is assumed to be aligned\r
393 //\r
394 Size = StrSize (NewString) - Size;\r
395 }\r
396 //\r
397 // If we are about to copy the offset of the string that follows the changed string make\r
398 // sure that the offsets are adjusted accordingly\r
399 //\r
400 if ((Index > *Reference) && !ResetStrings) {\r
401 CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));\r
402 Offset = (RELOFST) (Offset + Size);\r
403 CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));\r
404 }\r
405 //\r
406 // If we are adding a string that means we will have an extra string pointer that will affect all string offsets\r
407 //\r
408 if (AddString) {\r
409 CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));\r
410 Offset = (UINT32) (Offset + sizeof (RELOFST));\r
411 CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));\r
412 }\r
413 //\r
414 // If resetting the strings, we need to reduce the offset by the difference in the strings\r
415 //\r
416 if (ResetStrings) {\r
417 CopyMem (&Length, &StringPointer[Index], sizeof (RELOFST));\r
418 Length = Length - ((RELOFST) (OriginalStringCount - TotalStringCount) * sizeof (RELOFST));\r
419 CopyMem (&StringPointer[Index], &Length, sizeof (RELOFST));\r
420 }\r
421 //\r
422 // Notice that if the string was being added as a new token, we don't have to worry about the\r
423 // offsets changing in the other indexes\r
424 //\r
425 CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringPointer[Index], sizeof (RELOFST));\r
426 Count = Count + sizeof (RELOFST);\r
427 StringCount++;\r
428 }\r
429 //\r
430 // If we are adding a new string the above for loop did not copy the offset for us\r
431 //\r
432 if (AddString) {\r
433 //\r
434 // Since the Index is pointing to the beginning of the first string, we need to gather the size of the previous\r
435 // offset's string and create an offset to our new string.\r
436 //\r
437 CopyMem (&Offset, &StringPointer[Index - 1], sizeof (RELOFST));\r
438 StringLocation = (UINT8 *) StringPack;\r
439 StringLocation = StringLocation + Offset - sizeof (RELOFST);\r
440\r
441 //\r
442 // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues\r
443 //\r
444 for (Length = 0;\r
445 (StringLocation[Length] != 0) || (StringLocation[Length + 1] != 0);\r
446 Length = (RELOFST) (Length + 2)\r
447 )\r
448 ;\r
449 Length = (RELOFST) (Length + 2);\r
450\r
451 StringSize = (RELOFST) (Offset + Length);\r
452\r
453 //\r
454 // Copy the new string offset\r
455 //\r
456 CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringSize, sizeof (RELOFST));\r
457 Count = Count + sizeof (RELOFST);\r
458\r
459 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
460 Length = Length + sizeof (RELOFST);\r
461 CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
462 }\r
463 //\r
464 // Set Location to the First String\r
465 //\r
466 if (ResetStrings) {\r
467 Index = OriginalStringCount;\r
468 }\r
469 //\r
470 // Set Location to the First String\r
471 //\r
472 Location = (UINT8 *) &StringPointer[Index];\r
473 Index = 0;\r
474\r
475 //\r
476 // Keep copying strings until you run into two CHAR16's in a row that are NULL\r
477 //\r
478 do {\r
479 if ((*Reference == Increment) && !AddString) {\r
480 StringLocation = ((UINT8 *) (&NewBuffer->IfrData) + Count);\r
481 CopyMem (StringLocation, NewString, StrSize (NewString));\r
482\r
483 //\r
484 // Advance the destination location by Count number of bytes\r
485 //\r
486 Count = Count + StrSize (NewString);\r
487\r
488 //\r
489 // Add the difference between the new string and the old string to the length\r
490 //\r
491 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
492\r
493 //\r
494 // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues\r
495 //\r
496 StringLocation = (UINT8 *) &Location[Index];\r
497 for (Offset = 0;\r
498 (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);\r
499 Offset = (RELOFST) (Offset + 2)\r
500 )\r
501 ;\r
502 Offset = (RELOFST) (Offset + 2);\r
503\r
504 Length = Length + (UINT32) StrSize (NewString) - Offset;\r
505\r
506 CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
507 } else {\r
508 StringLocation = (UINT8 *) &Location[Index];\r
509 for (Offset = 0;\r
510 (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);\r
511 Offset = (RELOFST) (Offset + 2)\r
512 )\r
513 ;\r
514 Offset = (RELOFST) (Offset + 2);\r
515\r
516 CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringLocation, Offset);\r
517\r
518 //\r
519 // Advance the destination location by Count number of bytes\r
520 //\r
521 Count = Count + Offset;\r
522 }\r
523 //\r
524 // Retrieve the number of characters to advance the index - should land at beginning of next string\r
525 //\r
526 Index = Index + Offset;\r
527 Increment++;\r
528 StringCount--;\r
529 Offset = 0;\r
530 } while (StringCount > 0);\r
531\r
532 //\r
533 // If we are adding a new string, then the above do/while will not suffice\r
534 //\r
535 if (AddString) {\r
536 Offset = (RELOFST) StrSize (NewString);\r
537 CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), NewString, Offset);\r
538\r
539 Count = Count + StrSize (NewString);\r
540 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
541 Length = Length + (UINT32) StrSize (NewString);\r
542 CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
543 }\r
544\r
545 if (ResetStrings) {\r
546 //\r
547 // Skip the remainder of strings in the string package\r
548 //\r
549 StringCount = OriginalStringCount - TotalStringCount;\r
550\r
551 while (StringCount > 0) {\r
552 StringLocation = (UINT8 *) &Location[Index];\r
553 for (Offset = 0;\r
554 (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);\r
555 Offset = (RELOFST) (Offset + 2)\r
556 )\r
557 ;\r
558 Offset = (RELOFST) (Offset + 2);\r
559 Index = Index + Offset;\r
560 StringCount--;\r
561\r
562 //\r
563 // Adjust the size of the string pack by the string size we just skipped.\r
564 // Also reduce the length by the size of a RelativeOffset value since we\r
565 // obviously would have skipped that as well.\r
566 //\r
567 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
568 Length = Length - Offset - sizeof (RELOFST);\r
569 CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
570 }\r
571 }\r
572\r
573 StringPack = (EFI_HII_STRING_PACK *) &Location[Index];\r
574\r
575 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
576 for (; Length != 0;) {\r
577\r
578 CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);\r
579\r
580 Count = Count + Length;\r
581 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
582 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
583 }\r
584 //\r
585 // Copy the null terminator to the new buffer\r
586 //\r
587 CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, sizeof (EFI_HII_STRING_PACK));\r
588\r
589 //\r
590 // Based on if there is IFR data in this package instance, determine\r
591 // what the location is of the beginning of the string data.\r
592 //\r
593 if (StringPackageInstance->IfrSize > 0) {\r
594 Location = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;\r
595 StringPack = (EFI_HII_STRING_PACK *) Location;\r
596 Location = (UINT8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize;\r
597 NewStringPack = (EFI_HII_STRING_PACK *) Location;\r
598 } else {\r
599 StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
600 NewStringPack = (EFI_HII_STRING_PACK *) (&NewBuffer->IfrData);\r
601 }\r
602\r
603 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
604 for (; Length != 0;) {\r
605 //\r
606 // Since we updated the old version of the string data as we moved things over\r
607 // And we had a chicken-egg problem with the data we copied, let's post-fix the new\r
608 // buffer with accurate length data.\r
609 //\r
610 CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));\r
611 CopyMem (&NewStringPack->Header.Length, &StringPack->Header.Length, sizeof (UINT32));\r
612 CopyMem (&StringPack->Header.Length, &Count, sizeof (UINT32));\r
613\r
614 CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));\r
615 NewStringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (NewStringPack) + Count);\r
616 CopyMem (&Count, &StringPack->Header.Length, sizeof (UINT32));\r
617 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Count);\r
618 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
619 }\r
620\r
621 GetPackSize ((VOID *) ((CHAR8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize), &NewBuffer->StringSize, NULL);\r
622\r
623 //\r
624 // Search through the handles until the requested handle is found.\r
625 //\r
626 for (HandleDatabase = HiiData->DatabaseHead;\r
627 HandleDatabase->Handle != 0;\r
628 HandleDatabase = HandleDatabase->NextHandleDatabase\r
629 ) {\r
630 if (HandleDatabase->Handle == StringPackageInstance->Handle) {\r
631 //\r
632 // Free the previous buffer associated with this handle, and assign the new buffer to the handle\r
633 //\r
627c1d22 634 FreePool (HandleDatabase->Buffer);\r
878ddf1f 635 HandleDatabase->Buffer = NewBuffer;\r
636 break;\r
637 }\r
638 }\r
639\r
640 return EFI_SUCCESS;\r
641}\r
642\r
643EFI_STATUS\r
644EFIAPI\r
645HiiNewString (\r
646 IN EFI_HII_PROTOCOL *This,\r
647 IN CHAR16 *Language,\r
648 IN EFI_HII_HANDLE Handle,\r
649 IN OUT STRING_REF *Reference,\r
650 IN CHAR16 *NewString\r
651 )\r
652/*++\r
653\r
654Routine Description:\r
655 This function allows a new String to be added to an already existing String Package.\r
656 We will make a buffer the size of the package + StrSize of the new string. We will\r
657 copy the string package that first gets changed and the following language packages until\r
658 we encounter the NULL string package. All this time we will ensure that the offsets have\r
659 been adjusted. \r
660\r
661Arguments:\r
662 \r
663Returns: \r
664\r
665--*/\r
666{\r
667 UINTN Index;\r
668 CHAR16 *LangCodes;\r
669 CHAR16 Lang[4];\r
670 STRING_REF OriginalValue;\r
671 EFI_STATUS Status;\r
672\r
673 //\r
674 // To avoid a warning 4 uninitialized variable warning\r
675 //\r
676 Status = EFI_SUCCESS;\r
677\r
678 Status = HiiGetPrimaryLanguages (\r
679 This,\r
680 Handle,\r
681 &LangCodes\r
682 );\r
683\r
684 if (!EFI_ERROR (Status)) {\r
685 OriginalValue = *Reference;\r
686\r
687 if (Language == NULL) {\r
688 for (Index = 0; LangCodes[Index] != 0; Index += 3) {\r
689 *Reference = OriginalValue;\r
690 CopyMem (Lang, &LangCodes[Index], 6);\r
691 Lang[3] = 0;\r
692 Status = HiiNewString2 (\r
693 This,\r
694 Lang,\r
695 Handle,\r
696 Reference,\r
697 NewString,\r
698 FALSE\r
699 );\r
700\r
701 }\r
702 } else {\r
703 Status = HiiNewString2 (\r
704 This,\r
705 Language,\r
706 Handle,\r
707 Reference,\r
708 NewString,\r
709 FALSE\r
710 );\r
711 }\r
712\r
627c1d22 713 FreePool (LangCodes);\r
878ddf1f 714 }\r
715\r
716 return Status;\r
717}\r
718\r
719EFI_STATUS\r
720EFIAPI\r
721HiiResetStrings (\r
722 IN EFI_HII_PROTOCOL *This,\r
723 IN EFI_HII_HANDLE Handle\r
724 )\r
725/*++\r
726\r
727Routine Description:\r
728 \r
729 This function removes any new strings that were added after the initial string export for this handle.\r
730\r
731Arguments:\r
732\r
733Returns: \r
734\r
735--*/\r
736{\r
737 UINTN Index;\r
738 CHAR16 *LangCodes;\r
739 CHAR16 Lang[4];\r
740 STRING_REF Reference;\r
741 CHAR16 NewString;\r
742 EFI_STATUS Status;\r
743\r
744 Reference = 1;\r
745 NewString = 0;\r
746\r
747 HiiGetPrimaryLanguages (\r
748 This,\r
749 Handle,\r
750 &LangCodes\r
751 );\r
752\r
753 for (Index = 0; LangCodes[Index] != 0; Index += 3) {\r
754 CopyMem (Lang, &LangCodes[Index], 6);\r
755 Lang[3] = 0;\r
756 Status = HiiNewString2 (\r
757 This,\r
758 Lang,\r
759 Handle,\r
760 &Reference,\r
761 &NewString,\r
762 TRUE\r
763 );\r
1cc8ee78 764 ASSERT_EFI_ERROR (Status);\r
878ddf1f 765 }\r
766\r
627c1d22 767 FreePool (LangCodes);\r
878ddf1f 768 return EFI_SUCCESS;\r
769}\r
770\r
771EFI_STATUS\r
772EFIAPI\r
773HiiGetString (\r
774 IN EFI_HII_PROTOCOL *This,\r
775 IN EFI_HII_HANDLE Handle,\r
776 IN STRING_REF Token,\r
777 IN BOOLEAN Raw,\r
778 IN CHAR16 *LanguageString,\r
779 IN OUT UINTN *BufferLengthTemp,\r
780 OUT EFI_STRING StringBuffer\r
781 )\r
782/*++\r
783\r
784Routine Description:\r
785 \r
786 This function extracts a string from a package already registered with the EFI HII database.\r
787\r
788Arguments:\r
789 This - A pointer to the EFI_HII_PROTOCOL instance.\r
790 Handle - The HII handle on which the string resides.\r
791 Token - The string token assigned to the string.\r
792 Raw - If TRUE, the string is returned unedited in the internal storage format described\r
793 above. If false, the string returned is edited by replacing <cr> with <space> \r
794 and by removing special characters such as the <wide> prefix.\r
795 LanguageString - Pointer to a NULL-terminated string containing a single ISO 639-2 language\r
796 identifier, indicating the language to print. If the LanguageString is empty (starts\r
797 with a NULL), the default system language will be used to determine the language.\r
798 BufferLength - Length of the StringBuffer. If the status reports that the buffer width is too\r
799 small, this parameter is filled with the length of the buffer needed.\r
800 StringBuffer - The buffer designed to receive the characters in the string. Type EFI_STRING is\r
801 defined in String.\r
802\r
803Returns: \r
804 EFI_INVALID_PARAMETER - If input parameter is invalid.\r
805 EFI_BUFFER_TOO_SMALL - If the *BufferLength is too small.\r
806 EFI_SUCCESS - Operation is successful.\r
807 \r
808--*/\r
809{\r
810 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
811 EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;\r
812 EFI_HII_DATA *HiiData;\r
813 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
814 EFI_HII_STRING_PACK *StringPack;\r
815 RELOFST *StringPointer;\r
816 EFI_STATUS Status;\r
817 UINTN DataSize;\r
818 CHAR8 Lang[3];\r
819 CHAR16 Language[3];\r
820 UINT32 Length;\r
821 UINTN Count;\r
822 RELOFST Offset;\r
823 UINT16 *Local;\r
824 UINT16 Zero;\r
825 UINT16 Narrow;\r
826 UINT16 Wide;\r
827 UINT16 NoBreak;\r
828 BOOLEAN LangFound;\r
829 UINT16 *BufferLength = (UINT16 *) BufferLengthTemp;\r
830\r
831 if (This == NULL) {\r
832 return EFI_INVALID_PARAMETER;\r
833 }\r
834\r
835 LangFound = TRUE;\r
836\r
837 DataSize = sizeof (Lang);\r
838\r
839 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
840\r
841 PackageInstance = NULL;\r
842 Zero = 0;\r
843 Narrow = NARROW_CHAR;\r
844 Wide = WIDE_CHAR;\r
845 NoBreak = NON_BREAKING_CHAR;\r
846\r
847 //\r
848 // Check numeric value against the head of the database\r
849 //\r
850 for (HandleDatabase = HiiData->DatabaseHead;\r
851 HandleDatabase != NULL;\r
852 HandleDatabase = HandleDatabase->NextHandleDatabase\r
853 ) {\r
854 //\r
855 // Match the numeric value with the database entry - if matched, extract PackageInstance\r
856 //\r
857 if (Handle == HandleDatabase->Handle) {\r
858 PackageInstance = HandleDatabase->Buffer;\r
859 break;\r
860 }\r
861 }\r
862 //\r
863 // No handle was found - error condition\r
864 //\r
865 if (PackageInstance == NULL) {\r
866 return EFI_INVALID_PARAMETER;\r
867 }\r
868\r
869 Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
870\r
871 //\r
872 // If there is no specified language, assume the system default language\r
873 //\r
874 if (LanguageString == NULL) {\r
875 //\r
876 // Get system default language\r
877 //\r
878 Status = gRT->GetVariable (\r
879 (CHAR16 *) L"Lang",\r
880 &gEfiGlobalVariableGuid,\r
881 NULL,\r
882 &DataSize,\r
883 Lang\r
884 );\r
885\r
886 if (EFI_ERROR (Status)) {\r
887 //\r
888 // If Lang doesn't exist, just use the first language you find\r
889 //\r
890 LangFound = FALSE;\r
891 goto LangNotFound;\r
892 }\r
893 //\r
894 // Convert the ASCII Lang variable to a Unicode Language variable\r
895 //\r
896 AsciiToUnicode ((UINT8 *)Lang, Language);\r
897 } else {\r
898 //\r
899 // Copy input ISO value to Language variable\r
900 //\r
901 CopyMem (Language, LanguageString, 6);\r
902 }\r
903 //\r
904 // Based on if there is IFR data in this package instance, determine\r
905 // what the location is of the beginning of the string data.\r
906 //\r
907LangNotFound:\r
908 if (StringPackageInstance->IfrSize > 0) {\r
909 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
910 } else {\r
911 StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
912 }\r
913 //\r
914 // If Token is 0, extract entire string package\r
915 //\r
916 if (Token == 0) {\r
917 //\r
918 // Compute the entire string pack length, including all languages' and the terminating pack's.\r
919 //\r
920 Length = 0;\r
921 while (0 != StringPack->Header.Length) {\r
922 Length += StringPack->Header.Length;\r
923 StringPack = (VOID*)(((UINT8*)StringPack) + StringPack->Header.Length);\r
924 }\r
925 //\r
926 // Back to the start of package.\r
927 //\r
928 StringPack = (VOID*)(((UINT8*)StringPack) - Length); \r
929 //\r
930 // Terminating zero sub-pack.\r
931 //\r
932 Length += sizeof (EFI_HII_STRING_PACK); \r
933\r
934 //\r
935 // If trying to get the entire string package and have insufficient space. Return error.\r
936 //\r
937 if (Length > *BufferLength || StringBuffer == NULL) {\r
938 *BufferLength = (UINT16)Length;\r
939 return EFI_BUFFER_TOO_SMALL;\r
940 }\r
941 //\r
942 // Copy the Pack to the caller's buffer.\r
943 //\r
944 *BufferLength = (UINT16)Length;\r
945 CopyMem (StringBuffer, StringPack, Length);\r
946\r
947 return EFI_SUCCESS;\r
948 }\r
949 //\r
950 // There may be multiple instances packed together of strings\r
951 // so we must walk the self describing structures until we encounter\r
952 // what we are looking for, and then extract the string we are looking for\r
953 //\r
954 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
955 for (; Length != 0;) {\r
956 //\r
957 // If passed in Language ISO value is in this string pack's language string\r
958 // then we are dealing with the strings we want.\r
959 //\r
960 CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));\r
961 Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);\r
962\r
963 //\r
964 // If we cannot find the lang variable, we skip this check and use the first language available\r
965 //\r
966 if (LangFound) {\r
967 if (EFI_ERROR (Status)) {\r
968 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
969 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
970 continue;\r
971 }\r
972 }\r
973\r
974 StringPointer = (RELOFST *) (StringPack + 1);\r
975\r
976 //\r
977 // We have the right string package - size it, and copy it to the StringBuffer\r
978 //\r
979 if (Token >= StringPack->NumStringPointers) {\r
980 return EFI_INVALID_PARAMETER;\r
981 } else {\r
982 CopyMem (&Offset, &StringPointer[Token], sizeof (RELOFST));\r
983 }\r
984 //\r
985 // Since StringPack is a packed structure, we need to determine the string's\r
986 // size safely, thus byte-wise. Post-increment the size to include the null-terminator\r
987 //\r
988 Local = (UINT16 *) ((CHAR8 *) (StringPack) + Offset);\r
989 for (Count = 0; CompareMem (&Local[Count], &Zero, 2); Count++)\r
990 ;\r
991 Count++;\r
992\r
993 Count = Count * sizeof (CHAR16);;\r
994\r
995 if (*BufferLength >= Count && StringBuffer != NULL) {\r
996 //\r
997 // Copy the string to the user's buffer\r
998 //\r
999 if (Raw) {\r
1000 CopyMem (StringBuffer, Local, Count);\r
1001 } else {\r
1002 for (Count = 0; CompareMem (Local, &Zero, 2); Local++) {\r
1003 //\r
1004 // Skip "Narraw, Wide, NoBreak"\r
1005 //\r
1006 if (CompareMem (Local, &Narrow, 2) &&\r
1007 CompareMem (Local, &Wide, 2) && \r
1008 CompareMem (Local, &NoBreak, 2)) { \r
1009 CopyMem (&StringBuffer[Count++], Local, 2); \r
1010 } \r
1011 } \r
1012 //\r
1013 // Add "NULL" at the end.\r
1014 //\r
1015 CopyMem (&StringBuffer[Count], &Zero, 2);\r
1016 Count++;\r
1017 Count *= sizeof (CHAR16);\r
1018 }\r
1019\r
1020 *BufferLength = (UINT16) Count;\r
1021 return EFI_SUCCESS;\r
1022 } else {\r
1023 *BufferLength = (UINT16) Count;\r
1024 return EFI_BUFFER_TOO_SMALL;\r
1025 }\r
1026\r
1027 }\r
1028\r
1029 LangFound = FALSE;\r
1030 goto LangNotFound;\r
1031}\r
1032\r
1033EFI_STATUS\r
1034EFIAPI\r
1035HiiGetLine (\r
1036 IN EFI_HII_PROTOCOL *This,\r
1037 IN EFI_HII_HANDLE Handle,\r
1038 IN STRING_REF Token,\r
1039 IN OUT UINT16 *Index,\r
1040 IN UINT16 LineWidth,\r
1041 IN CHAR16 *LanguageString,\r
1042 IN OUT UINT16 *BufferLength,\r
1043 OUT EFI_STRING StringBuffer\r
1044 )\r
1045/*++\r
1046\r
1047Routine Description:\r
1048\r
1049 This function allows a program to extract a part of a string of not more than a given width. \r
1050 With repeated calls, this allows a calling program to extract "lines" of text that fit inside \r
1051 columns. The effort of measuring the fit of strings inside columns is localized to this call.\r
1052\r
1053Arguments:\r
1054\r
1055Returns: \r
1056\r
1057--*/\r
1058{\r
1059 UINTN Count;\r
1060 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
1061 EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;\r
1062 EFI_HII_DATA *HiiData;\r
1063 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
1064 EFI_HII_STRING_PACK *StringPack;\r
1065 RELOFST *StringPointer;\r
1066 CHAR16 *Location;\r
1067 EFI_STATUS Status;\r
1068 UINTN DataSize;\r
1069 CHAR8 Lang[3];\r
1070 CHAR16 Language[3];\r
1071\r
1072 if (This == NULL) {\r
1073 return EFI_INVALID_PARAMETER;\r
1074 }\r
1075\r
1076 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
1077\r
1078 HandleDatabase = HiiData->DatabaseHead;\r
1079\r
1080 PackageInstance = NULL;\r
1081 DataSize = 4;\r
1082\r
1083 //\r
1084 // Check numeric value against the head of the database\r
1085 //\r
1086 for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
1087 //\r
1088 // Match the numeric value with the database entry - if matched, extract PackageInstance\r
1089 //\r
1090 if (Handle == HandleDatabase->Handle) {\r
1091 PackageInstance = HandleDatabase->Buffer;\r
1092 }\r
1093 }\r
1094 //\r
1095 // No handle was found - error condition\r
1096 //\r
1097 if (PackageInstance == NULL) {\r
1098 return EFI_INVALID_PARAMETER;\r
1099 }\r
1100\r
1101 Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
1102\r
1103 //\r
1104 // If there is no specified language, assume the system default language\r
1105 //\r
1106 if (LanguageString == NULL) {\r
1107 //\r
1108 // Get system default language\r
1109 //\r
1110 Status = gRT->GetVariable (\r
1111 (CHAR16 *) L"Lang",\r
1112 &gEfiGlobalVariableGuid,\r
1113 NULL,\r
1114 &DataSize,\r
1115 Lang\r
1116 );\r
1117\r
1118 if (EFI_ERROR (Status)) {\r
1119 return Status;\r
1120 }\r
1121 //\r
1122 // Convert the ASCII Lang variable to a Unicode Language variable\r
1123 //\r
1124 AsciiToUnicode ((UINT8 *)Lang, Language);\r
1125 } else {\r
1126 //\r
1127 // Copy input ISO value to Language variable\r
1128 //\r
1129 CopyMem (Language, LanguageString, 6);\r
1130 }\r
1131 //\r
1132 // Based on if there is IFR data in this package instance, determine\r
1133 // what the location is of the beginning of the string data.\r
1134 //\r
1135 if (StringPackageInstance->IfrSize > 0) {\r
1136 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
1137 } else {\r
1138 StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
1139 }\r
1140\r
1141 StringPointer = (RELOFST *) (StringPack + 1);\r
1142\r
1143 //\r
1144 // There may be multiple instances packed together of strings\r
1145 // so we must walk the self describing structures until we encounter\r
1146 // what we are looking for, and then extract the string we are looking for\r
1147 //\r
1148 for (; StringPack->Header.Length != 0;) {\r
1149 //\r
1150 // If passed in Language ISO value is in this string pack's language string\r
1151 // then we are dealing with the strings we want.\r
1152 //\r
1153 Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language);\r
1154\r
1155 if (EFI_ERROR (Status)) {\r
1156 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);\r
1157 continue;\r
1158 }\r
1159\r
1160 Location = (CHAR16 *) ((CHAR8 *) (StringPack) + StringPointer[Token] +*Index * 2);\r
1161\r
1162 //\r
1163 // If the size of the remaining string is less than the LineWidth\r
1164 // then copy the entire thing\r
1165 //\r
1166 if (StrSize (Location) <= LineWidth) {\r
1167 if (*BufferLength >= StrSize (Location)) {\r
1168 StrCpy (StringBuffer, Location);\r
1169 return EFI_SUCCESS;\r
1170 } else {\r
1171 *BufferLength = (UINT16) StrSize (Location);\r
1172 return EFI_BUFFER_TOO_SMALL;\r
1173 }\r
1174 } else {\r
1175 //\r
1176 // Rewind the string from the maximum size until we see a space the break the line\r
1177 //\r
1178 for (Count = LineWidth; Location[Count] != 0x0020; Count--)\r
1179 ;\r
1180\r
1181 //\r
1182 // Put the index at the next character\r
1183 //\r
1184 *Index = (UINT16) (Count + 1);\r
1185\r
1186 if (*BufferLength >= Count) {\r
1187 StrnCpy (StringBuffer, Location, Count);\r
1188 return EFI_SUCCESS;\r
1189 } else {\r
1190 *BufferLength = (UINT16) Count;\r
1191 return EFI_BUFFER_TOO_SMALL;\r
1192 }\r
1193 }\r
1194 }\r
1195\r
1196 return EFI_SUCCESS;\r
1197}\r
1198\r
1199EFI_STATUS\r
1200HiiCompareLanguage (\r
1201 IN CHAR16 *LanguageStringLocation,\r
1202 IN CHAR16 *Language\r
1203 )\r
1204{\r
1205 UINT8 *Local;\r
1206 UINTN Index;\r
1207 CHAR16 *InputString;\r
1208 CHAR16 *OriginalInputString;\r
1209\r
1210 //\r
1211 // Allocate a temporary buffer for InputString\r
1212 //\r
1213 InputString = AllocateZeroPool (0x100);\r
1214\r
1215 ASSERT (InputString);\r
1216\r
1217 OriginalInputString = InputString;\r
1218\r
1219 Local = (UINT8 *) LanguageStringLocation;\r
1220\r
1221 //\r
1222 // Determine the size of this packed string safely (e.g. access by byte), post-increment\r
1223 // to include the null-terminator\r
1224 //\r
1225 for (Index = 0; Local[Index] != 0; Index = Index + 2)\r
1226 ;\r
1227 //\r
1228 // MARMAR Index = Index + 2;\r
1229 //\r
1230 // This is a packed structure that this location comes from, so let's make sure\r
1231 // the value is aligned by copying it to a local variable and working on it.\r
1232 //\r
1233 CopyMem (InputString, LanguageStringLocation, Index);\r
1234\r
1235 for (Index = 0; Index < 3; Index++) {\r
1236 InputString[Index] = (CHAR16) (InputString[Index] | 0x20);\r
1237 Language[Index] = (CHAR16) (Language[Index] | 0x20);\r
1238 }\r
1239 //\r
1240 // If the Language is the same return success\r
1241 //\r
1242 if (CompareMem (LanguageStringLocation, Language, 6) == 0) {\r
627c1d22 1243 FreePool (InputString);\r
878ddf1f 1244 return EFI_SUCCESS;\r
1245 }\r
1246 //\r
1247 // Skip the first three letters that comprised the primary language,\r
1248 // see if what is being compared against is a secondary language\r
1249 //\r
1250 InputString = InputString + 3;\r
1251\r
1252 //\r
1253 // If the Language is not the same as the Primary language, see if there are any\r
1254 // secondary languages, and if there are see if we have a match. If not, return an error.\r
1255 //\r
1256 for (Index = 0; InputString[Index] != 0; Index = Index + 3) {\r
1257 //\r
1258 // Getting in here means we have a secondary language\r
1259 //\r
1260 if (CompareMem (&InputString[Index], Language, 6) == 0) {\r
627c1d22 1261 FreePool (InputString);\r
878ddf1f 1262 return EFI_SUCCESS;\r
1263 }\r
1264 }\r
1265 //\r
1266 // If nothing was found, return the error\r
1267 //\r
627c1d22 1268 FreePool (OriginalInputString);\r
878ddf1f 1269 return EFI_NOT_FOUND;\r
1270\r
1271}\r