]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.c
edk2/MdePkg/Library/BaseLib/BaseLib.inf:
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Utility.c
CommitLineData
4259256b 1/**@file\r
2\r
3 This file contains the keyboard processing code to the HII database.\r
4\r
5Copyright (c) 2006 - 2008, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16\r
17#include "HiiDatabase.h"\r
d4775f2a 18#include "HiiHandle.h"\r
4259256b 19\r
0368663f 20EFI_GUID gFrameworkHiiCompatbilityGuid = EFI_IFR_FRAMEWORK_GUID;\r
21EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
22\r
23\r
4259256b 24EFI_GUID *\r
25GetGuidOfFirstFormset (\r
26 CONST EFI_HII_FORM_PACKAGE * FormPackage\r
27) \r
28{\r
0368663f 29 UINT8 *StartOfNextPackage;\r
30 EFI_IFR_OP_HEADER *OpCodeData;\r
4259256b 31\r
32 StartOfNextPackage = (UINT8 *) FormPackage + FormPackage->Header.Length;\r
33 OpCodeData = (EFI_IFR_OP_HEADER *) (FormPackage + 1);\r
34\r
35 while ((UINT8 *) OpCodeData < StartOfNextPackage) {\r
36 if (OpCodeData->OpCode == EFI_IFR_FORM_SET_OP) {\r
3711f8f8 37 return AllocateCopyPool (sizeof(EFI_GUID), &(((EFI_IFR_FORM_SET *) OpCodeData)->Guid));\r
4259256b 38 }\r
39 OpCodeData = (EFI_IFR_OP_HEADER *) ((UINT8 *) OpCodeData + OpCodeData->Length);\r
40 }\r
41\r
42 ASSERT (FALSE);\r
43\r
44 return NULL;\r
45}\r
46\r
ee3428bb 47EFI_HII_HANDLE\r
0368663f 48FwHiiHandleToUefiHiiHandle (\r
49 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
50 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
ee3428bb 51 )\r
52{\r
0368663f 53 HII_THUNK_CONTEXT *ThunkContext;\r
ee3428bb 54\r
0368663f 55 ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
ee3428bb 56 ASSERT (Private != NULL);\r
57\r
0368663f 58 ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);\r
ee3428bb 59\r
0368663f 60 if (ThunkContext != NULL) {\r
61 return ThunkContext->UefiHiiHandle;\r
ee3428bb 62 }\r
63 \r
64 return (EFI_HII_HANDLE) NULL;\r
65}\r
66\r
ebbd2793 67\r
0368663f 68HII_THUNK_CONTEXT *\r
69FwHiiHandleToThunkContext (\r
70 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
71 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
ebbd2793 72 )\r
73{\r
0368663f 74 LIST_ENTRY *Link;\r
75 HII_THUNK_CONTEXT *ThunkContext;\r
76\r
ebbd2793 77\r
0368663f 78 Link = GetFirstNode (&Private->ThunkContextListHead);\r
ebbd2793 79\r
0368663f 80 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
81 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
82\r
83 if (FwHiiHandle == ThunkContext->FwHiiHandle) {\r
84 return ThunkContext;\r
ebbd2793 85 }\r
0368663f 86\r
87 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
ebbd2793 88 }\r
89\r
0368663f 90 return NULL;\r
ebbd2793 91}\r
92\r
0368663f 93HII_THUNK_CONTEXT *\r
94UefiHiiHandleToThunkContext (\r
95 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
ea58467b 96 IN EFI_HII_HANDLE UefiHiiHandle\r
97 )\r
98{\r
0368663f 99 LIST_ENTRY *Link;\r
100 HII_THUNK_CONTEXT *ThunkContext;\r
ea58467b 101\r
0368663f 102 Link = GetFirstNode (&Private->ThunkContextListHead);\r
ea58467b 103\r
0368663f 104 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
105 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
106\r
107 if (UefiHiiHandle == ThunkContext->UefiHiiHandle) {\r
108 return ThunkContext;\r
ea58467b 109 }\r
0368663f 110 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
ea58467b 111 }\r
112\r
0368663f 113 return NULL;\r
ea58467b 114}\r
99a83b4c 115\r
116EFI_HII_HANDLE *\r
0368663f 117TagGuidToUefiHiiHandle (\r
118 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
99a83b4c 119 IN CONST EFI_GUID *Guid\r
120 )\r
121{\r
0368663f 122 LIST_ENTRY *Link;\r
123 HII_THUNK_CONTEXT *ThunkContext;\r
124\r
125 Link = GetFirstNode (&Private->ThunkContextListHead);\r
99a83b4c 126\r
0368663f 127 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
128 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
99a83b4c 129\r
0368663f 130 if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {\r
131 return ThunkContext->UefiHiiHandle;\r
99a83b4c 132 }\r
0368663f 133\r
134 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
99a83b4c 135 }\r
136\r
0368663f 137 return NULL;\r
99a83b4c 138 \r
139}\r
140\r
0368663f 141\r
d4775f2a 142VOID\r
0368663f 143DestroyThunkContextForUefiHiiHandle (\r
144 IN HII_THUNK_PRIVATE_DATA *Private,\r
145 IN EFI_HII_HANDLE UefiHiiHandle\r
146 )\r
147{\r
148 HII_THUNK_CONTEXT *ThunkContext;\r
149\r
150 ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);\r
151 ASSERT (ThunkContext != NULL);\r
152\r
d4775f2a 153 DestroyThunkContext (ThunkContext);\r
0368663f 154}\r
155\r
156\r
157/**\r
158 This function create a HII_THUNK_CONTEXT for a package list registered\r
159 by a module calling EFI_HII_DATABASE_PROTOCOL.NewPackageList. It records\r
160 the PackageListGuid in EFI_HII_PACKAGE_LIST_HEADER in the TagGuid in \r
161 HII_THUNK_CONTEXT created. This TagGuid will be used as a key to s\r
162\r
163**/\r
164HII_THUNK_CONTEXT *\r
165CreateThunkContextForUefiHiiHandle (\r
0368663f 166 IN EFI_HII_HANDLE UefiHiiHandle\r
167 )\r
168{\r
169 EFI_STATUS Status;\r
170 EFI_GUID PackageGuid;\r
171 HII_THUNK_CONTEXT *ThunkContext;\r
172\r
173 ThunkContext = AllocateZeroPool (sizeof (*ThunkContext));\r
174 ASSERT (ThunkContext != NULL);\r
175 \r
176 ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
177\r
d4775f2a 178 Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
0368663f 179 if (EFI_ERROR (Status)) {\r
180 return NULL;\r
181 }\r
182 \r
183 ThunkContext->UefiHiiHandle = UefiHiiHandle;\r
184 \r
185 Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);\r
186 ASSERT_EFI_ERROR (Status);\r
187 \r
188 CopyGuid(&ThunkContext->TagGuid, &PackageGuid);\r
189\r
190 InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
191 InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
192 \r
0368663f 193 return ThunkContext;\r
194}\r
195\r
196\r
197UINTN\r
198GetPackageCountByType (\r
199 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,\r
200 IN UINT8 PackageType\r
ea58467b 201 )\r
202{\r
0368663f 203 UINTN Count;\r
204 EFI_HII_PACKAGE_HEADER *PackageHeader;\r
205\r
206 PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageListHeader + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
207 Count = 0;\r
208 \r
209 while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
210 if (PackageHeader->Type == PackageType ) {\r
211 Count++;\r
212 }\r
213 PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
214 }\r
215 \r
216 \r
217 return Count;\r
218}\r
219\r
220LIST_ENTRY *\r
221GetOneOfOptionMapEntryListHead (\r
222 IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
223 IN UINT16 QuestionId\r
224 )\r
225{\r
226 LIST_ENTRY *Link;\r
227 ONE_OF_OPTION_MAP *Map;\r
228\r
229 Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);\r
230\r
231 while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) {\r
232 Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
233 if (QuestionId == Map->QuestionId) {\r
234 return &Map->OneOfOptionMapEntryListHead;\r
235 }\r
236 Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);\r
237 }\r
238 \r
239 return NULL;\r
240}\r
99a83b4c 241\r
242\r
0368663f 243EFI_STATUS\r
244CreateQuestionIdMap (\r
245 IN OUT HII_THUNK_CONTEXT *ThunkContext\r
246 )\r
247{\r
248 EFI_STATUS Status;\r
249 EFI_HII_PACKAGE_LIST_HEADER *List;\r
250 EFI_HII_PACKAGE_HEADER *Package;\r
251 UINTN Size;\r
252 EFI_IFR_OP_HEADER *OpCode;\r
253 UINTN Offset;\r
254 QUESTION_ID_MAP *IdMap;\r
255 EFI_IFR_VARSTORE *VarStore;\r
256 EFI_IFR_FORM_SET *FormSet;\r
257 EFI_IFR_QUESTION_HEADER *Question;\r
258 LIST_ENTRY *QuestionIdMapEntryListHead;\r
259 LIST_ENTRY *OneOfOptinMapEntryListHead;\r
260 QUESTION_ID_MAP_ENTRY *IdMapEntry;\r
261 EFI_IFR_GUID_OPTIONKEY *OptionMap;\r
262 ONE_OF_OPTION_MAP *OneOfOptionMap;\r
263 ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
264 EFI_IFR_GUID_CLASS *Class;\r
265 \r
266\r
267 Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);\r
268 if (EFI_ERROR (Status)) {\r
269 return Status;\r
ea58467b 270 }\r
99a83b4c 271\r
0368663f 272 //\r
273 // Get all VarStoreId and build the the QuestionId map.\r
274 // EFI_IFR_QUESTION_HEADER.VarStoreInfo.VarOffset -> Framework Question ID\r
275 // EFI_IFR_QUESTION_HEADER.QuestionId -> UEFI Question ID\r
276 //\r
277\r
278 //\r
279 // Skip the package list header.\r
280 //\r
281 Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);\r
282\r
283 while (Package->Type != EFI_HII_PACKAGE_END) {\r
284\r
285 if (Package->Type == EFI_HII_PACKAGE_FORM) {\r
286\r
287 //\r
288 // Skip the package header\r
289 //\r
290 Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
291 while (Offset < Package->Length) {\r
292 OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
293\r
294 switch (OpCode->OpCode) {\r
295 case EFI_IFR_FORM_SET_OP:\r
296 FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
297 ThunkContext->FormSetTitle = FormSet->FormSetTitle;\r
298 ThunkContext->FormSetHelp = FormSet->Help;\r
299 break;\r
300 \r
301 case EFI_IFR_VARSTORE_OP:\r
302 //\r
303 // IFR built from Framework VFR only has UEFI Buffer Type Storage\r
304 //\r
305 VarStore = (EFI_IFR_VARSTORE *) OpCode;\r
306 IdMap = AllocateZeroPool (sizeof (QUESTION_ID_MAP));\r
307 ASSERT (IdMap != NULL);\r
308 \r
309 IdMap->Signature = QUESTION_ID_MAP_SIGNATURE;\r
310 IdMap->VarStoreId = VarStore->VarStoreId;\r
311 IdMap->VarSize = VarStore->Size;\r
312 InitializeListHead (&IdMap->MapEntryListHead);\r
313 InsertTailList (&ThunkContext->QuestionIdMapListHead, &IdMap->Link);\r
314 break;\r
315\r
316 case EFI_IFR_NUMERIC_OP:\r
317 case EFI_IFR_CHECKBOX_OP:\r
318 case EFI_IFR_ONE_OF_OP:\r
319 case EFI_IFR_ORDERED_LIST_OP:\r
320 case EFI_IFR_STRING_OP:\r
321 //case EFI_IFR_PASSWORD_OP:\r
322 Question = (EFI_IFR_QUESTION_HEADER *)(OpCode + 1);\r
323 QuestionIdMapEntryListHead = GetMapEntryListHead (ThunkContext, Question->VarStoreId);\r
324\r
325 if (QuestionIdMapEntryListHead != NULL) {\r
326 //\r
327 // If the Question is using Buffer (EFI_IFR_VARSTORE_OP) type VarStore.\r
328 //\r
329 IdMapEntry = AllocateZeroPool (sizeof (QUESTION_ID_MAP_ENTRY));\r
330 ASSERT (IdMapEntry != NULL);\r
331\r
332 IdMapEntry->FwQId = Question->VarStoreInfo.VarOffset;\r
333 IdMapEntry->UefiQid = Question->QuestionId;\r
334 IdMapEntry->Signature = QUESTION_ID_MAP_ENTRY_SIGNATURE;\r
335\r
336 InsertTailList (QuestionIdMapEntryListHead, &IdMapEntry->Link);\r
337 }\r
338\r
339 break;\r
340 \r
341 case EFI_IFR_GUID_OP:\r
342 OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCode;\r
343 if (CompareGuid (&OptionMap->Guid, &gFrameworkHiiCompatbilityGuid)) {\r
344 if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {\r
345 OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (ThunkContext, OptionMap->QuestionId);\r
346 if (OneOfOptinMapEntryListHead == NULL) {\r
347 OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));\r
348 ASSERT (OneOfOptionMap != NULL);\r
349\r
350 OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;\r
351 OneOfOptionMap->QuestionId = OptionMap->QuestionId;\r
352 OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_8;\r
353 InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
354 OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;\r
355 InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);\r
356 }\r
357 OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));\r
358 ASSERT (OneOfOptionMapEntry != NULL);\r
359\r
360 OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;\r
361 OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;\r
362 CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));\r
363 \r
364 InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);\r
365 }\r
366 }else if (CompareGuid (&OptionMap->Guid, &gTianoHiiIfrGuid)) {\r
367 Class = (EFI_IFR_GUID_CLASS *) OpCode;\r
368\r
369 switch (Class->ExtendOpCode) {\r
370 case EFI_IFR_EXTEND_OP_CLASS:\r
371 ThunkContext->FormSetClass = Class->Class;\r
372 break;\r
373 case EFI_IFR_EXTEND_OP_SUBCLASS:\r
374 ThunkContext->FormSetSubClass = ((EFI_IFR_GUID_SUBCLASS *) Class)->SubClass;\r
375 break;\r
376\r
377 default:\r
378 break;\r
379 }\r
380 }\r
381 break;\r
382 \r
383 default:\r
384 break;\r
385 \r
386 }\r
387\r
388 Offset += OpCode->Length;\r
389 }\r
390 //\r
391 // Only Form Package is in a Package List.\r
392 //\r
393 break;\r
394 }\r
395\r
396 Package = (EFI_HII_PACKAGE_HEADER *) (UINT8 *) Package + Package->Length;\r
397 }\r
398\r
399 FreePool (List);\r
ea58467b 400 return EFI_SUCCESS;\r
401}\r
99a83b4c 402\r
0368663f 403\r
404LIST_ENTRY *\r
405GetMapEntryListHead (\r
406 IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
407 IN UINT16 VarStoreId\r
408 )\r
409{\r
410 LIST_ENTRY *Link;\r
411 QUESTION_ID_MAP *Map;\r
412\r
413 Link = GetFirstNode (&ThunkContext->QuestionIdMapListHead);\r
414\r
415 while (!IsNull (&ThunkContext->QuestionIdMapListHead, Link)) {\r
416 Map = QUESTION_ID_MAP_FROM_LINK (Link);\r
417 if (VarStoreId == Map->VarStoreId) {\r
418 return &Map->MapEntryListHead;\r
419 }\r
420 Link = GetNextNode (&ThunkContext->QuestionIdMapListHead, Link);\r
421 }\r
422 return NULL;\r
423}\r
424\r
425\r
d4775f2a 426HII_THUNK_CONTEXT *\r
427CreateThunkContext (\r
428 IN HII_THUNK_PRIVATE_DATA *Private,\r
429 IN UINTN StringPackageCount,\r
430 IN UINTN IfrPackageCount\r
431 )\r
432{\r
433 EFI_STATUS Status;\r
434 HII_THUNK_CONTEXT *ThunkContext;\r
435\r
436 ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));\r
437 ASSERT (ThunkContext != NULL);\r
438 \r
439 ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
440 ThunkContext->IfrPackageCount = IfrPackageCount;\r
441 ThunkContext->StringPackageCount = StringPackageCount;\r
442 Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
443 if (EFI_ERROR (Status)) {\r
444 return NULL;\r
445 }\r
446\r
447 InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
448 InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
449\r
450\r
451 return ThunkContext;\r
452 \r
453}\r
454\r
455VOID\r
456DestroyThunkContext (\r
457 IN HII_THUNK_CONTEXT *ThunkContext\r
458 )\r
459{\r
460 ASSERT (ThunkContext != NULL);\r
461\r
462 FreeHiiHandle (ThunkContext->FwHiiHandle);\r
463\r
464 DestroyQuestionIdMap (&ThunkContext->QuestionIdMapListHead);\r
465\r
466 DestoryOneOfOptionMap (&ThunkContext->OneOfOptionMapListHead);\r
467\r
468 RemoveEntryList (&ThunkContext->Link);\r
469\r
470 FreePool (ThunkContext);\r
471}\r
472\r
473\r
474VOID\r
475DestroyQuestionIdMap (\r
476 IN LIST_ENTRY *QuestionIdMapListHead\r
477 )\r
478{\r
479 QUESTION_ID_MAP *IdMap;\r
480 QUESTION_ID_MAP_ENTRY *IdMapEntry;\r
481 LIST_ENTRY *Link;\r
482 LIST_ENTRY *Link2;\r
483\r
484 while (!IsListEmpty (QuestionIdMapListHead)) {\r
485 Link = GetFirstNode (QuestionIdMapListHead);\r
486 \r
487 IdMap = QUESTION_ID_MAP_FROM_LINK (Link);\r
488\r
489 while (!IsListEmpty (&IdMap->MapEntryListHead)) {\r
490 Link2 = GetFirstNode (&IdMap->MapEntryListHead);\r
491 \r
492 IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);\r
493\r
494 RemoveEntryList (Link2);\r
495\r
496 FreePool (IdMapEntry);\r
497 }\r
498\r
499 RemoveEntryList (Link);\r
500 FreePool (IdMap);\r
501 }\r
502}\r
503\r
504VOID\r
505DestoryOneOfOptionMap (\r
506 IN LIST_ENTRY *OneOfOptionMapListHead\r
507 )\r
508{\r
509 ONE_OF_OPTION_MAP *Map;\r
510 ONE_OF_OPTION_MAP_ENTRY *MapEntry;\r
511 LIST_ENTRY *Link;\r
512 LIST_ENTRY *Link2;\r
513\r
514 while (!IsListEmpty (OneOfOptionMapListHead)) {\r
515 Link = GetFirstNode (OneOfOptionMapListHead);\r
516 \r
517 Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
518\r
519 while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {\r
520 Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);\r
521 \r
522 MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link);\r
523\r
524 RemoveEntryList (Link2);\r
525\r
526 FreePool (MapEntry);\r
527 }\r
528\r
529 RemoveEntryList (Link);\r
530 FreePool (Map);\r
531 }\r
532}\r
533\r
534\r
535\r
536\r