📄 driversupport.c
字号:
//
// Sort the remaining DriverBinding Protocol based on their Version field from
// highest to lowest.
//
for ( ; SortIndex < DriverBindingHandleCount; SortIndex++) {
HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
HighestIndex = SortIndex;
for (Index = SortIndex + 1; Index < DriverBindingHandleCount; Index++) {
if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
HighestVersion = SortedDriverBindingProtocols[Index]->Version;
HighestIndex = Index;
}
}
if (SortIndex != HighestIndex) {
DriverBinding = SortedDriverBindingProtocols[SortIndex];
SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
}
}
//
// Loop until no more drivers can be started on ControllerHandle
//
OneStarted = FALSE;
do {
//
// Loop through the sorted Driver Binding Protocol Instances in order, and see if
// any of the Driver Binding Protocols support the controller specified by
// ControllerHandle.
//
DriverBinding = NULL;
DriverFound = FALSE;
for (Index = 0; Index < NumberOfSortedDriverBindingProtocols; Index++) {
if (SortedDriverBindingProtocols[Index] != NULL) {
DriverBinding = SortedDriverBindingProtocols[Index];
Status = DriverBinding->Supported(
DriverBinding,
ControllerHandle,
(EFI_DEVICE_PATH_PROTOCOL *)RemainingDevicePath
);
if (!EFI_ERROR (Status)) {
SortedDriverBindingProtocols[Index] = NULL;
DriverFound = TRUE;
//
// A driver was found that supports ControllerHandle, so attempt to start the driver
// on ControllerHandle.
//
Status = DriverBinding->Start (
DriverBinding,
ControllerHandle,
(EFI_DEVICE_PATH_PROTOCOL *)RemainingDevicePath
);
if (!EFI_ERROR (Status)) {
//
// The driver was successfully started on ControllerHandle, so set a flag
//
OneStarted = TRUE;
}
break;
}
}
}
} while (DriverFound);
//
// Free any buffer that were allocated with AllocatePool()
//
BS->FreePool (SortedDriverBindingProtocols);
//
// If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
//
if (OneStarted) {
return EFI_SUCCESS;
}
//
// If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
//
if (RemainingDevicePath != NULL) {
if (IsDevicePathEnd (RemainingDevicePath)) {
return EFI_SUCCESS;
}
}
//
// Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
//
return EFI_NOT_FOUND;
}
EFI_STATUS
DisconnectController (
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE DriverImageHandle, OPTIONAL
IN EFI_HANDLE ChildHandle OPTIONAL
)
/*++
Routine Description:
Disonnects a controller from a driver
Arguments:
ControllerHandle -
GuidList -
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
IHANDLE *Handle;
PROTOCOL_ENTRY *ProtEntry;
PROTOCOL_INTERFACE *Prot;
LIST_ENTRY *Link;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
UINTN EntryCount;
UINTN ChildBufferCount;
EFI_HANDLE *ChildBuffer;
UINTN Index;
UINTN j;
UINTN k;
BOOLEAN Duplicate;
BOOLEAN ChildHandleValid;
BOOLEAN DriverImageHandleValid;
UINTN ChildrenToStop;
EFI_HANDLE *DriverImageHandleBuffer;
UINTN DriverImageHandleCount;
UINTN StopCount;
//
// Make sure ControllerHandle is valid
//
Handle = ControllerHandle;
if (Handle == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Handle->Signature != EFI_HANDLE_SIGNATURE) {
return EFI_INVALID_PARAMETER;
}
//
// Make sure ChildHandle is valid if it is not NULL
//
if (ChildHandle != NULL) {
Handle= ChildHandle;
if (Handle->Signature != EFI_HANDLE_SIGNATURE) {
return EFI_INVALID_PARAMETER;
}
}
Handle = ControllerHandle;
//
// Get list of drivers that are currently managing ControllerHandle
//
DriverImageHandleBuffer = NULL;
DriverImageHandleCount = 1;
if (DriverImageHandle == NULL) {
//
// Look at each protocol interface for a match
//
DriverImageHandleCount = 0;
for (Link = Handle->Protocols.Flink; Link != &Handle->Protocols; Link = Link->Flink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
ProtEntry = Prot->Protocol;
Status = OpenProtocolInformation (
ControllerHandle,
&ProtEntry->ProtocolID,
&OpenInfoBuffer,
&EntryCount
);
if (!EFI_ERROR (Status) && OpenInfoBuffer != NULL) {
for (Index = 0; Index < EntryCount; Index++) {
if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
DriverImageHandleCount++;
}
}
BS->FreePool (OpenInfoBuffer);
}
}
//
// If there are no drivers managing this controller, then return EFI_SUCCESS
//
if (DriverImageHandleCount == 0) {
return EFI_SUCCESS;
}
Status = BS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_HANDLE) * DriverImageHandleCount,
(VOID **)&DriverImageHandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
DriverImageHandleCount = 0;
for (Link = Handle->Protocols.Flink; Link != &Handle->Protocols; Link = Link->Flink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
ProtEntry = Prot->Protocol;
Status = OpenProtocolInformation (
ControllerHandle,
&ProtEntry->ProtocolID,
&OpenInfoBuffer,
&EntryCount
);
if (!EFI_ERROR (Status) && OpenInfoBuffer != NULL) {
for (Index = 0; Index < EntryCount; Index++) {
if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
Duplicate = FALSE;
for (j = 0; j< DriverImageHandleCount; j++) {
if (DriverImageHandleBuffer[j] == OpenInfoBuffer[Index].AgentHandle) {
Duplicate = TRUE;
}
}
if (Duplicate == FALSE) {
DriverImageHandleBuffer[DriverImageHandleCount] = OpenInfoBuffer[Index].AgentHandle;
DriverImageHandleCount++;
}
}
}
BS->FreePool (OpenInfoBuffer);
}
}
}
StopCount = 0;
for (j = 0; j < DriverImageHandleCount; j++) {
if (DriverImageHandleBuffer != NULL) {
DriverImageHandle = DriverImageHandleBuffer[j];
}
//
// Get the Driver Binding Protocol of the driver that is managing this controller
//
Status = BS->OpenProtocol (
DriverImageHandle,
&DriverBindingProtocol,
&DriverBinding,
NULL, //gMyImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Look at each protocol interface for a match
//
DriverImageHandleValid = FALSE;
ChildBufferCount = 0;
for (Link = Handle->Protocols.Flink; Link != &Handle->Protocols; Link = Link->Flink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
ProtEntry = Prot->Protocol;
Status = OpenProtocolInformation (
ControllerHandle,
&ProtEntry->ProtocolID,
&OpenInfoBuffer,
&EntryCount
);
if (!EFI_ERROR (Status) && OpenInfoBuffer != NULL) {
for (Index = 0; Index < EntryCount; Index++) {
if (OpenInfoBuffer[Index].AgentHandle == DriverImageHandle &&
(OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)) {
ChildBufferCount++;
}
if (OpenInfoBuffer[Index].AgentHandle == DriverImageHandle &&
(OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER)) {
DriverImageHandleValid = TRUE;
}
}
BS->FreePool (OpenInfoBuffer);
}
}
if (DriverImageHandleValid) {
ChildHandleValid = FALSE;
ChildBuffer = NULL;
if (ChildBufferCount != 0) {
Status = BS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_HANDLE) * ChildBufferCount,
(VOID **)&ChildBuffer
);
if (EFI_ERROR (Status)) {
if (DriverImageHandleBuffer != NULL) {
BS->FreePool (DriverImageHandleBuffer);
}
return Status;
}
ChildBufferCount = 0;
for (Link = Handle->Protocols.Flink; Link != &Handle->Protocols; Link = Link->Flink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
ProtEntry = Prot->Protocol;
Status = OpenProtocolInformation (
ControllerHandle,
&ProtEntry->ProtocolID,
&OpenInfoBuffer,
&EntryCount
);
if (!EFI_ERROR (Status) && OpenInfoBuffer != NULL) {
for (Index = 0; Index < EntryCount; Index++) {
if (OpenInfoBuffer[Index].AgentHandle == DriverImageHandle &&
(OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)) {
Duplicate = FALSE;
for (k = 0; k < ChildBufferCount; k++) {
if (ChildBuffer[k] == OpenInfoBuffer[Index].ControllerHandle) {
Duplicate = TRUE;
break;
}
}
if (Duplicate == FALSE) {
ChildBuffer[ChildBufferCount] = OpenInfoBuffer[Index].ControllerHandle;
if (ChildHandle == ChildBuffer[ChildBufferCount]) {
ChildHandleValid = TRUE;
}
ChildBufferCount++;
}
}
}
BS->FreePool (OpenInfoBuffer);
}
}
}
if (ChildHandle == NULL || ChildHandleValid) {
ChildrenToStop = 0;
Status = EFI_SUCCESS;
if (ChildBufferCount > 0) {
if (ChildHandle != NULL) {
ChildrenToStop = 1;
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
} else {
ChildrenToStop = ChildBufferCount;
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
}
}
if (!EFI_ERROR (Status) && ChildHandle == NULL && ChildBufferCount == ChildrenToStop) {
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
}
if (!EFI_ERROR(Status)) {
StopCount++;
}
}
if (ChildBuffer != NULL) {
BS->FreePool (ChildBuffer);
}
}
}
if (DriverImageHandleBuffer != NULL) {
BS->FreePool (DriverImageHandleBuffer);
}
if (StopCount > 0) {
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -