]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/HiiLib/HiiLib.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdePkg / Library / HiiLib / HiiLib.c
CommitLineData
dd51a993 1/** @file\r
2 HII Library implementation that uses DXE protocols and services.\r
3\r
4 Copyright (c) 2006, Intel Corporation<BR>\r
bad46384 5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
dd51a993 9\r
bad46384 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
dd51a993 12\r
dd51a993 13**/\r
14\r
c892d846 15\r
bad46384 16#include <PiDxe.h>\r
c892d846 17\r
7d582d6b 18#include <Protocol/HiiDatabase.h>\r
19#include <Protocol/HiiString.h>\r
20#include <Protocol/DevicePath.h>\r
21\r
22#include <Guid/GlobalVariable.h>\r
23\r
24#include <Library/BaseLib.h>\r
25#include <Library/BaseMemoryLib.h>\r
bad46384 26#include <Library/HiiLib.h>\r
27#include <Library/DebugLib.h>\r
28#include <Library/MemoryAllocationLib.h>\r
7d582d6b 29#include <Library/UefiBootServicesTableLib.h>\r
30#include <Library/UefiRuntimeServicesTableLib.h>\r
31#include <Library/PcdLib.h>\r
32\r
33#include <MdeModuleHii.h>\r
34\r
35#include "InternalHiiLib.h"\r
36\r
37\r
38EFI_HII_DATABASE_PROTOCOL *mHiiDatabaseProt;\r
39EFI_HII_STRING_PROTOCOL *mHiiStringProt;\r
40\r
41//\r
42// Hii vendor device path template\r
43//\r
44HII_VENDOR_DEVICE_PATH mHiiVendorDevicePathTemplate = {\r
45 {\r
46 {\r
47 {\r
48 HARDWARE_DEVICE_PATH,\r
49 HW_VENDOR_DP,\r
50 {\r
51 (UINT8) (sizeof (HII_VENDOR_DEVICE_PATH_NODE)),\r
52 (UINT8) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE)) >> 8)\r
53 }\r
54 },\r
55 EFI_IFR_TIANO_GUID\r
56 },\r
57 0\r
58 },\r
59 {\r
60 END_DEVICE_PATH_TYPE,\r
61 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
62 { \r
63 END_DEVICE_PATH_LENGTH\r
64 }\r
65 }\r
66};\r
67\r
68EFI_STATUS\r
69EFIAPI\r
70UefiHiiLibConstructor (\r
71 IN EFI_HANDLE ImageHandle,\r
72 IN EFI_SYSTEM_TABLE *SystemTable\r
73 )\r
74{\r
75 EFI_STATUS Status;\r
76 \r
77 Status = gBS->LocateProtocol (\r
78 &gEfiHiiDatabaseProtocolGuid,\r
79 NULL,\r
80 (VOID **) &mHiiDatabaseProt\r
81 );\r
82 ASSERT_EFI_ERROR (Status);\r
83 ASSERT (mHiiDatabaseProt != NULL);\r
84\r
85 Status = gBS->LocateProtocol (\r
86 &gEfiHiiStringProtocolGuid,\r
87 NULL,\r
88 (VOID **) &mHiiStringProt\r
89 );\r
90 ASSERT_EFI_ERROR (Status);\r
91 ASSERT (mHiiStringProt != NULL);\r
92\r
93 return EFI_SUCCESS;\r
94}\r
95\r
96EFI_STATUS\r
97HiiLibGetCurrentLanguage (\r
98 OUT CHAR8 *Lang\r
99 )\r
100/*++\r
101\r
102Routine Description:\r
103 Determine what is the current language setting\r
104\r
105Arguments:\r
106 Lang - Pointer of system language\r
107\r
108Returns:\r
109 Status code\r
110\r
111--*/\r
112{\r
113 EFI_STATUS Status;\r
114 UINTN Size;\r
115\r
116 //\r
117 // Get current language setting\r
118 //\r
119 Size = RFC_3066_ENTRY_SIZE;\r
120 Status = gRT->GetVariable (\r
121 L"PlatformLang",\r
122 &gEfiGlobalVariableGuid,\r
123 NULL,\r
124 &Size,\r
125 Lang\r
126 );\r
127\r
128 if (EFI_ERROR (Status)) {\r
129 AsciiStrCpy (Lang, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang));\r
130 }\r
131\r
132 return Status;\r
133}\r
134\r
135VOID\r
136HiiLibGetNextLanguage (\r
137 IN OUT CHAR8 **LangCode,\r
138 OUT CHAR8 *Lang\r
139 )\r
140/*++\r
141\r
142Routine Description:\r
143 Get next language from language code list (with separator ';').\r
144\r
145Arguments:\r
146 LangCode - On input: point to first language in the list. On output: point to\r
147 next language in the list, or NULL if no more language in the list.\r
148 Lang - The first language in the list.\r
149\r
150Returns:\r
151 None.\r
152\r
153--*/\r
154{\r
155 UINTN Index;\r
156 CHAR8 *StringPtr;\r
157\r
158 if (LangCode == NULL || *LangCode == NULL) {\r
159 *Lang = 0;\r
160 return;\r
161 }\r
162\r
163 Index = 0;\r
164 StringPtr = *LangCode;\r
165 while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {\r
166 Index++;\r
167 }\r
168\r
169 CopyMem (Lang, StringPtr, Index);\r
170 Lang[Index] = 0;\r
171\r
172 if (StringPtr[Index] == ';') {\r
173 Index++;\r
174 }\r
175 *LangCode = StringPtr + Index;\r
176}\r
177\r
178CHAR8 *\r
179HiiLibGetSupportedLanguages (\r
180 IN EFI_HII_HANDLE HiiHandle\r
181 )\r
182/*++\r
183\r
184Routine Description:\r
185 This function returns the list of supported languages, in the format specified\r
186 in UEFI specification Appendix M.\r
187\r
188Arguments:\r
189 HiiHandle - The HII package list handle.\r
190\r
191Returns:\r
192 The supported languages.\r
193\r
194--*/\r
195{\r
196 EFI_STATUS Status;\r
197 UINTN BufferSize;\r
198 CHAR8 *LanguageString;\r
199\r
200 //\r
201 // Collect current supported Languages for given HII handle\r
202 //\r
203 BufferSize = 0x1000;\r
204 LanguageString = AllocatePool (BufferSize);\r
205 Status = mHiiStringProt->GetLanguages (mHiiStringProt, HiiHandle, LanguageString, &BufferSize);\r
206 if (Status == EFI_BUFFER_TOO_SMALL) {\r
207 gBS->FreePool (LanguageString);\r
208 LanguageString = AllocatePool (BufferSize);\r
209 Status = mHiiStringProt->GetLanguages (mHiiStringProt, HiiHandle, LanguageString, &BufferSize);\r
210 }\r
211\r
212 if (EFI_ERROR (Status)) {\r
213 LanguageString = NULL;\r
214 }\r
215\r
216 return LanguageString;\r
217}\r
218\r
219UINT16\r
220HiiLibGetSupportedLanguageNumber (\r
221 IN EFI_HII_HANDLE HiiHandle\r
222 )\r
223/*++\r
224\r
225Routine Description:\r
226 This function returns the number of supported languages\r
227\r
228Arguments:\r
229 HiiHandle - The HII package list handle.\r
230\r
231Returns:\r
232 The number of supported languages.\r
233\r
234--*/\r
235{\r
236 CHAR8 *Languages;\r
237 CHAR8 *LanguageString;\r
238 UINT16 LangNumber;\r
239 CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
240\r
241 Languages = HiiLibGetSupportedLanguages (HiiHandle);\r
242 if (Languages == NULL) {\r
243 return 0;\r
244 }\r
245\r
246 LangNumber = 0;\r
247 LanguageString = Languages;\r
248 while (*LanguageString != 0) {\r
249 HiiLibGetNextLanguage (&LanguageString, Lang);\r
250 LangNumber++;\r
251 }\r
252 gBS->FreePool (Languages);\r
253\r
254 return LangNumber;\r
255}\r
256\r
257\r
258EFI_HII_PACKAGE_LIST_HEADER *\r
259InternalHiiLibPreparePackages (\r
260 IN UINTN NumberOfPackages,\r
261 IN CONST EFI_GUID *GuidId, OPTIONAL\r
262 VA_LIST Marker\r
263 )\r
264{\r
265 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
266 UINT8 *PackageListData;\r
267 UINT32 PackageListLength;\r
268 UINT32 PackageLength;\r
269 EFI_HII_PACKAGE_HEADER PackageHeader;\r
270 UINT8 *PackageArray;\r
271 UINTN Index;\r
272 VA_LIST MarkerBackup;\r
273\r
274 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
275\r
276 MarkerBackup = Marker;\r
277 \r
278 for (Index = 0; Index < NumberOfPackages; Index++) {\r
279 CopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));\r
280 PackageListLength += (PackageLength - sizeof (UINT32));\r
281 }\r
282\r
283 //\r
284 // Include the lenght of EFI_HII_PACKAGE_END\r
285 //\r
286 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
287 PackageListHeader = AllocateZeroPool (PackageListLength);\r
288 ASSERT (PackageListHeader != NULL);\r
289 CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));\r
290 PackageListHeader->PackageLength = PackageListLength;\r
291\r
292 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
293\r
294 Marker = MarkerBackup;\r
295 for (Index = 0; Index < NumberOfPackages; Index++) {\r
296 PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);\r
297 CopyMem (&PackageLength, PackageArray, sizeof (UINT32));\r
298 PackageLength -= sizeof (UINT32);\r
299 PackageArray += sizeof (UINT32);\r
300 CopyMem (PackageListData, PackageArray, PackageLength);\r
301 PackageListData += PackageLength;\r
302 }\r
303\r
304 //\r
305 // Append EFI_HII_PACKAGE_END\r
306 //\r
307 PackageHeader.Type = EFI_HII_PACKAGE_END;\r
308 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
309 CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
310\r
311 return PackageListHeader;\r
312}\r
313\r
314EFI_HII_PACKAGE_LIST_HEADER *\r
315EFIAPI\r
316HiiLibPreparePackageList (\r
317 IN UINTN NumberOfPackages,\r
318 IN CONST EFI_GUID *GuidId,\r
319 ...\r
320 )\r
321/*++\r
322\r
323Routine Description:\r
324 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.\r
325\r
326Arguments:\r
327 NumberOfPackages - Number of packages.\r
328 GuidId - Package GUID.\r
329\r
330Returns:\r
331 Pointer of EFI_HII_PACKAGE_LIST_HEADER.\r
332\r
333--*/\r
334{\r
335 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
336 VA_LIST Marker;\r
337\r
338 VA_START (Marker, GuidId);\r
339 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Marker);\r
340 VA_END (Marker);\r
341\r
342 return PackageListHeader;\r
343}\r
344\r
bad46384 345\r
dd51a993 346/**\r
7d582d6b 347 This function allocates pool for an EFI_HII_PACKAGE_LIST structure\r
348 with additional space that is big enough to host all packages described by the variable \r
349 argument list of package pointers. The allocated structure is initialized using NumberOfPackages, \r
350 GuidId, and the variable length argument list of package pointers.\r
dd51a993 351\r
7d582d6b 352 Then, EFI_HII_PACKAGE_LIST will be register to the default System HII Database. The\r
353 Handle to the newly registered Package List is returned throught HiiHandle.\r
dd51a993 354\r
7d582d6b 355 @param NumberOfPackages The number of HII packages to register.\r
356 @param GuidId Package List GUID ID.\r
357 @param HiiHandle The ID used to retrieve the Package List later.\r
358 @param ... The variable argument list describing all HII Package.\r
359\r
360 @return\r
361 The allocated and initialized packages.\r
dd51a993 362\r
363**/\r
7d582d6b 364\r
365EFI_STATUS\r
366EFIAPI\r
367HiiLibAddPackagesToHiiDatabase (\r
368 IN UINTN NumberOfPackages,\r
369 IN CONST EFI_GUID *GuidId,\r
370 IN EFI_HANDLE DriverHandle, OPTIONAL\r
371 OUT EFI_HII_HANDLE *HiiHandle, OPTIONAL\r
372 ...\r
373 )\r
374{\r
375 VA_LIST Args;\r
376 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
377 EFI_STATUS Status;\r
378\r
379\r
380 VA_START (Args, HiiHandle);\r
381 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Args);\r
382\r
383 Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageListHeader, DriverHandle, HiiHandle);\r
384 if (HiiHandle != NULL) {\r
385 if (EFI_ERROR (Status)) {\r
386 *HiiHandle = NULL;\r
387 }\r
388 }\r
389\r
390 FreePool (PackageListHeader);\r
391 VA_END (Args);\r
392 \r
393 return Status;\r
394}\r
395\r
396EFI_STATUS\r
397EFIAPI\r
398HiiLibAddFontPackageToHiiDatabase (\r
399 IN UINTN FontSize,\r
400 IN CONST UINT8 *FontBinary,\r
401 IN CONST EFI_GUID *GuidId,\r
402 OUT EFI_HII_HANDLE *HiiHandle OPTIONAL\r
403 )\r
404{\r
405 EFI_STATUS Status;\r
406 UINT8 *Location;\r
407 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;\r
408 UINTN PackageLength;\r
409 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
410 UINT8 *Package;\r
411\r
412 //\r
413 // Add 4 bytes to the header for entire length for PreparePackageList use only.\r
414 // Looks ugly. Might be updated when font tool is ready.\r
415 //\r
416 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + FontSize + 4;\r
417 Package = AllocateZeroPool (PackageLength);\r
418 if (Package == NULL) {\r
419 return EFI_OUT_OF_RESOURCES;\r
420 }\r
421 CopyMem (Package, &PackageLength, 4);\r
422 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR*) (Package + 4);\r
423 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);\r
424 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
425 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (FontSize / sizeof (EFI_NARROW_GLYPH));\r
426 \r
427 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);\r
428 CopyMem (Location, FontBinary, FontSize);\r
429 \r
430 //\r
431 // Add this simplified font package to a package list then install it.\r
432 //\r
433 PackageList = HiiLibPreparePackageList (1, GuidId, Package);\r
434 Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageList, NULL, HiiHandle);\r
435 ASSERT_EFI_ERROR (Status);\r
436 SafeFreePool (PackageList);\r
437 SafeFreePool (Package); \r
438\r
439 return EFI_SUCCESS;\r
440}\r
441\r
442EFI_STATUS\r
443EFIAPI\r
444HiiLibRemovePackagesFromHiiDatabase (\r
445 IN EFI_HII_HANDLE HiiHandle\r
446 )\r
447{\r
448 return mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle);\r
449}\r
450\r
451EFI_STATUS\r
452EFIAPI\r
453HiiLibCreateString (\r
454 IN EFI_HII_HANDLE PackageList,\r
455 OUT EFI_STRING_ID *StringId,\r
456 IN CONST EFI_STRING String\r
457 )\r
458{\r
459 EFI_STATUS Status;\r
460 CHAR8 *Languages;\r
461 CHAR8 *LangStrings;\r
462 CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
463\r
464 Status = EFI_SUCCESS;\r
465\r
466 Languages = HiiLibGetSupportedLanguages (PackageList);\r
467\r
468 LangStrings = Languages;\r
469 while (*LangStrings != 0) {\r
470 HiiLibGetNextLanguage (&LangStrings, Lang);\r
471\r
472 Status = mHiiStringProt->NewString (\r
473 mHiiStringProt,\r
474 PackageList,\r
475 StringId,\r
476 Lang,\r
477 NULL,\r
478 String,\r
479 NULL\r
480 );\r
481 if (EFI_ERROR (Status)) {\r
482 break;\r
483 }\r
484 }\r
485\r
486 FreePool (Languages);\r
487\r
488 return Status;\r
489 \r
490}\r
491\r
492EFI_STATUS\r
493EFIAPI\r
494HiiLibUpdateString (\r
495 IN EFI_HII_HANDLE PackageList,\r
496 IN EFI_STRING_ID StringId,\r
497 IN CONST EFI_STRING String\r
498 )\r
499{\r
500 EFI_STATUS Status;\r
501 CHAR8 *Languages;\r
502 CHAR8 *LangStrings;\r
503 CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
504\r
505 Status = EFI_SUCCESS;\r
506\r
507 Languages = HiiLibGetSupportedLanguages (PackageList);\r
508\r
509 LangStrings = Languages;\r
510 while (*LangStrings != 0) {\r
511 HiiLibGetNextLanguage (&LangStrings, Lang);\r
512\r
513 Status = mHiiStringProt->SetString (\r
514 mHiiStringProt,\r
515 PackageList,\r
516 StringId,\r
517 Lang,\r
518 String,\r
519 NULL\r
520 );\r
521 if (EFI_ERROR (Status)) {\r
522 break;\r
523 }\r
524 }\r
525\r
526 FreePool (Languages);\r
527\r
528 return Status;\r
529}\r
530\r
531// //\r
532// //////////////////////////////////////////////////\r
533// //\r
534\r
535//\r
536// This function is Implementation Specifc. HII_VENDOR_DEVICE_PATH\r
537// This should be moved to MdeModulepkg.\r
538//\r
539EFI_STATUS\r
dd51a993 540EFIAPI\r
7d582d6b 541HiiLibCreateHiiDriverHandle (\r
542 OUT EFI_HANDLE *DriverHandle\r
543 )\r
544{\r
545 EFI_STATUS Status;\r
546 HII_VENDOR_DEVICE_PATH_NODE *VendorDevicePath;\r
547 UINT64 MonotonicCount;\r
548\r
549 VendorDevicePath = AllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH), &mHiiVendorDevicePathTemplate);\r
550 if (VendorDevicePath == NULL) {\r
551 return EFI_OUT_OF_RESOURCES;\r
552 }\r
553\r
554 gBS->GetNextMonotonicCount (&MonotonicCount);\r
555 VendorDevicePath->MonotonicCount = (UINT32) MonotonicCount;\r
556\r
557 *DriverHandle = NULL;\r
558 Status = gBS->InstallProtocolInterface (\r
559 DriverHandle,\r
560 &gEfiDevicePathProtocolGuid,\r
561 EFI_NATIVE_INTERFACE,\r
562 VendorDevicePath\r
563 );\r
564 if (EFI_ERROR (Status)) {\r
565 return Status;\r
566 }\r
567\r
568 return EFI_SUCCESS;\r
569}\r
570\r
571\r
572EFI_STATUS\r
573EFIAPI\r
574HiiLibDestroyHiiDriverHandle (\r
575 IN EFI_HANDLE DriverHandle\r
576 )\r
577{\r
578 EFI_STATUS Status;\r
579 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
580\r
581 Status = gBS->HandleProtocol (\r
582 DriverHandle,\r
583 &gEfiDevicePathProtocolGuid,\r
584 (VOID **) &DevicePath\r
585 );\r
586 if (EFI_ERROR (Status)) {\r
587 return Status;\r
588 }\r
589\r
590 Status = gBS->UninstallProtocolInterface (\r
591 DriverHandle,\r
592 &gEfiDevicePathProtocolGuid,\r
593 DevicePath\r
594 );\r
595\r
596 return Status;\r
597}\r
598\r
599EFI_STATUS\r
600HiiLibExtractDefault(\r
601 IN VOID *Buffer,\r
602 IN UINTN *BufferSize,\r
603 UINTN Number,\r
dd51a993 604 ...\r
605 )\r
7d582d6b 606/*++\r
607\r
608 Routine Description:\r
609\r
610 Configure the buffer accrording to ConfigBody strings.\r
611\r
612 Arguments:\r
613 DefaultId - the ID of default.\r
614 Buffer - the start address of buffer.\r
615 BufferSize - the size of buffer.\r
616 Number - the number of the strings.\r
617\r
618 Returns:\r
619 EFI_BUFFER_TOO_SMALL - the BufferSize is too small to operate.\r
620 EFI_INVALID_PARAMETER - Buffer is NULL or BufferSize is 0.\r
621 EFI_SUCCESS - Operation successful.\r
622\r
623--*/\r
dd51a993 624{\r
7d582d6b 625 VA_LIST Args;\r
626 UINTN Index;\r
627 UINT32 TotalLen;\r
628 UINT8 *BufCfgArray;\r
629 UINT8 *BufferPos;\r
630 UINT16 Offset;\r
631 UINT16 Width;\r
632 UINT8 *Value;\r
633\r
634 if ((Buffer == NULL) || (BufferSize == NULL)) {\r
635 return EFI_INVALID_PARAMETER;\r
636 }\r
637\r
638 Offset = 0;\r
639 Width = 0;\r
640 Value = NULL;\r
641\r
642 VA_START (Args, Number);\r
643 for (Index = 0; Index < Number; Index++) {\r
644 BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *);\r
645 CopyMem (&TotalLen, BufCfgArray, sizeof (UINT32));\r
646 BufferPos = BufCfgArray + sizeof (UINT32);\r
647\r
648 while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) {\r
649 CopyMem (&Offset, BufferPos, sizeof (UINT16));\r
650 BufferPos += sizeof (UINT16);\r
651 CopyMem (&Width, BufferPos, sizeof (UINT16));\r
652 BufferPos += sizeof (UINT16);\r
653 Value = BufferPos;\r
654 BufferPos += Width;\r
655\r
656 if ((UINTN)(Offset + Width) > *BufferSize) {\r
657 return EFI_BUFFER_TOO_SMALL;\r
658 }\r
659\r
660 CopyMem ((UINT8 *)Buffer + Offset, Value, Width);\r
661 }\r
662 }\r
663 VA_END (Args);\r
664\r
665 *BufferSize = (UINTN)Offset;\r
666\r
667 return EFI_SUCCESS;\r
668}\r
669\r
670\r
671STATIC EFI_GUID mIfrVendorGuid = EFI_IFR_TIANO_GUID;\r
672\r
673EFI_STATUS\r
674HiiLibExtractClassFromHiiHandle (\r
675 IN EFI_HII_HANDLE Handle,\r
676 OUT UINT16 *Class,\r
677 OUT EFI_STRING_ID *FormSetTitle,\r
678 OUT EFI_STRING_ID *FormSetHelp\r
679 )\r
680/*++\r
681\r
682Routine Description:\r
683 Extract formset class for given HII handle.\r
684\r
685Arguments:\r
686 HiiHandle - Hii handle\r
687 Class - Class of the formset\r
688 FormSetTitle - Formset title string\r
689 FormSetHelp - Formset help string\r
690\r
691Returns:\r
692 EFI_SUCCESS - Successfully extract Class for specified Hii handle.\r
693\r
694--*/\r
695{\r
696 EFI_STATUS Status;\r
697 UINTN BufferSize;\r
698 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
699 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
700 UINT8 *Package;\r
701 UINT8 *OpCodeData;\r
702 UINT32 Offset;\r
703 UINT32 Offset2;\r
704 UINT32 PackageListLength;\r
705 EFI_HII_PACKAGE_HEADER PackageHeader;\r
706\r
707 *Class = EFI_NON_DEVICE_CLASS;\r
708 *FormSetTitle = 0;\r
709 *FormSetHelp = 0;\r
710\r
dd51a993 711 //\r
7d582d6b 712 // Locate HII Database protocol\r
713 //\r
714 Status = gBS->LocateProtocol (\r
715 &gEfiHiiDatabaseProtocolGuid,\r
716 NULL,\r
717 (VOID **) &HiiDatabase\r
718 );\r
719 if (EFI_ERROR (Status)) {\r
720 return Status;\r
721 }\r
722\r
723 //\r
724 // Get HII PackageList\r
725 //\r
726 BufferSize = 0;\r
727 HiiPackageList = NULL;\r
728 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);\r
729 if (Status == EFI_BUFFER_TOO_SMALL) {\r
730 HiiPackageList = AllocatePool (BufferSize);\r
731 ASSERT (HiiPackageList != NULL);\r
732\r
733 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);\r
734 }\r
735 if (EFI_ERROR (Status)) {\r
736 return Status;\r
737 }\r
738\r
bad46384 739 //\r
7d582d6b 740 // Get Form package from this HII package List\r
741 //\r
742 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
743 Offset2 = 0;\r
744 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
745\r
746 while (Offset < PackageListLength) {\r
747 Package = ((UINT8 *) HiiPackageList) + Offset;\r
748 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
749\r
750 if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
751 //\r
752 // Search Class Opcode in this Form Package\r
753 //\r
754 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
755 while (Offset2 < PackageHeader.Length) {\r
756 OpCodeData = Package + Offset2;\r
757\r
758 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
759 //\r
760 // Find FormSet OpCode\r
761 //\r
762 CopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
763 CopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
764 }\r
765\r
766 if ((((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP) &&\r
767 CompareGuid (&mIfrVendorGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER))) &&\r
768 (((EFI_IFR_GUID_CLASS *) OpCodeData)->ExtendOpCode == EFI_IFR_EXTEND_OP_CLASS)\r
769 ) {\r
770 //\r
771 // Find GUIDed Class OpCode\r
772 //\r
773 CopyMem (Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
774\r
775 //\r
776 // Till now, we ought to have found the formset Opcode\r
777 //\r
778 break;\r
779 }\r
780\r
781 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
782 }\r
783\r
784 if (Offset2 < PackageHeader.Length) {\r
785 //\r
786 // Target formset found\r
787 //\r
788 break;\r
789 }\r
790 }\r
791\r
792 Offset += PackageHeader.Length;\r
793 }\r
794\r
795 gBS->FreePool (HiiPackageList);\r
796\r
797 return EFI_SUCCESS;\r
dd51a993 798}\r
7d582d6b 799\r