]> code.delx.au - refind/blob - refind/bootsvcs.c
New documentation page; just a stub, for now....
[refind] / refind / bootsvcs.c
1 /*
2 * File to implement an full version of EFI_BOOT_SERVICES, to go beyond
3 * what GNU-EFI provides. These functions were taken, with modification,
4 * from various EDK2 and earlier files (see comments preceding the
5 * functions and other blocks of code). The original source files
6 * bore the following copyright notice:
7 *
8 * Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
9 * This program and the accompanying materials are licensed and made available under
10 * the terms and conditions of the BSD License that accompanies this distribution.
11 * The full text of the license may be found at
12 * http://opensource.org/licenses/bsd-license.php.
13 *
14 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 *
17 */
18
19 #include "bootsvcs.h"
20 #include "refit_call_wrapper.h"
21
22 // Following "global" constants are from AutoGen.c....
23 EFI_GUID gEfiLoadedImageProtocolGuid = { 0x5B1B31A1, 0x9562, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
24 EFI_GUID gEfiDriverBindingProtocolGuid = { 0x18A031AB, 0xB443, 0x4D1A, { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 }};
25 EFI_GUID gEfiDriverConfiguration2ProtocolGuid = { 0xBFD7DC1D, 0x24F1, 0x40D9, { 0x82, 0xE7, 0x2E, 0x09, 0xBB, 0x6B, 0x4E, 0xBE }};
26 EFI_GUID gEfiDriverConfigurationProtocolGuid = { 0x107A772B, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
27 EFI_GUID gEfiDriverDiagnosticsProtocolGuid = { 0x0784924F, 0xE296, 0x11D4, { 0x9A, 0x49, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
28 EFI_GUID gEfiDriverDiagnostics2ProtocolGuid = { 0x4D330321, 0x025F, 0x4AAC, { 0x90, 0xD8, 0x5E, 0xD9, 0x00, 0x17, 0x3B, 0x63 }};
29 EFI_GUID gEfiComponentNameProtocolGuid = { 0x107A772C, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
30 EFI_GUID gEfiComponentName2ProtocolGuid = { 0x6A7A5CFF, 0xE8D9, 0x4F70, { 0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14 }};
31 EFI_GUID gEfiDevicePathProtocolGuid = { 0x09576E91, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
32
33 // Below is from http://git.etherboot.org/?p=mirror/efi/shell/.git;a=commitdiff;h=b1b0c63423cac54dc964c2930e04aebb46a946ec;
34 // Seems to have been replaced by ParseHandleDatabaseByRelationshipWithType(), but the latter isn't working for me....
35 EFI_STATUS
36 LibScanHandleDatabase (
37 EFI_HANDLE DriverBindingHandle, OPTIONAL
38 UINT32 *DriverBindingHandleIndex, OPTIONAL
39 EFI_HANDLE ControllerHandle, OPTIONAL
40 UINT32 *ControllerHandleIndex, OPTIONAL
41 UINTN *HandleCount,
42 EFI_HANDLE **HandleBuffer,
43 UINT32 **HandleType
44 )
45
46 {
47 EFI_STATUS Status;
48 UINTN HandleIndex;
49 EFI_GUID **ProtocolGuidArray;
50 UINTN ArrayCount;
51 UINTN ProtocolIndex;
52 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
53 UINTN OpenInfoCount;
54 UINTN OpenInfoIndex;
55 UINTN ChildIndex;
56 BOOLEAN DriverBindingHandleIndexValid;
57 BOOLEAN ControllerHandleIndexValid;
58
59 DriverBindingHandleIndexValid = FALSE;
60 if (DriverBindingHandleIndex != NULL) {
61 *DriverBindingHandleIndex = 0xffffffff;
62 }
63
64 ControllerHandleIndexValid = FALSE;
65 if (ControllerHandleIndex != NULL) {
66 *ControllerHandleIndex = 0xffffffff;
67 }
68
69 *HandleCount = 0;
70 *HandleBuffer = NULL;
71 *HandleType = NULL;
72
73 //
74 // Retrieve the list of all handles from the handle database
75 //
76
77 Status = refit_call5_wrapper(gBS->LocateHandleBuffer,
78 AllHandles,
79 NULL,
80 NULL,
81 HandleCount,
82 HandleBuffer
83 );
84 if (EFI_ERROR (Status)) {
85 goto Error;
86 }
87
88 *HandleType = AllocatePool (*HandleCount * sizeof (UINT32));
89 if (*HandleType == NULL) {
90 goto Error;
91 }
92
93 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
94 //
95 // Assume that the handle type is unknown
96 //
97 (*HandleType)[HandleIndex] = EFI_HANDLE_TYPE_UNKNOWN;
98
99 if (DriverBindingHandle != NULL &&
100 DriverBindingHandleIndex != NULL &&
101 (*HandleBuffer)[HandleIndex] == DriverBindingHandle
102 ) {
103 *DriverBindingHandleIndex = (UINT32) HandleIndex;
104 DriverBindingHandleIndexValid = TRUE;
105 }
106
107 if (ControllerHandle != NULL && ControllerHandleIndex != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
108 *ControllerHandleIndex = (UINT32) HandleIndex;
109 ControllerHandleIndexValid = TRUE;
110 }
111
112 }
113
114 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
115 //
116 // Retrieve the list of all the protocols on each handle
117 //
118
119 Status = refit_call3_wrapper(gBS->ProtocolsPerHandle,
120 (*HandleBuffer)[HandleIndex],
121 &ProtocolGuidArray,
122 &ArrayCount
123 );
124 if (!EFI_ERROR (Status)) {
125
126 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
127
128 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) == 0) {
129 (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_IMAGE_HANDLE;
130 }
131
132 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) == 0) {
133 (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE;
134 }
135
136 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) == 0) {
137 (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE;
138 }
139
140 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) == 0) {
141 (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE;
142 }
143
144 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) == 0) {
145 (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE;
146 }
147
148 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) == 0) {
149 (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DEVICE_HANDLE;
150 }
151 //
152 // Retrieve the list of agents that have opened each protocol
153 //
154
155 Status = refit_call4_wrapper(gBS->OpenProtocolInformation,
156 (*HandleBuffer)[HandleIndex],
157 ProtocolGuidArray[ProtocolIndex],
158 &OpenInfo,
159 &OpenInfoCount
160 );
161 if (!EFI_ERROR (Status)) {
162
163 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
164 if (DriverBindingHandle != NULL && OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
165 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
166 //
167 // Mark the device handle as being managed by the driver specified by DriverBindingHandle
168 //
169 (*HandleType)[HandleIndex] |= (EFI_HANDLE_TYPE_DEVICE_HANDLE | EFI_HANDLE_TYPE_CONTROLLER_HANDLE);
170 //
171 // Mark the DriverBindingHandle as being a driver that is managing at least one controller
172 //
173 if (DriverBindingHandleIndexValid) {
174 (*HandleType)[*DriverBindingHandleIndex] |= EFI_HANDLE_TYPE_DEVICE_DRIVER;
175 }
176 }
177
178 if ((
179 OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
180 ) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
181 ) {
182 //
183 // Mark the DriverBindingHandle as being a driver that is managing at least one child controller
184 //
185 if (DriverBindingHandleIndexValid) {
186 (*HandleType)[*DriverBindingHandleIndex] |= EFI_HANDLE_TYPE_BUS_DRIVER;
187 }
188 }
189
190 if (ControllerHandle != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
191 if ((
192 OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
193 ) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
194 ) {
195 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
196 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].ControllerHandle) {
197 (*HandleType)[ChildIndex] |= (EFI_HANDLE_TYPE_DEVICE_HANDLE | EFI_HANDLE_TYPE_CHILD_HANDLE);
198 }
199 }
200 }
201 }
202 }
203
204 if (DriverBindingHandle == NULL && OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
205 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
206 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
207 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
208 (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_DEVICE_DRIVER;
209 }
210 }
211 }
212
213 if ((
214 OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
215 ) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
216 ) {
217 (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_PARENT_HANDLE;
218 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
219 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
220 (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_BUS_DRIVER;
221 }
222 }
223 }
224 }
225 }
226
227 FreePool (OpenInfo);
228 }
229 }
230
231 FreePool (ProtocolGuidArray);
232 }
233 }
234
235 return EFI_SUCCESS;
236
237 Error:
238 if (*HandleType != NULL) {
239 FreePool (*HandleType);
240 }
241
242 if (*HandleBuffer != NULL) {
243 FreePool (*HandleBuffer);
244 }
245
246 *HandleCount = 0;
247 *HandleBuffer = NULL;
248 *HandleType = NULL;
249
250 return Status;
251 } /* EFI_STATUS LibScanHandleDatabase() */