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