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