]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
Libraries and utilities for instrumenting regions of code and measuring their perform...
[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
93e3992d 778 )\r
779{\r
780 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
781 UINT32 HeaderSize;\r
782 EFI_STATUS Status;\r
783 EFI_HII_PACKAGE_HEADER PackageHeader;\r
784 CHAR8 *Language;\r
785 UINT32 LanguageSize;\r
786 LIST_ENTRY *Link;\r
787\r
788 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {\r
789 return EFI_INVALID_PARAMETER;\r
790 }\r
791 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
792 return EFI_INVALID_PARAMETER;\r
793 }\r
794\r
795 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
796 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));\r
797\r
798 //\r
799 // It is illegal to have two string packages with same language within one packagelist\r
800 // since the stringid will be duplicate if so. Check it to avoid this potential issue.\r
801 //\r
802 LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8);\r
803 Language = (CHAR8 *) AllocateZeroPool (LanguageSize);\r
804 if (Language == NULL) {\r
805 return EFI_OUT_OF_RESOURCES;\r
806 }\r
807 AsciiStrCpy (Language, (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);\r
808 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {\r
809 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
f324bf4d 810 if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {\r
676df92c 811 FreePool (Language);\r
93e3992d 812 return EFI_UNSUPPORTED;\r
813 }\r
814 }\r
676df92c 815 FreePool (Language);\r
93e3992d 816\r
817 //\r
818 // Create a String package node\r
819 //\r
820 StringPackage = (HII_STRING_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));\r
821 if (StringPackage == NULL) {\r
822 Status = EFI_OUT_OF_RESOURCES;\r
823 goto Error;\r
824 }\r
825\r
826 StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);\r
827 if (StringPackage->StringPkgHdr == NULL) {\r
828 Status = EFI_OUT_OF_RESOURCES;\r
829 goto Error;\r
830 }\r
831\r
832 StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);\r
833 if (StringPackage->StringBlock == NULL) {\r
834 Status = EFI_OUT_OF_RESOURCES;\r
835 goto Error;\r
836 }\r
837\r
838 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;\r
839 StringPackage->FontId = 0;\r
840 InitializeListHead (&StringPackage->FontInfoList);\r
841\r
842 //\r
843 // Copy the String package header.\r
844 //\r
845 CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize);\r
846\r
847 //\r
848 // Copy the String blocks\r
849 //\r
850 CopyMem (\r
851 StringPackage->StringBlock,\r
852 (UINT8 *) PackageHdr + HeaderSize,\r
853 PackageHeader.Length - HeaderSize\r
854 );\r
855\r
856 //\r
857 // Collect all font block info\r
858 //\r
d6a82eaf 859 Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId);\r
93e3992d 860 if (EFI_ERROR (Status)) {\r
861 return Status;\r
862 }\r
863\r
864 //\r
865 // Insert to String package array\r
866 //\r
867 InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry);\r
868 *Package = StringPackage;\r
869\r
870 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
871 PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
872 }\r
873\r
874 return EFI_SUCCESS;\r
875\r
876Error:\r
877\r
676df92c 878 if (StringPackage != NULL) {\r
c59634ea 879 if (StringPackage->StringBlock != NULL) {\r
880 FreePool (StringPackage->StringBlock);\r
881 }\r
882 if (StringPackage->StringPkgHdr != NULL) {\r
883 FreePool (StringPackage->StringPkgHdr);\r
884 }\r
676df92c 885 FreePool (StringPackage);\r
886 }\r
93e3992d 887 return Status;\r
888\r
889}\r
890\r
6ddd3af7
LG
891/**\r
892 Adjust all string packages in a single package list to have the same max string ID.\r
893 \r
894 @param PackageList Pointer to a package list which will be adjusted.\r
895\r
896 @retval EFI_SUCCESS Adjust all string packages successfully.\r
897 @retval others Can't adjust string packges.\r
898\r
899**/\r
900EFI_STATUS\r
901AdjustStringPackage (\r
902 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
903)\r
904{\r
905 LIST_ENTRY *Link;\r
906 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
907 UINT32 Skip2BlockSize;\r
908 UINT32 OldBlockSize;\r
909 UINT8 *StringBlock;\r
910 UINT8 *BlockPtr;\r
911 EFI_STRING_ID MaxStringId;\r
912 UINT16 SkipCount;\r
913\r
914 MaxStringId = 0;\r
915 for (Link = PackageList->StringPkgHdr.ForwardLink;\r
916 Link != &PackageList->StringPkgHdr;\r
917 Link = Link->ForwardLink\r
918 ) {\r
919 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
920 if (MaxStringId < StringPackage->MaxStringId) {\r
921 MaxStringId = StringPackage->MaxStringId;\r
922 }\r
923 }\r
924\r
925 for (Link = PackageList->StringPkgHdr.ForwardLink;\r
926 Link != &PackageList->StringPkgHdr;\r
927 Link = Link->ForwardLink\r
928 ) {\r
929 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
930 if (StringPackage->MaxStringId < MaxStringId) {\r
931 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
932 //\r
933 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.\r
934 //\r
935 SkipCount = (UINT16) (MaxStringId - StringPackage->MaxStringId);\r
936 Skip2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
937\r
938 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Skip2BlockSize);\r
939 if (StringBlock == NULL) {\r
940 return EFI_OUT_OF_RESOURCES;\r
941 }\r
942 //\r
943 // Copy original string blocks, except the EFI_HII_SIBT_END.\r
944 //\r
945 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
946 //\r
947 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks\r
948 //\r
949 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
950 *BlockPtr = EFI_HII_SIBT_SKIP2;\r
951 CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16));\r
952 BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
953\r
954 //\r
955 // Append a EFI_HII_SIBT_END block to the end.\r
956 //\r
957 *BlockPtr = EFI_HII_SIBT_END;\r
958 FreePool (StringPackage->StringBlock);\r
959 StringPackage->StringBlock = StringBlock;\r
960 StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize;\r
961 PackageList->PackageListHdr.PackageLength += Skip2BlockSize;\r
962 StringPackage->MaxStringId = MaxStringId;\r
963 }\r
964 }\r
965\r
966 return EFI_SUCCESS;\r
967}\r
93e3992d 968\r
969/**\r
970 This function exports String packages to a buffer.\r
e90b081a 971 This is a internal function.\r
93e3992d 972\r
973 @param Private Hii database private structure.\r
974 @param Handle Identification of a package list.\r
975 @param PackageList Pointer to a package list which will be exported.\r
976 @param UsedSize The length of buffer be used.\r
977 @param BufferSize Length of the Buffer.\r
978 @param Buffer Allocated space for storing exported data.\r
979 @param ResultSize The size of the already exported content of this\r
980 package list.\r
981\r
982 @retval EFI_SUCCESS String Packages are exported successfully.\r
983 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
984\r
985**/\r
93e3992d 986EFI_STATUS\r
987ExportStringPackages (\r
988 IN HII_DATABASE_PRIVATE_DATA *Private,\r
989 IN EFI_HII_HANDLE Handle,\r
990 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
991 IN UINTN UsedSize,\r
992 IN UINTN BufferSize,\r
993 IN OUT VOID *Buffer,\r
994 IN OUT UINTN *ResultSize\r
995 )\r
996{\r
997 LIST_ENTRY *Link;\r
998 UINTN PackageLength;\r
999 EFI_STATUS Status;\r
1000 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1001\r
1002 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1003 return EFI_INVALID_PARAMETER;\r
1004 }\r
1005\r
1006 if (BufferSize > 0 && Buffer == NULL ) {\r
1007 return EFI_INVALID_PARAMETER;\r
1008 }\r
1009\r
1010 PackageLength = 0;\r
1011 Status = EFI_SUCCESS;\r
1012\r
1013 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {\r
1014 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
1015 PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
1016 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1017 //\r
1018 // Invoke registered notification function with EXPORT_PACK notify type\r
1019 //\r
1020 Status = InvokeRegisteredFunction (\r
1021 Private,\r
1022 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1023 (VOID *) StringPackage,\r
1024 EFI_HII_PACKAGE_STRINGS,\r
1025 Handle\r
1026 );\r
1027 ASSERT_EFI_ERROR (Status);\r
1028 //\r
1029 // Copy String package header\r
1030 //\r
1031 CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize);\r
1032 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->HdrSize;\r
1033\r
1034 //\r
1035 // Copy String blocks information\r
1036 //\r
1037 CopyMem (\r
1038 Buffer,\r
1039 StringPackage->StringBlock,\r
1040 StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize\r
1041 );\r
1042 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
1043 }\r
1044 }\r
1045\r
1046 *ResultSize += PackageLength;\r
1047 return EFI_SUCCESS;\r
1048}\r
1049\r
1050\r
1051/**\r
1052 This function deletes all String packages from a package list node.\r
e90b081a 1053 This is a internal function.\r
93e3992d 1054\r
1055 @param Private Hii database private data.\r
1056 @param Handle Handle of the package list which contains the to\r
1057 be removed String packages.\r
1058 @param PackageList Pointer to a package list that contains removing\r
1059 packages.\r
1060\r
1061 @retval EFI_SUCCESS String Package(s) is deleted successfully.\r
1062 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1063\r
1064**/\r
93e3992d 1065EFI_STATUS\r
1066RemoveStringPackages (\r
1067 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1068 IN EFI_HII_HANDLE Handle,\r
1069 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1070 )\r
1071{\r
1072 LIST_ENTRY *ListHead;\r
1073 HII_STRING_PACKAGE_INSTANCE *Package;\r
1074 HII_FONT_INFO *FontInfo;\r
1075 EFI_STATUS Status;\r
1076\r
1077 ListHead = &PackageList->StringPkgHdr;\r
1078\r
1079 while (!IsListEmpty (ListHead)) {\r
1080 Package = CR (\r
1081 ListHead->ForwardLink,\r
1082 HII_STRING_PACKAGE_INSTANCE,\r
1083 StringEntry,\r
1084 HII_STRING_PACKAGE_SIGNATURE\r
1085 );\r
1086 Status = InvokeRegisteredFunction (\r
1087 Private,\r
1088 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1089 (VOID *) Package,\r
1090 EFI_HII_PACKAGE_STRINGS,\r
1091 Handle\r
1092 );\r
1093 if (EFI_ERROR (Status)) {\r
1094 return Status;\r
1095 }\r
1096\r
1097 RemoveEntryList (&Package->StringEntry);\r
1098 PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;\r
676df92c 1099 FreePool (Package->StringBlock);\r
1100 FreePool (Package->StringPkgHdr);\r
93e3992d 1101 //\r
1102 // Delete font information\r
1103 //\r
1104 while (!IsListEmpty (&Package->FontInfoList)) {\r
1105 FontInfo = CR (\r
1106 Package->FontInfoList.ForwardLink,\r
1107 HII_FONT_INFO,\r
1108 Entry,\r
1109 HII_FONT_INFO_SIGNATURE\r
1110 );\r
1111 RemoveEntryList (&FontInfo->Entry);\r
676df92c 1112 FreePool (FontInfo);\r
93e3992d 1113 }\r
1114\r
676df92c 1115 FreePool (Package);\r
93e3992d 1116 }\r
1117\r
1118 return EFI_SUCCESS;\r
1119}\r
1120\r
1121\r
1122/**\r
1123 This function insert a Font package to a package list node.\r
e90b081a 1124 This is a internal function.\r
93e3992d 1125\r
1126 @param Private Hii database private structure.\r
1127 @param PackageHdr Pointer to a buffer stored with Font package\r
1128 information.\r
1129 @param NotifyType The type of change concerning the database.\r
1130 @param PackageList Pointer to a package list which will be inserted\r
1131 to.\r
1132 @param Package Created Font package\r
1133\r
1134 @retval EFI_SUCCESS Font Package is inserted successfully.\r
1135 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1136 Font package.\r
1137 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1138 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already\r
1139 exists in current hii database.\r
1140\r
1141**/\r
93e3992d 1142EFI_STATUS\r
1143InsertFontPackage (\r
1144 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1145 IN VOID *PackageHdr,\r
1146 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1147 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1148 OUT HII_FONT_PACKAGE_INSTANCE **Package\r
1149 )\r
1150{\r
1151 HII_FONT_PACKAGE_INSTANCE *FontPackage;\r
1152 EFI_HII_FONT_PACKAGE_HDR *FontPkgHdr;\r
1153 UINT32 HeaderSize;\r
1154 EFI_STATUS Status;\r
1155 EFI_HII_PACKAGE_HEADER PackageHeader;\r
1156 EFI_FONT_INFO *FontInfo;\r
1157 UINT32 FontInfoSize;\r
1158 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1159\r
1160 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {\r
1161 return EFI_INVALID_PARAMETER;\r
1162 }\r
1163\r
1164 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
1165 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));\r
1166\r
1167 FontInfo = NULL;\r
1168 FontPackage = NULL;\r
1169 GlobalFont = NULL;\r
1170\r
1171 //\r
1172 // It is illegal to have two font packages with same EFI_FONT_INFO within hii\r
1173 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's\r
1174 // attributes and identify a font uniquely.\r
1175 //\r
1176 FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);\r
1177 if (FontPkgHdr == NULL) {\r
1178 Status = EFI_OUT_OF_RESOURCES;\r
1179 goto Error;\r
1180 }\r
1181 CopyMem (FontPkgHdr, PackageHdr, HeaderSize);\r
1182\r
1183 FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR);\r
1184 FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);\r
1185 if (FontInfo == NULL) {\r
1186 Status = EFI_OUT_OF_RESOURCES;\r
1187 goto Error;\r
1188 }\r
1189 FontInfo->FontStyle = FontPkgHdr->FontStyle;\r
1190 FontInfo->FontSize = FontPkgHdr->Cell.Height;\r
1191 StrCpy (FontInfo->FontName, FontPkgHdr->FontFamily);\r
1192\r
1193 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {\r
1194 Status = EFI_UNSUPPORTED;\r
1195 goto Error;\r
1196 }\r
1197\r
1198 //\r
1199 // Create a Font package node\r
1200 //\r
1201 FontPackage = (HII_FONT_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE));\r
1202 if (FontPackage == NULL) {\r
1203 Status = EFI_OUT_OF_RESOURCES;\r
1204 goto Error;\r
1205 }\r
1206 FontPackage->Signature = HII_FONT_PACKAGE_SIGNATURE;\r
1207 FontPackage->FontPkgHdr = FontPkgHdr;\r
1208 InitializeListHead (&FontPackage->GlyphInfoList);\r
1209\r
1210 FontPackage->GlyphBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);\r
1211 if (FontPackage->GlyphBlock == NULL) {\r
1212 Status = EFI_OUT_OF_RESOURCES;\r
1213 goto Error;\r
1214 }\r
1215 CopyMem (FontPackage->GlyphBlock, (UINT8 *) PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize);\r
1216\r
1217 //\r
1218 // Collect all default character cell information and backup in GlyphInfoList.\r
1219 //\r
1220 Status = FindGlyphBlock (FontPackage, (CHAR16) (-1), NULL, NULL, NULL);\r
1221 if (EFI_ERROR (Status)) {\r
1222 goto Error;\r
1223 }\r
1224\r
1225 //\r
1226 // This font package describes an unique EFI_FONT_INFO. Backup it in global\r
1227 // font info list.\r
1228 //\r
1229 GlobalFont = (HII_GLOBAL_FONT_INFO *) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO));\r
1230 if (GlobalFont == NULL) {\r
1231 Status = EFI_OUT_OF_RESOURCES;\r
1232 goto Error;\r
1233 }\r
1234 GlobalFont->Signature = HII_GLOBAL_FONT_INFO_SIGNATURE;\r
1235 GlobalFont->FontPackage = FontPackage;\r
1236 GlobalFont->FontInfoSize = FontInfoSize;\r
1237 GlobalFont->FontInfo = FontInfo;\r
1238 InsertTailList (&Private->FontInfoList, &GlobalFont->Entry);\r
1239\r
1240 //\r
1241 // Insert this font package to Font package array\r
1242 //\r
1243 InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry);\r
1244 *Package = FontPackage;\r
1245\r
1246 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1247 PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length;\r
1248 }\r
1249\r
1250 return EFI_SUCCESS;\r
1251\r
1252Error:\r
1253\r
676df92c 1254 if (FontPkgHdr != NULL) {\r
1255 FreePool (FontPkgHdr);\r
1256 }\r
1257 if (FontInfo != NULL) {\r
1258 FreePool (FontInfo);\r
1259 }\r
676df92c 1260 if (FontPackage != NULL) {\r
c59634ea 1261 if (FontPackage->GlyphBlock != NULL) {\r
1262 FreePool (FontPackage->GlyphBlock);\r
1263 }\r
676df92c 1264 FreePool (FontPackage);\r
1265 }\r
1266 if (GlobalFont != NULL) {\r
1267 FreePool (GlobalFont);\r
1268 }\r
93e3992d 1269\r
1270 return Status;\r
1271\r
1272}\r
1273\r
1274\r
1275/**\r
1276 This function exports Font packages to a buffer.\r
e90b081a 1277 This is a internal function.\r
93e3992d 1278\r
1279 @param Private Hii database private structure.\r
1280 @param Handle Identification of a package list.\r
1281 @param PackageList Pointer to a package list which will be exported.\r
1282 @param UsedSize The length of buffer be used.\r
1283 @param BufferSize Length of the Buffer.\r
1284 @param Buffer Allocated space for storing exported data.\r
1285 @param ResultSize The size of the already exported content of this\r
1286 package list.\r
1287\r
1288 @retval EFI_SUCCESS Font Packages are exported successfully.\r
1289 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1290\r
1291**/\r
93e3992d 1292EFI_STATUS\r
1293ExportFontPackages (\r
1294 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1295 IN EFI_HII_HANDLE Handle,\r
1296 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1297 IN UINTN UsedSize,\r
1298 IN UINTN BufferSize,\r
1299 IN OUT VOID *Buffer,\r
1300 IN OUT UINTN *ResultSize\r
1301 )\r
1302{\r
1303 LIST_ENTRY *Link;\r
1304 UINTN PackageLength;\r
1305 EFI_STATUS Status;\r
1306 HII_FONT_PACKAGE_INSTANCE *Package;\r
1307\r
1308\r
1309 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1310 return EFI_INVALID_PARAMETER;\r
1311 }\r
1312\r
1313 if (BufferSize > 0 && Buffer == NULL ) {\r
1314 return EFI_INVALID_PARAMETER;\r
1315 }\r
1316\r
1317 PackageLength = 0;\r
1318 Status = EFI_SUCCESS;\r
1319\r
1320 for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) {\r
1321 Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE);\r
1322 PackageLength += Package->FontPkgHdr->Header.Length;\r
1323 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1324 //\r
1325 // Invoke registered notification function with EXPORT_PACK notify type\r
1326 //\r
1327 Status = InvokeRegisteredFunction (\r
1328 Private,\r
1329 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1330 (VOID *) Package,\r
1331 EFI_HII_PACKAGE_FONTS,\r
1332 Handle\r
1333 );\r
1334 ASSERT_EFI_ERROR (Status);\r
1335 //\r
1336 // Copy Font package header\r
1337 //\r
1338 CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize);\r
1339 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->HdrSize;\r
1340\r
1341 //\r
1342 // Copy Glyph blocks information\r
1343 //\r
1344 CopyMem (\r
1345 Buffer,\r
1346 Package->GlyphBlock,\r
1347 Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize\r
1348 );\r
1349 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize;\r
1350 }\r
1351 }\r
1352\r
1353 *ResultSize += PackageLength;\r
1354 return EFI_SUCCESS;\r
1355}\r
1356\r
1357\r
1358/**\r
1359 This function deletes all Font packages from a package list node.\r
e90b081a 1360 This is a internal function.\r
93e3992d 1361\r
1362 @param Private Hii database private data.\r
1363 @param Handle Handle of the package list which contains the to\r
1364 be removed Font packages.\r
1365 @param PackageList Pointer to a package list that contains removing\r
1366 packages.\r
1367\r
1368 @retval EFI_SUCCESS Font Package(s) is deleted successfully.\r
1369 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1370\r
1371**/\r
93e3992d 1372EFI_STATUS\r
1373RemoveFontPackages (\r
1374 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1375 IN EFI_HII_HANDLE Handle,\r
1376 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1377 )\r
1378{\r
1379 LIST_ENTRY *ListHead;\r
1380 HII_FONT_PACKAGE_INSTANCE *Package;\r
1381 EFI_STATUS Status;\r
1382 HII_GLYPH_INFO *GlyphInfo;\r
1383 LIST_ENTRY *Link;\r
1384 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1385\r
1386 ListHead = &PackageList->FontPkgHdr;\r
1387\r
1388 while (!IsListEmpty (ListHead)) {\r
1389 Package = CR (\r
1390 ListHead->ForwardLink,\r
1391 HII_FONT_PACKAGE_INSTANCE,\r
1392 FontEntry,\r
1393 HII_FONT_PACKAGE_SIGNATURE\r
1394 );\r
1395 Status = InvokeRegisteredFunction (\r
1396 Private,\r
1397 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1398 (VOID *) Package,\r
1399 EFI_HII_PACKAGE_FONTS,\r
1400 Handle\r
1401 );\r
1402 if (EFI_ERROR (Status)) {\r
1403 return Status;\r
1404 }\r
1405\r
1406 RemoveEntryList (&Package->FontEntry);\r
1407 PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;\r
676df92c 1408\r
1409 if (Package->GlyphBlock != NULL) {\r
1410 FreePool (Package->GlyphBlock);\r
1411 }\r
1412 FreePool (Package->FontPkgHdr);\r
93e3992d 1413 //\r
1414 // Delete default character cell information\r
1415 //\r
1416 while (!IsListEmpty (&Package->GlyphInfoList)) {\r
1417 GlyphInfo = CR (\r
1418 Package->GlyphInfoList.ForwardLink,\r
1419 HII_GLYPH_INFO,\r
1420 Entry,\r
1421 HII_GLYPH_INFO_SIGNATURE\r
1422 );\r
1423 RemoveEntryList (&GlyphInfo->Entry);\r
676df92c 1424 FreePool (GlyphInfo);\r
93e3992d 1425 }\r
1426\r
1427 //\r
1428 // Remove corresponding global font info\r
1429 //\r
1430 for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
1431 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
1432 if (GlobalFont->FontPackage == Package) {\r
1433 RemoveEntryList (&GlobalFont->Entry);\r
676df92c 1434 FreePool (GlobalFont->FontInfo);\r
1435 FreePool (GlobalFont);\r
93e3992d 1436 break;\r
1437 }\r
1438 }\r
1439\r
676df92c 1440 FreePool (Package);\r
93e3992d 1441 }\r
1442\r
1443 return EFI_SUCCESS;\r
1444}\r
1445\r
1446\r
1447/**\r
1448 This function insert a Image package to a package list node.\r
e90b081a 1449 This is a internal function.\r
93e3992d 1450\r
1451 @param PackageHdr Pointer to a buffer stored with Image package\r
1452 information.\r
1453 @param NotifyType The type of change concerning the database.\r
1454 @param PackageList Pointer to a package list which will be inserted\r
1455 to.\r
1456 @param Package Created Image package\r
1457\r
1458 @retval EFI_SUCCESS Image Package is inserted successfully.\r
1459 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1460 Image package.\r
1461 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1462\r
1463**/\r
93e3992d 1464EFI_STATUS\r
1465InsertImagePackage (\r
1466 IN VOID *PackageHdr,\r
1467 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1468 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1469 OUT HII_IMAGE_PACKAGE_INSTANCE **Package\r
1470 )\r
1471{\r
1472 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
1473 UINT32 PaletteSize;\r
1474 UINT32 ImageSize;\r
1475 UINT16 Index;\r
1476 EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr;\r
1477 EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo;\r
1478 UINT32 PaletteInfoOffset;\r
1479 UINT32 ImageInfoOffset;\r
1480 UINT16 CurrentSize;\r
1481\r
1482 if (PackageHdr == NULL || PackageList == NULL) {\r
1483 return EFI_INVALID_PARAMETER;\r
1484 }\r
1485\r
1486 //\r
1487 // Less than one image package is allowed in one package list.\r
1488 //\r
1489 if (PackageList->ImagePkg != NULL) {\r
1490 return EFI_INVALID_PARAMETER;\r
1491 }\r
1492\r
1493 //\r
1494 // Create a Image package node\r
1495 //\r
1496 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));\r
1497 if (ImagePackage == NULL) {\r
1498 return EFI_OUT_OF_RESOURCES;\r
1499 }\r
1500\r
1501 //\r
1502 // Copy the Image package header.\r
1503 //\r
1504 CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));\r
1505\r
1506 PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset;\r
1507 ImageInfoOffset = ImagePackage->ImagePkgHdr.ImageInfoOffset;\r
1508\r
1509 //\r
1510 // If PaletteInfoOffset is zero, there are no palettes in this image package.\r
1511 //\r
1512 PaletteSize = 0;\r
1513 ImagePackage->PaletteBlock = NULL;\r
1514 if (PaletteInfoOffset != 0) {\r
1515 PaletteHdr = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *) ((UINT8 *) PackageHdr + PaletteInfoOffset);\r
1516 PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);\r
1517 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteHdr + PaletteSize);\r
1518\r
1519 for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) {\r
1520 CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16));\r
1521 CurrentSize += sizeof (UINT16);\r
1522 PaletteSize += (UINT32) CurrentSize;\r
1523 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteInfo + CurrentSize);\r
1524 }\r
1525\r
1526 ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize);\r
1527 if (ImagePackage->PaletteBlock == NULL) {\r
676df92c 1528 FreePool (ImagePackage);\r
93e3992d 1529 return EFI_OUT_OF_RESOURCES;\r
1530 }\r
1531 CopyMem (\r
1532 ImagePackage->PaletteBlock,\r
1533 (UINT8 *) PackageHdr + PaletteInfoOffset,\r
1534 PaletteSize\r
1535 );\r
1536 }\r
1537\r
1538 //\r
1539 // If ImageInfoOffset is zero, there are no images in this package.\r
1540 //\r
1541 ImageSize = 0;\r
1542 ImagePackage->ImageBlock = NULL;\r
1543 if (ImageInfoOffset != 0) {\r
1544 ImageSize = ImagePackage->ImagePkgHdr.Header.Length -\r
1545 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;\r
1546 ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (ImageSize);\r
1547 if (ImagePackage->ImageBlock == NULL) {\r
676df92c 1548 FreePool (ImagePackage->PaletteBlock);\r
1549 FreePool (ImagePackage);\r
93e3992d 1550 return EFI_OUT_OF_RESOURCES;\r
1551 }\r
1552 CopyMem (\r
1553 ImagePackage->ImageBlock,\r
1554 (UINT8 *) PackageHdr + ImageInfoOffset,\r
1555 ImageSize\r
1556 );\r
1557 }\r
1558\r
1559 ImagePackage->ImageBlockSize = ImageSize;\r
1560 ImagePackage->PaletteInfoSize = PaletteSize;\r
1561 PackageList->ImagePkg = ImagePackage;\r
1562 *Package = ImagePackage;\r
1563\r
1564 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1565 PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;\r
1566 }\r
1567\r
1568 return EFI_SUCCESS;\r
1569}\r
1570\r
1571\r
1572/**\r
1573 This function exports Image packages to a buffer.\r
e90b081a 1574 This is a internal function.\r
93e3992d 1575\r
1576 @param Private Hii database private structure.\r
1577 @param Handle Identification of a package list.\r
1578 @param PackageList Pointer to a package list which will be exported.\r
1579 @param UsedSize The length of buffer be used.\r
1580 @param BufferSize Length of the Buffer.\r
1581 @param Buffer Allocated space for storing exported data.\r
1582 @param ResultSize The size of the already exported content of this\r
1583 package list.\r
1584\r
1585 @retval EFI_SUCCESS Image Packages are exported successfully.\r
1586 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1587\r
1588**/\r
93e3992d 1589EFI_STATUS\r
1590ExportImagePackages (\r
1591 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1592 IN EFI_HII_HANDLE Handle,\r
1593 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1594 IN UINTN UsedSize,\r
1595 IN UINTN BufferSize,\r
1596 IN OUT VOID *Buffer,\r
1597 IN OUT UINTN *ResultSize\r
1598 )\r
1599{\r
1600 UINTN PackageLength;\r
1601 EFI_STATUS Status;\r
1602 HII_IMAGE_PACKAGE_INSTANCE *Package;\r
1603\r
1604\r
1605 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1606 return EFI_INVALID_PARAMETER;\r
1607 }\r
1608\r
1609 if (BufferSize > 0 && Buffer == NULL ) {\r
1610 return EFI_INVALID_PARAMETER;\r
1611 }\r
1612\r
1613 Package = PackageList->ImagePkg;\r
1614\r
1615 if (Package == NULL) {\r
1616 return EFI_SUCCESS;\r
1617 }\r
1618\r
1619 PackageLength = Package->ImagePkgHdr.Header.Length;\r
1620\r
1621 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1622 //\r
1623 // Invoke registered notification function with EXPORT_PACK notify type\r
1624 //\r
1625 Status = InvokeRegisteredFunction (\r
1626 Private,\r
1627 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1628 (VOID *) Package,\r
1629 EFI_HII_PACKAGE_IMAGES,\r
1630 Handle\r
1631 );\r
1632 ASSERT_EFI_ERROR (Status);\r
1633 ASSERT (Package->ImagePkgHdr.Header.Length ==\r
1634 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize);\r
1635 //\r
1636 // Copy Image package header,\r
1637 // then justify the offset for image info and palette info in the header.\r
1638 //\r
1639 CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));\r
1640 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
1641\r
1642 //\r
1643 // Copy Image blocks information\r
1644 //\r
1645 if (Package->ImageBlockSize != 0) {\r
1646 CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize);\r
1647 Buffer = (UINT8 *) Buffer + Package->ImageBlockSize;\r
1648 }\r
1649 //\r
1650 // Copy Palette information\r
1651 //\r
1652 if (Package->PaletteInfoSize != 0) {\r
1653 CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize);\r
1654 Buffer = (UINT8 *) Buffer + Package->PaletteInfoSize;\r
1655 }\r
1656 }\r
1657\r
1658 *ResultSize += PackageLength;\r
1659 return EFI_SUCCESS;\r
1660}\r
1661\r
1662\r
1663/**\r
1664 This function deletes Image package from a package list node.\r
e90b081a 1665 This is a internal function.\r
93e3992d 1666\r
1667 @param Private Hii database private data.\r
1668 @param Handle Handle of the package list which contains the to\r
1669 be removed Image packages.\r
1670 @param PackageList Package List which contains the to be removed\r
1671 Image package.\r
1672\r
1673 @retval EFI_SUCCESS Image Package(s) is deleted successfully.\r
1674 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1675\r
1676**/\r
93e3992d 1677EFI_STATUS\r
1678RemoveImagePackages (\r
1679 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1680 IN EFI_HII_HANDLE Handle,\r
1681 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1682 )\r
1683{\r
1684 HII_IMAGE_PACKAGE_INSTANCE *Package;\r
1685 EFI_STATUS Status;\r
1686\r
1687 Package = PackageList->ImagePkg;\r
1688\r
1689 //\r
1690 // Image package does not exist, return directly.\r
1691 //\r
1692 if (Package == NULL) {\r
1693 return EFI_SUCCESS;\r
1694 }\r
1695\r
1696 Status = InvokeRegisteredFunction (\r
1697 Private,\r
1698 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1699 (VOID *) Package,\r
1700 EFI_HII_PACKAGE_IMAGES,\r
1701 Handle\r
1702 );\r
1703 if (EFI_ERROR (Status)) {\r
1704 return Status;\r
1705 }\r
1706\r
1707 PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;\r
1708\r
676df92c 1709 FreePool (Package->ImageBlock);\r
1710 if (Package->PaletteBlock != NULL) {\r
1711 FreePool (Package->PaletteBlock);\r
1712 }\r
1713 FreePool (Package);\r
93e3992d 1714\r
1715 PackageList->ImagePkg = NULL;\r
1716\r
1717 return EFI_SUCCESS;\r
1718}\r
1719\r
1720\r
1721/**\r
1722 This function insert a Simple Font package to a package list node.\r
e90b081a 1723 This is a internal function.\r
93e3992d 1724\r
1725 @param PackageHdr Pointer to a buffer stored with Simple Font\r
1726 package information.\r
1727 @param NotifyType The type of change concerning the database.\r
1728 @param PackageList Pointer to a package list which will be inserted\r
1729 to.\r
1730 @param Package Created Simple Font package\r
1731\r
1732 @retval EFI_SUCCESS Simple Font Package is inserted successfully.\r
1733 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1734 Simple Font package.\r
1735 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1736\r
1737**/\r
93e3992d 1738EFI_STATUS\r
1739InsertSimpleFontPackage (\r
1740 IN VOID *PackageHdr,\r
1741 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1742 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1743 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE **Package\r
1744 )\r
1745{\r
1746 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;\r
1747 EFI_STATUS Status;\r
1748 EFI_HII_PACKAGE_HEADER Header;\r
1749\r
1750 if (PackageHdr == NULL || PackageList == NULL) {\r
1751 return EFI_INVALID_PARAMETER;\r
1752 }\r
1753\r
1754 //\r
1755 // Create a Simple Font package node\r
1756 //\r
1757 SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE));\r
1758 if (SimpleFontPackage == NULL) {\r
1759 Status = EFI_OUT_OF_RESOURCES;\r
1760 goto Error;\r
1761 }\r
1762 SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE;\r
1763\r
1764 //\r
1765 // Copy the Simple Font package.\r
1766 //\r
1767 CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
1768\r
1769 SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length);\r
1770 if (SimpleFontPackage->SimpleFontPkgHdr == NULL) {\r
1771 Status = EFI_OUT_OF_RESOURCES;\r
1772 goto Error;\r
1773 }\r
1774\r
1775 CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length);\r
1776\r
1777 //\r
1778 // Insert to Simple Font package array\r
1779 //\r
1780 InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry);\r
1781 *Package = SimpleFontPackage;\r
1782\r
1783 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1784 PackageList->PackageListHdr.PackageLength += Header.Length;\r
1785 }\r
1786\r
1787 return EFI_SUCCESS;\r
1788\r
1789Error:\r
1790\r
676df92c 1791 if (SimpleFontPackage != NULL) {\r
c59634ea 1792 if (SimpleFontPackage->SimpleFontPkgHdr != NULL) {\r
1793 FreePool (SimpleFontPackage->SimpleFontPkgHdr);\r
1794 }\r
676df92c 1795 FreePool (SimpleFontPackage);\r
1796 }\r
93e3992d 1797 return Status;\r
1798}\r
1799\r
1800\r
1801/**\r
1802 This function exports SimpleFont packages to a buffer.\r
e90b081a 1803 This is a internal function.\r
93e3992d 1804\r
1805 @param Private Hii database private structure.\r
1806 @param Handle Identification of a package list.\r
1807 @param PackageList Pointer to a package list which will be exported.\r
1808 @param UsedSize The length of buffer be used.\r
1809 @param BufferSize Length of the Buffer.\r
1810 @param Buffer Allocated space for storing exported data.\r
1811 @param ResultSize The size of the already exported content of this\r
1812 package list.\r
1813\r
1814 @retval EFI_SUCCESS SimpleFont Packages are exported successfully.\r
1815 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1816\r
1817**/\r
93e3992d 1818EFI_STATUS\r
1819ExportSimpleFontPackages (\r
1820 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1821 IN EFI_HII_HANDLE Handle,\r
1822 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1823 IN UINTN UsedSize,\r
1824 IN UINTN BufferSize,\r
1825 IN OUT VOID *Buffer,\r
1826 IN OUT UINTN *ResultSize\r
1827 )\r
1828{\r
1829 LIST_ENTRY *Link;\r
1830 UINTN PackageLength;\r
1831 EFI_STATUS Status;\r
1832 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;\r
1833\r
1834 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1835 return EFI_INVALID_PARAMETER;\r
1836 }\r
1837\r
1838 if (BufferSize > 0 && Buffer == NULL ) {\r
1839 return EFI_INVALID_PARAMETER;\r
1840 }\r
1841\r
1842 PackageLength = 0;\r
1843 Status = EFI_SUCCESS;\r
1844\r
1845 for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) {\r
1846 Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);\r
1847 PackageLength += Package->SimpleFontPkgHdr->Header.Length;\r
1848 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1849 //\r
1850 // Invoke registered notification function with EXPORT_PACK notify type\r
1851 //\r
1852 Status = InvokeRegisteredFunction (\r
1853 Private,\r
1854 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1855 (VOID *) Package,\r
1856 EFI_HII_PACKAGE_SIMPLE_FONTS,\r
1857 Handle\r
1858 );\r
1859 ASSERT_EFI_ERROR (Status);\r
1860\r
1861 //\r
1862 // Copy SimpleFont package\r
1863 //\r
1864 CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length);\r
1865 Buffer = (UINT8 *) Buffer + Package->SimpleFontPkgHdr->Header.Length;\r
1866 }\r
1867 }\r
1868\r
1869 *ResultSize += PackageLength;\r
1870 return EFI_SUCCESS;\r
1871}\r
1872\r
1873\r
1874/**\r
1875 This function deletes all Simple Font packages from a package list node.\r
e90b081a 1876 This is a internal function.\r
93e3992d 1877\r
1878 @param Private Hii database private data.\r
1879 @param Handle Handle of the package list which contains the to\r
1880 be removed Simple Font packages.\r
1881 @param PackageList Pointer to a package list that contains removing\r
1882 packages.\r
1883\r
1884 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.\r
1885 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1886\r
1887**/\r
93e3992d 1888EFI_STATUS\r
1889RemoveSimpleFontPackages (\r
1890 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1891 IN EFI_HII_HANDLE Handle,\r
1892 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1893 )\r
1894{\r
1895 LIST_ENTRY *ListHead;\r
1896 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;\r
1897 EFI_STATUS Status;\r
1898\r
1899 ListHead = &PackageList->SimpleFontPkgHdr;\r
1900\r
1901 while (!IsListEmpty (ListHead)) {\r
1902 Package = CR (\r
1903 ListHead->ForwardLink,\r
1904 HII_SIMPLE_FONT_PACKAGE_INSTANCE,\r
1905 SimpleFontEntry,\r
1906 HII_S_FONT_PACKAGE_SIGNATURE\r
1907 );\r
1908 Status = InvokeRegisteredFunction (\r
1909 Private,\r
1910 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1911 (VOID *) Package,\r
1912 EFI_HII_PACKAGE_SIMPLE_FONTS,\r
1913 Handle\r
1914 );\r
1915 if (EFI_ERROR (Status)) {\r
1916 return Status;\r
1917 }\r
1918\r
1919 RemoveEntryList (&Package->SimpleFontEntry);\r
1920 PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;\r
676df92c 1921 FreePool (Package->SimpleFontPkgHdr);\r
1922 FreePool (Package);\r
93e3992d 1923 }\r
1924\r
1925 return EFI_SUCCESS;\r
1926}\r
1927\r
1928\r
1929/**\r
1930 This function insert a Device path package to a package list node.\r
e90b081a 1931 This is a internal function.\r
93e3992d 1932\r
1933 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol\r
1934 instance\r
1935 @param NotifyType The type of change concerning the database.\r
1936 @param PackageList Pointer to a package list which will be inserted\r
1937 to.\r
1938\r
1939 @retval EFI_SUCCESS Device path Package is inserted successfully.\r
1940 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1941 Device path package.\r
1942 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.\r
1943\r
1944**/\r
93e3992d 1945EFI_STATUS\r
1946InsertDevicePathPackage (\r
1947 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1948 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1949 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1950 )\r
1951{\r
1952 UINT32 PackageLength;\r
1953 EFI_HII_PACKAGE_HEADER Header;\r
1954\r
1955 if (DevicePath == NULL || PackageList == NULL) {\r
1956 return EFI_INVALID_PARAMETER;\r
1957 }\r
1958 //\r
1959 // Less than one device path package is allowed in one package list.\r
1960 //\r
1961 if (PackageList->DevicePathPkg != NULL) {\r
1962 return EFI_INVALID_PARAMETER;\r
1963 }\r
1964\r
1965 PackageLength = (UINT32) GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER);\r
1966 PackageList->DevicePathPkg = (UINT8 *) AllocateZeroPool (PackageLength);\r
1967 if (PackageList->DevicePathPkg == NULL) {\r
1968 return EFI_OUT_OF_RESOURCES;\r
1969 }\r
1970\r
1971 Header.Length = PackageLength;\r
1972 Header.Type = EFI_HII_PACKAGE_DEVICE_PATH;\r
1973 CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER));\r
1974 CopyMem (\r
1975 PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
1976 DevicePath,\r
1977 PackageLength - sizeof (EFI_HII_PACKAGE_HEADER)\r
1978 );\r
1979\r
1980 //\r
1981 // Since Device Path package is created by NewPackageList, either NEW_PACK\r
1982 // or ADD_PACK should increase the length of package list.\r
1983 //\r
1984 PackageList->PackageListHdr.PackageLength += PackageLength;\r
1985 return EFI_SUCCESS;\r
1986}\r
1987\r
1988\r
1989/**\r
1990 This function exports device path package to a buffer.\r
e90b081a 1991 This is a internal function.\r
93e3992d 1992\r
1993 @param Private Hii database private structure.\r
1994 @param Handle Identification of a package list.\r
1995 @param PackageList Pointer to a package list which will be exported.\r
1996 @param UsedSize The length of buffer be used.\r
1997 @param BufferSize Length of the Buffer.\r
1998 @param Buffer Allocated space for storing exported data.\r
1999 @param ResultSize The size of the already exported content of this\r
2000 package list.\r
2001\r
2002 @retval EFI_SUCCESS Device path Package is exported successfully.\r
2003 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2004\r
2005**/\r
93e3992d 2006EFI_STATUS\r
2007ExportDevicePathPackage (\r
2008 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2009 IN EFI_HII_HANDLE Handle,\r
2010 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2011 IN UINTN UsedSize,\r
2012 IN UINTN BufferSize,\r
2013 IN OUT VOID *Buffer,\r
2014 IN OUT UINTN *ResultSize\r
2015 )\r
2016{\r
2017 EFI_STATUS Status;\r
2018 UINT8 *Package;\r
2019 EFI_HII_PACKAGE_HEADER Header;\r
2020\r
2021 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
2022 return EFI_INVALID_PARAMETER;\r
2023 }\r
2024 if (BufferSize > 0 && Buffer == NULL ) {\r
2025 return EFI_INVALID_PARAMETER;\r
2026 }\r
2027\r
2028 Package = PackageList->DevicePathPkg;\r
2029\r
2030 if (Package == NULL) {\r
2031 return EFI_SUCCESS;\r
2032 }\r
2033\r
2034 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
2035\r
2036 if (Header.Length + *ResultSize + UsedSize <= BufferSize) {\r
2037 //\r
2038 // Invoke registered notification function with EXPORT_PACK notify type\r
2039 //\r
2040 Status = InvokeRegisteredFunction (\r
2041 Private,\r
2042 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
2043 (VOID *) Package,\r
2044 EFI_HII_PACKAGE_DEVICE_PATH,\r
2045 Handle\r
2046 );\r
2047 ASSERT_EFI_ERROR (Status);\r
2048\r
2049 //\r
2050 // Copy Device path package\r
2051 //\r
2052 CopyMem (Buffer, Package, Header.Length);\r
2053 }\r
2054\r
2055 *ResultSize += Header.Length;\r
2056 return EFI_SUCCESS;\r
2057}\r
2058\r
2059\r
2060/**\r
2061 This function deletes Device Path package from a package list node.\r
e90b081a 2062 This is a internal function.\r
93e3992d 2063\r
2064 @param Private Hii database private data.\r
2065 @param Handle Handle of the package list.\r
2066 @param PackageList Package List which contains the to be removed\r
2067 Device Path package.\r
2068\r
2069 @retval EFI_SUCCESS Device Path Package is deleted successfully.\r
2070 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
2071\r
2072**/\r
93e3992d 2073EFI_STATUS\r
2074RemoveDevicePathPackage (\r
2075 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2076 IN EFI_HII_HANDLE Handle,\r
2077 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2078 )\r
2079{\r
2080 EFI_STATUS Status;\r
2081 UINT8 *Package;\r
2082 EFI_HII_PACKAGE_HEADER Header;\r
2083\r
2084 Package = PackageList->DevicePathPkg;\r
2085\r
2086 //\r
2087 // No device path, return directly.\r
2088 //\r
2089 if (Package == NULL) {\r
2090 return EFI_SUCCESS;\r
2091 }\r
2092\r
2093 Status = InvokeRegisteredFunction (\r
2094 Private,\r
2095 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2096 (VOID *) Package,\r
2097 EFI_HII_PACKAGE_DEVICE_PATH,\r
2098 Handle\r
2099 );\r
2100 if (EFI_ERROR (Status)) {\r
2101 return Status;\r
2102 }\r
2103\r
2104 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
2105 PackageList->PackageListHdr.PackageLength -= Header.Length;\r
2106\r
676df92c 2107 FreePool (Package);\r
93e3992d 2108\r
2109 PackageList->DevicePathPkg = NULL;\r
2110\r
2111 return EFI_SUCCESS;\r
2112}\r
2113\r
2114\r
2115/**\r
2116 This function will insert a device path package to package list firstly then\r
2117 invoke notification functions if any.\r
e90b081a 2118 This is a internal function.\r
93e3992d 2119\r
2120 @param Private Hii database private structure.\r
2121 @param NotifyType The type of change concerning the database.\r
2122 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol\r
2123 instance\r
2124 @param DatabaseRecord Pointer to a database record contains a package\r
2125 list which will be inserted to.\r
2126\r
2127 @retval EFI_SUCCESS Device path Package is inserted successfully.\r
2128 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2129 Device path package.\r
2130 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.\r
2131\r
2132**/\r
93e3992d 2133EFI_STATUS\r
2134AddDevicePathPackage (\r
2135 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2136 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2137 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
2138 IN OUT HII_DATABASE_RECORD *DatabaseRecord\r
2139 )\r
2140{\r
2141 EFI_STATUS Status;\r
2142\r
2143 if (DevicePath == NULL) {\r
2144 return EFI_SUCCESS;\r
2145 }\r
2146\r
2147 ASSERT (Private != NULL);\r
2148 ASSERT (DatabaseRecord != NULL);\r
2149\r
2150 //\r
2151 // Create a device path package and insert to packagelist\r
2152 //\r
2153 Status = InsertDevicePathPackage (\r
2154 DevicePath,\r
2155 NotifyType,\r
2156 DatabaseRecord->PackageList\r
2157 );\r
2158 if (EFI_ERROR (Status)) {\r
2159 return Status;\r
2160 }\r
2161\r
2162 return InvokeRegisteredFunction (\r
2163 Private,\r
2164 NotifyType,\r
2165 (VOID *) DatabaseRecord->PackageList->DevicePathPkg,\r
2166 EFI_HII_PACKAGE_DEVICE_PATH,\r
2167 DatabaseRecord->Handle\r
2168 );\r
2169}\r
2170\r
2171\r
2172/**\r
2173 This function insert a Keyboard Layout package to a package list node.\r
e90b081a 2174 This is a internal function.\r
93e3992d 2175\r
2176 @param PackageHdr Pointer to a buffer stored with Keyboard Layout\r
2177 package information.\r
2178 @param NotifyType The type of change concerning the database.\r
2179 @param PackageList Pointer to a package list which will be inserted\r
2180 to.\r
2181 @param Package Created Keyboard Layout package\r
2182\r
2183 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.\r
2184 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2185 Keyboard Layout package.\r
2186 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
2187\r
2188**/\r
93e3992d 2189EFI_STATUS\r
2190InsertKeyboardLayoutPackage (\r
2191 IN VOID *PackageHdr,\r
2192 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2193 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2194 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE **Package\r
2195 )\r
2196{\r
2197 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;\r
2198 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2199 EFI_STATUS Status;\r
2200\r
2201 if (PackageHdr == NULL || PackageList == NULL) {\r
2202 return EFI_INVALID_PARAMETER;\r
2203 }\r
2204\r
2205 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2206\r
2207 //\r
2208 // Create a Keyboard Layout package node\r
2209 //\r
2210 KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE));\r
2211 if (KeyboardLayoutPackage == NULL) {\r
2212 Status = EFI_OUT_OF_RESOURCES;\r
2213 goto Error;\r
2214 }\r
2215 KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE;\r
2216\r
2217 KeyboardLayoutPackage->KeyboardPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);\r
2218 if (KeyboardLayoutPackage->KeyboardPkg == NULL) {\r
2219 Status = EFI_OUT_OF_RESOURCES;\r
2220 goto Error;\r
2221 }\r
2222\r
2223 CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length);\r
2224 InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry);\r
2225\r
2226 *Package = KeyboardLayoutPackage;\r
2227\r
2228 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2229 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;\r
2230 }\r
2231\r
2232 return EFI_SUCCESS;\r
2233\r
2234Error:\r
2235\r
c59634ea 2236\r
676df92c 2237 if (KeyboardLayoutPackage != NULL) {\r
c59634ea 2238 if (KeyboardLayoutPackage->KeyboardPkg != NULL) {\r
2239 FreePool (KeyboardLayoutPackage->KeyboardPkg);\r
2240 }\r
676df92c 2241 FreePool (KeyboardLayoutPackage);\r
2242 }\r
93e3992d 2243\r
2244 return Status;\r
2245}\r
2246\r
2247\r
2248/**\r
2249 This function exports Keyboard Layout packages to a buffer.\r
e90b081a 2250 This is a internal function.\r
93e3992d 2251\r
2252 @param Private Hii database private structure.\r
2253 @param Handle Identification of a package list.\r
2254 @param PackageList Pointer to a package list which will be exported.\r
2255 @param UsedSize The length of buffer be used.\r
2256 @param BufferSize Length of the Buffer.\r
2257 @param Buffer Allocated space for storing exported data.\r
2258 @param ResultSize The size of the already exported content of this\r
2259 package list.\r
2260\r
2261 @retval EFI_SUCCESS Keyboard Layout Packages are exported\r
2262 successfully.\r
2263 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2264\r
2265**/\r
93e3992d 2266EFI_STATUS\r
2267ExportKeyboardLayoutPackages (\r
2268 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2269 IN EFI_HII_HANDLE Handle,\r
2270 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2271 IN UINTN UsedSize,\r
2272 IN UINTN BufferSize,\r
2273 IN OUT VOID *Buffer,\r
2274 IN OUT UINTN *ResultSize\r
2275 )\r
2276{\r
2277 LIST_ENTRY *Link;\r
2278 UINTN PackageLength;\r
2279 EFI_STATUS Status;\r
2280 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
2281 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2282\r
2283 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
2284 return EFI_INVALID_PARAMETER;\r
2285 }\r
2286\r
2287 if (BufferSize > 0 && Buffer == NULL ) {\r
2288 return EFI_INVALID_PARAMETER;\r
2289 }\r
2290\r
2291 PackageLength = 0;\r
2292 Status = EFI_SUCCESS;\r
2293\r
2294 for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) {\r
2295 Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE);\r
2296 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
2297 PackageLength += PackageHeader.Length;\r
2298 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
2299 //\r
2300 // Invoke registered notification function with EXPORT_PACK notify type\r
2301 //\r
2302 Status = InvokeRegisteredFunction (\r
2303 Private,\r
2304 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
2305 (EFI_HII_PACKAGE_HEADER *) Package,\r
2306 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,\r
2307 Handle\r
2308 );\r
2309 ASSERT_EFI_ERROR (Status);\r
2310\r
2311 //\r
2312 // Copy Keyboard Layout package\r
2313 //\r
2314 CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length);\r
2315 Buffer = (UINT8 *) Buffer + PackageHeader.Length;\r
2316 }\r
2317 }\r
2318\r
2319 *ResultSize += PackageLength;\r
2320 return EFI_SUCCESS;\r
2321}\r
2322\r
2323\r
2324/**\r
2325 This function deletes all Keyboard Layout packages from a package list node.\r
e90b081a 2326 This is a internal function.\r
93e3992d 2327\r
2328 @param Private Hii database private data.\r
2329 @param Handle Handle of the package list which contains the to\r
2330 be removed Keyboard Layout packages.\r
2331 @param PackageList Pointer to a package list that contains removing\r
2332 packages.\r
2333\r
2334 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted\r
2335 successfully.\r
2336 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
2337\r
2338**/\r
93e3992d 2339EFI_STATUS\r
2340RemoveKeyboardLayoutPackages (\r
2341 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2342 IN EFI_HII_HANDLE Handle,\r
2343 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2344 )\r
2345{\r
2346 LIST_ENTRY *ListHead;\r
2347 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
2348 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2349 EFI_STATUS Status;\r
2350\r
2351 ListHead = &PackageList->KeyboardLayoutHdr;\r
2352\r
2353 while (!IsListEmpty (ListHead)) {\r
2354 Package = CR (\r
2355 ListHead->ForwardLink,\r
2356 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
2357 KeyboardEntry,\r
2358 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
2359 );\r
2360 Status = InvokeRegisteredFunction (\r
2361 Private,\r
2362 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2363 (VOID *) Package,\r
2364 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,\r
2365 Handle\r
2366 );\r
2367 if (EFI_ERROR (Status)) {\r
2368 return Status;\r
2369 }\r
2370\r
2371 RemoveEntryList (&Package->KeyboardEntry);\r
2372 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
2373 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;\r
676df92c 2374 FreePool (Package->KeyboardPkg);\r
2375 FreePool (Package);\r
93e3992d 2376 }\r
2377\r
2378 return EFI_SUCCESS;\r
2379}\r
2380\r
2381\r
2382/**\r
2383 This function will insert a package list to hii database firstly then\r
2384 invoke notification functions if any. It is the worker function of\r
2385 HiiNewPackageList and HiiUpdatePackageList.\r
2386\r
e90b081a 2387 This is a internal function.\r
2388\r
93e3992d 2389 @param Private Hii database private structure.\r
2390 @param NotifyType The type of change concerning the database.\r
2391 @param PackageList Pointer to a package list.\r
2392 @param DatabaseRecord Pointer to a database record contains a package\r
2393 list instance which will be inserted to.\r
2394\r
2395 @retval EFI_SUCCESS All incoming packages are inserted to current\r
2396 database.\r
2397 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2398 Device path package.\r
2399 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2400\r
2401**/\r
93e3992d 2402EFI_STATUS\r
2403AddPackages (\r
2404 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2405 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2406 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
2407 IN OUT HII_DATABASE_RECORD *DatabaseRecord\r
2408 )\r
2409{\r
2410 EFI_STATUS Status;\r
2411 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
2412 HII_IFR_PACKAGE_INSTANCE *FormPackage;\r
2413 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;\r
2414 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
2415 HII_FONT_PACKAGE_INSTANCE *FontPackage;\r
2416 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;\r
2417 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
2418 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
2419 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2420 UINT32 OldPackageListLen;\r
6ddd3af7 2421 BOOLEAN StringPkgIsAdd;\r
93e3992d 2422\r
6c46a5ab 2423 //\r
2424 // Initialize Variables\r
2425 //\r
6ddd3af7 2426 StringPkgIsAdd = FALSE;\r
6c46a5ab 2427 FontPackage = NULL;\r
2428\r
93e3992d 2429 //\r
2430 // Process the package list header\r
2431 //\r
2432 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;\r
2433 CopyMem (\r
2434 &DatabaseRecord->PackageList->PackageListHdr,\r
2435 (VOID *) PackageList,\r
2436 sizeof (EFI_HII_PACKAGE_LIST_HEADER)\r
2437 );\r
2438 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2439 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;\r
2440 }\r
2441\r
2442 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
2443 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2444\r
2445 Status = EFI_SUCCESS;\r
2446\r
2447 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
2448 switch (PackageHeader.Type) {\r
2449 case EFI_HII_PACKAGE_TYPE_GUID:\r
2450 Status = InsertGuidPackage (\r
2451 PackageHdrPtr,\r
2452 NotifyType,\r
2453 DatabaseRecord->PackageList,\r
2454 &GuidPackage\r
2455 );\r
2456 if (EFI_ERROR (Status)) {\r
2457 return Status;\r
2458 }\r
2459 Status = InvokeRegisteredFunction (\r
2460 Private,\r
2461 NotifyType,\r
2462 (VOID *) GuidPackage,\r
2463 (UINT8) (PackageHeader.Type),\r
2464 DatabaseRecord->Handle\r
2465 );\r
2466 break;\r
8d00a0f1 2467 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 2468 Status = InsertFormPackage (\r
2469 PackageHdrPtr,\r
2470 NotifyType,\r
2471 DatabaseRecord->PackageList,\r
2472 &FormPackage\r
2473 );\r
2474 if (EFI_ERROR (Status)) {\r
2475 return Status;\r
2476 }\r
2477 Status = InvokeRegisteredFunction (\r
2478 Private,\r
2479 NotifyType,\r
2480 (VOID *) FormPackage,\r
2481 (UINT8) (PackageHeader.Type),\r
2482 DatabaseRecord->Handle\r
2483 );\r
2484 break;\r
2485 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
2486 Status = InsertKeyboardLayoutPackage (\r
2487 PackageHdrPtr,\r
2488 NotifyType,\r
2489 DatabaseRecord->PackageList,\r
2490 &KeyboardLayoutPackage\r
2491 );\r
2492 if (EFI_ERROR (Status)) {\r
2493 return Status;\r
2494 }\r
2495 Status = InvokeRegisteredFunction (\r
2496 Private,\r
2497 NotifyType,\r
2498 (VOID *) KeyboardLayoutPackage,\r
2499 (UINT8) (PackageHeader.Type),\r
2500 DatabaseRecord->Handle\r
2501 );\r
2502 break;\r
2503 case EFI_HII_PACKAGE_STRINGS:\r
2504 Status = InsertStringPackage (\r
2505 Private,\r
2506 PackageHdrPtr,\r
2507 NotifyType,\r
2508 DatabaseRecord->PackageList,\r
2509 &StringPackage\r
2510 );\r
2511 if (EFI_ERROR (Status)) {\r
2512 return Status;\r
2513 }\r
2514 Status = InvokeRegisteredFunction (\r
2515 Private,\r
2516 NotifyType,\r
2517 (VOID *) StringPackage,\r
2518 (UINT8) (PackageHeader.Type),\r
2519 DatabaseRecord->Handle\r
2520 );\r
6ddd3af7 2521 StringPkgIsAdd = TRUE;\r
93e3992d 2522 break;\r
2523 case EFI_HII_PACKAGE_FONTS:\r
2524 Status = InsertFontPackage (\r
2525 Private,\r
2526 PackageHdrPtr,\r
2527 NotifyType,\r
2528 DatabaseRecord->PackageList,\r
2529 &FontPackage\r
2530 );\r
2531 if (EFI_ERROR (Status)) {\r
2532 return Status;\r
2533 }\r
2534 Status = InvokeRegisteredFunction (\r
2535 Private,\r
2536 NotifyType,\r
2537 (VOID *) FontPackage,\r
2538 (UINT8) (PackageHeader.Type),\r
2539 DatabaseRecord->Handle\r
2540 );\r
2541 break;\r
2542 case EFI_HII_PACKAGE_IMAGES:\r
2543 Status = InsertImagePackage (\r
2544 PackageHdrPtr,\r
2545 NotifyType,\r
2546 DatabaseRecord->PackageList,\r
2547 &ImagePackage\r
2548 );\r
2549 if (EFI_ERROR (Status)) {\r
2550 return Status;\r
2551 }\r
2552 Status = InvokeRegisteredFunction (\r
2553 Private,\r
2554 NotifyType,\r
2555 (VOID *) ImagePackage,\r
2556 (UINT8) (PackageHeader.Type),\r
2557 DatabaseRecord->Handle\r
2558 );\r
2559 break;\r
2560 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
2561 Status = InsertSimpleFontPackage (\r
2562 PackageHdrPtr,\r
2563 NotifyType,\r
2564 DatabaseRecord->PackageList,\r
2565 &SimpleFontPackage\r
2566 );\r
2567 if (EFI_ERROR (Status)) {\r
2568 return Status;\r
2569 }\r
2570 Status = InvokeRegisteredFunction (\r
2571 Private,\r
2572 NotifyType,\r
2573 (VOID *) SimpleFontPackage,\r
2574 (UINT8) (PackageHeader.Type),\r
2575 DatabaseRecord->Handle\r
2576 );\r
2577 break;\r
2578 case EFI_HII_PACKAGE_DEVICE_PATH:\r
2579 Status = AddDevicePathPackage (\r
2580 Private,\r
2581 NotifyType,\r
2582 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),\r
2583 DatabaseRecord\r
2584 );\r
2585 break;\r
2586 default:\r
2587 break;\r
2588 }\r
2589\r
2590 if (EFI_ERROR (Status)) {\r
2591 return Status;\r
2592 }\r
2593 //\r
2594 // goto header of next package\r
2595 //\r
2596 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
2597 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2598 }\r
6ddd3af7
LG
2599 \r
2600 //\r
2601 // Adjust String Package to make sure all string packages have the same max string ID.\r
2602 //\r
2603 if (!EFI_ERROR (Status) && StringPkgIsAdd) {\r
2604 Status = AdjustStringPackage (DatabaseRecord->PackageList);\r
2605 }\r
93e3992d 2606\r
2607 return Status;\r
2608}\r
2609\r
2610\r
2611/**\r
2612 This function exports a package list to a buffer. It is the worker function\r
2613 of HiiExportPackageList.\r
2614\r
e90b081a 2615 This is a internal function.\r
2616\r
93e3992d 2617 @param Private Hii database private structure.\r
2618 @param Handle Identification of a package list.\r
2619 @param PackageList Pointer to a package list which will be exported.\r
2620 @param UsedSize The length of buffer has been used by exporting\r
2621 package lists when Handle is NULL.\r
2622 @param BufferSize Length of the Buffer.\r
2623 @param Buffer Allocated space for storing exported data.\r
2624\r
2625 @retval EFI_SUCCESS Keyboard Layout Packages are exported\r
2626 successfully.\r
2627 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2628\r
2629**/\r
93e3992d 2630EFI_STATUS\r
2631ExportPackageList (\r
2632 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2633 IN EFI_HII_HANDLE Handle,\r
2634 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2635 IN OUT UINTN *UsedSize,\r
2636 IN UINTN BufferSize,\r
2637 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
2638 )\r
2639{\r
2640 EFI_STATUS Status;\r
2641 UINTN ResultSize;\r
2642 EFI_HII_PACKAGE_HEADER EndofPackageList;\r
2643\r
96ff65a1 2644 ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);\r
93e3992d 2645 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
2646 ASSERT (IsHiiHandleValid (Handle));\r
2647\r
2648 if (BufferSize > 0 && Buffer == NULL ) {\r
2649 return EFI_INVALID_PARAMETER;\r
2650 }\r
2651\r
2652 //\r
2653 // Copy the package list header\r
2654 // ResultSize indicates the length of the exported bytes of this package list\r
2655 //\r
2656 ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
2657 if (ResultSize + *UsedSize <= BufferSize) {\r
2658 CopyMem ((VOID *) Buffer, PackageList, ResultSize);\r
2659 }\r
2660 //\r
2661 // Copy the packages and invoke EXPORT_PACK notify functions if exists.\r
2662 //\r
2663 Status = ExportGuidPackages (\r
2664 Private,\r
2665 Handle,\r
2666 PackageList,\r
2667 *UsedSize,\r
2668 BufferSize,\r
2669 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2670 &ResultSize\r
2671 );\r
2672 if (EFI_ERROR (Status)) {\r
2673 return Status;\r
2674 }\r
2675 Status = ExportFormPackages (\r
2676 Private,\r
2677 Handle,\r
2678 PackageList,\r
2679 *UsedSize,\r
2680 BufferSize,\r
2681 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2682 &ResultSize\r
2683 );\r
2684 if (EFI_ERROR (Status)) {\r
2685 return Status;\r
2686 }\r
2687 Status = ExportKeyboardLayoutPackages (\r
2688 Private,\r
2689 Handle,\r
2690 PackageList,\r
2691 *UsedSize,\r
2692 BufferSize,\r
2693 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2694 &ResultSize\r
2695 );\r
2696 if (EFI_ERROR (Status)) {\r
2697 return Status;\r
2698 }\r
2699 Status = ExportStringPackages (\r
2700 Private,\r
2701 Handle,\r
2702 PackageList,\r
2703 *UsedSize,\r
2704 BufferSize,\r
2705 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2706 &ResultSize\r
2707 );\r
2708 if (EFI_ERROR (Status)) {\r
2709 return Status;\r
2710 }\r
2711 Status = ExportFontPackages (\r
2712 Private,\r
2713 Handle,\r
2714 PackageList,\r
2715 *UsedSize,\r
2716 BufferSize,\r
2717 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2718 &ResultSize\r
2719 );\r
2720 if (EFI_ERROR (Status)) {\r
2721 return Status;\r
2722 }\r
2723 Status = ExportImagePackages (\r
2724 Private,\r
2725 Handle,\r
2726 PackageList,\r
2727 *UsedSize,\r
2728 BufferSize,\r
2729 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2730 &ResultSize\r
2731 );\r
2732 if (EFI_ERROR (Status)) {\r
2733 return Status;\r
2734 }\r
2735 Status = ExportSimpleFontPackages (\r
2736 Private,\r
2737 Handle,\r
2738 PackageList,\r
2739 *UsedSize,\r
2740 BufferSize,\r
2741 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2742 &ResultSize\r
2743 );\r
2744 if (EFI_ERROR (Status)) {\r
2745 return Status;\r
2746 }\r
2747 Status = ExportDevicePathPackage (\r
2748 Private,\r
2749 Handle,\r
2750 PackageList,\r
2751 *UsedSize,\r
2752 BufferSize,\r
2753 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2754 &ResultSize\r
2755 );\r
2756 if (EFI_ERROR (Status)) {\r
2757 return Status;\r
2758 }\r
2759 //\r
2760 // Append the package list end.\r
2761 //\r
2762 EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
2763 EndofPackageList.Type = EFI_HII_PACKAGE_END;\r
2764 if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {\r
2765 CopyMem (\r
2766 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2767 (VOID *) &EndofPackageList,\r
2768 sizeof (EFI_HII_PACKAGE_HEADER)\r
2769 );\r
2770 }\r
2771\r
2772 *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);\r
2773\r
2774 return EFI_SUCCESS;\r
2775}\r
2776\r
2777\r
2778/**\r
2779 This function adds the packages in the package list to the database and returns a handle. If there is a\r
2780 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will\r
2781 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.\r
2782\r
2783 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2784 instance.\r
2785 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
2786 structure.\r
2787 @param DriverHandle Associate the package list with this EFI handle.\r
b1a803d1 2788 If a NULL is specified, this data will not be associate\r
2789 with any drivers and cannot have a callback induced.\r
93e3992d 2790 @param Handle A pointer to the EFI_HII_HANDLE instance.\r
2791\r
2792 @retval EFI_SUCCESS The package list associated with the Handle was\r
2793 added to the HII database.\r
2794 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2795 database contents.\r
2796 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.\r
2797 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.\r
2798\r
2799**/\r
2800EFI_STATUS\r
2801EFIAPI\r
2802HiiNewPackageList (\r
2803 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2804 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
b1a803d1 2805 IN CONST EFI_HANDLE DriverHandle, OPTIONAL\r
93e3992d 2806 OUT EFI_HII_HANDLE *Handle\r
2807 )\r
2808{\r
2809 EFI_STATUS Status;\r
2810 HII_DATABASE_PRIVATE_DATA *Private;\r
2811 HII_DATABASE_RECORD *DatabaseRecord;\r
2812 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2813 LIST_ENTRY *Link;\r
2814 EFI_GUID PackageListGuid;\r
2815\r
2816 if (This == NULL || PackageList == NULL || Handle == NULL) {\r
2817 return EFI_INVALID_PARAMETER;\r
2818 }\r
2819\r
2820 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2821 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));\r
2822\r
2823 //\r
2824 // Check the Package list GUID to guarantee this GUID is unique in database.\r
2825 //\r
2826 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2827 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2828 if (CompareGuid (\r
2829 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
aa2614b7 2830 &PackageListGuid) && \r
2831 DatabaseRecord->DriverHandle == DriverHandle) {\r
93e3992d 2832 return EFI_INVALID_PARAMETER;\r
2833 }\r
2834 }\r
2835\r
2836 //\r
2837 // Build a PackageList node\r
2838 //\r
2839 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
2840 if (EFI_ERROR (Status)) {\r
2841 return Status;\r
2842 }\r
2843\r
2844 //\r
2845 // Fill in information of the created Package List node\r
2846 // according to incoming package list.\r
2847 //\r
2848 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
2849 if (EFI_ERROR (Status)) {\r
2850 return Status;\r
2851 }\r
2852\r
2853 DatabaseRecord->DriverHandle = DriverHandle;\r
2854\r
2855 //\r
2856 // Create a Device path package and add into the package list if exists.\r
2857 //\r
2858 Status = gBS->HandleProtocol (\r
2859 DriverHandle,\r
2860 &gEfiDevicePathProtocolGuid,\r
2861 (VOID **) &DevicePath\r
2862 );\r
2863 if (!EFI_ERROR (Status)) {\r
2864 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);\r
2865 ASSERT_EFI_ERROR (Status);\r
2866 }\r
2867\r
2868 *Handle = DatabaseRecord->Handle;\r
2869 return EFI_SUCCESS;\r
2870}\r
2871\r
2872\r
2873/**\r
2874 This function removes the package list that is associated with a handle Handle\r
2875 from the HII database. Before removing the package, any registered functions\r
2876 with the notification type REMOVE_PACK and the same package type will be called.\r
2877\r
2878 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2879 instance.\r
2880 @param Handle The handle that was registered to the data that is\r
2881 requested for removal.\r
2882\r
2883 @retval EFI_SUCCESS The data associated with the Handle was removed\r
2884 from the HII database.\r
813acf3a 2885 @retval EFI_NOT_FOUND The specified andle is not in database.\r
93e3992d 2886 @retval EFI_INVALID_PARAMETER The Handle was not valid.\r
2887\r
2888**/\r
2889EFI_STATUS\r
2890EFIAPI\r
2891HiiRemovePackageList (\r
2892 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2893 IN EFI_HII_HANDLE Handle\r
2894 )\r
2895{\r
2896 EFI_STATUS Status;\r
2897 HII_DATABASE_PRIVATE_DATA *Private;\r
2898 LIST_ENTRY *Link;\r
2899 HII_DATABASE_RECORD *Node;\r
2900 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
2901 HII_HANDLE *HiiHandle;\r
2902\r
813acf3a 2903 if (This == NULL) {\r
93e3992d 2904 return EFI_INVALID_PARAMETER;\r
2905 }\r
2906\r
813acf3a 2907 if (!IsHiiHandleValid (Handle)) {\r
2908 return EFI_NOT_FOUND;\r
2909 }\r
2910\r
93e3992d 2911 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2912\r
2913 //\r
2914 // Get the packagelist to be removed.\r
2915 //\r
2916 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2917 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2918 if (Node->Handle == Handle) {\r
2919 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
2920 ASSERT (PackageList != NULL);\r
2921\r
2922 //\r
2923 // Call registered functions with REMOVE_PACK before removing packages\r
2924 // then remove them.\r
2925 //\r
2926 Status = RemoveGuidPackages (Private, Handle, PackageList);\r
2927 if (EFI_ERROR (Status)) {\r
2928 return Status;\r
2929 }\r
2930 Status = RemoveFormPackages (Private, Handle, PackageList);\r
2931 if (EFI_ERROR (Status)) {\r
2932 return Status;\r
2933 }\r
2934 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
2935 if (EFI_ERROR (Status)) {\r
2936 return Status;\r
2937 }\r
2938 Status = RemoveStringPackages (Private, Handle, PackageList);\r
2939 if (EFI_ERROR (Status)) {\r
2940 return Status;\r
2941 }\r
2942 Status = RemoveFontPackages (Private, Handle, PackageList);\r
2943 if (EFI_ERROR (Status)) {\r
2944 return Status;\r
2945 }\r
2946 Status = RemoveImagePackages (Private, Handle, PackageList);\r
2947 if (EFI_ERROR (Status)) {\r
2948 return Status;\r
2949 }\r
2950 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
2951 if (EFI_ERROR (Status)) {\r
2952 return Status;\r
2953 }\r
2954 Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
2955 if (EFI_ERROR (Status)) {\r
2956 return Status;\r
2957 }\r
2958\r
2959 //\r
2960 // Free resources of the package list\r
2961 //\r
2962 RemoveEntryList (&Node->DatabaseEntry);\r
2963\r
2964 HiiHandle = (HII_HANDLE *) Handle;\r
2965 RemoveEntryList (&HiiHandle->Handle);\r
2966 Private->HiiHandleCount--;\r
2967 ASSERT (Private->HiiHandleCount >= 0);\r
2968\r
2969 HiiHandle->Signature = 0;\r
676df92c 2970 FreePool (HiiHandle);\r
2971 FreePool (Node->PackageList);\r
2972 FreePool (Node);\r
93e3992d 2973\r
2974 return EFI_SUCCESS;\r
2975 }\r
2976 }\r
2977\r
2978 return EFI_NOT_FOUND;\r
2979}\r
2980\r
2981\r
2982/**\r
2983 This function updates the existing package list (which has the specified Handle)\r
2984 in the HII databases, using the new package list specified by PackageList.\r
2985\r
2986 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2987 instance.\r
2988 @param Handle The handle that was registered to the data that is\r
2989 requested to be updated.\r
2990 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
2991 package.\r
2992\r
2993 @retval EFI_SUCCESS The HII database was successfully updated.\r
2994 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated\r
2995 database.\r
813acf3a 2996 @retval EFI_INVALID_PARAMETER PackageList was NULL.\r
2997 @retval EFI_NOT_FOUND The specified Handle is not in database.\r
93e3992d 2998\r
2999**/\r
3000EFI_STATUS\r
3001EFIAPI\r
3002HiiUpdatePackageList (\r
3003 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3004 IN EFI_HII_HANDLE Handle,\r
3005 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList\r
3006 )\r
3007{\r
3008 EFI_STATUS Status;\r
3009 HII_DATABASE_PRIVATE_DATA *Private;\r
3010 LIST_ENTRY *Link;\r
3011 HII_DATABASE_RECORD *Node;\r
3012 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
3013 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;\r
3014 EFI_HII_PACKAGE_HEADER PackageHeader;\r
3015\r
813acf3a 3016 if (This == NULL || PackageList == NULL) {\r
93e3992d 3017 return EFI_INVALID_PARAMETER;\r
3018 }\r
3019\r
3020 if (!IsHiiHandleValid (Handle)) {\r
3021 return EFI_NOT_FOUND;\r
3022 }\r
3023\r
3024 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3025\r
3026 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
3027\r
3028 Status = EFI_SUCCESS;\r
3029\r
3030 //\r
3031 // Get original packagelist to be updated\r
3032 //\r
3033 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3034 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3035 if (Node->Handle == Handle) {\r
3036 OldPackageList = Node->PackageList;\r
3037 //\r
3038 // Remove the package if its type matches one of the package types which is\r
3039 // contained in the new package list.\r
3040 //\r
3041 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
3042 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
3043 switch (PackageHeader.Type) {\r
3044 case EFI_HII_PACKAGE_TYPE_GUID:\r
3045 Status = RemoveGuidPackages (Private, Handle, OldPackageList);\r
3046 break;\r
8d00a0f1 3047 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3048 Status = RemoveFormPackages (Private, Handle, OldPackageList);\r
3049 break;\r
3050 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3051 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);\r
3052 break;\r
3053 case EFI_HII_PACKAGE_STRINGS:\r
3054 Status = RemoveStringPackages (Private, Handle, OldPackageList);\r
3055 break;\r
3056 case EFI_HII_PACKAGE_FONTS:\r
3057 Status = RemoveFontPackages (Private, Handle, OldPackageList);\r
3058 break;\r
3059 case EFI_HII_PACKAGE_IMAGES:\r
3060 Status = RemoveImagePackages (Private, Handle, OldPackageList);\r
3061 break;\r
3062 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3063 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);\r
3064 break;\r
3065 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3066 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);\r
3067 break;\r
3068 }\r
3069\r
3070 if (EFI_ERROR (Status)) {\r
3071 return Status;\r
3072 }\r
3073\r
3074 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
3075 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
3076 }\r
3077\r
3078 //\r
3079 // Add all of the packages within the new package list\r
3080 //\r
3081 return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
3082 }\r
3083 }\r
3084\r
3085 return EFI_NOT_FOUND;\r
3086}\r
3087\r
3088\r
3089/**\r
3090 This function returns a list of the package handles of the specified type\r
3091 that are currently active in the database. The pseudo-type\r
3092 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.\r
3093\r
3094 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3095 instance.\r
3096 @param PackageType Specifies the package type of the packages to list\r
3097 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3098 listed.\r
3099 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3100 this is the pointer to the GUID which must match\r
3101 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.\r
3102 Otherwise, it must be NULL.\r
3103 @param HandleBufferLength On input, a pointer to the length of the handle\r
3104 buffer. On output, the length of the handle\r
3105 buffer that is required for the handles found.\r
3106 @param Handle An array of EFI_HII_HANDLE instances returned.\r
3107\r
3108 @retval EFI_SUCCESS The matching handles are outputed successfully.\r
813acf3a 3109 HandleBufferLength is updated with the actual length.\r
93e3992d 3110 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3111 Handle is too small to support the number of\r
3112 handles. HandleBufferLength is updated with a\r
3113 value that will enable the data to fit.\r
3114 @retval EFI_NOT_FOUND No matching handle could not be found in database.\r
3115 @retval EFI_INVALID_PARAMETER Handle or HandleBufferLength was NULL.\r
813acf3a 3116 \r
3117 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but\r
3118 PackageGuid is not NULL, PackageType is a EFI_HII_\r
3119 PACKAGE_TYPE_GUID but PackageGuid is NULL.\r
93e3992d 3120\r
3121**/\r
3122EFI_STATUS\r
3123EFIAPI\r
3124HiiListPackageLists (\r
3125 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3126 IN UINT8 PackageType,\r
3127 IN CONST EFI_GUID *PackageGuid,\r
3128 IN OUT UINTN *HandleBufferLength,\r
3129 OUT EFI_HII_HANDLE *Handle\r
3130 )\r
3131{\r
3132 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
3133 HII_DATABASE_PRIVATE_DATA *Private;\r
3134 HII_DATABASE_RECORD *Node;\r
3135 LIST_ENTRY *Link;\r
3136 BOOLEAN Matched;\r
3137 HII_HANDLE **Result;\r
3138 UINTN ResultSize;\r
3139 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3140 LIST_ENTRY *Link1;\r
3141\r
3142 //\r
3143 // Check input parameters\r
3144 //\r
3145 if (This == NULL || HandleBufferLength == NULL) {\r
3146 return EFI_INVALID_PARAMETER;\r
3147 }\r
3148 if (*HandleBufferLength > 0 && Handle == NULL) {\r
3149 return EFI_INVALID_PARAMETER;\r
3150 }\r
3151 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3152 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3153 return EFI_INVALID_PARAMETER;\r
3154 }\r
3155\r
3156 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3157 Matched = FALSE;\r
3158 Result = (HII_HANDLE **) Handle;\r
3159 ResultSize = 0;\r
3160\r
3161 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3162 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3163 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3164 switch (PackageType) {\r
3165 case EFI_HII_PACKAGE_TYPE_GUID:\r
3166 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {\r
3167 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);\r
3168 if (CompareGuid (\r
3169 (EFI_GUID *) PackageGuid,\r
3170 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))\r
3171 )) {\r
3172 Matched = TRUE;\r
3173 break;\r
3174 }\r
3175 }\r
3176 break;\r
8d00a0f1 3177 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3178 if (!IsListEmpty (&PackageList->FormPkgHdr)) {\r
3179 Matched = TRUE;\r
3180 }\r
3181 break;\r
3182 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3183 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {\r
3184 Matched = TRUE;\r
3185 }\r
3186 break;\r
3187 case EFI_HII_PACKAGE_STRINGS:\r
3188 if (!IsListEmpty (&PackageList->StringPkgHdr)) {\r
3189 Matched = TRUE;\r
3190 }\r
3191 break;\r
3192 case EFI_HII_PACKAGE_FONTS:\r
3193 if (!IsListEmpty (&PackageList->FontPkgHdr)) {\r
3194 Matched = TRUE;\r
3195 }\r
3196 break;\r
3197 case EFI_HII_PACKAGE_IMAGES:\r
3198 if (PackageList->ImagePkg != NULL) {\r
3199 Matched = TRUE;\r
3200 }\r
3201 break;\r
3202 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3203 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {\r
3204 Matched = TRUE;\r
3205 }\r
3206 break;\r
3207 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3208 if (PackageList->DevicePathPkg != NULL) {\r
3209 Matched = TRUE;\r
3210 }\r
3211 break;\r
3212 //\r
3213 // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles\r
3214 // to be listed.\r
3215 //\r
3216 case EFI_HII_PACKAGE_TYPE_ALL:\r
3217 Matched = TRUE;\r
3218 break;\r
3219 default:\r
3220 break;\r
3221 }\r
3222\r
3223 //\r
3224 // This active package list has the specified package type, list it.\r
3225 //\r
3226 if (Matched) {\r
3227 ResultSize += sizeof (EFI_HII_HANDLE);\r
3228 if (ResultSize <= *HandleBufferLength) {\r
3229 *Result++ = Node->Handle;\r
3230 }\r
3231 }\r
3232 Matched = FALSE;\r
3233 }\r
3234\r
3235 if (ResultSize == 0) {\r
3236 return EFI_NOT_FOUND;\r
3237 }\r
3238\r
3239 if (*HandleBufferLength < ResultSize) {\r
3240 *HandleBufferLength = ResultSize;\r
3241 return EFI_BUFFER_TOO_SMALL;\r
3242 }\r
3243\r
3244 *HandleBufferLength = ResultSize;\r
3245 return EFI_SUCCESS;\r
3246}\r
3247\r
3248\r
3249/**\r
3250 This function will export one or all package lists in the database to a buffer.\r
3251 For each package list exported, this function will call functions registered\r
3252 with EXPORT_PACK and then copy the package list to the buffer.\r
3253\r
3254 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3255 instance.\r
3256 @param Handle An EFI_HII_HANDLE that corresponds to the desired\r
3257 package list in the HII database to export or NULL\r
3258 to indicate all package lists should be exported.\r
3259 @param BufferSize On input, a pointer to the length of the buffer.\r
3260 On output, the length of the buffer that is\r
3261 required for the exported data.\r
3262 @param Buffer A pointer to a buffer that will contain the\r
3263 results of the export function.\r
3264\r
3265 @retval EFI_SUCCESS Package exported.\r
3266 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3267 Handle is too small to support the number of\r
3268 handles. HandleBufferLength is updated with a\r
3269 value that will enable the data to fit.\r
3270 @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the\r
3271 current database.\r
3272 @retval EFI_INVALID_PARAMETER Handle or Buffer or BufferSize was NULL.\r
3273\r
3274**/\r
3275EFI_STATUS\r
3276EFIAPI\r
3277HiiExportPackageLists (\r
3278 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3279 IN EFI_HII_HANDLE Handle,\r
3280 IN OUT UINTN *BufferSize,\r
3281 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
3282 )\r
3283{\r
3284 LIST_ENTRY *Link;\r
3285 EFI_STATUS Status;\r
3286 HII_DATABASE_PRIVATE_DATA *Private;\r
3287 HII_DATABASE_RECORD *Node;\r
3288 UINTN UsedSize;\r
3289\r
3290 if (This == NULL || BufferSize == NULL || Handle == NULL) {\r
3291 return EFI_INVALID_PARAMETER;\r
3292 }\r
3293 if (*BufferSize > 0 && Buffer == NULL) {\r
3294 return EFI_INVALID_PARAMETER;\r
3295 }\r
3296 if (!IsHiiHandleValid (Handle)) {\r
3297 return EFI_NOT_FOUND;\r
3298 }\r
3299\r
3300 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3301 UsedSize = 0;\r
3302\r
3303 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3304 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3305 if (Handle == NULL) {\r
3306 //\r
3307 // Export all package lists in current hii database.\r
3308 //\r
3309 Status = ExportPackageList (\r
3310 Private,\r
3311 Node->Handle,\r
3312 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3313 &UsedSize,\r
3314 *BufferSize,\r
3315 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)\r
3316 );\r
3317 ASSERT_EFI_ERROR (Status);\r
6672d625 3318 } else if (Handle != NULL && Node->Handle == Handle) {\r
93e3992d 3319 Status = ExportPackageList (\r
3320 Private,\r
3321 Handle,\r
3322 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3323 &UsedSize,\r
3324 *BufferSize,\r
3325 Buffer\r
3326 );\r
3327 ASSERT_EFI_ERROR (Status);\r
3328 if (*BufferSize < UsedSize) {\r
3329 *BufferSize = UsedSize;\r
3330 return EFI_BUFFER_TOO_SMALL;\r
3331 }\r
3332 return EFI_SUCCESS;\r
3333 }\r
3334 }\r
3335\r
3336 if (Handle == NULL && UsedSize != 0) {\r
3337 if (*BufferSize < UsedSize) {\r
3338 *BufferSize = UsedSize;\r
3339 return EFI_BUFFER_TOO_SMALL;\r
3340 }\r
3341 return EFI_SUCCESS;\r
3342 }\r
3343\r
3344 return EFI_NOT_FOUND;\r
3345}\r
3346\r
3347\r
3348/**\r
3349 This function registers a function which will be called when specified actions related to packages of\r
3350 the specified type occur in the HII database. By registering a function, other HII-related drivers are\r
3351 notified when specific package types are added, removed or updated in the HII database.\r
3352 Each driver or application which registers a notification should use\r
3353 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.\r
3354\r
3355 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3356 instance.\r
3357 @param PackageType Specifies the package type of the packages to list\r
3358 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3359 listed.\r
3360 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3361 this is the pointer to the GUID which must match\r
3362 the Guid field of\r
3363 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must\r
3364 be NULL.\r
3365 @param PackageNotifyFn Points to the function to be called when the event\r
3366 specified by\r
3367 NotificationType occurs.\r
3368 @param NotifyType Describes the types of notification which this\r
3369 function will be receiving.\r
3370 @param NotifyHandle Points to the unique handle assigned to the\r
3371 registered notification. Can be used in\r
3372 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()\r
3373 to stop notifications.\r
3374\r
3375 @retval EFI_SUCCESS Notification registered successfully.\r
3376 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures\r
3377 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.\r
3378 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not\r
3379 EFI_HII_PACKAGE_TYPE_GUID.\r
3380 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is\r
3381 EFI_HII_PACKAGE_TYPE_GUID.\r
3382\r
3383**/\r
3384EFI_STATUS\r
3385EFIAPI\r
3386HiiRegisterPackageNotify (\r
3387 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3388 IN UINT8 PackageType,\r
3389 IN CONST EFI_GUID *PackageGuid,\r
3390 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,\r
3391 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
3392 OUT EFI_HANDLE *NotifyHandle\r
3393 )\r
3394{\r
3395 HII_DATABASE_PRIVATE_DATA *Private;\r
3396 HII_DATABASE_NOTIFY *Notify;\r
3397 EFI_STATUS Status;\r
3398\r
3399 if (This == NULL || NotifyHandle == NULL) {\r
3400 return EFI_INVALID_PARAMETER;\r
3401 }\r
3402 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3403 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3404 return EFI_INVALID_PARAMETER;\r
3405 }\r
3406\r
3407 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3408\r
3409 //\r
3410 // Allocate a notification node\r
3411 //\r
3412 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));\r
3413 if (Notify == NULL) {\r
3414 return EFI_OUT_OF_RESOURCES;\r
3415 }\r
3416\r
3417 //\r
3418 // Generate a notify handle\r
3419 //\r
3420 Status = gBS->InstallMultipleProtocolInterfaces (\r
3421 &Notify->NotifyHandle,\r
3422 &mHiiDatabaseNotifyGuid,\r
3423 NULL,\r
3424 NULL\r
3425 );\r
3426 ASSERT_EFI_ERROR (Status);\r
3427\r
3428 //\r
3429 // Fill in the information to the notification node\r
3430 //\r
3431 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;\r
3432 Notify->PackageType = PackageType;\r
3433 Notify->PackageGuid = (EFI_GUID *) PackageGuid;\r
3434 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;\r
3435 Notify->NotifyType = NotifyType;\r
3436\r
3437 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);\r
3438 *NotifyHandle = Notify->NotifyHandle;\r
3439\r
3440 return EFI_SUCCESS;\r
3441}\r
3442\r
3443\r
3444/**\r
3445 Removes the specified HII database package-related notification.\r
3446\r
3447 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3448 instance.\r
e90b081a 3449 @param NotificationHandle The handle of the notification function being\r
93e3992d 3450 unregistered.\r
3451\r
3452 @retval EFI_SUCCESS Notification is unregistered successfully.\r
3453 @retval EFI_INVALID_PARAMETER The Handle is invalid.\r
3454 @retval EFI_NOT_FOUND The incoming notification handle does not exist\r
3455 in current hii database.\r
3456\r
3457**/\r
3458EFI_STATUS\r
3459EFIAPI\r
3460HiiUnregisterPackageNotify (\r
3461 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3462 IN EFI_HANDLE NotificationHandle\r
3463 )\r
3464{\r
3465 HII_DATABASE_PRIVATE_DATA *Private;\r
3466 HII_DATABASE_NOTIFY *Notify;\r
3467 LIST_ENTRY *Link;\r
3468 EFI_STATUS Status;\r
3469\r
813acf3a 3470 if (This == NULL) {\r
93e3992d 3471 return EFI_INVALID_PARAMETER;\r
3472 }\r
3473\r
813acf3a 3474 if (NotificationHandle == NULL) {\r
3475 return EFI_NOT_FOUND;\r
3476 }\r
3477\r
93e3992d 3478 Status = gBS->OpenProtocol (\r
3479 NotificationHandle,\r
3480 &mHiiDatabaseNotifyGuid,\r
3481 NULL,\r
3482 NULL,\r
3483 NULL,\r
3484 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
3485 );\r
3486 if (EFI_ERROR (Status)) {\r
813acf3a 3487 return EFI_NOT_FOUND;\r
93e3992d 3488 }\r
3489\r
3490 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3491\r
3492 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {\r
3493 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);\r
3494 if (Notify->NotifyHandle == NotificationHandle) {\r
3495 //\r
3496 // Remove the matching notification node\r
3497 //\r
3498 RemoveEntryList (&Notify->DatabaseNotifyEntry);\r
3499 Status = gBS->UninstallMultipleProtocolInterfaces (\r
3500 Notify->NotifyHandle,\r
3501 &mHiiDatabaseNotifyGuid,\r
3502 NULL,\r
3503 NULL\r
3504 );\r
3505 ASSERT_EFI_ERROR (Status);\r
676df92c 3506 FreePool (Notify);\r
93e3992d 3507\r
3508 return EFI_SUCCESS;\r
3509 }\r
3510 }\r
3511\r
3512 return EFI_NOT_FOUND;\r
3513}\r
3514\r
3515\r
3516/**\r
3517 This routine retrieves an array of GUID values for each keyboard layout that\r
3518 was previously registered in the system.\r
3519\r
3520 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3521 instance.\r
3522 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard\r
3523 GUID buffer. On output, the length of the handle\r
3524 buffer that is required for the handles found.\r
3525 @param KeyGuidBuffer An array of keyboard layout GUID instances\r
3526 returned.\r
3527\r
3528 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.\r
3529 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates\r
3530 that KeyGuidBuffer is too small to support the\r
3531 number of GUIDs. KeyGuidBufferLength is\r
3532 updated with a value that will enable the data to\r
3533 fit.\r
3534 @retval EFI_INVALID_PARAMETER The KeyGuidBuffer or KeyGuidBufferLength was NULL.\r
3535 @retval EFI_NOT_FOUND There was no keyboard layout.\r
3536\r
3537**/\r
3538EFI_STATUS\r
3539EFIAPI\r
3540HiiFindKeyboardLayouts (\r
3541 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3542 IN OUT UINT16 *KeyGuidBufferLength,\r
3543 OUT EFI_GUID *KeyGuidBuffer\r
3544 )\r
3545{\r
3546 HII_DATABASE_PRIVATE_DATA *Private;\r
3547 HII_DATABASE_RECORD *Node;\r
3548 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3549 LIST_ENTRY *Link;\r
3550 LIST_ENTRY *Link1;\r
3551 UINT16 ResultSize;\r
3552 UINTN Index;\r
3553 UINT16 LayoutCount;\r
3554 UINT16 LayoutLength;\r
3555 UINT8 *Layout;\r
3556 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3557\r
3558 if (This == NULL || KeyGuidBufferLength == NULL) {\r
3559 return EFI_INVALID_PARAMETER;\r
3560 }\r
3561\r
3562 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {\r
3563 return EFI_INVALID_PARAMETER;\r
3564 }\r
3565\r
3566 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3567 ResultSize = 0;\r
3568\r
3569 //\r
3570 // Search all package lists in whole database to retrieve keyboard layout.\r
3571 //\r
3572 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3573 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3574 PackageList = Node->PackageList;\r
3575 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3576 Link1 != &PackageList->KeyboardLayoutHdr;\r
3577 Link1 = Link1->ForwardLink\r
3578 ) {\r
3579 //\r
3580 // Find out all Keyboard Layout packages in this package list.\r
3581 //\r
3582 Package = CR (\r
3583 Link1,\r
3584 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3585 KeyboardEntry,\r
3586 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3587 );\r
3588 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3589 CopyMem (\r
3590 &LayoutCount,\r
3591 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
3592 sizeof (UINT16)\r
3593 );\r
3594 for (Index = 0; Index < LayoutCount; Index++) {\r
3595 ResultSize += sizeof (EFI_GUID);\r
3596 if (ResultSize <= *KeyGuidBufferLength) {\r
813acf3a 3597 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));\r
93e3992d 3598 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3599 Layout = Layout + LayoutLength;\r
3600 }\r
3601 }\r
3602 }\r
3603 }\r
3604\r
3605 if (ResultSize == 0) {\r
3606 return EFI_NOT_FOUND;\r
3607 }\r
3608\r
3609 if (*KeyGuidBufferLength < ResultSize) {\r
3610 *KeyGuidBufferLength = ResultSize;\r
3611 return EFI_BUFFER_TOO_SMALL;\r
3612 }\r
3613\r
3614 *KeyGuidBufferLength = ResultSize;\r
3615 return EFI_SUCCESS;\r
3616}\r
3617\r
3618\r
3619/**\r
3620 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys\r
3621 on a keyboard and the character(s) that are associated with a particular set of key strokes.\r
3622\r
3623 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3624 instance.\r
3625 @param KeyGuid A pointer to the unique ID associated with a given\r
3626 keyboard layout. If KeyGuid is NULL then the\r
3627 current layout will be retrieved.\r
3628 @param KeyboardLayoutLength On input, a pointer to the length of the\r
3629 KeyboardLayout buffer. On output, the length of\r
3630 the data placed into KeyboardLayout.\r
3631 @param KeyboardLayout A pointer to a buffer containing the retrieved\r
3632 keyboard layout.\r
3633\r
3634 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.\r
3635 @retval EFI_NOT_FOUND The requested keyboard layout was not found.\r
3636 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was\r
3637 NULL.\r
3638 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates\r
3639 that KeyboardLayout is too small to support the\r
3640 requested keyboard layout. KeyboardLayoutLength is\r
3641 updated with a value that will enable the\r
3642 data to fit.\r
3643\r
3644**/\r
3645EFI_STATUS\r
3646EFIAPI\r
3647HiiGetKeyboardLayout (\r
3648 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3649 IN CONST EFI_GUID *KeyGuid,\r
3650 IN OUT UINT16 *KeyboardLayoutLength,\r
3651 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout\r
3652 )\r
3653{\r
3654 HII_DATABASE_PRIVATE_DATA *Private;\r
3655 HII_DATABASE_RECORD *Node;\r
3656 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3657 LIST_ENTRY *Link;\r
3658 LIST_ENTRY *Link1;\r
3659 UINTN Index;\r
3660 UINT8 *Layout;\r
3661 UINT16 LayoutCount;\r
3662 UINT16 LayoutLength;\r
3663 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3664\r
3665 if (This == NULL || KeyboardLayoutLength == NULL) {\r
3666 return EFI_INVALID_PARAMETER;\r
3667 }\r
3668 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {\r
3669 return EFI_INVALID_PARAMETER;\r
3670 }\r
3671\r
3672 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3673 //\r
3674 // Retrieve the current keyboard layout.\r
3675 //\r
3676 if (KeyGuid == NULL) {\r
3677 if (Private->CurrentLayout == NULL) {\r
3678 return EFI_NOT_FOUND;\r
3679 }\r
3680 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));\r
3681 if (*KeyboardLayoutLength < LayoutLength) {\r
3682 *KeyboardLayoutLength = LayoutLength;\r
3683 return EFI_BUFFER_TOO_SMALL;\r
3684 }\r
3685 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);\r
3686 return EFI_SUCCESS;\r
3687 }\r
3688\r
3689 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3690 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3691 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3692 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3693 Link1 != &PackageList->KeyboardLayoutHdr;\r
3694 Link1 = Link1->ForwardLink\r
3695 ) {\r
3696 Package = CR (\r
3697 Link1,\r
3698 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3699 KeyboardEntry,\r
3700 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3701 );\r
3702\r
3703 Layout = (UINT8 *) Package->KeyboardPkg +\r
3704 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3705 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));\r
3706 for (Index = 0; Index < LayoutCount; Index++) {\r
3707 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3708 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {\r
3709 if (LayoutLength <= *KeyboardLayoutLength) {\r
3710 CopyMem (KeyboardLayout, Layout, LayoutLength);\r
3711 return EFI_SUCCESS;\r
3712 } else {\r
3713 *KeyboardLayoutLength = LayoutLength;\r
3714 return EFI_BUFFER_TOO_SMALL;\r
3715 }\r
3716 }\r
3717 Layout = Layout + LayoutLength;\r
3718 }\r
3719 }\r
3720 }\r
3721\r
3722 return EFI_NOT_FOUND;\r
3723}\r
3724\r
3725\r
3726/**\r
3727 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine\r
3728 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID\r
3729 group type. This is so that agents which are sensitive to the current keyboard layout being changed\r
3730 can be notified of this change.\r
3731\r
3732 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3733 instance.\r
3734 @param KeyGuid A pointer to the unique ID associated with a given\r
3735 keyboard layout.\r
3736\r
3737 @retval EFI_SUCCESS The current keyboard layout was successfully set.\r
3738 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so\r
3739 action was taken.\r
3740 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.\r
3741\r
3742**/\r
3743EFI_STATUS\r
3744EFIAPI\r
3745HiiSetKeyboardLayout (\r
3746 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3747 IN CONST EFI_GUID *KeyGuid\r
3748 )\r
3749{\r
3750 HII_DATABASE_PRIVATE_DATA *Private;\r
3751 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;\r
3752 UINT16 KeyboardLayoutLength;\r
3753 EFI_STATUS Status;\r
3754\r
3755 if (This == NULL || KeyGuid == NULL) {\r
3756 return EFI_INVALID_PARAMETER;\r
3757 }\r
3758\r
3759 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3760\r
3761 //\r
3762 // The specified GUID equals the current keyboard layout GUID,\r
3763 // return directly.\r
3764 //\r
3765 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {\r
3766 return EFI_SUCCESS;\r
3767 }\r
3768\r
3769 //\r
3770 // Try to find the incoming keyboard layout data in current database.\r
3771 //\r
3772 KeyboardLayoutLength = 0;\r
3773 KeyboardLayout = NULL;\r
3774 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3775 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3776 return Status;\r
3777 }\r
3778\r
3779 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);\r
3780 ASSERT (KeyboardLayout != NULL);\r
3781 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3782 ASSERT_EFI_ERROR (Status);\r
3783\r
3784 //\r
3785 // Backup current keyboard layout.\r
3786 //\r
3787 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));\r
676df92c 3788 if (Private->CurrentLayout != NULL) {\r
3789 FreePool(Private->CurrentLayout);\r
3790 }\r
93e3992d 3791 Private->CurrentLayout = KeyboardLayout;\r
3792\r
3793 //\r
3794 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify\r
3795 // current keyboard layout is changed.\r
3796 //\r
3797 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);\r
3798 ASSERT_EFI_ERROR (Status);\r
3799\r
3800 return EFI_SUCCESS;\r
3801}\r
3802\r
3803\r
3804/**\r
3805 Return the EFI handle associated with a package list.\r
3806\r
3807 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3808 instance.\r
3809 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired\r
3810 package list in the HIIdatabase.\r
3811 @param DriverHandle On return, contains the EFI_HANDLE which was\r
3812 registered with the package list in\r
3813 NewPackageList().\r
3814\r
3815 @retval EFI_SUCCESS The DriverHandle was returned successfully.\r
3816 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or\r
3817 DriverHandle was NULL.\r
3818 @retval EFI_NOT_FOUND This PackageList handle can not be found in\r
3819 current database.\r
3820\r
3821**/\r
3822EFI_STATUS\r
3823EFIAPI\r
3824HiiGetPackageListHandle (\r
3825 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3826 IN EFI_HII_HANDLE PackageListHandle,\r
3827 OUT EFI_HANDLE *DriverHandle\r
3828 )\r
3829{\r
3830 HII_DATABASE_PRIVATE_DATA *Private;\r
3831 HII_DATABASE_RECORD *Node;\r
3832 LIST_ENTRY *Link;\r
3833\r
3834 if (This == NULL || DriverHandle == NULL) {\r
3835 return EFI_INVALID_PARAMETER;\r
3836 }\r
3837\r
3838 if (!IsHiiHandleValid (PackageListHandle)) {\r
3839 return EFI_INVALID_PARAMETER;\r
3840 }\r
3841\r
3842 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3843\r
3844 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3845 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3846 if (Node->Handle == PackageListHandle) {\r
3847 *DriverHandle = Node->DriverHandle;\r
3848 return EFI_SUCCESS;\r
3849 }\r
3850 }\r
3851\r
3852 return EFI_NOT_FOUND;\r
3853}\r
3854\r