+/**\r
+ Function to uninstall FMP instance.\r
+\r
+ @param[in] Handle The device handle to install a FMP instance on.\r
+\r
+ @retval EFI_SUCCESS FMP Installed\r
+ @retval EFI_INVALID_PARAMETER Handle was invalid\r
+ @retval other Error installing FMP\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UninstallFmpInstance (\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Handle,\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ (VOID **)&Fmp,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol open error. Status = %r.\n", mImageIdName, Status));\r
+ return Status;\r
+ }\r
+\r
+ Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (Fmp);\r
+ FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);\r
+\r
+ if (Private->FmpDeviceLockEvent != NULL) {\r
+ gBS->CloseEvent (Private->FmpDeviceLockEvent);\r
+ }\r
+\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Private->Handle,\r
+ &gEfiFirmwareManagementProtocolGuid, &Private->Fmp,\r
+ &gEdkiiFirmwareManagementProgressProtocolGuid, &mFmpProgress,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol uninstall error. Status = %r.\n", mImageIdName, Status));\r
+ return Status;\r
+ }\r
+\r
+ if (Private->Descriptor.VersionName != NULL) {\r
+ FreePool (Private->Descriptor.VersionName);\r
+ }\r
+ if (Private->FmpDeviceContext != NULL) {\r
+ FmpDeviceSetContext (NULL, &Private->FmpDeviceContext);\r
+ }\r
+ if (Private->VersionVariableName != NULL) {\r
+ FreePool (Private->VersionVariableName);\r
+ }\r
+ if (Private->LsvVariableName != NULL) {\r
+ FreePool (Private->LsvVariableName);\r
+ }\r
+ if (Private->LastAttemptStatusVariableName != NULL) {\r
+ FreePool (Private->LastAttemptStatusVariableName);\r
+ }\r
+ if (Private->LastAttemptVersionVariableName != NULL) {\r
+ FreePool (Private->LastAttemptVersionVariableName);\r
+ }\r
+ if (Private->FmpStateVariableName != NULL) {\r
+ FreePool (Private->FmpStateVariableName);\r
+ }\r
+ FreePool (Private);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Unloads the application and its installed protocol.\r
+\r
+ @param ImageHandle Handle that identifies the image to be unloaded.\r
+ @param SystemTable The system table.\r
+\r
+ @retval EFI_SUCCESS The image has been unloaded.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FmpDxeLibDestructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ if (mFmpSingleInstance) {\r
+ return UninstallFmpInstance (ImageHandle);\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r