locate.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 738 行 · 第 1/2 页
C
738 行
/*++
Copyright (c) 2004, 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:
locate.c
Abstract:
Locate handle functions
Revision History
--*/
#include "hand.h"
//
// ProtocolRequest - Last LocateHandle request ID
//
UINTN mEfiLocateHandleRequest = 0;
//
// Internal prototypes
//
typedef struct {
EFI_GUID *Protocol;
VOID *SearchKey;
EFI_LIST_ENTRY *Position;
PROTOCOL_ENTRY *ProtEntry;
} LOCATE_POSITION;
typedef
IHANDLE *
(* CORE_GET_NEXT) (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
STATIC
IHANDLE *
CoreGetNextLocateAllHandles (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
STATIC
IHANDLE *
CoreGetNextLocateByRegisterNotify (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
STATIC
IHANDLE *
CoreGetNextLocateByProtocol (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
//
//
//
EFI_BOOTSERVICE
EFI_STATUS
EFIAPI
CoreLocateHandle (
IN EFI_LOCATE_SEARCH_TYPE SearchType,
IN EFI_GUID *Protocol OPTIONAL,
IN VOID *SearchKey OPTIONAL,
IN OUT UINTN *BufferSize,
OUT EFI_HANDLE *Buffer
)
/*++
Routine Description:
Locates the requested handle(s) and returns them in Buffer.
Arguments:
SearchType - The type of search to perform to locate the handles
Protocol - The protocol to search for
SearchKey - Dependant on SearchType
BufferSize - On input the size of Buffer. On output the
size of data returned.
Buffer - The buffer to return the results in
Returns:
EFI_BUFFER_TOO_SMALL - Buffer too small, required buffer size is returned in BufferSize.
EFI_INVALID_PARAMETER - Invalid parameter
EFI_SUCCESS - Successfully found the requested handle(s) and returns them in Buffer.
--*/
{
EFI_STATUS Status;
LOCATE_POSITION Position;
PROTOCOL_NOTIFY *ProtNotify;
CORE_GET_NEXT GetNext;
UINTN ResultSize;
IHANDLE *Handle;
IHANDLE **ResultBuffer;
VOID *Interface;
if (BufferSize == NULL) {
Status = EFI_INVALID_PARAMETER;
}
if ((*BufferSize > 0) && (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
GetNext = NULL;
//
// Set initial position
//
Position.Protocol = Protocol;
Position.SearchKey = SearchKey;
Position.Position = &gHandleList;
ResultSize = 0;
ResultBuffer = (IHANDLE **) Buffer;
Status = EFI_SUCCESS;
//
// Lock the protocol database
//
CoreAcquireProtocolLock ();
//
// Get the search function based on type
//
switch (SearchType) {
case AllHandles:
GetNext = CoreGetNextLocateAllHandles;
break;
case ByRegisterNotify:
//
// Must have SearchKey for locate ByRegisterNotify
//
if (SearchKey == NULL) {
Status = EFI_INVALID_PARAMETER;
break;
}
GetNext = CoreGetNextLocateByRegisterNotify;
break;
case ByProtocol:
GetNext = CoreGetNextLocateByProtocol;
if (Protocol == NULL) {
Status = EFI_INVALID_PARAMETER;
break;
}
//
// Look up the protocol entry and set the head pointer
//
Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
if (Position.ProtEntry == NULL) {
Status = EFI_NOT_FOUND;
break;
}
Position.Position = &Position.ProtEntry->Protocols;
break;
default:
Status = EFI_INVALID_PARAMETER;
break;
}
if (EFI_ERROR(Status)) {
CoreReleaseProtocolLock ();
return Status;
}
//
// Enumerate out the matching handles
//
mEfiLocateHandleRequest += 1;
for (; ;) {
//
// Get the next handle. If no more handles, stop
//
Handle = GetNext (&Position, &Interface);
if (NULL == Handle) {
break;
}
//
// Increase the resulting buffer size, and if this handle
// fits return it
//
ResultSize += sizeof(Handle);
if (ResultSize <= *BufferSize) {
*ResultBuffer = Handle;
ResultBuffer += 1;
}
}
//
// If the result is a zero length buffer, then there were no
// matching handles
//
if (ResultSize == 0) {
Status = EFI_NOT_FOUND;
} else {
//
// Return the resulting buffer size. If it's larger than what
// was passed, then set the error code
//
if (ResultSize > *BufferSize) {
Status = EFI_BUFFER_TOO_SMALL;
}
*BufferSize = ResultSize;
if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {
//
// If this is a search by register notify and a handle was
// returned, update the register notification position
//
ProtNotify = SearchKey;
ProtNotify->Position = ProtNotify->Position->ForwardLink;
}
}
CoreReleaseProtocolLock ();
return Status;
}
STATIC
IHANDLE *
CoreGetNextLocateAllHandles (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
)
/*++
Routine Description:
Routine to get the next Handle, when you are searching for all handles.
Arguments:
Position - Information about which Handle to seach for.
Interface - Return the interface structure for the matching protocol.
Returns:
IHANDLE - An IHANDLE is returned if the next Position is not the end of the
list. A NULL_HANDLE is returned if it's the end of the list.
--*/
{
IHANDLE *Handle;
//
// Next handle
//
Position->Position = Position->Position->ForwardLink;
//
// If not at the end of the list, get the handle
//
Handle = NULL_HANDLE;
*Interface = NULL;
if (Position->Position != &gHandleList) {
Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
}
return Handle;
}
STATIC
IHANDLE *
CoreGetNextLocateByRegisterNotify (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
)
/*++
Routine Description:
Routine to get the next Handle, when you are searching for register protocol
notifies.
Arguments:
Position - Information about which Handle to seach for.
Interface - Return the interface structure for the matching protocol.
Returns:
IHANDLE - An IHANDLE is returned if the next Position is not the end of the
list. A NULL_HANDLE is returned if it's the end of the list.
--*/
{
IHANDLE *Handle;
PROTOCOL_NOTIFY *ProtNotify;
PROTOCOL_INTERFACE *Prot;
EFI_LIST_ENTRY *Link;
Handle = NULL_HANDLE;
*Interface = NULL;
ProtNotify = Position->SearchKey;
//
// If this is the first request, get the next handle
//
if (ProtNotify != NULL) {
ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
Position->SearchKey = NULL;
//
// If not at the end of the list, get the next handle
//
Link = ProtNotify->Position->ForwardLink;
if (Link != &ProtNotify->Protocol->Protocols) {
Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
Handle = (IHANDLE *) Prot->Handle;
*Interface = Prot->Interface;
}
}
return Handle;
}
STATIC
IHANDLE *
CoreGetNextLocateByProtocol (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
)
/*++
Routine Description:
Routine to get the next Handle, when you are searching for a given protocol.
Arguments:
Position - Information about which Handle to seach for.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?