]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Package.c
Modules cleanup.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / HiiDataBaseDxe / Package.c
CommitLineData
103b6520 1/*++\r
2\r
ececc2eb 3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
103b6520 7http://opensource.org/licenses/bsd-license.php \r
ececc2eb 8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
103b6520 11\r
12Module Name:\r
13\r
14 Package.c\r
15\r
16Abstract:\r
17\r
18 This file contains the package processing code to the HII database.\r
19\r
20--*/\r
21\r
22\r
103b6520 23#include "HiiDatabase.h"\r
24\r
25EFI_STATUS\r
26GetPackSize (\r
27 IN VOID *Pack,\r
28 OUT UINTN *PackSize,\r
29 OUT UINT32 *NumberOfTokens\r
30 )\r
31/*++\r
32\r
33Routine Description:\r
34 Determines the passed in Pack's size and returns the value.\r
ececc2eb 35\r
103b6520 36Arguments:\r
37\r
ececc2eb 38Returns:\r
103b6520 39\r
40--*/\r
41{\r
42 EFI_HII_STRING_PACK *StringPack;\r
43 UINT16 Type;\r
44 UINT32 Length;\r
45\r
46 *PackSize = 0;\r
47\r
48 Type = EFI_HII_IFR;\r
49 if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {\r
50 //\r
51 // The header contains the full IFR length\r
52 //\r
53 CopyMem (&Length, &((EFI_HII_PACK_HEADER *) Pack)->Length, sizeof (Length));\r
54 *PackSize = (UINTN) Length;\r
55 return EFI_SUCCESS;\r
56 }\r
57\r
58 Type = EFI_HII_STRING;\r
59 if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {\r
60 //\r
61 // The header contains the STRING package length\r
62 // The assumption is that the strings for all languages\r
63 // are a contiguous block of data and there is a series of\r
64 // these package instances which will terminate with a NULL package\r
65 // instance.\r
66 //\r
67 StringPack = (EFI_HII_STRING_PACK *) Pack;\r
68\r
69 //\r
70 // There may be multiple instances packed together of strings\r
71 // so we must walk the self describing structures until we encounter\r
72 // the NULL structure to determine the full size.\r
73 //\r
74 CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));\r
75 if (NumberOfTokens != NULL) {\r
76 CopyMem (NumberOfTokens, &StringPack->NumStringPointers, sizeof (UINT32));\r
77 }\r
78\r
79 while (Length != 0) {\r
80 *PackSize = *PackSize + Length;\r
81 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) StringPack + Length);\r
82 CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));\r
83 }\r
84 //\r
85 // Encountered a length of 0, so let's add the space for the NULL terminator\r
86 // pack's length and call it done.\r
87 //\r
88 *PackSize = *PackSize + sizeof (EFI_HII_STRING_PACK);\r
89 return EFI_SUCCESS;\r
90 }\r
91 //\r
92 // We only determine the size of the non-global Package types.\r
93 // If neither IFR or STRING data were found, return an error\r
94 //\r
95 return EFI_NOT_FOUND;\r
96}\r
97\r
98EFI_STATUS\r
99ValidatePack (\r
100 IN EFI_HII_PROTOCOL *This,\r
101 IN EFI_HII_PACKAGE_INSTANCE *PackageInstance,\r
102 OUT EFI_HII_PACKAGE_INSTANCE **StringPackageInstance,\r
103 OUT UINT32 *TotalStringCount\r
104 )\r
105/*++\r
106\r
107Routine Description:\r
108 Verifies that the package instance is using the correct handle for string operations.\r
ececc2eb 109\r
103b6520 110Arguments:\r
111\r
ececc2eb 112Returns:\r
103b6520 113\r
114--*/\r
115{\r
116 EFI_HII_DATA *HiiData;\r
117 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
118 EFI_HII_PACKAGE_INSTANCE *HandlePackageInstance;\r
119 UINT8 *RawData;\r
120 EFI_GUID Guid;\r
121 EFI_HII_IFR_PACK *FormPack;\r
122 UINTN Index;\r
123\r
124 if (This == NULL) {\r
125 return EFI_INVALID_PARAMETER;\r
126 }\r
127\r
128 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
129\r
130 HandleDatabase = HiiData->DatabaseHead;\r
131 ZeroMem (&Guid, sizeof (EFI_GUID));\r
132\r
133 *StringPackageInstance = PackageInstance;\r
134\r
135 //\r
136 // Based on if there is IFR data in this package instance, determine\r
137 // what the location is of the beginning of the string data.\r
138 //\r
139 if (PackageInstance->IfrSize > 0) {\r
140 FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
141 } else {\r
142 //\r
143 // If there is no IFR data assume the caller knows what they are doing.\r
144 //\r
145 return EFI_SUCCESS;\r
146 }\r
147\r
148 RawData = (UINT8 *) FormPack;\r
149\r
150 for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
151 if (RawData[Index] == EFI_IFR_FORM_SET_OP) {\r
152 //\r
153 // Cache the guid for this formset\r
154 //\r
155 CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));\r
156 break;\r
157 }\r
158\r
159 Index = RawData[Index + 1] + Index;\r
160 }\r
161 //\r
162 // If there is no string package, and the PackageInstance->IfrPack.Guid and PackageInstance->Guid are\r
163 // different, we should return the correct handle for the caller to use for strings.\r
164 //\r
165 if ((PackageInstance->StringSize == 0) && (!CompareGuid (&Guid, &PackageInstance->Guid))) {\r
166 //\r
167 // Search the database for a handle that matches the PackageInstance->Guid\r
168 //\r
169 for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
170 //\r
171 // Get Ifrdata and extract the Guid for it\r
172 //\r
173 HandlePackageInstance = HandleDatabase->Buffer;\r
174\r
175 ASSERT (HandlePackageInstance->IfrSize != 0);\r
176\r
177 FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&HandlePackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
178 RawData = (UINT8 *) FormPack;\r
179\r
180 for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
181 if (RawData[Index] == EFI_IFR_FORM_SET_OP) {\r
182 //\r
183 // Cache the guid for this formset\r
184 //\r
185 CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));\r
186 break;\r
187 }\r
188\r
189 Index = RawData[Index + 1] + Index;\r
190 }\r
191 //\r
192 // If the Guid from the new handle matches the original Guid referenced in the original package data\r
193 // return the appropriate package instance data to use.\r
194 //\r
195 if (CompareGuid (&Guid, &PackageInstance->Guid)) {\r
196 if (TotalStringCount != NULL) {\r
197 *TotalStringCount = HandleDatabase->NumberOfTokens;\r
198 }\r
199\r
200 *StringPackageInstance = HandlePackageInstance;\r
201 }\r
202 }\r
203 //\r
204 // end for\r
205 //\r
206 } else {\r
207 return EFI_SUCCESS;\r
208 }\r
209\r
210 return EFI_SUCCESS;\r
211}\r
212\r
213EFI_STATUS\r
214EFIAPI\r
215HiiNewPack (\r
216 IN EFI_HII_PROTOCOL *This,\r
217 IN EFI_HII_PACKAGES *Packages,\r
218 OUT EFI_HII_HANDLE *Handle\r
219 )\r
220/*++\r
221\r
222Routine Description:\r
223\r
224 Extracts the various packs from a package list.\r
ececc2eb 225\r
103b6520 226Arguments:\r
227\r
228 This - Pointer of HII protocol.\r
229 Packages - Pointer of HII packages.\r
230 Handle - Handle value to be returned.\r
231\r
ececc2eb 232Returns:\r
103b6520 233\r
234 EFI_SUCCESS - Pacakges has added to HII database successfully.\r
235 EFI_INVALID_PARAMETER - Invalid parameter.\r
236\r
237--*/\r
238{\r
239 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
240 EFI_HII_DATA *HiiData;\r
241 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
242 EFI_HII_HANDLE_DATABASE *Database;\r
243 EFI_HII_PACK_HEADER *PackageHeader;\r
244 EFI_HII_GLOBAL_DATA *GlobalData;\r
245 EFI_HII_IFR_PACK *IfrPack;\r
246 EFI_HII_STRING_PACK *StringPack;\r
247 EFI_HII_FONT_PACK *FontPack;\r
248 EFI_HII_KEYBOARD_PACK *KeyboardPack;\r
249 EFI_STATUS Status;\r
250 UINTN IfrSize;\r
251 UINTN StringSize;\r
252 UINTN TotalStringSize;\r
253 UINTN InstanceSize;\r
254 UINTN Count;\r
255 UINTN Index;\r
256 UINT16 Member;\r
257 EFI_GUID Guid;\r
258 EFI_FORM_SET_STUB FormSetStub;\r
259 UINT8 *Location;\r
260 UINT16 Unicode;\r
261 UINT16 NumWideGlyphs;\r
262 UINT16 NumNarrowGlyphs;\r
263 UINT32 NumberOfTokens;\r
264 UINT32 TotalTokenNumber;\r
265 UINT8 *Local;\r
266 EFI_NARROW_GLYPH *NarrowGlyph;\r
267\r
268 if (Packages->NumberOfPackages == 0 || This == NULL) {\r
269 return EFI_INVALID_PARAMETER;\r
270 }\r
271\r
272 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
273\r
274 GlobalData = HiiData->GlobalData;\r
275\r
276 Database = HiiData->DatabaseHead;\r
277\r
278 PackageInstance = NULL;\r
279 IfrPack = NULL;\r
280 StringPack = NULL;\r
281 InstanceSize = 0;\r
282 IfrSize = 0;\r
283 StringSize = 0;\r
284 TotalStringSize = 0;\r
285 NumberOfTokens = 0;\r
286 TotalTokenNumber = 0;\r
287\r
288 //\r
289 // Search through the passed in Packages for the IfrPack and any StringPack.\r
290 //\r
291 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
292\r
293 PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));\r
294\r
295 switch (PackageHeader->Type) {\r
296 case EFI_HII_IFR:\r
297 //\r
298 // There shoule be only one Ifr package.\r
299 //\r
300 ASSERT (IfrPack == NULL);\r
301 IfrPack = (EFI_HII_IFR_PACK *) PackageHeader;\r
302 break;\r
303\r
304 case EFI_HII_STRING:\r
305 StringPack = (EFI_HII_STRING_PACK *) PackageHeader;\r
306 //\r
307 // Sending me a String Package. Get its size.\r
308 //\r
309 Status = GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);\r
310 ASSERT (!EFI_ERROR (Status));\r
311\r
312 //\r
313 // The size which GetPackSize() returns include the null terminator. So if multiple\r
314 // string packages are passed in, merge all these packages, and only pad one null terminator.\r
315 //\r
316 if (TotalStringSize > 0) {\r
317 TotalStringSize -= sizeof (EFI_HII_STRING_PACK);\r
318 }\r
319\r
320 TotalStringSize += StringSize;\r
321 TotalTokenNumber += NumberOfTokens;\r
322 break;\r
323 }\r
324 }\r
325 //\r
326 // If sending a StringPack without an IfrPack, you must include a GuidId\r
327 //\r
328 if ((StringPack != NULL) && (IfrPack == NULL)) {\r
329 if (Packages->GuidId == NULL) {\r
330 return EFI_INVALID_PARAMETER;\r
331 }\r
332 }\r
333 //\r
334 // If passing in an IfrPack and a GuidId is provided, ensure they are the same value.\r
335 //\r
336 if ((IfrPack != NULL) && (Packages->GuidId != NULL)) {\r
337 Location = ((UINT8 *) IfrPack);\r
338 Location = (UINT8 *) (((UINTN) Location) + sizeof (EFI_HII_PACK_HEADER));\r
339\r
340 //\r
341 // Advance to the Form Set Op-code\r
342 //\r
343 for (Count = 0; ((EFI_IFR_OP_HEADER *) &Location[Count])->OpCode != EFI_IFR_FORM_SET_OP;) {\r
344 Count = Count + ((EFI_IFR_OP_HEADER *) &Location[Count])->Length;\r
345 }\r
346 //\r
347 // Copy to local variable\r
348 //\r
349 CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &Location[Count])->Guid, sizeof (EFI_GUID));\r
350\r
351 //\r
352 // Check to see if IfrPack->Guid != GuidId\r
353 //\r
354 if (!CompareGuid (&Guid, Packages->GuidId)) {\r
355 //\r
356 // If a string package is present, the GUIDs should have agreed. Return an error\r
357 //\r
358 if (StringPack != NULL) {\r
359 return EFI_INVALID_PARAMETER;\r
360 }\r
361 }\r
362 }\r
363 //\r
364 // If someone is passing in a string only, create a dummy IfrPack with a Guid\r
365 // to enable future searching of this data.\r
366 //\r
367 if ((IfrPack == NULL) && (StringPack != NULL)) {\r
368 ZeroMem (&FormSetStub, sizeof (FormSetStub));\r
369\r
370 FormSetStub.Header.Type = EFI_HII_IFR;\r
371 FormSetStub.Header.Length = sizeof (EFI_FORM_SET_STUB);\r
372\r
373 FormSetStub.FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;\r
374 FormSetStub.FormSet.Header.Length = (UINT8) sizeof (EFI_IFR_FORM_SET);\r
375 //\r
376 // Dummy string\r
377 //\r
378 FormSetStub.FormSet.FormSetTitle = 0x02;\r
379 CopyMem (&FormSetStub.FormSet.Guid, Packages->GuidId, sizeof (EFI_GUID));\r
380\r
381 FormSetStub.EndFormSet.Header.OpCode = EFI_IFR_END_FORM_SET_OP;\r
382 FormSetStub.EndFormSet.Header.Length = (UINT8) sizeof (EFI_IFR_END_FORM_SET);\r
383 IfrPack = (EFI_HII_IFR_PACK *) &FormSetStub;\r
384 }\r
385\r
386 if (IfrPack != NULL) {\r
387 //\r
388 // Sending me an IFR Package. Get its size.\r
389 //\r
390 Status = GetPackSize ((VOID *) IfrPack, &IfrSize, NULL);\r
391 ASSERT (!EFI_ERROR (Status));\r
392 }\r
393 //\r
394 // Prepare the internal package instace buffer to store package data.\r
395 //\r
396 InstanceSize = IfrSize + TotalStringSize;\r
397\r
398 if (InstanceSize != 0) {\r
399 PackageInstance = AllocateZeroPool (InstanceSize + sizeof (EFI_HII_PACKAGE_INSTANCE));\r
400\r
401 ASSERT (PackageInstance);\r
402\r
403 //\r
404 // If there is no DatabaseHead allocated - allocate one\r
405 //\r
406 if (HiiData->DatabaseHead == NULL) {\r
407 HiiData->DatabaseHead = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));\r
408 ASSERT (HiiData->DatabaseHead);\r
409 }\r
410 //\r
411 // If the head is being used (Handle is non-zero), allocate next Database and\r
412 // add it to the linked-list\r
413 //\r
414 if (HiiData->DatabaseHead->Handle != 0) {\r
415 HandleDatabase = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));\r
416\r
417 ASSERT (HandleDatabase);\r
418\r
419 for (; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase)\r
420 ;\r
421\r
422 //\r
423 // We are sitting on the Database entry which contains the null Next pointer. Fix it.\r
424 //\r
425 Database->NextHandleDatabase = HandleDatabase;\r
426\r
427 }\r
428\r
429 Database = HiiData->DatabaseHead;\r
430\r
431 //\r
432 // Initialize this instance data\r
433 //\r
434 for (*Handle = 1; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase) {\r
435 //\r
436 // Since the first Database instance will have a passed back handle of 1, we will continue\r
437 // down the linked list of entries until we encounter the end of the linked list. Each time\r
438 // we go down one level deeper, increment the handle value that will be passed back.\r
439 //\r
440 if (Database->Handle >= *Handle) {\r
441 *Handle = (EFI_HII_HANDLE) (Database->Handle + 1);\r
442 }\r
443 }\r
444\r
445 PackageInstance->Handle = *Handle;\r
446 PackageInstance->IfrSize = IfrSize;\r
447 PackageInstance->StringSize = TotalStringSize;\r
448 if (Packages->GuidId != NULL) {\r
449 CopyMem (&PackageInstance->Guid, Packages->GuidId, sizeof (EFI_GUID));\r
450 }\r
451\r
452 Database->Buffer = PackageInstance;\r
453 Database->Handle = PackageInstance->Handle;\r
454 Database->NumberOfTokens = TotalTokenNumber;\r
455 Database->NextHandleDatabase = NULL;\r
456 }\r
457 //\r
458 // Copy the Ifr package data into package instance.\r
459 //\r
460 if (IfrSize > 0) {\r
461 CopyMem (&PackageInstance->IfrData, IfrPack, IfrSize);\r
462 }\r
463 //\r
464 // Main loop to store package data into HII database.\r
465 //\r
466 StringSize = 0;\r
467 TotalStringSize = 0;\r
468\r
469 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
470\r
471 PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));\r
472\r
473 switch (PackageHeader->Type) {\r
474 case EFI_HII_STRING:\r
475 StringPack = (EFI_HII_STRING_PACK *) PackageHeader;\r
476 //\r
477 // The size which GetPackSize() returns include the null terminator. So if multiple\r
478 // string packages are passed in, merge all these packages, and only pad one null terminator.\r
479 //\r
480 if (TotalStringSize > 0) {\r
481 TotalStringSize -= sizeof (EFI_HII_STRING_PACK);\r
482 }\r
483\r
484 GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);\r
485 CopyMem ((CHAR8 *) (&PackageInstance->IfrData) + IfrSize + TotalStringSize, StringPack, StringSize);\r
486\r
487 TotalStringSize += StringSize;\r
488 break;\r
489\r
490 case EFI_HII_HANDLES:\r
491 CopyMem (&PackageInstance->HandlePack, PackageHeader, sizeof (EFI_HII_HANDLE_PACK));\r
492 break;\r
493\r
494 case EFI_HII_FONT:\r
495 FontPack = (EFI_HII_FONT_PACK *) PackageHeader;\r
496 //\r
497 // Add whatever narrow glyphs were passed to us if undefined\r
498 //\r
499 CopyMem (&NumNarrowGlyphs, &FontPack->NumberOfNarrowGlyphs, sizeof (UINT16));\r
500 for (Count = 0; Count <= NumNarrowGlyphs; Count++) {\r
501 Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) + (sizeof (EFI_NARROW_GLYPH)) * Count;\r
502 NarrowGlyph = (EFI_NARROW_GLYPH *) Local;\r
503 CopyMem (&Member, &NarrowGlyph->UnicodeWeight, sizeof (UINT16));\r
504 //\r
505 // If the glyph is already defined, do not overwrite it. It is what it is.\r
506 //\r
507 CopyMem (&Unicode, &GlobalData->NarrowGlyphs[Member].UnicodeWeight, sizeof (UINT16));\r
508 if (Unicode == 0) {\r
509 CopyMem (&GlobalData->NarrowGlyphs[Member], Local, sizeof (EFI_NARROW_GLYPH));\r
510 }\r
511 }\r
512 //\r
513 // Add whatever wide glyphs were passed to us if undefined\r
514 //\r
515 CopyMem (&NumWideGlyphs, &FontPack->NumberOfWideGlyphs, sizeof (UINT16));\r
516 for (Count = 0; Count <= NumWideGlyphs; Count++) {\r
517 Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) +\r
518 (sizeof (EFI_NARROW_GLYPH)) *\r
519 NumNarrowGlyphs;\r
520 CopyMem (\r
521 &Member,\r
522 (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),\r
523 sizeof (UINT16)\r
524 );\r
525 //\r
526 // If the glyph is already defined, do not overwrite it. It is what it is.\r
527 //\r
528 CopyMem (&Unicode, &GlobalData->WideGlyphs[Member].UnicodeWeight, sizeof (UINT16));\r
529 if (Unicode == 0) {\r
530 Local = (UINT8*)(&FontPack->NumberOfWideGlyphs + sizeof(UINT8)) + (sizeof(EFI_NARROW_GLYPH)) * NumNarrowGlyphs;\r
531 CopyMem (\r
532 &GlobalData->WideGlyphs[Member],\r
533 (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),\r
534 sizeof (EFI_WIDE_GLYPH)\r
535 );\r
536 }\r
537 }\r
538 break;\r
539\r
540 case EFI_HII_KEYBOARD:\r
541 KeyboardPack = (EFI_HII_KEYBOARD_PACK *) PackageHeader;\r
542 //\r
543 // Sending me a Keyboard Package\r
544 //\r
545 if (KeyboardPack->DescriptorCount > 105) {\r
546 return EFI_INVALID_PARAMETER;\r
547 }\r
548 //\r
549 // If someone updates the Descriptors with a count of 0, blow aware the overrides.\r
550 //\r
551 if (KeyboardPack->DescriptorCount == 0) {\r
552 ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
553 }\r
554\r
555 if (KeyboardPack->DescriptorCount < 106 && KeyboardPack->DescriptorCount > 0) {\r
556 //\r
557 // If SystemKeyboard was updated already, then steer changes to the override database\r
558 //\r
559 if (GlobalData->SystemKeyboardUpdate) {\r
560 ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
561 for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {\r
562 CopyMem (&Member, &KeyboardPack->Descriptor[Count].Key, sizeof (UINT16));\r
563 CopyMem (\r
564 &GlobalData->OverrideKeyboardLayout[Member],\r
565 &KeyboardPack->Descriptor[Count],\r
566 sizeof (EFI_KEY_DESCRIPTOR)\r
567 );\r
568 }\r
569 } else {\r
570 //\r
571 // SystemKeyboard was never updated, so this is likely the keyboard driver setting the System database.\r
572 //\r
573 ZeroMem (GlobalData->SystemKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
574 for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {\r
575 CopyMem (&Member, &KeyboardPack->Descriptor->Key, sizeof (UINT16));\r
576 CopyMem (\r
577 &GlobalData->SystemKeyboardLayout[Member],\r
578 &KeyboardPack->Descriptor[Count],\r
579 sizeof (EFI_KEY_DESCRIPTOR)\r
580 );\r
581 }\r
582 //\r
583 // Just updated the system keyboard database, reflect that in the global flag.\r
584 //\r
585 GlobalData->SystemKeyboardUpdate = TRUE;\r
586 }\r
587 }\r
588 break;\r
589\r
590 default:\r
591 break;\r
592 }\r
593 }\r
594\r
595 return EFI_SUCCESS;\r
596}\r
597\r
598EFI_STATUS\r
599EFIAPI\r
600HiiRemovePack (\r
601 IN EFI_HII_PROTOCOL *This,\r
602 IN EFI_HII_HANDLE Handle\r
603 )\r
604/*++\r
605\r
606Routine Description:\r
607 Removes the various packs from a Handle\r
ececc2eb 608\r
103b6520 609Arguments:\r
610\r
ececc2eb 611Returns:\r
103b6520 612\r
613--*/\r
614{\r
615 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
616 EFI_HII_DATA *HiiData;\r
617 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
618 EFI_HII_HANDLE_DATABASE *PreviousHandleDatabase;\r
619\r
620 if (This == NULL || Handle == 0) {\r
621 return EFI_INVALID_PARAMETER;\r
622 }\r
623\r
624 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
625\r
626 HandleDatabase = HiiData->DatabaseHead;\r
627 PackageInstance = NULL;\r
628\r
629 //\r
630 // Initialize the Previous with the Head of the Database\r
631 //\r
632 PreviousHandleDatabase = HandleDatabase;\r
633\r
634 for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
635 //\r
636 // Match the numeric value with the database entry - if matched,\r
637 // free the package instance and apply fix-up to database linked list\r
638 //\r
639 if (Handle == HandleDatabase->Handle) {\r
640 PackageInstance = HandleDatabase->Buffer;\r
641\r
642 //\r
643 // Free the Package Instance\r
644 //\r
645 FreePool (PackageInstance);\r
646\r
647 //\r
648 // If this was the only Handle in the database\r
649 //\r
650 if (HiiData->DatabaseHead == HandleDatabase) {\r
651 HiiData->DatabaseHead = NULL;\r
652 }\r
653 //\r
654 // Make the parent->Next point to the current->Next\r
655 //\r
656 PreviousHandleDatabase->NextHandleDatabase = HandleDatabase->NextHandleDatabase;\r
657 FreePool (HandleDatabase);\r
658 return EFI_SUCCESS;\r
659 }\r
660 //\r
661 // If this was not the HandleDatabase entry we were looking for, cache it just in case the next one is\r
662 //\r
663 PreviousHandleDatabase = HandleDatabase;\r
664 }\r
665 //\r
666 // No handle was found - error condition\r
667 //\r
668 if (PackageInstance == NULL) {\r
669 return EFI_INVALID_PARAMETER;\r
670 }\r
671\r
672 return EFI_SUCCESS;\r
673}\r