]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/HiiLib/HiiLib.c
Remove the OPTIONAL modifier as HiiHandle is a compulsory para.
[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
26 @param VOID\r
27\r
28 @retval VOID\r
e52c5a9f 29\r
30**/\r
54cf8780 31VOID\r
32LocateHiiProtocols (\r
33 VOID\r
7d582d6b 34 )\r
35{\r
54cf8780 36 EFI_STATUS Status;\r
37\r
38 if (mHiiProtocolsInitialized) {\r
39 return;\r
40 }\r
41\r
42 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabaseProt);\r
7d582d6b 43 ASSERT_EFI_ERROR (Status);\r
7d582d6b 44\r
54cf8780 45 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &mHiiStringProt);\r
7d582d6b 46 ASSERT_EFI_ERROR (Status);\r
7d582d6b 47\r
54cf8780 48 mHiiProtocolsInitialized = TRUE;\r
7d582d6b 49}\r
50\r
7d582d6b 51\r
52\r
53EFI_HII_PACKAGE_LIST_HEADER *\r
54InternalHiiLibPreparePackages (\r
55 IN UINTN NumberOfPackages,\r
56 IN CONST EFI_GUID *GuidId, OPTIONAL\r
57 VA_LIST Marker\r
58 )\r
59{\r
60 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
61 UINT8 *PackageListData;\r
62 UINT32 PackageListLength;\r
63 UINT32 PackageLength;\r
64 EFI_HII_PACKAGE_HEADER PackageHeader;\r
65 UINT8 *PackageArray;\r
66 UINTN Index;\r
67 VA_LIST MarkerBackup;\r
68\r
69 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
70\r
71 MarkerBackup = Marker;\r
72 \r
73 for (Index = 0; Index < NumberOfPackages; Index++) {\r
74 CopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));\r
75 PackageListLength += (PackageLength - sizeof (UINT32));\r
76 }\r
77\r
78 //\r
79 // Include the lenght of EFI_HII_PACKAGE_END\r
80 //\r
81 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
82 PackageListHeader = AllocateZeroPool (PackageListLength);\r
83 ASSERT (PackageListHeader != NULL);\r
84 CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));\r
85 PackageListHeader->PackageLength = PackageListLength;\r
86\r
87 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
88\r
89 Marker = MarkerBackup;\r
90 for (Index = 0; Index < NumberOfPackages; Index++) {\r
91 PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);\r
92 CopyMem (&PackageLength, PackageArray, sizeof (UINT32));\r
93 PackageLength -= sizeof (UINT32);\r
94 PackageArray += sizeof (UINT32);\r
95 CopyMem (PackageListData, PackageArray, PackageLength);\r
96 PackageListData += PackageLength;\r
97 }\r
98\r
99 //\r
100 // Append EFI_HII_PACKAGE_END\r
101 //\r
102 PackageHeader.Type = EFI_HII_PACKAGE_END;\r
103 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
104 CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
105\r
106 return PackageListHeader;\r
107}\r
108\r
109EFI_HII_PACKAGE_LIST_HEADER *\r
110EFIAPI\r
111HiiLibPreparePackageList (\r
112 IN UINTN NumberOfPackages,\r
113 IN CONST EFI_GUID *GuidId,\r
114 ...\r
115 )\r
7d582d6b 116{\r
117 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
118 VA_LIST Marker;\r
119\r
e52c5a9f 120 ASSERT (GuidId != NULL);\r
121\r
7d582d6b 122 VA_START (Marker, GuidId);\r
123 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Marker);\r
124 VA_END (Marker);\r
125\r
126 return PackageListHeader;\r
127}\r
128\r
bad46384 129\r
7d582d6b 130EFI_STATUS\r
131EFIAPI\r
e52c5a9f 132HiiLibAddPackages (\r
7d582d6b 133 IN UINTN NumberOfPackages,\r
134 IN CONST EFI_GUID *GuidId,\r
135 IN EFI_HANDLE DriverHandle, OPTIONAL\r
2a10d874 136 OUT EFI_HII_HANDLE *HiiHandle,\r
7d582d6b 137 ...\r
138 )\r
139{\r
140 VA_LIST Args;\r
141 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
142 EFI_STATUS Status;\r
143\r
e52c5a9f 144 ASSERT (HiiHandle != NULL);\r
7d582d6b 145\r
54cf8780 146 LocateHiiProtocols ();\r
147\r
7d582d6b 148 VA_START (Args, HiiHandle);\r
149 PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Args);\r
150\r
151 Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageListHeader, DriverHandle, HiiHandle);\r
152 if (HiiHandle != NULL) {\r
153 if (EFI_ERROR (Status)) {\r
154 *HiiHandle = NULL;\r
155 }\r
156 }\r
157\r
158 FreePool (PackageListHeader);\r
159 VA_END (Args);\r
160 \r
161 return Status;\r
162}\r
163\r
e52c5a9f 164VOID\r
7d582d6b 165EFIAPI\r
e52c5a9f 166HiiLibRemovePackages (\r
7d582d6b 167 IN EFI_HII_HANDLE HiiHandle\r
168 )\r
169{\r
e52c5a9f 170 EFI_STATUS Status;\r
e52c5a9f 171 ASSERT (HiiHandle != NULL);\r
54cf8780 172\r
173 LocateHiiProtocols ();\r
174\r
e52c5a9f 175 Status = mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle);\r
176 ASSERT_EFI_ERROR (Status);\r
7d582d6b 177}\r
178\r
e52c5a9f 179\r
7d582d6b 180EFI_STATUS\r
181EFIAPI\r
e52c5a9f 182HiiLibGetHiiHandles (\r
183 IN OUT UINTN *HandleBufferLength,\r
184 OUT EFI_HII_HANDLE **HiiHandleBuffer\r
7d582d6b 185 )\r
186{\r
e52c5a9f 187 UINTN BufferLength;\r
7d582d6b 188 EFI_STATUS Status;\r
7d582d6b 189\r
e52c5a9f 190 ASSERT (HandleBufferLength != NULL);\r
191 ASSERT (HiiHandleBuffer != NULL);\r
7d582d6b 192\r
e52c5a9f 193 BufferLength = 0;\r
7d582d6b 194\r
54cf8780 195 LocateHiiProtocols ();\r
196\r
e52c5a9f 197 //\r
198 // Try to find the actual buffer size for HiiHandle Buffer.\r
199 //\r
200 Status = mHiiDatabaseProt->ListPackageLists (\r
201 mHiiDatabaseProt,\r
202 EFI_HII_PACKAGE_TYPE_ALL,\r
7d582d6b 203 NULL,\r
e52c5a9f 204 &BufferLength,\r
205 *HiiHandleBuffer\r
7d582d6b 206 );\r
7d582d6b 207\r
e52c5a9f 208 if (Status == EFI_BUFFER_TOO_SMALL) {\r
209 *HiiHandleBuffer = AllocateZeroPool (BufferLength);\r
210 Status = mHiiDatabaseProt->ListPackageLists (\r
211 mHiiDatabaseProt,\r
212 EFI_HII_PACKAGE_TYPE_ALL,\r
213 NULL,\r
214 &BufferLength,\r
215 *HiiHandleBuffer\r
216 );\r
217 //\r
218 // we should not fail here.\r
219 //\r
220 ASSERT_EFI_ERROR (Status);\r
7d582d6b 221 }\r
222\r
e52c5a9f 223 *HandleBufferLength = BufferLength;\r
7d582d6b 224\r
225 return Status;\r
226}\r
227\r
7d582d6b 228EFI_STATUS\r
dd51a993 229EFIAPI\r
e52c5a9f 230HiiLibExtractGuidFromHiiHandle (\r
231 IN EFI_HII_HANDLE Handle,\r
232 OUT EFI_GUID *Guid\r
7d582d6b 233 )\r
234{\r
235 EFI_STATUS Status;\r
e52c5a9f 236 UINTN BufferSize;\r
237 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
7d582d6b 238\r
e52c5a9f 239 ASSERT (Guid != NULL);\r
7d582d6b 240\r
e52c5a9f 241 //\r
242 // Get HII PackageList\r
243 //\r
244 BufferSize = 0;\r
245 HiiPackageList = NULL;\r
54cf8780 246\r
247 LocateHiiProtocols ();\r
248\r
e52c5a9f 249 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
250 ASSERT (Status != EFI_NOT_FOUND);\r
251 \r
252 if (Status == EFI_BUFFER_TOO_SMALL) {\r
253 HiiPackageList = AllocatePool (BufferSize);\r
254 ASSERT (HiiPackageList != NULL);\r
7d582d6b 255\r
e52c5a9f 256 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
7d582d6b 257 }\r
7d582d6b 258 if (EFI_ERROR (Status)) {\r
259 return Status;\r
260 }\r
261\r
e52c5a9f 262 //\r
263 // Extract GUID\r
264 //\r
265 CopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));\r
7d582d6b 266\r
e52c5a9f 267 gBS->FreePool (HiiPackageList);\r
7d582d6b 268\r
269 return EFI_SUCCESS;\r
270}\r
271\r
e52c5a9f 272EFI_HII_HANDLE\r
273EFIAPI\r
274HiiLibDevicePathToHiiHandle (\r
275 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
7d582d6b 276 )\r
7d582d6b 277{\r
e52c5a9f 278 EFI_STATUS Status;\r
279 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
280 UINTN BufferSize;\r
281 UINTN HandleCount;\r
282 UINTN Index;\r
283 EFI_HANDLE *Handles;\r
284 EFI_HANDLE Handle;\r
285 UINTN Size;\r
286 EFI_HANDLE DriverHandle;\r
287 EFI_HII_HANDLE *HiiHandles;\r
288 EFI_HII_HANDLE HiiHandle;\r
7d582d6b 289\r
e52c5a9f 290 ASSERT (DevicePath != NULL);\r
7d582d6b 291\r
dd51a993 292 //\r
e52c5a9f 293 // Locate Device Path Protocol handle buffer\r
7d582d6b 294 //\r
e52c5a9f 295 Status = gBS->LocateHandleBuffer (\r
296 ByProtocol,\r
297 &gEfiDevicePathProtocolGuid,\r
7d582d6b 298 NULL,\r
e52c5a9f 299 &HandleCount,\r
300 &Handles\r
7d582d6b 301 );\r
302 if (EFI_ERROR (Status)) {\r
e52c5a9f 303 return NULL;\r
7d582d6b 304 }\r
305\r
306 //\r
e52c5a9f 307 // Search Driver Handle by Device Path\r
7d582d6b 308 //\r
e52c5a9f 309 DriverHandle = NULL;\r
310 BufferSize = GetDevicePathSize (DevicePath);\r
311 for(Index = 0; Index < HandleCount; Index++) {\r
312 Handle = Handles[Index];\r
313 gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);\r
314\r
315 //\r
316 // Check whether DevicePath match\r
317 //\r
318 Size = GetDevicePathSize (TmpDevicePath);\r
319 if ((Size == BufferSize) && CompareMem (DevicePath, TmpDevicePath, Size) == 0) {\r
320 DriverHandle = Handle;\r
321 break;\r
322 }\r
7d582d6b 323 }\r
e52c5a9f 324 gBS->FreePool (Handles);\r
325\r
326 if (DriverHandle == NULL) {\r
327 return NULL;\r
7d582d6b 328 }\r
329\r
54cf8780 330 LocateHiiProtocols ();\r
331\r
bad46384 332 //\r
e52c5a9f 333 // Retrieve all Hii Handles from HII database\r
7d582d6b 334 //\r
e52c5a9f 335 BufferSize = 0x1000;\r
336 HiiHandles = AllocatePool (BufferSize);\r
337 ASSERT (HiiHandles != NULL);\r
338 Status = mHiiDatabaseProt->ListPackageLists (\r
339 mHiiDatabaseProt,\r
340 EFI_HII_PACKAGE_TYPE_ALL,\r
341 NULL,\r
342 &BufferSize,\r
343 HiiHandles\r
344 );\r
345 if (Status == EFI_BUFFER_TOO_SMALL) {\r
346 gBS->FreePool (HiiHandles);\r
347 HiiHandles = AllocatePool (BufferSize);\r
348 ASSERT (HiiHandles != NULL);\r
349\r
350 Status = mHiiDatabaseProt->ListPackageLists (\r
351 mHiiDatabaseProt,\r
352 EFI_HII_PACKAGE_TYPE_ALL,\r
353 NULL,\r
354 &BufferSize,\r
355 HiiHandles\r
356 );\r
357 }\r
7d582d6b 358\r
e52c5a9f 359 if (EFI_ERROR (Status)) {\r
360 gBS->FreePool (HiiHandles);\r
361 return NULL;\r
362 }\r
7d582d6b 363\r
e52c5a9f 364 //\r
365 // Search Hii Handle by Driver Handle\r
366 //\r
367 HiiHandle = NULL;\r
368 HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
369 for (Index = 0; Index < HandleCount; Index++) {\r
370 Status = mHiiDatabaseProt->GetPackageListHandle (\r
371 mHiiDatabaseProt,\r
372 HiiHandles[Index],\r
373 &Handle\r
374 );\r
375 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
376 HiiHandle = HiiHandles[Index];\r
377 break;\r
7d582d6b 378 }\r
7d582d6b 379 }\r
380\r
e52c5a9f 381 gBS->FreePool (HiiHandles);\r
382 return HiiHandle;\r
383}\r
7d582d6b 384\r
e52c5a9f 385BOOLEAN\r
386IsHiiHandleRegistered (\r
387 EFI_HII_HANDLE HiiHandle\r
388 )\r
389{\r
390 EFI_STATUS Status;\r
391 UINTN BufferSize;\r
392 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
393\r
394 ASSERT (HiiHandle != NULL);\r
395\r
396 HiiPackageList = NULL;\r
397 BufferSize = 0;\r
54cf8780 398\r
399 LocateHiiProtocols ();\r
400\r
e52c5a9f 401 Status = mHiiDatabaseProt->ExportPackageLists (\r
402 mHiiDatabaseProt,\r
403 HiiHandle,\r
404 &BufferSize,\r
405 HiiPackageList\r
406 );\r
407\r
408 return (BOOLEAN) (Status == EFI_BUFFER_TOO_SMALL);\r
dd51a993 409}\r
7d582d6b 410\r