locate.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 738 行 · 第 1/2 页
C
738 行
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;
EFI_LIST_ENTRY *Link;
PROTOCOL_INTERFACE *Prot;
Handle = NULL_HANDLE;
*Interface = NULL;
for (; ;) {
//
// Next entry
//
Link = Position->Position->ForwardLink;
Position->Position = Link;
//
// If not at the end, return the handle
//
if (Link == &Position->ProtEntry->Protocols) {
Handle = NULL_HANDLE;
break;
}
//
// Get the handle
//
Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
Handle = (IHANDLE *) Prot->Handle;
*Interface = Prot->Interface;
//
// If this handle has not been returned this request, then
// return it now
//
if (Handle->LocateRequest != mEfiLocateHandleRequest) {
Handle->LocateRequest = mEfiLocateHandleRequest;
break;
}
}
return Handle;
}
EFI_BOOTSERVICE
EFI_STATUS
EFIAPI
CoreLocateDevicePath (
IN EFI_GUID *Protocol,
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
OUT EFI_HANDLE *Device
)
/*++
Routine Description:
Locates the handle to a device on the device path that best matches the specified protocol.
Arguments:
Protocol - The protocol to search for.
DevicePath - On input, a pointer to a pointer to the device path. On output, the device
path pointer is modified to point to the remaining part of the devicepath.
Device - A pointer to the returned device handle.
Returns:
EFI_SUCCESS - The resulting handle was returned.
EFI_NOT_FOUND - No handles matched the search.
EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
--*/
{
INTN SourceSize;
INTN Size;
INTN BestMatch;
UINTN HandleCount;
UINTN Index;
EFI_STATUS Status;
EFI_HANDLE *Handles;
EFI_HANDLE Handle;
EFI_DEVICE_PATH_PROTOCOL *SourcePath;
EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
if (Protocol == NULL) {
return EFI_INVALID_PARAMETER;
}
if ((DevicePath == NULL) || (*DevicePath == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (Device == NULL) {
return EFI_INVALID_PARAMETER;
}
*Device = NULL_HANDLE;
SourcePath = *DevicePath;
SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
//
// The source path can only have 1 instance
//
if (CoreIsDevicePathMultiInstance (SourcePath)) {
DEBUG((EFI_D_ERROR, "LocateDevicePath: Device path has too many instances\n"));
return EFI_INVALID_PARAMETER;
}
//
// Get a list of all handles that support the requested protocol
//
Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles);
if (EFI_ERROR (Status) || HandleCount == 0) {
return EFI_NOT_FOUND;
}
BestMatch = -1;
for(Index = 0; Index < HandleCount; Index += 1) {
Handle = Handles[Index];
Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, &TmpDevicePath);
if (EFI_ERROR (Status)) {
//
// If this handle doesn't support device path, then skip it
//
continue;
}
//
// Check if DevicePath is first part of SourcePath
//
Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
if ((Size <= SourceSize) && EfiCompareMem (SourcePath, TmpDevicePath, Size) == 0) {
//
// If the size is equal to the best match, then we
// have a duplice device path for 2 different device
// handles
//
ASSERT (Size != BestMatch);
//
// We've got a match, see if it's the best match so far
//
if (Size > BestMatch) {
BestMatch = Size;
*Device = Handle;
}
}
}
CoreFreePool (Handles);
//
// If there wasn't any match, then no parts of the device path was found.
// Which is strange since there is likely a "root level" device path in the system.
//
if (BestMatch == -1) {
return EFI_NOT_FOUND;
}
//
// Return the remaining part of the device path
//
*DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch);
return EFI_SUCCESS;
}
EFI_BOOTSERVICE11
EFI_STATUS
EFIAPI
CoreLocateProtocol (
IN EFI_GUID *Protocol,
IN VOID *Registration OPTIONAL,
OUT VOID **Interface
)
/*++
Routine Description:
Return the first Protocol Interface that matches the Protocol GUID. If
Registration is pasased in return a Protocol Instance that was just add
to the system. If Retistration is NULL return the first Protocol Interface
you find.
Arguments:
Protocol - The protocol to search for
Registration - Optional Registration Key returned from RegisterProtocolNotify()
Interface - Return the Protocol interface (instance).
Returns:
EFI_SUCCESS - If a valid Interface is returned
EFI_INVALID_PARAMETER - Invalid parameter
EFI_NOT_FOUND - Protocol interface not found
--*/
{
EFI_STATUS Status;
LOCATE_POSITION Position;
PROTOCOL_NOTIFY *ProtNotify;
IHANDLE *Handle;
if (Interface == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Protocol == NULL) {
return EFI_NOT_FOUND;
}
*Interface = NULL;
Status = EFI_SUCCESS;
//
// Set initial position
//
Position.Protocol = Protocol;
Position.SearchKey = Registration;
Position.Position = &gHandleList;
//
// Lock the protocol database
//
CoreAcquireProtocolLock ();
mEfiLocateHandleRequest += 1;
if (NULL == Registration) {
//
// Look up the protocol entry and set the head pointer
//
Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
if (Position.ProtEntry == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
}
Position.Position = &Position.ProtEntry->Protocols;
Handle = CoreGetNextLocateByProtocol (&Position, Interface);
} else {
Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface);
}
if (NULL == Handle) {
Status = EFI_NOT_FOUND;
} else if (NULL != Registration) {
//
// If this is a search by register notify and a handle was
// returned, update the register notification position
//
ProtNotify = Registration;
ProtNotify->Position = ProtNotify->Position->ForwardLink;
}
Done:
CoreReleaseProtocolLock ();
return Status;
}
EFI_BOOTSERVICE11
EFI_STATUS
EFIAPI
CoreLocateHandleBuffer (
IN EFI_LOCATE_SEARCH_TYPE SearchType,
IN EFI_GUID *Protocol OPTIONAL,
IN VOID *SearchKey OPTIONAL,
IN OUT UINTN *NumberHandles,
OUT EFI_HANDLE **Buffer
)
/*++
Routine Description:
Function returns an array of handles that support the requested protocol
in a buffer allocated from pool. This is a version of CoreLocateHandle()
that allocates a buffer for the caller.
Arguments:
SearchType - Specifies which handle(s) are to be returned.
Protocol - Provides the protocol to search by.
This parameter is only valid for SearchType ByProtocol.
SearchKey - Supplies the search key depending on the SearchType.
NumberHandles - The number of handles returned in Buffer.
Buffer - A pointer to the buffer to return the requested array of
handles that support Protocol.
Returns:
EFI_SUCCESS - The result array of handles was returned.
EFI_NOT_FOUND - No handles match the search.
EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the matching results.
EFI_INVALID_PARAMETER - Invalid parameter
--*/
{
EFI_STATUS Status;
UINTN BufferSize;
if (NumberHandles == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
BufferSize = 0;
*NumberHandles = 0;
*Buffer = NULL;
Status = CoreLocateHandle (
SearchType,
Protocol,
SearchKey,
&BufferSize,
*Buffer
);
//
// LocateHandleBuffer() returns incorrect status code if SearchType is
// invalid.
//
// Add code to correctly handle expected errors from CoreLocateHandle().
//
if (EFI_ERROR(Status)) {
switch (Status) {
case EFI_BUFFER_TOO_SMALL:
break;
case EFI_INVALID_PARAMETER:
return Status;
default:
return EFI_NOT_FOUND;
}
}
*Buffer = CoreAllocateBootServicesPool (BufferSize);
if (*Buffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = CoreLocateHandle (
SearchType,
Protocol,
SearchKey,
&BufferSize,
*Buffer
);
*NumberHandles = BufferSize/sizeof(EFI_HANDLE);
if (EFI_ERROR(Status)) {
*NumberHandles = 0;
}
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?