]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Universal / UserInterface / HiiDataBase / Dxe / Package.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, 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#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
35 \r
36Arguments:\r
37\r
38Returns: \r
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
109 \r
110Arguments:\r
111\r
112Returns: \r
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
225 \r
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
232Returns: \r
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 EFI_WIDE_GLYPH *WideGlyph;\r
268\r
269 if (Packages->NumberOfPackages == 0 || This == NULL) {\r
270 return EFI_INVALID_PARAMETER;\r
271 }\r
272\r
273 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
274\r
275 GlobalData = HiiData->GlobalData;\r
276\r
277 Database = HiiData->DatabaseHead;\r
278\r
279 PackageInstance = NULL;\r
280 IfrPack = NULL;\r
281 StringPack = NULL;\r
282 InstanceSize = 0;\r
283 IfrSize = 0;\r
284 StringSize = 0;\r
285 TotalStringSize = 0;\r
286 NumberOfTokens = 0;\r
287 TotalTokenNumber = 0;\r
288\r
289 //\r
290 // Search through the passed in Packages for the IfrPack and any StringPack.\r
291 //\r
292 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
293\r
294 PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));\r
295\r
296 switch (PackageHeader->Type) {\r
297 case EFI_HII_IFR:\r
298 //\r
299 // There shoule be only one Ifr package.\r
300 //\r
301 ASSERT (IfrPack == NULL);\r
302 IfrPack = (EFI_HII_IFR_PACK *) PackageHeader;\r
303 break;\r
304\r
305 case EFI_HII_STRING:\r
306 StringPack = (EFI_HII_STRING_PACK *) PackageHeader;\r
307 //\r
308 // Sending me a String Package. Get its size.\r
309 //\r
310 Status = GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);\r
311 ASSERT (!EFI_ERROR (Status));\r
312\r
313 //\r
314 // The size which GetPackSize() returns include the null terminator. So if multiple\r
315 // string packages are passed in, merge all these packages, and only pad one null terminator.\r
316 //\r
317 if (TotalStringSize > 0) {\r
318 TotalStringSize -= sizeof (EFI_HII_STRING_PACK);\r
319 }\r
320\r
321 TotalStringSize += StringSize;\r
322 TotalTokenNumber += NumberOfTokens;\r
323 break;\r
324 }\r
325 }\r
326 //\r
327 // If sending a StringPack without an IfrPack, you must include a GuidId\r
328 //\r
329 if ((StringPack != NULL) && (IfrPack == NULL)) {\r
330 if (Packages->GuidId == NULL) {\r
331 return EFI_INVALID_PARAMETER;\r
332 }\r
333 }\r
334 //\r
335 // If passing in an IfrPack and a GuidId is provided, ensure they are the same value.\r
336 //\r
337 if ((IfrPack != NULL) && (Packages->GuidId != NULL)) {\r
338 Location = ((UINT8 *) IfrPack);\r
339 Location = (UINT8 *) (((UINTN) Location) + sizeof (EFI_HII_PACK_HEADER));\r
340\r
341 //\r
342 // Advance to the Form Set Op-code\r
343 //\r
344 for (Count = 0; ((EFI_IFR_OP_HEADER *) &Location[Count])->OpCode != EFI_IFR_FORM_SET_OP;) {\r
345 Count = Count + ((EFI_IFR_OP_HEADER *) &Location[Count])->Length;\r
346 }\r
347 //\r
348 // Copy to local variable\r
349 //\r
350 CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &Location[Count])->Guid, sizeof (EFI_GUID));\r
351\r
352 //\r
353 // Check to see if IfrPack->Guid != GuidId\r
354 //\r
355 if (!CompareGuid (&Guid, Packages->GuidId)) {\r
356 //\r
357 // If a string package is present, the GUIDs should have agreed. Return an error\r
358 //\r
359 if (StringPack != NULL) {\r
360 return EFI_INVALID_PARAMETER;\r
361 }\r
362 }\r
363 }\r
364 //\r
365 // If someone is passing in a string only, create a dummy IfrPack with a Guid\r
366 // to enable future searching of this data.\r
367 //\r
368 if ((IfrPack == NULL) && (StringPack != NULL)) {\r
369 ZeroMem (&FormSetStub, sizeof (FormSetStub));\r
370\r
371 FormSetStub.Header.Type = EFI_HII_IFR;\r
372 FormSetStub.Header.Length = sizeof (EFI_FORM_SET_STUB);\r
373\r
374 FormSetStub.FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;\r
375 FormSetStub.FormSet.Header.Length = (UINT8) sizeof (EFI_IFR_FORM_SET);\r
376 //\r
377 // Dummy string\r
378 //\r
379 FormSetStub.FormSet.FormSetTitle = 0x02;\r
380 CopyMem (&FormSetStub.FormSet.Guid, Packages->GuidId, sizeof (EFI_GUID));\r
381\r
382 FormSetStub.EndFormSet.Header.OpCode = EFI_IFR_END_FORM_SET_OP;\r
383 FormSetStub.EndFormSet.Header.Length = (UINT8) sizeof (EFI_IFR_END_FORM_SET);\r
384 IfrPack = (EFI_HII_IFR_PACK *) &FormSetStub;\r
385 }\r
386\r
387 if (IfrPack != NULL) {\r
388 //\r
389 // Sending me an IFR Package. Get its size.\r
390 //\r
391 Status = GetPackSize ((VOID *) IfrPack, &IfrSize, NULL);\r
392 ASSERT (!EFI_ERROR (Status));\r
393 }\r
394 //\r
395 // Prepare the internal package instace buffer to store package data.\r
396 //\r
397 InstanceSize = IfrSize + TotalStringSize;\r
398\r
399 if (InstanceSize != 0) {\r
400 PackageInstance = AllocateZeroPool (InstanceSize + sizeof (EFI_HII_PACKAGE_INSTANCE));\r
401\r
402 ASSERT (PackageInstance);\r
403\r
404 //\r
405 // If there is no DatabaseHead allocated - allocate one\r
406 //\r
407 if (HiiData->DatabaseHead == NULL) {\r
408 HiiData->DatabaseHead = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));\r
409 ASSERT (HiiData->DatabaseHead);\r
410 }\r
411 //\r
412 // If the head is being used (Handle is non-zero), allocate next Database and\r
413 // add it to the linked-list\r
414 //\r
415 if (HiiData->DatabaseHead->Handle != 0) {\r
416 HandleDatabase = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));\r
417\r
418 ASSERT (HandleDatabase);\r
419\r
420 for (; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase)\r
421 ;\r
422\r
423 //\r
424 // We are sitting on the Database entry which contains the null Next pointer. Fix it.\r
425 //\r
426 Database->NextHandleDatabase = HandleDatabase;\r
427\r
428 }\r
429\r
430 Database = HiiData->DatabaseHead;\r
431\r
432 //\r
433 // Initialize this instance data\r
434 //\r
435 for (*Handle = 1; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase) {\r
436 //\r
437 // Since the first Database instance will have a passed back handle of 1, we will continue\r
438 // down the linked list of entries until we encounter the end of the linked list. Each time\r
439 // we go down one level deeper, increment the handle value that will be passed back.\r
440 //\r
441 if (Database->Handle >= *Handle) {\r
442 *Handle = Database->Handle + 1;\r
443 }\r
444 }\r
445\r
446 PackageInstance->Handle = *Handle;\r
447 PackageInstance->IfrSize = IfrSize;\r
448 PackageInstance->StringSize = TotalStringSize;\r
449 if (Packages->GuidId != NULL) {\r
450 CopyMem (&PackageInstance->Guid, Packages->GuidId, sizeof (EFI_GUID));\r
451 }\r
452\r
453 Database->Buffer = PackageInstance;\r
454 Database->Handle = PackageInstance->Handle;\r
455 Database->NumberOfTokens = TotalTokenNumber;\r
456 Database->NextHandleDatabase = NULL;\r
457 }\r
458 //\r
459 // Copy the Ifr package data into package instance.\r
460 //\r
461 if (IfrSize > 0) {\r
462 CopyMem (&PackageInstance->IfrData, IfrPack, IfrSize);\r
463 }\r
464 //\r
465 // Main loop to store package data into HII database.\r
466 //\r
467 StringSize = 0;\r
468 TotalStringSize = 0;\r
469\r
470 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
471\r
472 PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));\r
473\r
474 switch (PackageHeader->Type) {\r
475 case EFI_HII_STRING:\r
476 StringPack = (EFI_HII_STRING_PACK *) PackageHeader;\r
477 //\r
478 // The size which GetPackSize() returns include the null terminator. So if multiple\r
479 // string packages are passed in, merge all these packages, and only pad one null terminator.\r
480 //\r
481 if (TotalStringSize > 0) {\r
482 TotalStringSize -= sizeof (EFI_HII_STRING_PACK);\r
483 }\r
484\r
485 GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);\r
486 CopyMem ((CHAR8 *) (&PackageInstance->IfrData) + IfrSize + TotalStringSize, StringPack, StringSize);\r
487\r
488 TotalStringSize += StringSize;\r
489 break;\r
490\r
491 case EFI_HII_HANDLES:\r
492 CopyMem (&PackageInstance->HandlePack, PackageHeader, sizeof (EFI_HII_HANDLE_PACK));\r
493 break;\r
494\r
495 case EFI_HII_FONT:\r
496 FontPack = (EFI_HII_FONT_PACK *) PackageHeader;\r
497 //\r
498 // Add whatever narrow glyphs were passed to us if undefined\r
499 //\r
500 CopyMem (&NumNarrowGlyphs, &FontPack->NumberOfNarrowGlyphs, sizeof (UINT16));\r
501 for (Count = 0; Count <= NumNarrowGlyphs; Count++) {\r
502 Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) + (sizeof (EFI_NARROW_GLYPH)) * Count;\r
503 NarrowGlyph = (EFI_NARROW_GLYPH *) Local;\r
504 CopyMem (&Member, &NarrowGlyph->UnicodeWeight, sizeof (UINT16));\r
505 //\r
506 // If the glyph is already defined, do not overwrite it. It is what it is.\r
507 //\r
508 CopyMem (&Unicode, &GlobalData->NarrowGlyphs[Member].UnicodeWeight, sizeof (UINT16));\r
509 if (Unicode == 0) {\r
510 CopyMem (&GlobalData->NarrowGlyphs[Member], Local, sizeof (EFI_NARROW_GLYPH));\r
511 }\r
512 }\r
513 //\r
514 // Add whatever wide glyphs were passed to us if undefined\r
515 //\r
516 CopyMem (&NumWideGlyphs, &FontPack->NumberOfWideGlyphs, sizeof (UINT16));\r
517 for (Count = 0; Count <= NumWideGlyphs; Count++) {\r
518 Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) +\r
519 (sizeof (EFI_NARROW_GLYPH)) *\r
520 NumNarrowGlyphs;\r
521 WideGlyph = (EFI_WIDE_GLYPH *) Local;\r
522 CopyMem (\r
523 &Member,\r
524 (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),\r
525 sizeof (UINT16)\r
526 );\r
527 //\r
528 // If the glyph is already defined, do not overwrite it. It is what it is.\r
529 //\r
530 CopyMem (&Unicode, &GlobalData->WideGlyphs[Member].UnicodeWeight, sizeof (UINT16));\r
531 if (Unicode == 0) {\r
532 Local = (UINT8*)(&FontPack->NumberOfWideGlyphs + sizeof(UINT8)) + (sizeof(EFI_NARROW_GLYPH)) * NumNarrowGlyphs;\r
533 WideGlyph = (EFI_WIDE_GLYPH *) Local;\r
534 CopyMem (\r
535 &GlobalData->WideGlyphs[Member],\r
536 (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),\r
537 sizeof (EFI_WIDE_GLYPH)\r
538 );\r
539 }\r
540 }\r
541 break;\r
542\r
543 case EFI_HII_KEYBOARD:\r
544 KeyboardPack = (EFI_HII_KEYBOARD_PACK *) PackageHeader;\r
545 //\r
546 // Sending me a Keyboard Package\r
547 //\r
548 if (KeyboardPack->DescriptorCount > 105) {\r
549 return EFI_INVALID_PARAMETER;\r
550 }\r
551 //\r
552 // If someone updates the Descriptors with a count of 0, blow aware the overrides.\r
553 //\r
554 if (KeyboardPack->DescriptorCount == 0) {\r
555 ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
556 }\r
557\r
558 if (KeyboardPack->DescriptorCount < 106 && KeyboardPack->DescriptorCount > 0) {\r
559 //\r
560 // If SystemKeyboard was updated already, then steer changes to the override database\r
561 //\r
562 if (GlobalData->SystemKeyboardUpdate) {\r
563 ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
564 for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {\r
565 CopyMem (&Member, &KeyboardPack->Descriptor[Count].Key, sizeof (UINT16));\r
566 CopyMem (\r
567 &GlobalData->OverrideKeyboardLayout[Member],\r
568 &KeyboardPack->Descriptor[Count],\r
569 sizeof (EFI_KEY_DESCRIPTOR)\r
570 );\r
571 }\r
572 } else {\r
573 //\r
574 // SystemKeyboard was never updated, so this is likely the keyboard driver setting the System database.\r
575 //\r
576 ZeroMem (GlobalData->SystemKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
577 for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {\r
578 CopyMem (&Member, &KeyboardPack->Descriptor->Key, sizeof (UINT16));\r
579 CopyMem (\r
580 &GlobalData->SystemKeyboardLayout[Member],\r
581 &KeyboardPack->Descriptor[Count],\r
582 sizeof (EFI_KEY_DESCRIPTOR)\r
583 );\r
584 }\r
585 //\r
586 // Just updated the system keyboard database, reflect that in the global flag.\r
587 //\r
588 GlobalData->SystemKeyboardUpdate = TRUE;\r
589 }\r
590 }\r
591 break;\r
592\r
593 default:\r
594 break;\r
595 }\r
596 }\r
597\r
598 return EFI_SUCCESS;\r
599}\r
600\r
601EFI_STATUS\r
602EFIAPI\r
603HiiRemovePack (\r
604 IN EFI_HII_PROTOCOL *This,\r
605 IN EFI_HII_HANDLE Handle\r
606 )\r
607/*++\r
608\r
609Routine Description:\r
610 Removes the various packs from a Handle\r
611 \r
612Arguments:\r
613\r
614Returns: \r
615\r
616--*/\r
617{\r
618 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
619 EFI_HII_DATA *HiiData;\r
620 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
621 EFI_HII_HANDLE_DATABASE *PreviousHandleDatabase;\r
622 UINTN Count;\r
623\r
624 if (This == NULL || Handle == 0) {\r
625 return EFI_INVALID_PARAMETER;\r
626 }\r
627\r
628 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
629\r
630 HandleDatabase = HiiData->DatabaseHead;\r
631 PackageInstance = NULL;\r
632\r
633 //\r
634 // Initialize the Previous with the Head of the Database\r
635 //\r
636 PreviousHandleDatabase = HandleDatabase;\r
637\r
638 for (Count = 0; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
639 //\r
640 // Match the numeric value with the database entry - if matched,\r
641 // free the package instance and apply fix-up to database linked list\r
642 //\r
643 if (Handle == HandleDatabase->Handle) {\r
644 PackageInstance = HandleDatabase->Buffer;\r
645\r
646 //\r
647 // Free the Package Instance\r
648 //\r
649 gBS->FreePool (PackageInstance);\r
650\r
651 //\r
652 // If this was the only Handle in the database\r
653 //\r
654 if (HiiData->DatabaseHead == HandleDatabase) {\r
655 HiiData->DatabaseHead = NULL;\r
656 }\r
657 //\r
658 // Make the parent->Next point to the current->Next\r
659 //\r
660 PreviousHandleDatabase->NextHandleDatabase = HandleDatabase->NextHandleDatabase;\r
661 gBS->FreePool (HandleDatabase);\r
662 return EFI_SUCCESS;\r
663 }\r
664 //\r
665 // If this was not the HandleDatabase entry we were looking for, cache it just in case the next one is\r
666 //\r
667 PreviousHandleDatabase = HandleDatabase;\r
668 }\r
669 //\r
670 // No handle was found - error condition\r
671 //\r
672 if (PackageInstance == NULL) {\r
673 return EFI_INVALID_PARAMETER;\r
674 }\r
675\r
676 return EFI_SUCCESS;\r
677}\r