]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
DUET BDS clean up.
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
CommitLineData
93e3992d 1/** @file\r
e90b081a 2Implementation for EFI_HII_DATABASE_PROTOCOL.\r
3\r
b1a803d1 4Copyright (c) 2007 - 2010, 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
d6a82eaf 860 Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId);\r
93e3992d 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
b1a803d1 2702 If a NULL is specified, this data will not be associate\r
2703 with any drivers and cannot have a callback induced.\r
93e3992d 2704 @param Handle A pointer to the EFI_HII_HANDLE instance.\r
2705\r
2706 @retval EFI_SUCCESS The package list associated with the Handle was\r
2707 added to the HII database.\r
2708 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2709 database contents.\r
2710 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.\r
2711 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.\r
2712\r
2713**/\r
2714EFI_STATUS\r
2715EFIAPI\r
2716HiiNewPackageList (\r
2717 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2718 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
b1a803d1 2719 IN CONST EFI_HANDLE DriverHandle, OPTIONAL\r
93e3992d 2720 OUT EFI_HII_HANDLE *Handle\r
2721 )\r
2722{\r
2723 EFI_STATUS Status;\r
2724 HII_DATABASE_PRIVATE_DATA *Private;\r
2725 HII_DATABASE_RECORD *DatabaseRecord;\r
2726 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2727 LIST_ENTRY *Link;\r
2728 EFI_GUID PackageListGuid;\r
2729\r
2730 if (This == NULL || PackageList == NULL || Handle == NULL) {\r
2731 return EFI_INVALID_PARAMETER;\r
2732 }\r
2733\r
2734 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2735 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));\r
2736\r
2737 //\r
2738 // Check the Package list GUID to guarantee this GUID is unique in database.\r
2739 //\r
2740 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2741 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2742 if (CompareGuid (\r
2743 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
aa2614b7 2744 &PackageListGuid) && \r
2745 DatabaseRecord->DriverHandle == DriverHandle) {\r
93e3992d 2746 return EFI_INVALID_PARAMETER;\r
2747 }\r
2748 }\r
2749\r
2750 //\r
2751 // Build a PackageList node\r
2752 //\r
2753 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
2754 if (EFI_ERROR (Status)) {\r
2755 return Status;\r
2756 }\r
2757\r
2758 //\r
2759 // Fill in information of the created Package List node\r
2760 // according to incoming package list.\r
2761 //\r
2762 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
2763 if (EFI_ERROR (Status)) {\r
2764 return Status;\r
2765 }\r
2766\r
2767 DatabaseRecord->DriverHandle = DriverHandle;\r
2768\r
2769 //\r
2770 // Create a Device path package and add into the package list if exists.\r
2771 //\r
2772 Status = gBS->HandleProtocol (\r
2773 DriverHandle,\r
2774 &gEfiDevicePathProtocolGuid,\r
2775 (VOID **) &DevicePath\r
2776 );\r
2777 if (!EFI_ERROR (Status)) {\r
2778 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);\r
2779 ASSERT_EFI_ERROR (Status);\r
2780 }\r
2781\r
2782 *Handle = DatabaseRecord->Handle;\r
2783 return EFI_SUCCESS;\r
2784}\r
2785\r
2786\r
2787/**\r
2788 This function removes the package list that is associated with a handle Handle\r
2789 from the HII database. Before removing the package, any registered functions\r
2790 with the notification type REMOVE_PACK and the same package type will be called.\r
2791\r
2792 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2793 instance.\r
2794 @param Handle The handle that was registered to the data that is\r
2795 requested for removal.\r
2796\r
2797 @retval EFI_SUCCESS The data associated with the Handle was removed\r
2798 from the HII database.\r
813acf3a 2799 @retval EFI_NOT_FOUND The specified andle is not in database.\r
93e3992d 2800 @retval EFI_INVALID_PARAMETER The Handle was not valid.\r
2801\r
2802**/\r
2803EFI_STATUS\r
2804EFIAPI\r
2805HiiRemovePackageList (\r
2806 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2807 IN EFI_HII_HANDLE Handle\r
2808 )\r
2809{\r
2810 EFI_STATUS Status;\r
2811 HII_DATABASE_PRIVATE_DATA *Private;\r
2812 LIST_ENTRY *Link;\r
2813 HII_DATABASE_RECORD *Node;\r
2814 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
2815 HII_HANDLE *HiiHandle;\r
2816\r
813acf3a 2817 if (This == NULL) {\r
93e3992d 2818 return EFI_INVALID_PARAMETER;\r
2819 }\r
2820\r
813acf3a 2821 if (!IsHiiHandleValid (Handle)) {\r
2822 return EFI_NOT_FOUND;\r
2823 }\r
2824\r
93e3992d 2825 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2826\r
2827 //\r
2828 // Get the packagelist to be removed.\r
2829 //\r
2830 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2831 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2832 if (Node->Handle == Handle) {\r
2833 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
2834 ASSERT (PackageList != NULL);\r
2835\r
2836 //\r
2837 // Call registered functions with REMOVE_PACK before removing packages\r
2838 // then remove them.\r
2839 //\r
2840 Status = RemoveGuidPackages (Private, Handle, PackageList);\r
2841 if (EFI_ERROR (Status)) {\r
2842 return Status;\r
2843 }\r
2844 Status = RemoveFormPackages (Private, Handle, PackageList);\r
2845 if (EFI_ERROR (Status)) {\r
2846 return Status;\r
2847 }\r
2848 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
2849 if (EFI_ERROR (Status)) {\r
2850 return Status;\r
2851 }\r
2852 Status = RemoveStringPackages (Private, Handle, PackageList);\r
2853 if (EFI_ERROR (Status)) {\r
2854 return Status;\r
2855 }\r
2856 Status = RemoveFontPackages (Private, Handle, PackageList);\r
2857 if (EFI_ERROR (Status)) {\r
2858 return Status;\r
2859 }\r
2860 Status = RemoveImagePackages (Private, Handle, PackageList);\r
2861 if (EFI_ERROR (Status)) {\r
2862 return Status;\r
2863 }\r
2864 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
2865 if (EFI_ERROR (Status)) {\r
2866 return Status;\r
2867 }\r
2868 Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
2869 if (EFI_ERROR (Status)) {\r
2870 return Status;\r
2871 }\r
2872\r
2873 //\r
2874 // Free resources of the package list\r
2875 //\r
2876 RemoveEntryList (&Node->DatabaseEntry);\r
2877\r
2878 HiiHandle = (HII_HANDLE *) Handle;\r
2879 RemoveEntryList (&HiiHandle->Handle);\r
2880 Private->HiiHandleCount--;\r
2881 ASSERT (Private->HiiHandleCount >= 0);\r
2882\r
2883 HiiHandle->Signature = 0;\r
676df92c 2884 FreePool (HiiHandle);\r
2885 FreePool (Node->PackageList);\r
2886 FreePool (Node);\r
93e3992d 2887\r
2888 return EFI_SUCCESS;\r
2889 }\r
2890 }\r
2891\r
2892 return EFI_NOT_FOUND;\r
2893}\r
2894\r
2895\r
2896/**\r
2897 This function updates the existing package list (which has the specified Handle)\r
2898 in the HII databases, using the new package list specified by PackageList.\r
2899\r
2900 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2901 instance.\r
2902 @param Handle The handle that was registered to the data that is\r
2903 requested to be updated.\r
2904 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
2905 package.\r
2906\r
2907 @retval EFI_SUCCESS The HII database was successfully updated.\r
2908 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated\r
2909 database.\r
813acf3a 2910 @retval EFI_INVALID_PARAMETER PackageList was NULL.\r
2911 @retval EFI_NOT_FOUND The specified Handle is not in database.\r
93e3992d 2912\r
2913**/\r
2914EFI_STATUS\r
2915EFIAPI\r
2916HiiUpdatePackageList (\r
2917 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2918 IN EFI_HII_HANDLE Handle,\r
2919 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList\r
2920 )\r
2921{\r
2922 EFI_STATUS Status;\r
2923 HII_DATABASE_PRIVATE_DATA *Private;\r
2924 LIST_ENTRY *Link;\r
2925 HII_DATABASE_RECORD *Node;\r
2926 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
2927 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;\r
2928 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2929\r
813acf3a 2930 if (This == NULL || PackageList == NULL) {\r
93e3992d 2931 return EFI_INVALID_PARAMETER;\r
2932 }\r
2933\r
2934 if (!IsHiiHandleValid (Handle)) {\r
2935 return EFI_NOT_FOUND;\r
2936 }\r
2937\r
2938 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2939\r
2940 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
2941\r
2942 Status = EFI_SUCCESS;\r
2943\r
2944 //\r
2945 // Get original packagelist to be updated\r
2946 //\r
2947 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2948 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2949 if (Node->Handle == Handle) {\r
2950 OldPackageList = Node->PackageList;\r
2951 //\r
2952 // Remove the package if its type matches one of the package types which is\r
2953 // contained in the new package list.\r
2954 //\r
2955 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2956 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
2957 switch (PackageHeader.Type) {\r
2958 case EFI_HII_PACKAGE_TYPE_GUID:\r
2959 Status = RemoveGuidPackages (Private, Handle, OldPackageList);\r
2960 break;\r
8d00a0f1 2961 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 2962 Status = RemoveFormPackages (Private, Handle, OldPackageList);\r
2963 break;\r
2964 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
2965 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);\r
2966 break;\r
2967 case EFI_HII_PACKAGE_STRINGS:\r
2968 Status = RemoveStringPackages (Private, Handle, OldPackageList);\r
2969 break;\r
2970 case EFI_HII_PACKAGE_FONTS:\r
2971 Status = RemoveFontPackages (Private, Handle, OldPackageList);\r
2972 break;\r
2973 case EFI_HII_PACKAGE_IMAGES:\r
2974 Status = RemoveImagePackages (Private, Handle, OldPackageList);\r
2975 break;\r
2976 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
2977 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);\r
2978 break;\r
2979 case EFI_HII_PACKAGE_DEVICE_PATH:\r
2980 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);\r
2981 break;\r
2982 }\r
2983\r
2984 if (EFI_ERROR (Status)) {\r
2985 return Status;\r
2986 }\r
2987\r
2988 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
2989 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2990 }\r
2991\r
2992 //\r
2993 // Add all of the packages within the new package list\r
2994 //\r
2995 return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
2996 }\r
2997 }\r
2998\r
2999 return EFI_NOT_FOUND;\r
3000}\r
3001\r
3002\r
3003/**\r
3004 This function returns a list of the package handles of the specified type\r
3005 that are currently active in the database. The pseudo-type\r
3006 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.\r
3007\r
3008 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3009 instance.\r
3010 @param PackageType Specifies the package type of the packages to list\r
3011 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3012 listed.\r
3013 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3014 this is the pointer to the GUID which must match\r
3015 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.\r
3016 Otherwise, it must be NULL.\r
3017 @param HandleBufferLength On input, a pointer to the length of the handle\r
3018 buffer. On output, the length of the handle\r
3019 buffer that is required for the handles found.\r
3020 @param Handle An array of EFI_HII_HANDLE instances returned.\r
3021\r
3022 @retval EFI_SUCCESS The matching handles are outputed successfully.\r
813acf3a 3023 HandleBufferLength is updated with the actual length.\r
93e3992d 3024 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3025 Handle is too small to support the number of\r
3026 handles. HandleBufferLength is updated with a\r
3027 value that will enable the data to fit.\r
3028 @retval EFI_NOT_FOUND No matching handle could not be found in database.\r
3029 @retval EFI_INVALID_PARAMETER Handle or HandleBufferLength was NULL.\r
813acf3a 3030 \r
3031 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but\r
3032 PackageGuid is not NULL, PackageType is a EFI_HII_\r
3033 PACKAGE_TYPE_GUID but PackageGuid is NULL.\r
93e3992d 3034\r
3035**/\r
3036EFI_STATUS\r
3037EFIAPI\r
3038HiiListPackageLists (\r
3039 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3040 IN UINT8 PackageType,\r
3041 IN CONST EFI_GUID *PackageGuid,\r
3042 IN OUT UINTN *HandleBufferLength,\r
3043 OUT EFI_HII_HANDLE *Handle\r
3044 )\r
3045{\r
3046 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
3047 HII_DATABASE_PRIVATE_DATA *Private;\r
3048 HII_DATABASE_RECORD *Node;\r
3049 LIST_ENTRY *Link;\r
3050 BOOLEAN Matched;\r
3051 HII_HANDLE **Result;\r
3052 UINTN ResultSize;\r
3053 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3054 LIST_ENTRY *Link1;\r
3055\r
3056 //\r
3057 // Check input parameters\r
3058 //\r
3059 if (This == NULL || HandleBufferLength == NULL) {\r
3060 return EFI_INVALID_PARAMETER;\r
3061 }\r
3062 if (*HandleBufferLength > 0 && Handle == NULL) {\r
3063 return EFI_INVALID_PARAMETER;\r
3064 }\r
3065 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3066 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3067 return EFI_INVALID_PARAMETER;\r
3068 }\r
3069\r
3070 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3071 Matched = FALSE;\r
3072 Result = (HII_HANDLE **) Handle;\r
3073 ResultSize = 0;\r
3074\r
3075 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3076 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3077 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3078 switch (PackageType) {\r
3079 case EFI_HII_PACKAGE_TYPE_GUID:\r
3080 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {\r
3081 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);\r
3082 if (CompareGuid (\r
3083 (EFI_GUID *) PackageGuid,\r
3084 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))\r
3085 )) {\r
3086 Matched = TRUE;\r
3087 break;\r
3088 }\r
3089 }\r
3090 break;\r
8d00a0f1 3091 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3092 if (!IsListEmpty (&PackageList->FormPkgHdr)) {\r
3093 Matched = TRUE;\r
3094 }\r
3095 break;\r
3096 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3097 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {\r
3098 Matched = TRUE;\r
3099 }\r
3100 break;\r
3101 case EFI_HII_PACKAGE_STRINGS:\r
3102 if (!IsListEmpty (&PackageList->StringPkgHdr)) {\r
3103 Matched = TRUE;\r
3104 }\r
3105 break;\r
3106 case EFI_HII_PACKAGE_FONTS:\r
3107 if (!IsListEmpty (&PackageList->FontPkgHdr)) {\r
3108 Matched = TRUE;\r
3109 }\r
3110 break;\r
3111 case EFI_HII_PACKAGE_IMAGES:\r
3112 if (PackageList->ImagePkg != NULL) {\r
3113 Matched = TRUE;\r
3114 }\r
3115 break;\r
3116 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3117 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {\r
3118 Matched = TRUE;\r
3119 }\r
3120 break;\r
3121 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3122 if (PackageList->DevicePathPkg != NULL) {\r
3123 Matched = TRUE;\r
3124 }\r
3125 break;\r
3126 //\r
3127 // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles\r
3128 // to be listed.\r
3129 //\r
3130 case EFI_HII_PACKAGE_TYPE_ALL:\r
3131 Matched = TRUE;\r
3132 break;\r
3133 default:\r
3134 break;\r
3135 }\r
3136\r
3137 //\r
3138 // This active package list has the specified package type, list it.\r
3139 //\r
3140 if (Matched) {\r
3141 ResultSize += sizeof (EFI_HII_HANDLE);\r
3142 if (ResultSize <= *HandleBufferLength) {\r
3143 *Result++ = Node->Handle;\r
3144 }\r
3145 }\r
3146 Matched = FALSE;\r
3147 }\r
3148\r
3149 if (ResultSize == 0) {\r
3150 return EFI_NOT_FOUND;\r
3151 }\r
3152\r
3153 if (*HandleBufferLength < ResultSize) {\r
3154 *HandleBufferLength = ResultSize;\r
3155 return EFI_BUFFER_TOO_SMALL;\r
3156 }\r
3157\r
3158 *HandleBufferLength = ResultSize;\r
3159 return EFI_SUCCESS;\r
3160}\r
3161\r
3162\r
3163/**\r
3164 This function will export one or all package lists in the database to a buffer.\r
3165 For each package list exported, this function will call functions registered\r
3166 with EXPORT_PACK and then copy the package list to the buffer.\r
3167\r
3168 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3169 instance.\r
3170 @param Handle An EFI_HII_HANDLE that corresponds to the desired\r
3171 package list in the HII database to export or NULL\r
3172 to indicate all package lists should be exported.\r
3173 @param BufferSize On input, a pointer to the length of the buffer.\r
3174 On output, the length of the buffer that is\r
3175 required for the exported data.\r
3176 @param Buffer A pointer to a buffer that will contain the\r
3177 results of the export function.\r
3178\r
3179 @retval EFI_SUCCESS Package exported.\r
3180 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3181 Handle is too small to support the number of\r
3182 handles. HandleBufferLength is updated with a\r
3183 value that will enable the data to fit.\r
3184 @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the\r
3185 current database.\r
3186 @retval EFI_INVALID_PARAMETER Handle or Buffer or BufferSize was NULL.\r
3187\r
3188**/\r
3189EFI_STATUS\r
3190EFIAPI\r
3191HiiExportPackageLists (\r
3192 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3193 IN EFI_HII_HANDLE Handle,\r
3194 IN OUT UINTN *BufferSize,\r
3195 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
3196 )\r
3197{\r
3198 LIST_ENTRY *Link;\r
3199 EFI_STATUS Status;\r
3200 HII_DATABASE_PRIVATE_DATA *Private;\r
3201 HII_DATABASE_RECORD *Node;\r
3202 UINTN UsedSize;\r
3203\r
3204 if (This == NULL || BufferSize == NULL || Handle == NULL) {\r
3205 return EFI_INVALID_PARAMETER;\r
3206 }\r
3207 if (*BufferSize > 0 && Buffer == NULL) {\r
3208 return EFI_INVALID_PARAMETER;\r
3209 }\r
3210 if (!IsHiiHandleValid (Handle)) {\r
3211 return EFI_NOT_FOUND;\r
3212 }\r
3213\r
3214 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3215 UsedSize = 0;\r
3216\r
3217 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3218 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3219 if (Handle == NULL) {\r
3220 //\r
3221 // Export all package lists in current hii database.\r
3222 //\r
3223 Status = ExportPackageList (\r
3224 Private,\r
3225 Node->Handle,\r
3226 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3227 &UsedSize,\r
3228 *BufferSize,\r
3229 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)\r
3230 );\r
3231 ASSERT_EFI_ERROR (Status);\r
6672d625 3232 } else if (Handle != NULL && Node->Handle == Handle) {\r
93e3992d 3233 Status = ExportPackageList (\r
3234 Private,\r
3235 Handle,\r
3236 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3237 &UsedSize,\r
3238 *BufferSize,\r
3239 Buffer\r
3240 );\r
3241 ASSERT_EFI_ERROR (Status);\r
3242 if (*BufferSize < UsedSize) {\r
3243 *BufferSize = UsedSize;\r
3244 return EFI_BUFFER_TOO_SMALL;\r
3245 }\r
3246 return EFI_SUCCESS;\r
3247 }\r
3248 }\r
3249\r
3250 if (Handle == NULL && UsedSize != 0) {\r
3251 if (*BufferSize < UsedSize) {\r
3252 *BufferSize = UsedSize;\r
3253 return EFI_BUFFER_TOO_SMALL;\r
3254 }\r
3255 return EFI_SUCCESS;\r
3256 }\r
3257\r
3258 return EFI_NOT_FOUND;\r
3259}\r
3260\r
3261\r
3262/**\r
3263 This function registers a function which will be called when specified actions related to packages of\r
3264 the specified type occur in the HII database. By registering a function, other HII-related drivers are\r
3265 notified when specific package types are added, removed or updated in the HII database.\r
3266 Each driver or application which registers a notification should use\r
3267 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.\r
3268\r
3269 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3270 instance.\r
3271 @param PackageType Specifies the package type of the packages to list\r
3272 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3273 listed.\r
3274 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3275 this is the pointer to the GUID which must match\r
3276 the Guid field of\r
3277 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must\r
3278 be NULL.\r
3279 @param PackageNotifyFn Points to the function to be called when the event\r
3280 specified by\r
3281 NotificationType occurs.\r
3282 @param NotifyType Describes the types of notification which this\r
3283 function will be receiving.\r
3284 @param NotifyHandle Points to the unique handle assigned to the\r
3285 registered notification. Can be used in\r
3286 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()\r
3287 to stop notifications.\r
3288\r
3289 @retval EFI_SUCCESS Notification registered successfully.\r
3290 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures\r
3291 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.\r
3292 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not\r
3293 EFI_HII_PACKAGE_TYPE_GUID.\r
3294 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is\r
3295 EFI_HII_PACKAGE_TYPE_GUID.\r
3296\r
3297**/\r
3298EFI_STATUS\r
3299EFIAPI\r
3300HiiRegisterPackageNotify (\r
3301 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3302 IN UINT8 PackageType,\r
3303 IN CONST EFI_GUID *PackageGuid,\r
3304 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,\r
3305 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
3306 OUT EFI_HANDLE *NotifyHandle\r
3307 )\r
3308{\r
3309 HII_DATABASE_PRIVATE_DATA *Private;\r
3310 HII_DATABASE_NOTIFY *Notify;\r
3311 EFI_STATUS Status;\r
3312\r
3313 if (This == NULL || NotifyHandle == NULL) {\r
3314 return EFI_INVALID_PARAMETER;\r
3315 }\r
3316 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3317 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3318 return EFI_INVALID_PARAMETER;\r
3319 }\r
3320\r
3321 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3322\r
3323 //\r
3324 // Allocate a notification node\r
3325 //\r
3326 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));\r
3327 if (Notify == NULL) {\r
3328 return EFI_OUT_OF_RESOURCES;\r
3329 }\r
3330\r
3331 //\r
3332 // Generate a notify handle\r
3333 //\r
3334 Status = gBS->InstallMultipleProtocolInterfaces (\r
3335 &Notify->NotifyHandle,\r
3336 &mHiiDatabaseNotifyGuid,\r
3337 NULL,\r
3338 NULL\r
3339 );\r
3340 ASSERT_EFI_ERROR (Status);\r
3341\r
3342 //\r
3343 // Fill in the information to the notification node\r
3344 //\r
3345 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;\r
3346 Notify->PackageType = PackageType;\r
3347 Notify->PackageGuid = (EFI_GUID *) PackageGuid;\r
3348 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;\r
3349 Notify->NotifyType = NotifyType;\r
3350\r
3351 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);\r
3352 *NotifyHandle = Notify->NotifyHandle;\r
3353\r
3354 return EFI_SUCCESS;\r
3355}\r
3356\r
3357\r
3358/**\r
3359 Removes the specified HII database package-related notification.\r
3360\r
3361 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3362 instance.\r
e90b081a 3363 @param NotificationHandle The handle of the notification function being\r
93e3992d 3364 unregistered.\r
3365\r
3366 @retval EFI_SUCCESS Notification is unregistered successfully.\r
3367 @retval EFI_INVALID_PARAMETER The Handle is invalid.\r
3368 @retval EFI_NOT_FOUND The incoming notification handle does not exist\r
3369 in current hii database.\r
3370\r
3371**/\r
3372EFI_STATUS\r
3373EFIAPI\r
3374HiiUnregisterPackageNotify (\r
3375 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3376 IN EFI_HANDLE NotificationHandle\r
3377 )\r
3378{\r
3379 HII_DATABASE_PRIVATE_DATA *Private;\r
3380 HII_DATABASE_NOTIFY *Notify;\r
3381 LIST_ENTRY *Link;\r
3382 EFI_STATUS Status;\r
3383\r
813acf3a 3384 if (This == NULL) {\r
93e3992d 3385 return EFI_INVALID_PARAMETER;\r
3386 }\r
3387\r
813acf3a 3388 if (NotificationHandle == NULL) {\r
3389 return EFI_NOT_FOUND;\r
3390 }\r
3391\r
93e3992d 3392 Status = gBS->OpenProtocol (\r
3393 NotificationHandle,\r
3394 &mHiiDatabaseNotifyGuid,\r
3395 NULL,\r
3396 NULL,\r
3397 NULL,\r
3398 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
3399 );\r
3400 if (EFI_ERROR (Status)) {\r
813acf3a 3401 return EFI_NOT_FOUND;\r
93e3992d 3402 }\r
3403\r
3404 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3405\r
3406 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {\r
3407 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);\r
3408 if (Notify->NotifyHandle == NotificationHandle) {\r
3409 //\r
3410 // Remove the matching notification node\r
3411 //\r
3412 RemoveEntryList (&Notify->DatabaseNotifyEntry);\r
3413 Status = gBS->UninstallMultipleProtocolInterfaces (\r
3414 Notify->NotifyHandle,\r
3415 &mHiiDatabaseNotifyGuid,\r
3416 NULL,\r
3417 NULL\r
3418 );\r
3419 ASSERT_EFI_ERROR (Status);\r
676df92c 3420 FreePool (Notify);\r
93e3992d 3421\r
3422 return EFI_SUCCESS;\r
3423 }\r
3424 }\r
3425\r
3426 return EFI_NOT_FOUND;\r
3427}\r
3428\r
3429\r
3430/**\r
3431 This routine retrieves an array of GUID values for each keyboard layout that\r
3432 was previously registered in the system.\r
3433\r
3434 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3435 instance.\r
3436 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard\r
3437 GUID buffer. On output, the length of the handle\r
3438 buffer that is required for the handles found.\r
3439 @param KeyGuidBuffer An array of keyboard layout GUID instances\r
3440 returned.\r
3441\r
3442 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.\r
3443 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates\r
3444 that KeyGuidBuffer is too small to support the\r
3445 number of GUIDs. KeyGuidBufferLength is\r
3446 updated with a value that will enable the data to\r
3447 fit.\r
3448 @retval EFI_INVALID_PARAMETER The KeyGuidBuffer or KeyGuidBufferLength was NULL.\r
3449 @retval EFI_NOT_FOUND There was no keyboard layout.\r
3450\r
3451**/\r
3452EFI_STATUS\r
3453EFIAPI\r
3454HiiFindKeyboardLayouts (\r
3455 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3456 IN OUT UINT16 *KeyGuidBufferLength,\r
3457 OUT EFI_GUID *KeyGuidBuffer\r
3458 )\r
3459{\r
3460 HII_DATABASE_PRIVATE_DATA *Private;\r
3461 HII_DATABASE_RECORD *Node;\r
3462 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3463 LIST_ENTRY *Link;\r
3464 LIST_ENTRY *Link1;\r
3465 UINT16 ResultSize;\r
3466 UINTN Index;\r
3467 UINT16 LayoutCount;\r
3468 UINT16 LayoutLength;\r
3469 UINT8 *Layout;\r
3470 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3471\r
3472 if (This == NULL || KeyGuidBufferLength == NULL) {\r
3473 return EFI_INVALID_PARAMETER;\r
3474 }\r
3475\r
3476 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {\r
3477 return EFI_INVALID_PARAMETER;\r
3478 }\r
3479\r
3480 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3481 ResultSize = 0;\r
3482\r
3483 //\r
3484 // Search all package lists in whole database to retrieve keyboard layout.\r
3485 //\r
3486 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3487 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3488 PackageList = Node->PackageList;\r
3489 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3490 Link1 != &PackageList->KeyboardLayoutHdr;\r
3491 Link1 = Link1->ForwardLink\r
3492 ) {\r
3493 //\r
3494 // Find out all Keyboard Layout packages in this package list.\r
3495 //\r
3496 Package = CR (\r
3497 Link1,\r
3498 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3499 KeyboardEntry,\r
3500 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3501 );\r
3502 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3503 CopyMem (\r
3504 &LayoutCount,\r
3505 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
3506 sizeof (UINT16)\r
3507 );\r
3508 for (Index = 0; Index < LayoutCount; Index++) {\r
3509 ResultSize += sizeof (EFI_GUID);\r
3510 if (ResultSize <= *KeyGuidBufferLength) {\r
813acf3a 3511 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));\r
93e3992d 3512 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3513 Layout = Layout + LayoutLength;\r
3514 }\r
3515 }\r
3516 }\r
3517 }\r
3518\r
3519 if (ResultSize == 0) {\r
3520 return EFI_NOT_FOUND;\r
3521 }\r
3522\r
3523 if (*KeyGuidBufferLength < ResultSize) {\r
3524 *KeyGuidBufferLength = ResultSize;\r
3525 return EFI_BUFFER_TOO_SMALL;\r
3526 }\r
3527\r
3528 *KeyGuidBufferLength = ResultSize;\r
3529 return EFI_SUCCESS;\r
3530}\r
3531\r
3532\r
3533/**\r
3534 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys\r
3535 on a keyboard and the character(s) that are associated with a particular set of key strokes.\r
3536\r
3537 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3538 instance.\r
3539 @param KeyGuid A pointer to the unique ID associated with a given\r
3540 keyboard layout. If KeyGuid is NULL then the\r
3541 current layout will be retrieved.\r
3542 @param KeyboardLayoutLength On input, a pointer to the length of the\r
3543 KeyboardLayout buffer. On output, the length of\r
3544 the data placed into KeyboardLayout.\r
3545 @param KeyboardLayout A pointer to a buffer containing the retrieved\r
3546 keyboard layout.\r
3547\r
3548 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.\r
3549 @retval EFI_NOT_FOUND The requested keyboard layout was not found.\r
3550 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was\r
3551 NULL.\r
3552 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates\r
3553 that KeyboardLayout is too small to support the\r
3554 requested keyboard layout. KeyboardLayoutLength is\r
3555 updated with a value that will enable the\r
3556 data to fit.\r
3557\r
3558**/\r
3559EFI_STATUS\r
3560EFIAPI\r
3561HiiGetKeyboardLayout (\r
3562 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3563 IN CONST EFI_GUID *KeyGuid,\r
3564 IN OUT UINT16 *KeyboardLayoutLength,\r
3565 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout\r
3566 )\r
3567{\r
3568 HII_DATABASE_PRIVATE_DATA *Private;\r
3569 HII_DATABASE_RECORD *Node;\r
3570 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3571 LIST_ENTRY *Link;\r
3572 LIST_ENTRY *Link1;\r
3573 UINTN Index;\r
3574 UINT8 *Layout;\r
3575 UINT16 LayoutCount;\r
3576 UINT16 LayoutLength;\r
3577 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3578\r
3579 if (This == NULL || KeyboardLayoutLength == NULL) {\r
3580 return EFI_INVALID_PARAMETER;\r
3581 }\r
3582 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {\r
3583 return EFI_INVALID_PARAMETER;\r
3584 }\r
3585\r
3586 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3587 //\r
3588 // Retrieve the current keyboard layout.\r
3589 //\r
3590 if (KeyGuid == NULL) {\r
3591 if (Private->CurrentLayout == NULL) {\r
3592 return EFI_NOT_FOUND;\r
3593 }\r
3594 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));\r
3595 if (*KeyboardLayoutLength < LayoutLength) {\r
3596 *KeyboardLayoutLength = LayoutLength;\r
3597 return EFI_BUFFER_TOO_SMALL;\r
3598 }\r
3599 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);\r
3600 return EFI_SUCCESS;\r
3601 }\r
3602\r
3603 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3604 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3605 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3606 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3607 Link1 != &PackageList->KeyboardLayoutHdr;\r
3608 Link1 = Link1->ForwardLink\r
3609 ) {\r
3610 Package = CR (\r
3611 Link1,\r
3612 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3613 KeyboardEntry,\r
3614 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3615 );\r
3616\r
3617 Layout = (UINT8 *) Package->KeyboardPkg +\r
3618 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3619 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));\r
3620 for (Index = 0; Index < LayoutCount; Index++) {\r
3621 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3622 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {\r
3623 if (LayoutLength <= *KeyboardLayoutLength) {\r
3624 CopyMem (KeyboardLayout, Layout, LayoutLength);\r
3625 return EFI_SUCCESS;\r
3626 } else {\r
3627 *KeyboardLayoutLength = LayoutLength;\r
3628 return EFI_BUFFER_TOO_SMALL;\r
3629 }\r
3630 }\r
3631 Layout = Layout + LayoutLength;\r
3632 }\r
3633 }\r
3634 }\r
3635\r
3636 return EFI_NOT_FOUND;\r
3637}\r
3638\r
3639\r
3640/**\r
3641 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine\r
3642 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID\r
3643 group type. This is so that agents which are sensitive to the current keyboard layout being changed\r
3644 can be notified of this change.\r
3645\r
3646 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3647 instance.\r
3648 @param KeyGuid A pointer to the unique ID associated with a given\r
3649 keyboard layout.\r
3650\r
3651 @retval EFI_SUCCESS The current keyboard layout was successfully set.\r
3652 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so\r
3653 action was taken.\r
3654 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.\r
3655\r
3656**/\r
3657EFI_STATUS\r
3658EFIAPI\r
3659HiiSetKeyboardLayout (\r
3660 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3661 IN CONST EFI_GUID *KeyGuid\r
3662 )\r
3663{\r
3664 HII_DATABASE_PRIVATE_DATA *Private;\r
3665 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;\r
3666 UINT16 KeyboardLayoutLength;\r
3667 EFI_STATUS Status;\r
3668\r
3669 if (This == NULL || KeyGuid == NULL) {\r
3670 return EFI_INVALID_PARAMETER;\r
3671 }\r
3672\r
3673 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3674\r
3675 //\r
3676 // The specified GUID equals the current keyboard layout GUID,\r
3677 // return directly.\r
3678 //\r
3679 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {\r
3680 return EFI_SUCCESS;\r
3681 }\r
3682\r
3683 //\r
3684 // Try to find the incoming keyboard layout data in current database.\r
3685 //\r
3686 KeyboardLayoutLength = 0;\r
3687 KeyboardLayout = NULL;\r
3688 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3689 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3690 return Status;\r
3691 }\r
3692\r
3693 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);\r
3694 ASSERT (KeyboardLayout != NULL);\r
3695 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3696 ASSERT_EFI_ERROR (Status);\r
3697\r
3698 //\r
3699 // Backup current keyboard layout.\r
3700 //\r
3701 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));\r
676df92c 3702 if (Private->CurrentLayout != NULL) {\r
3703 FreePool(Private->CurrentLayout);\r
3704 }\r
93e3992d 3705 Private->CurrentLayout = KeyboardLayout;\r
3706\r
3707 //\r
3708 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify\r
3709 // current keyboard layout is changed.\r
3710 //\r
3711 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);\r
3712 ASSERT_EFI_ERROR (Status);\r
3713\r
3714 return EFI_SUCCESS;\r
3715}\r
3716\r
3717\r
3718/**\r
3719 Return the EFI handle associated with a package list.\r
3720\r
3721 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3722 instance.\r
3723 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired\r
3724 package list in the HIIdatabase.\r
3725 @param DriverHandle On return, contains the EFI_HANDLE which was\r
3726 registered with the package list in\r
3727 NewPackageList().\r
3728\r
3729 @retval EFI_SUCCESS The DriverHandle was returned successfully.\r
3730 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or\r
3731 DriverHandle was NULL.\r
3732 @retval EFI_NOT_FOUND This PackageList handle can not be found in\r
3733 current database.\r
3734\r
3735**/\r
3736EFI_STATUS\r
3737EFIAPI\r
3738HiiGetPackageListHandle (\r
3739 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3740 IN EFI_HII_HANDLE PackageListHandle,\r
3741 OUT EFI_HANDLE *DriverHandle\r
3742 )\r
3743{\r
3744 HII_DATABASE_PRIVATE_DATA *Private;\r
3745 HII_DATABASE_RECORD *Node;\r
3746 LIST_ENTRY *Link;\r
3747\r
3748 if (This == NULL || DriverHandle == NULL) {\r
3749 return EFI_INVALID_PARAMETER;\r
3750 }\r
3751\r
3752 if (!IsHiiHandleValid (PackageListHandle)) {\r
3753 return EFI_INVALID_PARAMETER;\r
3754 }\r
3755\r
3756 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3757\r
3758 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3759 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3760 if (Node->Handle == PackageListHandle) {\r
3761 *DriverHandle = Node->DriverHandle;\r
3762 return EFI_SUCCESS;\r
3763 }\r
3764 }\r
3765\r
3766 return EFI_NOT_FOUND;\r
3767}\r
3768\r