/** @file
  UEFI handle & protocol handling.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DxeMain.h"
#include "Handle.h"

//
// mProtocolDatabase     - A list of all protocols in the system.  (simple list for now)
// gHandleList           - A list of all the handles in the system
// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase
// gHandleDatabaseKey    -  The Key to show that the handle has been created/modified
//
LIST_ENTRY          mProtocolDatabase     = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
LIST_ENTRY          gHandleList           = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
EFI_LOCK            gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
UINT64              gHandleDatabaseKey    = 0;
ORDERED_COLLECTION  *gOrderedHandleList   = NULL;

/**
  Acquire lock on gProtocolDatabaseLock.

**/
VOID
CoreAcquireProtocolLock (
  VOID
  )
{
  CoreAcquireLock (&gProtocolDatabaseLock);
}

/**
  Release lock on gProtocolDatabaseLock.

**/
VOID
CoreReleaseProtocolLock (
  VOID
  )
{
  CoreReleaseLock (&gProtocolDatabaseLock);
}

/**
  Comparator function for two opaque pointers, ordering on (unsigned) pointer
  value itself.
  Can be used as both Key and UserStruct comparator.

  @param[in] Pointer1  First pointer.

  @param[in] Pointer2  Second pointer.

  @retval <0  If Pointer1 compares less than Pointer2.

  @retval  0  If Pointer1 compares equal to Pointer2.

  @retval >0  If Pointer1 compares greater than Pointer2.
**/
STATIC
INTN
EFIAPI
PointerCompare (
  IN CONST VOID  *Pointer1,
  IN CONST VOID  *Pointer2
  )
{
  if (Pointer1 == Pointer2) {
    return 0;
  }

  if ((UINTN)Pointer1 < (UINTN)Pointer2) {
    return -1;
  }

  return 1;
}

/**
  Initializes "handle" support.

  @return Status code.

**/
EFI_STATUS
CoreInitializeHandleServices (
  VOID
  )
{
  gOrderedHandleList = OrderedCollectionInit (PointerCompare, PointerCompare);

  if (gOrderedHandleList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Check whether a handle is a valid EFI_HANDLE
  The gProtocolDatabaseLock must be owned

  @param  UserHandle             The handle to check

  @retval EFI_INVALID_PARAMETER  The handle is NULL or not a valid EFI_HANDLE.
  @retval EFI_SUCCESS            The handle is valid EFI_HANDLE.

**/
EFI_STATUS
CoreValidateHandle (
  IN  EFI_HANDLE  UserHandle
  )
{
  ORDERED_COLLECTION_ENTRY  *Entry;

  if (UserHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ASSERT_LOCKED (&gProtocolDatabaseLock);

  Entry = OrderedCollectionFind (gOrderedHandleList, UserHandle);
  if (Entry != NULL) {
    return EFI_SUCCESS;
  }

  return EFI_INVALID_PARAMETER;
}

/**
  Finds the protocol entry for the requested protocol.
  The gProtocolDatabaseLock must be owned

  @param  Protocol               The ID of the protocol
  @param  Create                 Create a new entry if not found

  @return Protocol entry

**/
PROTOCOL_ENTRY  *
CoreFindProtocolEntry (
  IN EFI_GUID  *Protocol,
  IN BOOLEAN   Create
  )
{
  LIST_ENTRY      *Link;
  PROTOCOL_ENTRY  *Item;
  PROTOCOL_ENTRY  *ProtEntry;

  ASSERT_LOCKED (&gProtocolDatabaseLock);

  //
  // Search the database for the matching GUID
  //

  ProtEntry = NULL;
  for (Link = mProtocolDatabase.ForwardLink;
       Link != &mProtocolDatabase;
       Link = Link->ForwardLink)
  {
    Item = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
    if (CompareGuid (&Item->ProtocolID, Protocol)) {
      //
      // This is the protocol entry
      //

      ProtEntry = Item;
      break;
    }
  }

  //
  // If the protocol entry was not found and Create is TRUE, then
  // allocate a new entry
  //
  if ((ProtEntry == NULL) && Create) {
    ProtEntry = AllocatePool (sizeof (PROTOCOL_ENTRY));

    if (ProtEntry != NULL) {
      //
      // Initialize new protocol entry structure
      //
      ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;
      CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol);
      InitializeListHead (&ProtEntry->Protocols);
      InitializeListHead (&ProtEntry->Notify);

      //
      // Add it to protocol database
      //
      InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);
    }
  }

  return ProtEntry;
}

/**
  Finds the protocol instance for the requested handle and protocol.
  Note: This function doesn't do parameters checking, it's caller's responsibility
  to pass in valid parameters.

  @param  Handle                 The handle to search the protocol on
  @param  Protocol               GUID of the protocol
  @param  Interface              The interface for the protocol being searched

  @return Protocol instance (NULL: Not found)

**/
PROTOCOL_INTERFACE *
CoreFindProtocolInterface (
  IN IHANDLE   *Handle,
  IN EFI_GUID  *Protocol,
  IN VOID      *Interface
  )
{
  PROTOCOL_INTERFACE  *Prot;
  PROTOCOL_ENTRY      *ProtEntry;
  LIST_ENTRY          *Link;

  ASSERT_LOCKED (&gProtocolDatabaseLock);
  Prot = NULL;

  //
  // Lookup the protocol entry for this protocol ID
  //

  ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
  if (ProtEntry != NULL) {
    //
    // Look at each protocol interface for any matches
    //
    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
      //
      // If this protocol interface matches, remove it
      //
      Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
      if ((Prot->Interface == Interface) && (Prot->Protocol == ProtEntry)) {
        break;
      }

      Prot = NULL;
    }
  }

  return Prot;
}

