📄 handle.c
字号:
// 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 + -