/** @file
  This module produces two driver health manager forms.
  One will be used by BDS core to configure the Configured Required
  driver health instances, the other will be automatically included by
  firmware setup (UI).

Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DriverHealthManagerDxe.h"
#include "DriverHealthManagerVfr.h"

EFI_HII_CONFIG_ACCESS_PROTOCOL  mDriverHealthManagerConfigAccess = {
  DriverHealthManagerFakeExtractConfig,
  DriverHealthManagerFakeRouteConfig,
  DriverHealthManagerCallback
};

EFI_GUID  mDriverHealthManagerForm = DRIVER_HEALTH_MANAGER_FORMSET_GUID;

FORM_DEVICE_PATH  mDriverHealthManagerFormDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    EFI_CALLER_ID_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

EFI_HII_HANDLE                       mDriverHealthManagerHiiHandle;
EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO  *mDriverHealthManagerHealthInfo     = NULL;
UINTN                                mDriverHealthManagerHealthInfoCount = 0;
EFI_HII_DATABASE_PROTOCOL            *mDriverHealthManagerDatabase;
EFI_HII_PACKAGE_LIST_HEADER          *mBackupHiiPackageList = NULL;

extern UINT8  DriverHealthManagerVfrBin[];
extern UINT8  DriverHealthConfigureVfrBin[];

/**
  This function allows a caller to extract the current configuration for one
  or more named elements from the target driver.


  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Request         A null-terminated Unicode string in <ConfigRequest> format.
  @param Progress        On return, points to a character in the Request string.
                         Points to the string's null terminator if request was successful.
                         Points to the most recent '&' before the first failing name/value
                         pair (or the beginning of the string if the failure is in the
                         first name/value pair) if the request was not successful.
  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which
                         has all values filled in for the names in the Request string.
                         String to be allocated by the called function.

  @retval  EFI_SUCCESS            The Results is filled with the requested values.
  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.

**/
EFI_STATUS
EFIAPI
DriverHealthManagerFakeExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Request,
  OUT EFI_STRING                            *Progress,
  OUT EFI_STRING                            *Results
  )
{
  if ((Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  return EFI_NOT_FOUND;
}

/**
  This function processes the results of changes in configuration.


  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Configuration   A null-terminated Unicode string in <ConfigResp> format.
  @param Progress        A pointer to a string filled in with the offset of the most
                         recent '&' before the first failing name/value pair (or the
                         beginning of the string if the failure is in the first
                         name/value pair) or the terminating NULL if all was successful.

  @retval  EFI_SUCCESS            The Results is processed successfully.
  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.
  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.

**/
EFI_STATUS
EFIAPI
DriverHealthManagerFakeRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                            *Progress
  )
{
  if ((Configuration == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Configuration;

  return EFI_NOT_FOUND;
}

/**
  Create a default HiiPackageList that only contains static STRING_ARRAY_NAME data
  once the driver is initialized. This HiiPackageList is used to be updated in
  DriverHealthManagerCleanDynamicString function.
**/
EFI_HII_PACKAGE_LIST_HEADER *
CreateBackupStringPackageList (
  VOID
  )
{
  EFI_HII_PACKAGE_LIST_HEADER  *BackupHiiPackageList;
  UINTN                        BufferSize;
  EFI_HII_PACKAGE_HEADER       *PackageHeader;
  UINT32                       FixedStringSize;

  FixedStringSize      = *(UINT32 *)&STRING_ARRAY_NAME - sizeof (UINT32);
  BufferSize           = sizeof (EFI_HII_PACKAGE_LIST_HEADER) + FixedStringSize + sizeof (EFI_HII_PACKAGE_HEADER);
  BackupHiiPackageList = AllocateZeroPool (BufferSize);
  if (BackupHiiPackageList == NULL) {
    ASSERT (BackupHiiPackageList != NULL);
    return NULL;
  }

  BackupHiiPackageList->PackageLength = (UINT32)BufferSize;
  CopyMem (&BackupHiiPackageList->PackageListGuid, &gEfiCallerIdGuid, sizeof (EFI_GUID));

  PackageHeader = (EFI_HII_PACKAGE_HEADER *)(BackupHiiPackageList + 1);
  CopyMem (PackageHeader, STRING_ARRAY_NAME + sizeof (UINT32), FixedStringSize);

  PackageHeader         = (EFI_HII_PACKAGE_HEADER *)((UINT8 *)PackageHeader + FixedStringSize);
  PackageHeader->Type   = EFI_HII_PACKAGE_END;
  PackageHeader->Length = sizeof (EFI_HII_PACKAGE_HEADER);

  return BackupHiiPackageList;
}

/**

  Install the health manager forms.
  One will be used by BDS core to configure the Configured Required
  driver health instances, the other will be automatically included by
  firmware setup (UI).

  @param ImageHandle     The image handle.
  @param SystemTable     The system table.

  @retval  EFI_SUCEESS   The health manager forms are successfully installed.

**/
EFI_STATUS
EFIAPI
InitializeDriverHealthManager (
  EFI_HANDLE        ImageHandle,
  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  Handle;

  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **)&mDriverHealthManagerDatabase
                  );
  ASSERT_EFI_ERROR (Status);

  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiDevicePathProtocolGuid,
                  &mDriverHealthManagerFormDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &mDriverHealthManagerConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Publish Driver Health HII data.
  //
  mDriverHealthManagerHiiHandle = HiiAddPackages (
                                    &gEfiCallerIdGuid,
                                    Handle,
                                    DriverHealthManagerVfrBin,
                                    DriverHealthConfigureVfrBin,
                                    STRING_ARRAY_NAME,
                                    NULL
                                    );
  ASSERT (mDriverHealthManagerHiiHandle != NULL);

  mBackupHiiPackageList = CreateBackupStringPackageList ();

  return EFI_SUCCESS;
}

/**

  Select the best matching language according to front page policy for best user experience.

  This function supports both ISO 639-2 and RFC 4646 language codes, but language
  code types may not be mixed in a single call to this function.

  @param  SupportedLanguages   A pointer to a Null-terminated ASCII string that
                               contains a set of language codes in the format
                               specified by Iso639Language.
  @param  Iso639Language       If TRUE, then all language codes are assumed to be
                               in ISO 639-2 format.  If FALSE, then all language
                               codes are assumed to be in RFC 4646 language format.

  @retval NULL                 The best matching language could not be found in SupportedLanguages.
  @retval NULL                 There are not enough resources available to return the best matching
                               language.
  @retval Other                A pointer to a Null-terminated ASCII string that is the best matching
                               language in SupportedLanguages.
**/
CHAR8 *
DriverHealthManagerSelectBestLanguage (
  IN CHAR8    *SupportedLanguages,
  IN BOOLEAN  Iso639Language
  )
{
  CHAR8  *LanguageVariable;
  CHAR8  *BestLanguage;

  GetEfiGlobalVariable2 (Iso639Language ? L"Lang" : L"PlatformLang", (VOID **)&LanguageVariable, NULL);

  BestLanguage = GetBestLanguage (
                   SupportedLanguages,
                   Iso639Language,
                   (LanguageVariable != NULL) ? LanguageVariable : "",
                   Iso639Language ? "eng" : "en-US",
                   NULL
                   );
  if (LanguageVariable != NULL) {
    FreePool (LanguageVariable);
  }

  return BestLanguage;
}

/**

  This is an internal worker function to get the Component Name (2) protocol interface
  and the language it supports.

  @param  ProtocolGuid         A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.
  @param  ComponentName        A pointer to the Component Name (2) protocol interface.
  @param  SupportedLanguage    The best suitable language that matches the SupportedLangues interface for the
                               located Component Name (2) instance.

  @retval EFI_SUCCESS          The Component Name (2) protocol instance is successfully located and we find
                               the best matching language it support.
  @retval EFI_UNSUPPORTED      The input Language is not supported by the Component Name (2) protocol.
  @retval Other                Some error occurs when locating Component Name (2) protocol instance or finding
                               the supported language.

**/
EFI_STATUS
DriverHealthManagerGetComponentNameWorker (
  IN  EFI_GUID                     *ProtocolGuid,
  IN  EFI_HANDLE                   DriverBindingHandle,
  OUT EFI_COMPONENT_NAME_PROTOCOL  **ComponentName,
  OUT CHAR8                        **SupportedLanguage
  )
{
  EFI_STATUS  Status;

  //
  // Locate Component Name (2) protocol on the driver binging handle.
  //
  Status = gBS->OpenProtocol (
                  DriverBindingHandle,
                  ProtocolGuid,
                  (VOID **)ComponentName,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Apply shell policy to select the best language.
  //
  *SupportedLanguage = DriverHealthManagerSelectBestLanguage (
                         (*ComponentName)->SupportedLanguages,
                         (BOOLEAN)(ProtocolGuid == &gEfiComponentNameProtocolGuid)
                         );
  if (*SupportedLanguage == NULL) {
    Status = EFI_UNSUPPORTED;
  }

  return Status;
}

/**

  This is an internal worker function to get driver name from Component Name (2) protocol interface.

  @param  ProtocolGuid         A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.
  @param  DriverName           A pointer to the Unicode string to return. This Unicode string is the name
                               of the driver specified by This.

  @retval EFI_SUCCESS          The driver name is successfully retrieved from Component Name (2) protocol
                               interface.
  @retval Other                The driver name cannot be retrieved from Component Name (2) protocol
                               interface.

**/
EFI_STATUS
DriverHealthManagerGetDriverNameWorker (
  IN  EFI_GUID    *ProtocolGuid,
  IN  EFI_HANDLE  DriverBindingHandle,
  OUT CHAR16      **DriverName
  )
{
  EFI_STATUS                   Status;
  CHAR8                        *BestLanguage;
  EFI_COMPONENT_NAME_PROTOCOL  *ComponentName;

  //
  // Retrieve Component Name (2) protocol instance on the driver binding handle and
  // find the best language this instance supports.
  //
  Status = DriverHealthManagerGetComponentNameWorker (
             ProtocolGuid,
             DriverBindingHandle,
             &ComponentName,
             &BestLanguage
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the driver name from Component Name (2) protocol instance on the driver binging handle.
  //
  Status = ComponentName->GetDriverName (
                            ComponentName,
                            BestLanguage,
                            DriverName
                            );
  FreePool (BestLanguage);

  return Status;
}

/**
  This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface
  in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.
  If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward
  compatibility support.

  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.

  @return A pointer to the Unicode string to return. This Unicode string is the name of the controller
          specified by ControllerHandle and ChildHandle.


**/
CHAR16 *
DriverHealthManagerGetDriverName (
  IN  EFI_HANDLE  DriverBindingHandle
  )
{
  EFI_STATUS  Status;
  CHAR16      *DriverName;

  //
  // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
  //
  Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentName2ProtocolGuid, DriverBindingHandle, &DriverName);
  if (EFI_ERROR (Status)) {
    //
    // If it fails to get the driver name from Component Name protocol interface, we should fall back on
    // EFI 1.1 Component Name protocol interface.
    //
    Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentNameProtocolGuid, DriverBindingHandle, &DriverName);
  }

  if (!EFI_ERROR (Status)) {
    return AllocateCopyPool (StrSize (DriverName), DriverName);
  } else {
    return ConvertDevicePathToText (DevicePathFromHandle (DriverBindingHandle), FALSE, TRUE);
  }
}

/**
  This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
  in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
  If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
  compatibility support.

  @param  ProtocolGuid         A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.
  @param  ControllerHandle     The handle of a controller that the driver specified by This is managing.
                               This handle specifies the controller whose name is to be returned.
  @param  ChildHandle          The handle of the child controller to retrieve the name of. This is an
                               optional parameter that may be NULL. It will be NULL for device drivers.
                               It will also be NULL for bus drivers that attempt to retrieve the name
                               of the bus controller. It will not be NULL for a bus driver that attempts
                               to retrieve the name of a child controller.
  @param  ControllerName       A pointer to the Unicode string to return. This Unicode string
                               is the name of the controller specified by ControllerHandle and ChildHandle.

  @retval  EFI_SUCCESS         The controller name is successfully retrieved from Component Name (2) protocol
                               interface.
  @retval  Other               The controller name cannot be retrieved from Component Name (2) protocol.

**/
EFI_STATUS
DriverHealthManagerGetControllerNameWorker (
  IN  EFI_GUID    *ProtocolGuid,
  IN  EFI_HANDLE  DriverBindingHandle,
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_HANDLE  ChildHandle,
  OUT CHAR16      **ControllerName
  )
{
  EFI_STATUS                   Status;
  CHAR8                        *BestLanguage;
  EFI_COMPONENT_NAME_PROTOCOL  *ComponentName;

  //
  // Retrieve Component Name (2) protocol instance on the driver binding handle and
  // find the best language this instance supports.
  //
  Status = DriverHealthManagerGetComponentNameWorker (
             ProtocolGuid,
             DriverBindingHandle,
             &ComponentName,
             &BestLanguage
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the controller name from Component Name (2) protocol instance on the driver binging handle.
  //
  Status = ComponentName->GetControllerName (
                            ComponentName,
                            ControllerHandle,
                            ChildHandle,
                            BestLanguage,
                            ControllerName
                            );
  FreePool (BestLanguage);

  return Status;
}

/**

  This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
  in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
  If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
  compatibility support.

  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.
  @param  ControllerHandle     The handle of a controller that the driver specified by DriverBindingHandle is managing.
                               This handle specifies the controller whose name is to be returned.
  @param  ChildHandle          The handle of the child controller to retrieve the name of. This is an
                               optional parameter that may be NULL. It will be NULL for device drivers.
                               It will also be NULL for bus drivers that attempt to retrieve the name
                               of the bus controller. It will not be NULL for a bus driver that attempts
                               to retrieve the name of a child controller.

  @return A pointer to the Unicode string to return. This Unicode string is the name of the controller
          specified by ControllerHandle and ChildHandle.
**/
CHAR16 *
DriverHealthManagerGetControllerName (
  IN  EFI_HANDLE  DriverBindingHandle,
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_HANDLE  ChildHandle
  )
{
  EFI_STATUS  Status;
  CHAR16      *ControllerName;

  //
  // Get controller name from UEFI 2.0 Component Name 2 protocol interface.
  //
  Status = DriverHealthManagerGetControllerNameWorker (
             &gEfiComponentName2ProtocolGuid,
             DriverBindingHandle,
             ControllerHandle,
             ChildHandle,
             &ControllerName
             );
  if (EFI_ERROR (Status)) {
    //
    // If it fails to get the controller name from Component Name protocol interface, we should fall back on
    // EFI 1.1 Component Name protocol interface.
    //
    Status = DriverHealthManagerGetControllerNameWorker (
               &gEfiComponentNameProtocolGuid,
               DriverBindingHandle,
               ControllerHandle,
               ChildHandle,
               &ControllerName
               );
  }

  if (!EFI_ERROR (Status)) {
    return AllocateCopyPool (StrSize (ControllerName), ControllerName);
  } else {
    return ConvertDevicePathToText (DevicePathFromHandle (ChildHandle != NULL ? ChildHandle : ControllerHandle), FALSE, TRUE);
  }
}

/**
  The repair notify function.
  @param Value  A value between 0 and Limit that identifies the current progress
                of the repair operation.
  @param Limit  The maximum value of Value for the current repair operation.
                If Limit is 0, then the completion progress is indeterminate.
                For example, a driver that wants to specify progress in percent
                would use a Limit value of 100.

  @retval EFI_SUCCESS  Successfully return from the notify function.
**/
EFI_STATUS
EFIAPI
DriverHealthManagerRepairNotify (
  IN UINTN  Value,
  IN UINTN  Limit
  )
{
  DEBUG ((DEBUG_INFO, "[DriverHealthManagement]RepairNotify: %d/%d\n", Value, Limit));
  return EFI_SUCCESS;
}

/**
  Look for the formset GUID which has the gEfiHiiDriverHealthFormsetGuid class GUID in the specified HII package list.

  @param Handle         Handle to the HII package list.
  @param FormsetGuid    Return the formset GUID.

  @retval EFI_SUCCESS           The formset is found successfully.
  @retval EFI_NOT_FOUND         The formset cannot be found.
  @retval EFI_OUT_OF_RESOURCES  Failed to find enough free memory
**/
EFI_STATUS
DriverHealthManagerGetFormsetId (
  IN  EFI_HII_HANDLE  Handle,
  OUT EFI_GUID        *FormsetGuid
  )
{
  EFI_STATUS                   Status;
  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;
  UINTN                        BufferSize;
  UINT8                        *Package;
  UINT8                        *OpCodeData;
  UINT32                       Offset;
  UINT32                       Offset2;
  EFI_HII_PACKAGE_HEADER       PackageHeader;
  UINT8                        Index;
  UINT8                        NumberOfClassGuid;
  EFI_GUID                     *ClassGuid;

  //
  // Get HII PackageList
  //
  BufferSize     = 0;
  HiiPackageList = NULL;
  Status         = mDriverHealthManagerDatabase->ExportPackageLists (mDriverHealthManagerDatabase, Handle, &BufferSize, HiiPackageList);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HiiPackageList = AllocatePool (BufferSize);
    if (HiiPackageList == NULL) {
      ASSERT (HiiPackageList != NULL);
      return EFI_OUT_OF_RESOURCES;
    }

    Status = mDriverHealthManagerDatabase->ExportPackageLists (mDriverHealthManagerDatabase, Handle, &BufferSize, HiiPackageList);
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (HiiPackageList == NULL) {
    ASSERT (HiiPackageList != NULL);
    return EFI_NOT_FOUND;
  }

  //
  // Get Form package from this HII package List
  //
  for (Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); Offset < ReadUnaligned32 (&HiiPackageList->PackageLength); Offset += PackageHeader.Length) {
    Package = ((UINT8 *)HiiPackageList) + Offset;
    CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));

    if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
      //
      // Search FormSet in this Form Package
      //

      for (Offset2 = sizeof (EFI_HII_PACKAGE_HEADER); Offset2 < PackageHeader.Length; Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length) {
        OpCodeData = Package + Offset2;

        if ((((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) &&
            (((EFI_IFR_OP_HEADER *)OpCodeData)->Length > OFFSET_OF (EFI_IFR_FORM_SET, Flags)))
        {
          //
          // Try to compare against formset class GUID
          //
          NumberOfClassGuid = (UINT8)(((EFI_IFR_FORM_SET *)OpCodeData)->Flags & 0x3);
          ClassGuid         = (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_FORM_SET));
          for (Index = 0; Index < NumberOfClassGuid; Index++) {
            if (CompareGuid (&gEfiHiiDriverHealthFormsetGuid, &ClassGuid[Index])) {
              CopyMem (FormsetGuid, &((EFI_IFR_FORM_SET *)OpCodeData)->Guid, sizeof (EFI_GUID));
              FreePool (HiiPackageList);
              return EFI_SUCCESS;
            }
          }
        }
      }
    }
  }

  //
  // Form package not found in this Package List
  //
  FreePool (HiiPackageList);

  return EFI_NOT_FOUND;
}

