]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c
Fix the bugs for DatahubGen module
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Package.c
CommitLineData
4259256b 1/**@file\r
2\r
3 This file contains the keyboard processing code to the HII database.\r
4\r
5Copyright (c) 2006 - 2008, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16\r
17#include "HiiDatabase.h"\r
18\r
19\r
20EFI_STATUS\r
21GetIfrAndStringPackNum (\r
22 IN CONST EFI_HII_PACKAGES *Packages,\r
23 UINTN *IfrPackNum,\r
24 UINTN *StringPackNum\r
25 )\r
26{\r
27 UINTN Index;\r
28 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
29\r
30 ASSERT (Packages != NULL);\r
31 ASSERT (IfrPackNum != NULL);\r
32 ASSERT (StringPackNum != NULL);\r
33\r
34 *IfrPackNum = 0;\r
35 *StringPackNum = 0;\r
36\r
37 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
38 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
39 //\r
40 // BugBug: The current UEFI HII build tool generate a binary in the format defined in: \r
41 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
42 // this binary is with same package type. So the returned IfrPackNum and StringPackNum\r
43 // may not be the exact number of valid package number in the binary generated \r
44 // by HII Build tool.\r
45 //\r
46 switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {\r
47 case EFI_HII_PACKAGE_FORM:\r
48 *IfrPackNum += 1;\r
49 break;\r
50 case EFI_HII_PACKAGE_STRINGS:\r
51 *StringPackNum += 1;\r
52 break;\r
53\r
54 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
55 break;\r
56\r
57 //\r
58 // The following fonts are invalid for a module that using Framework to UEFI thunk layer.\r
59 //\r
60 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
61 case EFI_HII_PACKAGE_FONTS:\r
62 case EFI_HII_PACKAGE_IMAGES:\r
63 default:\r
64 ASSERT (FALSE);\r
65 return EFI_INVALID_PARAMETER;\r
66 break;\r
67 }\r
68 }\r
69\r
70 return EFI_SUCCESS;\r
71}\r
72\r
73EFI_STATUS \r
74LibExportPackageLists (\r
75 IN EFI_HII_HANDLE UefiHiiHandle,\r
76 OUT EFI_HII_PACKAGE_LIST_HEADER **PackageListHeader,\r
77 OUT UINTN *PackageListSize\r
78 )\r
79{\r
80 EFI_STATUS Status;\r
81 UINTN Size;\r
82 EFI_HII_PACKAGE_LIST_HEADER *PackageListHdr;\r
83\r
84 ASSERT (PackageListSize != NULL);\r
85 ASSERT (PackageListHeader != NULL);\r
86\r
87 Size = 0;\r
88 PackageListHdr = NULL;\r
59336178 89 Status = mHiiDatabase->ExportPackageLists (\r
90 mHiiDatabase,\r
4259256b 91 UefiHiiHandle,\r
92 &Size,\r
93 PackageListHdr\r
94 );\r
95 ASSERT_EFI_ERROR (Status == EFI_BUFFER_TOO_SMALL);\r
96 if (Status == EFI_BUFFER_TOO_SMALL) {\r
97 PackageListHdr = AllocateZeroPool (Size);\r
98 ASSERT (PackageListHdr != NULL);\r
99 \r
100 if (PackageListHeader == NULL) {\r
101 return EFI_OUT_OF_RESOURCES;\r
102 } else {\r
59336178 103 Status = mHiiDatabase->ExportPackageLists (\r
104 mHiiDatabase,\r
4259256b 105 UefiHiiHandle,\r
106 &Size,\r
107 PackageListHdr\r
108 );\r
109 ASSERT_EFI_ERROR (Status);\r
110 }\r
111 }\r
112\r
113 if (!EFI_ERROR (Status)) {\r
114 *PackageListHeader = PackageListHdr;\r
115 *PackageListSize = Size;\r
116 }\r
117\r
118 return Status;\r
119}\r
120\r
121BOOLEAN\r
122IsOnlyStringPackagesInPackageList (\r
123 IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader\r
124 )\r
125{\r
126 EFI_HII_PACKAGE_HEADER *PackageHeader;\r
127\r
128 PackageHeader = (EFI_HII_PACKAGE_HEADER *) (StringPackageListHeader + 1);\r
129\r
130 while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
131 PackageHeader = (EFI_HII_PACKAGE_HEADER *) (PackageHeader );\r
132 }\r
133}\r
134 \r
135\r
136EFI_STATUS\r
137InsertStringPackagesToIfrPackageList (\r
138 IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader,\r
139 IN EFI_HII_HANDLE UefiHiiHandle \r
140 )\r
141{\r
142 EFI_STATUS Status;\r
59336178 143 Status = mHiiDatabase->UpdatePackageList (\r
144 mHiiDatabase,\r
4259256b 145 UefiHiiHandle,\r
146 StringPackageListHeader\r
147 );\r
148\r
149 return Status;\r
150}\r
151\r
152\r
153/**\r
154 Removes a node from a doubly linked list, and returns the node that follows\r
155 the removed node.\r
156\r
157 Removes the node Entry from a doubly linked list. It is up to the caller of\r
158 this function to release the memory used by this node if that is required. On\r
159 exit, the node following Entry in the doubly linked list is returned. If\r
160 Entry is the only node in the linked list, then the head node of the linked\r
161 list is returned.\r
162\r
163 If Entry is NULL, then ASSERT().\r
164 If Entry is the head node of an empty list, then ASSERT().\r
165 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
166 linked list containing Entry, including the Entry node, is greater than\r
167 or equal to PcdMaximumLinkedListLength, then ASSERT().\r
168\r
169 @param Entry A pointer to a node in a linked list\r
170\r
171 @return Entry\r
172\r
173**/\r
174EFI_STATUS\r
175AddStringPackagesToMatchingIfrPackageList (\r
176 IN EFI_HII_THUNK_PRIVATE_DATA *Private,\r
177 IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader\r
178 )\r
179{\r
180 EFI_STATUS Status;\r
181 LIST_ENTRY *ListEntry;\r
182 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
183\r
184 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
185 ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
186 ListEntry = ListEntry->ForwardLink\r
187 ) {\r
188 HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
189 if (CompareGuid (&StringPackageListHeader->PackageListGuid, &HandleMapEntry->TagGuid)) {\r
190 Status = InsertStringPackagesToIfrPackageList (StringPackageListHeader, HandleMapEntry->UefiHiiHandle);\r
191 }\r
192 }\r
193 \r
194 return EFI_NOT_FOUND;\r
195}\r
196EFI_HII_PACKAGE_LIST_HEADER *\r
197PrepareUefiPackageListFromFrameworkHiiPackages (\r
198 IN CONST EFI_HII_PACKAGES *Packages,\r
199 IN CONST EFI_GUID *GuidId OPTIONAL\r
200 )\r
201{\r
202 UINTN NumberOfPackages;\r
203 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
204 UINT8 *PackageListData;\r
205 UINT32 PackageListLength;\r
206 UINT32 PackageLength;\r
207 EFI_HII_PACKAGE_HEADER PackageHeader;\r
208 UINTN Index;\r
209 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
210\r
211 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) ((UINT8 *) &Packages->GuidId + sizeof (Packages->GuidId));\r
212 NumberOfPackages = Packages->NumberOfPackages;\r
213\r
214 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
215\r
216 for (Index = 0; Index < NumberOfPackages; Index++) {\r
217 CopyMem (&PackageLength, &TianoAutogenPackageHdrArray[Index]->BinaryLength, sizeof (UINT32));\r
99a83b4c 218 //\r
219 //TIANO_AUTOGEN_PACKAGES_HEADER.BinaryLength include the BinaryLength itself.\r
220 //\r
221 PackageListLength += (PackageLength - sizeof(UINT32)); \r
4259256b 222 }\r
223\r
224 //\r
225 // Include the lenght of EFI_HII_PACKAGE_END\r
226 //\r
227 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
228 PackageListHeader = AllocateZeroPool (PackageListLength);\r
229 ASSERT (PackageListHeader != NULL);\r
230 if (GuidId == NULL) {\r
231 CopyMem (&PackageListHeader->PackageListGuid, Packages->GuidId, sizeof (EFI_GUID));\r
232 } else {\r
233 CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));\r
234 }\r
235 PackageListHeader->PackageLength = PackageListLength;\r
236\r
237 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
238\r
239 for (Index = 0; Index < NumberOfPackages; Index++) {\r
240 CopyMem (&PackageLength, &(TianoAutogenPackageHdrArray[Index]->BinaryLength), sizeof (UINT32));\r
241 PackageLength -= sizeof (UINT32);\r
242 CopyMem (PackageListData, &(TianoAutogenPackageHdrArray[Index]->PackageHeader), PackageLength);\r
243 PackageListData += PackageLength;\r
244 }\r
245\r
246 //\r
247 // Append EFI_HII_PACKAGE_END\r
248 //\r
249 PackageHeader.Type = EFI_HII_PACKAGE_END;\r
250 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
251 CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
252\r
253 return PackageListHeader; \r
254}\r
255\r
59336178 256VOID\r
257GenerateGuidId (\r
258 IN CONST EFI_GUID * InGuid,\r
259 OUT EFI_GUID * OutGuid\r
4259256b 260 )\r
261{\r
4259256b 262 UINT64 MonotonicCount;\r
263\r
59336178 264 CopyMem (OutGuid, InGuid, sizeof (EFI_GUID));\r
4259256b 265 \r
266 gBS->GetNextMonotonicCount (&MonotonicCount);\r
267 //\r
268 // Use Monotonic Count as a psedo random number generator.\r
269 //\r
59336178 270 *((UINT64 *) OutGuid) = *((UINT64 *) OutGuid) + MonotonicCount;\r
4259256b 271}\r
272\r
273EFI_STATUS\r
274FindAndAddStringPackageToIfrPackageList(\r
275 EFI_HII_THUNK_PRIVATE_DATA *Private,\r
276 EFI_GUID *GuidId,\r
277 EFI_HII_HANDLE UefiIfrHiiHandle\r
278 )\r
279{\r
280 EFI_STATUS Status;\r
281 LIST_ENTRY *ListEntry;\r
282 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
283 EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;\r
284 UINTN Size;\r
285\r
286 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
287 ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
288 ListEntry = ListEntry->ForwardLink\r
289 ) {\r
290 HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
291 if (CompareGuid (GuidId, &HandleMapEntry->TagGuid) && (!HandleMapEntry->DoesPackageListImportStringPackages)) {\r
292 Status = LibExportPackageLists (HandleMapEntry->UefiHiiHandle, &StringPackageListHeader, &Size);\r
293 ASSERT_EFI_ERROR (Status);\r
294\r
295 //\r
296 // Add Function to only get only String Packages from the Package List\r
297 //\r
298\r
299 Status = InsertStringPackagesToIfrPackageList (StringPackageListHeader, UefiIfrHiiHandle);\r
300 ASSERT_EFI_ERROR (Status);\r
301 \r
302 FreePool (StringPackageListHeader);\r
303 return EFI_SUCCESS;\r
304 }\r
305 }\r
306\r
307 return EFI_NOT_FOUND;\r
308\r
309}\r
310\r
59336178 311CONST EFI_GUID mAGuid = \r
312 { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e } };\r
313\r
4259256b 314EFI_STATUS\r
315UefiRegisterPackageList(\r
316 EFI_HII_THUNK_PRIVATE_DATA *Private,\r
317 EFI_HII_PACKAGES *Packages,\r
318 FRAMEWORK_EFI_HII_HANDLE *Handle\r
319 )\r
320{\r
321 EFI_STATUS Status;\r
322 UINTN StringPackNum;\r
323 UINTN IfrPackNum;\r
324 EFI_HII_PACKAGE_LIST_HEADER *UefiPackageListHeader;\r
325 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;\r
59336178 326 EFI_GUID GuidId;\r
4259256b 327 EFI_HANDLE UefiHiiDriverHandle;\r
328\r
4259256b 329 UefiHiiDriverHandle = NULL;\r
330\r
331 Status = GetIfrAndStringPackNum (Packages, &IfrPackNum, &StringPackNum);\r
332 ASSERT_EFI_ERROR (Status);\r
59336178 333 //\r
334 // Thunk Layer only handle the following combinations of IfrPack, StringPkg and FontPack\r
335 //\r
336 if (IfrPackNum > 1) {\r
337 return EFI_UNSUPPORTED;\r
338 }\r
4259256b 339\r
340 HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry));\r
341 ASSERT (HandleMappingEntry != NULL);\r
342 \r
343 HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE;\r
344 HandleMappingEntry->FrameworkHiiHandle = Private->StaticHiiHandle++;\r
59336178 345\r
346 //\r
347 // Packages->GuidId may be NULL. In such case, caller of FramworkHii->NewPack is registering\r
348 // package with StringPack and IfrPack.\r
349 //\r
350 if (Packages->GuidId == NULL) {\r
351 Packages->GuidId = &GuidId;\r
352 GenerateGuidId (&mAGuid, Packages->GuidId);\r
353 }\r
354 \r
4259256b 355 CopyGuid (&HandleMappingEntry->TagGuid, Packages->GuidId);\r
356\r
357 if ((StringPackNum == 0) && (IfrPackNum != 0)) {\r
358 //\r
359 // UEFI HII database does not allow two package list with the same GUID.\r
360 // In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
361 // a PackageList with only IFR to a Package list the with String package.\r
362 //\r
59336178 363 GenerateGuidId (Packages->GuidId, &GuidId);\r
4259256b 364 }\r
365\r
366 //\r
367 // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
368 // that Setup Utility will load the Buffer Storage\r
369 //\r
370 if (IfrPackNum != 0) {\r
ebbd2793 371 InstallDefaultUefiConfigAccessProtocol (Packages, &UefiHiiDriverHandle, HandleMappingEntry);\r
4259256b 372 }\r
59336178 373 UefiPackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
374 Status = mHiiDatabase->NewPackageList (\r
375 mHiiDatabase,\r
4259256b 376 UefiPackageListHeader, \r
377 UefiHiiDriverHandle,\r
378 &HandleMappingEntry->UefiHiiHandle\r
379 );\r
380 ASSERT_EFI_ERROR (Status);\r
381 if (EFI_ERROR (Status)) {\r
382 goto Done;\r
383 }\r
384 \r
385 if (IfrPackNum == 0) {\r
386 if (StringPackNum != 0) {\r
387 //\r
388 // Look for a package list with IFR Pack which has already registed with HII Database\r
389 //\r
390 HandleMappingEntry->IsPackageListWithOnlyStringPackages = TRUE;\r
391 Status = AddStringPackagesToMatchingIfrPackageList (\r
392 Private,\r
393 UefiPackageListHeader\r
394 );\r
395\r
396 if (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND) {\r
397\r
398 if (Status == EFI_NOT_FOUND) {\r
399 Status = EFI_SUCCESS;\r
400 }\r
401 }\r
402 }\r
403 } else {\r
404 if (StringPackNum == 0) {\r
405 //\r
406 // Register the Package List to UEFI HII first.\r
407 //\r
408 Status = FindAndAddStringPackageToIfrPackageList (\r
409 Private,\r
410 Packages->GuidId,\r
411 HandleMappingEntry->UefiHiiHandle\r
412 );\r
413 ASSERT_EFI_ERROR (Status);\r
414 if (!EFI_ERROR (Status)) {\r
415 HandleMappingEntry->DoesPackageListImportStringPackages = TRUE;\r
416 }\r
417 }\r
418 }\r
419\r
420 if (!EFI_ERROR (Status)) {\r
421 InsertTailList (&Private->HiiThunkHandleMappingDBListHead, &HandleMappingEntry->List);\r
422 }\r
423\r
424Done:\r
425 if (EFI_ERROR (Status)) {\r
426 FreePool (HandleMappingEntry);\r
427 } else {\r
428 *Handle = HandleMappingEntry->FrameworkHiiHandle;\r
429 }\r
430\r
431 FreePool (UefiPackageListHeader);\r
4259256b 432 \r
433 return Status;\r
434}\r
435\r
436EFI_STATUS\r
437EFIAPI\r
438HiiNewPack (\r
439 IN EFI_HII_PROTOCOL *This,\r
440 IN EFI_HII_PACKAGES *Packages,\r
441 OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
442 )\r
443/*++\r
444\r
445Routine Description:\r
446\r
447 Extracts the various packs from a package list.\r
448\r
449Arguments:\r
450\r
451 This - Pointer of HII protocol.\r
452 Packages - Pointer of HII packages.\r
453 Handle - Handle value to be returned.\r
454\r
455Returns:\r
456\r
457 EFI_SUCCESS - Pacakges has added to HII database successfully.\r
458 EFI_INVALID_PARAMETER - Invalid parameter.\r
459\r
460--*/\r
461{\r
462 EFI_STATUS Status;\r
463 EFI_HII_THUNK_PRIVATE_DATA *Private;\r
464\r
465 if (Handle == NULL) {\r
466 return EFI_INVALID_PARAMETER;\r
467 }\r
468\r
469 if (Packages == NULL) {\r
470 return EFI_INVALID_PARAMETER;\r
471 }\r
472\r
473 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
474\r
475 Status = UefiRegisterPackageList (\r
476 Private,\r
477 Packages,\r
478 Handle\r
479 );\r
480\r
481 return Status;\r
482}\r
483\r
484EFI_STATUS\r
485EFIAPI\r
486HiiRemovePack (\r
487 IN EFI_HII_PROTOCOL *This,\r
488 IN FRAMEWORK_EFI_HII_HANDLE Handle\r
489 )\r
490/*++\r
491\r
492Routine Description:\r
493 Removes the various packs from a Handle\r
494\r
495Arguments:\r
496\r
497Returns:\r
498\r
499--*/\r
500{\r
501 EFI_STATUS Status;\r
502 EFI_HII_THUNK_PRIVATE_DATA *Private;\r
4259256b 503 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
99a83b4c 504 EFI_DEVICE_PATH_PROTOCOL *Path;\r
4259256b 505\r
506 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
507\r
99a83b4c 508 HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
4259256b 509\r
99a83b4c 510 if (HandleMapEntry->UefiHiiHandle != NULL) {\r
59336178 511 Status = mHiiDatabase->RemovePackageList (\r
512 mHiiDatabase,\r
99a83b4c 513 HandleMapEntry->UefiHiiHandle\r
514 );\r
515 ASSERT_EFI_ERROR (Status);\r
516\r
517 Status = gBS->HandleProtocol (\r
518 HandleMapEntry->UefiHiiHandle,\r
519 &gEfiDevicePathProtocolGuid,\r
520 &Path\r
521 );\r
522\r
523 if (!EFI_ERROR (Status)) {\r
524 Status = gBS->UninstallProtocolInterface (\r
525 HandleMapEntry->UefiHiiHandle,\r
526 &gEfiDevicePathProtocolGuid,\r
527 Path\r
528 );\r
529 if (!EFI_ERROR (Status)) {\r
530 FreePool (Path);\r
531 }\r
4259256b 532 }\r
99a83b4c 533\r
534 RemoveEntryList (&HandleMapEntry->List);\r
535\r
536 FreePool (HandleMapEntry);\r
537 return Status;\r
4259256b 538 }\r
539\r
540 return EFI_NOT_FOUND;\r
541}\r