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