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