]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / UefiEfiIfrSupportLib / UefiIfrCommon.c
1 /*++
2
3 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 UefiIfrCommon.c
15
16 Abstract:
17
18 Common Library Routines to assist handle HII elements.
19
20 --*/
21
22 #include "UefiIfrLibrary.h"
23
24 //
25 // Hii vendor device path template
26 //
27 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePathTemplate = {
28 {
29 {
30 {
31 HARDWARE_DEVICE_PATH,
32 HW_VENDOR_DP,
33 {
34 (UINT8) (sizeof (HII_VENDOR_DEVICE_PATH_NODE)),
35 (UINT8) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE)) >> 8)
36 }
37 },
38 EFI_IFR_TIANO_GUID,
39 },
40 0,
41 0
42 },
43 {
44 END_DEVICE_PATH_TYPE,
45 END_ENTIRE_DEVICE_PATH_SUBTYPE,
46 {
47 END_DEVICE_PATH_LENGTH
48 }
49 }
50 };
51
52 //
53 // Hii relative protocols
54 //
55 BOOLEAN mHiiProtocolsInitialized = FALSE;
56
57 EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase;
58 EFI_HII_STRING_PROTOCOL *gIfrLibHiiString;
59
60 VOID
61 LocateHiiProtocols (
62 VOID
63 )
64 /*++
65
66 Routine Description:
67 This function locate Hii relative protocols for later usage.
68
69 Arguments:
70 None.
71
72 Returns:
73 None.
74
75 --*/
76 {
77 EFI_STATUS Status;
78
79 if (mHiiProtocolsInitialized) {
80 return;
81 }
82
83 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gIfrLibHiiDatabase);
84 ASSERT_EFI_ERROR (Status);
85
86 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gIfrLibHiiString);
87 ASSERT_EFI_ERROR (Status);
88
89 mHiiProtocolsInitialized = TRUE;
90 }
91
92 EFI_HII_PACKAGE_LIST_HEADER *
93 PreparePackageList (
94 IN UINTN NumberOfPackages,
95 IN EFI_GUID *GuidId,
96 ...
97 )
98 /*++
99
100 Routine Description:
101 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
102
103 Arguments:
104 NumberOfPackages - Number of packages.
105 GuidId - Package GUID.
106
107 Returns:
108 Pointer of EFI_HII_PACKAGE_LIST_HEADER.
109
110 --*/
111 {
112 VA_LIST Marker;
113 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
114 UINT8 *PackageListData;
115 UINT32 PackageListLength;
116 UINT32 PackageLength;
117 EFI_HII_PACKAGE_HEADER PackageHeader;
118 UINT8 *PackageArray;
119 UINTN Index;
120
121 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
122
123 VA_START (Marker, GuidId);
124 for (Index = 0; Index < NumberOfPackages; Index++) {
125 EfiCopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));
126 PackageListLength += (PackageLength - sizeof (UINT32));
127 }
128 VA_END (Marker);
129
130 //
131 // Include the lenght of EFI_HII_PACKAGE_END
132 //
133 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);
134 PackageListHeader = EfiLibAllocateZeroPool (PackageListLength);
135 ASSERT (PackageListHeader != NULL);
136 EfiCopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));
137 PackageListHeader->PackageLength = PackageListLength;
138
139 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);
140
141 VA_START (Marker, GuidId);
142 for (Index = 0; Index < NumberOfPackages; Index++) {
143 PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);
144 EfiCopyMem (&PackageLength, PackageArray, sizeof (UINT32));
145 PackageLength -= sizeof (UINT32);
146 PackageArray += sizeof (UINT32);
147 EfiCopyMem (PackageListData, PackageArray, PackageLength);
148 PackageListData += PackageLength;
149 }
150 VA_END (Marker);
151
152 //
153 // Append EFI_HII_PACKAGE_END
154 //
155 PackageHeader.Type = EFI_HII_PACKAGE_END;
156 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);
157 EfiCopyMem (PackageListData, &PackageHeader, PackageHeader.Length);
158
159 return PackageListHeader;
160 }
161
162 EFI_STATUS
163 CreateHiiDriverHandle (
164 OUT EFI_HANDLE *DriverHandle
165 )
166 /*++
167
168 Routine Description:
169 The HII driver handle passed in for HiiDatabase.NewPackageList() requires
170 that there should be DevicePath Protocol installed on it.
171 This routine create a virtual Driver Handle by installing a vendor device
172 path on it, so as to use it to invoke HiiDatabase.NewPackageList().
173
174 Arguments:
175 DriverHandle - Handle to be returned
176
177 Returns:
178 EFI_SUCCESS - Handle destroy success.
179 EFI_OUT_OF_RESOURCES - Not enough memory.
180
181 --*/
182 {
183 EFI_STATUS Status;
184 HII_VENDOR_DEVICE_PATH_NODE *VendorDevicePath;
185
186 VendorDevicePath = EfiLibAllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH), &mHiiVendorDevicePathTemplate);
187 if (VendorDevicePath == NULL) {
188 return EFI_OUT_OF_RESOURCES;
189 }
190
191 //
192 // Use memory address as unique ID to distinguish from different device paths
193 //
194 VendorDevicePath->UniqueId = (UINT64) ((UINTN) VendorDevicePath);
195
196 *DriverHandle = NULL;
197 Status = gBS->InstallMultipleProtocolInterfaces (
198 DriverHandle,
199 &gEfiDevicePathProtocolGuid,
200 VendorDevicePath,
201 NULL
202 );
203 if (EFI_ERROR (Status)) {
204 return Status;
205 }
206
207 return EFI_SUCCESS;
208 }
209
210 EFI_STATUS
211 DestroyHiiDriverHandle (
212 IN EFI_HANDLE DriverHandle
213 )
214 /*++
215
216 Routine Description:
217 Destroy the Driver Handle created by CreateHiiDriverHandle().
218
219 Arguments:
220 DriverHandle - Handle returned by CreateHiiDriverHandle()
221
222 Returns:
223 EFI_SUCCESS - Handle destroy success.
224 other - Handle destroy fail.
225
226 --*/
227 {
228 EFI_STATUS Status;
229 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
230
231 Status = gBS->HandleProtocol (
232 DriverHandle,
233 &gEfiDevicePathProtocolGuid,
234 (VOID **) &DevicePath
235 );
236 if (EFI_ERROR (Status)) {
237 return Status;
238 }
239
240 Status = gBS->UninstallProtocolInterface (
241 DriverHandle,
242 &gEfiDevicePathProtocolGuid,
243 DevicePath
244 );
245 gBS->FreePool (DevicePath);
246 return Status;
247 }
248
249 EFI_HII_HANDLE
250 DevicePathToHiiHandle (
251 IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,
252 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
253 )
254 /*++
255
256 Routine Description:
257 Find HII Handle associated with given Device Path.
258
259 Arguments:
260 HiiDatabase - Point to EFI_HII_DATABASE_PROTOCOL instance.
261 DevicePath - Device Path associated with the HII package list handle.
262
263 Returns:
264 Handle - HII package list Handle associated with the Device Path.
265 NULL - Hii Package list handle is not found.
266
267 --*/
268 {
269 EFI_STATUS Status;
270 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
271 UINTN BufferSize;
272 UINTN HandleCount;
273 UINTN Index;
274 EFI_HANDLE *Handles;
275 EFI_HANDLE Handle;
276 UINTN Size;
277 EFI_HANDLE DriverHandle;
278 EFI_HII_HANDLE *HiiHandles;
279 EFI_HII_HANDLE HiiHandle;
280
281 //
282 // Locate Device Path Protocol handle buffer
283 //
284 Status = gBS->LocateHandleBuffer (
285 ByProtocol,
286 &gEfiDevicePathProtocolGuid,
287 NULL,
288 &HandleCount,
289 &Handles
290 );
291 if (EFI_ERROR (Status)) {
292 return NULL;
293 }
294
295 //
296 // Search Driver Handle by Device Path
297 //
298 DriverHandle = NULL;
299 BufferSize = EfiDevicePathSize (DevicePath);
300 for(Index = 0; Index < HandleCount; Index++) {
301 Handle = Handles[Index];
302 gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);
303
304 //
305 // Check whether DevicePath match
306 //
307 Size = EfiDevicePathSize (TmpDevicePath);
308 if ((Size == BufferSize) && EfiCompareMem (DevicePath, TmpDevicePath, Size) == 0) {
309 DriverHandle = Handle;
310 break;
311 }
312 }
313 gBS->FreePool (Handles);
314
315 if (DriverHandle == NULL) {
316 return NULL;
317 }
318
319 //
320 // Retrieve all Hii Handles from HII database
321 //
322 BufferSize = 0x1000;
323 HiiHandles = EfiLibAllocatePool (BufferSize);
324 ASSERT (HiiHandles != NULL);
325 Status = HiiDatabase->ListPackageLists (
326 HiiDatabase,
327 EFI_HII_PACKAGE_TYPE_ALL,
328 NULL,
329 &BufferSize,
330 HiiHandles
331 );
332 if (Status == EFI_BUFFER_TOO_SMALL) {
333 gBS->FreePool (HiiHandles);
334 HiiHandles = EfiLibAllocatePool (BufferSize);
335 ASSERT (HiiHandles != NULL);
336
337 Status = HiiDatabase->ListPackageLists (
338 HiiDatabase,
339 EFI_HII_PACKAGE_TYPE_ALL,
340 NULL,
341 &BufferSize,
342 HiiHandles
343 );
344 }
345
346 if (EFI_ERROR (Status)) {
347 gBS->FreePool (HiiHandles);
348 return NULL;
349 }
350
351 //
352 // Search Hii Handle by Driver Handle
353 //
354 HiiHandle = NULL;
355 HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
356 for (Index = 0; Index < HandleCount; Index++) {
357 Status = HiiDatabase->GetPackageListHandle (
358 HiiDatabase,
359 HiiHandles[Index],
360 &Handle
361 );
362 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
363 HiiHandle = HiiHandles[Index];
364 break;
365 }
366 }
367
368 gBS->FreePool (HiiHandles);
369 return HiiHandle;
370 }
371
372 EFI_STATUS
373 GetHiiHandles (
374 IN OUT UINTN *HandleBufferLength,
375 OUT EFI_HII_HANDLE **HiiHandleBuffer
376 )
377 /*++
378
379 Routine Description:
380 Determines the handles that are currently active in the database.
381 It's the caller's responsibility to free handle buffer.
382
383 Arguments:
384 HiiDatabase - A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
385 HandleBufferLength - On input, a pointer to the length of the handle buffer. On output,
386 the length of the handle buffer that is required for the handles found.
387 HiiHandleBuffer - Pointer to an array of Hii Handles returned.
388
389 Returns:
390 EFI_SUCCESS - Get an array of Hii Handles successfully.
391 EFI_INVALID_PARAMETER - Hii is NULL.
392 EFI_NOT_FOUND - Database not found.
393
394 --*/
395 {
396 UINTN BufferLength;
397 EFI_STATUS Status;
398
399 BufferLength = 0;
400
401 LocateHiiProtocols ();
402
403 //
404 // Try to find the actual buffer size for HiiHandle Buffer.
405 //
406 Status = gIfrLibHiiDatabase->ListPackageLists (
407 gIfrLibHiiDatabase,
408 EFI_HII_PACKAGE_TYPE_ALL,
409 NULL,
410 &BufferLength,
411 *HiiHandleBuffer
412 );
413
414 if (Status == EFI_BUFFER_TOO_SMALL) {
415 *HiiHandleBuffer = EfiLibAllocateZeroPool (BufferLength);
416 Status = gIfrLibHiiDatabase->ListPackageLists (
417 gIfrLibHiiDatabase,
418 EFI_HII_PACKAGE_TYPE_ALL,
419 NULL,
420 &BufferLength,
421 *HiiHandleBuffer
422 );
423 //
424 // we should not fail here.
425 //
426 ASSERT_EFI_ERROR (Status);
427 }
428
429 *HandleBufferLength = BufferLength;
430
431 return Status;
432 }
433
434 EFI_STATUS
435 ExtractGuidFromHiiHandle (
436 IN EFI_HII_HANDLE Handle,
437 OUT EFI_GUID *Guid
438 )
439 /*++
440
441 Routine Description:
442 Extract Hii package list GUID for given HII handle.
443
444 Arguments:
445 HiiHandle - Hii handle
446 Guid - Package list GUID
447
448 Returns:
449 EFI_SUCCESS - Successfully extract GUID from Hii database.
450
451 --*/
452 {
453 EFI_STATUS Status;
454 UINTN BufferSize;
455 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
456 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
457
458 //
459 // Locate HII Database protocol
460 //
461 Status = gBS->LocateProtocol (
462 &gEfiHiiDatabaseProtocolGuid,
463 NULL,
464 (VOID **) &HiiDatabase
465 );
466 if (EFI_ERROR (Status)) {
467 return Status;
468 }
469
470 //
471 // Get HII PackageList
472 //
473 BufferSize = 0;
474 HiiPackageList = NULL;
475 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
476 if (Status == EFI_BUFFER_TOO_SMALL) {
477 HiiPackageList = EfiLibAllocatePool (BufferSize);
478 ASSERT (HiiPackageList != NULL);
479
480 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
481 }
482 if (EFI_ERROR (Status)) {
483 return Status;
484 }
485
486 //
487 // Extract GUID
488 //
489 EfiCopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));
490
491 gBS->FreePool (HiiPackageList);
492
493 return EFI_SUCCESS;
494 }
495
496 EFI_STATUS
497 ExtractClassFromHiiHandle (
498 IN EFI_HII_HANDLE Handle,
499 OUT UINT16 *Class,
500 OUT EFI_STRING_ID *FormSetTitle,
501 OUT EFI_STRING_ID *FormSetHelp
502 )
503 /*++
504
505 Routine Description:
506 Extract formset class for given HII handle.
507
508 Arguments:
509 HiiHandle - Hii handle
510 Class - Class of the formset
511 FormSetTitle - Formset title string
512 FormSetHelp - Formset help string
513
514 Returns:
515 EFI_SUCCESS - Successfully extract Class for specified Hii handle.
516 EFI_NOT_FOUND - Class not found.
517
518 --*/
519 {
520 EFI_STATUS Status;
521 UINTN BufferSize;
522 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
523 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
524 UINT8 *Package;
525 UINT8 *FormSet;
526 UINT8 *OpCodeData;
527 UINT32 Offset;
528 UINT32 Offset2;
529 UINT32 PackageListLength;
530 EFI_HII_PACKAGE_HEADER PackageHeader;
531 BOOLEAN ClassFound;
532
533 *Class = EFI_NON_DEVICE_CLASS;
534 *FormSetTitle = 0;
535 *FormSetHelp = 0;
536 ClassFound = FALSE;
537
538 //
539 // Locate HII Database protocol
540 //
541 Status = gBS->LocateProtocol (
542 &gEfiHiiDatabaseProtocolGuid,
543 NULL,
544 (VOID **) &HiiDatabase
545 );
546 if (EFI_ERROR (Status)) {
547 return Status;
548 }
549
550 //
551 // Get HII PackageList
552 //
553 BufferSize = 0;
554 HiiPackageList = NULL;
555 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
556 if (Status == EFI_BUFFER_TOO_SMALL) {
557 HiiPackageList = EfiLibAllocatePool (BufferSize);
558 ASSERT (HiiPackageList != NULL);
559
560 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
561 }
562 if (HiiPackageList == NULL) {
563 return EFI_OUT_OF_RESOURCES;
564 }
565 if (EFI_ERROR (Status)) {
566 gBS->FreePool (HiiPackageList);
567 return Status;
568 }
569
570 //
571 // Get Form package from this HII package List
572 //
573 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
574 Offset2 = 0;
575 FormSet = NULL;
576 EfiCopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
577
578 while (Offset < PackageListLength) {
579 Package = ((UINT8 *) HiiPackageList) + Offset;
580 EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
581
582 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
583 //
584 // Search Class Opcode in this Form Package
585 //
586 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
587 while (Offset2 < PackageHeader.Length) {
588 OpCodeData = Package + Offset2;
589
590 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
591 //
592 // Find FormSet OpCode
593 //
594 EfiCopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
595 EfiCopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
596 }
597
598 if ((((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP) &&
599 (EfiCompareGuid (&mIfrVendorGuid, &((EFI_IFR_GUID *) OpCodeData)->Guid)) &&
600 (((EFI_IFR_GUID_CLASS *) OpCodeData)->ExtendOpCode == EFI_IFR_EXTEND_OP_CLASS)
601 ) {
602 //
603 // Find GUIDed Class OpCode
604 //
605 EfiCopyMem (Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
606
607 //
608 // Till now, we ought to have found the formset Opcode
609 //
610 ClassFound = TRUE;
611 break;
612 }
613
614 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
615 }
616
617 if (Offset2 < PackageHeader.Length) {
618 //
619 // Target formset found
620 //
621 break;
622 }
623 }
624
625 Offset += PackageHeader.Length;
626 }
627
628 gBS->FreePool (HiiPackageList);
629
630 return ClassFound ? EFI_SUCCESS : EFI_NOT_FOUND;
631 }
632
633 EFI_STATUS
634 ExtractClassGuidFromHiiHandle (
635 IN EFI_HII_HANDLE Handle,
636 OUT UINT8 *NumberOfClassGuid,
637 OUT EFI_GUID **ClassGuid,
638 OUT EFI_STRING_ID *FormSetTitle,
639 OUT EFI_STRING_ID *FormSetHelp
640 )
641 /*++
642
643 Routine Description:
644 Extract formset ClassGuid for given HII handle.
645
646 Arguments:
647 HiiHandle - Hii handle
648 NumberOfClassGuid - Number of ClassGuid
649 ClassGuid - Pointer to callee allocated buffer, an array of ClassGuid
650 FormSetTitle - Formset title string
651 FormSetHelp - Formset help string
652
653 Returns:
654 EFI_SUCCESS - Successfully extract Class for specified Hii handle.
655
656 --*/
657 {
658 EFI_STATUS Status;
659 UINTN BufferSize;
660 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
661 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
662 UINT8 *Package;
663 UINT8 *FormSet;
664 UINT8 *OpCodeData;
665 UINT32 Offset;
666 UINT32 Offset2;
667 UINT32 PackageListLength;
668 EFI_HII_PACKAGE_HEADER PackageHeader;
669
670 if (NumberOfClassGuid == NULL || ClassGuid == NULL || FormSetTitle == NULL || FormSetHelp == NULL) {
671 return EFI_INVALID_PARAMETER;
672 }
673
674 *NumberOfClassGuid = 0;
675 *ClassGuid = NULL;
676 *FormSetTitle = 0;
677 *FormSetHelp = 0;
678
679 //
680 // Locate HII Database protocol
681 //
682 Status = gBS->LocateProtocol (
683 &gEfiHiiDatabaseProtocolGuid,
684 NULL,
685 (VOID **) &HiiDatabase
686 );
687 if (EFI_ERROR (Status)) {
688 return Status;
689 }
690
691 //
692 // Get HII PackageList
693 //
694 BufferSize = 0;
695 HiiPackageList = NULL;
696 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
697 if (Status == EFI_BUFFER_TOO_SMALL) {
698 HiiPackageList = EfiLibAllocatePool (BufferSize);
699 ASSERT (HiiPackageList != NULL);
700
701 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
702 }
703 if (EFI_ERROR (Status)) {
704 return Status;
705 }
706
707 //
708 // Get Form package from this HII package List
709 //
710 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
711 Offset2 = 0;
712 FormSet = NULL;
713 EfiCopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
714
715 while (Offset < PackageListLength) {
716 Package = ((UINT8 *) HiiPackageList) + Offset;
717 EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
718
719 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
720 //
721 // Search Class Opcode in this Form Package
722 //
723 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
724 while (Offset2 < PackageHeader.Length) {
725 OpCodeData = Package + Offset2;
726
727 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
728 //
729 // Find FormSet OpCode
730 //
731 EfiCopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
732 EfiCopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
733 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length > ((UINTN) &((EFI_IFR_FORM_SET *) 0)->Flags)) {
734 //
735 // New version of formset OpCode
736 //
737 *NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
738 *ClassGuid = EfiLibAllocateCopyPool (
739 *NumberOfClassGuid * sizeof (EFI_GUID),
740 ((EFI_IFR_FORM_SET *) OpCodeData)->ClassGuid
741 );
742 }
743 break;
744 }
745
746 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
747 }
748
749 if (Offset2 < PackageHeader.Length) {
750 //
751 // Target formset found
752 //
753 break;
754 }
755 }
756
757 Offset += PackageHeader.Length;
758 }
759
760 gBS->FreePool (HiiPackageList);
761
762 return EFI_SUCCESS;
763 }