/* For example, IP will open a MNP child to transmit/receive packets, when MNP is stopped, IP should also be stopped. IP needs to find its own private data which is related the IP's service binding instance that is install on UNDI/SNP handle. Now, the controller is either a MNP or ARP child handle. But IP opens these handle BY_DRIVER, use that info, we can get the UNDI/SNP handle. */
EFI_HANDLE EFIAPI NetLibGetNicHandle(IN EFI_HANDLE Controller, IN EFI_GUID *ProtocolGuid)
/* For example, IP will open a MNP child to transmit/receive packets, when MNP is stopped, IP should also be stopped. IP needs to find its own private data which is related the IP's service binding instance that is install on UNDI/SNP handle. Now, the controller is either a MNP or ARP child handle. But IP opens these handle BY_DRIVER, use that info, we can get the UNDI/SNP handle. */
EFI_HANDLE EFIAPI NetLibGetNicHandle(IN EFI_HANDLE Controller, IN EFI_GUID *ProtocolGuid)
{
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenBuffer;
  EFI_HANDLE                           Handle;
  EFI_STATUS                           Status;
  UINTN                                OpenCount;
  UINTN                                Index;
  ASSERT (ProtocolGuid != NULL);
  Status = gBS->OpenProtocolInformation (
                  Controller,
                  ProtocolGuid,
                  &OpenBuffer,
                  &OpenCount
                  );
  if (EFI_ERROR (Status)) {
    return NULL;
  }
  Handle = NULL;
  for (Index = 0; Index < OpenCount; Index++) {
    if ((OpenBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
      Handle = OpenBuffer[Index].ControllerHandle;
      break;
    }
  }
  gBS->FreePool (OpenBuffer);
  return Handle;
}