]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Handle.c
837c1491ee36b17a015988758bee41c35942e20f
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiDriverLib / Handle.c
1 /*++
2
3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. 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
75 //
76 // Get list of all handles that support the first protocol.
77 //
78 Status = gBS->LocateHandleBuffer (
79 ByProtocol,
80 ProtocolFirst,
81 NULL,
82 &NumberOfHandles,
83 &HandleBuffer
84 );
85 if (EFI_ERROR (Status)) {
86 return Status;
87 }
88
89 //
90 // Check if this is a countinuation of handle searching.
91 //
92 Idx = 0;
93 if ((Handle != NULL) && (*Handle != NULL)) {
94 //
95 // Leave the Idx just beyond the matching handle.
96 //
97 for (; Idx < NumberOfHandles;) {
98 if (*Handle == HandleBuffer[Idx++]) {
99 break;
100 }
101 }
102 }
103
104 //
105 // Iterate handles testing for presence of remaining protocols.
106 //
107 for (; Idx < NumberOfHandles; Idx++) {
108
109 //
110 // Start with the second protocol, the first one is sure on this handle.
111 //
112 VA_START (args, Interface);
113 Protocol = VA_ARG (args, EFI_GUID *);
114
115 //
116 // Iterate protocols from the variable list.
117 //
118 while (TRUE) {
119
120 Protocol = VA_ARG (args, EFI_GUID *);
121
122 if (Protocol == NULL) {
123
124 //
125 // If here, the list was iterated successfully
126 // finding each protocol on a single handle.
127 //
128
129 Status = EFI_SUCCESS;
130
131 //
132 // OPTIONAL parameter returning the Handle.
133 //
134 if (Handle != NULL) {
135 *Handle = HandleBuffer[Idx];
136 }
137
138 //
139 // OPTIONAL parameter returning the first rotocol's Interface.
140 //
141 if (Interface != NULL) {
142 Status = gBS->HandleProtocol (
143 HandleBuffer[Idx],
144 ProtocolFirst,
145 Interface
146 );
147 }
148
149 goto lbl_out;
150 }
151
152 Status = gBS->HandleProtocol (
153 HandleBuffer[Idx],
154 Protocol,
155 &AnInterface
156 );
157 if (EFI_ERROR (Status)) {
158
159 //
160 // This handle does not have the iterated protocol.
161 //
162 break;
163 }
164 }
165
166 }
167
168 //
169 // If here, no handle that bears all the protocols was found.
170 //
171 Status = EFI_NOT_FOUND;
172
173 lbl_out:
174 gBS->FreePool (HandleBuffer);
175 return Status;
176 }