/**
  Check if the given device path is already installed.

  @param  DevicePath            The given device path

  @retval TRUE                  The device path is already installed
  @retval FALSE                 The device path is not installed

**/
BOOLEAN
IsDevicePathInstalled (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  UINTN               SourceSize;
  UINTN               Size;
  BOOLEAN             Found;
  LIST_ENTRY          *Link;
  PROTOCOL_ENTRY      *ProtEntry;
  PROTOCOL_INTERFACE  *Prot;

  if (DevicePath == NULL) {
    return FALSE;
  }

  Found      = FALSE;
  SourceSize = GetDevicePathSize (DevicePath);
  ASSERT (SourceSize >= END_DEVICE_PATH_LENGTH);

  CoreAcquireProtocolLock ();
  //
  // Look up the protocol entry
  //
  ProtEntry = CoreFindProtocolEntry (&gEfiDevicePathProtocolGuid, FALSE);
  if (ProtEntry == NULL) {
    goto Done;
  }

  for (Link = ProtEntry->Protocols.ForwardLink; Link != &ProtEntry->Protocols; Link = Link->ForwardLink) {
    //
    // Loop on the DevicePathProtocol interfaces
    //
    Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);

    //
    // Check if DevicePath is same as this interface
    //
    Size = GetDevicePathSize (Prot->Interface);
    ASSERT (Size >= END_DEVICE_PATH_LENGTH);
    if ((Size == SourceSize) && (CompareMem (DevicePath, Prot->Interface, Size - END_DEVICE_PATH_LENGTH) == 0)) {
      Found = TRUE;
      break;
    }
  }

Done:
  CoreReleaseProtocolLock ();
  return Found;
}

/**
  Removes an event from a register protocol notify list on a protocol.

  @param  Event                  The event to search for in the protocol
                                 database.

  @return EFI_SUCCESS   if the event was found and removed.
  @return EFI_NOT_FOUND if the event was not found in the protocl database.

**/
EFI_STATUS
CoreUnregisterProtocolNotifyEvent (
  IN EFI_EVENT  Event
  )
{
  LIST_ENTRY       *Link;
  PROTOCOL_ENTRY   *ProtEntry;
  LIST_ENTRY       *NotifyLink;
  PROTOCOL_NOTIFY  *ProtNotify;

  CoreAcquireProtocolLock ();

  for ( Link =  mProtocolDatabase.ForwardLink;
        Link != &mProtocolDatabase;
        Link =  Link->ForwardLink)
  {
    ProtEntry = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);

    for ( NotifyLink =  ProtEntry->Notify.ForwardLink;
          NotifyLink != &ProtEntry->Notify;
          NotifyLink =  NotifyLink->ForwardLink)
    {
      ProtNotify = CR (NotifyLink, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);

      if (ProtNotify->Event == Event) {
        RemoveEntryList (&ProtNotify->Link);
        CoreFreePool (ProtNotify);
        CoreReleaseProtocolLock ();
        return EFI_SUCCESS;
      }
    }
  }

  CoreReleaseProtocolLock ();
  return EFI_NOT_FOUND;
}

/**
  Removes all the events in the protocol database that match Event.

  @param  Event                  The event to search for in the protocol
                                 database.

  @return EFI_SUCCESS when done searching the entire database.

**/
EFI_STATUS
CoreUnregisterProtocolNotify (
  IN EFI_EVENT  Event
  )
{
  EFI_STATUS  Status;

  do {
    Status = CoreUnregisterProtocolNotifyEvent (Event);
  } while (!EFI_ERROR (Status));

  return EFI_SUCCESS;
}

/**
  Wrapper function to CoreInstallProtocolInterfaceNotify.  This is the public API which
  Calls the private one which contains a BOOLEAN parameter for notifications

  @param  UserHandle             The handle to install the protocol handler on,
                                 or NULL if a new handle is to be allocated
  @param  Protocol               The protocol to add to the handle
  @param  InterfaceType          Indicates whether Interface is supplied in
                                 native form.
  @param  Interface              The interface for the protocol being added

  @return Status code

**/
EFI_STATUS
EFIAPI
CoreInstallProtocolInterface (
  IN OUT EFI_HANDLE      *UserHandle,
  IN EFI_GUID            *Protocol,
  IN EFI_INTERFACE_TYPE  InterfaceType,
  IN VOID                *Interface
  )
{
  return CoreInstallProtocolInterfaceNotify (
           UserHandle,
           Protocol,
           InterfaceType,
           Interface,
           TRUE
           );
}