/**
  Processes a single controller using the EFI Driver Health Protocol associated with
  that controller.

  @param DriverHealth       A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
  @param ControllerHandle   The class guid specifies which form set will be displayed.
  @param ChildHandle        The handle of the child controller to retrieve the health
                            status on.  This is an optional parameter that may be NULL.
  @param HealthStatus       The health status of the controller.
  @param MessageList        An array of warning or error messages associated
                            with the controller specified by ControllerHandle and
                            ChildHandle.  This is an optional parameter that may be NULL.
  @param FormHiiHandle      The HII handle for an HII form associated with the
                            controller specified by ControllerHandle and ChildHandle.
**/
VOID
DriverHealthManagerProcessSingleControllerHealth (
  IN  EFI_DRIVER_HEALTH_PROTOCOL     *DriverHealth,
  IN  EFI_HANDLE                     ControllerHandle  OPTIONAL,
  IN  EFI_HANDLE                     ChildHandle       OPTIONAL,
  IN  EFI_DRIVER_HEALTH_STATUS       HealthStatus,
  IN  EFI_DRIVER_HEALTH_HII_MESSAGE  **MessageList     OPTIONAL,
  IN  EFI_HII_HANDLE                 FormHiiHandle
  )
{
  EFI_STATUS  Status;

  ASSERT (HealthStatus != EfiDriverHealthStatusConfigurationRequired);
  //
  // If the module need to be repaired or reconfiguration,  will process it until
  // reach a terminal status. The status from EfiDriverHealthStatusRepairRequired after repair
  // will be in (Health, Failed, Configuration Required).
  //
  switch (HealthStatus) {
    case EfiDriverHealthStatusRepairRequired:
      Status = DriverHealth->Repair (
                               DriverHealth,
                               ControllerHandle,
                               ChildHandle,
                               DriverHealthManagerRepairNotify
                               );
      break;

    case EfiDriverHealthStatusRebootRequired:
      gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
      break;

    case EfiDriverHealthStatusReconnectRequired:
      Status = gBS->DisconnectController (ControllerHandle, NULL, NULL);
      if (EFI_ERROR (Status)) {
        //
        // Disconnect failed.  Need to promote reconnect to a reboot.
        //
        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
      } else {
        gBS->ConnectController (ControllerHandle, NULL, NULL, TRUE);
      }

      break;

    default:
      break;
  }
}

