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