/**
  Installs a protocol interface into the boot services environment.

  @param  UserHandle             The handle to install the protocol handler on,
                                 or NULL if a new handle is to be allocated
  @param  Protocol               The protocol to add to the handle
  @param  InterfaceType          Indicates whether Interface is supplied in
                                 native form.
  @param  Interface              The interface for the protocol being added
  @param  Notify                 indicates whether notify the notification list
                                 for this protocol

  @retval EFI_INVALID_PARAMETER  Invalid parameter
  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate
  @retval EFI_SUCCESS            Protocol interface successfully installed

**/
EFI_STATUS
CoreInstallProtocolInterfaceNotify (
  IN OUT EFI_HANDLE      *UserHandle,
  IN EFI_GUID            *Protocol,
  IN EFI_INTERFACE_TYPE  InterfaceType,
  IN VOID                *Interface,
  IN BOOLEAN             Notify
  )
{
  PROTOCOL_INTERFACE  *Prot;
  PROTOCOL_ENTRY      *ProtEntry;
  IHANDLE             *Handle;
  EFI_STATUS          Status;
  VOID                *ExistingInterface;

  //
  // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
  // Also added check for invalid UserHandle and Protocol pointers.
  //
  if ((UserHandle == NULL) || (Protocol == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (InterfaceType != EFI_NATIVE_INTERFACE) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Print debug message
  //
  DEBUG ((DEBUG_INFO, "InstallProtocolInterface: %g %p\n", Protocol, Interface));

  Status = EFI_OUT_OF_RESOURCES;
  Prot   = NULL;
  Handle = NULL;

  if (*UserHandle != NULL) {
    Status = CoreHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);
    if (!EFI_ERROR (Status)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Lock the protocol database
  //
  CoreAcquireProtocolLock ();

  //
  // Lookup the Protocol Entry for the requested protocol
  //
  ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);
  if (ProtEntry == NULL) {
    goto Done;
  }

  //
  // Allocate a new protocol interface structure
  //
  Prot = AllocateZeroPool (sizeof (PROTOCOL_INTERFACE));
  if (Prot == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // If caller didn't supply a handle, allocate a new one
  //
  Handle = (IHANDLE *)*UserHandle;
  if (Handle == NULL) {
    Handle = AllocateZeroPool (sizeof (IHANDLE));
    if (Handle == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    //
    // Add this handle to the ordered list of all handles
    // in the system
    //
    Status = OrderedCollectionInsert (gOrderedHandleList, NULL, Handle);
    if (EFI_ERROR (Status)) {
      CoreFreePool (Handle);
      goto Done;
    }

    //
    // Initialize new handler structure
    //
    Handle->Signature = EFI_HANDLE_SIGNATURE;
    InitializeListHead (&Handle->Protocols);

    //
    // Add this handle to the list global list of all handles
    // in the system
    //
    InsertTailList (&gHandleList, &Handle->AllHandles);
  } else {
    Status = CoreValidateHandle (Handle);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));
      goto Done;
    }
  }

  //
  // Initialize/update the Key to show that the handle has been created/modified
  //
  gHandleDatabaseKey++;
  Handle->Key = gHandleDatabaseKey;

  //
  // Each interface that is added must be unique
  //
  ASSERT (CoreFindProtocolInterface (Handle, Protocol, Interface) == NULL);

  //
  // Initialize the protocol interface structure
  //
  Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;
  Prot->Handle    = Handle;
  Prot->Protocol  = ProtEntry;
  Prot->Interface = Interface;

  //
  // Initalize OpenProtocol Data base
  //
  InitializeListHead (&Prot->OpenList);
  Prot->OpenListCount = 0;

  //
  // Add this protocol interface to the head of the supported
  // protocol list for this handle
  //
  InsertHeadList (&Handle->Protocols, &Prot->Link);

  //
  // Add this protocol interface to the tail of the
  // protocol entry
  //
  InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);

  //
  // Notify the notification list for this protocol
  //
  if (Notify) {
    CoreNotifyProtocolEntry (ProtEntry);
  }

  Status = EFI_SUCCESS;

Done:
  //
  // Done, unlock the database and return
  //
  CoreReleaseProtocolLock ();
  if (!EFI_ERROR (Status)) {
    //
    // Return the new handle back to the caller
    //
    *UserHandle = Handle;
  } else {
    //
    // There was an error, clean up
    //
    if (Prot != NULL) {
      CoreFreePool (Prot);
    }

    DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));
  }

  return Status;
}

