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