handle.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,701 行 · 第 1/3 页
C
1,701 行
CoreReleaseProtocolLock ();
if (!EFI_ERROR (Status)) {
//
// Return the new handle back to the caller
//
*UserHandle = Handle;
} else {
//
// There was an error, clean up
//
if (Prot != NULL) {
CoreFreePool (Prot);
}
}
return Status;
}
EFI_BOOTSERVICE11
EFI_STATUS
EFIAPI
CoreInstallMultipleProtocolInterfaces (
IN OUT EFI_HANDLE *Handle,
...
)
/*++
Routine Description:
Installs a list of protocol interface into the boot services environment.
This function calls InstallProtocolInterface() in a loop. If any error
occures all the protocols added by this function are removed. This is
basically a lib function to save space.
Arguments:
Handle - The handle to install the protocol handlers on,
or NULL if a new handle is to be allocated
... - EFI_GUID followed by protocol instance. A NULL terminates the
list. The pairs are the arguments to InstallProtocolInterface().
All the protocols are added to Handle.
Returns:
EFI_INVALID_PARAMETER - Handle is NULL.
EFI_SUCCESS - Protocol interfaces successfully installed.
--*/
{
VA_LIST args;
EFI_STATUS Status;
EFI_GUID *Protocol;
VOID *Interface;
EFI_TPL OldTpl;
UINTN Index;
EFI_HANDLE OldHandle;
EFI_HANDLE DeviceHandle;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
if (Handle == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Syncronize with notifcations.
//
OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);
OldHandle = *Handle;
//
// Check for duplicate device path and install the protocol interfaces
//
VA_START (args, Handle);
for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
//
// If protocol is NULL, then it's the end of the list
//
Protocol = VA_ARG (args, EFI_GUID *);
if (Protocol == NULL) {
break;
}
Interface = VA_ARG (args, VOID *);
//
// Make sure you are installing on top a device path that has already been added.
//
if (EfiCompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) {
DeviceHandle = NULL;
DevicePath = Interface;
Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);
if (!EFI_ERROR (Status) && (DeviceHandle != NULL_HANDLE) && IsDevicePathEnd(DevicePath)) {
Status = EFI_ALREADY_STARTED;
continue;
}
}
//
// Install it
//
Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
}
//
// If there was an error, remove all the interfaces that were installed without any errors
//
if (EFI_ERROR (Status)) {
//
// Reset the va_arg back to the first argument.
//
VA_START (args, Handle);
for (; Index > 1; Index--) {
Protocol = VA_ARG (args, EFI_GUID *);
Interface = VA_ARG (args, VOID *);
CoreUninstallProtocolInterface (*Handle, Protocol, Interface);
}
*Handle = OldHandle;
}
//
// Done
//
CoreRestoreTpl (OldTpl);
return Status;
}
EFI_STATUS
CoreDisconnectControllersUsingProtocolInterface (
IN EFI_HANDLE UserHandle,
IN PROTOCOL_INTERFACE *Prot
)
/*++
Routine Description:
Attempts to disconnect all drivers that are using the protocol interface being queried.
If failed, reconnect all drivers disconnected.
Note: This function doesn't do parameters checking, it's caller's responsibility
to pass in valid parameters.
Arguments:
UserHandle - The handle on which the protocol is installed
Prot - The protocol to disconnect drivers from
Returns:
EFI_SUCCESS - Drivers using the protocol interface are all disconnected
EFI_ACCESS_DENIED - Failed to disconnect one or all of the drivers
--*/
{
EFI_STATUS Status;
BOOLEAN ItemFound;
EFI_LIST_ENTRY *Link;
OPEN_PROTOCOL_DATA *OpenData;
Status = EFI_SUCCESS;
//
// Attempt to disconnect all drivers from this protocol interface
//
do {
ItemFound = FALSE;
for ( Link = Prot->OpenList.ForwardLink;
(Link != &Prot->OpenList) && !ItemFound;
Link = Link->ForwardLink ) {
OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
ItemFound = TRUE;
CoreReleaseProtocolLock ();
Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
CoreAcquireProtocolLock ();
if (EFI_ERROR (Status)) {
ItemFound = FALSE;
break;
}
}
}
} while (ItemFound);
if (!EFI_ERROR (Status)) {
//
// Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items
//
do {
ItemFound = FALSE;
for ( Link = Prot->OpenList.ForwardLink;
(Link != &Prot->OpenList) && !ItemFound;
Link = Link->ForwardLink ) {
OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
if (OpenData->Attributes &
(EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {
ItemFound = TRUE;
RemoveEntryList (&OpenData->Link);
Prot->OpenListCount--;
CoreFreePool (OpenData);
}
}
} while (ItemFound);
}
//
// If there are errors or still has open items in the list, then reconnect all the drivers and return an error
//
if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {
CoreReleaseProtocolLock ();
CoreConnectController (UserHandle, NULL, NULL, TRUE);
CoreAcquireProtocolLock ();
Status = EFI_ACCESS_DENIED;
}
return Status;
}
EFI_BOOTSERVICE
EFI_STATUS
EFIAPI
CoreUninstallProtocolInterface (
IN EFI_HANDLE UserHandle,
IN EFI_GUID *Protocol,
IN VOID *Interface
)
/*++
Routine Description:
Uninstalls all instances of a protocol:interfacer from a handle.
If the last protocol interface is remove from the handle, the
handle is freed.
Arguments:
UserHandle - The handle to remove the protocol handler from
Protocol - The protocol, of protocol:interface, to remove
Interface - The interface, of protocol:interface, to remove
Returns:
EFI_INVALID_PARAMETER - Protocol is NULL.
EFI_SUCCESS - Protocol interface successfully uninstalled.
--*/
{
EFI_STATUS Status;
IHANDLE *Handle;
PROTOCOL_INTERFACE *Prot;
//
// Check that Protocol is valid
//
if (Protocol == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check that UserHandle is a valid handle
//
Status = CoreValidateHandle (UserHandle);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Lock the protocol database
//
CoreAcquireProtocolLock ();
//
// Check that Protocol exists on UserHandle, and Interface matches the interface in the database
//
Prot = CoreFindProtocolInterface (UserHandle, Protocol, Interface);
if (Prot == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
}
//
// Attempt to disconnect all drivers that are using the protocol interface that is about to be removed
//
Status = CoreDisconnectControllersUsingProtocolInterface (
UserHandle,
Prot
);
if (EFI_ERROR (Status)) {
//
// One or more drivers refused to release, so return the error
//
goto Done;
}
//
// Remove the protocol interface from the protocol
//
Status = EFI_NOT_FOUND;
Handle = (IHANDLE *)UserHandle;
Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, Interface);
if (Prot != NULL) {
//
// Update the Key to show that the handle has been created/modified
//
gHandleDatabaseKey++;
Handle->Key = gHandleDatabaseKey;
//
// Remove the protocol interface from the handle
//
RemoveEntryList (&Prot->Link);
//
// Free the memory
//
Prot->Signature = 0;
CoreFreePool (Prot);
Status = EFI_SUCCESS;
}
//
// If there are no more handlers for the handle, free the handle
//
if (IsListEmpty (&Handle->Protocols)) {
Handle->Signature = 0;
RemoveEntryList (&Handle->AllHandles);
CoreFreePool (Handle);
}
Done:
//
// Done, unlock the database and return
//
CoreReleaseProtocolLock ();
return Status;
}
EFI_BOOTSERVICE11
EFI_STATUS
EFIAPI
CoreUninstallMultipleProtocolInterfaces (
IN EFI_HANDLE Handle,
...
)
/*++
Routine Description:
Uninstalls a list of protocol interface in the boot services environment.
This function calls UnisatllProtocolInterface() in a loop. This is
basically a lib function to save space.
Arguments:
Handle - The handle to uninstall the protocol
... - EFI_GUID followed by protocol instance. A NULL terminates the
list. The pairs are the arguments to UninstallProtocolInterface().
All the protocols are added to Handle.
Returns:
Status code
--*/
{
EFI_STATUS Status;
VA_LIST args;
EFI_GUID *Protocol;
VOID *Interface;
UINTN Index;
VA_START (args, Handle);
for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
//
// If protocol is NULL, then it's the end of the list
//
Protocol = VA_ARG (args, EFI_GUID *);
if (Protocol == NULL) {
break;
}
Interface = VA_ARG (args, VOID *);
//
// Uninstall it
//
Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface);
}
//
// If there was an error, add all the interfaces that were
// uninstalled without any errors
//
if (EFI_ERROR (Status)) {
//
// Reset the va_arg back to the first argument.
//
VA_START (args, Handle);
for (; Index > 1; Index--) {
Protocol = VA_ARG(args, EFI_GUID *);
Interface = VA_ARG(args, VOID *);
CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
}
}
return Status;
}
PROTOCOL_INTERFACE *
CoreGetProtocolInterface (
IN EFI_HANDLE UserHandle,
IN EFI_GUID *Protocol
)
/*++
Routine Description:
Locate a certain GUID protocol interface in a Handle's protocols.
Arguments:
UserHandle - The handle to obtain the protocol interface on
Protocol - The GUID of the protocol
Returns:
The requested protocol interface for the handle
--*/
{
EFI_STATUS Status;
PROTOCOL_ENTRY *ProtEntry;
PROTOCOL_INTERFACE *Prot;
IHANDLE *Handle;
EFI_LIST_ENTRY *Link;
Status = CoreValidateHandle (UserHandle);
if (EFI_ERROR (Status)) {
return NULL;
}
Handle = (IHANDLE *)UserHandle;
//
// Look at each protocol interface for a match
//
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
ProtEntry = Prot->Protocol;
if (EfiCompareGuid (&ProtEntry->ProtocolID, Protocol)) {
return Prot;
}
}
return NULL;
}
EFI_BOOTSERVICE
EFI_STATUS
EFIAPI
CoreHandleProtocol (
IN EFI_HANDLE UserHandle,
IN EFI_GUID *Protocol,
OUT VOID **Interface
)
/*++
Routine Description:
Queries a handle to determine if it supports a specified protocol.
Arguments:
UserHandle - The handle being queried.
Protocol - The published unique identifier of the protocol.
Interface - Supplies the address where a pointer to the corresponding Protocol
Interface is returned.
Returns:
The requested protocol interface for the handle
--*/
{
return CoreOpenProtocol (
UserHandle,
Protocol,
Interface,
gDxeCoreImageHandle,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
);
}
EFI_BOOTSERVICE11
EFI_STATUS
EFIAPI
CoreOpenProtocol (
IN EFI_HANDLE UserHandle,
IN EFI_GUID *Protocol,
OUT VOID **Interface OPTIONAL,
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE ControllerHandle,
IN UINT32 Attributes
)
/*++
Routine Description:
Locates the installed protocol handler for the handle, and
invokes it to obtain the protocol interface. Usage information
is registered in the protocol data base.
Arguments:
UserHandle - The handle to obtain the protocol interface on
Protocol - The ID of the protocol
Interface - The location to return the protocol interface
ImageHandle - The handle of the Image that is opening the protocol interface
specified by Protocol and Interface.
ControllerHandle - The controller handle that is requiring this interface.
Attributes - The open mode of the protocol interface specified by Handle
and Protocol.
Returns:
EFI_INVALID_PARAMETER - Protocol is NULL.
EFI_SUCCESS - Get the protocol interface.
--*/
{
EFI_STATUS Status;
PROTOCOL_INTERFACE *Prot;
EFI_LIST_ENTRY *Link;
OPEN_PROTOCOL_DATA *OpenData;
BOOLEAN ByDriver;
BOOLEAN Exclusive;
BOOLEAN Disconnect;
BOOLEAN ExactMatch;
//
// Check for invalid Protocol
//
if (Protocol == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check for invalid Interface
//
if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
if (Interface == NULL) {
return EFI_INVALID_PARAMETER;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?