/**
  Installs a list of protocol interface into the boot services environment.
  This function calls InstallProtocolInterface() in a loop. If any error
  occures all the protocols added by this function are removed. This is
  basically a lib function to save space.

  @param  Handle                 The pointer to a handle to install the new
                                 protocol interfaces on, or a pointer to NULL
                                 if a new handle is to be allocated.
  @param  ...                    EFI_GUID followed by protocol instance. A NULL
                                 terminates the  list. The pairs are the
                                 arguments to InstallProtocolInterface(). All the
                                 protocols are added to Handle.

  @retval EFI_SUCCESS            All the protocol interface was installed.
  @retval EFI_OUT_OF_RESOURCES   There was not enough memory in pool to install all the protocols.
  @retval EFI_ALREADY_STARTED    A Device Path Protocol instance was passed in that is already present in
                                 the handle database.
  @retval EFI_INVALID_PARAMETER  Handle is NULL.
  @retval EFI_INVALID_PARAMETER  Protocol is already installed on the handle specified by Handle.

**/
EFI_STATUS
EFIAPI
CoreInstallMultipleProtocolInterfaces (
  IN OUT EFI_HANDLE  *Handle,
  ...
  )
{
  VA_LIST     Args;
  EFI_STATUS  Status;
  EFI_GUID    *Protocol;
  VOID        *Interface;
  EFI_TPL     OldTpl;
  UINTN       Index;
  EFI_HANDLE  OldHandle;

  if (Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Syncronize with notifcations.
  //
  OldTpl    = CoreRaiseTpl (TPL_NOTIFY);
  OldHandle = *Handle;

  //
  // Check for duplicate device path and install the protocol interfaces
  //
  VA_START (Args, Handle);
  for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
    //
    // If protocol is NULL, then it's the end of the list
    //
    Protocol = VA_ARG (Args, EFI_GUID *);
    if (Protocol == NULL) {
      break;
    }

    Interface = VA_ARG (Args, VOID *);

    //
    // Make sure you are installing on top a device path that has already been added.
    //
    if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid) &&
        IsDevicePathInstalled (Interface))
    {
      Status = EFI_ALREADY_STARTED;
      continue;
    }

    //
    // Install it
    //
    Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
  }

  VA_END (Args);

  //
  // If there was an error, remove all the interfaces that were installed without any errors
  //
  if (EFI_ERROR (Status)) {
    //
    // Reset the va_arg back to the first argument.
    //
    VA_START (Args, Handle);
    for ( ; Index > 1; Index--) {
      Protocol  = VA_ARG (Args, EFI_GUID *);
      Interface = VA_ARG (Args, VOID *);
      CoreUninstallProtocolInterface (*Handle, Protocol, Interface);
    }

    VA_END (Args);

    *Handle = OldHandle;
  }

  //
  // Done
  //
  CoreRestoreTpl (OldTpl);
  return Status;
}

/**
  Attempts to disconnect all drivers that are using the protocol interface being queried.
  If failed, reconnect all drivers disconnected.
  Note: This function doesn't do parameters checking, it's caller's responsibility
  to pass in valid parameters.

  @param  UserHandle             The handle on which the protocol is installed
  @param  Prot                   The protocol to disconnect drivers from

  @retval EFI_SUCCESS            Drivers using the protocol interface are all
                                 disconnected
  @retval EFI_ACCESS_DENIED      Failed to disconnect one or all of the drivers

**/
EFI_STATUS
CoreDisconnectControllersUsingProtocolInterface (
  IN EFI_HANDLE          UserHandle,
  IN PROTOCOL_INTERFACE  *Prot
  )
{
  EFI_STATUS          Status;
  BOOLEAN             ItemFound;
  LIST_ENTRY          *Link;
  OPEN_PROTOCOL_DATA  *OpenData;

  Status = EFI_SUCCESS;

  //
  // Attempt to disconnect all drivers from this protocol interface
  //
  do {
    ItemFound = FALSE;
    for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
      OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
      if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
        CoreReleaseProtocolLock ();
        Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
        CoreAcquireProtocolLock ();
        if (!EFI_ERROR (Status)) {
          ItemFound = TRUE;
        }

        break;
      }
    }
  } while (ItemFound);

  if (!EFI_ERROR (Status)) {
    //
    // Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items
    //
    for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) {
      OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
      if ((OpenData->Attributes &
           (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0)
      {
        Link = RemoveEntryList (&OpenData->Link);
        Prot->OpenListCount--;
        CoreFreePool (OpenData);
      } else {
        Link = Link->ForwardLink;
      }
    }
  }

  //
  // If there are errors or still has open items in the list, then reconnect all the drivers and return an error
  //
  if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {
    CoreReleaseProtocolLock ();
    CoreConnectController (UserHandle, NULL, NULL, TRUE);
    CoreAcquireProtocolLock ();
    Status = EFI_ACCESS_DENIED;
  }

  return Status;
}

