]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
Some HII related definitions change. Note these changes are inconsistent with current...
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
CommitLineData
93e3992d 1/** @file\r
e90b081a 2Implementation for EFI_HII_DATABASE_PROTOCOL.\r
3\r
aa2614b7 4Copyright (c) 2007 - 2009, Intel Corporation\r
93e3992d 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
93e3992d 13**/\r
14\r
15\r
16#include "HiiDatabase.h"\r
17\r
18//\r
19// Global variables\r
20//\r
fe1e36e5 21EFI_GUID mHiiDatabaseNotifyGuid = HII_DATABASE_NOTIFY_GUID;\r
93e3992d 22\r
23\r
24/**\r
25 This function generates a HII_DATABASE_RECORD node and adds into hii database.\r
e90b081a 26 This is a internal function.\r
93e3992d 27\r
28 @param Private hii database private structure\r
e90b081a 29 @param DatabaseNode HII_DATABASE_RECORD node which is used to store a\r
93e3992d 30 package list\r
31\r
32 @retval EFI_SUCCESS A database record is generated successfully.\r
33 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
34 database contents.\r
35 @retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL.\r
36\r
37**/\r
93e3992d 38EFI_STATUS\r
39GenerateHiiDatabaseRecord (\r
40 IN HII_DATABASE_PRIVATE_DATA *Private,\r
41 OUT HII_DATABASE_RECORD **DatabaseNode\r
42 )\r
43{\r
44 HII_DATABASE_RECORD *DatabaseRecord;\r
45 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
46 HII_HANDLE *HiiHandle;\r
47\r
48 if (Private == NULL || DatabaseNode == NULL) {\r
49 return EFI_INVALID_PARAMETER;\r
50 }\r
51\r
52 DatabaseRecord = (HII_DATABASE_RECORD *) AllocateZeroPool (sizeof (HII_DATABASE_RECORD));\r
53 if (DatabaseRecord == NULL) {\r
54 return EFI_OUT_OF_RESOURCES;\r
55 }\r
56 DatabaseRecord->Signature = HII_DATABASE_RECORD_SIGNATURE;\r
57\r
58 DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE));\r
59 if (DatabaseRecord->PackageList == NULL) {\r
676df92c 60 FreePool (DatabaseRecord);\r
93e3992d 61 return EFI_OUT_OF_RESOURCES;\r
62 }\r
63\r
64 PackageList = DatabaseRecord->PackageList;\r
65\r
66 InitializeListHead (&PackageList->GuidPkgHdr);\r
67 InitializeListHead (&PackageList->FormPkgHdr);\r
68 InitializeListHead (&PackageList->KeyboardLayoutHdr);\r
69 InitializeListHead (&PackageList->StringPkgHdr);\r
70 InitializeListHead (&PackageList->FontPkgHdr);\r
71 InitializeListHead (&PackageList->SimpleFontPkgHdr);\r
72 PackageList->ImagePkg = NULL;\r
73 PackageList->DevicePathPkg = NULL;\r
74\r
75 //\r
76 // Create a new hii handle\r
77 //\r
78 HiiHandle = (HII_HANDLE *) AllocateZeroPool (sizeof (HII_HANDLE));\r
79 if (HiiHandle == NULL) {\r
676df92c 80 FreePool (DatabaseRecord->PackageList);\r
81 FreePool (DatabaseRecord);\r
93e3992d 82 return EFI_OUT_OF_RESOURCES;\r
83 }\r
84 HiiHandle->Signature = HII_HANDLE_SIGNATURE;\r
85 //\r
86 // Backup the number of Hii handles\r
87 //\r
88 Private->HiiHandleCount++;\r
89 HiiHandle->Key = Private->HiiHandleCount;\r
90 //\r
91 // Insert the handle to hii handle list of the whole database.\r
92 //\r
93 InsertTailList (&Private->HiiHandleList, &HiiHandle->Handle);\r
94\r
95 DatabaseRecord->Handle = (EFI_HII_HANDLE) HiiHandle;\r
96\r
97 //\r
98 // Insert the Package List node to Package List link of the whole database.\r
99 //\r
100 InsertTailList (&Private->DatabaseList, &DatabaseRecord->DatabaseEntry);\r
101\r
102 *DatabaseNode = DatabaseRecord;\r
103\r
104 return EFI_SUCCESS;\r
105\r
106}\r
107\r
108\r
109/**\r
110 This function checks whether a handle is a valid EFI_HII_HANDLE\r
e90b081a 111 This is a internal function.\r
93e3992d 112\r
113 @param Handle Pointer to a EFI_HII_HANDLE\r
114\r
115 @retval TRUE Valid\r
116 @retval FALSE Invalid\r
117\r
118**/\r
119BOOLEAN\r
120IsHiiHandleValid (\r
121 EFI_HII_HANDLE Handle\r
122 )\r
123{\r
124 HII_HANDLE *HiiHandle;\r
125\r
126 HiiHandle = (HII_HANDLE *) Handle;\r
127\r
128 if (HiiHandle == NULL) {\r
129 return FALSE;\r
130 }\r
131\r
132 if (HiiHandle->Signature != HII_HANDLE_SIGNATURE) {\r
133 return FALSE;\r
134 }\r
135\r
136 return TRUE;\r
137}\r
138\r
139\r
140/**\r
141 This function invokes the matching registered function.\r
e90b081a 142 This is a internal function.\r
93e3992d 143\r
144 @param Private HII Database driver private structure.\r
145 @param NotifyType The type of change concerning the database.\r
146 @param PackageInstance Points to the package referred to by the\r
147 notification.\r
148 @param PackageType Package type\r
149 @param Handle The handle of the package list which contains the\r
150 specified package.\r
151\r
152 @retval EFI_SUCCESS Already checked all registered function and\r
153 invoked if matched.\r
154 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
155\r
156**/\r
93e3992d 157EFI_STATUS\r
158InvokeRegisteredFunction (\r
159 IN HII_DATABASE_PRIVATE_DATA *Private,\r
160 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
161 IN VOID *PackageInstance,\r
162 IN UINT8 PackageType,\r
163 IN EFI_HII_HANDLE Handle\r
164 )\r
165{\r
166 HII_DATABASE_NOTIFY *Notify;\r
167 LIST_ENTRY *Link;\r
168 EFI_HII_PACKAGE_HEADER *Package;\r
169 UINT8 *Buffer;\r
170 UINT32 BufferSize;\r
171 UINT32 HeaderSize;\r
172 UINT32 ImageBlockSize;\r
173 UINT32 PaletteInfoSize;\r
174\r
175 if (Private == NULL || (NotifyType & 0xF) == 0 || PackageInstance == NULL) {\r
176 return EFI_INVALID_PARAMETER;\r
177 }\r
178 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
179 return EFI_INVALID_PARAMETER;\r
180 }\r
181 if (!IsHiiHandleValid (Handle)) {\r
182 return EFI_INVALID_PARAMETER;\r
183 }\r
184\r
185 Buffer = NULL;\r
186 Package = NULL;\r
187\r
188 //\r
189 // Convert the incoming package from hii database storage format to UEFI\r
190 // storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR.\r
191 //\r
192 switch (PackageType) {\r
193 case EFI_HII_PACKAGE_TYPE_GUID:\r
194 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg);\r
195 break;\r
196\r
8d00a0f1 197 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 198 BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length;\r
199 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
200 ASSERT (Buffer != NULL);\r
201 CopyMem (\r
202 Buffer,\r
203 &((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr,\r
204 sizeof (EFI_HII_PACKAGE_HEADER)\r
205 );\r
206 CopyMem (\r
207 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),\r
208 ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->IfrData,\r
209 BufferSize - sizeof (EFI_HII_PACKAGE_HEADER)\r
210 );\r
211 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
212 break;\r
213\r
214 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
215 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *) PackageInstance)->KeyboardPkg);\r
216 break;\r
217\r
218 case EFI_HII_PACKAGE_STRINGS:\r
219 BufferSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->Header.Length;\r
220 HeaderSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->HdrSize;\r
221 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
222 ASSERT (Buffer != NULL);\r
223 CopyMem (\r
224 Buffer,\r
225 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr,\r
226 HeaderSize\r
227 );\r
228 CopyMem (\r
229 Buffer + HeaderSize,\r
230 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringBlock,\r
231 BufferSize - HeaderSize\r
232 );\r
233 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
234 break;\r
235\r
236 case EFI_HII_PACKAGE_FONTS:\r
237 BufferSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->Header.Length;\r
238 HeaderSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->HdrSize;\r
239 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
240 ASSERT (Buffer != NULL);\r
241 CopyMem (\r
242 Buffer,\r
243 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr,\r
244 HeaderSize\r
245 );\r
246 CopyMem (\r
247 Buffer + HeaderSize,\r
248 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->GlyphBlock,\r
249 BufferSize - HeaderSize\r
250 );\r
251 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
252 break;\r
253\r
254 case EFI_HII_PACKAGE_IMAGES:\r
255 BufferSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr.Header.Length;\r
256 HeaderSize = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
257 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
258 ASSERT (Buffer != NULL);\r
259\r
260 CopyMem (\r
261 Buffer,\r
262 &((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr,\r
263 HeaderSize\r
264 );\r
265 CopyMem (\r
266 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),\r
267 &HeaderSize,\r
268 sizeof (UINT32)\r
269 );\r
270\r
271 ImageBlockSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlockSize;\r
272 if (ImageBlockSize != 0) {\r
273 CopyMem (\r
274 Buffer + HeaderSize,\r
275 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlock,\r
276 ImageBlockSize\r
277 );\r
278 }\r
279\r
280 PaletteInfoSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteInfoSize;\r
281 if (PaletteInfoSize != 0) {\r
282 CopyMem (\r
283 Buffer + HeaderSize + ImageBlockSize,\r
284 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteBlock,\r
285 PaletteInfoSize\r
286 );\r
287 HeaderSize += ImageBlockSize;\r
288 CopyMem (\r
289 Buffer + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT32),\r
290 &HeaderSize,\r
291 sizeof (UINT32)\r
292 );\r
293 }\r
294 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
295 break;\r
296\r
297 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
298 BufferSize = ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr->Header.Length;\r
299 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
300 ASSERT (Buffer != NULL);\r
301 CopyMem (\r
302 Buffer,\r
303 ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr,\r
304 BufferSize\r
305 );\r
306 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
307 break;\r
308\r
309 case EFI_HII_PACKAGE_DEVICE_PATH:\r
310 Package = (EFI_HII_PACKAGE_HEADER *) PackageInstance;\r
311 break;\r
312\r
313 default:\r
314 return EFI_INVALID_PARAMETER;\r
315 }\r
316\r
317 for (Link = Private->DatabaseNotifyList.ForwardLink;\r
318 Link != &Private->DatabaseNotifyList;\r
319 Link = Link->ForwardLink\r
320 ) {\r
321 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);\r
322 if (Notify->NotifyType == NotifyType && Notify->PackageType == PackageType) {\r
323 //\r
324 // Check in case PackageGuid is not NULL when Package is GUID package\r
325 //\r
326 if (PackageType != EFI_HII_PACKAGE_TYPE_GUID) {\r
327 Notify->PackageGuid = NULL;\r
328 }\r
329 //\r
330 // Status of Registered Function is unknown so did not check it\r
331 //\r
332 Notify->PackageNotifyFn (\r
333 Notify->PackageType,\r
334 Notify->PackageGuid,\r
335 Package,\r
336 Handle,\r
337 NotifyType\r
338 );\r
339 }\r
340 }\r
341\r
676df92c 342 if (Buffer != NULL) {\r
343 FreePool (Buffer);\r
344 }\r
93e3992d 345\r
346 return EFI_SUCCESS;\r
347}\r
348\r
349\r
350/**\r
351 This function insert a GUID package to a package list node.\r
e90b081a 352 This is a internal function.\r
93e3992d 353\r
354 @param PackageHdr Pointer to a buffer stored with GUID package\r
355 information.\r
356 @param NotifyType The type of change concerning the database.\r
357 @param PackageList Pointer to a package list which will be inserted\r
358 to.\r
359 @param Package Created GUID pacakge\r
360\r
361 @retval EFI_SUCCESS Guid Package is inserted successfully.\r
362 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
363 Guid package.\r
364 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
365\r
366**/\r
93e3992d 367EFI_STATUS\r
368InsertGuidPackage (\r
369 IN VOID *PackageHdr,\r
370 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
371 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
372 OUT HII_GUID_PACKAGE_INSTANCE **Package\r
373 )\r
374{\r
375 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
376 EFI_HII_PACKAGE_HEADER PackageHeader;\r
377\r
378 if (PackageHdr == NULL || PackageList == NULL) {\r
379 return EFI_INVALID_PARAMETER;\r
380 }\r
381\r
382 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
383\r
384 //\r
385 // Create a GUID package node\r
386 //\r
387 GuidPackage = (HII_GUID_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE));\r
388 if (GuidPackage == NULL) {\r
389 return EFI_OUT_OF_RESOURCES;\r
390 }\r
391 GuidPackage->GuidPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);\r
392 if (GuidPackage->GuidPkg == NULL) {\r
676df92c 393 FreePool (GuidPackage);\r
93e3992d 394 return EFI_OUT_OF_RESOURCES;\r
395 }\r
396\r
397 GuidPackage->Signature = HII_GUID_PACKAGE_SIGNATURE;\r
398 CopyMem (GuidPackage->GuidPkg, PackageHdr, PackageHeader.Length);\r
399 InsertTailList (&PackageList->GuidPkgHdr, &GuidPackage->GuidEntry);\r
400 *Package = GuidPackage;\r
401\r
402 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
403 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;\r
404 }\r
405\r
406 return EFI_SUCCESS;\r
407}\r
408\r
409\r
410/**\r
411 This function exports GUID packages to a buffer.\r
e90b081a 412 This is a internal function.\r
93e3992d 413\r
414 @param Private Hii database private structure.\r
415 @param Handle Identification of a package list.\r
416 @param PackageList Pointer to a package list which will be exported.\r
417 @param UsedSize The length of buffer be used.\r
418 @param BufferSize Length of the Buffer.\r
419 @param Buffer Allocated space for storing exported data.\r
420 @param ResultSize The size of the already exported content of this\r
421 package list.\r
422\r
423 @retval EFI_SUCCESS Guid Packages are exported successfully.\r
424 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
425\r
426**/\r
93e3992d 427EFI_STATUS\r
428ExportGuidPackages (\r
429 IN HII_DATABASE_PRIVATE_DATA *Private,\r
430 IN EFI_HII_HANDLE Handle,\r
431 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
432 IN UINTN UsedSize,\r
433 IN UINTN BufferSize,\r
434 IN OUT VOID *Buffer,\r
435 IN OUT UINTN *ResultSize\r
436 )\r
437{\r
438 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
439 LIST_ENTRY *Link;\r
440 UINTN PackageLength;\r
441 EFI_HII_PACKAGE_HEADER PackageHeader;\r
442 EFI_STATUS Status;\r
443\r
444 if (PackageList == NULL || ResultSize == NULL) {\r
445 return EFI_INVALID_PARAMETER;\r
446 }\r
447\r
448 if (BufferSize > 0 && Buffer == NULL ) {\r
449 return EFI_INVALID_PARAMETER;\r
450 }\r
451\r
452 PackageLength = 0;\r
453 Status = EFI_SUCCESS;\r
454\r
455 for (Link = PackageList->GuidPkgHdr.ForwardLink; Link != &PackageList->GuidPkgHdr; Link = Link->ForwardLink) {\r
456 GuidPackage = CR (Link, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);\r
457 CopyMem (&PackageHeader, GuidPackage->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
458 PackageLength += PackageHeader.Length;\r
459 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
460 Status = InvokeRegisteredFunction (\r
461 Private,\r
462 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
463 (VOID *) GuidPackage,\r
464 EFI_HII_PACKAGE_TYPE_GUID,\r
465 Handle\r
466 );\r
467 ASSERT_EFI_ERROR (Status);\r
468 CopyMem (Buffer, GuidPackage->GuidPkg, PackageHeader.Length);\r
469 Buffer = (UINT8 *) Buffer + PackageHeader.Length;\r
470 }\r
471 }\r
472\r
473 *ResultSize += PackageLength;\r
474 return EFI_SUCCESS;\r
475}\r
476\r
477\r
478/**\r
479 This function deletes all GUID packages from a package list node.\r
e90b081a 480 This is a internal function.\r
93e3992d 481\r
482 @param Private Hii database private data.\r
483 @param Handle Handle of the package list which contains the to\r
484 be removed GUID packages.\r
485 @param PackageList Pointer to a package list that contains removing\r
486 packages.\r
487\r
488 @retval EFI_SUCCESS GUID Package(s) is deleted successfully.\r
489 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
490\r
491**/\r
93e3992d 492EFI_STATUS\r
493RemoveGuidPackages (\r
494 IN HII_DATABASE_PRIVATE_DATA *Private,\r
495 IN EFI_HII_HANDLE Handle,\r
496 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
497 )\r
498{\r
499 LIST_ENTRY *ListHead;\r
500 HII_GUID_PACKAGE_INSTANCE *Package;\r
501 EFI_STATUS Status;\r
502 EFI_HII_PACKAGE_HEADER PackageHeader;\r
503\r
504 ListHead = &PackageList->GuidPkgHdr;\r
505\r
506 while (!IsListEmpty (ListHead)) {\r
507 Package = CR (\r
508 ListHead->ForwardLink,\r
509 HII_GUID_PACKAGE_INSTANCE,\r
510 GuidEntry,\r
511 HII_GUID_PACKAGE_SIGNATURE\r
512 );\r
513 Status = InvokeRegisteredFunction (\r
514 Private,\r
515 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
516 (VOID *) Package,\r
517 EFI_HII_PACKAGE_TYPE_GUID,\r
518 Handle\r
519 );\r
520 if (EFI_ERROR (Status)) {\r
521 return Status;\r
522 }\r
523\r
524 RemoveEntryList (&Package->GuidEntry);\r
525 CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
526 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;\r
676df92c 527 FreePool (Package->GuidPkg);\r
528 FreePool (Package);\r
93e3992d 529 }\r
530\r
531 return EFI_SUCCESS;\r
532}\r
533\r
534\r
535/**\r
536 This function insert a Form package to a package list node.\r
e90b081a 537 This is a internal function.\r
93e3992d 538\r
539 @param PackageHdr Pointer to a buffer stored with Form package\r
540 information.\r
541 @param NotifyType The type of change concerning the database.\r
542 @param PackageList Pointer to a package list which will be inserted\r
543 to.\r
544 @param Package Created Form package\r
545\r
546 @retval EFI_SUCCESS Form Package is inserted successfully.\r
547 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
548 Form package.\r
549 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
550\r
551**/\r
93e3992d 552EFI_STATUS\r
553InsertFormPackage (\r
554 IN VOID *PackageHdr,\r
555 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
556 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
557 OUT HII_IFR_PACKAGE_INSTANCE **Package\r
558 )\r
559{\r
560 HII_IFR_PACKAGE_INSTANCE *FormPackage;\r
561 EFI_HII_PACKAGE_HEADER PackageHeader;\r
562\r
563 if (PackageHdr == NULL || PackageList == NULL) {\r
564 return EFI_INVALID_PARAMETER;\r
565 }\r
566\r
567 //\r
568 // Get the length of the package, including package header itself\r
569 //\r
570 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
571\r
572 //\r
573 // Create a Form package node\r
574 //\r
575 FormPackage = (HII_IFR_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE));\r
576 if (FormPackage == NULL) {\r
577 return EFI_OUT_OF_RESOURCES;\r
578 }\r
579\r
580 FormPackage->IfrData = (UINT8 *) AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER));\r
581 if (FormPackage->IfrData == NULL) {\r
676df92c 582 FreePool (FormPackage);\r
93e3992d 583 return EFI_OUT_OF_RESOURCES;\r
584 }\r
585\r
586 FormPackage->Signature = HII_IFR_PACKAGE_SIGNATURE;\r
587 //\r
588 // Copy Package Header\r
589 //\r
590 CopyMem (&FormPackage->FormPkgHdr, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));\r
591\r
592 //\r
593 // Copy Ifr contents\r
594 //\r
595 CopyMem (\r
596 FormPackage->IfrData,\r
597 (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER),\r
598 PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER)\r
599 );\r
600\r
601 InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);\r
602 *Package = FormPackage;\r
603\r
604 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
605 PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;\r
606 }\r
607 return EFI_SUCCESS;\r
608}\r
609\r
610\r
611/**\r
612 This function exports Form packages to a buffer.\r
e90b081a 613 This is a internal function.\r
93e3992d 614\r
615 @param Private Hii database private structure.\r
616 @param Handle Identification of a package list.\r
617 @param PackageList Pointer to a package list which will be exported.\r
618 @param UsedSize The length of buffer be used.\r
619 @param BufferSize Length of the Buffer.\r
620 @param Buffer Allocated space for storing exported data.\r
621 @param ResultSize The size of the already exported content of this\r
622 package list.\r
623\r
624 @retval EFI_SUCCESS Form Packages are exported successfully.\r
625 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
626\r
627**/\r
93e3992d 628EFI_STATUS\r
629ExportFormPackages (\r
630 IN HII_DATABASE_PRIVATE_DATA *Private,\r
631 IN EFI_HII_HANDLE Handle,\r
632 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
633 IN UINTN UsedSize,\r
634 IN UINTN BufferSize,\r
635 IN OUT VOID *Buffer,\r
636 IN OUT UINTN *ResultSize\r
637 )\r
638{\r
639 HII_IFR_PACKAGE_INSTANCE *FormPackage;\r
640 UINTN PackageLength;\r
641 LIST_ENTRY *Link;\r
642 EFI_STATUS Status;\r
643\r
644 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
645 return EFI_INVALID_PARAMETER;\r
646 }\r
647\r
648 if (BufferSize > 0 && Buffer == NULL ) {\r
649 return EFI_INVALID_PARAMETER;\r
650 }\r
651\r
652 PackageLength = 0;\r
653 Status = EFI_SUCCESS;\r
654\r
655 //\r
656 // Export Form packages.\r
657 //\r
658 for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {\r
659 FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);\r
660 PackageLength += FormPackage->FormPkgHdr.Length;\r
6e3f5b2a 661 if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) {\r
93e3992d 662 //\r
663 // Invoke registered notification if exists\r
664 //\r
665 Status = InvokeRegisteredFunction (\r
666 Private,\r
667 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
668 (VOID *) FormPackage,\r
8d00a0f1 669 EFI_HII_PACKAGE_FORMS,\r
93e3992d 670 Handle\r
671 );\r
672 ASSERT_EFI_ERROR (Status);\r
673 //\r
674 // Copy the Form package content.\r
675 //\r
676 CopyMem (Buffer, (VOID *) (&FormPackage->FormPkgHdr), sizeof (EFI_HII_PACKAGE_HEADER));\r
677 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_PACKAGE_HEADER);\r
678 CopyMem (\r
679 Buffer,\r
680 (VOID *) FormPackage->IfrData,\r
681 FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER)\r
682 );\r
683 Buffer = (UINT8 *) Buffer + FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);\r
684 }\r
685 }\r
686\r
687 *ResultSize += PackageLength;\r
688\r
689 return EFI_SUCCESS;\r
690\r
691}\r
692\r
693\r
694/**\r
695 This function deletes all Form packages from a package list node.\r
e90b081a 696 This is a internal function.\r
93e3992d 697\r
698 @param Private Hii database private data.\r
699 @param Handle Handle of the package list which contains the to\r
700 be removed Form packages.\r
701 @param PackageList Pointer to a package list that contains removing\r
702 packages.\r
703\r
704 @retval EFI_SUCCESS Form Package(s) is deleted successfully.\r
705 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
706\r
707**/\r
93e3992d 708EFI_STATUS\r
709RemoveFormPackages (\r
710 IN HII_DATABASE_PRIVATE_DATA *Private,\r
711 IN EFI_HII_HANDLE Handle,\r
712 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
713 )\r
714{\r
715 LIST_ENTRY *ListHead;\r
716 HII_IFR_PACKAGE_INSTANCE *Package;\r
717 EFI_STATUS Status;\r
718\r
719 ListHead = &PackageList->FormPkgHdr;\r
720\r
721 while (!IsListEmpty (ListHead)) {\r
722 Package = CR (\r
723 ListHead->ForwardLink,\r
724 HII_IFR_PACKAGE_INSTANCE,\r
725 IfrEntry,\r
726 HII_IFR_PACKAGE_SIGNATURE\r
727 );\r
728 Status = InvokeRegisteredFunction (\r
729 Private,\r
730 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
731 (VOID *) Package,\r
8d00a0f1 732 EFI_HII_PACKAGE_FORMS,\r
93e3992d 733 Handle\r
734 );\r
735 if (EFI_ERROR (Status)) {\r
736 return Status;\r
737 }\r
738\r
739 RemoveEntryList (&Package->IfrEntry);\r
740 PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;\r
676df92c 741 FreePool (Package->IfrData);\r
742 FreePool (Package);\r
93e3992d 743\r
744 }\r
745\r
746 return EFI_SUCCESS;\r
747}\r
748\r
749\r
750\r
751/**\r
752 This function insert a String package to a package list node.\r
e90b081a 753 This is a internal function.\r
93e3992d 754\r
755 @param Private Hii database private structure.\r
756 @param PackageHdr Pointer to a buffer stored with String package\r
757 information.\r
758 @param NotifyType The type of change concerning the database.\r
759 @param PackageList Pointer to a package list which will be inserted\r
760 to.\r
761 @param Package Created String package\r
762\r
763 @retval EFI_SUCCESS String Package is inserted successfully.\r
764 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
765 String package.\r
766 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
767 @retval EFI_UNSUPPORTED A string package with the same language already\r
768 exists in current package list.\r
769\r
770**/\r
93e3992d 771EFI_STATUS\r
772InsertStringPackage (\r
773 IN HII_DATABASE_PRIVATE_DATA *Private,\r
774 IN VOID *PackageHdr,\r
775 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
776 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
777 OUT HII_STRING_PACKAGE_INSTANCE **Package\r
778\r
779 )\r
780{\r
781 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
782 UINT32 HeaderSize;\r
783 EFI_STATUS Status;\r
784 EFI_HII_PACKAGE_HEADER PackageHeader;\r
785 CHAR8 *Language;\r
786 UINT32 LanguageSize;\r
787 LIST_ENTRY *Link;\r
788\r
789 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {\r
790 return EFI_INVALID_PARAMETER;\r
791 }\r
792 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
793 return EFI_INVALID_PARAMETER;\r
794 }\r
795\r
796 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
797 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));\r
798\r
799 //\r
800 // It is illegal to have two string packages with same language within one packagelist\r
801 // since the stringid will be duplicate if so. Check it to avoid this potential issue.\r
802 //\r
803 LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8);\r
804 Language = (CHAR8 *) AllocateZeroPool (LanguageSize);\r
805 if (Language == NULL) {\r
806 return EFI_OUT_OF_RESOURCES;\r
807 }\r
808 AsciiStrCpy (Language, (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);\r
809 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {\r
810 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
f324bf4d 811 if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {\r
676df92c 812 FreePool (Language);\r
93e3992d 813 return EFI_UNSUPPORTED;\r
814 }\r
815 }\r
676df92c 816 FreePool (Language);\r
93e3992d 817\r
818 //\r
819 // Create a String package node\r
820 //\r
821 StringPackage = (HII_STRING_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));\r
822 if (StringPackage == NULL) {\r
823 Status = EFI_OUT_OF_RESOURCES;\r
824 goto Error;\r
825 }\r
826\r
827 StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);\r
828 if (StringPackage->StringPkgHdr == NULL) {\r
829 Status = EFI_OUT_OF_RESOURCES;\r
830 goto Error;\r
831 }\r
832\r
833 StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);\r
834 if (StringPackage->StringBlock == NULL) {\r
835 Status = EFI_OUT_OF_RESOURCES;\r
836 goto Error;\r
837 }\r
838\r
839 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;\r
840 StringPackage->FontId = 0;\r
841 InitializeListHead (&StringPackage->FontInfoList);\r
842\r
843 //\r
844 // Copy the String package header.\r
845 //\r
846 CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize);\r
847\r
848 //\r
849 // Copy the String blocks\r
850 //\r
851 CopyMem (\r
852 StringPackage->StringBlock,\r
853 (UINT8 *) PackageHdr + HeaderSize,\r
854 PackageHeader.Length - HeaderSize\r
855 );\r
856\r
857 //\r
858 // Collect all font block info\r
859 //\r
860 Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, NULL);\r
861 if (EFI_ERROR (Status)) {\r
862 return Status;\r
863 }\r
864\r
865 //\r
866 // Insert to String package array\r
867 //\r
868 InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry);\r
869 *Package = StringPackage;\r
870\r
871 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
872 PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
873 }\r
874\r
875 return EFI_SUCCESS;\r
876\r
877Error:\r
878\r
676df92c 879 if (StringPackage != NULL) {\r
c59634ea 880 if (StringPackage->StringBlock != NULL) {\r
881 FreePool (StringPackage->StringBlock);\r
882 }\r
883 if (StringPackage->StringPkgHdr != NULL) {\r
884 FreePool (StringPackage->StringPkgHdr);\r
885 }\r
676df92c 886 FreePool (StringPackage);\r
887 }\r
93e3992d 888 return Status;\r
889\r
890}\r
891\r
892\r
893/**\r
894 This function exports String packages to a buffer.\r
e90b081a 895 This is a internal function.\r
93e3992d 896\r
897 @param Private Hii database private structure.\r
898 @param Handle Identification of a package list.\r
899 @param PackageList Pointer to a package list which will be exported.\r
900 @param UsedSize The length of buffer be used.\r
901 @param BufferSize Length of the Buffer.\r
902 @param Buffer Allocated space for storing exported data.\r
903 @param ResultSize The size of the already exported content of this\r
904 package list.\r
905\r
906 @retval EFI_SUCCESS String Packages are exported successfully.\r
907 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
908\r
909**/\r
93e3992d 910EFI_STATUS\r
911ExportStringPackages (\r
912 IN HII_DATABASE_PRIVATE_DATA *Private,\r
913 IN EFI_HII_HANDLE Handle,\r
914 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
915 IN UINTN UsedSize,\r
916 IN UINTN BufferSize,\r
917 IN OUT VOID *Buffer,\r
918 IN OUT UINTN *ResultSize\r
919 )\r
920{\r
921 LIST_ENTRY *Link;\r
922 UINTN PackageLength;\r
923 EFI_STATUS Status;\r
924 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
925\r
926 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
927 return EFI_INVALID_PARAMETER;\r
928 }\r
929\r
930 if (BufferSize > 0 && Buffer == NULL ) {\r
931 return EFI_INVALID_PARAMETER;\r
932 }\r
933\r
934 PackageLength = 0;\r
935 Status = EFI_SUCCESS;\r
936\r
937 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {\r
938 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
939 PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
940 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
941 //\r
942 // Invoke registered notification function with EXPORT_PACK notify type\r
943 //\r
944 Status = InvokeRegisteredFunction (\r
945 Private,\r
946 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
947 (VOID *) StringPackage,\r
948 EFI_HII_PACKAGE_STRINGS,\r
949 Handle\r
950 );\r
951 ASSERT_EFI_ERROR (Status);\r
952 //\r
953 // Copy String package header\r
954 //\r
955 CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize);\r
956 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->HdrSize;\r
957\r
958 //\r
959 // Copy String blocks information\r
960 //\r
961 CopyMem (\r
962 Buffer,\r
963 StringPackage->StringBlock,\r
964 StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize\r
965 );\r
966 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
967 }\r
968 }\r
969\r
970 *ResultSize += PackageLength;\r
971 return EFI_SUCCESS;\r
972}\r
973\r
974\r
975/**\r
976 This function deletes all String packages from a package list node.\r
e90b081a 977 This is a internal function.\r
93e3992d 978\r
979 @param Private Hii database private data.\r
980 @param Handle Handle of the package list which contains the to\r
981 be removed String packages.\r
982 @param PackageList Pointer to a package list that contains removing\r
983 packages.\r
984\r
985 @retval EFI_SUCCESS String Package(s) is deleted successfully.\r
986 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
987\r
988**/\r
93e3992d 989EFI_STATUS\r
990RemoveStringPackages (\r
991 IN HII_DATABASE_PRIVATE_DATA *Private,\r
992 IN EFI_HII_HANDLE Handle,\r
993 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
994 )\r
995{\r
996 LIST_ENTRY *ListHead;\r
997 HII_STRING_PACKAGE_INSTANCE *Package;\r
998 HII_FONT_INFO *FontInfo;\r
999 EFI_STATUS Status;\r
1000\r
1001 ListHead = &PackageList->StringPkgHdr;\r
1002\r
1003 while (!IsListEmpty (ListHead)) {\r
1004 Package = CR (\r
1005 ListHead->ForwardLink,\r
1006 HII_STRING_PACKAGE_INSTANCE,\r
1007 StringEntry,\r
1008 HII_STRING_PACKAGE_SIGNATURE\r
1009 );\r
1010 Status = InvokeRegisteredFunction (\r
1011 Private,\r
1012 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1013 (VOID *) Package,\r
1014 EFI_HII_PACKAGE_STRINGS,\r
1015 Handle\r
1016 );\r
1017 if (EFI_ERROR (Status)) {\r
1018 return Status;\r
1019 }\r
1020\r
1021 RemoveEntryList (&Package->StringEntry);\r
1022 PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;\r
676df92c 1023 FreePool (Package->StringBlock);\r
1024 FreePool (Package->StringPkgHdr);\r
93e3992d 1025 //\r
1026 // Delete font information\r
1027 //\r
1028 while (!IsListEmpty (&Package->FontInfoList)) {\r
1029 FontInfo = CR (\r
1030 Package->FontInfoList.ForwardLink,\r
1031 HII_FONT_INFO,\r
1032 Entry,\r
1033 HII_FONT_INFO_SIGNATURE\r
1034 );\r
1035 RemoveEntryList (&FontInfo->Entry);\r
676df92c 1036 FreePool (FontInfo);\r
93e3992d 1037 }\r
1038\r
676df92c 1039 FreePool (Package);\r
93e3992d 1040 }\r
1041\r
1042 return EFI_SUCCESS;\r
1043}\r
1044\r
1045\r
1046/**\r
1047 This function insert a Font package to a package list node.\r
e90b081a 1048 This is a internal function.\r
93e3992d 1049\r
1050 @param Private Hii database private structure.\r
1051 @param PackageHdr Pointer to a buffer stored with Font package\r
1052 information.\r
1053 @param NotifyType The type of change concerning the database.\r
1054 @param PackageList Pointer to a package list which will be inserted\r
1055 to.\r
1056 @param Package Created Font package\r
1057\r
1058 @retval EFI_SUCCESS Font Package is inserted successfully.\r
1059 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1060 Font package.\r
1061 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1062 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already\r
1063 exists in current hii database.\r
1064\r
1065**/\r
93e3992d 1066EFI_STATUS\r
1067InsertFontPackage (\r
1068 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1069 IN VOID *PackageHdr,\r
1070 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1071 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1072 OUT HII_FONT_PACKAGE_INSTANCE **Package\r
1073 )\r
1074{\r
1075 HII_FONT_PACKAGE_INSTANCE *FontPackage;\r
1076 EFI_HII_FONT_PACKAGE_HDR *FontPkgHdr;\r
1077 UINT32 HeaderSize;\r
1078 EFI_STATUS Status;\r
1079 EFI_HII_PACKAGE_HEADER PackageHeader;\r
1080 EFI_FONT_INFO *FontInfo;\r
1081 UINT32 FontInfoSize;\r
1082 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1083\r
1084 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {\r
1085 return EFI_INVALID_PARAMETER;\r
1086 }\r
1087\r
1088 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
1089 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));\r
1090\r
1091 FontInfo = NULL;\r
1092 FontPackage = NULL;\r
1093 GlobalFont = NULL;\r
1094\r
1095 //\r
1096 // It is illegal to have two font packages with same EFI_FONT_INFO within hii\r
1097 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's\r
1098 // attributes and identify a font uniquely.\r
1099 //\r
1100 FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);\r
1101 if (FontPkgHdr == NULL) {\r
1102 Status = EFI_OUT_OF_RESOURCES;\r
1103 goto Error;\r
1104 }\r
1105 CopyMem (FontPkgHdr, PackageHdr, HeaderSize);\r
1106\r
1107 FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR);\r
1108 FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);\r
1109 if (FontInfo == NULL) {\r
1110 Status = EFI_OUT_OF_RESOURCES;\r
1111 goto Error;\r
1112 }\r
1113 FontInfo->FontStyle = FontPkgHdr->FontStyle;\r
1114 FontInfo->FontSize = FontPkgHdr->Cell.Height;\r
1115 StrCpy (FontInfo->FontName, FontPkgHdr->FontFamily);\r
1116\r
1117 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {\r
1118 Status = EFI_UNSUPPORTED;\r
1119 goto Error;\r
1120 }\r
1121\r
1122 //\r
1123 // Create a Font package node\r
1124 //\r
1125 FontPackage = (HII_FONT_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE));\r
1126 if (FontPackage == NULL) {\r
1127 Status = EFI_OUT_OF_RESOURCES;\r
1128 goto Error;\r
1129 }\r
1130 FontPackage->Signature = HII_FONT_PACKAGE_SIGNATURE;\r
1131 FontPackage->FontPkgHdr = FontPkgHdr;\r
1132 InitializeListHead (&FontPackage->GlyphInfoList);\r
1133\r
1134 FontPackage->GlyphBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);\r
1135 if (FontPackage->GlyphBlock == NULL) {\r
1136 Status = EFI_OUT_OF_RESOURCES;\r
1137 goto Error;\r
1138 }\r
1139 CopyMem (FontPackage->GlyphBlock, (UINT8 *) PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize);\r
1140\r
1141 //\r
1142 // Collect all default character cell information and backup in GlyphInfoList.\r
1143 //\r
1144 Status = FindGlyphBlock (FontPackage, (CHAR16) (-1), NULL, NULL, NULL);\r
1145 if (EFI_ERROR (Status)) {\r
1146 goto Error;\r
1147 }\r
1148\r
1149 //\r
1150 // This font package describes an unique EFI_FONT_INFO. Backup it in global\r
1151 // font info list.\r
1152 //\r
1153 GlobalFont = (HII_GLOBAL_FONT_INFO *) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO));\r
1154 if (GlobalFont == NULL) {\r
1155 Status = EFI_OUT_OF_RESOURCES;\r
1156 goto Error;\r
1157 }\r
1158 GlobalFont->Signature = HII_GLOBAL_FONT_INFO_SIGNATURE;\r
1159 GlobalFont->FontPackage = FontPackage;\r
1160 GlobalFont->FontInfoSize = FontInfoSize;\r
1161 GlobalFont->FontInfo = FontInfo;\r
1162 InsertTailList (&Private->FontInfoList, &GlobalFont->Entry);\r
1163\r
1164 //\r
1165 // Insert this font package to Font package array\r
1166 //\r
1167 InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry);\r
1168 *Package = FontPackage;\r
1169\r
1170 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1171 PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length;\r
1172 }\r
1173\r
1174 return EFI_SUCCESS;\r
1175\r
1176Error:\r
1177\r
676df92c 1178 if (FontPkgHdr != NULL) {\r
1179 FreePool (FontPkgHdr);\r
1180 }\r
1181 if (FontInfo != NULL) {\r
1182 FreePool (FontInfo);\r
1183 }\r
676df92c 1184 if (FontPackage != NULL) {\r
c59634ea 1185 if (FontPackage->GlyphBlock != NULL) {\r
1186 FreePool (FontPackage->GlyphBlock);\r
1187 }\r
676df92c 1188 FreePool (FontPackage);\r
1189 }\r
1190 if (GlobalFont != NULL) {\r
1191 FreePool (GlobalFont);\r
1192 }\r
93e3992d 1193\r
1194 return Status;\r
1195\r
1196}\r
1197\r
1198\r
1199/**\r
1200 This function exports Font packages to a buffer.\r
e90b081a 1201 This is a internal function.\r
93e3992d 1202\r
1203 @param Private Hii database private structure.\r
1204 @param Handle Identification of a package list.\r
1205 @param PackageList Pointer to a package list which will be exported.\r
1206 @param UsedSize The length of buffer be used.\r
1207 @param BufferSize Length of the Buffer.\r
1208 @param Buffer Allocated space for storing exported data.\r
1209 @param ResultSize The size of the already exported content of this\r
1210 package list.\r
1211\r
1212 @retval EFI_SUCCESS Font Packages are exported successfully.\r
1213 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1214\r
1215**/\r
93e3992d 1216EFI_STATUS\r
1217ExportFontPackages (\r
1218 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1219 IN EFI_HII_HANDLE Handle,\r
1220 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1221 IN UINTN UsedSize,\r
1222 IN UINTN BufferSize,\r
1223 IN OUT VOID *Buffer,\r
1224 IN OUT UINTN *ResultSize\r
1225 )\r
1226{\r
1227 LIST_ENTRY *Link;\r
1228 UINTN PackageLength;\r
1229 EFI_STATUS Status;\r
1230 HII_FONT_PACKAGE_INSTANCE *Package;\r
1231\r
1232\r
1233 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1234 return EFI_INVALID_PARAMETER;\r
1235 }\r
1236\r
1237 if (BufferSize > 0 && Buffer == NULL ) {\r
1238 return EFI_INVALID_PARAMETER;\r
1239 }\r
1240\r
1241 PackageLength = 0;\r
1242 Status = EFI_SUCCESS;\r
1243\r
1244 for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) {\r
1245 Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE);\r
1246 PackageLength += Package->FontPkgHdr->Header.Length;\r
1247 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1248 //\r
1249 // Invoke registered notification function with EXPORT_PACK notify type\r
1250 //\r
1251 Status = InvokeRegisteredFunction (\r
1252 Private,\r
1253 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1254 (VOID *) Package,\r
1255 EFI_HII_PACKAGE_FONTS,\r
1256 Handle\r
1257 );\r
1258 ASSERT_EFI_ERROR (Status);\r
1259 //\r
1260 // Copy Font package header\r
1261 //\r
1262 CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize);\r
1263 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->HdrSize;\r
1264\r
1265 //\r
1266 // Copy Glyph blocks information\r
1267 //\r
1268 CopyMem (\r
1269 Buffer,\r
1270 Package->GlyphBlock,\r
1271 Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize\r
1272 );\r
1273 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize;\r
1274 }\r
1275 }\r
1276\r
1277 *ResultSize += PackageLength;\r
1278 return EFI_SUCCESS;\r
1279}\r
1280\r
1281\r
1282/**\r
1283 This function deletes all Font packages from a package list node.\r
e90b081a 1284 This is a internal function.\r
93e3992d 1285\r
1286 @param Private Hii database private data.\r
1287 @param Handle Handle of the package list which contains the to\r
1288 be removed Font packages.\r
1289 @param PackageList Pointer to a package list that contains removing\r
1290 packages.\r
1291\r
1292 @retval EFI_SUCCESS Font Package(s) is deleted successfully.\r
1293 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1294\r
1295**/\r
93e3992d 1296EFI_STATUS\r
1297RemoveFontPackages (\r
1298 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1299 IN EFI_HII_HANDLE Handle,\r
1300 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1301 )\r
1302{\r
1303 LIST_ENTRY *ListHead;\r
1304 HII_FONT_PACKAGE_INSTANCE *Package;\r
1305 EFI_STATUS Status;\r
1306 HII_GLYPH_INFO *GlyphInfo;\r
1307 LIST_ENTRY *Link;\r
1308 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1309\r
1310 ListHead = &PackageList->FontPkgHdr;\r
1311\r
1312 while (!IsListEmpty (ListHead)) {\r
1313 Package = CR (\r
1314 ListHead->ForwardLink,\r
1315 HII_FONT_PACKAGE_INSTANCE,\r
1316 FontEntry,\r
1317 HII_FONT_PACKAGE_SIGNATURE\r
1318 );\r
1319 Status = InvokeRegisteredFunction (\r
1320 Private,\r
1321 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1322 (VOID *) Package,\r
1323 EFI_HII_PACKAGE_FONTS,\r
1324 Handle\r
1325 );\r
1326 if (EFI_ERROR (Status)) {\r
1327 return Status;\r
1328 }\r
1329\r
1330 RemoveEntryList (&Package->FontEntry);\r
1331 PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;\r
676df92c 1332\r
1333 if (Package->GlyphBlock != NULL) {\r
1334 FreePool (Package->GlyphBlock);\r
1335 }\r
1336 FreePool (Package->FontPkgHdr);\r
93e3992d 1337 //\r
1338 // Delete default character cell information\r
1339 //\r
1340 while (!IsListEmpty (&Package->GlyphInfoList)) {\r
1341 GlyphInfo = CR (\r
1342 Package->GlyphInfoList.ForwardLink,\r
1343 HII_GLYPH_INFO,\r
1344 Entry,\r
1345 HII_GLYPH_INFO_SIGNATURE\r
1346 );\r
1347 RemoveEntryList (&GlyphInfo->Entry);\r
676df92c 1348 FreePool (GlyphInfo);\r
93e3992d 1349 }\r
1350\r
1351 //\r
1352 // Remove corresponding global font info\r
1353 //\r
1354 for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
1355 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
1356 if (GlobalFont->FontPackage == Package) {\r
1357 RemoveEntryList (&GlobalFont->Entry);\r
676df92c 1358 FreePool (GlobalFont->FontInfo);\r
1359 FreePool (GlobalFont);\r
93e3992d 1360 break;\r
1361 }\r
1362 }\r
1363\r
676df92c 1364 FreePool (Package);\r
93e3992d 1365 }\r
1366\r
1367 return EFI_SUCCESS;\r
1368}\r
1369\r
1370\r
1371/**\r
1372 This function insert a Image package to a package list node.\r
e90b081a 1373 This is a internal function.\r
93e3992d 1374\r
1375 @param PackageHdr Pointer to a buffer stored with Image package\r
1376 information.\r
1377 @param NotifyType The type of change concerning the database.\r
1378 @param PackageList Pointer to a package list which will be inserted\r
1379 to.\r
1380 @param Package Created Image package\r
1381\r
1382 @retval EFI_SUCCESS Image Package is inserted successfully.\r
1383 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1384 Image package.\r
1385 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1386\r
1387**/\r
93e3992d 1388EFI_STATUS\r
1389InsertImagePackage (\r
1390 IN VOID *PackageHdr,\r
1391 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1392 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1393 OUT HII_IMAGE_PACKAGE_INSTANCE **Package\r
1394 )\r
1395{\r
1396 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
1397 UINT32 PaletteSize;\r
1398 UINT32 ImageSize;\r
1399 UINT16 Index;\r
1400 EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr;\r
1401 EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo;\r
1402 UINT32 PaletteInfoOffset;\r
1403 UINT32 ImageInfoOffset;\r
1404 UINT16 CurrentSize;\r
1405\r
1406 if (PackageHdr == NULL || PackageList == NULL) {\r
1407 return EFI_INVALID_PARAMETER;\r
1408 }\r
1409\r
1410 //\r
1411 // Less than one image package is allowed in one package list.\r
1412 //\r
1413 if (PackageList->ImagePkg != NULL) {\r
1414 return EFI_INVALID_PARAMETER;\r
1415 }\r
1416\r
1417 //\r
1418 // Create a Image package node\r
1419 //\r
1420 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));\r
1421 if (ImagePackage == NULL) {\r
1422 return EFI_OUT_OF_RESOURCES;\r
1423 }\r
1424\r
1425 //\r
1426 // Copy the Image package header.\r
1427 //\r
1428 CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));\r
1429\r
1430 PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset;\r
1431 ImageInfoOffset = ImagePackage->ImagePkgHdr.ImageInfoOffset;\r
1432\r
1433 //\r
1434 // If PaletteInfoOffset is zero, there are no palettes in this image package.\r
1435 //\r
1436 PaletteSize = 0;\r
1437 ImagePackage->PaletteBlock = NULL;\r
1438 if (PaletteInfoOffset != 0) {\r
1439 PaletteHdr = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *) ((UINT8 *) PackageHdr + PaletteInfoOffset);\r
1440 PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);\r
1441 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteHdr + PaletteSize);\r
1442\r
1443 for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) {\r
1444 CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16));\r
1445 CurrentSize += sizeof (UINT16);\r
1446 PaletteSize += (UINT32) CurrentSize;\r
1447 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteInfo + CurrentSize);\r
1448 }\r
1449\r
1450 ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize);\r
1451 if (ImagePackage->PaletteBlock == NULL) {\r
676df92c 1452 FreePool (ImagePackage);\r
93e3992d 1453 return EFI_OUT_OF_RESOURCES;\r
1454 }\r
1455 CopyMem (\r
1456 ImagePackage->PaletteBlock,\r
1457 (UINT8 *) PackageHdr + PaletteInfoOffset,\r
1458 PaletteSize\r
1459 );\r
1460 }\r
1461\r
1462 //\r
1463 // If ImageInfoOffset is zero, there are no images in this package.\r
1464 //\r
1465 ImageSize = 0;\r
1466 ImagePackage->ImageBlock = NULL;\r
1467 if (ImageInfoOffset != 0) {\r
1468 ImageSize = ImagePackage->ImagePkgHdr.Header.Length -\r
1469 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;\r
1470 ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (ImageSize);\r
1471 if (ImagePackage->ImageBlock == NULL) {\r
676df92c 1472 FreePool (ImagePackage->PaletteBlock);\r
1473 FreePool (ImagePackage);\r
93e3992d 1474 return EFI_OUT_OF_RESOURCES;\r
1475 }\r
1476 CopyMem (\r
1477 ImagePackage->ImageBlock,\r
1478 (UINT8 *) PackageHdr + ImageInfoOffset,\r
1479 ImageSize\r
1480 );\r
1481 }\r
1482\r
1483 ImagePackage->ImageBlockSize = ImageSize;\r
1484 ImagePackage->PaletteInfoSize = PaletteSize;\r
1485 PackageList->ImagePkg = ImagePackage;\r
1486 *Package = ImagePackage;\r
1487\r
1488 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1489 PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;\r
1490 }\r
1491\r
1492 return EFI_SUCCESS;\r
1493}\r
1494\r
1495\r
1496/**\r
1497 This function exports Image packages to a buffer.\r
e90b081a 1498 This is a internal function.\r
93e3992d 1499\r
1500 @param Private Hii database private structure.\r
1501 @param Handle Identification of a package list.\r
1502 @param PackageList Pointer to a package list which will be exported.\r
1503 @param UsedSize The length of buffer be used.\r
1504 @param BufferSize Length of the Buffer.\r
1505 @param Buffer Allocated space for storing exported data.\r
1506 @param ResultSize The size of the already exported content of this\r
1507 package list.\r
1508\r
1509 @retval EFI_SUCCESS Image Packages are exported successfully.\r
1510 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1511\r
1512**/\r
93e3992d 1513EFI_STATUS\r
1514ExportImagePackages (\r
1515 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1516 IN EFI_HII_HANDLE Handle,\r
1517 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1518 IN UINTN UsedSize,\r
1519 IN UINTN BufferSize,\r
1520 IN OUT VOID *Buffer,\r
1521 IN OUT UINTN *ResultSize\r
1522 )\r
1523{\r
1524 UINTN PackageLength;\r
1525 EFI_STATUS Status;\r
1526 HII_IMAGE_PACKAGE_INSTANCE *Package;\r
1527\r
1528\r
1529 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1530 return EFI_INVALID_PARAMETER;\r
1531 }\r
1532\r
1533 if (BufferSize > 0 && Buffer == NULL ) {\r
1534 return EFI_INVALID_PARAMETER;\r
1535 }\r
1536\r
1537 Package = PackageList->ImagePkg;\r
1538\r
1539 if (Package == NULL) {\r
1540 return EFI_SUCCESS;\r
1541 }\r
1542\r
1543 PackageLength = Package->ImagePkgHdr.Header.Length;\r
1544\r
1545 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1546 //\r
1547 // Invoke registered notification function with EXPORT_PACK notify type\r
1548 //\r
1549 Status = InvokeRegisteredFunction (\r
1550 Private,\r
1551 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1552 (VOID *) Package,\r
1553 EFI_HII_PACKAGE_IMAGES,\r
1554 Handle\r
1555 );\r
1556 ASSERT_EFI_ERROR (Status);\r
1557 ASSERT (Package->ImagePkgHdr.Header.Length ==\r
1558 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize);\r
1559 //\r
1560 // Copy Image package header,\r
1561 // then justify the offset for image info and palette info in the header.\r
1562 //\r
1563 CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));\r
1564 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
1565\r
1566 //\r
1567 // Copy Image blocks information\r
1568 //\r
1569 if (Package->ImageBlockSize != 0) {\r
1570 CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize);\r
1571 Buffer = (UINT8 *) Buffer + Package->ImageBlockSize;\r
1572 }\r
1573 //\r
1574 // Copy Palette information\r
1575 //\r
1576 if (Package->PaletteInfoSize != 0) {\r
1577 CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize);\r
1578 Buffer = (UINT8 *) Buffer + Package->PaletteInfoSize;\r
1579 }\r
1580 }\r
1581\r
1582 *ResultSize += PackageLength;\r
1583 return EFI_SUCCESS;\r
1584}\r
1585\r
1586\r
1587/**\r
1588 This function deletes Image package from a package list node.\r
e90b081a 1589 This is a internal function.\r
93e3992d 1590\r
1591 @param Private Hii database private data.\r
1592 @param Handle Handle of the package list which contains the to\r
1593 be removed Image packages.\r
1594 @param PackageList Package List which contains the to be removed\r
1595 Image package.\r
1596\r
1597 @retval EFI_SUCCESS Image Package(s) is deleted successfully.\r
1598 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1599\r
1600**/\r
93e3992d 1601EFI_STATUS\r
1602RemoveImagePackages (\r
1603 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1604 IN EFI_HII_HANDLE Handle,\r
1605 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1606 )\r
1607{\r
1608 HII_IMAGE_PACKAGE_INSTANCE *Package;\r
1609 EFI_STATUS Status;\r
1610\r
1611 Package = PackageList->ImagePkg;\r
1612\r
1613 //\r
1614 // Image package does not exist, return directly.\r
1615 //\r
1616 if (Package == NULL) {\r
1617 return EFI_SUCCESS;\r
1618 }\r
1619\r
1620 Status = InvokeRegisteredFunction (\r
1621 Private,\r
1622 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1623 (VOID *) Package,\r
1624 EFI_HII_PACKAGE_IMAGES,\r
1625 Handle\r
1626 );\r
1627 if (EFI_ERROR (Status)) {\r
1628 return Status;\r
1629 }\r
1630\r
1631 PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;\r
1632\r
676df92c 1633 FreePool (Package->ImageBlock);\r
1634 if (Package->PaletteBlock != NULL) {\r
1635 FreePool (Package->PaletteBlock);\r
1636 }\r
1637 FreePool (Package);\r
93e3992d 1638\r
1639 PackageList->ImagePkg = NULL;\r
1640\r
1641 return EFI_SUCCESS;\r
1642}\r
1643\r
1644\r
1645/**\r
1646 This function insert a Simple Font package to a package list node.\r
e90b081a 1647 This is a internal function.\r
93e3992d 1648\r
1649 @param PackageHdr Pointer to a buffer stored with Simple Font\r
1650 package information.\r
1651 @param NotifyType The type of change concerning the database.\r
1652 @param PackageList Pointer to a package list which will be inserted\r
1653 to.\r
1654 @param Package Created Simple Font package\r
1655\r
1656 @retval EFI_SUCCESS Simple Font Package is inserted successfully.\r
1657 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1658 Simple Font package.\r
1659 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1660\r
1661**/\r
93e3992d 1662EFI_STATUS\r
1663InsertSimpleFontPackage (\r
1664 IN VOID *PackageHdr,\r
1665 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1666 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1667 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE **Package\r
1668 )\r
1669{\r
1670 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;\r
1671 EFI_STATUS Status;\r
1672 EFI_HII_PACKAGE_HEADER Header;\r
1673\r
1674 if (PackageHdr == NULL || PackageList == NULL) {\r
1675 return EFI_INVALID_PARAMETER;\r
1676 }\r
1677\r
1678 //\r
1679 // Create a Simple Font package node\r
1680 //\r
1681 SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE));\r
1682 if (SimpleFontPackage == NULL) {\r
1683 Status = EFI_OUT_OF_RESOURCES;\r
1684 goto Error;\r
1685 }\r
1686 SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE;\r
1687\r
1688 //\r
1689 // Copy the Simple Font package.\r
1690 //\r
1691 CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
1692\r
1693 SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length);\r
1694 if (SimpleFontPackage->SimpleFontPkgHdr == NULL) {\r
1695 Status = EFI_OUT_OF_RESOURCES;\r
1696 goto Error;\r
1697 }\r
1698\r
1699 CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length);\r
1700\r
1701 //\r
1702 // Insert to Simple Font package array\r
1703 //\r
1704 InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry);\r
1705 *Package = SimpleFontPackage;\r
1706\r
1707 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1708 PackageList->PackageListHdr.PackageLength += Header.Length;\r
1709 }\r
1710\r
1711 return EFI_SUCCESS;\r
1712\r
1713Error:\r
1714\r
676df92c 1715 if (SimpleFontPackage != NULL) {\r
c59634ea 1716 if (SimpleFontPackage->SimpleFontPkgHdr != NULL) {\r
1717 FreePool (SimpleFontPackage->SimpleFontPkgHdr);\r
1718 }\r
676df92c 1719 FreePool (SimpleFontPackage);\r
1720 }\r
93e3992d 1721 return Status;\r
1722}\r
1723\r
1724\r
1725/**\r
1726 This function exports SimpleFont packages to a buffer.\r
e90b081a 1727 This is a internal function.\r
93e3992d 1728\r
1729 @param Private Hii database private structure.\r
1730 @param Handle Identification of a package list.\r
1731 @param PackageList Pointer to a package list which will be exported.\r
1732 @param UsedSize The length of buffer be used.\r
1733 @param BufferSize Length of the Buffer.\r
1734 @param Buffer Allocated space for storing exported data.\r
1735 @param ResultSize The size of the already exported content of this\r
1736 package list.\r
1737\r
1738 @retval EFI_SUCCESS SimpleFont Packages are exported successfully.\r
1739 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1740\r
1741**/\r
93e3992d 1742EFI_STATUS\r
1743ExportSimpleFontPackages (\r
1744 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1745 IN EFI_HII_HANDLE Handle,\r
1746 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1747 IN UINTN UsedSize,\r
1748 IN UINTN BufferSize,\r
1749 IN OUT VOID *Buffer,\r
1750 IN OUT UINTN *ResultSize\r
1751 )\r
1752{\r
1753 LIST_ENTRY *Link;\r
1754 UINTN PackageLength;\r
1755 EFI_STATUS Status;\r
1756 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;\r
1757\r
1758 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1759 return EFI_INVALID_PARAMETER;\r
1760 }\r
1761\r
1762 if (BufferSize > 0 && Buffer == NULL ) {\r
1763 return EFI_INVALID_PARAMETER;\r
1764 }\r
1765\r
1766 PackageLength = 0;\r
1767 Status = EFI_SUCCESS;\r
1768\r
1769 for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) {\r
1770 Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);\r
1771 PackageLength += Package->SimpleFontPkgHdr->Header.Length;\r
1772 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1773 //\r
1774 // Invoke registered notification function with EXPORT_PACK notify type\r
1775 //\r
1776 Status = InvokeRegisteredFunction (\r
1777 Private,\r
1778 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1779 (VOID *) Package,\r
1780 EFI_HII_PACKAGE_SIMPLE_FONTS,\r
1781 Handle\r
1782 );\r
1783 ASSERT_EFI_ERROR (Status);\r
1784\r
1785 //\r
1786 // Copy SimpleFont package\r
1787 //\r
1788 CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length);\r
1789 Buffer = (UINT8 *) Buffer + Package->SimpleFontPkgHdr->Header.Length;\r
1790 }\r
1791 }\r
1792\r
1793 *ResultSize += PackageLength;\r
1794 return EFI_SUCCESS;\r
1795}\r
1796\r
1797\r
1798/**\r
1799 This function deletes all Simple Font packages from a package list node.\r
e90b081a 1800 This is a internal function.\r
93e3992d 1801\r
1802 @param Private Hii database private data.\r
1803 @param Handle Handle of the package list which contains the to\r
1804 be removed Simple Font packages.\r
1805 @param PackageList Pointer to a package list that contains removing\r
1806 packages.\r
1807\r
1808 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.\r
1809 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1810\r
1811**/\r
93e3992d 1812EFI_STATUS\r
1813RemoveSimpleFontPackages (\r
1814 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1815 IN EFI_HII_HANDLE Handle,\r
1816 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1817 )\r
1818{\r
1819 LIST_ENTRY *ListHead;\r
1820 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;\r
1821 EFI_STATUS Status;\r
1822\r
1823 ListHead = &PackageList->SimpleFontPkgHdr;\r
1824\r
1825 while (!IsListEmpty (ListHead)) {\r
1826 Package = CR (\r
1827 ListHead->ForwardLink,\r
1828 HII_SIMPLE_FONT_PACKAGE_INSTANCE,\r
1829 SimpleFontEntry,\r
1830 HII_S_FONT_PACKAGE_SIGNATURE\r
1831 );\r
1832 Status = InvokeRegisteredFunction (\r
1833 Private,\r
1834 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1835 (VOID *) Package,\r
1836 EFI_HII_PACKAGE_SIMPLE_FONTS,\r
1837 Handle\r
1838 );\r
1839 if (EFI_ERROR (Status)) {\r
1840 return Status;\r
1841 }\r
1842\r
1843 RemoveEntryList (&Package->SimpleFontEntry);\r
1844 PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;\r
676df92c 1845 FreePool (Package->SimpleFontPkgHdr);\r
1846 FreePool (Package);\r
93e3992d 1847 }\r
1848\r
1849 return EFI_SUCCESS;\r
1850}\r
1851\r
1852\r
1853/**\r
1854 This function insert a Device path package to a package list node.\r
e90b081a 1855 This is a internal function.\r
93e3992d 1856\r
1857 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol\r
1858 instance\r
1859 @param NotifyType The type of change concerning the database.\r
1860 @param PackageList Pointer to a package list which will be inserted\r
1861 to.\r
1862\r
1863 @retval EFI_SUCCESS Device path Package is inserted successfully.\r
1864 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1865 Device path package.\r
1866 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.\r
1867\r
1868**/\r
93e3992d 1869EFI_STATUS\r
1870InsertDevicePathPackage (\r
1871 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1872 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1873 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1874 )\r
1875{\r
1876 UINT32 PackageLength;\r
1877 EFI_HII_PACKAGE_HEADER Header;\r
1878\r
1879 if (DevicePath == NULL || PackageList == NULL) {\r
1880 return EFI_INVALID_PARAMETER;\r
1881 }\r
1882 //\r
1883 // Less than one device path package is allowed in one package list.\r
1884 //\r
1885 if (PackageList->DevicePathPkg != NULL) {\r
1886 return EFI_INVALID_PARAMETER;\r
1887 }\r
1888\r
1889 PackageLength = (UINT32) GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER);\r
1890 PackageList->DevicePathPkg = (UINT8 *) AllocateZeroPool (PackageLength);\r
1891 if (PackageList->DevicePathPkg == NULL) {\r
1892 return EFI_OUT_OF_RESOURCES;\r
1893 }\r
1894\r
1895 Header.Length = PackageLength;\r
1896 Header.Type = EFI_HII_PACKAGE_DEVICE_PATH;\r
1897 CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER));\r
1898 CopyMem (\r
1899 PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
1900 DevicePath,\r
1901 PackageLength - sizeof (EFI_HII_PACKAGE_HEADER)\r
1902 );\r
1903\r
1904 //\r
1905 // Since Device Path package is created by NewPackageList, either NEW_PACK\r
1906 // or ADD_PACK should increase the length of package list.\r
1907 //\r
1908 PackageList->PackageListHdr.PackageLength += PackageLength;\r
1909 return EFI_SUCCESS;\r
1910}\r
1911\r
1912\r
1913/**\r
1914 This function exports device path package to a buffer.\r
e90b081a 1915 This is a internal function.\r
93e3992d 1916\r
1917 @param Private Hii database private structure.\r
1918 @param Handle Identification of a package list.\r
1919 @param PackageList Pointer to a package list which will be exported.\r
1920 @param UsedSize The length of buffer be used.\r
1921 @param BufferSize Length of the Buffer.\r
1922 @param Buffer Allocated space for storing exported data.\r
1923 @param ResultSize The size of the already exported content of this\r
1924 package list.\r
1925\r
1926 @retval EFI_SUCCESS Device path Package is exported successfully.\r
1927 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1928\r
1929**/\r
93e3992d 1930EFI_STATUS\r
1931ExportDevicePathPackage (\r
1932 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1933 IN EFI_HII_HANDLE Handle,\r
1934 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1935 IN UINTN UsedSize,\r
1936 IN UINTN BufferSize,\r
1937 IN OUT VOID *Buffer,\r
1938 IN OUT UINTN *ResultSize\r
1939 )\r
1940{\r
1941 EFI_STATUS Status;\r
1942 UINT8 *Package;\r
1943 EFI_HII_PACKAGE_HEADER Header;\r
1944\r
1945 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1946 return EFI_INVALID_PARAMETER;\r
1947 }\r
1948 if (BufferSize > 0 && Buffer == NULL ) {\r
1949 return EFI_INVALID_PARAMETER;\r
1950 }\r
1951\r
1952 Package = PackageList->DevicePathPkg;\r
1953\r
1954 if (Package == NULL) {\r
1955 return EFI_SUCCESS;\r
1956 }\r
1957\r
1958 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
1959\r
1960 if (Header.Length + *ResultSize + UsedSize <= BufferSize) {\r
1961 //\r
1962 // Invoke registered notification function with EXPORT_PACK notify type\r
1963 //\r
1964 Status = InvokeRegisteredFunction (\r
1965 Private,\r
1966 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1967 (VOID *) Package,\r
1968 EFI_HII_PACKAGE_DEVICE_PATH,\r
1969 Handle\r
1970 );\r
1971 ASSERT_EFI_ERROR (Status);\r
1972\r
1973 //\r
1974 // Copy Device path package\r
1975 //\r
1976 CopyMem (Buffer, Package, Header.Length);\r
1977 }\r
1978\r
1979 *ResultSize += Header.Length;\r
1980 return EFI_SUCCESS;\r
1981}\r
1982\r
1983\r
1984/**\r
1985 This function deletes Device Path package from a package list node.\r
e90b081a 1986 This is a internal function.\r
93e3992d 1987\r
1988 @param Private Hii database private data.\r
1989 @param Handle Handle of the package list.\r
1990 @param PackageList Package List which contains the to be removed\r
1991 Device Path package.\r
1992\r
1993 @retval EFI_SUCCESS Device Path Package is deleted successfully.\r
1994 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1995\r
1996**/\r
93e3992d 1997EFI_STATUS\r
1998RemoveDevicePathPackage (\r
1999 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2000 IN EFI_HII_HANDLE Handle,\r
2001 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2002 )\r
2003{\r
2004 EFI_STATUS Status;\r
2005 UINT8 *Package;\r
2006 EFI_HII_PACKAGE_HEADER Header;\r
2007\r
2008 Package = PackageList->DevicePathPkg;\r
2009\r
2010 //\r
2011 // No device path, return directly.\r
2012 //\r
2013 if (Package == NULL) {\r
2014 return EFI_SUCCESS;\r
2015 }\r
2016\r
2017 Status = InvokeRegisteredFunction (\r
2018 Private,\r
2019 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2020 (VOID *) Package,\r
2021 EFI_HII_PACKAGE_DEVICE_PATH,\r
2022 Handle\r
2023 );\r
2024 if (EFI_ERROR (Status)) {\r
2025 return Status;\r
2026 }\r
2027\r
2028 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
2029 PackageList->PackageListHdr.PackageLength -= Header.Length;\r
2030\r
676df92c 2031 FreePool (Package);\r
93e3992d 2032\r
2033 PackageList->DevicePathPkg = NULL;\r
2034\r
2035 return EFI_SUCCESS;\r
2036}\r
2037\r
2038\r
2039/**\r
2040 This function will insert a device path package to package list firstly then\r
2041 invoke notification functions if any.\r
e90b081a 2042 This is a internal function.\r
93e3992d 2043\r
2044 @param Private Hii database private structure.\r
2045 @param NotifyType The type of change concerning the database.\r
2046 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol\r
2047 instance\r
2048 @param DatabaseRecord Pointer to a database record contains a package\r
2049 list which will be inserted to.\r
2050\r
2051 @retval EFI_SUCCESS Device path Package is inserted successfully.\r
2052 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2053 Device path package.\r
2054 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.\r
2055\r
2056**/\r
93e3992d 2057EFI_STATUS\r
2058AddDevicePathPackage (\r
2059 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2060 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2061 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
2062 IN OUT HII_DATABASE_RECORD *DatabaseRecord\r
2063 )\r
2064{\r
2065 EFI_STATUS Status;\r
2066\r
2067 if (DevicePath == NULL) {\r
2068 return EFI_SUCCESS;\r
2069 }\r
2070\r
2071 ASSERT (Private != NULL);\r
2072 ASSERT (DatabaseRecord != NULL);\r
2073\r
2074 //\r
2075 // Create a device path package and insert to packagelist\r
2076 //\r
2077 Status = InsertDevicePathPackage (\r
2078 DevicePath,\r
2079 NotifyType,\r
2080 DatabaseRecord->PackageList\r
2081 );\r
2082 if (EFI_ERROR (Status)) {\r
2083 return Status;\r
2084 }\r
2085\r
2086 return InvokeRegisteredFunction (\r
2087 Private,\r
2088 NotifyType,\r
2089 (VOID *) DatabaseRecord->PackageList->DevicePathPkg,\r
2090 EFI_HII_PACKAGE_DEVICE_PATH,\r
2091 DatabaseRecord->Handle\r
2092 );\r
2093}\r
2094\r
2095\r
2096/**\r
2097 This function insert a Keyboard Layout package to a package list node.\r
e90b081a 2098 This is a internal function.\r
93e3992d 2099\r
2100 @param PackageHdr Pointer to a buffer stored with Keyboard Layout\r
2101 package information.\r
2102 @param NotifyType The type of change concerning the database.\r
2103 @param PackageList Pointer to a package list which will be inserted\r
2104 to.\r
2105 @param Package Created Keyboard Layout package\r
2106\r
2107 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.\r
2108 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2109 Keyboard Layout package.\r
2110 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
2111\r
2112**/\r
93e3992d 2113EFI_STATUS\r
2114InsertKeyboardLayoutPackage (\r
2115 IN VOID *PackageHdr,\r
2116 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2117 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2118 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE **Package\r
2119 )\r
2120{\r
2121 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;\r
2122 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2123 EFI_STATUS Status;\r
2124\r
2125 if (PackageHdr == NULL || PackageList == NULL) {\r
2126 return EFI_INVALID_PARAMETER;\r
2127 }\r
2128\r
2129 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2130\r
2131 //\r
2132 // Create a Keyboard Layout package node\r
2133 //\r
2134 KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE));\r
2135 if (KeyboardLayoutPackage == NULL) {\r
2136 Status = EFI_OUT_OF_RESOURCES;\r
2137 goto Error;\r
2138 }\r
2139 KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE;\r
2140\r
2141 KeyboardLayoutPackage->KeyboardPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);\r
2142 if (KeyboardLayoutPackage->KeyboardPkg == NULL) {\r
2143 Status = EFI_OUT_OF_RESOURCES;\r
2144 goto Error;\r
2145 }\r
2146\r
2147 CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length);\r
2148 InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry);\r
2149\r
2150 *Package = KeyboardLayoutPackage;\r
2151\r
2152 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2153 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;\r
2154 }\r
2155\r
2156 return EFI_SUCCESS;\r
2157\r
2158Error:\r
2159\r
c59634ea 2160\r
676df92c 2161 if (KeyboardLayoutPackage != NULL) {\r
c59634ea 2162 if (KeyboardLayoutPackage->KeyboardPkg != NULL) {\r
2163 FreePool (KeyboardLayoutPackage->KeyboardPkg);\r
2164 }\r
676df92c 2165 FreePool (KeyboardLayoutPackage);\r
2166 }\r
93e3992d 2167\r
2168 return Status;\r
2169}\r
2170\r
2171\r
2172/**\r
2173 This function exports Keyboard Layout packages to a buffer.\r
e90b081a 2174 This is a internal function.\r
93e3992d 2175\r
2176 @param Private Hii database private structure.\r
2177 @param Handle Identification of a package list.\r
2178 @param PackageList Pointer to a package list which will be exported.\r
2179 @param UsedSize The length of buffer be used.\r
2180 @param BufferSize Length of the Buffer.\r
2181 @param Buffer Allocated space for storing exported data.\r
2182 @param ResultSize The size of the already exported content of this\r
2183 package list.\r
2184\r
2185 @retval EFI_SUCCESS Keyboard Layout Packages are exported\r
2186 successfully.\r
2187 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2188\r
2189**/\r
93e3992d 2190EFI_STATUS\r
2191ExportKeyboardLayoutPackages (\r
2192 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2193 IN EFI_HII_HANDLE Handle,\r
2194 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2195 IN UINTN UsedSize,\r
2196 IN UINTN BufferSize,\r
2197 IN OUT VOID *Buffer,\r
2198 IN OUT UINTN *ResultSize\r
2199 )\r
2200{\r
2201 LIST_ENTRY *Link;\r
2202 UINTN PackageLength;\r
2203 EFI_STATUS Status;\r
2204 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
2205 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2206\r
2207 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
2208 return EFI_INVALID_PARAMETER;\r
2209 }\r
2210\r
2211 if (BufferSize > 0 && Buffer == NULL ) {\r
2212 return EFI_INVALID_PARAMETER;\r
2213 }\r
2214\r
2215 PackageLength = 0;\r
2216 Status = EFI_SUCCESS;\r
2217\r
2218 for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) {\r
2219 Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE);\r
2220 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
2221 PackageLength += PackageHeader.Length;\r
2222 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
2223 //\r
2224 // Invoke registered notification function with EXPORT_PACK notify type\r
2225 //\r
2226 Status = InvokeRegisteredFunction (\r
2227 Private,\r
2228 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
2229 (EFI_HII_PACKAGE_HEADER *) Package,\r
2230 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,\r
2231 Handle\r
2232 );\r
2233 ASSERT_EFI_ERROR (Status);\r
2234\r
2235 //\r
2236 // Copy Keyboard Layout package\r
2237 //\r
2238 CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length);\r
2239 Buffer = (UINT8 *) Buffer + PackageHeader.Length;\r
2240 }\r
2241 }\r
2242\r
2243 *ResultSize += PackageLength;\r
2244 return EFI_SUCCESS;\r
2245}\r
2246\r
2247\r
2248/**\r
2249 This function deletes all Keyboard Layout packages from a package list node.\r
e90b081a 2250 This is a internal function.\r
93e3992d 2251\r
2252 @param Private Hii database private data.\r
2253 @param Handle Handle of the package list which contains the to\r
2254 be removed Keyboard Layout packages.\r
2255 @param PackageList Pointer to a package list that contains removing\r
2256 packages.\r
2257\r
2258 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted\r
2259 successfully.\r
2260 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
2261\r
2262**/\r
93e3992d 2263EFI_STATUS\r
2264RemoveKeyboardLayoutPackages (\r
2265 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2266 IN EFI_HII_HANDLE Handle,\r
2267 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2268 )\r
2269{\r
2270 LIST_ENTRY *ListHead;\r
2271 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
2272 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2273 EFI_STATUS Status;\r
2274\r
2275 ListHead = &PackageList->KeyboardLayoutHdr;\r
2276\r
2277 while (!IsListEmpty (ListHead)) {\r
2278 Package = CR (\r
2279 ListHead->ForwardLink,\r
2280 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
2281 KeyboardEntry,\r
2282 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
2283 );\r
2284 Status = InvokeRegisteredFunction (\r
2285 Private,\r
2286 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2287 (VOID *) Package,\r
2288 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,\r
2289 Handle\r
2290 );\r
2291 if (EFI_ERROR (Status)) {\r
2292 return Status;\r
2293 }\r
2294\r
2295 RemoveEntryList (&Package->KeyboardEntry);\r
2296 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
2297 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;\r
676df92c 2298 FreePool (Package->KeyboardPkg);\r
2299 FreePool (Package);\r
93e3992d 2300 }\r
2301\r
2302 return EFI_SUCCESS;\r
2303}\r
2304\r
2305\r
2306/**\r
2307 This function will insert a package list to hii database firstly then\r
2308 invoke notification functions if any. It is the worker function of\r
2309 HiiNewPackageList and HiiUpdatePackageList.\r
2310\r
e90b081a 2311 This is a internal function.\r
2312\r
93e3992d 2313 @param Private Hii database private structure.\r
2314 @param NotifyType The type of change concerning the database.\r
2315 @param PackageList Pointer to a package list.\r
2316 @param DatabaseRecord Pointer to a database record contains a package\r
2317 list instance which will be inserted to.\r
2318\r
2319 @retval EFI_SUCCESS All incoming packages are inserted to current\r
2320 database.\r
2321 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2322 Device path package.\r
2323 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2324\r
2325**/\r
93e3992d 2326EFI_STATUS\r
2327AddPackages (\r
2328 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2329 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2330 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
2331 IN OUT HII_DATABASE_RECORD *DatabaseRecord\r
2332 )\r
2333{\r
2334 EFI_STATUS Status;\r
2335 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
2336 HII_IFR_PACKAGE_INSTANCE *FormPackage;\r
2337 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;\r
2338 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
2339 HII_FONT_PACKAGE_INSTANCE *FontPackage;\r
2340 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;\r
2341 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
2342 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
2343 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2344 UINT32 OldPackageListLen;\r
2345\r
6c46a5ab 2346 //\r
2347 // Initialize Variables\r
2348 //\r
2349 FontPackage = NULL;\r
2350\r
93e3992d 2351 //\r
2352 // Process the package list header\r
2353 //\r
2354 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;\r
2355 CopyMem (\r
2356 &DatabaseRecord->PackageList->PackageListHdr,\r
2357 (VOID *) PackageList,\r
2358 sizeof (EFI_HII_PACKAGE_LIST_HEADER)\r
2359 );\r
2360 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2361 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;\r
2362 }\r
2363\r
2364 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
2365 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2366\r
2367 Status = EFI_SUCCESS;\r
2368\r
2369 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
2370 switch (PackageHeader.Type) {\r
2371 case EFI_HII_PACKAGE_TYPE_GUID:\r
2372 Status = InsertGuidPackage (\r
2373 PackageHdrPtr,\r
2374 NotifyType,\r
2375 DatabaseRecord->PackageList,\r
2376 &GuidPackage\r
2377 );\r
2378 if (EFI_ERROR (Status)) {\r
2379 return Status;\r
2380 }\r
2381 Status = InvokeRegisteredFunction (\r
2382 Private,\r
2383 NotifyType,\r
2384 (VOID *) GuidPackage,\r
2385 (UINT8) (PackageHeader.Type),\r
2386 DatabaseRecord->Handle\r
2387 );\r
2388 break;\r
8d00a0f1 2389 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 2390 Status = InsertFormPackage (\r
2391 PackageHdrPtr,\r
2392 NotifyType,\r
2393 DatabaseRecord->PackageList,\r
2394 &FormPackage\r
2395 );\r
2396 if (EFI_ERROR (Status)) {\r
2397 return Status;\r
2398 }\r
2399 Status = InvokeRegisteredFunction (\r
2400 Private,\r
2401 NotifyType,\r
2402 (VOID *) FormPackage,\r
2403 (UINT8) (PackageHeader.Type),\r
2404 DatabaseRecord->Handle\r
2405 );\r
2406 break;\r
2407 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
2408 Status = InsertKeyboardLayoutPackage (\r
2409 PackageHdrPtr,\r
2410 NotifyType,\r
2411 DatabaseRecord->PackageList,\r
2412 &KeyboardLayoutPackage\r
2413 );\r
2414 if (EFI_ERROR (Status)) {\r
2415 return Status;\r
2416 }\r
2417 Status = InvokeRegisteredFunction (\r
2418 Private,\r
2419 NotifyType,\r
2420 (VOID *) KeyboardLayoutPackage,\r
2421 (UINT8) (PackageHeader.Type),\r
2422 DatabaseRecord->Handle\r
2423 );\r
2424 break;\r
2425 case EFI_HII_PACKAGE_STRINGS:\r
2426 Status = InsertStringPackage (\r
2427 Private,\r
2428 PackageHdrPtr,\r
2429 NotifyType,\r
2430 DatabaseRecord->PackageList,\r
2431 &StringPackage\r
2432 );\r
2433 if (EFI_ERROR (Status)) {\r
2434 return Status;\r
2435 }\r
2436 Status = InvokeRegisteredFunction (\r
2437 Private,\r
2438 NotifyType,\r
2439 (VOID *) StringPackage,\r
2440 (UINT8) (PackageHeader.Type),\r
2441 DatabaseRecord->Handle\r
2442 );\r
2443 break;\r
2444 case EFI_HII_PACKAGE_FONTS:\r
2445 Status = InsertFontPackage (\r
2446 Private,\r
2447 PackageHdrPtr,\r
2448 NotifyType,\r
2449 DatabaseRecord->PackageList,\r
2450 &FontPackage\r
2451 );\r
2452 if (EFI_ERROR (Status)) {\r
2453 return Status;\r
2454 }\r
2455 Status = InvokeRegisteredFunction (\r
2456 Private,\r
2457 NotifyType,\r
2458 (VOID *) FontPackage,\r
2459 (UINT8) (PackageHeader.Type),\r
2460 DatabaseRecord->Handle\r
2461 );\r
2462 break;\r
2463 case EFI_HII_PACKAGE_IMAGES:\r
2464 Status = InsertImagePackage (\r
2465 PackageHdrPtr,\r
2466 NotifyType,\r
2467 DatabaseRecord->PackageList,\r
2468 &ImagePackage\r
2469 );\r
2470 if (EFI_ERROR (Status)) {\r
2471 return Status;\r
2472 }\r
2473 Status = InvokeRegisteredFunction (\r
2474 Private,\r
2475 NotifyType,\r
2476 (VOID *) ImagePackage,\r
2477 (UINT8) (PackageHeader.Type),\r
2478 DatabaseRecord->Handle\r
2479 );\r
2480 break;\r
2481 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
2482 Status = InsertSimpleFontPackage (\r
2483 PackageHdrPtr,\r
2484 NotifyType,\r
2485 DatabaseRecord->PackageList,\r
2486 &SimpleFontPackage\r
2487 );\r
2488 if (EFI_ERROR (Status)) {\r
2489 return Status;\r
2490 }\r
2491 Status = InvokeRegisteredFunction (\r
2492 Private,\r
2493 NotifyType,\r
2494 (VOID *) SimpleFontPackage,\r
2495 (UINT8) (PackageHeader.Type),\r
2496 DatabaseRecord->Handle\r
2497 );\r
2498 break;\r
2499 case EFI_HII_PACKAGE_DEVICE_PATH:\r
2500 Status = AddDevicePathPackage (\r
2501 Private,\r
2502 NotifyType,\r
2503 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),\r
2504 DatabaseRecord\r
2505 );\r
2506 break;\r
2507 default:\r
2508 break;\r
2509 }\r
2510\r
2511 if (EFI_ERROR (Status)) {\r
2512 return Status;\r
2513 }\r
2514 //\r
2515 // goto header of next package\r
2516 //\r
2517 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
2518 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2519 }\r
2520\r
2521 return Status;\r
2522}\r
2523\r
2524\r
2525/**\r
2526 This function exports a package list to a buffer. It is the worker function\r
2527 of HiiExportPackageList.\r
2528\r
e90b081a 2529 This is a internal function.\r
2530\r
93e3992d 2531 @param Private Hii database private structure.\r
2532 @param Handle Identification of a package list.\r
2533 @param PackageList Pointer to a package list which will be exported.\r
2534 @param UsedSize The length of buffer has been used by exporting\r
2535 package lists when Handle is NULL.\r
2536 @param BufferSize Length of the Buffer.\r
2537 @param Buffer Allocated space for storing exported data.\r
2538\r
2539 @retval EFI_SUCCESS Keyboard Layout Packages are exported\r
2540 successfully.\r
2541 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2542\r
2543**/\r
93e3992d 2544EFI_STATUS\r
2545ExportPackageList (\r
2546 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2547 IN EFI_HII_HANDLE Handle,\r
2548 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2549 IN OUT UINTN *UsedSize,\r
2550 IN UINTN BufferSize,\r
2551 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
2552 )\r
2553{\r
2554 EFI_STATUS Status;\r
2555 UINTN ResultSize;\r
2556 EFI_HII_PACKAGE_HEADER EndofPackageList;\r
2557\r
96ff65a1 2558 ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);\r
93e3992d 2559 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
2560 ASSERT (IsHiiHandleValid (Handle));\r
2561\r
2562 if (BufferSize > 0 && Buffer == NULL ) {\r
2563 return EFI_INVALID_PARAMETER;\r
2564 }\r
2565\r
2566 //\r
2567 // Copy the package list header\r
2568 // ResultSize indicates the length of the exported bytes of this package list\r
2569 //\r
2570 ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
2571 if (ResultSize + *UsedSize <= BufferSize) {\r
2572 CopyMem ((VOID *) Buffer, PackageList, ResultSize);\r
2573 }\r
2574 //\r
2575 // Copy the packages and invoke EXPORT_PACK notify functions if exists.\r
2576 //\r
2577 Status = ExportGuidPackages (\r
2578 Private,\r
2579 Handle,\r
2580 PackageList,\r
2581 *UsedSize,\r
2582 BufferSize,\r
2583 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2584 &ResultSize\r
2585 );\r
2586 if (EFI_ERROR (Status)) {\r
2587 return Status;\r
2588 }\r
2589 Status = ExportFormPackages (\r
2590 Private,\r
2591 Handle,\r
2592 PackageList,\r
2593 *UsedSize,\r
2594 BufferSize,\r
2595 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2596 &ResultSize\r
2597 );\r
2598 if (EFI_ERROR (Status)) {\r
2599 return Status;\r
2600 }\r
2601 Status = ExportKeyboardLayoutPackages (\r
2602 Private,\r
2603 Handle,\r
2604 PackageList,\r
2605 *UsedSize,\r
2606 BufferSize,\r
2607 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2608 &ResultSize\r
2609 );\r
2610 if (EFI_ERROR (Status)) {\r
2611 return Status;\r
2612 }\r
2613 Status = ExportStringPackages (\r
2614 Private,\r
2615 Handle,\r
2616 PackageList,\r
2617 *UsedSize,\r
2618 BufferSize,\r
2619 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2620 &ResultSize\r
2621 );\r
2622 if (EFI_ERROR (Status)) {\r
2623 return Status;\r
2624 }\r
2625 Status = ExportFontPackages (\r
2626 Private,\r
2627 Handle,\r
2628 PackageList,\r
2629 *UsedSize,\r
2630 BufferSize,\r
2631 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2632 &ResultSize\r
2633 );\r
2634 if (EFI_ERROR (Status)) {\r
2635 return Status;\r
2636 }\r
2637 Status = ExportImagePackages (\r
2638 Private,\r
2639 Handle,\r
2640 PackageList,\r
2641 *UsedSize,\r
2642 BufferSize,\r
2643 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2644 &ResultSize\r
2645 );\r
2646 if (EFI_ERROR (Status)) {\r
2647 return Status;\r
2648 }\r
2649 Status = ExportSimpleFontPackages (\r
2650 Private,\r
2651 Handle,\r
2652 PackageList,\r
2653 *UsedSize,\r
2654 BufferSize,\r
2655 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2656 &ResultSize\r
2657 );\r
2658 if (EFI_ERROR (Status)) {\r
2659 return Status;\r
2660 }\r
2661 Status = ExportDevicePathPackage (\r
2662 Private,\r
2663 Handle,\r
2664 PackageList,\r
2665 *UsedSize,\r
2666 BufferSize,\r
2667 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2668 &ResultSize\r
2669 );\r
2670 if (EFI_ERROR (Status)) {\r
2671 return Status;\r
2672 }\r
2673 //\r
2674 // Append the package list end.\r
2675 //\r
2676 EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
2677 EndofPackageList.Type = EFI_HII_PACKAGE_END;\r
2678 if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {\r
2679 CopyMem (\r
2680 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2681 (VOID *) &EndofPackageList,\r
2682 sizeof (EFI_HII_PACKAGE_HEADER)\r
2683 );\r
2684 }\r
2685\r
2686 *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);\r
2687\r
2688 return EFI_SUCCESS;\r
2689}\r
2690\r
2691\r
2692/**\r
2693 This function adds the packages in the package list to the database and returns a handle. If there is a\r
2694 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will\r
2695 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.\r
2696\r
2697 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2698 instance.\r
2699 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
2700 structure.\r
2701 @param DriverHandle Associate the package list with this EFI handle.\r
2702 @param Handle A pointer to the EFI_HII_HANDLE instance.\r
2703\r
2704 @retval EFI_SUCCESS The package list associated with the Handle was\r
2705 added to the HII database.\r
2706 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2707 database contents.\r
2708 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.\r
2709 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.\r
2710\r
2711**/\r
2712EFI_STATUS\r
2713EFIAPI\r
2714HiiNewPackageList (\r
2715 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2716 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
2717 IN CONST EFI_HANDLE DriverHandle,\r
2718 OUT EFI_HII_HANDLE *Handle\r
2719 )\r
2720{\r
2721 EFI_STATUS Status;\r
2722 HII_DATABASE_PRIVATE_DATA *Private;\r
2723 HII_DATABASE_RECORD *DatabaseRecord;\r
2724 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2725 LIST_ENTRY *Link;\r
2726 EFI_GUID PackageListGuid;\r
2727\r
2728 if (This == NULL || PackageList == NULL || Handle == NULL) {\r
2729 return EFI_INVALID_PARAMETER;\r
2730 }\r
2731\r
2732 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2733 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));\r
2734\r
2735 //\r
2736 // Check the Package list GUID to guarantee this GUID is unique in database.\r
2737 //\r
2738 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2739 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2740 if (CompareGuid (\r
2741 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
aa2614b7 2742 &PackageListGuid) && \r
2743 DatabaseRecord->DriverHandle == DriverHandle) {\r
93e3992d 2744 return EFI_INVALID_PARAMETER;\r
2745 }\r
2746 }\r
2747\r
2748 //\r
2749 // Build a PackageList node\r
2750 //\r
2751 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
2752 if (EFI_ERROR (Status)) {\r
2753 return Status;\r
2754 }\r
2755\r
2756 //\r
2757 // Fill in information of the created Package List node\r
2758 // according to incoming package list.\r
2759 //\r
2760 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
2761 if (EFI_ERROR (Status)) {\r
2762 return Status;\r
2763 }\r
2764\r
2765 DatabaseRecord->DriverHandle = DriverHandle;\r
2766\r
2767 //\r
2768 // Create a Device path package and add into the package list if exists.\r
2769 //\r
2770 Status = gBS->HandleProtocol (\r
2771 DriverHandle,\r
2772 &gEfiDevicePathProtocolGuid,\r
2773 (VOID **) &DevicePath\r
2774 );\r
2775 if (!EFI_ERROR (Status)) {\r
2776 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);\r
2777 ASSERT_EFI_ERROR (Status);\r
2778 }\r
2779\r
2780 *Handle = DatabaseRecord->Handle;\r
2781 return EFI_SUCCESS;\r
2782}\r
2783\r
2784\r
2785/**\r
2786 This function removes the package list that is associated with a handle Handle\r
2787 from the HII database. Before removing the package, any registered functions\r
2788 with the notification type REMOVE_PACK and the same package type will be called.\r
2789\r
2790 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2791 instance.\r
2792 @param Handle The handle that was registered to the data that is\r
2793 requested for removal.\r
2794\r
2795 @retval EFI_SUCCESS The data associated with the Handle was removed\r
2796 from the HII database.\r
813acf3a 2797 @retval EFI_NOT_FOUND The specified andle is not in database.\r
93e3992d 2798 @retval EFI_INVALID_PARAMETER The Handle was not valid.\r
2799\r
2800**/\r
2801EFI_STATUS\r
2802EFIAPI\r
2803HiiRemovePackageList (\r
2804 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2805 IN EFI_HII_HANDLE Handle\r
2806 )\r
2807{\r
2808 EFI_STATUS Status;\r
2809 HII_DATABASE_PRIVATE_DATA *Private;\r
2810 LIST_ENTRY *Link;\r
2811 HII_DATABASE_RECORD *Node;\r
2812 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
2813 HII_HANDLE *HiiHandle;\r
2814\r
813acf3a 2815 if (This == NULL) {\r
93e3992d 2816 return EFI_INVALID_PARAMETER;\r
2817 }\r
2818\r
813acf3a 2819 if (!IsHiiHandleValid (Handle)) {\r
2820 return EFI_NOT_FOUND;\r
2821 }\r
2822\r
93e3992d 2823 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2824\r
2825 //\r
2826 // Get the packagelist to be removed.\r
2827 //\r
2828 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2829 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2830 if (Node->Handle == Handle) {\r
2831 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
2832 ASSERT (PackageList != NULL);\r
2833\r
2834 //\r
2835 // Call registered functions with REMOVE_PACK before removing packages\r
2836 // then remove them.\r
2837 //\r
2838 Status = RemoveGuidPackages (Private, Handle, PackageList);\r
2839 if (EFI_ERROR (Status)) {\r
2840 return Status;\r
2841 }\r
2842 Status = RemoveFormPackages (Private, Handle, PackageList);\r
2843 if (EFI_ERROR (Status)) {\r
2844 return Status;\r
2845 }\r
2846 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
2847 if (EFI_ERROR (Status)) {\r
2848 return Status;\r
2849 }\r
2850 Status = RemoveStringPackages (Private, Handle, PackageList);\r
2851 if (EFI_ERROR (Status)) {\r
2852 return Status;\r
2853 }\r
2854 Status = RemoveFontPackages (Private, Handle, PackageList);\r
2855 if (EFI_ERROR (Status)) {\r
2856 return Status;\r
2857 }\r
2858 Status = RemoveImagePackages (Private, Handle, PackageList);\r
2859 if (EFI_ERROR (Status)) {\r
2860 return Status;\r
2861 }\r
2862 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
2863 if (EFI_ERROR (Status)) {\r
2864 return Status;\r
2865 }\r
2866 Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
2867 if (EFI_ERROR (Status)) {\r
2868 return Status;\r
2869 }\r
2870\r
2871 //\r
2872 // Free resources of the package list\r
2873 //\r
2874 RemoveEntryList (&Node->DatabaseEntry);\r
2875\r
2876 HiiHandle = (HII_HANDLE *) Handle;\r
2877 RemoveEntryList (&HiiHandle->Handle);\r
2878 Private->HiiHandleCount--;\r
2879 ASSERT (Private->HiiHandleCount >= 0);\r
2880\r
2881 HiiHandle->Signature = 0;\r
676df92c 2882 FreePool (HiiHandle);\r
2883 FreePool (Node->PackageList);\r
2884 FreePool (Node);\r
93e3992d 2885\r
2886 return EFI_SUCCESS;\r
2887 }\r
2888 }\r
2889\r
2890 return EFI_NOT_FOUND;\r
2891}\r
2892\r
2893\r
2894/**\r
2895 This function updates the existing package list (which has the specified Handle)\r
2896 in the HII databases, using the new package list specified by PackageList.\r
2897\r
2898 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2899 instance.\r
2900 @param Handle The handle that was registered to the data that is\r
2901 requested to be updated.\r
2902 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
2903 package.\r
2904\r
2905 @retval EFI_SUCCESS The HII database was successfully updated.\r
2906 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated\r
2907 database.\r
813acf3a 2908 @retval EFI_INVALID_PARAMETER PackageList was NULL.\r
2909 @retval EFI_NOT_FOUND The specified Handle is not in database.\r
93e3992d 2910\r
2911**/\r
2912EFI_STATUS\r
2913EFIAPI\r
2914HiiUpdatePackageList (\r
2915 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2916 IN EFI_HII_HANDLE Handle,\r
2917 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList\r
2918 )\r
2919{\r
2920 EFI_STATUS Status;\r
2921 HII_DATABASE_PRIVATE_DATA *Private;\r
2922 LIST_ENTRY *Link;\r
2923 HII_DATABASE_RECORD *Node;\r
2924 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
2925 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;\r
2926 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2927\r
813acf3a 2928 if (This == NULL || PackageList == NULL) {\r
93e3992d 2929 return EFI_INVALID_PARAMETER;\r
2930 }\r
2931\r
2932 if (!IsHiiHandleValid (Handle)) {\r
2933 return EFI_NOT_FOUND;\r
2934 }\r
2935\r
2936 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2937\r
2938 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
2939\r
2940 Status = EFI_SUCCESS;\r
2941\r
2942 //\r
2943 // Get original packagelist to be updated\r
2944 //\r
2945 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2946 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2947 if (Node->Handle == Handle) {\r
2948 OldPackageList = Node->PackageList;\r
2949 //\r
2950 // Remove the package if its type matches one of the package types which is\r
2951 // contained in the new package list.\r
2952 //\r
2953 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2954 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
2955 switch (PackageHeader.Type) {\r
2956 case EFI_HII_PACKAGE_TYPE_GUID:\r
2957 Status = RemoveGuidPackages (Private, Handle, OldPackageList);\r
2958 break;\r
8d00a0f1 2959 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 2960 Status = RemoveFormPackages (Private, Handle, OldPackageList);\r
2961 break;\r
2962 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
2963 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);\r
2964 break;\r
2965 case EFI_HII_PACKAGE_STRINGS:\r
2966 Status = RemoveStringPackages (Private, Handle, OldPackageList);\r
2967 break;\r
2968 case EFI_HII_PACKAGE_FONTS:\r
2969 Status = RemoveFontPackages (Private, Handle, OldPackageList);\r
2970 break;\r
2971 case EFI_HII_PACKAGE_IMAGES:\r
2972 Status = RemoveImagePackages (Private, Handle, OldPackageList);\r
2973 break;\r
2974 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
2975 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);\r
2976 break;\r
2977 case EFI_HII_PACKAGE_DEVICE_PATH:\r
2978 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);\r
2979 break;\r
2980 }\r
2981\r
2982 if (EFI_ERROR (Status)) {\r
2983 return Status;\r
2984 }\r
2985\r
2986 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
2987 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2988 }\r
2989\r
2990 //\r
2991 // Add all of the packages within the new package list\r
2992 //\r
2993 return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
2994 }\r
2995 }\r
2996\r
2997 return EFI_NOT_FOUND;\r
2998}\r
2999\r
3000\r
3001/**\r
3002 This function returns a list of the package handles of the specified type\r
3003 that are currently active in the database. The pseudo-type\r
3004 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.\r
3005\r
3006 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3007 instance.\r
3008 @param PackageType Specifies the package type of the packages to list\r
3009 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3010 listed.\r
3011 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3012 this is the pointer to the GUID which must match\r
3013 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.\r
3014 Otherwise, it must be NULL.\r
3015 @param HandleBufferLength On input, a pointer to the length of the handle\r
3016 buffer. On output, the length of the handle\r
3017 buffer that is required for the handles found.\r
3018 @param Handle An array of EFI_HII_HANDLE instances returned.\r
3019\r
3020 @retval EFI_SUCCESS The matching handles are outputed successfully.\r
813acf3a 3021 HandleBufferLength is updated with the actual length.\r
93e3992d 3022 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3023 Handle is too small to support the number of\r
3024 handles. HandleBufferLength is updated with a\r
3025 value that will enable the data to fit.\r
3026 @retval EFI_NOT_FOUND No matching handle could not be found in database.\r
3027 @retval EFI_INVALID_PARAMETER Handle or HandleBufferLength was NULL.\r
813acf3a 3028 \r
3029 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but\r
3030 PackageGuid is not NULL, PackageType is a EFI_HII_\r
3031 PACKAGE_TYPE_GUID but PackageGuid is NULL.\r
93e3992d 3032\r
3033**/\r
3034EFI_STATUS\r
3035EFIAPI\r
3036HiiListPackageLists (\r
3037 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3038 IN UINT8 PackageType,\r
3039 IN CONST EFI_GUID *PackageGuid,\r
3040 IN OUT UINTN *HandleBufferLength,\r
3041 OUT EFI_HII_HANDLE *Handle\r
3042 )\r
3043{\r
3044 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
3045 HII_DATABASE_PRIVATE_DATA *Private;\r
3046 HII_DATABASE_RECORD *Node;\r
3047 LIST_ENTRY *Link;\r
3048 BOOLEAN Matched;\r
3049 HII_HANDLE **Result;\r
3050 UINTN ResultSize;\r
3051 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3052 LIST_ENTRY *Link1;\r
3053\r
3054 //\r
3055 // Check input parameters\r
3056 //\r
3057 if (This == NULL || HandleBufferLength == NULL) {\r
3058 return EFI_INVALID_PARAMETER;\r
3059 }\r
3060 if (*HandleBufferLength > 0 && Handle == NULL) {\r
3061 return EFI_INVALID_PARAMETER;\r
3062 }\r
3063 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3064 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3065 return EFI_INVALID_PARAMETER;\r
3066 }\r
3067\r
3068 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3069 Matched = FALSE;\r
3070 Result = (HII_HANDLE **) Handle;\r
3071 ResultSize = 0;\r
3072\r
3073 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3074 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3075 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3076 switch (PackageType) {\r
3077 case EFI_HII_PACKAGE_TYPE_GUID:\r
3078 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {\r
3079 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);\r
3080 if (CompareGuid (\r
3081 (EFI_GUID *) PackageGuid,\r
3082 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))\r
3083 )) {\r
3084 Matched = TRUE;\r
3085 break;\r
3086 }\r
3087 }\r
3088 break;\r
8d00a0f1 3089 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3090 if (!IsListEmpty (&PackageList->FormPkgHdr)) {\r
3091 Matched = TRUE;\r
3092 }\r
3093 break;\r
3094 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3095 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {\r
3096 Matched = TRUE;\r
3097 }\r
3098 break;\r
3099 case EFI_HII_PACKAGE_STRINGS:\r
3100 if (!IsListEmpty (&PackageList->StringPkgHdr)) {\r
3101 Matched = TRUE;\r
3102 }\r
3103 break;\r
3104 case EFI_HII_PACKAGE_FONTS:\r
3105 if (!IsListEmpty (&PackageList->FontPkgHdr)) {\r
3106 Matched = TRUE;\r
3107 }\r
3108 break;\r
3109 case EFI_HII_PACKAGE_IMAGES:\r
3110 if (PackageList->ImagePkg != NULL) {\r
3111 Matched = TRUE;\r
3112 }\r
3113 break;\r
3114 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3115 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {\r
3116 Matched = TRUE;\r
3117 }\r
3118 break;\r
3119 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3120 if (PackageList->DevicePathPkg != NULL) {\r
3121 Matched = TRUE;\r
3122 }\r
3123 break;\r
3124 //\r
3125 // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles\r
3126 // to be listed.\r
3127 //\r
3128 case EFI_HII_PACKAGE_TYPE_ALL:\r
3129 Matched = TRUE;\r
3130 break;\r
3131 default:\r
3132 break;\r
3133 }\r
3134\r
3135 //\r
3136 // This active package list has the specified package type, list it.\r
3137 //\r
3138 if (Matched) {\r
3139 ResultSize += sizeof (EFI_HII_HANDLE);\r
3140 if (ResultSize <= *HandleBufferLength) {\r
3141 *Result++ = Node->Handle;\r
3142 }\r
3143 }\r
3144 Matched = FALSE;\r
3145 }\r
3146\r
3147 if (ResultSize == 0) {\r
3148 return EFI_NOT_FOUND;\r
3149 }\r
3150\r
3151 if (*HandleBufferLength < ResultSize) {\r
3152 *HandleBufferLength = ResultSize;\r
3153 return EFI_BUFFER_TOO_SMALL;\r
3154 }\r
3155\r
3156 *HandleBufferLength = ResultSize;\r
3157 return EFI_SUCCESS;\r
3158}\r
3159\r
3160\r
3161/**\r
3162 This function will export one or all package lists in the database to a buffer.\r
3163 For each package list exported, this function will call functions registered\r
3164 with EXPORT_PACK and then copy the package list to the buffer.\r
3165\r
3166 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3167 instance.\r
3168 @param Handle An EFI_HII_HANDLE that corresponds to the desired\r
3169 package list in the HII database to export or NULL\r
3170 to indicate all package lists should be exported.\r
3171 @param BufferSize On input, a pointer to the length of the buffer.\r
3172 On output, the length of the buffer that is\r
3173 required for the exported data.\r
3174 @param Buffer A pointer to a buffer that will contain the\r
3175 results of the export function.\r
3176\r
3177 @retval EFI_SUCCESS Package exported.\r
3178 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3179 Handle is too small to support the number of\r
3180 handles. HandleBufferLength is updated with a\r
3181 value that will enable the data to fit.\r
3182 @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the\r
3183 current database.\r
3184 @retval EFI_INVALID_PARAMETER Handle or Buffer or BufferSize was NULL.\r
3185\r
3186**/\r
3187EFI_STATUS\r
3188EFIAPI\r
3189HiiExportPackageLists (\r
3190 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3191 IN EFI_HII_HANDLE Handle,\r
3192 IN OUT UINTN *BufferSize,\r
3193 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
3194 )\r
3195{\r
3196 LIST_ENTRY *Link;\r
3197 EFI_STATUS Status;\r
3198 HII_DATABASE_PRIVATE_DATA *Private;\r
3199 HII_DATABASE_RECORD *Node;\r
3200 UINTN UsedSize;\r
3201\r
3202 if (This == NULL || BufferSize == NULL || Handle == NULL) {\r
3203 return EFI_INVALID_PARAMETER;\r
3204 }\r
3205 if (*BufferSize > 0 && Buffer == NULL) {\r
3206 return EFI_INVALID_PARAMETER;\r
3207 }\r
3208 if (!IsHiiHandleValid (Handle)) {\r
3209 return EFI_NOT_FOUND;\r
3210 }\r
3211\r
3212 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3213 UsedSize = 0;\r
3214\r
3215 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3216 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3217 if (Handle == NULL) {\r
3218 //\r
3219 // Export all package lists in current hii database.\r
3220 //\r
3221 Status = ExportPackageList (\r
3222 Private,\r
3223 Node->Handle,\r
3224 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3225 &UsedSize,\r
3226 *BufferSize,\r
3227 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)\r
3228 );\r
3229 ASSERT_EFI_ERROR (Status);\r
6672d625 3230 } else if (Handle != NULL && Node->Handle == Handle) {\r
93e3992d 3231 Status = ExportPackageList (\r
3232 Private,\r
3233 Handle,\r
3234 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3235 &UsedSize,\r
3236 *BufferSize,\r
3237 Buffer\r
3238 );\r
3239 ASSERT_EFI_ERROR (Status);\r
3240 if (*BufferSize < UsedSize) {\r
3241 *BufferSize = UsedSize;\r
3242 return EFI_BUFFER_TOO_SMALL;\r
3243 }\r
3244 return EFI_SUCCESS;\r
3245 }\r
3246 }\r
3247\r
3248 if (Handle == NULL && UsedSize != 0) {\r
3249 if (*BufferSize < UsedSize) {\r
3250 *BufferSize = UsedSize;\r
3251 return EFI_BUFFER_TOO_SMALL;\r
3252 }\r
3253 return EFI_SUCCESS;\r
3254 }\r
3255\r
3256 return EFI_NOT_FOUND;\r
3257}\r
3258\r
3259\r
3260/**\r
3261 This function registers a function which will be called when specified actions related to packages of\r
3262 the specified type occur in the HII database. By registering a function, other HII-related drivers are\r
3263 notified when specific package types are added, removed or updated in the HII database.\r
3264 Each driver or application which registers a notification should use\r
3265 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.\r
3266\r
3267 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3268 instance.\r
3269 @param PackageType Specifies the package type of the packages to list\r
3270 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3271 listed.\r
3272 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3273 this is the pointer to the GUID which must match\r
3274 the Guid field of\r
3275 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must\r
3276 be NULL.\r
3277 @param PackageNotifyFn Points to the function to be called when the event\r
3278 specified by\r
3279 NotificationType occurs.\r
3280 @param NotifyType Describes the types of notification which this\r
3281 function will be receiving.\r
3282 @param NotifyHandle Points to the unique handle assigned to the\r
3283 registered notification. Can be used in\r
3284 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()\r
3285 to stop notifications.\r
3286\r
3287 @retval EFI_SUCCESS Notification registered successfully.\r
3288 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures\r
3289 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.\r
3290 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not\r
3291 EFI_HII_PACKAGE_TYPE_GUID.\r
3292 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is\r
3293 EFI_HII_PACKAGE_TYPE_GUID.\r
3294\r
3295**/\r
3296EFI_STATUS\r
3297EFIAPI\r
3298HiiRegisterPackageNotify (\r
3299 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3300 IN UINT8 PackageType,\r
3301 IN CONST EFI_GUID *PackageGuid,\r
3302 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,\r
3303 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
3304 OUT EFI_HANDLE *NotifyHandle\r
3305 )\r
3306{\r
3307 HII_DATABASE_PRIVATE_DATA *Private;\r
3308 HII_DATABASE_NOTIFY *Notify;\r
3309 EFI_STATUS Status;\r
3310\r
3311 if (This == NULL || NotifyHandle == NULL) {\r
3312 return EFI_INVALID_PARAMETER;\r
3313 }\r
3314 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3315 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3316 return EFI_INVALID_PARAMETER;\r
3317 }\r
3318\r
3319 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3320\r
3321 //\r
3322 // Allocate a notification node\r
3323 //\r
3324 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));\r
3325 if (Notify == NULL) {\r
3326 return EFI_OUT_OF_RESOURCES;\r
3327 }\r
3328\r
3329 //\r
3330 // Generate a notify handle\r
3331 //\r
3332 Status = gBS->InstallMultipleProtocolInterfaces (\r
3333 &Notify->NotifyHandle,\r
3334 &mHiiDatabaseNotifyGuid,\r
3335 NULL,\r
3336 NULL\r
3337 );\r
3338 ASSERT_EFI_ERROR (Status);\r
3339\r
3340 //\r
3341 // Fill in the information to the notification node\r
3342 //\r
3343 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;\r
3344 Notify->PackageType = PackageType;\r
3345 Notify->PackageGuid = (EFI_GUID *) PackageGuid;\r
3346 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;\r
3347 Notify->NotifyType = NotifyType;\r
3348\r
3349 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);\r
3350 *NotifyHandle = Notify->NotifyHandle;\r
3351\r
3352 return EFI_SUCCESS;\r
3353}\r
3354\r
3355\r
3356/**\r
3357 Removes the specified HII database package-related notification.\r
3358\r
3359 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3360 instance.\r
e90b081a 3361 @param NotificationHandle The handle of the notification function being\r
93e3992d 3362 unregistered.\r
3363\r
3364 @retval EFI_SUCCESS Notification is unregistered successfully.\r
3365 @retval EFI_INVALID_PARAMETER The Handle is invalid.\r
3366 @retval EFI_NOT_FOUND The incoming notification handle does not exist\r
3367 in current hii database.\r
3368\r
3369**/\r
3370EFI_STATUS\r
3371EFIAPI\r
3372HiiUnregisterPackageNotify (\r
3373 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3374 IN EFI_HANDLE NotificationHandle\r
3375 )\r
3376{\r
3377 HII_DATABASE_PRIVATE_DATA *Private;\r
3378 HII_DATABASE_NOTIFY *Notify;\r
3379 LIST_ENTRY *Link;\r
3380 EFI_STATUS Status;\r
3381\r
813acf3a 3382 if (This == NULL) {\r
93e3992d 3383 return EFI_INVALID_PARAMETER;\r
3384 }\r
3385\r
813acf3a 3386 if (NotificationHandle == NULL) {\r
3387 return EFI_NOT_FOUND;\r
3388 }\r
3389\r
93e3992d 3390 Status = gBS->OpenProtocol (\r
3391 NotificationHandle,\r
3392 &mHiiDatabaseNotifyGuid,\r
3393 NULL,\r
3394 NULL,\r
3395 NULL,\r
3396 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
3397 );\r
3398 if (EFI_ERROR (Status)) {\r
813acf3a 3399 return EFI_NOT_FOUND;\r
93e3992d 3400 }\r
3401\r
3402 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3403\r
3404 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {\r
3405 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);\r
3406 if (Notify->NotifyHandle == NotificationHandle) {\r
3407 //\r
3408 // Remove the matching notification node\r
3409 //\r
3410 RemoveEntryList (&Notify->DatabaseNotifyEntry);\r
3411 Status = gBS->UninstallMultipleProtocolInterfaces (\r
3412 Notify->NotifyHandle,\r
3413 &mHiiDatabaseNotifyGuid,\r
3414 NULL,\r
3415 NULL\r
3416 );\r
3417 ASSERT_EFI_ERROR (Status);\r
676df92c 3418 FreePool (Notify);\r
93e3992d 3419\r
3420 return EFI_SUCCESS;\r
3421 }\r
3422 }\r
3423\r
3424 return EFI_NOT_FOUND;\r
3425}\r
3426\r
3427\r
3428/**\r
3429 This routine retrieves an array of GUID values for each keyboard layout that\r
3430 was previously registered in the system.\r
3431\r
3432 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3433 instance.\r
3434 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard\r
3435 GUID buffer. On output, the length of the handle\r
3436 buffer that is required for the handles found.\r
3437 @param KeyGuidBuffer An array of keyboard layout GUID instances\r
3438 returned.\r
3439\r
3440 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.\r
3441 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates\r
3442 that KeyGuidBuffer is too small to support the\r
3443 number of GUIDs. KeyGuidBufferLength is\r
3444 updated with a value that will enable the data to\r
3445 fit.\r
3446 @retval EFI_INVALID_PARAMETER The KeyGuidBuffer or KeyGuidBufferLength was NULL.\r
3447 @retval EFI_NOT_FOUND There was no keyboard layout.\r
3448\r
3449**/\r
3450EFI_STATUS\r
3451EFIAPI\r
3452HiiFindKeyboardLayouts (\r
3453 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3454 IN OUT UINT16 *KeyGuidBufferLength,\r
3455 OUT EFI_GUID *KeyGuidBuffer\r
3456 )\r
3457{\r
3458 HII_DATABASE_PRIVATE_DATA *Private;\r
3459 HII_DATABASE_RECORD *Node;\r
3460 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3461 LIST_ENTRY *Link;\r
3462 LIST_ENTRY *Link1;\r
3463 UINT16 ResultSize;\r
3464 UINTN Index;\r
3465 UINT16 LayoutCount;\r
3466 UINT16 LayoutLength;\r
3467 UINT8 *Layout;\r
3468 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3469\r
3470 if (This == NULL || KeyGuidBufferLength == NULL) {\r
3471 return EFI_INVALID_PARAMETER;\r
3472 }\r
3473\r
3474 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {\r
3475 return EFI_INVALID_PARAMETER;\r
3476 }\r
3477\r
3478 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3479 ResultSize = 0;\r
3480\r
3481 //\r
3482 // Search all package lists in whole database to retrieve keyboard layout.\r
3483 //\r
3484 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3485 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3486 PackageList = Node->PackageList;\r
3487 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3488 Link1 != &PackageList->KeyboardLayoutHdr;\r
3489 Link1 = Link1->ForwardLink\r
3490 ) {\r
3491 //\r
3492 // Find out all Keyboard Layout packages in this package list.\r
3493 //\r
3494 Package = CR (\r
3495 Link1,\r
3496 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3497 KeyboardEntry,\r
3498 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3499 );\r
3500 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3501 CopyMem (\r
3502 &LayoutCount,\r
3503 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
3504 sizeof (UINT16)\r
3505 );\r
3506 for (Index = 0; Index < LayoutCount; Index++) {\r
3507 ResultSize += sizeof (EFI_GUID);\r
3508 if (ResultSize <= *KeyGuidBufferLength) {\r
813acf3a 3509 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));\r
93e3992d 3510 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3511 Layout = Layout + LayoutLength;\r
3512 }\r
3513 }\r
3514 }\r
3515 }\r
3516\r
3517 if (ResultSize == 0) {\r
3518 return EFI_NOT_FOUND;\r
3519 }\r
3520\r
3521 if (*KeyGuidBufferLength < ResultSize) {\r
3522 *KeyGuidBufferLength = ResultSize;\r
3523 return EFI_BUFFER_TOO_SMALL;\r
3524 }\r
3525\r
3526 *KeyGuidBufferLength = ResultSize;\r
3527 return EFI_SUCCESS;\r
3528}\r
3529\r
3530\r
3531/**\r
3532 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys\r
3533 on a keyboard and the character(s) that are associated with a particular set of key strokes.\r
3534\r
3535 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3536 instance.\r
3537 @param KeyGuid A pointer to the unique ID associated with a given\r
3538 keyboard layout. If KeyGuid is NULL then the\r
3539 current layout will be retrieved.\r
3540 @param KeyboardLayoutLength On input, a pointer to the length of the\r
3541 KeyboardLayout buffer. On output, the length of\r
3542 the data placed into KeyboardLayout.\r
3543 @param KeyboardLayout A pointer to a buffer containing the retrieved\r
3544 keyboard layout.\r
3545\r
3546 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.\r
3547 @retval EFI_NOT_FOUND The requested keyboard layout was not found.\r
3548 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was\r
3549 NULL.\r
3550 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates\r
3551 that KeyboardLayout is too small to support the\r
3552 requested keyboard layout. KeyboardLayoutLength is\r
3553 updated with a value that will enable the\r
3554 data to fit.\r
3555\r
3556**/\r
3557EFI_STATUS\r
3558EFIAPI\r
3559HiiGetKeyboardLayout (\r
3560 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3561 IN CONST EFI_GUID *KeyGuid,\r
3562 IN OUT UINT16 *KeyboardLayoutLength,\r
3563 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout\r
3564 )\r
3565{\r
3566 HII_DATABASE_PRIVATE_DATA *Private;\r
3567 HII_DATABASE_RECORD *Node;\r
3568 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3569 LIST_ENTRY *Link;\r
3570 LIST_ENTRY *Link1;\r
3571 UINTN Index;\r
3572 UINT8 *Layout;\r
3573 UINT16 LayoutCount;\r
3574 UINT16 LayoutLength;\r
3575 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3576\r
3577 if (This == NULL || KeyboardLayoutLength == NULL) {\r
3578 return EFI_INVALID_PARAMETER;\r
3579 }\r
3580 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {\r
3581 return EFI_INVALID_PARAMETER;\r
3582 }\r
3583\r
3584 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3585 //\r
3586 // Retrieve the current keyboard layout.\r
3587 //\r
3588 if (KeyGuid == NULL) {\r
3589 if (Private->CurrentLayout == NULL) {\r
3590 return EFI_NOT_FOUND;\r
3591 }\r
3592 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));\r
3593 if (*KeyboardLayoutLength < LayoutLength) {\r
3594 *KeyboardLayoutLength = LayoutLength;\r
3595 return EFI_BUFFER_TOO_SMALL;\r
3596 }\r
3597 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);\r
3598 return EFI_SUCCESS;\r
3599 }\r
3600\r
3601 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3602 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3603 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3604 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3605 Link1 != &PackageList->KeyboardLayoutHdr;\r
3606 Link1 = Link1->ForwardLink\r
3607 ) {\r
3608 Package = CR (\r
3609 Link1,\r
3610 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3611 KeyboardEntry,\r
3612 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3613 );\r
3614\r
3615 Layout = (UINT8 *) Package->KeyboardPkg +\r
3616 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3617 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));\r
3618 for (Index = 0; Index < LayoutCount; Index++) {\r
3619 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3620 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {\r
3621 if (LayoutLength <= *KeyboardLayoutLength) {\r
3622 CopyMem (KeyboardLayout, Layout, LayoutLength);\r
3623 return EFI_SUCCESS;\r
3624 } else {\r
3625 *KeyboardLayoutLength = LayoutLength;\r
3626 return EFI_BUFFER_TOO_SMALL;\r
3627 }\r
3628 }\r
3629 Layout = Layout + LayoutLength;\r
3630 }\r
3631 }\r
3632 }\r
3633\r
3634 return EFI_NOT_FOUND;\r
3635}\r
3636\r
3637\r
3638/**\r
3639 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine\r
3640 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID\r
3641 group type. This is so that agents which are sensitive to the current keyboard layout being changed\r
3642 can be notified of this change.\r
3643\r
3644 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3645 instance.\r
3646 @param KeyGuid A pointer to the unique ID associated with a given\r
3647 keyboard layout.\r
3648\r
3649 @retval EFI_SUCCESS The current keyboard layout was successfully set.\r
3650 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so\r
3651 action was taken.\r
3652 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.\r
3653\r
3654**/\r
3655EFI_STATUS\r
3656EFIAPI\r
3657HiiSetKeyboardLayout (\r
3658 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3659 IN CONST EFI_GUID *KeyGuid\r
3660 )\r
3661{\r
3662 HII_DATABASE_PRIVATE_DATA *Private;\r
3663 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;\r
3664 UINT16 KeyboardLayoutLength;\r
3665 EFI_STATUS Status;\r
3666\r
3667 if (This == NULL || KeyGuid == NULL) {\r
3668 return EFI_INVALID_PARAMETER;\r
3669 }\r
3670\r
3671 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3672\r
3673 //\r
3674 // The specified GUID equals the current keyboard layout GUID,\r
3675 // return directly.\r
3676 //\r
3677 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {\r
3678 return EFI_SUCCESS;\r
3679 }\r
3680\r
3681 //\r
3682 // Try to find the incoming keyboard layout data in current database.\r
3683 //\r
3684 KeyboardLayoutLength = 0;\r
3685 KeyboardLayout = NULL;\r
3686 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3687 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3688 return Status;\r
3689 }\r
3690\r
3691 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);\r
3692 ASSERT (KeyboardLayout != NULL);\r
3693 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3694 ASSERT_EFI_ERROR (Status);\r
3695\r
3696 //\r
3697 // Backup current keyboard layout.\r
3698 //\r
3699 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));\r
676df92c 3700 if (Private->CurrentLayout != NULL) {\r
3701 FreePool(Private->CurrentLayout);\r
3702 }\r
93e3992d 3703 Private->CurrentLayout = KeyboardLayout;\r
3704\r
3705 //\r
3706 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify\r
3707 // current keyboard layout is changed.\r
3708 //\r
3709 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);\r
3710 ASSERT_EFI_ERROR (Status);\r
3711\r
3712 return EFI_SUCCESS;\r
3713}\r
3714\r
3715\r
3716/**\r
3717 Return the EFI handle associated with a package list.\r
3718\r
3719 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3720 instance.\r
3721 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired\r
3722 package list in the HIIdatabase.\r
3723 @param DriverHandle On return, contains the EFI_HANDLE which was\r
3724 registered with the package list in\r
3725 NewPackageList().\r
3726\r
3727 @retval EFI_SUCCESS The DriverHandle was returned successfully.\r
3728 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or\r
3729 DriverHandle was NULL.\r
3730 @retval EFI_NOT_FOUND This PackageList handle can not be found in\r
3731 current database.\r
3732\r
3733**/\r
3734EFI_STATUS\r
3735EFIAPI\r
3736HiiGetPackageListHandle (\r
3737 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3738 IN EFI_HII_HANDLE PackageListHandle,\r
3739 OUT EFI_HANDLE *DriverHandle\r
3740 )\r
3741{\r
3742 HII_DATABASE_PRIVATE_DATA *Private;\r
3743 HII_DATABASE_RECORD *Node;\r
3744 LIST_ENTRY *Link;\r
3745\r
3746 if (This == NULL || DriverHandle == NULL) {\r
3747 return EFI_INVALID_PARAMETER;\r
3748 }\r
3749\r
3750 if (!IsHiiHandleValid (PackageListHandle)) {\r
3751 return EFI_INVALID_PARAMETER;\r
3752 }\r
3753\r
3754 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3755\r
3756 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3757 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3758 if (Node->Handle == PackageListHandle) {\r
3759 *DriverHandle = Node->DriverHandle;\r
3760 return EFI_SUCCESS;\r
3761 }\r
3762 }\r
3763\r
3764 return EFI_NOT_FOUND;\r
3765}\r
3766\r