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