/**
  Uninstalls all instances of a protocol:interfacer from a handle.
  If the last protocol interface is remove from the handle, the
  handle is freed.

  @param  UserHandle             The handle to remove the protocol handler from
  @param  Protocol               The protocol, of protocol:interface, to remove
  @param  Interface              The interface, of protocol:interface, to remove

  @retval EFI_INVALID_PARAMETER  Protocol is NULL.
  @retval EFI_SUCCESS            Protocol interface successfully uninstalled.

**/
EFI_STATUS
EFIAPI
CoreUninstallProtocolInterface (
  IN EFI_HANDLE  UserHandle,
  IN EFI_GUID    *Protocol,
  IN VOID        *Interface
  )
{
  EFI_STATUS          Status;
  IHANDLE             *Handle;
  PROTOCOL_INTERFACE  *Prot;

  //
  // Check that Protocol is valid
  //
  if (Protocol == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Lock the protocol database
  //
  CoreAcquireProtocolLock ();

  //
  // Check that UserHandle is a valid handle
  //
  Status = CoreValidateHandle (UserHandle);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
  //
  Prot = CoreFindProtocolInterface (UserHandle, Protocol, Interface);
  if (Prot == NULL) {
    Status = EFI_NOT_FOUND;
    goto Done;
  }

  //
  // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed
  //
  Status = CoreDisconnectControllersUsingProtocolInterface (
             UserHandle,
             Prot
             );
  if (EFI_ERROR (Status)) {
    //
    // One or more drivers refused to release, so return the error
    //
    goto Done;
  }

  //
  // Remove the protocol interface from the protocol
  //
  Status = EFI_NOT_FOUND;
  Handle = (IHANDLE *)UserHandle;
  Prot   = CoreRemoveInterfaceFromProtocol (Handle, Protocol, Interface);

  if (Prot != NULL) {
    //
    // Update the Key to show that the handle has been created/modified
    //
    gHandleDatabaseKey++;
    Handle->Key = gHandleDatabaseKey;

    //
    // Remove the protocol interface from the handle
    //
    RemoveEntryList (&Prot->Link);

    //
    // Free the memory
    //
    Prot->Signature = 0;
    CoreFreePool (Prot);
    Status = EFI_SUCCESS;
  }

  //
  // If there are no more handlers for the handle, free the handle
  //
  if (IsListEmpty (&Handle->Protocols)) {
    Handle->Signature = 0;
    OrderedCollectionDelete (
      gOrderedHandleList,
      OrderedCollectionFind (gOrderedHandleList, Handle),
      NULL
      );
    RemoveEntryList (&Handle->AllHandles);
    CoreFreePool (Handle);
  }

Done:
  //
  // Done, unlock the database and return
  //
  CoreReleaseProtocolLock ();
  return Status;
}

/**
  Uninstalls a list of protocol interface in the boot services environment.
  This function calls UninstallProtocolInterface() in a loop. This is
  basically a lib function to save space.

  If any errors are generated while the protocol interfaces are being
  uninstalled, then the protocol interfaces uninstalled prior to the error will
  be reinstalled and EFI_INVALID_PARAMETER will be returned.

  @param  Handle                 The handle to uninstall the protocol interfaces
                                 from.
  @param  ...                    EFI_GUID followed by protocol instance. A NULL
                                 terminates the list. The pairs are the
                                 arguments to UninstallProtocolInterface(). All
                                 the protocols are added to Handle.

  @retval EFI_SUCCESS            if all protocol interfaces where uninstalled.
  @retval EFI_INVALID_PARAMETER  if any protocol interface could not be
                                 uninstalled and an attempt was made to
                                 reinstall previously uninstalled protocol
                                 interfaces.
**/
EFI_STATUS
EFIAPI
CoreUninstallMultipleProtocolInterfaces (
  IN EFI_HANDLE  Handle,
  ...
  )
{
  EFI_STATUS  Status;
  VA_LIST     Args;
  EFI_GUID    *Protocol;
  VOID        *Interface;
  UINTN       Index;

  VA_START (Args, Handle);
  for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
    //
    // If protocol is NULL, then it's the end of the list
    //
    Protocol = VA_ARG (Args, EFI_GUID *);
    if (Protocol == NULL) {
      break;
    }

    Interface = VA_ARG (Args, VOID *);

    //
    // Uninstall it
    //
    Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface);
  }

  VA_END (Args);

  //
  // If there was an error, add all the interfaces that were
  // uninstalled without any errors
  //
  if (EFI_ERROR (Status)) {
    //
    // Reset the va_arg back to the first argument.
    //
    VA_START (Args, Handle);
    for ( ; Index > 1; Index--) {
      Protocol  = VA_ARG (Args, EFI_GUID *);
      Interface = VA_ARG (Args, VOID *);
      CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
    }

    VA_END (Args);
    Status = EFI_INVALID_PARAMETER;
  }

  return Status;
}

/**
  Locate a certain GUID protocol interface in a Handle's protocols.

  @param  UserHandle             The handle to obtain the protocol interface on
                                 The caller must pass in a valid UserHandle that
                                 is checked with CoreValidateHandle().
  @param  Protocol               The GUID of the protocol

  @return The requested protocol interface for the handle

**/
STATIC
PROTOCOL_INTERFACE  *
CoreGetProtocolInterface (
  IN  EFI_HANDLE  UserHandle,
  IN  EFI_GUID    *Protocol
  )
{
  PROTOCOL_ENTRY      *ProtEntry;
  PROTOCOL_INTERFACE  *Prot;
  IHANDLE             *Handle;
  LIST_ENTRY          *Link;

  Handle = (IHANDLE *)UserHandle;

  //
  // Look at each protocol interface for a match
  //
  for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
    Prot      = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
    ProtEntry = Prot->Protocol;
    if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) {
      return Prot;
    }
  }

  return NULL;
}

/**
  Queries a handle to determine if it supports a specified protocol.

  @param  UserHandle             The handle being queried.
  @param  Protocol               The published unique identifier of the protocol.
  @param  Interface              Supplies the address where a pointer to the
                                 corresponding Protocol Interface is returned.

  @retval EFI_SUCCESS            The interface information for the specified protocol was returned.
  @retval EFI_UNSUPPORTED        The device does not support the specified protocol.
  @retval EFI_INVALID_PARAMETER  Handle is NULL..
  @retval EFI_INVALID_PARAMETER  Protocol is NULL.
  @retval EFI_INVALID_PARAMETER  Interface is NULL.

**/
EFI_STATUS
EFIAPI
CoreHandleProtocol (
  IN EFI_HANDLE  UserHandle,
  IN EFI_GUID    *Protocol,
  OUT VOID       **Interface
  )
{
  return CoreOpenProtocol (
           UserHandle,
           Protocol,
           Interface,
           gDxeCoreImageHandle,
           NULL,
           EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
           );
}

