]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/ExtendedIfrSupportLib/Common.c
Sync in bug fix from EDK I:
[mirror_edk2.git] / MdeModulePkg / Library / ExtendedIfrSupportLib / Common.c
1 /** @file
2 Common Library Routines to assist handle HII elements.
3
4 Copyright (c) 2007 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "LibraryInternal.h"
16
17
18 //
19 // Hii relative protocols
20 //
21
22 EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase;
23 EFI_HII_STRING_PROTOCOL *gIfrLibHiiString;
24
25 /**
26 ExtendedIfrSupportLib's constructor. It locates the required protocol:
27 gEfiHiiDatabaseProtocolGuid and gEfiHiiStringProtocolGuid.
28
29 @param ImageHandle The firmware allocated handle for the EFI image.
30
31 @param SystemTable A pointer to the EFI System Table.
32
33 @retval EFI_SUCCESS This function always completes successfully.
34
35 **/
36 EFI_STATUS
37 EFIAPI
38 ExtendedIfrSupportLibConstructor (
39 IN EFI_HANDLE ImageHandle,
40 IN EFI_SYSTEM_TABLE *SystemTable
41 )
42 {
43 EFI_STATUS Status;
44
45 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gIfrLibHiiDatabase);
46 ASSERT_EFI_ERROR (Status);
47
48 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gIfrLibHiiString);
49 ASSERT_EFI_ERROR (Status);
50
51 return EFI_SUCCESS;
52 }
53
54
55
56 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID mIfrVendorGuid = EFI_IFR_TIANO_GUID;
57
58 /**
59 Extract formset class for given HII handle.
60
61
62 @param Handle The HII handle.
63 @param Class Class of the formset.
64 @param FormSetTitle Formset title string.
65 @param FormSetHelp Formset help string.
66
67 @retval EFI_SUCCESS Successfully extract Class for specified Hii handle.
68 @return Other values if failed to export packages for the given HII handle.
69
70 **/
71 EFI_STATUS
72 EFIAPI
73 IfrLibExtractClassFromHiiHandle (
74 IN EFI_HII_HANDLE Handle,
75 OUT UINT16 *Class,
76 OUT EFI_STRING_ID *FormSetTitle,
77 OUT EFI_STRING_ID *FormSetHelp
78 )
79 {
80 EFI_STATUS Status;
81 UINTN BufferSize;
82 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
83 UINT8 *Package;
84 UINT8 *OpCodeData;
85 UINT32 Offset;
86 UINT32 Offset2;
87 UINT32 PackageListLength;
88 EFI_HII_PACKAGE_HEADER PackageHeader;
89
90 ASSERT (Handle != NULL);
91 ASSERT (Class != NULL);
92 ASSERT (FormSetTitle != NULL);
93 ASSERT (FormSetHelp != NULL);
94
95 *Class = EFI_NON_DEVICE_CLASS;
96 *FormSetTitle = 0;
97 *FormSetHelp = 0;
98
99 //
100 // Get HII PackageList
101 //
102 BufferSize = 0;
103 HiiPackageList = NULL;
104 Status = gIfrLibHiiDatabase->ExportPackageLists (gIfrLibHiiDatabase, Handle, &BufferSize, HiiPackageList);
105 ASSERT (Status != EFI_NOT_FOUND);
106
107 if (Status == EFI_BUFFER_TOO_SMALL) {
108 HiiPackageList = AllocatePool (BufferSize);
109 ASSERT (HiiPackageList != NULL);
110
111 Status = gIfrLibHiiDatabase->ExportPackageLists (gIfrLibHiiDatabase, Handle, &BufferSize, HiiPackageList);
112 }
113 if (EFI_ERROR (Status)) {
114 return Status;
115 }
116
117 //
118 // Get Form package from this HII package List
119 //
120 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
121 Offset2 = 0;
122 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
123
124 while (Offset < PackageListLength) {
125 Package = ((UINT8 *) HiiPackageList) + Offset;
126 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
127
128 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
129 //
130 // Search Class Opcode in this Form Package
131 //
132 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
133 while (Offset2 < PackageHeader.Length) {
134 OpCodeData = Package + Offset2;
135
136 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
137 //
138 // Find FormSet OpCode
139 //
140 CopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
141 CopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
142 }
143
144 if ((((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP) &&
145 CompareGuid (&mIfrVendorGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER))) &&
146 (((EFI_IFR_GUID_CLASS *) OpCodeData)->ExtendOpCode == EFI_IFR_EXTEND_OP_CLASS)
147 ) {
148 //
149 // Find GUIDed Class OpCode
150 //
151 CopyMem (Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
152
153 //
154 // Till now, we ought to have found the formset Opcode
155 //
156 break;
157 }
158
159 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
160 }
161
162 if (Offset2 < PackageHeader.Length) {
163 //
164 // Target formset found
165 //
166 break;
167 }
168 }
169
170 Offset += PackageHeader.Length;
171 }
172
173 FreePool (HiiPackageList);
174
175 return EFI_SUCCESS;
176 }
177
178