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