/**
  Locates the installed protocol handler for the handle, and
  invokes it to obtain the protocol interface. Usage information
  is registered in the protocol data base.

  @param  UserHandle             The handle to obtain the protocol interface on
  @param  Protocol               The ID of the protocol
  @param  Interface              The location to return the protocol interface
  @param  ImageHandle            The handle of the Image that is opening the
                                 protocol interface specified by Protocol and
                                 Interface.
  @param  ControllerHandle       The controller handle that is requiring this
                                 interface.
  @param  Attributes             The open mode of the protocol interface
                                 specified by Handle and Protocol.

  @retval EFI_INVALID_PARAMETER  Protocol is NULL.
  @retval EFI_SUCCESS            Get the protocol interface.

**/
EFI_STATUS
EFIAPI
CoreOpenProtocol (
  IN  EFI_HANDLE  UserHandle,
  IN  EFI_GUID    *Protocol,
  OUT VOID        **Interface OPTIONAL,
  IN  EFI_HANDLE  ImageHandle,
  IN  EFI_HANDLE  ControllerHandle,
  IN  UINT32      Attributes
  )
{
  EFI_STATUS          Status;
  PROTOCOL_INTERFACE  *Prot;
  LIST_ENTRY          *Link;
  OPEN_PROTOCOL_DATA  *OpenData;
  BOOLEAN             ByDriver;
  BOOLEAN             Exclusive;
  BOOLEAN             Disconnect;
  BOOLEAN             ExactMatch;

  //
  // Check for invalid Protocol
  //
  if (Protocol == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check for invalid Interface
  //
  if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Prot = NULL;

  //
  // Lock the protocol database
  //
  CoreAcquireProtocolLock ();

  //
  // Check for invalid UserHandle
  //
  Status = CoreValidateHandle (UserHandle);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Check for invalid Attributes
  //
  switch (Attributes) {
    case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
      Status = CoreValidateHandle (ImageHandle);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      Status = CoreValidateHandle (ControllerHandle);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      if (UserHandle == ControllerHandle) {
        Status = EFI_INVALID_PARAMETER;
        goto Done;
      }

      break;
    case EFI_OPEN_PROTOCOL_BY_DRIVER:
    case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
      Status = CoreValidateHandle (ImageHandle);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      Status = CoreValidateHandle (ControllerHandle);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      break;
    case EFI_OPEN_PROTOCOL_EXCLUSIVE:
      Status = CoreValidateHandle (ImageHandle);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      break;
    case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
    case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
    case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
      break;
    default:
      Status = EFI_INVALID_PARAMETER;
      goto Done;
  }

  //
  // Look at each protocol interface for a match
  //
  Prot = CoreGetProtocolInterface (UserHandle, Protocol);
  if (Prot == NULL) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  Status = EFI_SUCCESS;

  ByDriver  = FALSE;
  Exclusive = FALSE;
  for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
    OpenData   = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
    ExactMatch =  (BOOLEAN)((OpenData->AgentHandle == ImageHandle) &&
                            (OpenData->Attributes == Attributes)  &&
                            (OpenData->ControllerHandle == ControllerHandle));
    if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
      ByDriver = TRUE;
      if (ExactMatch) {
        Status = EFI_ALREADY_STARTED;
        goto Done;
      }
    }

    if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) {
      Exclusive = TRUE;
    } else if (ExactMatch) {
      OpenData->OpenCount++;
      Status = EFI_SUCCESS;
      goto Done;
    }
  }

  //
  // ByDriver  TRUE  -> A driver is managing (UserHandle, Protocol)
  // ByDriver  FALSE -> There are no drivers managing (UserHandle, Protocol)
  // Exclusive TRUE  -> Something has exclusive access to (UserHandle, Protocol)
  // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)
  //

  switch (Attributes) {
    case EFI_OPEN_PROTOCOL_BY_DRIVER:
      if (Exclusive || ByDriver) {
        Status = EFI_ACCESS_DENIED;
        goto Done;
      }

      break;
    case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
    case EFI_OPEN_PROTOCOL_EXCLUSIVE:
      if (Exclusive) {
        Status = EFI_ACCESS_DENIED;
        goto Done;
      }

      if (ByDriver) {
        do {
          Disconnect = FALSE;
          for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
            OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
            if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
              Disconnect = TRUE;
              CoreReleaseProtocolLock ();
              Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
              CoreAcquireProtocolLock ();
              if (EFI_ERROR (Status)) {
                Status = EFI_ACCESS_DENIED;
                goto Done;
              } else {
                break;
              }
            }
          }
        } while (Disconnect);
      }

      break;
    case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
    case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
    case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
    case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
      break;
  }

  if (ImageHandle == NULL) {
    Status = EFI_SUCCESS;
    goto Done;
  }

  //
  // Create new entry
  //
  OpenData = AllocatePool (sizeof (OPEN_PROTOCOL_DATA));
  if (OpenData == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
  } else {
    OpenData->Signature        = OPEN_PROTOCOL_DATA_SIGNATURE;
    OpenData->AgentHandle      = ImageHandle;
    OpenData->ControllerHandle = ControllerHandle;
    OpenData->Attributes       = Attributes;
    OpenData->OpenCount        = 1;
    InsertTailList (&Prot->OpenList, &OpenData->Link);
    Prot->OpenListCount++;
    Status = EFI_SUCCESS;
  }

