]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/HiiLib/HiiLib.c
[Description]:
[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
e52c5a9f 170VOID\r
7d582d6b 171EFIAPI\r
e52c5a9f 172HiiLibRemovePackages (\r
7d582d6b 173 IN EFI_HII_HANDLE HiiHandle\r
174 )\r
175{\r
e52c5a9f 176 EFI_STATUS Status;\r
177\r
178 ASSERT (HiiHandle != NULL);\r
179 Status = mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle);\r
180 ASSERT_EFI_ERROR (Status);\r
7d582d6b 181}\r
182\r
e52c5a9f 183\r
7d582d6b 184EFI_STATUS\r
185EFIAPI\r
e52c5a9f 186HiiLibGetHiiHandles (\r
187 IN OUT UINTN *HandleBufferLength,\r
188 OUT EFI_HII_HANDLE **HiiHandleBuffer\r
7d582d6b 189 )\r
190{\r
e52c5a9f 191 UINTN BufferLength;\r
7d582d6b 192 EFI_STATUS Status;\r
7d582d6b 193\r
e52c5a9f 194 ASSERT (HandleBufferLength != NULL);\r
195 ASSERT (HiiHandleBuffer != NULL);\r
7d582d6b 196\r
e52c5a9f 197 BufferLength = 0;\r
7d582d6b 198\r
e52c5a9f 199 //\r
200 // Try to find the actual buffer size for HiiHandle Buffer.\r
201 //\r
202 Status = mHiiDatabaseProt->ListPackageLists (\r
203 mHiiDatabaseProt,\r
204 EFI_HII_PACKAGE_TYPE_ALL,\r
7d582d6b 205 NULL,\r
e52c5a9f 206 &BufferLength,\r
207 *HiiHandleBuffer\r
7d582d6b 208 );\r
7d582d6b 209\r
e52c5a9f 210 if (Status == EFI_BUFFER_TOO_SMALL) {\r
211 *HiiHandleBuffer = AllocateZeroPool (BufferLength);\r
212 Status = mHiiDatabaseProt->ListPackageLists (\r
213 mHiiDatabaseProt,\r
214 EFI_HII_PACKAGE_TYPE_ALL,\r
215 NULL,\r
216 &BufferLength,\r
217 *HiiHandleBuffer\r
218 );\r
219 //\r
220 // we should not fail here.\r
221 //\r
222 ASSERT_EFI_ERROR (Status);\r
7d582d6b 223 }\r
224\r
e52c5a9f 225 *HandleBufferLength = BufferLength;\r
7d582d6b 226\r
227 return Status;\r
228}\r
229\r
7d582d6b 230EFI_STATUS\r
dd51a993 231EFIAPI\r
e52c5a9f 232HiiLibExtractGuidFromHiiHandle (\r
233 IN EFI_HII_HANDLE Handle,\r
234 OUT EFI_GUID *Guid\r
7d582d6b 235 )\r
236{\r
237 EFI_STATUS Status;\r
e52c5a9f 238 UINTN BufferSize;\r
239 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
7d582d6b 240\r
e52c5a9f 241 ASSERT (Guid != NULL);\r
7d582d6b 242\r
e52c5a9f 243 //\r
244 // Get HII PackageList\r
245 //\r
246 BufferSize = 0;\r
247 HiiPackageList = NULL;\r
248 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
249 ASSERT (Status != EFI_NOT_FOUND);\r
250 \r
251 if (Status == EFI_BUFFER_TOO_SMALL) {\r
252 HiiPackageList = AllocatePool (BufferSize);\r
253 ASSERT (HiiPackageList != NULL);\r
7d582d6b 254\r
e52c5a9f 255 Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
7d582d6b 256 }\r
7d582d6b 257 if (EFI_ERROR (Status)) {\r
258 return Status;\r
259 }\r
260\r
e52c5a9f 261 //\r
262 // Extract GUID\r
263 //\r
264 CopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));\r
7d582d6b 265\r
e52c5a9f 266 gBS->FreePool (HiiPackageList);\r
7d582d6b 267\r
268 return EFI_SUCCESS;\r
269}\r
270\r
e52c5a9f 271EFI_HII_HANDLE\r
272EFIAPI\r
273HiiLibDevicePathToHiiHandle (\r
274 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
7d582d6b 275 )\r
7d582d6b 276{\r
e52c5a9f 277 EFI_STATUS Status;\r
278 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
279 UINTN BufferSize;\r
280 UINTN HandleCount;\r
281 UINTN Index;\r
282 EFI_HANDLE *Handles;\r
283 EFI_HANDLE Handle;\r
284 UINTN Size;\r
285 EFI_HANDLE DriverHandle;\r
286 EFI_HII_HANDLE *HiiHandles;\r
287 EFI_HII_HANDLE HiiHandle;\r
7d582d6b 288\r
e52c5a9f 289 ASSERT (DevicePath != NULL);\r
7d582d6b 290\r
dd51a993 291 //\r
e52c5a9f 292 // Locate Device Path Protocol handle buffer\r
7d582d6b 293 //\r
e52c5a9f 294 Status = gBS->LocateHandleBuffer (\r
295 ByProtocol,\r
296 &gEfiDevicePathProtocolGuid,\r
7d582d6b 297 NULL,\r
e52c5a9f 298 &HandleCount,\r
299 &Handles\r
7d582d6b 300 );\r
301 if (EFI_ERROR (Status)) {\r
e52c5a9f 302 return NULL;\r
7d582d6b 303 }\r
304\r
305 //\r
e52c5a9f 306 // Search Driver Handle by Device Path\r
7d582d6b 307 //\r
e52c5a9f 308 DriverHandle = NULL;\r
309 BufferSize = GetDevicePathSize (DevicePath);\r
310 for(Index = 0; Index < HandleCount; Index++) {\r
311 Handle = Handles[Index];\r
312 gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);\r
313\r
314 //\r
315 // Check whether DevicePath match\r
316 //\r
317 Size = GetDevicePathSize (TmpDevicePath);\r
318 if ((Size == BufferSize) && CompareMem (DevicePath, TmpDevicePath, Size) == 0) {\r
319 DriverHandle = Handle;\r
320 break;\r
321 }\r
7d582d6b 322 }\r
e52c5a9f 323 gBS->FreePool (Handles);\r
324\r
325 if (DriverHandle == NULL) {\r
326 return NULL;\r
7d582d6b 327 }\r
328\r
bad46384 329 //\r
e52c5a9f 330 // Retrieve all Hii Handles from HII database\r
7d582d6b 331 //\r
e52c5a9f 332 BufferSize = 0x1000;\r
333 HiiHandles = AllocatePool (BufferSize);\r
334 ASSERT (HiiHandles != NULL);\r
335 Status = mHiiDatabaseProt->ListPackageLists (\r
336 mHiiDatabaseProt,\r
337 EFI_HII_PACKAGE_TYPE_ALL,\r
338 NULL,\r
339 &BufferSize,\r
340 HiiHandles\r
341 );\r
342 if (Status == EFI_BUFFER_TOO_SMALL) {\r
343 gBS->FreePool (HiiHandles);\r
344 HiiHandles = AllocatePool (BufferSize);\r
345 ASSERT (HiiHandles != NULL);\r
346\r
347 Status = mHiiDatabaseProt->ListPackageLists (\r
348 mHiiDatabaseProt,\r
349 EFI_HII_PACKAGE_TYPE_ALL,\r
350 NULL,\r
351 &BufferSize,\r
352 HiiHandles\r
353 );\r
354 }\r
7d582d6b 355\r
e52c5a9f 356 if (EFI_ERROR (Status)) {\r
357 gBS->FreePool (HiiHandles);\r
358 return NULL;\r
359 }\r
7d582d6b 360\r
e52c5a9f 361 //\r
362 // Search Hii Handle by Driver Handle\r
363 //\r
364 HiiHandle = NULL;\r
365 HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
366 for (Index = 0; Index < HandleCount; Index++) {\r
367 Status = mHiiDatabaseProt->GetPackageListHandle (\r
368 mHiiDatabaseProt,\r
369 HiiHandles[Index],\r
370 &Handle\r
371 );\r
372 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
373 HiiHandle = HiiHandles[Index];\r
374 break;\r
7d582d6b 375 }\r
7d582d6b 376 }\r
377\r
e52c5a9f 378 gBS->FreePool (HiiHandles);\r
379 return HiiHandle;\r
380}\r
7d582d6b 381\r
e52c5a9f 382BOOLEAN\r
383IsHiiHandleRegistered (\r
384 EFI_HII_HANDLE HiiHandle\r
385 )\r
386{\r
387 EFI_STATUS Status;\r
388 UINTN BufferSize;\r
389 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
390\r
391 ASSERT (HiiHandle != NULL);\r
392\r
393 HiiPackageList = NULL;\r
394 BufferSize = 0;\r
395 Status = mHiiDatabaseProt->ExportPackageLists (\r
396 mHiiDatabaseProt,\r
397 HiiHandle,\r
398 &BufferSize,\r
399 HiiPackageList\r
400 );\r
401\r
402 return (BOOLEAN) (Status == EFI_BUFFER_TOO_SMALL);\r
dd51a993 403}\r
7d582d6b 404\r