/**
  Update the form to include the driver health instances.

  @param ConfigureOnly  Only include the configure required driver health instances
                        when TRUE, include all the driver health instances otherwise.
**/
VOID
DriverHealthManagerUpdateForm (
  BOOLEAN  ConfigureOnly
  )
{
  EFI_STATUS          Status;
  EFI_IFR_GUID_LABEL  *StartLabel;
  EFI_IFR_GUID_LABEL  *EndLabel;
  VOID                *StartOpCodeHandle;
  VOID                *EndOpCodeHandle;
  UINTN               Index;
  EFI_STRING_ID       Prompt;
  EFI_STRING_ID       Help;
  EFI_STRING_ID       TextTwo;
  CHAR16              String[512];
  UINTN               StringCount;
  EFI_STRING          TmpString;
  EFI_STRING          DriverName;
  EFI_STRING          ControllerName;
  UINTN               MessageIndex;
  EFI_HANDLE          DriverHandle;
  EFI_STRING_ID       DevicePath;
  EFI_GUID            FormsetGuid;

  EfiBootManagerFreeDriverHealthInfo (mDriverHealthManagerHealthInfo, mDriverHealthManagerHealthInfoCount);
  mDriverHealthManagerHealthInfo = EfiBootManagerGetDriverHealthInfo (&mDriverHealthManagerHealthInfoCount);

  //
  // Allocate space for creation of UpdateData Buffer
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel               = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = LABEL_BEGIN;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel               = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  for (Index = 0; Index < mDriverHealthManagerHealthInfoCount; Index++) {
    if (ConfigureOnly && (mDriverHealthManagerHealthInfo[Index].HealthStatus != EfiDriverHealthStatusConfigurationRequired)) {
      continue;
    }

    DriverName = DriverHealthManagerGetDriverName (mDriverHealthManagerHealthInfo[Index].DriverHealthHandle);
    ASSERT (DriverName != NULL);

    if (mDriverHealthManagerHealthInfo[Index].ControllerHandle == NULL) {
      //
      // The ControllerHandle is set to NULL and the HealthStatus is set to EfiDriverHealthStatusHealthy
      // if all the controllers managed by the driver are in healthy state.
      //
      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);
      UnicodeSPrint (String, sizeof (String), L"%s", DriverName);
    } else {
      ControllerName = DriverHealthManagerGetControllerName (
                         mDriverHealthManagerHealthInfo[Index].DriverHealthHandle,
                         mDriverHealthManagerHealthInfo[Index].ControllerHandle,
                         mDriverHealthManagerHealthInfo[Index].ChildHandle
                         );
      ASSERT (ControllerName != NULL);
      UnicodeSPrint (String, sizeof (String), L"%s    %s", DriverName, ControllerName);
      FreePool (ControllerName);
    }

    FreePool (DriverName);

    Prompt = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);

    switch (mDriverHealthManagerHealthInfo[Index].HealthStatus) {
      case EfiDriverHealthStatusRepairRequired:
        TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REPAIR_REQUIRED), NULL);
        break;
      case EfiDriverHealthStatusConfigurationRequired:
        TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_CONFIGURATION_REQUIRED), NULL);
        break;
      case EfiDriverHealthStatusFailed:
        TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_FAILED), NULL);
        break;
      case EfiDriverHealthStatusReconnectRequired:
        TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_RECONNECT_REQUIRED), NULL);
        break;
      case EfiDriverHealthStatusRebootRequired:
        TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REBOOT_REQUIRED), NULL);
        break;
      default:
        ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);
        TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_HEALTHY), NULL);
        break;
    }

    StringCount = UnicodeSPrint (String, sizeof (String), L"%s\n", TmpString);
    FreePool (TmpString);

    //
    // Add the message of the Module itself provided as the help.
    //
    if (mDriverHealthManagerHealthInfo[Index].MessageList != NULL) {
      for (MessageIndex = 0; mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle != NULL; MessageIndex++) {
        TmpString = HiiGetString (
                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle,
                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].StringId,
                      NULL
                      );
        StringCount += UnicodeSPrint (String + StringCount, sizeof (String) - sizeof (String[0]) * StringCount, L"\n%s", TmpString);
        FreePool (TmpString);
      }
    }

    Help = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);

    switch (mDriverHealthManagerHealthInfo[Index].HealthStatus) {
      case EfiDriverHealthStatusConfigurationRequired:
        Status = mDriverHealthManagerDatabase->GetPackageListHandle (
                                                 mDriverHealthManagerDatabase,
                                                 mDriverHealthManagerHealthInfo[Index].HiiHandle,
                                                 &DriverHandle
                                                 );
        ASSERT_EFI_ERROR (Status);
        TmpString  = ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, TRUE);
        DevicePath = HiiSetString (mDriverHealthManagerHiiHandle, 0, TmpString, NULL);
        FreePool (TmpString);

        Status = DriverHealthManagerGetFormsetId (mDriverHealthManagerHealthInfo[Index].HiiHandle, &FormsetGuid);
        ASSERT_EFI_ERROR (Status);

        HiiCreateGotoExOpCode (
          StartOpCodeHandle,
          0,
          Prompt,
          Help,
          0,
          0,
          0,
          &FormsetGuid,
          DevicePath
          );
        break;

      case EfiDriverHealthStatusRepairRequired:
      case EfiDriverHealthStatusReconnectRequired:
      case EfiDriverHealthStatusRebootRequired:
        HiiCreateActionOpCode (
          StartOpCodeHandle,
          (EFI_QUESTION_ID)(Index + QUESTION_ID_DRIVER_HEALTH_BASE),
          Prompt,
          Help,
          EFI_IFR_FLAG_CALLBACK,
          0
          );
        break;

      default:
        ASSERT (
          mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy ||
          mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusFailed
          );
        TextTwo = Help;
        HiiCreateTextOpCode (
          StartOpCodeHandle,
          Prompt,
          0,
          TextTwo
          );
        break;
    }
  }

  Status = HiiUpdateForm (
             mDriverHealthManagerHiiHandle,
             ConfigureOnly ? PcdGetPtr (PcdDriverHealthConfigureForm) : &mDriverHealthManagerForm,
             DRIVER_HEALTH_FORM_ID,
             StartOpCodeHandle,
             EndOpCodeHandle
             );
  ASSERT_EFI_ERROR (Status);

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}

