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