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