]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/HiiLib/HiiLib.c
1) Cleanup HiiLib, IfrSupportLib.
[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 #include "InternalHiiLib.h"
16
17 EFI_HII_DATABASE_PROTOCOL *mHiiDatabaseProt;
18 EFI_HII_STRING_PROTOCOL *mHiiStringProt;
19
20 /**
21 The constructor function of Hii Library.
22
23 The constructor function caches the value of default HII protocol instances.
24
25 @param ImageHandle The firmware allocated handle for the EFI image.
26 @param SystemTable A pointer to the EFI System Table.
27
28 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
29
30 **/
31 EFI_STATUS
32 EFIAPI
33 UefiHiiLibConstructor (
34 IN EFI_HANDLE ImageHandle,
35 IN EFI_SYSTEM_TABLE *SystemTable
36 )
37 {
38 EFI_STATUS Status;
39
40 Status = gBS->LocateProtocol (
41 &gEfiHiiDatabaseProtocolGuid,
42 NULL,
43 (VOID **) &mHiiDatabaseProt
44 );
45 ASSERT_EFI_ERROR (Status);
46 ASSERT (mHiiDatabaseProt != NULL);
47
48 Status = gBS->LocateProtocol (
49 &gEfiHiiStringProtocolGuid,
50 NULL,
51 (VOID **) &mHiiStringProt
52 );
53 ASSERT_EFI_ERROR (Status);
54 ASSERT (mHiiStringProt != NULL);
55
56 return EFI_SUCCESS;
57 }
58
59
60
61 EFI_HII_PACKAGE_LIST_HEADER *
62 InternalHiiLibPreparePackages (
63 IN UINTN NumberOfPackages,
64 IN CONST EFI_GUID *GuidId, OPTIONAL
65 VA_LIST Marker
66 )
67 {
68 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
69 UINT8 *PackageListData;
70 UINT32 PackageListLength;
71 UINT32 PackageLength;
72 EFI_HII_PACKAGE_HEADER PackageHeader;
73 UINT8 *PackageArray;
74 UINTN Index;
75 VA_LIST MarkerBackup;
76
77 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
78
79 MarkerBackup = Marker;
80
81 for (Index = 0; Index < NumberOfPackages; Index++) {
82 CopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));
83 PackageListLength += (PackageLength - sizeof (UINT32));
84 }
85
86 //
87 // Include the lenght of EFI_HII_PACKAGE_END
88 //
89 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);
90 PackageListHeader = AllocateZeroPool (PackageListLength);
91 ASSERT (PackageListHeader != NULL);
92 CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));
93 PackageListHeader->PackageLength = PackageListLength;
94
95 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);
96
97 Marker = MarkerBackup;
98 for (Index = 0; Index < NumberOfPackages; Index++) {
99 PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);
100 CopyMem (&PackageLength, PackageArray, sizeof (UINT32));
101 PackageLength -= sizeof (UINT32);
102 PackageArray += sizeof (UINT32);
103 CopyMem (PackageListData, PackageArray, PackageLength);
104 PackageListData += PackageLength;
105 }
106
107 //
108 // Append EFI_HII_PACKAGE_END
109 //
110 PackageHeader.Type = EFI_HII_PACKAGE_END;
111 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);
112 CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);
113
114 return PackageListHeader;
115 }
116
117 EFI_HII_PACKAGE_LIST_HEADER *
118 EFIAPI
119 HiiLibPreparePackageList (
120 IN UINTN NumberOfPackages,
121 IN CONST EFI_GUID *GuidId,
122 ...
123 )
124 {
125 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
126 VA_LIST Marker;
127
128 ASSERT (GuidId != NULL);
129
130 VA_START (Marker, GuidId);
131 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Marker);
132 VA_END (Marker);
133
134 return PackageListHeader;
135 }
136
137
138 EFI_STATUS
139 EFIAPI
140 HiiLibAddPackages (
141 IN UINTN NumberOfPackages,
142 IN CONST EFI_GUID *GuidId,
143 IN EFI_HANDLE DriverHandle, OPTIONAL
144 OUT EFI_HII_HANDLE *HiiHandle, OPTIONAL
145 ...
146 )
147 {
148 VA_LIST Args;
149 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
150 EFI_STATUS Status;
151
152 ASSERT (HiiHandle != NULL);
153
154 VA_START (Args, HiiHandle);
155 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Args);
156
157 Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageListHeader, DriverHandle, HiiHandle);
158 if (HiiHandle != NULL) {
159 if (EFI_ERROR (Status)) {
160 *HiiHandle = NULL;
161 }
162 }
163
164 FreePool (PackageListHeader);
165 VA_END (Args);
166
167 return Status;
168 }
169
170 EFI_STATUS
171 EFIAPI
172 HiiLibAddFontPackageToHiiDatabase (
173 IN UINTN FontSize,
174 IN CONST UINT8 *FontBinary,
175 IN CONST EFI_GUID *GuidId,
176 OUT EFI_HII_HANDLE *HiiHandle OPTIONAL
177 )
178 {
179 EFI_STATUS Status;
180 UINT8 *Location;
181 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;
182 UINTN PackageLength;
183 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
184 UINT8 *Package;
185
186 //
187 // Add 4 bytes to the header for entire length for HiiLibPreparePackageList use only.
188 // Looks ugly. Might be updated when font tool is ready.
189 //
190 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + FontSize + 4;
191 Package = AllocateZeroPool (PackageLength);
192 if (Package == NULL) {
193 return EFI_OUT_OF_RESOURCES;
194 }
195 CopyMem (Package, &PackageLength, 4);
196 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR*) (Package + 4);
197 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);
198 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;
199 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (FontSize / sizeof (EFI_NARROW_GLYPH));
200
201 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);
202 CopyMem (Location, FontBinary, FontSize);
203
204 //
205 // Add this simplified font package to a package list then install it.
206 //
207 PackageList = HiiLibPreparePackageList (1, GuidId, Package);
208 Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageList, NULL, HiiHandle);
209 ASSERT_EFI_ERROR (Status);
210 SafeFreePool (PackageList);
211 SafeFreePool (Package);
212
213 return EFI_SUCCESS;
214 }
215
216 VOID
217 EFIAPI
218 HiiLibRemovePackages (
219 IN EFI_HII_HANDLE HiiHandle
220 )
221 {
222 EFI_STATUS Status;
223
224 ASSERT (HiiHandle != NULL);
225 Status = mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle);
226 ASSERT_EFI_ERROR (Status);
227 }
228
229
230 EFI_STATUS
231 EFIAPI
232 HiiLibGetHiiHandles (
233 IN OUT UINTN *HandleBufferLength,
234 OUT EFI_HII_HANDLE **HiiHandleBuffer
235 )
236 {
237 UINTN BufferLength;
238 EFI_STATUS Status;
239
240 ASSERT (HandleBufferLength != NULL);
241 ASSERT (HiiHandleBuffer != NULL);
242
243 BufferLength = 0;
244
245 //
246 // Try to find the actual buffer size for HiiHandle Buffer.
247 //
248 Status = mHiiDatabaseProt->ListPackageLists (
249 mHiiDatabaseProt,
250 EFI_HII_PACKAGE_TYPE_ALL,
251 NULL,
252 &BufferLength,
253 *HiiHandleBuffer
254 );
255
256 if (Status == EFI_BUFFER_TOO_SMALL) {
257 *HiiHandleBuffer = AllocateZeroPool (BufferLength);
258 Status = mHiiDatabaseProt->ListPackageLists (
259 mHiiDatabaseProt,
260 EFI_HII_PACKAGE_TYPE_ALL,
261 NULL,
262 &BufferLength,
263 *HiiHandleBuffer
264 );
265 //
266 // we should not fail here.
267 //
268 ASSERT_EFI_ERROR (Status);
269 }
270
271 *HandleBufferLength = BufferLength;
272
273 return Status;
274 }
275
276 EFI_STATUS
277 EFIAPI
278 HiiLibExtractGuidFromHiiHandle (
279 IN EFI_HII_HANDLE Handle,
280 OUT EFI_GUID *Guid
281 )
282 {
283 EFI_STATUS Status;
284 UINTN BufferSize;
285 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
286
287 ASSERT (Guid != NULL);
288
289 //
290 // Get HII PackageList
291 //
292 BufferSize = 0;
293 HiiPackageList = NULL;
294 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);
295 ASSERT (Status != EFI_NOT_FOUND);
296
297 if (Status == EFI_BUFFER_TOO_SMALL) {
298 HiiPackageList = AllocatePool (BufferSize);
299 ASSERT (HiiPackageList != NULL);
300
301 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);
302 }
303 if (EFI_ERROR (Status)) {
304 return Status;
305 }
306
307 //
308 // Extract GUID
309 //
310 CopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));
311
312 gBS->FreePool (HiiPackageList);
313
314 return EFI_SUCCESS;
315 }
316
317 EFI_HII_HANDLE
318 EFIAPI
319 HiiLibDevicePathToHiiHandle (
320 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
321 )
322 {
323 EFI_STATUS Status;
324 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
325 UINTN BufferSize;
326 UINTN HandleCount;
327 UINTN Index;
328 EFI_HANDLE *Handles;
329 EFI_HANDLE Handle;
330 UINTN Size;
331 EFI_HANDLE DriverHandle;
332 EFI_HII_HANDLE *HiiHandles;
333 EFI_HII_HANDLE HiiHandle;
334
335 ASSERT (DevicePath != NULL);
336
337 //
338 // Locate Device Path Protocol handle buffer
339 //
340 Status = gBS->LocateHandleBuffer (
341 ByProtocol,
342 &gEfiDevicePathProtocolGuid,
343 NULL,
344 &HandleCount,
345 &Handles
346 );
347 if (EFI_ERROR (Status)) {
348 return NULL;
349 }
350
351 //
352 // Search Driver Handle by Device Path
353 //
354 DriverHandle = NULL;
355 BufferSize = GetDevicePathSize (DevicePath);
356 for(Index = 0; Index < HandleCount; Index++) {
357 Handle = Handles[Index];
358 gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);
359
360 //
361 // Check whether DevicePath match
362 //
363 Size = GetDevicePathSize (TmpDevicePath);
364 if ((Size == BufferSize) && CompareMem (DevicePath, TmpDevicePath, Size) == 0) {
365 DriverHandle = Handle;
366 break;
367 }
368 }
369 gBS->FreePool (Handles);
370
371 if (DriverHandle == NULL) {
372 return NULL;
373 }
374
375 //
376 // Retrieve all Hii Handles from HII database
377 //
378 BufferSize = 0x1000;
379 HiiHandles = AllocatePool (BufferSize);
380 ASSERT (HiiHandles != NULL);
381 Status = mHiiDatabaseProt->ListPackageLists (
382 mHiiDatabaseProt,
383 EFI_HII_PACKAGE_TYPE_ALL,
384 NULL,
385 &BufferSize,
386 HiiHandles
387 );
388 if (Status == EFI_BUFFER_TOO_SMALL) {
389 gBS->FreePool (HiiHandles);
390 HiiHandles = AllocatePool (BufferSize);
391 ASSERT (HiiHandles != NULL);
392
393 Status = mHiiDatabaseProt->ListPackageLists (
394 mHiiDatabaseProt,
395 EFI_HII_PACKAGE_TYPE_ALL,
396 NULL,
397 &BufferSize,
398 HiiHandles
399 );
400 }
401
402 if (EFI_ERROR (Status)) {
403 gBS->FreePool (HiiHandles);
404 return NULL;
405 }
406
407 //
408 // Search Hii Handle by Driver Handle
409 //
410 HiiHandle = NULL;
411 HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
412 for (Index = 0; Index < HandleCount; Index++) {
413 Status = mHiiDatabaseProt->GetPackageListHandle (
414 mHiiDatabaseProt,
415 HiiHandles[Index],
416 &Handle
417 );
418 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
419 HiiHandle = HiiHandles[Index];
420 break;
421 }
422 }
423
424 gBS->FreePool (HiiHandles);
425 return HiiHandle;
426 }
427
428 BOOLEAN
429 IsHiiHandleRegistered (
430 EFI_HII_HANDLE HiiHandle
431 )
432 {
433 EFI_STATUS Status;
434 UINTN BufferSize;
435 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
436
437 ASSERT (HiiHandle != NULL);
438
439 HiiPackageList = NULL;
440 BufferSize = 0;
441 Status = mHiiDatabaseProt->ExportPackageLists (
442 mHiiDatabaseProt,
443 HiiHandle,
444 &BufferSize,
445 HiiPackageList
446 );
447
448 return (BOOLEAN) (Status == EFI_BUFFER_TOO_SMALL);
449 }
450