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