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