/**
  Called when the form is closing to remove the dynamically added string from the HII package list.
**/
VOID
DriverHealthManagerCleanDynamicString (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = mDriverHealthManagerDatabase->UpdatePackageList (
                                           mDriverHealthManagerDatabase,
                                           mDriverHealthManagerHiiHandle,
                                           mBackupHiiPackageList
                                           );
  ASSERT_EFI_ERROR (Status);
}

/**
  This function is invoked if user selected a interactive opcode from Driver Health's
  Formset.

  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Action          Specifies the type of action taken by the browser.
  @param QuestionId      A unique value which is sent to the original exporting driver
                         so that it can identify the type of data to expect.
  @param Type            The type of value for the question.
  @param Value           A pointer to the data being sent to the original exporting driver.
  @param ActionRequest   On return, points to the action requested by the callback function.

  @retval  EFI_SUCCESS           The callback successfully handled the action.
  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.

**/
EFI_STATUS
EFIAPI
DriverHealthManagerCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  EFI_BROWSER_ACTION                    Action,
  IN  EFI_QUESTION_ID                       QuestionId,
  IN  UINT8                                 Type,
  IN  EFI_IFR_TYPE_VALUE                    *Value,
  OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  UINTN  Index;

  if ((QuestionId == QUESTION_ID_REFRESH_MANAGER) || (QuestionId == QUESTION_ID_REFRESH_CONFIGURE)) {
    if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
      DriverHealthManagerUpdateForm ((BOOLEAN)(QuestionId == QUESTION_ID_REFRESH_CONFIGURE));
    } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
      DriverHealthManagerCleanDynamicString ();
    }

    return EFI_SUCCESS;
  }

  if (Action != EFI_BROWSER_ACTION_CHANGED) {
    //
    // Do nothing for other UEFI Action. Only do call back when data is changed.
    //
    return EFI_UNSUPPORTED;
  }

  if ((Value == NULL) || (ActionRequest == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((DEBUG_ERROR, "QuestionId = %x\n", QuestionId));

  //
  // We will have returned from processing a callback - user either hit ESC to exit, or selected
  // a target to display.
  // Process the diver health status states here.
  //
  Index = QuestionId - QUESTION_ID_DRIVER_HEALTH_BASE;
  ASSERT (Index < mDriverHealthManagerHealthInfoCount);
  //
  // Process the driver's healthy status for the specify module
  //
  DriverHealthManagerProcessSingleControllerHealth (
    mDriverHealthManagerHealthInfo[Index].DriverHealth,
    mDriverHealthManagerHealthInfo[Index].ControllerHandle,
    mDriverHealthManagerHealthInfo[Index].ChildHandle,
    mDriverHealthManagerHealthInfo[Index].HealthStatus,
    &(mDriverHealthManagerHealthInfo[Index].MessageList),
    mDriverHealthManagerHealthInfo[Index].HiiHandle
    );

  DriverHealthManagerUpdateForm ((BOOLEAN)(QuestionId == QUESTION_ID_REFRESH_CONFIGURE));

  return EFI_SUCCESS;
}
