getinfo.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 562 行 · 第 1/2 页

C
562
字号
/*++
Copyright (c) 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:
  GetInfo.c

Abstract:
  
  Some library routines to get drivers related infos


--*/
#include "GetInfo.h"

EFI_STATUS
GetDeviceHandlesManagedByDriver (
  IN  EFI_HANDLE  DriverBindingHandle,
  OUT UINTN       *ControllerHandleCount,
  OUT EFI_HANDLE  **ControllerHandleBuffer
  )
/*++

Routine Description:
  Get all device handles which are being opened by a specific driver.
  The rountine will allocate pool buffer for the found device handles, and it is the caller's responsibility to safe
  free the buffer
  
Arguments:
  DriverBindingHandle - the handle of a driver which contains the binding protocol
  ControllerHandleCount - the number of available device handles returned in ControllerHandleBuffer
  ControllerHandleBuffer - a pointer to the buffer to return the array of device handles
  
Returns:
  EFI_STATUS
  If returned status is not succeful or find no available device , the *ControllerHandleBuffer will be NULL
  
--*/
{
  UINTN                               HandleCount;
  EFI_HANDLE                          *HandleBuffer;
  BOOLEAN                             *HandleBufferMap;
  EFI_STATUS                          Status;
  UINTN                               HandleIndex;
  UINTN                               AvailableIndex;
  EFI_GUID                            **ProtocolGuidArray;
  UINTN                               ArrayCount;
  UINTN                               ProtocolIndex;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
  UINTN                               OpenInfoCount;
  UINTN                               OpenInfoIndex;
  
  *ControllerHandleCount  = 0;
  *ControllerHandleBuffer = NULL;
  HandleCount = 0;
  HandleBuffer = NULL;  
  
  if (DriverBindingHandle == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Error;
  }
  
  //
  // Retrieve the list of all handles from the handle database
  //
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  NULL,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  
  //
  //Create a map for HandleBuffer. If a handle in HandleBuffer is the wanted device handle, its map item is true.
  //
  HandleBufferMap = EfiLibAllocateZeroPool (sizeof (BOOLEAN) * HandleCount);
  ASSERT (HandleBufferMap != NULL);
  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
    HandleBufferMap[HandleIndex] = FALSE;
  }
  
  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
    //
    // Check if it is a device handle
    //
    Status = gBS->OpenProtocol (
                    HandleBuffer[HandleIndex],
                    &gEfiDevicePathProtocolGuid,
                    NULL,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }
    //
    // Retrieve the list of all the protocols on each handle
    //
    Status = gBS->ProtocolsPerHandle (
                    HandleBuffer[HandleIndex],
                    &ProtocolGuidArray,
                    &ArrayCount
                    );
                  
    if (!EFI_ERROR (Status)) {
      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
        //
        // Retrieve the list of agents that have opened each protocol
        //
        Status = gBS->OpenProtocolInformation (
                        HandleBuffer[HandleIndex],
                        ProtocolGuidArray[ProtocolIndex],
                        &OpenInfo,
                        &OpenInfoCount
                        );
        if (!EFI_ERROR (Status)) {
          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
            if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
              if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER)
                  == EFI_OPEN_PROTOCOL_BY_DRIVER
                 ){
                //
                // HandleBufferMap[HandleIndex] is the wanted device handle, find it in the handlebuffer
                // A bus driver maybe open a Controller with BY_DRIVER attribute for different protocol  many times, 
                //
                HandleBufferMap[HandleIndex] = TRUE;
              }
            }
          }
          gBS->FreePool (OpenInfo);
        }
      }
      gBS->FreePool (ProtocolGuidArray);
    }
  }
  //
  // count how many device handles are found
  //
  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
    if (HandleBufferMap[HandleIndex]) {
      (*ControllerHandleCount)++;
    }
  }
  
  if (*ControllerHandleCount > 0) {
    //
    // Copy the found device handle to returned buffer
    //
    *ControllerHandleBuffer = EfiLibAllocateZeroPool (sizeof (EFI_HANDLE) * (*ControllerHandleCount));
    ASSERT (*ControllerHandleBuffer != NULL);
    for (HandleIndex = 0, AvailableIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
      if (HandleBufferMap[HandleIndex]) {
        (*ControllerHandleBuffer)[AvailableIndex] = HandleBuffer[HandleIndex];
        AvailableIndex++;
      }
    }
  }
  
  if (HandleBuffer != NULL) {
    gBS->FreePool (HandleBuffer);
  }
  
  return EFI_SUCCESS;

Error:

  if (HandleBuffer != NULL) {
    gBS->FreePool (HandleBuffer);
  }

  return Status;
}

EFI_STATUS
GetChildDeviceHandlesManagedByDriver (
  IN  EFI_HANDLE  DriverBindingHandle,
  IN  EFI_HANDLE  ControllerHandle,
  OUT UINTN       *ChildControllerHandleCount,
  OUT EFI_HANDLE  **ChildControllerHandleBuffer
  )
/*++

Routine Description:
  Get all child device handles which are being opened by a specific driver.
  The rountine will allocate pool buffer for the found child device handles, and it is the caller's responsibility to safe
  free the buffer
  
Arguments:
  DriverBindingHandle - the handle of a driver which contains the binding protocol
  ControllerHandle - the device controller handle be opened by its child device 
  ChildControllerHandleCount - the number of available device handles returned in ControllerHandleBuffer
  ChildControllerHandleBuffer - a pointer to the buffer to return the array of child device handles
  
Returns:
  EFI_STATUS
  If returned status is not succeful or find no available device , the *ChildControllerHandleBuffer will be NULL
  
--*/

{
  UINTN                               HandleCount;
  EFI_HANDLE                          *HandleBuffer;
  BOOLEAN                             *HandleBufferMap;
  EFI_STATUS                          Status;
  UINTN                               HandleIndex;
  UINTN                               AvailableIndex;
  EFI_GUID                            **ProtocolGuidArray;
  UINTN                               ArrayCount;
  UINTN                               ProtocolIndex;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
  UINTN                               OpenInfoCount;
  UINTN                               OpenInfoIndex;
  
  *ChildControllerHandleCount  = 0;
  *ChildControllerHandleBuffer = NULL;
  HandleCount = 0;
  HandleBuffer = NULL;  
  
  if ((DriverBindingHandle == NULL) || (ControllerHandle == NULL)) {
    Status = EFI_INVALID_PARAMETER;
    goto Error;
  }
  
  //
  // Retrieve the list of all handles from the handle database
  //
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  NULL,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  //
  //Create a map for HandleBuffer. If a handle in HandleBuffer is the wanted device handle, its map item is true.
  //
  HandleBufferMap = EfiLibAllocateZeroPool (sizeof (BOOLEAN) * HandleCount);
  ASSERT (HandleBufferMap != NULL);
  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
    HandleBufferMap[HandleIndex] = FALSE;
  }
  
  //
  // Retrieve the list of all the protocols on each handle
  //
  Status = gBS->ProtocolsPerHandle (
                  ControllerHandle,
                  &ProtocolGuidArray,
                  &ArrayCount
                  );
                
  if (!EFI_ERROR (Status)) {
    for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
      //
      // Retrieve the list of agents that have opened each protocol
      //
      Status = gBS->OpenProtocolInformation (
                      ControllerHandle,
                      ProtocolGuidArray[ProtocolIndex],
                      &OpenInfo,
                      &OpenInfoCount
                      );
      if (!EFI_ERROR (Status)) {
        for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
          if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
            if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
                  == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?