⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handle.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 3 页
字号:
  // Check for invalid UserHandle
  //
  Status = ValidateHandle (UserHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Check for invalid Attributes
  //
  switch (Attributes) {
  case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :
    Status = ValidateHandle (ImageHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Status = ValidateHandle (ControllerHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    if (UserHandle == ControllerHandle) {
      return EFI_INVALID_PARAMETER;
    }
    break;
  case EFI_OPEN_PROTOCOL_BY_DRIVER :
  case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :
    Status = ValidateHandle (ImageHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Status = ValidateHandle (ControllerHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    break;
  case EFI_OPEN_PROTOCOL_EXCLUSIVE :
    Status = ValidateHandle (ImageHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    break;
  case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :
  case EFI_OPEN_PROTOCOL_GET_PROTOCOL :
  case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :
    break;
  default:
    return EFI_INVALID_PARAMETER;
  }

  //
  // Lock the protocol database
  //
  AcquireLock (&ProtocolDatabaseLock);

  //
  // Look at each protocol interface for a match
  //
  Prot = GetProtocolEntry (UserHandle, Protocol);
  if (Prot == NULL) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  //
  // This is the protocol interface entry for this protocol
  //    
  if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
    *Interface = Prot->Interface;
  }
  Status = EFI_SUCCESS;

  ByDriver        = FALSE;
  Exclusive       = FALSE;
  for ( Link = Prot->OpenList.Flink; Link != &Prot->OpenList; Link = Link->Flink) {
    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) {
      ByDriver = TRUE;
      if (ExactMatch) {
        Status = EFI_ALREADY_STARTED;
        goto Done;
      }
    }
    if (OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {
      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.Flink; Link != &Prot->OpenList && !Disconnect; Link = Link->Flink) {
          OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
          if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
            Disconnect = TRUE;
            ReleaseLock (&ProtocolDatabaseLock);
            Status = BS->DisconnectController (UserHandle, OpenData->AgentHandle, NULL);
            AcquireLock (&ProtocolDatabaseLock);
            if (EFI_ERROR (Status)) {
              Status = EFI_ACCESS_DENIED;
              goto Done;
            }
          }
        }
      } 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){
    //
    // Create new entry
    //
    Status = BS->AllocatePool (EfiBootServicesData, sizeof(OPEN_PROTOCOL_DATA), &OpenData);
    if (!EFI_ERROR (Status)) {
      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:
  //
  // Done. Release the database lock are return
  //
  ReleaseLock (&ProtocolDatabaseLock);
  return Status;
}

EFI_STATUS
BOOTSERVICE
CloseProtocol (
  IN  EFI_HANDLE                UserHandle,
  IN  EFI_GUID                  *Protocol,
  IN  EFI_HANDLE                ImageHandle,
  IN  EFI_HANDLE                ControllerHandle  OPTIONAL
  )
/*++

Routine Description:

  Close Protocol

Arguments:

  UserHandle       - The handle to close the protocol interface on

  Protocol         - The ID of the protocol 

  ImageHandle      - The user of the protocol to close

  ControllerHandle - The user of the protocol to close

Returns:

  
--*/
{
  EFI_STATUS          Status;
  PROTOCOL_INTERFACE  *ProtocolInterface;
  LIST_ENTRY      *Link;
  OPEN_PROTOCOL_DATA  *OpenData;
  BOOLEAN             Removed;

  //
  // Check for invalid parameters
  //
  Status = ValidateHandle (UserHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ValidateHandle (ImageHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  if (ControllerHandle != NULL) {
    Status = ValidateHandle (ControllerHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  if (Protocol == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Lock the protocol database
  //
  AcquireLock (&ProtocolDatabaseLock);

  //
  // Look at each protocol interface for a match
  //
  Status = EFI_NOT_FOUND;
  ProtocolInterface = GetProtocolEntry (UserHandle, Protocol);
  if (ProtocolInterface == NULL) {
    goto Done;
  }

  //
  // Walk the Open data base looking for ImageHandle
  //
  do {
    Removed = FALSE;
    for ( Link = ProtocolInterface->OpenList.Flink; 
          (Link != &ProtocolInterface->OpenList) && Removed == FALSE;
          Link = Link->Flink
          ) {
      OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
    
      if (OpenData->AgentHandle == ImageHandle && OpenData->ControllerHandle == ControllerHandle) {
        RemoveEntryList (&OpenData->Link);  
        ProtocolInterface->OpenListCount--;
        BS->FreePool (OpenData);
        Removed = TRUE;
        Status = EFI_SUCCESS;
      }
    }
  } while (Removed == TRUE);

Done:
  //
  // Done. Release the database lock are return
  //
  ReleaseLock (&ProtocolDatabaseLock);
  return Status;
}

EFI_STATUS
BOOTSERVICE
OpenProtocolInformation (
  IN  EFI_HANDLE                          UserHandle,
  IN  EFI_GUID                            *Protocol,
  IN  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
  OUT UINTN                               *EntryCount
  )
/*++

Routine Description:

  Return information about Opened protocols in the system

Arguments:

  UserHandle  - The handle to close the protocol interface on

  Protocol    - The ID of the protocol 

  EntryBuffer - 

  EntryCount  - Number of EntryBuffer entries

Returns:

  
--*/
{
  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
  //
  AcquireLock (&ProtocolDatabaseLock);

  //
  // Look at each protocol interface for a match
  //
  Status = EFI_NOT_FOUND;
  ProtocolInterface = GetProtocolEntry (UserHandle, Protocol);
  if (ProtocolInterface == NULL) {
    goto Done;
  }

  //
  // Count the number of Open Entries
  //
  for ( Link = ProtocolInterface->OpenList.Flink, Count = 0; 
        (Link != &ProtocolInterface->OpenList) ;
        Link = Link->Flink  ) {
    Count++;
  } 

  ASSERT (Count == ProtocolInterface->OpenListCount);

  if (Count == 0) {
    Size = sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);
  } else {
    Size = Count * sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);
  }

  Status = BS->AllocatePool (EfiBootServicesData, Size, &Buffer);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }
  
  for ( Link = ProtocolInterface->OpenList.Flink, Count = 0; 
        (Link != &ProtocolInterface->OpenList);
        Link = Link->Flink, 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 are return
  //
  ReleaseLock (&ProtocolDatabaseLock);
  return Status;
}

EFI_STATUS
BOOTSERVICE
ProtocolsPerHandle (
  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;

  Handle = UserHandle;
  if (Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (Handle->Signature != EFI_HANDLE_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  if (ProtocolBuffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (ProtocolBufferCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *ProtocolBufferCount = 0;

  ProtocolCount = 0;
  for (Link = Handle->Protocols.Flink; Link != &Handle->Protocols; Link = Link->Flink) {
    Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
    ProtocolCount++;
  }

  //
  // If there are no protocol interfaces installed on Handle, then Handle is not a valid EFI_HANDLE
  //
  if (ProtocolCount == 0) {
    return EFI_INVALID_PARAMETER;
  }

  Status = BS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (EFI_GUID *) * ProtocolCount,
                  (VOID **)&Buffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *ProtocolBuffer = Buffer;
  *ProtocolBufferCount = ProtocolCount;

  for ( Link = Handle->Protocols.Flink, ProtocolCount = 0;
        Link != &Handle->Protocols; 
        Link = Link->Flink, ProtocolCount++) {
    Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
    Buffer[ProtocolCount] = &(Prot->Protocol->ProtocolID);
  }

  return Status;
}

UINT64
CoreGetHandleDatabaseKey (
  )

{
  return HandleDatabaseKey;
}


VOID
CoreConnectHandlesByKey (
  UINT64  Key
  )

{
  EFI_STATUS      Status;
  UINTN           Count;
  LIST_ENTRY      *Link;
  EFI_HANDLE      *HandleBuffer;
  IHANDLE         *Handle;
  UINTN           Index;

  //
  // Lock the protocol database
  //
  AcquireLock (&ProtocolDatabaseLock);

  for (Link = HandleList.Flink, Count = 0; Link != &HandleList; Link = Link->Flink) {
    Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
    if (Handle->Key > Key) {
      Count++;
    }
  }

  ///////////////////////////////////////////////////////////////////////
  //Append following code to avoid allocate zero size memory 2003-08-07
  if(Count == 0){
	  ReleaseLock(&ProtocolDatabaseLock);
	  return;
  }
  ///////////////////////////////////////////////////////////////////////

  Status = BS->AllocatePool (EfiBootServicesData, Count * sizeof (EFI_HANDLE), (VOID **)&HandleBuffer);
  if (EFI_ERROR (Status)) {
    //Append following line to unlock the resource before exit 2003-08-07
    ReleaseLock(&ProtocolDatabaseLock);
    return;
  }

  for (Link = HandleList.Flink, Count = 0; Link != &HandleList; Link = Link->Flink) {
    Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
    if (Handle->Key > Key) {
      HandleBuffer[Count++] = Handle;
    }
  }

  //
  // Unlock the protocol database
  //
  ReleaseLock (&ProtocolDatabaseLock);

  //
  // Connect all handles whose Key value is greater than Key
  //
  for (Index = 0; Index < Count; Index++) {
    ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
  }

  FreePool (HandleBuffer);
}

⌨️ 快捷键说明

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