]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/IfrSupportLib/UefiIfrCommon.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Library / IfrSupportLib / UefiIfrCommon.c
1 /** @file
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. 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
23 #include "UefiIfrLibraryInternal.h"
24
25 //
26 // Hii relative protocols
27 //
28 BOOLEAN mHiiProtocolsInitialized = FALSE;
29
30 EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase;
31 EFI_HII_STRING_PROTOCOL *gIfrLibHiiString;
32
33
34 /**
35 This function locate Hii relative protocols for later usage.
36
37 None.
38
39 @return None.
40
41 **/
42 VOID
43 LocateHiiProtocols (
44 VOID
45 )
46 {
47 EFI_STATUS Status;
48
49 if (mHiiProtocolsInitialized) {
50 return;
51 }
52
53 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gIfrLibHiiDatabase);
54 ASSERT_EFI_ERROR (Status);
55
56 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gIfrLibHiiString);
57 ASSERT_EFI_ERROR (Status);
58
59 mHiiProtocolsInitialized = TRUE;
60 }
61
62
63 /**
64 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
65
66 @param NumberOfPackages Number of packages.
67 @param GuidId Package GUID.
68
69 @return Pointer of EFI_HII_PACKAGE_LIST_HEADER.
70
71 **/
72 EFI_HII_PACKAGE_LIST_HEADER *
73 PreparePackageList (
74 IN UINTN NumberOfPackages,
75 IN EFI_GUID *GuidId,
76 ...
77 )
78 {
79 VA_LIST Marker;
80 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
81 UINT8 *PackageListData;
82 UINT32 PackageListLength;
83 UINT32 PackageLength;
84 EFI_HII_PACKAGE_HEADER PackageHeader;
85 UINT8 *PackageArray;
86 UINTN Index;
87
88 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
89
90 VA_START (Marker, GuidId);
91 for (Index = 0; Index < NumberOfPackages; Index++) {
92 CopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));
93 PackageListLength += (PackageLength - sizeof (UINT32));
94 }
95 VA_END (Marker);
96
97 //
98 // Include the lenght of EFI_HII_PACKAGE_END
99 //
100 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);
101 PackageListHeader = AllocateZeroPool (PackageListLength);
102 ASSERT (PackageListHeader != NULL);
103 CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));
104 PackageListHeader->PackageLength = PackageListLength;
105
106 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);
107
108 VA_START (Marker, GuidId);
109 for (Index = 0; Index < NumberOfPackages; Index++) {
110 PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);
111 CopyMem (&PackageLength, PackageArray, sizeof (UINT32));
112 PackageLength -= sizeof (UINT32);
113 PackageArray += sizeof (UINT32);
114 CopyMem (PackageListData, PackageArray, PackageLength);
115 PackageListData += PackageLength;
116 }
117 VA_END (Marker);
118
119 //
120 // Append EFI_HII_PACKAGE_END
121 //
122 PackageHeader.Type = EFI_HII_PACKAGE_END;
123 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);
124 CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);
125
126 return PackageListHeader;
127 }
128
129
130 /**
131 Find HII Handle associated with given Device Path.
132
133 @param HiiDatabase Point to EFI_HII_DATABASE_PROTOCOL instance.
134 @param DevicePath Device Path associated with the HII package list
135 handle.
136
137 @retval Handle HII package list Handle associated with the Device
138 Path.
139 @retval NULL Hii Package list handle is not found.
140
141 **/
142 EFI_HII_HANDLE
143 DevicePathToHiiHandle (
144 IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,
145 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
146 )
147 {
148 EFI_STATUS Status;
149 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
150 UINTN BufferSize;
151 UINTN HandleCount;
152 UINTN Index;
153 EFI_HANDLE *Handles;
154 EFI_HANDLE Handle;
155 UINTN Size;
156 EFI_HANDLE DriverHandle;
157 EFI_HII_HANDLE *HiiHandles;
158 EFI_HII_HANDLE HiiHandle;
159
160 //
161 // Locate Device Path Protocol handle buffer
162 //
163 Status = gBS->LocateHandleBuffer (
164 ByProtocol,
165 &gEfiDevicePathProtocolGuid,
166 NULL,
167 &HandleCount,
168 &Handles
169 );
170 if (EFI_ERROR (Status)) {
171 return NULL;
172 }
173
174 //
175 // Search Driver Handle by Device Path
176 //
177 DriverHandle = NULL;
178 BufferSize = GetDevicePathSize (DevicePath);
179 for(Index = 0; Index < HandleCount; Index++) {
180 Handle = Handles[Index];
181 gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);
182
183 //
184 // Check whether DevicePath match
185 //
186 Size = GetDevicePathSize (TmpDevicePath);
187 if ((Size == BufferSize) && CompareMem (DevicePath, TmpDevicePath, Size) == 0) {
188 DriverHandle = Handle;
189 break;
190 }
191 }
192 gBS->FreePool (Handles);
193
194 if (DriverHandle == NULL) {
195 return NULL;
196 }
197
198 //
199 // Retrieve all Hii Handles from HII database
200 //
201 BufferSize = 0x1000;
202 HiiHandles = AllocatePool (BufferSize);
203 ASSERT (HiiHandles != NULL);
204 Status = HiiDatabase->ListPackageLists (
205 HiiDatabase,
206 EFI_HII_PACKAGE_TYPE_ALL,
207 NULL,
208 &BufferSize,
209 HiiHandles
210 );
211 if (Status == EFI_BUFFER_TOO_SMALL) {
212 gBS->FreePool (HiiHandles);
213 HiiHandles = AllocatePool (BufferSize);
214 ASSERT (HiiHandles != NULL);
215
216 Status = HiiDatabase->ListPackageLists (
217 HiiDatabase,
218 EFI_HII_PACKAGE_TYPE_ALL,
219 NULL,
220 &BufferSize,
221 HiiHandles
222 );
223 }
224
225 if (EFI_ERROR (Status)) {
226 gBS->FreePool (HiiHandles);
227 return NULL;
228 }
229
230 //
231 // Search Hii Handle by Driver Handle
232 //
233 HiiHandle = NULL;
234 HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
235 for (Index = 0; Index < HandleCount; Index++) {
236 Status = HiiDatabase->GetPackageListHandle (
237 HiiDatabase,
238 HiiHandles[Index],
239 &Handle
240 );
241 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
242 HiiHandle = HiiHandles[Index];
243 break;
244 }
245 }
246
247 gBS->FreePool (HiiHandles);
248 return HiiHandle;
249 }
250
251
252 /**
253 Determines the handles that are currently active in the database.
254 It's the caller's responsibility to free handle buffer.
255
256 @param HiiDatabase A pointer to the EFI_HII_DATABASE_PROTOCOL
257 instance.
258 @param HandleBufferLength On input, a pointer to the length of the handle
259 buffer. On output, the length of the handle buffer
260 that is required for the handles found.
261 @param HiiHandleBuffer Pointer to an array of Hii Handles returned.
262
263 @retval EFI_SUCCESS Get an array of Hii Handles successfully.
264 @retval EFI_INVALID_PARAMETER Hii is NULL.
265 @retval EFI_NOT_FOUND Database not found.
266
267 **/
268 EFI_STATUS
269 GetHiiHandles (
270 IN OUT UINTN *HandleBufferLength,
271 OUT EFI_HII_HANDLE **HiiHandleBuffer
272 )
273 {
274 UINTN BufferLength;
275 EFI_STATUS Status;
276
277 BufferLength = 0;
278
279 LocateHiiProtocols ();
280
281 //
282 // Try to find the actual buffer size for HiiHandle Buffer.
283 //
284 Status = gIfrLibHiiDatabase->ListPackageLists (
285 gIfrLibHiiDatabase,
286 EFI_HII_PACKAGE_TYPE_ALL,
287 NULL,
288 &BufferLength,
289 *HiiHandleBuffer
290 );
291
292 if (Status == EFI_BUFFER_TOO_SMALL) {
293 *HiiHandleBuffer = AllocateZeroPool (BufferLength);
294 Status = gIfrLibHiiDatabase->ListPackageLists (
295 gIfrLibHiiDatabase,
296 EFI_HII_PACKAGE_TYPE_ALL,
297 NULL,
298 &BufferLength,
299 *HiiHandleBuffer
300 );
301 //
302 // we should not fail here.
303 //
304 ASSERT_EFI_ERROR (Status);
305 }
306
307 *HandleBufferLength = BufferLength;
308
309 return Status;
310 }
311
312
313 /**
314 Extract Hii package list GUID for given HII handle.
315
316 @param HiiHandle Hii handle
317 @param Guid Package list GUID
318
319 @retval EFI_SUCCESS Successfully extract GUID from Hii database.
320
321 **/
322 EFI_STATUS
323 ExtractGuidFromHiiHandle (
324 IN EFI_HII_HANDLE Handle,
325 OUT EFI_GUID *Guid
326 )
327 {
328 EFI_STATUS Status;
329 UINTN BufferSize;
330 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
331 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
332
333 //
334 // Locate HII Database protocol
335 //
336 Status = gBS->LocateProtocol (
337 &gEfiHiiDatabaseProtocolGuid,
338 NULL,
339 (VOID **) &HiiDatabase
340 );
341 if (EFI_ERROR (Status)) {
342 return Status;
343 }
344
345 //
346 // Get HII PackageList
347 //
348 BufferSize = 0;
349 HiiPackageList = NULL;
350 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
351 if (Status == EFI_BUFFER_TOO_SMALL) {
352 HiiPackageList = AllocatePool (BufferSize);
353 ASSERT (HiiPackageList != NULL);
354
355 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
356 }
357 if (EFI_ERROR (Status)) {
358 return Status;
359 }
360
361 //
362 // Extract GUID
363 //
364 CopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));
365
366 gBS->FreePool (HiiPackageList);
367
368 return EFI_SUCCESS;
369 }