)\r
{\r
IHANDLE *Handle;\r
+ LIST_ENTRY *Link;\r
\r
- Handle = (IHANDLE *)UserHandle;\r
- if (Handle == NULL) {\r
+ if (UserHandle == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- if (Handle->Signature != EFI_HANDLE_SIGNATURE) {\r
- return EFI_INVALID_PARAMETER;\r
+\r
+ for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {\r
+ Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
+ if (Handle == (IHANDLE *) UserHandle) {\r
+ return EFI_SUCCESS;\r
+ }\r
}\r
- return EFI_SUCCESS;\r
+\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
\r
//\r
do {\r
ItemFound = FALSE;\r
- for ( Link = Prot->OpenList.ForwardLink;\r
- (Link != &Prot->OpenList) && !ItemFound;\r
- Link = Link->ForwardLink ) {\r
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {\r
OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
- ItemFound = TRUE;\r
CoreReleaseProtocolLock ();\r
Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);\r
CoreAcquireProtocolLock ();\r
- if (EFI_ERROR (Status)) {\r
- ItemFound = FALSE;\r
- break;\r
+ if (!EFI_ERROR (Status)) {\r
+ ItemFound = TRUE;\r
}\r
+ break;\r
}\r
}\r
} while (ItemFound);\r
//\r
// Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items\r
//\r
- do {\r
- ItemFound = FALSE;\r
- for ( Link = Prot->OpenList.ForwardLink;\r
- (Link != &Prot->OpenList) && !ItemFound;\r
- Link = Link->ForwardLink ) {\r
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
- if ((OpenData->Attributes &\r
- (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) {\r
- ItemFound = TRUE;\r
- RemoveEntryList (&OpenData->Link);\r
- Prot->OpenListCount--;\r
- CoreFreePool (OpenData);\r
- }\r
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) {\r
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
+ if ((OpenData->Attributes &\r
+ (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) {\r
+ Link = RemoveEntryList (&OpenData->Link);\r
+ Prot->OpenListCount--;\r
+ CoreFreePool (OpenData);\r
+ } else {\r
+ Link = Link->ForwardLink;\r
}\r
- } while (ItemFound);\r
+ }\r
}\r
\r
//\r
Prot = CoreGetProtocolInterface (UserHandle, Protocol);\r
if (Prot == NULL) {\r
Status = EFI_UNSUPPORTED;\r
- if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL){\r
- //Return NULL Interface if Unsupported Protocol\r
- *Interface = NULL;\r
- }\r
goto Done;\r
}\r
\r
if (ByDriver) {\r
do {\r
Disconnect = FALSE;\r
- for ( Link = Prot->OpenList.ForwardLink; (Link != &Prot->OpenList) && (!Disconnect); Link = Link->ForwardLink) {\r
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {\r
OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
Disconnect = TRUE;\r
if (EFI_ERROR (Status)) {\r
Status = EFI_ACCESS_DENIED;\r
goto Done;\r
+ } else {\r
+ break;\r
}\r
}\r
}\r
\r
Done:\r
\r
- //\r
- // This is the protocol interface entry for this protocol.\r
- // In case of any Error, Interface should not be updated as per spec.\r
- //\r
- if (!EFI_ERROR (Status) && (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {\r
- *Interface = Prot->Interface;\r
+ if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\r
+ //\r
+ // Keep Interface unmodified in case of any Error\r
+ // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED.\r
+ //\r
+ if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {\r
+ //\r
+ // According to above logic, if 'Prot' is NULL, then the 'Status' must be\r
+ // EFI_UNSUPPORTED. Here the 'Status' is not EFI_UNSUPPORTED, so 'Prot'\r
+ // must be not NULL.\r
+ //\r
+ // The ASSERT here is for addressing a false positive NULL pointer\r
+ // dereference issue raised from static analysis.\r
+ //\r
+ ASSERT (Prot != NULL);\r
+ //\r
+ // EFI_ALREADY_STARTED is not an error for bus driver.\r
+ // Return the corresponding protocol interface.\r
+ //\r
+ *Interface = Prot->Interface;\r
+ } else if (Status == EFI_UNSUPPORTED) {\r
+ //\r
+ // Return NULL Interface if Unsupported Protocol.\r
+ //\r
+ *Interface = NULL;\r
+ }\r
}\r
+\r
//\r
- // Done. Release the database lock are return\r
+ // Done. Release the database lock and return\r
//\r
CoreReleaseProtocolLock ();\r
return Status;\r