Done:

  if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
    //
    // Keep Interface unmodified in case of any Error
    // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED.
    //
    if ((!EFI_ERROR (Status) || (Status == EFI_ALREADY_STARTED)) && (Prot != NULL)) {
      //
      // According to above logic, if 'Prot' is NULL, then the 'Status' must be
      // EFI_UNSUPPORTED. Here the 'Status' is not EFI_UNSUPPORTED, so 'Prot'
      // must be not NULL.
      //
      // The ASSERT here is for addressing a false positive NULL pointer
      // dereference issue raised from static analysis.
      //
      ASSERT (Prot != NULL);
      //
      // EFI_ALREADY_STARTED is not an error for bus driver.
      // Return the corresponding protocol interface.
      //
      *Interface = Prot->Interface;
    } else if (Status == EFI_UNSUPPORTED) {
      //
      // Return NULL Interface if Unsupported Protocol.
      //
      *Interface = NULL;
    }
  }

  //
  // Done. Release the database lock and return
  //
  CoreReleaseProtocolLock ();
  return Status;
}

/**
  Closes a protocol on a handle that was opened using OpenProtocol().

  @param  UserHandle             The handle for the protocol interface that was
                                 previously opened with OpenProtocol(), and is
                                 now being closed.
  @param  Protocol               The published unique identifier of the protocol.
                                 It is the caller's responsibility to pass in a
                                 valid GUID.
  @param  AgentHandle            The handle of the agent that is closing the
                                 protocol interface.
  @param  ControllerHandle       If the agent that opened a protocol is a driver
                                 that follows the EFI Driver Model, then this
                                 parameter is the controller handle that required
                                 the protocol interface. If the agent does not
                                 follow the EFI Driver Model, then this parameter
                                 is optional and may be NULL.

  @retval EFI_SUCCESS            The protocol instance was closed.
  @retval EFI_INVALID_PARAMETER  Handle, AgentHandle or ControllerHandle is not a
                                 valid EFI_HANDLE.
  @retval EFI_NOT_FOUND          Can not find the specified protocol or
                                 AgentHandle.

**/
EFI_STATUS
EFIAPI
CoreCloseProtocol (
  IN  EFI_HANDLE  UserHandle,
  IN  EFI_GUID    *Protocol,
  IN  EFI_HANDLE  AgentHandle,
  IN  EFI_HANDLE  ControllerHandle
  )
{
  EFI_STATUS          Status;
  PROTOCOL_INTERFACE  *ProtocolInterface;
  LIST_ENTRY          *Link;
  OPEN_PROTOCOL_DATA  *OpenData;

  //
  // Lock the protocol database
  //
  CoreAcquireProtocolLock ();

  //
  // Check for invalid parameters
  //
  Status = CoreValidateHandle (UserHandle);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = CoreValidateHandle (AgentHandle);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  if (ControllerHandle != NULL) {
    Status = CoreValidateHandle (ControllerHandle);
    if (EFI_ERROR (Status)) {
      goto Done;
    }
  }

  if (Protocol == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

  //
  // Look at each protocol interface for a match
  //
  Status            = EFI_NOT_FOUND;
  ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol);
  if (ProtocolInterface == NULL) {
    goto Done;
  }

  //
  // Walk the Open data base looking for AgentHandle
  //
  Link = ProtocolInterface->OpenList.ForwardLink;
  while (Link != &ProtocolInterface->OpenList) {
    OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
    Link     = Link->ForwardLink;
    if ((OpenData->AgentHandle == AgentHandle) && (OpenData->ControllerHandle == ControllerHandle)) {
      RemoveEntryList (&OpenData->Link);
      ProtocolInterface->OpenListCount--;
      CoreFreePool (OpenData);
      Status = EFI_SUCCESS;
    }
  }

Done:
  //
  // Done. Release the database lock and return.
  //
  CoreReleaseProtocolLock ();
  return Status;
}

/**
  Return information about Opened protocols in the system

  @param  UserHandle             The handle to close the protocol interface on
  @param  Protocol               The ID of the protocol
  @param  EntryBuffer            A pointer to a buffer of open protocol information in the
                                 form of EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
  @param  EntryCount             Number of EntryBuffer entries

  @retval EFI_SUCCESS            The open protocol information was returned in EntryBuffer,
                                 and the number of entries was returned EntryCount.
  @retval EFI_NOT_FOUND          Handle does not support the protocol specified by Protocol.
  @retval EFI_OUT_OF_RESOURCES   There are not enough resources available to allocate EntryBuffer.

**/
EFI_STATUS
EFIAPI
CoreOpenProtocolInformation (
  IN  EFI_HANDLE                           UserHandle,
  IN  EFI_GUID                             *Protocol,
  OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  **EntryBuffer,
  OUT UINTN                                *EntryCount
  )
{
  EFI_STATUS                           Status;
  PROTOCOL_INTERFACE                   *ProtocolInterface;
  LIST_ENTRY                           *Link;
  OPEN_PROTOCOL_DATA                   *OpenData;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *Buffer;
  UINTN                                Count;
  UINTN                                Size;

  *EntryBuffer = NULL;
  *EntryCount  = 0;

  //
  // Lock the protocol database
  //
  CoreAcquireProtocolLock ();

  //
  // Check for invalid UserHandle
  //
  Status = CoreValidateHandle (UserHandle);
  if (EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;
    goto Done;
  }

  //
  // Look at each protocol interface for a match
  //
  Status            = EFI_NOT_FOUND;
  ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol);
  if (ProtocolInterface == NULL) {
    goto Done;
  }

  //
  // Count the number of Open Entries
  //
  for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0;
        (Link != &ProtocolInterface->OpenList);
        Link = Link->ForwardLink  )
  {
    Count++;
  }

  ASSERT (Count == ProtocolInterface->OpenListCount);

  if (Count == 0) {
    Size = sizeof (EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);
  } else {
    Size = Count * sizeof (EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);
  }

  Buffer = AllocatePool (Size);
  if (Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  Status = EFI_SUCCESS;
  for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0;
        (Link != &ProtocolInterface->OpenList);
        Link = Link->ForwardLink, Count++  )
  {
    OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

    Buffer[Count].AgentHandle      = OpenData->AgentHandle;
    Buffer[Count].ControllerHandle = OpenData->ControllerHandle;
    Buffer[Count].Attributes       = OpenData->Attributes;
    Buffer[Count].OpenCount        = OpenData->OpenCount;
  }

  *EntryBuffer = Buffer;
  *EntryCount  = Count;

