]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/HiiLib/HiiLib.c
Clean up ExtendedHiiLib, HiiLib, IfrSupportLib, ExtendedIfrSupportLib for Doxygen...
[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
c344685c 17CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabaseProt;\r
18CONST EFI_HII_STRING_PROTOCOL *mHiiStringProt;\r
54cf8780 19BOOLEAN mHiiProtocolsInitialized = FALSE;\r
20\r
7d582d6b 21\r
e52c5a9f 22/**\r
7d582d6b 23\r
54cf8780 24 This function locate Hii relative protocols for later usage.\r
25\r
e52c5a9f 26**/\r
54cf8780 27VOID\r
28LocateHiiProtocols (\r
29 VOID\r
7d582d6b 30 )\r
31{\r
54cf8780 32 EFI_STATUS Status;\r
33\r
34 if (mHiiProtocolsInitialized) {\r
35 return;\r
36 }\r
37\r
38 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabaseProt);\r
7d582d6b 39 ASSERT_EFI_ERROR (Status);\r
7d582d6b 40\r
54cf8780 41 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &mHiiStringProt);\r
7d582d6b 42 ASSERT_EFI_ERROR (Status);\r
7d582d6b 43\r
54cf8780 44 mHiiProtocolsInitialized = TRUE;\r
7d582d6b 45}\r
46\r
7d582d6b 47\r
48\r
ad1b3619 49/**\r
50 This funciton build the package list based on the package number,\r
51 the GUID of the package list and the list of pointer which point to\r
52 package header that defined by UEFI VFR compiler and StringGather\r
53 tool.\r
54\r
55 If there is not enough resource for the new package list,\r
56 the function will ASSERT.\r
57\r
58 @param NumberOfPackages The number of packages be \r
59 @param GuidId The GUID for the package list to be generated.\r
60 @param Marker The variable argument list. Each entry represent a specific package header that is\r
61 generated by VFR compiler and StrGather tool. The first 4 bytes is a UINT32 value\r
62 that indicate the overall length of the package.\r
63\r
64 @return The pointer to the package list header.\r
65\r
66**/\r
7d582d6b 67EFI_HII_PACKAGE_LIST_HEADER *\r
68InternalHiiLibPreparePackages (\r
69 IN UINTN NumberOfPackages,\r
ad1b3619 70 IN CONST EFI_GUID *GuidId,\r
7d582d6b 71 VA_LIST Marker\r
72 )\r
73{\r
74 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
75 UINT8 *PackageListData;\r
76 UINT32 PackageListLength;\r
77 UINT32 PackageLength;\r
78 EFI_HII_PACKAGE_HEADER PackageHeader;\r
79 UINT8 *PackageArray;\r
80 UINTN Index;\r
81 VA_LIST MarkerBackup;\r
82\r
83 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
84\r
85 MarkerBackup = Marker;\r
86 \r
87 for (Index = 0; Index < NumberOfPackages; Index++) {\r
88 CopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));\r
89 PackageListLength += (PackageLength - sizeof (UINT32));\r
90 }\r
91\r
92 //\r
93 // Include the lenght of EFI_HII_PACKAGE_END\r
94 //\r
95 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
96 PackageListHeader = AllocateZeroPool (PackageListLength);\r
97 ASSERT (PackageListHeader != NULL);\r
98 CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));\r
99 PackageListHeader->PackageLength = PackageListLength;\r
100\r
101 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
102\r
103 Marker = MarkerBackup;\r
104 for (Index = 0; Index < NumberOfPackages; Index++) {\r
105 PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);\r
106 CopyMem (&PackageLength, PackageArray, sizeof (UINT32));\r
107 PackageLength -= sizeof (UINT32);\r
108 PackageArray += sizeof (UINT32);\r
109 CopyMem (PackageListData, PackageArray, PackageLength);\r
110 PackageListData += PackageLength;\r
111 }\r
112\r
113 //\r
114 // Append EFI_HII_PACKAGE_END\r
115 //\r
116 PackageHeader.Type = EFI_HII_PACKAGE_END;\r
117 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
118 CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
119\r
120 return PackageListHeader;\r
121}\r
122\r
ad1b3619 123/**\r
124 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.\r
125\r
126 If GuidId is NULL, then ASSERT.\r
127 If not enough resource to complete the operation, then ASSERT.\r
128\r
129 @param NumberOfPackages Number of packages.\r
130 @param GuidId Package GUID.\r
131 @param ... Variable argument list for packages to be assembled.\r
132\r
133 @return EFI_HII_PACKAGE_LIST_HEADER Pointer of EFI_HII_PACKAGE_LIST_HEADER. The function will ASSERT if system has\r
134 not enough resource to complete the operation.\r
135\r
136**/\r
7d582d6b 137EFI_HII_PACKAGE_LIST_HEADER *\r
138EFIAPI\r
139HiiLibPreparePackageList (\r
140 IN UINTN NumberOfPackages,\r
141 IN CONST EFI_GUID *GuidId,\r
142 ...\r
143 )\r
7d582d6b 144{\r
145 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
146 VA_LIST Marker;\r
147\r
e52c5a9f 148 ASSERT (GuidId != NULL);\r
149\r
7d582d6b 150 VA_START (Marker, GuidId);\r
151 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Marker);\r
152 VA_END (Marker);\r
153\r
154 return PackageListHeader;\r
155}\r
156\r
bad46384 157\r
ad1b3619 158/**\r
159 This function allocates pool for an EFI_HII_PACKAGE_LIST structure\r
160 with additional space that is big enough to host all packages described by the variable \r
161 argument list of package pointers. The allocated structure is initialized using NumberOfPackages, \r
162 GuidId, and the variable length argument list of package pointers.\r
163\r
164 Then, EFI_HII_PACKAGE_LIST will be register to the default System HII Database. The\r
165 Handle to the newly registered Package List is returned throught HiiHandle.\r
166\r
167 If HiiHandle is NULL, then ASSERT.\r
168\r
169 @param NumberOfPackages The number of HII packages to register.\r
170 @param GuidId Package List GUID ID.\r
171 @param DriverHandle Optional. If not NULL, the DriverHandle on which an instance of DEVICE_PATH_PROTOCOL is installed.\r
172 This DriverHandle uniquely defines the device that the added packages are associated with.\r
173 @param HiiHandle On output, the HiiHandle is update with the handle which can be used to retrieve the Package \r
174 List later. If the functions failed to add the package to the default HII database, this value will\r
175 be set to NULL.\r
176 @param ... The variable argument list describing all HII Package.\r
177\r
178 @return EFI_SUCCESS If the packages are successfully added to the default HII database.\r
179 @return EFI_OUT_OF_RESOURCE Not enough resource to complete the operation.\r
180\r
181**/\r
7d582d6b 182EFI_STATUS\r
183EFIAPI\r
e52c5a9f 184HiiLibAddPackages (\r
7d582d6b 185 IN UINTN NumberOfPackages,\r
186 IN CONST EFI_GUID *GuidId,\r
187 IN EFI_HANDLE DriverHandle, OPTIONAL\r
2a10d874 188 OUT EFI_HII_HANDLE *HiiHandle,\r
7d582d6b 189 ...\r
190 )\r
191{\r
192 VA_LIST Args;\r
193 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
194 EFI_STATUS Status;\r
195\r
e52c5a9f 196 ASSERT (HiiHandle != NULL);\r
7d582d6b 197\r
54cf8780 198 LocateHiiProtocols ();\r
199\r
7d582d6b 200 VA_START (Args, HiiHandle);\r
201 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Args);\r
202\r
203 Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageListHeader, DriverHandle, HiiHandle);\r
204 if (HiiHandle != NULL) {\r
205 if (EFI_ERROR (Status)) {\r
206 *HiiHandle = NULL;\r
207 }\r
208 }\r
209\r
210 FreePool (PackageListHeader);\r
211 VA_END (Args);\r
212 \r
213 return Status;\r
214}\r
215\r
ad1b3619 216/**\r
217 Removes a package list from the default HII database.\r
218\r
219 If HiiHandle is NULL, then ASSERT.\r
220 If HiiHandle is not a valid EFI_HII_HANDLE in the default HII database, then ASSERT.\r
221\r
222 @param HiiHandle The handle that was previously registered to the data base that is requested for removal.\r
223 List later.\r
224\r
225 @return VOID\r
226\r
227**/\r
e52c5a9f 228VOID\r
7d582d6b 229EFIAPI\r
e52c5a9f 230HiiLibRemovePackages (\r
7d582d6b 231 IN EFI_HII_HANDLE HiiHandle\r
232 )\r
233{\r
e52c5a9f 234 EFI_STATUS Status;\r
e52c5a9f 235 ASSERT (HiiHandle != NULL);\r
54cf8780 236\r
237 LocateHiiProtocols ();\r
238\r
e52c5a9f 239 Status = mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle);\r
240 ASSERT_EFI_ERROR (Status);\r
7d582d6b 241}\r
242\r
e52c5a9f 243\r
ad1b3619 244/**\r
245 Determines the handles that are currently active in the database.\r
246 It's the caller's responsibility to free handle buffer.\r
247\r
248 If HandleBufferLength is NULL, then ASSERT.\r
249 If HiiHandleBuffer is NULL, then ASSERT.\r
250\r
251 @param HandleBufferLength On input, a pointer to the length of the handle\r
252 buffer. On output, the length of the handle buffer\r
253 that is required for the handles found.\r
254 @param HiiHandleBuffer Pointer to an array of Hii Handles returned.\r
255\r
256 @retval EFI_SUCCESS Get an array of Hii Handles successfully.\r
257\r
258**/\r
7d582d6b 259EFI_STATUS\r
260EFIAPI\r
e52c5a9f 261HiiLibGetHiiHandles (\r
262 IN OUT UINTN *HandleBufferLength,\r
263 OUT EFI_HII_HANDLE **HiiHandleBuffer\r
7d582d6b 264 )\r
265{\r
e52c5a9f 266 UINTN BufferLength;\r
7d582d6b 267 EFI_STATUS Status;\r
7d582d6b 268\r
e52c5a9f 269 ASSERT (HandleBufferLength != NULL);\r
270 ASSERT (HiiHandleBuffer != NULL);\r
7d582d6b 271\r
e52c5a9f 272 BufferLength = 0;\r
7d582d6b 273\r
54cf8780 274 LocateHiiProtocols ();\r
275\r
e52c5a9f 276 //\r
277 // Try to find the actual buffer size for HiiHandle Buffer.\r
278 //\r
279 Status = mHiiDatabaseProt->ListPackageLists (\r
280 mHiiDatabaseProt,\r
281 EFI_HII_PACKAGE_TYPE_ALL,\r
7d582d6b 282 NULL,\r
e52c5a9f 283 &BufferLength,\r
284 *HiiHandleBuffer\r
7d582d6b 285 );\r
7d582d6b 286\r
e52c5a9f 287 if (Status == EFI_BUFFER_TOO_SMALL) {\r
288 *HiiHandleBuffer = AllocateZeroPool (BufferLength);\r
289 Status = mHiiDatabaseProt->ListPackageLists (\r
290 mHiiDatabaseProt,\r
291 EFI_HII_PACKAGE_TYPE_ALL,\r
292 NULL,\r
293 &BufferLength,\r
294 *HiiHandleBuffer\r
295 );\r
296 //\r
297 // we should not fail here.\r
298 //\r
299 ASSERT_EFI_ERROR (Status);\r
7d582d6b 300 }\r
301\r
e52c5a9f 302 *HandleBufferLength = BufferLength;\r
7d582d6b 303\r
304 return Status;\r
305}\r
306\r
ad1b3619 307/**\r
308 Extract Hii package list GUID for given HII handle.\r
309\r
310 If HiiHandle could not be found in the default HII database, then ASSERT.\r
311 If Guid is NULL, then ASSERT.\r
312\r
313 @param Handle Hii handle\r
314 @param Guid Package list GUID\r
315\r
316 @retval EFI_SUCCESS Successfully extract GUID from Hii database.\r
317\r
318**/\r
7d582d6b 319EFI_STATUS\r
dd51a993 320EFIAPI\r
e52c5a9f 321HiiLibExtractGuidFromHiiHandle (\r
322 IN EFI_HII_HANDLE Handle,\r
323 OUT EFI_GUID *Guid\r
7d582d6b 324 )\r
325{\r
326 EFI_STATUS Status;\r
e52c5a9f 327 UINTN BufferSize;\r
328 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
7d582d6b 329\r
e52c5a9f 330 ASSERT (Guid != NULL);\r
7d582d6b 331\r
e52c5a9f 332 //\r
333 // Get HII PackageList\r
334 //\r
335 BufferSize = 0;\r
336 HiiPackageList = NULL;\r
54cf8780 337\r
338 LocateHiiProtocols ();\r
339\r
e52c5a9f 340 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
341 ASSERT (Status != EFI_NOT_FOUND);\r
342 \r
343 if (Status == EFI_BUFFER_TOO_SMALL) {\r
344 HiiPackageList = AllocatePool (BufferSize);\r
345 ASSERT (HiiPackageList != NULL);\r
7d582d6b 346\r
e52c5a9f 347 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
7d582d6b 348 }\r
7d582d6b 349 if (EFI_ERROR (Status)) {\r
350 return Status;\r
351 }\r
352\r
e52c5a9f 353 //\r
354 // Extract GUID\r
355 //\r
356 CopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));\r
7d582d6b 357\r
e52c5a9f 358 gBS->FreePool (HiiPackageList);\r
7d582d6b 359\r
360 return EFI_SUCCESS;\r
361}\r
362\r
ad1b3619 363/**\r
364 Find HII Handle in the default HII database associated with given Device Path.\r
365\r
366 If DevicePath is NULL, then ASSERT.\r
367\r
368 @param DevicePath Device Path associated with the HII package list\r
369 handle.\r
370\r
371 @retval Handle HII package list Handle associated with the Device\r
372 Path.\r
373 @retval NULL Hii Package list handle is not found.\r
374\r
375**/\r
e52c5a9f 376EFI_HII_HANDLE\r
377EFIAPI\r
378HiiLibDevicePathToHiiHandle (\r
379 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
7d582d6b 380 )\r
7d582d6b 381{\r
e52c5a9f 382 EFI_STATUS Status;\r
383 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
384 UINTN BufferSize;\r
385 UINTN HandleCount;\r
386 UINTN Index;\r
387 EFI_HANDLE *Handles;\r
388 EFI_HANDLE Handle;\r
389 UINTN Size;\r
390 EFI_HANDLE DriverHandle;\r
391 EFI_HII_HANDLE *HiiHandles;\r
392 EFI_HII_HANDLE HiiHandle;\r
7d582d6b 393\r
e52c5a9f 394 ASSERT (DevicePath != NULL);\r
7d582d6b 395\r
dd51a993 396 //\r
e52c5a9f 397 // Locate Device Path Protocol handle buffer\r
7d582d6b 398 //\r
e52c5a9f 399 Status = gBS->LocateHandleBuffer (\r
400 ByProtocol,\r
401 &gEfiDevicePathProtocolGuid,\r
7d582d6b 402 NULL,\r
e52c5a9f 403 &HandleCount,\r
404 &Handles\r
7d582d6b 405 );\r
406 if (EFI_ERROR (Status)) {\r
e52c5a9f 407 return NULL;\r
7d582d6b 408 }\r
409\r
410 //\r
e52c5a9f 411 // Search Driver Handle by Device Path\r
7d582d6b 412 //\r
e52c5a9f 413 DriverHandle = NULL;\r
414 BufferSize = GetDevicePathSize (DevicePath);\r
415 for(Index = 0; Index < HandleCount; Index++) {\r
416 Handle = Handles[Index];\r
417 gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);\r
418\r
419 //\r
420 // Check whether DevicePath match\r
421 //\r
422 Size = GetDevicePathSize (TmpDevicePath);\r
423 if ((Size == BufferSize) && CompareMem (DevicePath, TmpDevicePath, Size) == 0) {\r
424 DriverHandle = Handle;\r
425 break;\r
426 }\r
7d582d6b 427 }\r
e52c5a9f 428 gBS->FreePool (Handles);\r
429\r
430 if (DriverHandle == NULL) {\r
431 return NULL;\r
7d582d6b 432 }\r
433\r
54cf8780 434 LocateHiiProtocols ();\r
435\r
bad46384 436 //\r
e52c5a9f 437 // Retrieve all Hii Handles from HII database\r
7d582d6b 438 //\r
e52c5a9f 439 BufferSize = 0x1000;\r
440 HiiHandles = AllocatePool (BufferSize);\r
441 ASSERT (HiiHandles != NULL);\r
442 Status = mHiiDatabaseProt->ListPackageLists (\r
443 mHiiDatabaseProt,\r
444 EFI_HII_PACKAGE_TYPE_ALL,\r
445 NULL,\r
446 &BufferSize,\r
447 HiiHandles\r
448 );\r
449 if (Status == EFI_BUFFER_TOO_SMALL) {\r
450 gBS->FreePool (HiiHandles);\r
451 HiiHandles = AllocatePool (BufferSize);\r
452 ASSERT (HiiHandles != NULL);\r
453\r
454 Status = mHiiDatabaseProt->ListPackageLists (\r
455 mHiiDatabaseProt,\r
456 EFI_HII_PACKAGE_TYPE_ALL,\r
457 NULL,\r
458 &BufferSize,\r
459 HiiHandles\r
460 );\r
461 }\r
7d582d6b 462\r
e52c5a9f 463 if (EFI_ERROR (Status)) {\r
464 gBS->FreePool (HiiHandles);\r
465 return NULL;\r
466 }\r
7d582d6b 467\r
e52c5a9f 468 //\r
469 // Search Hii Handle by Driver Handle\r
470 //\r
471 HiiHandle = NULL;\r
472 HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
473 for (Index = 0; Index < HandleCount; Index++) {\r
474 Status = mHiiDatabaseProt->GetPackageListHandle (\r
475 mHiiDatabaseProt,\r
476 HiiHandles[Index],\r
477 &Handle\r
478 );\r
479 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
480 HiiHandle = HiiHandles[Index];\r
481 break;\r
7d582d6b 482 }\r
7d582d6b 483 }\r
484\r
e52c5a9f 485 gBS->FreePool (HiiHandles);\r
486 return HiiHandle;\r
487}\r
7d582d6b 488\r
ad1b3619 489/**\r
490 This function check if the Hii Handle is a valid handle registered\r
491 in the HII database.\r
492\r
493 @param HiiHandle The HII Handle.\r
494\r
495 @retval TRUE If it is a valid HII handle.\r
496 @retval FALSE If it is a invalid HII handle.\r
497**/\r
e52c5a9f 498BOOLEAN\r
499IsHiiHandleRegistered (\r
500 EFI_HII_HANDLE HiiHandle\r
501 )\r
502{\r
503 EFI_STATUS Status;\r
504 UINTN BufferSize;\r
505 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
506\r
507 ASSERT (HiiHandle != NULL);\r
508\r
509 HiiPackageList = NULL;\r
510 BufferSize = 0;\r
54cf8780 511\r
512 LocateHiiProtocols ();\r
513\r
e52c5a9f 514 Status = mHiiDatabaseProt->ExportPackageLists (\r
515 mHiiDatabaseProt,\r
516 HiiHandle,\r
517 &BufferSize,\r
518 HiiPackageList\r
519 );\r
520\r
521 return (BOOLEAN) (Status == EFI_BUFFER_TOO_SMALL);\r
dd51a993 522}\r
7d582d6b 523\r