]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c
Update the title Network Configuration to IPv4 Network Configuration since IPv6 UI...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / VlanConfigDxe / VlanConfigImpl.c
CommitLineData
779ae357 1/** @file\r
2 HII Config Access protocol implementation of VLAN configuration module.\r
3\r
e2851998 4Copyright (c) 2009 - 2010, Intel Corporation.<BR>\r
779ae357 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions\r
7of the BSD License which accompanies this distribution. The full\r
8text of the license may be found at<BR>\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#include "VlanConfigImpl.h"\r
17\r
18EFI_GUID mVlanFormSetGuid = VLAN_CONFIG_PRIVATE_GUID;\r
19CHAR16 mVlanStorageName[] = L"VlanNvData";\r
20EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting = NULL;\r
21\r
22VLAN_CONFIG_PRIVATE_DATA mVlanConfigPrivateDateTemplate = {\r
23 VLAN_CONFIG_PRIVATE_DATA_SIGNATURE,\r
24 {\r
25 VlanExtractConfig,\r
26 VlanRouteConfig,\r
27 VlanCallback\r
28 }\r
29};\r
30\r
31VENDOR_DEVICE_PATH mHiiVendorDevicePathNode = {\r
32 {\r
33 HARDWARE_DEVICE_PATH,\r
34 HW_VENDOR_DP,\r
35 {\r
36 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
37 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
38 }\r
39 },\r
40 VLAN_CONFIG_PRIVATE_GUID\r
41};\r
42\r
43/**\r
44 This function allows a caller to extract the current configuration for one\r
45 or more named elements from the target driver.\r
46\r
47 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
48 @param[in] Request A null-terminated Unicode string in\r
49 <ConfigRequest> format.\r
50 @param[out] Progress On return, points to a character in the Request\r
51 string. Points to the string's null terminator if\r
52 request was successful. Points to the most recent\r
53 '&' before the first failing name/value pair (or\r
54 the beginning of the string if the failure is in\r
55 the first name/value pair) if the request was not\r
56 successful.\r
57 @param[out] Results A null-terminated Unicode string in\r
58 <ConfigAltResp> format which has all values filled\r
59 in for the names in the Request string. String to\r
60 be allocated by the called function.\r
61\r
62 @retval EFI_SUCCESS The Results is filled with the requested values.\r
63 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
64 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
65 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
66 driver.\r
67\r
68**/\r
69EFI_STATUS\r
70EFIAPI\r
71VlanExtractConfig (\r
72 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
73 IN CONST EFI_STRING Request,\r
74 OUT EFI_STRING *Progress,\r
75 OUT EFI_STRING *Results\r
76 )\r
77{\r
59aefb7e
LG
78 EFI_STATUS Status;\r
79 UINTN BufferSize;\r
80 VLAN_CONFIGURATION Configuration;\r
81 VLAN_CONFIG_PRIVATE_DATA *PrivateData;\r
82 EFI_STRING ConfigRequestHdr;\r
83 EFI_STRING ConfigRequest;\r
84 BOOLEAN AllocatedRequest;\r
85 UINTN Size;\r
86\r
87 if (Progress == NULL || Results == NULL) {\r
779ae357 88 return EFI_INVALID_PARAMETER;\r
89 }\r
90\r
59aefb7e
LG
91 *Progress = Request;\r
92 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mVlanFormSetGuid, mVlanStorageName)) {\r
93 return EFI_NOT_FOUND;\r
94 }\r
95\r
96 ConfigRequestHdr = NULL;\r
97 ConfigRequest = NULL;\r
98 AllocatedRequest = FALSE;\r
99 Size = 0;\r
100\r
779ae357 101 //\r
102 // Retrieve the pointer to the UEFI HII Config Routing Protocol\r
103 //\r
104 if (mHiiConfigRouting == NULL) {\r
105 gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mHiiConfigRouting);\r
106 }\r
107 ASSERT (mHiiConfigRouting != NULL);\r
108\r
109 //\r
110 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
111 //\r
59aefb7e 112 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);\r
779ae357 113 ZeroMem (&Configuration, sizeof (VLAN_CONFIGURATION));\r
114 BufferSize = sizeof (VLAN_CONFIG_PRIVATE_DATA);\r
59aefb7e
LG
115 ConfigRequest = Request;\r
116 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
117 //\r
118 // Request has no request element, construct full request string.\r
119 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
120 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
121 //\r
122 ConfigRequestHdr = HiiConstructConfigHdr (&mVlanFormSetGuid, mVlanStorageName, PrivateData->DriverHandle);\r
123 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
124 ConfigRequest = AllocateZeroPool (Size);\r
125 ASSERT (ConfigRequest != NULL);\r
126 AllocatedRequest = TRUE;\r
127 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
128 FreePool (ConfigRequestHdr);\r
129 }\r
130\r
779ae357 131 Status = mHiiConfigRouting->BlockToConfig (\r
132 mHiiConfigRouting,\r
59aefb7e 133 ConfigRequest,\r
779ae357 134 (UINT8 *) &Configuration,\r
135 BufferSize,\r
136 Results,\r
137 Progress\r
138 );\r
59aefb7e
LG
139 //\r
140 // Free the allocated config request string.\r
141 //\r
142 if (AllocatedRequest) {\r
143 FreePool (ConfigRequest);\r
144 ConfigRequest = NULL;\r
145 }\r
146 //\r
147 // Set Progress string to the original request string.\r
148 //\r
149 if (Request == NULL) {\r
150 *Progress = NULL;\r
151 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
152 *Progress = Request + StrLen (Request);\r
153 }\r
154\r
779ae357 155 return Status;\r
156}\r
157\r
158\r
159/**\r
160 This function processes the results of changes in configuration.\r
161\r
162 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
163 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
164 format.\r
165 @param[out] Progress A pointer to a string filled in with the offset of\r
166 the most recent '&' before the first failing\r
167 name/value pair (or the beginning of the string if\r
168 the failure is in the first name/value pair) or\r
169 the terminating NULL if all was successful.\r
170\r
171 @retval EFI_SUCCESS The Results is processed successfully.\r
172 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
173 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
174 driver.\r
175\r
176**/\r
177EFI_STATUS\r
178EFIAPI\r
179VlanRouteConfig (\r
180 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
181 IN CONST EFI_STRING Configuration,\r
182 OUT EFI_STRING *Progress\r
183 )\r
184{\r
185 if (Configuration == NULL || Progress == NULL) {\r
186 return EFI_INVALID_PARAMETER;\r
187 }\r
188\r
189 *Progress = Configuration;\r
190 if (!HiiIsConfigHdrMatch (Configuration, &mVlanFormSetGuid, mVlanStorageName)) {\r
191 return EFI_NOT_FOUND;\r
192 }\r
193\r
194 *Progress = Configuration + StrLen (Configuration);\r
195 return EFI_SUCCESS;\r
196}\r
197\r
198/**\r
199 This function processes the results of changes in configuration.\r
200\r
201 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
202 @param[in] Action Specifies the type of action taken by the browser.\r
203 @param[in] QuestionId A unique value which is sent to the original\r
204 exporting driver so that it can identify the type\r
205 of data to expect.\r
206 @param[in] Type The type of value for the question.\r
207 @param[in] Value A pointer to the data being sent to the original\r
208 exporting driver.\r
209 @param[out] ActionRequest On return, points to the action requested by the\r
210 callback function.\r
211\r
212 @retval EFI_SUCCESS The callback successfully handled the action.\r
213 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
214 variable and its data.\r
215 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
216 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
217 callback.\r
218\r
219**/\r
220EFI_STATUS\r
221EFIAPI\r
222VlanCallback (\r
223 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
224 IN EFI_BROWSER_ACTION Action,\r
225 IN EFI_QUESTION_ID QuestionId,\r
226 IN UINT8 Type,\r
227 IN EFI_IFR_TYPE_VALUE *Value,\r
228 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
229 )\r
230{\r
231 VLAN_CONFIG_PRIVATE_DATA *PrivateData;\r
232 VLAN_CONFIGURATION *Configuration;\r
233 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;\r
234 UINTN Index;\r
235 EFI_HANDLE VlanHandle;\r
236\r
237 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);\r
238\r
239 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
240 //\r
241 // On FORM_OPEN event, update current VLAN list\r
242 //\r
243 VlanUpdateForm (PrivateData);\r
244\r
245 return EFI_SUCCESS;\r
246 }\r
247\r
248 //\r
249 // Get Browser data\r
250 //\r
251 Configuration = AllocateZeroPool (sizeof (VLAN_CONFIGURATION));\r
252 ASSERT (Configuration != NULL);\r
253 HiiGetBrowserData (&mVlanFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration);\r
254\r
255 VlanConfig = PrivateData->VlanConfig;\r
256\r
257 switch (QuestionId) {\r
258 case VLAN_ADD_QUESTION_ID:\r
259 //\r
260 // Add a VLAN\r
261 //\r
262 VlanConfig->Set (VlanConfig, Configuration->VlanId, Configuration->Priority);\r
263 VlanUpdateForm (PrivateData);\r
264\r
265 //\r
266 // Connect the newly created VLAN device\r
267 //\r
268 VlanHandle = NetLibGetVlanHandle (PrivateData->ControllerHandle, Configuration->VlanId);\r
269 if (VlanHandle == NULL) {\r
270 //\r
271 // There may be no child handle created for VLAN ID 0, connect the parent handle\r
272 //\r
273 VlanHandle = PrivateData->ControllerHandle;\r
274 }\r
275 gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);\r
276\r
277 //\r
278 // Clear UI data\r
279 //\r
280 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
281 Configuration->VlanId = 0;\r
282 Configuration->Priority = 0;\r
283 break;\r
284\r
285 case VLAN_REMOVE_QUESTION_ID:\r
286 //\r
287 // Remove VLAN\r
288 //\r
e2851998 289 ASSERT (PrivateData->NumberOfVlan <= MAX_VLAN_NUMBER);\r
779ae357 290 for (Index = 0; Index < PrivateData->NumberOfVlan; Index++) {\r
291 if (Configuration->VlanList[Index] != 0) {\r
292 //\r
293 // Checkbox is selected, need remove this VLAN\r
294 //\r
295 VlanConfig->Remove (VlanConfig, PrivateData->VlanId[Index]);\r
296 }\r
297 }\r
298\r
299 VlanUpdateForm (PrivateData);\r
300 if (PrivateData->NumberOfVlan == 0) {\r
301 //\r
302 // No VLAN device now, connect the physical NIC handle.\r
303 // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm()\r
304 //\r
305 gBS->ConnectController (PrivateData->ControllerHandle, NULL, NULL, TRUE);\r
306 }\r
307\r
308 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
309 ZeroMem (Configuration->VlanList, MAX_VLAN_NUMBER);\r
310 break;\r
311\r
312 default:\r
313 break;\r
314 }\r
315\r
316 HiiSetBrowserData (&mVlanFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration, NULL);\r
317 FreePool (Configuration);\r
318 return EFI_SUCCESS;\r
319}\r
320\r
321\r
322/**\r
323 This function update VLAN list in the VLAN configuration Form.\r
324\r
325 @param[in, out] PrivateData Points to VLAN configuration private data.\r
326\r
327**/\r
328VOID\r
329VlanUpdateForm (\r
330 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData\r
331 )\r
332{\r
333 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;\r
334 UINT16 NumberOfVlan;\r
335 UINTN Index;\r
336 EFI_VLAN_FIND_DATA *VlanData;\r
337 VOID *StartOpCodeHandle;\r
338 EFI_IFR_GUID_LABEL *StartLabel;\r
339 VOID *EndOpCodeHandle;\r
340 EFI_IFR_GUID_LABEL *EndLabel;\r
341 CHAR16 *String;\r
342 CHAR16 VlanStr[30];\r
343 CHAR16 VlanIdStr[6];\r
344 UINTN DigitalCount;\r
345 EFI_STRING_ID StringId;\r
346\r
347 //\r
348 // Find current VLAN configuration\r
349 //\r
350 VlanData = NULL;\r
351 NumberOfVlan = 0;\r
352 VlanConfig = PrivateData->VlanConfig;\r
353 VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);\r
354\r
355 //\r
356 // Update VLAN configuration in PrivateData\r
357 //\r
358 if (NumberOfVlan > MAX_VLAN_NUMBER) {\r
359 NumberOfVlan = MAX_VLAN_NUMBER;\r
360 }\r
361 PrivateData->NumberOfVlan = NumberOfVlan;\r
362\r
363 //\r
364 // Init OpCode Handle\r
365 //\r
366 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
367 ASSERT (StartOpCodeHandle != NULL);\r
368\r
369 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
370 ASSERT (EndOpCodeHandle != NULL);\r
371\r
372 //\r
373 // Create Hii Extend Label OpCode as the start opcode\r
374 //\r
375 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
376 StartOpCodeHandle,\r
377 &gEfiIfrTianoGuid,\r
378 NULL,\r
379 sizeof (EFI_IFR_GUID_LABEL)\r
380 );\r
381 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
382 StartLabel->Number = LABEL_VLAN_LIST;\r
383\r
384 //\r
385 // Create Hii Extend Label OpCode as the end opcode\r
386 //\r
387 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
388 EndOpCodeHandle,\r
389 &gEfiIfrTianoGuid,\r
390 NULL,\r
391 sizeof (EFI_IFR_GUID_LABEL)\r
392 );\r
393 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
394 EndLabel->Number = LABEL_END;\r
395\r
396 ZeroMem (PrivateData->VlanId, MAX_VLAN_NUMBER);\r
397 for (Index = 0; Index < NumberOfVlan; Index++) {\r
398 String = VlanStr;\r
399\r
400 StrCpy (String, L" VLAN ID:");\r
401 String += 10;\r
402 //\r
403 // Pad VlanId string up to 4 characters with space\r
404 //\r
405 DigitalCount = UnicodeValueToString (VlanIdStr, 0, VlanData[Index].VlanId, 5);\r
406 SetMem16 (String, (4 - DigitalCount) * sizeof (CHAR16), L' ');\r
407 StrCpy (String + 4 - DigitalCount, VlanIdStr);\r
408 String += 4;\r
409\r
410 StrCpy (String, L", Priority:");\r
411 String += 11;\r
412 String += UnicodeValueToString (String, 0, VlanData[Index].Priority, 4);\r
413 *String = 0;\r
414\r
415 StringId = HiiSetString (PrivateData->HiiHandle, 0, VlanStr, NULL);\r
416 ASSERT (StringId != 0);\r
417\r
418 HiiCreateCheckBoxOpCode (\r
419 StartOpCodeHandle,\r
420 (EFI_QUESTION_ID) (VLAN_LIST_VAR_OFFSET + Index),\r
421 VLAN_CONFIGURATION_VARSTORE_ID,\r
422 (UINT16) (VLAN_LIST_VAR_OFFSET + Index),\r
423 StringId,\r
424 STRING_TOKEN (STR_VLAN_VLAN_LIST_HELP),\r
425 0,\r
426 0,\r
427 NULL\r
428 );\r
429\r
430 //\r
431 // Save VLAN id to private data\r
432 //\r
433 PrivateData->VlanId[Index] = VlanData[Index].VlanId;\r
434 }\r
435\r
436 HiiUpdateForm (\r
437 PrivateData->HiiHandle, // HII handle\r
438 &mVlanFormSetGuid, // Formset GUID\r
439 VLAN_CONFIGURATION_FORM_ID, // Form ID\r
440 StartOpCodeHandle, // Label for where to insert opcodes\r
441 EndOpCodeHandle // Replace data\r
442 );\r
443\r
444 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
445 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
446\r
447 if (VlanData != NULL) {\r
448 FreePool (VlanData);\r
449 }\r
450}\r
451\r
452\r
453/**\r
454 This function publish the VLAN configuration Form for a network device. The\r
455 HII Config Access protocol will be installed on a child handle of the network\r
456 device.\r
457\r
458 @param[in, out] PrivateData Points to VLAN configuration private data.\r
459\r
460 @retval EFI_SUCCESS HII Form is installed for this network device.\r
461 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
462 @retval Others Other errors as indicated.\r
463\r
464**/\r
465EFI_STATUS\r
466InstallVlanConfigForm (\r
467 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData\r
468 )\r
469{\r
470 EFI_STATUS Status;\r
471 EFI_HII_HANDLE HiiHandle;\r
472 EFI_HANDLE DriverHandle;\r
e2851998 473 CHAR16 Str[26 + sizeof (EFI_MAC_ADDRESS) * 2 + 1];\r
779ae357 474 CHAR16 *MacString;\r
475 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;\r
476 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
477\r
478 //\r
479 // Create child handle and install HII Config Access Protocol\r
480 //\r
481 ChildDevicePath = AppendDevicePathNode (\r
482 PrivateData->ParentDevicePath,\r
483 (CONST EFI_DEVICE_PATH_PROTOCOL *) &mHiiVendorDevicePathNode\r
484 );\r
485 if (ChildDevicePath == NULL) {\r
486 return EFI_OUT_OF_RESOURCES;\r
487 }\r
488 PrivateData->ChildDevicePath = ChildDevicePath;\r
489\r
490 DriverHandle = NULL;\r
491 ConfigAccess = &PrivateData->ConfigAccess;\r
492 Status = gBS->InstallMultipleProtocolInterfaces (\r
493 &DriverHandle,\r
494 &gEfiDevicePathProtocolGuid,\r
495 ChildDevicePath,\r
496 &gEfiHiiConfigAccessProtocolGuid,\r
497 ConfigAccess,\r
498 NULL\r
499 );\r
500 if (EFI_ERROR (Status)) {\r
501 return Status;\r
502 }\r
503 PrivateData->DriverHandle = DriverHandle;\r
504\r
505 //\r
506 // Publish the HII package list\r
507 //\r
508 HiiHandle = HiiAddPackages (\r
509 &mVlanFormSetGuid,\r
510 DriverHandle,\r
511 VlanConfigDxeStrings,\r
512 VlanConfigBin,\r
513 NULL\r
514 );\r
515 if (HiiHandle == NULL) {\r
516 return EFI_OUT_OF_RESOURCES;\r
517 }\r
518 PrivateData->HiiHandle = HiiHandle;\r
519\r
520 //\r
521 // Update formset title\r
522 //\r
523 MacString = NULL;\r
524 Status = NetLibGetMacString (PrivateData->ControllerHandle, PrivateData->ImageHandle, &MacString);\r
525 if (EFI_ERROR (Status)) {\r
526 return Status;\r
527 }\r
528 PrivateData->MacString = MacString;\r
529\r
530 StrCpy (Str, L"VLAN Configuration (MAC:");\r
1b2bf3ca 531 StrnCat (Str, MacString, sizeof (EFI_MAC_ADDRESS) * 2);\r
779ae357 532 StrCat (Str, L")");\r
533 HiiSetString (\r
534 HiiHandle,\r
535 STRING_TOKEN (STR_VLAN_FORM_SET_TITLE),\r
536 Str,\r
537 NULL\r
538 );\r
539\r
540 //\r
541 // Update form title\r
542 //\r
543 HiiSetString (\r
544 HiiHandle,\r
545 STRING_TOKEN (STR_VLAN_FORM_TITLE),\r
546 Str,\r
547 NULL\r
548 );\r
549\r
550 return EFI_SUCCESS;\r
551}\r
552\r
553/**\r
554 This function remove the VLAN configuration Form for a network device. The\r
555 child handle for HII Config Access protocol will be destroyed.\r
556\r
557 @param[in, out] PrivateData Points to VLAN configuration private data.\r
558\r
559**/\r
560VOID\r
561UninstallVlanConfigForm (\r
562 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData\r
563 )\r
564{\r
565 //\r
566 // Free MAC string\r
567 //\r
568 if (PrivateData->MacString != NULL) {\r
569 FreePool (PrivateData->MacString);\r
570 PrivateData->MacString = NULL;\r
571 }\r
572\r
573 //\r
574 // Uninstall HII package list\r
575 //\r
576 if (PrivateData->HiiHandle != NULL) {\r
577 HiiRemovePackages (PrivateData->HiiHandle);\r
578 PrivateData->HiiHandle = NULL;\r
579 }\r
580\r
581 //\r
582 // Uninstall HII Config Access Protocol\r
583 //\r
584 if (PrivateData->DriverHandle != NULL) {\r
585 gBS->UninstallMultipleProtocolInterfaces (\r
586 PrivateData->DriverHandle,\r
587 &gEfiDevicePathProtocolGuid,\r
588 PrivateData->ChildDevicePath,\r
589 &gEfiHiiConfigAccessProtocolGuid,\r
590 &PrivateData->ConfigAccess,\r
591 NULL\r
592 );\r
593 PrivateData->DriverHandle = NULL;\r
594\r
595 if (PrivateData->ChildDevicePath != NULL) {\r
596 FreePool (PrivateData->ChildDevicePath);\r
597 PrivateData->ChildDevicePath = NULL;\r
598 }\r
599 }\r
600}\r