]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Hand/Locate.c
Fix LocateDevicePath() to return proper error status code. It was returning EFI_INVA...
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Hand / Locate.c
index 373bf9f2d208e0d27cd9f6f94daca7e55d193b58..d4bc63c2ee7084cf81b603facff2402be263d8be 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Locate handle functions\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2011, 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
@@ -12,7 +12,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <DxeMain.h>\r
+#include "DxeMain.h"\r
+#include "Handle.h"\r
 \r
 //\r
 // ProtocolRequest - Last LocateHandle request ID\r
@@ -30,7 +31,7 @@ typedef struct {
   PROTOCOL_ENTRY  *ProtEntry;\r
 } LOCATE_POSITION;\r
 \r
-typedef \r
+typedef\r
 IHANDLE *\r
 (* CORE_GET_NEXT) (\r
   IN OUT LOCATE_POSITION    *Position,\r
@@ -40,13 +41,12 @@ IHANDLE *
 /**\r
   Routine to get the next Handle, when you are searching for all handles.\r
 \r
-  @param  Position               Information about which Handle to seach for. \r
-  @param  Interface              Return the interface structure for the matching \r
-                                 protocol. \r
+  @param  Position               Information about which Handle to seach for.\r
+  @param  Interface              Return the interface structure for the matching\r
+                                 protocol.\r
 \r
-  @retval IHANDLE                An IHANDLE is returned if the next Position is \r
-                                 not the end of the list. A NULL_HANDLE is \r
-                                 returned if it's the end of the list.\r
+  @return An pointer to IHANDLE if the next Position is not the end of the list.\r
+          Otherwise,NULL is returned.\r
 \r
 **/\r
 IHANDLE *\r
@@ -59,13 +59,12 @@ CoreGetNextLocateAllHandles (
   Routine to get the next Handle, when you are searching for register protocol\r
   notifies.\r
 \r
-  @param  Position               Information about which Handle to seach for. \r
-  @param  Interface              Return the interface structure for the matching \r
-                                 protocol. \r
+  @param  Position               Information about which Handle to seach for.\r
+  @param  Interface              Return the interface structure for the matching\r
+                                 protocol.\r
 \r
-  @retval IHANDLE                An IHANDLE is returned if the next Position is \r
-                                 not the end of the list. A NULL_HANDLE is \r
-                                 returned if it's the end of the list.\r
+  @return An pointer to IHANDLE if the next Position is not the end of the list.\r
+          Otherwise,NULL is returned.\r
 \r
 **/\r
 IHANDLE *\r
@@ -77,13 +76,12 @@ CoreGetNextLocateByRegisterNotify (
 /**\r
   Routine to get the next Handle, when you are searching for a given protocol.\r
 \r
-  @param  Position               Information about which Handle to seach for. \r
-  @param  Interface              Return the interface structure for the matching \r
-                                 protocol. \r
+  @param  Position               Information about which Handle to seach for.\r
+  @param  Interface              Return the interface structure for the matching\r
+                                 protocol.\r
 \r
-  @retval IHANDLE                An IHANDLE is returned if the next Position is \r
-                                 not the end of the list. A NULL_HANDLE is \r
-                                 returned if it's the end of the list.\r
+  @return An pointer to IHANDLE if the next Position is not the end of the list.\r
+          Otherwise,NULL is returned.\r
 \r
 **/\r
 IHANDLE *\r
@@ -96,18 +94,18 @@ CoreGetNextLocateByProtocol (
 /**\r
   Locates the requested handle(s) and returns them in Buffer.\r
 \r
-  @param  SearchType             The type of search to perform to locate the \r
-                                 handles \r
-  @param  Protocol               The protocol to search for \r
-  @param  SearchKey              Dependant on SearchType \r
-  @param  BufferSize             On input the size of Buffer.  On output the  \r
-                                 size of data returned. \r
-  @param  Buffer                 The buffer to return the results in \r
-\r
-  @retval EFI_BUFFER_TOO_SMALL   Buffer too small, required buffer size is \r
-                                 returned in BufferSize. \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter \r
-  @retval EFI_SUCCESS            Successfully found the requested handle(s) and \r
+  @param  SearchType             The type of search to perform to locate the\r
+                                 handles\r
+  @param  Protocol               The protocol to search for\r
+  @param  SearchKey              Dependant on SearchType\r
+  @param  BufferSize             On input the size of Buffer.  On output the\r
+                                 size of data returned.\r
+  @param  Buffer                 The buffer to return the results in\r
+\r
+  @retval EFI_BUFFER_TOO_SMALL   Buffer too small, required buffer size is\r
+                                 returned in BufferSize.\r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter\r
+  @retval EFI_SUCCESS            Successfully found the requested handle(s) and\r
                                  returns them in Buffer.\r
 \r
 **/\r
@@ -129,15 +127,15 @@ CoreLocateHandle (
   IHANDLE             *Handle;\r
   IHANDLE             **ResultBuffer;\r
   VOID                *Interface;\r
\r
+\r
   if (BufferSize == NULL) {\r
-    Status = EFI_INVALID_PARAMETER;\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   if ((*BufferSize > 0) && (Buffer == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   GetNext = NULL;\r
 \r
   //\r
@@ -160,11 +158,11 @@ CoreLocateHandle (
   // Get the search function based on type\r
   //\r
   switch (SearchType) {\r
-  case AllHandles:      \r
-    GetNext = CoreGetNextLocateAllHandles;       \r
+  case AllHandles:\r
+    GetNext = CoreGetNextLocateAllHandles;\r
     break;\r
 \r
-  case ByRegisterNotify:    \r
+  case ByRegisterNotify:\r
     //\r
     // Must have SearchKey for locate ByRegisterNotify\r
     //\r
@@ -172,10 +170,10 @@ CoreLocateHandle (
       Status = EFI_INVALID_PARAMETER;\r
       break;\r
     }\r
-    GetNext = CoreGetNextLocateByRegisterNotify;   \r
+    GetNext = CoreGetNextLocateByRegisterNotify;\r
     break;\r
 \r
-  case ByProtocol:      \r
+  case ByProtocol:\r
     GetNext = CoreGetNextLocateByProtocol;\r
     if (Protocol == NULL) {\r
       Status = EFI_INVALID_PARAMETER;\r
@@ -202,6 +200,7 @@ CoreLocateHandle (
     return Status;\r
   }\r
 \r
+  ASSERT (GetNext != NULL);\r
   //\r
   // Enumerate out the matching handles\r
   //\r
@@ -239,15 +238,16 @@ CoreLocateHandle (
     //\r
     if (ResultSize > *BufferSize) {\r
       Status = EFI_BUFFER_TOO_SMALL;\r
-    } \r
-    \r
+    }\r
+\r
     *BufferSize = ResultSize;\r
 \r
     if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {\r
       //\r
       // If this is a search by register notify and a handle was\r
       // returned, update the register notification position\r
-      // \r
+      //\r
+      ASSERT (SearchKey != NULL);\r
       ProtNotify = SearchKey;\r
       ProtNotify->Position = ProtNotify->Position->ForwardLink;\r
     }\r
@@ -262,12 +262,12 @@ CoreLocateHandle (
 /**\r
   Routine to get the next Handle, when you are searching for all handles.\r
 \r
-  @param  Position               Information about which Handle to seach for. \r
-  @param  Interface              Return the interface structure for the matching \r
-                                 protocol. \r
+  @param  Position               Information about which Handle to seach for.\r
+  @param  Interface              Return the interface structure for the matching\r
+                                 protocol.\r
 \r
   @return An pointer to IHANDLE if the next Position is not the end of the list.\r
-          Otherwise,NULL_HANDLE is returned.\r
+          Otherwise,NULL is returned.\r
 \r
 **/\r
 IHANDLE *\r
@@ -286,7 +286,7 @@ CoreGetNextLocateAllHandles (
   //\r
   // If not at the end of the list, get the handle\r
   //\r
-  Handle      = NULL_HANDLE;\r
+  Handle      = NULL;\r
   *Interface  = NULL;\r
   if (Position->Position != &gHandleList) {\r
     Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
@@ -301,12 +301,12 @@ CoreGetNextLocateAllHandles (
   Routine to get the next Handle, when you are searching for register protocol\r
   notifies.\r
 \r
-  @param  Position               Information about which Handle to seach for. \r
-  @param  Interface              Return the interface structure for the matching \r
-                                 protocol. \r
+  @param  Position               Information about which Handle to seach for.\r
+  @param  Interface              Return the interface structure for the matching\r
+                                 protocol.\r
 \r
   @return An pointer to IHANDLE if the next Position is not the end of the list.\r
-          Otherwise,NULL_HANDLE is returned.\r
+          Otherwise,NULL is returned.\r
 \r
 **/\r
 IHANDLE *\r
@@ -318,9 +318,9 @@ CoreGetNextLocateByRegisterNotify (
   IHANDLE             *Handle;\r
   PROTOCOL_NOTIFY     *ProtNotify;\r
   PROTOCOL_INTERFACE  *Prot;\r
-  LIST_ENTRY          *Link;    \r
+  LIST_ENTRY          *Link;\r
 \r
-  Handle      = NULL_HANDLE;\r
+  Handle      = NULL;\r
   *Interface  = NULL;\r
   ProtNotify = Position->SearchKey;\r
 \r
@@ -337,9 +337,9 @@ CoreGetNextLocateByRegisterNotify (
     Link = ProtNotify->Position->ForwardLink;\r
     if (Link != &ProtNotify->Protocol->Protocols) {\r
       Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
-      Handle = (IHANDLE *) Prot->Handle;\r
+      Handle = Prot->Handle;\r
       *Interface = Prot->Interface;\r
-    }  \r
+    }\r
   }\r
 \r
   return Handle;\r
@@ -349,12 +349,12 @@ CoreGetNextLocateByRegisterNotify (
 /**\r
   Routine to get the next Handle, when you are searching for a given protocol.\r
 \r
-  @param  Position               Information about which Handle to seach for. \r
-  @param  Interface              Return the interface structure for the matching \r
-                                 protocol. \r
+  @param  Position               Information about which Handle to seach for.\r
+  @param  Interface              Return the interface structure for the matching\r
+                                 protocol.\r
 \r
   @return An pointer to IHANDLE if the next Position is not the end of the list.\r
-          Otherwise,NULL_HANDLE is returned.\r
+          Otherwise,NULL is returned.\r
 \r
 **/\r
 IHANDLE *\r
@@ -366,8 +366,8 @@ CoreGetNextLocateByProtocol (
   IHANDLE             *Handle;\r
   LIST_ENTRY          *Link;\r
   PROTOCOL_INTERFACE  *Prot;\r
\r
-  Handle      = NULL_HANDLE;\r
+\r
+  Handle      = NULL;\r
   *Interface  = NULL;\r
   for (; ;) {\r
     //\r
@@ -380,7 +380,7 @@ CoreGetNextLocateByProtocol (
     // If not at the end, return the handle\r
     //\r
     if (Link == &Position->ProtEntry->Protocols) {\r
-      Handle = NULL_HANDLE;\r
+      Handle = NULL;\r
       break;\r
     }\r
 \r
@@ -388,11 +388,11 @@ CoreGetNextLocateByProtocol (
     // Get the handle\r
     //\r
     Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
-    Handle = (IHANDLE *) Prot->Handle;\r
+    Handle = Prot->Handle;\r
     *Interface = Prot->Interface;\r
 \r
     //\r
-    // If this handle has not been returned this request, then \r
+    // If this handle has not been returned this request, then\r
     // return it now\r
     //\r
     if (Handle->LocateRequest != mEfiLocateHandleRequest) {\r
@@ -406,18 +406,19 @@ CoreGetNextLocateByProtocol (
 \r
 \r
 /**\r
-  Locates the handle to a device on the device path that best matches the specified protocol.\r
+  Locates the handle to a device on the device path that supports the specified protocol.\r
 \r
-  @param  Protocol               The protocol to search for. \r
-  @param  DevicePath             On input, a pointer to a pointer to the device \r
-                                 path. On output, the device path pointer is \r
-                                 modified to point to the remaining part of the \r
-                                 devicepath. \r
-  @param  Device                 A pointer to the returned device handle. \r
+  @param  Protocol              Specifies the protocol to search for.\r
+  @param  DevicePath            On input, a pointer to a pointer to the device path. On output, the device\r
+                                path pointer is modified to point to the remaining part of the device\r
+                                path.\r
+  @param  Device                A pointer to the returned device handle.\r
 \r
-  @retval EFI_SUCCESS            The resulting handle was returned. \r
-  @retval EFI_NOT_FOUND          No handles matched the search. \r
-  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.\r
+  @retval EFI_SUCCESS           The resulting handle was returned.\r
+  @retval EFI_NOT_FOUND         No handles match the search.\r
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.\r
+  @retval EFI_INVALID_PARAMETER DevicePath is NULL.\r
+  @retval EFI_INVALID_PARAMETER A handle matched the search and Device is NULL.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -436,33 +437,34 @@ CoreLocateDevicePath (
   EFI_STATUS                  Status;\r
   EFI_HANDLE                  *Handles;\r
   EFI_HANDLE                  Handle;\r
+  EFI_HANDLE                  BestDevice;\r
   EFI_DEVICE_PATH_PROTOCOL    *SourcePath;\r
   EFI_DEVICE_PATH_PROTOCOL    *TmpDevicePath;\r
-  \r
+\r
   if (Protocol == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   if ((DevicePath == NULL) || (*DevicePath == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
-  if (Device == NULL) {\r
-    return  EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  *Device = NULL_HANDLE;\r
+\r
+  BestDevice = NULL;\r
   SourcePath = *DevicePath;\r
-  SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
-  \r
-  //\r
-  // The source path can only have 1 instance\r
-  //\r
-  if (CoreIsDevicePathMultiInstance (SourcePath)) {\r
-    DEBUG((DEBUG_ERROR, "LocateDevicePath: Device path has too many instances\n"));\r
-    return EFI_INVALID_PARAMETER;\r
+  TmpDevicePath = SourcePath;\r
+  while (!IsDevicePathEnd (TmpDevicePath)) {\r
+    if (IsDevicePathEndInstance (TmpDevicePath)) {\r
+      //\r
+      // If DevicePath is a multi-instance device path,\r
+      // the function will operate on the first instance \r
+      //\r
+      break;\r
+    }\r
+    TmpDevicePath = NextDevicePathNode (TmpDevicePath);\r
   }\r
 \r
+  SourceSize = (UINTN) TmpDevicePath - (UINTN) SourcePath;\r
+\r
   //\r
   // Get a list of all handles that support the requested protocol\r
   //\r
@@ -485,35 +487,41 @@ CoreLocateDevicePath (
     //\r
     // Check if DevicePath is first part of SourcePath\r
     //\r
-    Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
-    if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, Size) == 0) {\r
+    Size = GetDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
+    ASSERT (Size >= 0);\r
+    if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, (UINTN) Size) == 0) {\r
       //\r
       // If the size is equal to the best match, then we\r
-      // have a duplice device path for 2 different device\r
+      // have a duplicate device path for 2 different device\r
       // handles\r
       //\r
       ASSERT (Size != BestMatch);\r
-      \r
+\r
       //\r
       // We've got a match, see if it's the best match so far\r
       //\r
       if (Size > BestMatch) {\r
         BestMatch = Size;\r
-        *Device = Handle;\r
+        BestDevice = Handle;\r
       }\r
     }\r
   }\r
 \r
   CoreFreePool (Handles);\r
-   \r
+\r
   //\r
-  // If there wasn't any match, then no parts of the device path was found.  \r
+  // If there wasn't any match, then no parts of the device path was found.\r
   // Which is strange since there is likely a "root level" device path in the system.\r
   //\r
   if (BestMatch == -1) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  if (Device == NULL) {\r
+    return  EFI_INVALID_PARAMETER;\r
+  }\r
+  *Device = BestDevice;\r
+  \r
   //\r
   // Return the remaining part of the device path\r
   //\r
@@ -522,19 +530,19 @@ CoreLocateDevicePath (
 }\r
 \r
 \r
- /**\r
+/**\r
   Return the first Protocol Interface that matches the Protocol GUID. If\r
-  Registration is pasased in return a Protocol Instance that was just add\r
-  to the system. If Retistration is NULL return the first Protocol Interface\r
+  Registration is passed in, return a Protocol Instance that was just add\r
+  to the system. If Registration is NULL return the first Protocol Interface\r
   you find.\r
 \r
-  @param  Protocol               The protocol to search for \r
-  @param  Registration           Optional Registration Key returned from \r
-                                 RegisterProtocolNotify() \r
-  @param  Interface              Return the Protocol interface (instance). \r
+  @param  Protocol               The protocol to search for\r
+  @param  Registration           Optional Registration Key returned from\r
+                                 RegisterProtocolNotify()\r
+  @param  Interface              Return the Protocol interface (instance).\r
 \r
-  @retval EFI_SUCCESS            If a valid Interface is returned \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter \r
+  @retval EFI_SUCCESS            If a valid Interface is returned\r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter\r
   @retval EFI_NOT_FOUND          Protocol interface not found\r
 \r
 **/\r
@@ -554,11 +562,11 @@ CoreLocateProtocol (
   if (Interface == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   if (Protocol == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
+\r
   *Interface = NULL;\r
   Status = EFI_SUCCESS;\r
 \r
@@ -568,7 +576,7 @@ CoreLocateProtocol (
   Position.Protocol  = Protocol;\r
   Position.SearchKey = Registration;\r
   Position.Position  = &gHandleList;\r
-  \r
+\r
   //\r
   // Lock the protocol database\r
   //\r
@@ -589,7 +597,7 @@ CoreLocateProtocol (
 \r
     Handle = CoreGetNextLocateByProtocol (&Position, Interface);\r
   } else {\r
-    Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface);   \r
+    Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface);\r
   }\r
 \r
   if (Handle == NULL) {\r
@@ -598,7 +606,7 @@ CoreLocateProtocol (
     //\r
     // If this is a search by register notify and a handle was\r
     // returned, update the register notification position\r
-    // \r
+    //\r
     ProtNotify = Registration;\r
     ProtNotify->Position = ProtNotify->Position->ForwardLink;\r
   }\r
@@ -614,20 +622,20 @@ Done:
   in a buffer allocated from pool. This is a version of CoreLocateHandle()\r
   that allocates a buffer for the caller.\r
 \r
-  @param  SearchType             Specifies which handle(s) are to be returned. \r
-  @param  Protocol               Provides the protocol to search by.    This \r
-                                 parameter is only valid for SearchType \r
-                                 ByProtocol. \r
-  @param  SearchKey              Supplies the search key depending on the \r
-                                 SearchType. \r
-  @param  NumberHandles          The number of handles returned in Buffer. \r
-  @param  Buffer                 A pointer to the buffer to return the requested \r
-                                 array of  handles that support Protocol. \r
-\r
-  @retval EFI_SUCCESS            The result array of handles was returned. \r
-  @retval EFI_NOT_FOUND          No handles match the search. \r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough pool memory to store the \r
-                                 matching results. \r
+  @param  SearchType             Specifies which handle(s) are to be returned.\r
+  @param  Protocol               Provides the protocol to search by.    This\r
+                                 parameter is only valid for SearchType\r
+                                 ByProtocol.\r
+  @param  SearchKey              Supplies the search key depending on the\r
+                                 SearchType.\r
+  @param  NumberHandles          The number of handles returned in Buffer.\r
+  @param  Buffer                 A pointer to the buffer to return the requested\r
+                                 array of  handles that support Protocol.\r
+\r
+  @retval EFI_SUCCESS            The result array of handles was returned.\r
+  @retval EFI_NOT_FOUND          No handles match the search.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough pool memory to store the\r
+                                 matching results.\r
   @retval EFI_INVALID_PARAMETER  One or more paramters are not valid.\r
 \r
 **/\r
@@ -675,7 +683,7 @@ CoreLocateHandleBuffer (
     return Status;\r
   }\r
 \r
-  *Buffer = CoreAllocateBootServicesPool (BufferSize);\r
+  *Buffer = AllocatePool (BufferSize);\r
   if (*Buffer == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r