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