Home | History | Annotate | Download | only in EfiDriverLib
      1 /*++
      2 
      3 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   Handle.c
     15 
     16 Abstract:
     17 
     18   Support for Handle lib fucntions.
     19 
     20 --*/
     21 
     22 #include "Tiano.h"
     23 #include "EfiDriverLib.h"
     24 
     25 EFI_STATUS
     26 EfiLibLocateHandleProtocolByProtocols (
     27   IN OUT EFI_HANDLE        * Handle, OPTIONAL
     28   OUT    VOID              **Interface, OPTIONAL
     29   ...
     30   )
     31 /*++
     32 Routine Description:
     33 
     34   Function locates Protocol and/or Handle on which all Protocols specified
     35   as a variable list are installed.
     36   It supports continued search. The caller must assure that no handles are added
     37   or removed while performing continued search, by e.g., rising the TPL and not
     38   calling any handle routines. Otherwise the behavior is undefined.
     39 
     40 Arguments:
     41 
     42   Handle        - The address of handle to receive the handle on which protocols
     43                   indicated by the variable list are installed.
     44                   If points to NULL, all handles are searched. If pointing to a
     45                   handle returned from previous call, searches starting from next handle.
     46                   If NULL, the parameter is ignored.
     47 
     48   Interface     - The address of a pointer to a protocol interface that will receive
     49                   the interface indicated by first variable argument.
     50                   If NULL, the parameter is ignored.
     51 
     52   ...           - A variable argument list containing protocol GUIDs. Must end with NULL.
     53 
     54 Returns:
     55 
     56   EFI_SUCCESS  - All the protocols where found on same handle.
     57   EFI_NOT_FOUND - A Handle with all the protocols installed was not found.
     58   Other values as may be returned from LocateHandleBuffer() or HandleProtocol().
     59 
     60 --*/
     61 {
     62   VA_LIST     args;
     63   EFI_STATUS  Status;
     64   EFI_GUID    *Protocol;
     65   EFI_GUID    *ProtocolFirst;
     66   EFI_HANDLE  *HandleBuffer;
     67   UINTN       NumberOfHandles;
     68   UINTN       Idx;
     69   VOID        *AnInterface;
     70 
     71   AnInterface = NULL;
     72   VA_START (args, Interface);
     73   ProtocolFirst = VA_ARG (args, EFI_GUID *);
     74   VA_END (args);
     75 
     76   //
     77   // Get list of all handles that support the first protocol.
     78   //
     79   Status = gBS->LocateHandleBuffer (
     80                   ByProtocol,
     81                   ProtocolFirst,
     82                   NULL,
     83                   &NumberOfHandles,
     84                   &HandleBuffer
     85                   );
     86   if (EFI_ERROR (Status)) {
     87     return Status;
     88   }
     89 
     90   //
     91   // Check if this is a countinuation of handle searching.
     92   //
     93   Idx = 0;
     94   if ((Handle != NULL) && (*Handle != NULL)) {
     95     //
     96     // Leave the Idx just beyond the matching handle.
     97     //
     98     for (; Idx < NumberOfHandles;) {
     99       if (*Handle == HandleBuffer[Idx++]) {
    100         break;
    101       }
    102     }
    103   }
    104 
    105   //
    106   // Iterate handles testing for presence of remaining protocols.
    107   //
    108   for (; Idx < NumberOfHandles; Idx++) {
    109 
    110     //
    111     // Start with the second protocol, the first one is sure on this handle.
    112     //
    113     VA_START (args, Interface);
    114     Protocol = VA_ARG (args, EFI_GUID *);
    115 
    116     //
    117     // Iterate protocols from the variable list.
    118     //
    119     while (TRUE) {
    120 
    121       Protocol = VA_ARG (args, EFI_GUID *);
    122 
    123       if (Protocol == NULL) {
    124 
    125         //
    126         // If here, the list was iterated successfully
    127         // finding each protocol on a single handle.
    128         //
    129 
    130         Status = EFI_SUCCESS;
    131 
    132         //
    133         // OPTIONAL parameter returning the Handle.
    134         //
    135         if (Handle != NULL) {
    136           *Handle = HandleBuffer[Idx];
    137         }
    138 
    139         //
    140         // OPTIONAL parameter returning the first rotocol's Interface.
    141         //
    142         if (Interface != NULL) {
    143           Status = gBS->HandleProtocol (
    144                           HandleBuffer[Idx],
    145                           ProtocolFirst,
    146                           Interface
    147                           );
    148         }
    149 
    150         VA_END (args);
    151 
    152         goto lbl_out;
    153       }
    154 
    155       Status = gBS->HandleProtocol (
    156                       HandleBuffer[Idx],
    157                       Protocol,
    158                       &AnInterface
    159                       );
    160       if (EFI_ERROR (Status)) {
    161 
    162         //
    163         // This handle does not have the iterated protocol.
    164         //
    165         break;
    166       }
    167     }
    168 
    169     VA_END (args);
    170   }
    171 
    172   //
    173   // If here, no handle that bears all the protocols was found.
    174   //
    175   Status = EFI_NOT_FOUND;
    176 
    177 lbl_out:
    178   gBS->FreePool (HandleBuffer);
    179   return Status;
    180 }
    181