Done:
  //
  // Done. Release the database lock.
  //
  CoreReleaseProtocolLock ();
  return Status;
}

/**
  Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
  from pool.

  @param  UserHandle             The handle from which to retrieve the list of
                                 protocol interface GUIDs.
  @param  ProtocolBuffer         A pointer to the list of protocol interface GUID
                                 pointers that are installed on Handle.
  @param  ProtocolBufferCount    A pointer to the number of GUID pointers present
                                 in ProtocolBuffer.

  @retval EFI_SUCCESS            The list of protocol interface GUIDs installed
                                 on Handle was returned in ProtocolBuffer. The
                                 number of protocol interface GUIDs was returned
                                 in ProtocolBufferCount.
  @retval EFI_INVALID_PARAMETER  Handle is NULL.
  @retval EFI_INVALID_PARAMETER  Handle is not a valid EFI_HANDLE.
  @retval EFI_INVALID_PARAMETER  ProtocolBuffer is NULL.
  @retval EFI_INVALID_PARAMETER  ProtocolBufferCount is NULL.
  @retval EFI_OUT_OF_RESOURCES   There is not enough pool memory to store the
                                 results.

**/
EFI_STATUS
EFIAPI
CoreProtocolsPerHandle (
  IN EFI_HANDLE  UserHandle,
  OUT EFI_GUID   ***ProtocolBuffer,
  OUT UINTN      *ProtocolBufferCount
  )
{
  EFI_STATUS          Status;
  IHANDLE             *Handle;
  PROTOCOL_INTERFACE  *Prot;
  LIST_ENTRY          *Link;
  UINTN               ProtocolCount;
  EFI_GUID            **Buffer;

  if (ProtocolBuffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (ProtocolBufferCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *ProtocolBufferCount = 0;

  ProtocolCount = 0;

  CoreAcquireProtocolLock ();

  Status = CoreValidateHandle (UserHandle);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Handle = (IHANDLE *)UserHandle;

  for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
    ProtocolCount++;
  }

  //
  // If there are no protocol interfaces installed on Handle, then Handle is not a valid EFI_HANDLE
  //
  if (ProtocolCount == 0) {
    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

  Buffer = AllocatePool (sizeof (EFI_GUID *) * ProtocolCount);
  if (Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  *ProtocolBuffer      = Buffer;
  *ProtocolBufferCount = ProtocolCount;

  for ( Link = Handle->Protocols.ForwardLink, ProtocolCount = 0;
        Link != &Handle->Protocols;
        Link = Link->ForwardLink, ProtocolCount++)
  {
    Prot                  = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
    Buffer[ProtocolCount] = &(Prot->Protocol->ProtocolID);
  }

  Status = EFI_SUCCESS;

Done:
  CoreReleaseProtocolLock ();
  return Status;
}

/**
  return handle database key.


  @return Handle database key.

**/
UINT64
CoreGetHandleDatabaseKey (
  VOID
  )
{
  return gHandleDatabaseKey;
}

/**
  Go connect any handles that were created or modified while a image executed.

  @param  Key                    The Key to show that the handle has been
                                 created/modified

**/
VOID
CoreConnectHandlesByKey (
  UINT64  Key
  )
{
  UINTN       Count;
  LIST_ENTRY  *Link;
  EFI_HANDLE  *HandleBuffer;
  IHANDLE     *Handle;
  UINTN       Index;

  //
  // Lock the protocol database
  //
  CoreAcquireProtocolLock ();

  for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) {
    Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
    if (Handle->Key > Key) {
      Count++;
    }
  }

  HandleBuffer = AllocatePool (Count * sizeof (EFI_HANDLE));
  if (HandleBuffer == NULL) {
    CoreReleaseProtocolLock ();
    return;
  }

  for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) {
    Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
    if (Handle->Key > Key) {
      HandleBuffer[Count++] = Handle;
    }
  }

  //
  // Unlock the protocol database
  //
  CoreReleaseProtocolLock ();

  //
  // Connect all handles whose Key value is greater than Key
  //
  for (Index = 0; Index < Count; Index++) {
    CoreConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
  }

  CoreFreePool (HandleBuffer);
}
