/** @file\r
UEFI handle & protocol handling.\r
\r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
\r
**/\r
\r
-#include <DxeMain.h>\r
+#include "DxeMain.h"\r
+#include "Handle.h"\r
\r
\r
//\r
// gHandleDatabaseKey - The Key to show that the handle has been created/modified\r
//\r
LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);\r
-LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);\r
-EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);\r
-UINT64 gHandleDatabaseKey = 0;\r
+LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);\r
+EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);\r
+UINT64 gHandleDatabaseKey = 0;\r
\r
\r
\r
)\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
// allocate a new entry\r
//\r
if ((ProtEntry == NULL) && Create) {\r
- ProtEntry = CoreAllocateBootServicesPool (sizeof(PROTOCOL_ENTRY));\r
+ ProtEntry = AllocatePool (sizeof(PROTOCOL_ENTRY));\r
\r
if (ProtEntry != NULL) {\r
//\r
//\r
// Print debug message\r
//\r
- DEBUG((DEBUG_LOAD | DEBUG_INFO, "InstallProtocolInterface: %g %p\n", Protocol, Interface));\r
+ DEBUG((DEBUG_INFO, "InstallProtocolInterface: %g %p\n", Protocol, Interface));\r
\r
Status = EFI_OUT_OF_RESOURCES;\r
Prot = NULL;\r
Handle = NULL;\r
\r
- ASSERT (gDxeCoreBS != NULL);\r
-\r
- if (*UserHandle != NULL_HANDLE) {\r
+ if (*UserHandle != NULL) {\r
Status = CoreHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);\r
if (!EFI_ERROR (Status)) {\r
return EFI_INVALID_PARAMETER;\r
//\r
// Allocate a new protocol interface structure\r
//\r
- Prot = CoreAllocateZeroBootServicesPool (sizeof(PROTOCOL_INTERFACE));\r
+ Prot = AllocateZeroPool (sizeof(PROTOCOL_INTERFACE));\r
if (Prot == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
//\r
Handle = (IHANDLE *)*UserHandle;\r
if (Handle == NULL) {\r
- Handle = CoreAllocateZeroBootServicesPool (sizeof(IHANDLE));\r
+ Handle = AllocateZeroPool (sizeof(IHANDLE));\r
if (Handle == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
// in the system\r
//\r
InsertTailList (&gHandleList, &Handle->AllHandles);\r
- }\r
-\r
- Status = CoreValidateHandle (Handle);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
+ } else {\r
+ Status = CoreValidateHandle (Handle);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));\r
+ goto Done;\r
+ }\r
}\r
\r
//\r
if (Prot != NULL) {\r
CoreFreePool (Prot);\r
}\r
+ DEBUG((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));\r
}\r
\r
return Status;\r
occures all the protocols added by this function are removed. This is\r
basically a lib function to save space.\r
\r
- @param Handle The handle to install the protocol handlers on,\r
- or NULL if a new handle is to be allocated\r
+ @param Handle The pointer to a handle to install the new\r
+ protocol interfaces on, or a pointer to NULL\r
+ if a new handle is to be allocated.\r
@param ... EFI_GUID followed by protocol instance. A NULL\r
terminates the list. The pairs are the\r
arguments to InstallProtocolInterface(). All the\r
protocols are added to Handle.\r
\r
+ @retval EFI_SUCCESS All the protocol interface was installed.\r
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.\r
+ @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in\r
+ the handle database.\r
@retval EFI_INVALID_PARAMETER Handle is NULL.\r
- @retval EFI_SUCCESS Protocol interfaces successfully installed.\r
+ @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.\r
\r
**/\r
EFI_STATUS\r
DeviceHandle = NULL;\r
DevicePath = Interface;\r
Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);\r
- if (!EFI_ERROR (Status) && (DeviceHandle != NULL_HANDLE) && IsDevicePathEnd(DevicePath)) {\r
+ if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(DevicePath)) {\r
Status = EFI_ALREADY_STARTED;\r
continue;\r
}\r
//\r
Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);\r
}\r
+ VA_END (Args);\r
\r
//\r
// If there was an error, remove all the interfaces that were installed without any errors\r
Interface = VA_ARG (Args, VOID *);\r
CoreUninstallProtocolInterface (*Handle, Protocol, Interface);\r
}\r
+ VA_END (Args);\r
+\r
*Handle = OldHandle;\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) {\r
- ItemFound = TRUE;\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\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)) {\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
//\r
Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface);\r
}\r
+ VA_END (Args);\r
\r
//\r
// If there was an error, add all the interfaces that were\r
Interface = VA_ARG(Args, VOID *);\r
CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);\r
}\r
+ VA_END (Args);\r
}\r
\r
return Status;\r
@param Interface Supplies the address where a pointer to the\r
corresponding Protocol Interface is returned.\r
\r
- @return The requested protocol interface for the handle\r
+ @retval EFI_SUCCESS The interface information for the specified protocol was returned.\r
+ @retval EFI_UNSUPPORTED The device does not support the specified protocol.\r
+ @retval EFI_INVALID_PARAMETER Handle is NULL..\r
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.\r
+ @retval EFI_INVALID_PARAMETER Interface is NULL.\r
\r
**/\r
EFI_STATUS\r
//\r
// Check for invalid Interface\r
//\r
- if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\r
- if (Interface == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- *Interface = NULL;\r
- }\r
+ if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
goto Done;\r
}\r
\r
- //\r
- // This is the protocol interface entry for this protocol\r
- //\r
- if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\r
- *Interface = Prot->Interface;\r
- }\r
Status = EFI_SUCCESS;\r
\r
ByDriver = FALSE;\r
ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) &&\r
(OpenData->Attributes == Attributes) &&\r
(OpenData->ControllerHandle == ControllerHandle));\r
- if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
ByDriver = TRUE;\r
if (ExactMatch) {\r
Status = EFI_ALREADY_STARTED;\r
goto Done;\r
}\r
}\r
- if (OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) {\r
Exclusive = TRUE;\r
} else if (ExactMatch) {\r
OpenData->OpenCount++;\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) {\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
Disconnect = TRUE;\r
CoreReleaseProtocolLock ();\r
Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);\r
if (EFI_ERROR (Status)) {\r
Status = EFI_ACCESS_DENIED;\r
goto Done;\r
+ } else {\r
+ break;\r
}\r
}\r
}\r
//\r
// Create new entry\r
//\r
- OpenData = CoreAllocateBootServicesPool (sizeof(OPEN_PROTOCOL_DATA));\r
+ OpenData = AllocatePool (sizeof(OPEN_PROTOCOL_DATA));\r
if (OpenData == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
} else {\r
}\r
\r
Done:\r
+\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
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (ControllerHandle != NULL_HANDLE) {\r
+ if (ControllerHandle != NULL) {\r
Status = CoreValidateHandle (ControllerHandle);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
\r
@param UserHandle The handle to close the protocol interface on\r
@param Protocol The ID of the protocol\r
- @param EntryBuffer A pointer to a buffer of open protocol\r
- information in the form of\r
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.\r
+ @param EntryBuffer A pointer to a buffer of open protocol information in the\r
+ form of EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.\r
@param EntryCount Number of EntryBuffer entries\r
\r
+ @retval EFI_SUCCESS The open protocol information was returned in EntryBuffer,\r
+ and the number of entries was returned EntryCount.\r
+ @retval EFI_NOT_FOUND Handle does not support the protocol specified by Protocol.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate EntryBuffer.\r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
Size = Count * sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);\r
}\r
\r
- Buffer = CoreAllocateBootServicesPool (Size);\r
+ Buffer = AllocatePool (Size);\r
if (Buffer == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
goto Done;\r
}\r
\r
- Buffer = CoreAllocateBootServicesPool (sizeof (EFI_GUID *) * ProtocolCount);\r
+ Buffer = AllocatePool (sizeof (EFI_GUID *) * ProtocolCount);\r
if (Buffer == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
}\r
\r
- HandleBuffer = CoreAllocateBootServicesPool (Count * sizeof (EFI_HANDLE));\r
+ HandleBuffer = AllocatePool (Count * sizeof (EFI_HANDLE));\r
if (HandleBuffer == NULL) {\r
CoreReleaseProtocolLock ();\r
return;\r