📄 locate.c
字号:
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
locate.c
Abstract:
Locate handle functions
Revision History
--*/
#include "hand.h"
//
// ProtocolRequest - Last LocateHandle request ID
//
STATIC UINTN EfiLocateHandleRequest;
//
// Internal prototypes
//
typedef struct {
EFI_GUID *Protocol;
VOID *SearchKey;
LIST_ENTRY *Position;
PROTOCOL_ENTRY *ProtEntry;
} LOCATE_POSITION;
typedef
IHANDLE *
(* GET_NEXT) (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
STATIC
IHANDLE *
GetNextLocateAllHandles (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
STATIC
IHANDLE *
GetNextLocateByRegisterNotify (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
STATIC
IHANDLE *
GetNextLocateByProtocol (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
);
//
//
//
EFI_STATUS
BOOTSERVICE
LocateHandle (
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:
Status code.
On success, BufferSize and Buffer is returned
On EFI_BUFFER_TOO_SMALL, BufferSize is returned
On succes, the registration record that has been added
--*/
{
LOCATE_POSITION Position;
PROTOCOL_NOTIFY *ProtNotify;
GET_NEXT GetNext;
UINTN ResultSize;
IHANDLE *Handle;
IHANDLE **ResultBuffer;
EFI_STATUS Status;
VOID *Interface;
//
// Set initial position
//
Position.Protocol = Protocol;
Position.SearchKey = SearchKey;
Position.Position = &HandleList;
ResultSize = 0;
ResultBuffer = (IHANDLE **) Buffer;
Status = EFI_SUCCESS;
//
// Lock the protocol database
//
AcquireLock (&ProtocolDatabaseLock);
//
// Get the search function based on type
//
switch (SearchType) {
case AllHandles:
GetNext = GetNextLocateAllHandles;
break;
case ByRegisterNotify:
if(SearchKey == NULL){
Status = EFI_INVALID_PARAMETER;
break;
}
GetNext = GetNextLocateByRegisterNotify;
break;
case ByProtocol:
if(Protocol == NULL){
Status = EFI_INVALID_PARAMETER;
break;
}
GetNext = GetNextLocateByProtocol;
//
// Look up the protocol entry and set the head pointer
//
Position.ProtEntry = FindProtocolEntry (Protocol, FALSE);
if (!Position.ProtEntry) {
Status = EFI_NOT_FOUND;
break;
}
Position.Position = &Position.ProtEntry->Protocols;
break;
default:
Status = EFI_INVALID_PARAMETER;
break;
}
if (EFI_ERROR(Status)) {
ReleaseLock (&ProtocolDatabaseLock);
return Status;
}
//
// Enumerate out the matching handles
//
EfiLocateHandleRequest += 1;
for (; ;) {
//
// Get the next handle. If no more handles, stop
//
Handle = GetNext(&Position, &Interface);
if (!Handle) {
break;
}
//
// Increase the resulting buffer size, and if this handle
// fits return it
//
ResultSize += sizeof(Handle);
if (ResultSize <= *BufferSize) {
*ResultBuffer = Handle;
ResultBuffer += 1;
}
}
//
// Return the resulting buffer size. If it's larger then what
// was passed, then set the error code
//
if (ResultSize > *BufferSize) {
Status = EFI_BUFFER_TOO_SMALL;
}
*BufferSize = ResultSize;
//
// If the result is a zero length buffer, then there were no
// matching handles
//
if (ResultSize == 0) {
Status = EFI_NOT_FOUND;
}
//
// If this is a search by register notify and a handle was
// returned, update the register notification position
//
if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {
ProtNotify = SearchKey;
ProtNotify->Position = ProtNotify->Position->Flink;
}
ReleaseLock (&ProtocolDatabaseLock);
return Status;
}
STATIC
IHANDLE *
GetNextLocateAllHandles (
IN OUT LOCATE_POSITION *Position,
OUT VOID **Interface
)
{
IHANDLE *Handle;
//
// Next handle
//
Position->Position = Position->Position->Flink;
//
// If not at the end of the list, get the handle
//
Handle = NULL;
*Interface = NULL;
if (Position->Position != &HandleList) {
Handle = CR(Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
}
return Handle;
}
STATIC
IHANDLE *
GetNextLocateByRegisterNotify (
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;
LIST_ENTRY *Link;
Handle = NULL;
*Interface = NULL;
ProtNotify = Position->SearchKey;
//
// If this is the first request, get the next handle
//
if (ProtNotify) {
ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
Position->SearchKey = NULL;
//
// If not at the end of the list, get the next handle
//
Link = ProtNotify->Position->Flink;
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 *
GetNextLocateByProtocol (
IN OUT LOCATE_POSITION *Position,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -