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