hand.c revision 1.4 1 1.4 jmcneill /* $NetBSD: hand.c,v 1.4 2018/08/16 18:22:05 jmcneill Exp $ */
2 1.1 jakllsch
3 1.1 jakllsch /*++
4 1.1 jakllsch
5 1.1 jakllsch Copyright (c) 1998 Intel Corporation
6 1.1 jakllsch
7 1.1 jakllsch Module Name:
8 1.1 jakllsch
9 1.1 jakllsch hand.c
10 1.1 jakllsch
11 1.1 jakllsch Abstract:
12 1.1 jakllsch
13 1.1 jakllsch
14 1.1 jakllsch
15 1.1 jakllsch
16 1.1 jakllsch Revision History
17 1.1 jakllsch
18 1.1 jakllsch --*/
19 1.1 jakllsch
20 1.1 jakllsch #include "lib.h"
21 1.1 jakllsch #include "efistdarg.h" // !!!
22 1.1 jakllsch
23 1.1 jakllsch
24 1.1 jakllsch EFI_STATUS
25 1.1 jakllsch LibLocateProtocol (
26 1.1 jakllsch IN EFI_GUID *ProtocolGuid,
27 1.1 jakllsch OUT VOID **Interface
28 1.1 jakllsch )
29 1.1 jakllsch //
30 1.1 jakllsch // Find the first instance of this Protocol in the system and return it's interface
31 1.1 jakllsch //
32 1.1 jakllsch {
33 1.1 jakllsch EFI_STATUS Status;
34 1.1 jakllsch UINTN NumberHandles, Index;
35 1.1 jakllsch EFI_HANDLE *Handles;
36 1.1 jakllsch
37 1.1 jakllsch
38 1.1 jakllsch *Interface = NULL;
39 1.1 jakllsch Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
40 1.1 jakllsch if (EFI_ERROR(Status)) {
41 1.1 jakllsch DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n"));
42 1.1 jakllsch return Status;
43 1.1 jakllsch }
44 1.1 jakllsch
45 1.1 jakllsch for (Index=0; Index < NumberHandles; Index++) {
46 1.1 jakllsch Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handles[Index], ProtocolGuid, Interface);
47 1.1 jakllsch if (!EFI_ERROR(Status)) {
48 1.1 jakllsch break;
49 1.1 jakllsch }
50 1.1 jakllsch }
51 1.1 jakllsch
52 1.1 jakllsch if (Handles) {
53 1.1 jakllsch FreePool (Handles);
54 1.1 jakllsch }
55 1.1 jakllsch
56 1.1 jakllsch return Status;
57 1.1 jakllsch }
58 1.1 jakllsch
59 1.1 jakllsch EFI_STATUS
60 1.1 jakllsch LibLocateHandle (
61 1.1 jakllsch IN EFI_LOCATE_SEARCH_TYPE SearchType,
62 1.1 jakllsch IN EFI_GUID *Protocol OPTIONAL,
63 1.1 jakllsch IN VOID *SearchKey OPTIONAL,
64 1.1 jakllsch IN OUT UINTN *NoHandles,
65 1.1 jakllsch OUT EFI_HANDLE **Buffer
66 1.1 jakllsch )
67 1.1 jakllsch
68 1.1 jakllsch {
69 1.1 jakllsch EFI_STATUS Status;
70 1.1 jakllsch UINTN BufferSize;
71 1.1 jakllsch
72 1.1 jakllsch //
73 1.1 jakllsch // Initialize for GrowBuffer loop
74 1.1 jakllsch //
75 1.1 jakllsch
76 1.1 jakllsch Status = EFI_SUCCESS;
77 1.1 jakllsch *Buffer = NULL;
78 1.1 jakllsch BufferSize = 50 * sizeof(EFI_HANDLE);
79 1.1 jakllsch
80 1.1 jakllsch //
81 1.1 jakllsch // Call the real function
82 1.1 jakllsch //
83 1.1 jakllsch
84 1.1 jakllsch while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
85 1.1 jakllsch
86 1.1 jakllsch Status = uefi_call_wrapper(
87 1.1 jakllsch BS->LocateHandle,
88 1.1 jakllsch 5,
89 1.1 jakllsch SearchType,
90 1.1 jakllsch Protocol,
91 1.1 jakllsch SearchKey,
92 1.1 jakllsch &BufferSize,
93 1.1 jakllsch *Buffer
94 1.1 jakllsch );
95 1.1 jakllsch
96 1.1 jakllsch }
97 1.1 jakllsch
98 1.1 jakllsch *NoHandles = BufferSize / sizeof (EFI_HANDLE);
99 1.1 jakllsch if (EFI_ERROR(Status)) {
100 1.1 jakllsch *NoHandles = 0;
101 1.1 jakllsch }
102 1.1 jakllsch
103 1.1 jakllsch return Status;
104 1.1 jakllsch }
105 1.1 jakllsch
106 1.1 jakllsch EFI_STATUS
107 1.1 jakllsch LibLocateHandleByDiskSignature (
108 1.1 jakllsch IN UINT8 MBRType,
109 1.1 jakllsch IN UINT8 SignatureType,
110 1.1 jakllsch IN VOID *Signature,
111 1.1 jakllsch IN OUT UINTN *NoHandles,
112 1.1 jakllsch OUT EFI_HANDLE **Buffer
113 1.1 jakllsch )
114 1.1 jakllsch
115 1.1 jakllsch {
116 1.1 jakllsch EFI_STATUS Status;
117 1.1 jakllsch UINTN BufferSize;
118 1.1 jakllsch UINTN NoBlockIoHandles;
119 1.1 jakllsch EFI_HANDLE *BlockIoBuffer;
120 1.1 jakllsch EFI_DEVICE_PATH *DevicePath;
121 1.1 jakllsch UINTN Index;
122 1.4 jmcneill EFI_DEVICE_PATH *Next, *DevPath;
123 1.1 jakllsch HARDDRIVE_DEVICE_PATH *HardDriveDevicePath;
124 1.1 jakllsch BOOLEAN Match;
125 1.1 jakllsch BOOLEAN PreviousNodeIsHardDriveDevicePath;
126 1.1 jakllsch
127 1.1 jakllsch //
128 1.1 jakllsch // Initialize for GrowBuffer loop
129 1.1 jakllsch //
130 1.1 jakllsch
131 1.4 jmcneill Status = EFI_SUCCESS;
132 1.1 jakllsch BlockIoBuffer = NULL;
133 1.1 jakllsch BufferSize = 50 * sizeof(EFI_HANDLE);
134 1.1 jakllsch
135 1.1 jakllsch //
136 1.1 jakllsch // Call the real function
137 1.1 jakllsch //
138 1.1 jakllsch
139 1.1 jakllsch while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) {
140 1.1 jakllsch
141 1.1 jakllsch //
142 1.1 jakllsch // Get list of device handles that support the BLOCK_IO Protocol.
143 1.1 jakllsch //
144 1.1 jakllsch
145 1.1 jakllsch Status = uefi_call_wrapper(
146 1.1 jakllsch BS->LocateHandle,
147 1.1 jakllsch 5,
148 1.1 jakllsch ByProtocol,
149 1.1 jakllsch &BlockIoProtocol,
150 1.1 jakllsch NULL,
151 1.1 jakllsch &BufferSize,
152 1.1 jakllsch BlockIoBuffer
153 1.1 jakllsch );
154 1.1 jakllsch
155 1.1 jakllsch }
156 1.1 jakllsch
157 1.1 jakllsch NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE);
158 1.1 jakllsch if (EFI_ERROR(Status)) {
159 1.1 jakllsch NoBlockIoHandles = 0;
160 1.1 jakllsch }
161 1.1 jakllsch
162 1.1 jakllsch //
163 1.1 jakllsch // If there was an error or there are no device handles that support
164 1.1 jakllsch // the BLOCK_IO Protocol, then return.
165 1.1 jakllsch //
166 1.1 jakllsch
167 1.1 jakllsch if (NoBlockIoHandles == 0) {
168 1.1 jakllsch FreePool(BlockIoBuffer);
169 1.1 jakllsch *NoHandles = 0;
170 1.1 jakllsch *Buffer = NULL;
171 1.1 jakllsch return Status;
172 1.1 jakllsch }
173 1.1 jakllsch
174 1.1 jakllsch //
175 1.1 jakllsch // Loop through all the device handles that support the BLOCK_IO Protocol
176 1.1 jakllsch //
177 1.1 jakllsch
178 1.1 jakllsch *NoHandles = 0;
179 1.1 jakllsch
180 1.1 jakllsch for(Index=0;Index<NoBlockIoHandles;Index++) {
181 1.1 jakllsch
182 1.1 jakllsch Status = uefi_call_wrapper(
183 1.1 jakllsch BS->HandleProtocol,
184 1.1 jakllsch 3,
185 1.1 jakllsch BlockIoBuffer[Index],
186 1.1 jakllsch &DevicePathProtocol,
187 1.1 jakllsch (VOID*)&DevicePath
188 1.1 jakllsch );
189 1.1 jakllsch
190 1.1 jakllsch //
191 1.1 jakllsch // Search DevicePath for a Hard Drive Media Device Path node.
192 1.1 jakllsch // If one is found, then see if it matches the signature that was
193 1.1 jakllsch // passed in. If it does match, and the next node is the End of the
194 1.1 jakllsch // device path, and the previous node is not a Hard Drive Media Device
195 1.1 jakllsch // Path, then we have found a match.
196 1.1 jakllsch //
197 1.1 jakllsch
198 1.1 jakllsch Match = FALSE;
199 1.1 jakllsch
200 1.1 jakllsch if (DevicePath != NULL) {
201 1.1 jakllsch
202 1.1 jakllsch PreviousNodeIsHardDriveDevicePath = FALSE;
203 1.1 jakllsch
204 1.1 jakllsch DevPath = DevicePath;
205 1.1 jakllsch
206 1.1 jakllsch //
207 1.1 jakllsch // Check for end of device path type
208 1.1 jakllsch //
209 1.1 jakllsch
210 1.1 jakllsch for (; ;) {
211 1.1 jakllsch
212 1.1 jakllsch if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
213 1.1 jakllsch (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
214 1.1 jakllsch
215 1.1 jakllsch HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath);
216 1.1 jakllsch
217 1.1 jakllsch if (PreviousNodeIsHardDriveDevicePath == FALSE) {
218 1.1 jakllsch
219 1.1 jakllsch Next = NextDevicePathNode(DevPath);
220 1.1 jakllsch if (IsDevicePathEndType(Next)) {
221 1.1 jakllsch if ((HardDriveDevicePath->MBRType == MBRType) &&
222 1.1 jakllsch (HardDriveDevicePath->SignatureType == SignatureType)) {
223 1.1 jakllsch switch(SignatureType) {
224 1.1 jakllsch case SIGNATURE_TYPE_MBR:
225 1.1 jakllsch if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) {
226 1.1 jakllsch Match = TRUE;
227 1.1 jakllsch }
228 1.1 jakllsch break;
229 1.1 jakllsch case SIGNATURE_TYPE_GUID:
230 1.1 jakllsch if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0]))) == 0) {
231 1.1 jakllsch Match = TRUE;
232 1.1 jakllsch }
233 1.1 jakllsch break;
234 1.1 jakllsch }
235 1.1 jakllsch }
236 1.1 jakllsch }
237 1.1 jakllsch }
238 1.1 jakllsch PreviousNodeIsHardDriveDevicePath = TRUE;
239 1.1 jakllsch } else {
240 1.1 jakllsch PreviousNodeIsHardDriveDevicePath = FALSE;
241 1.1 jakllsch }
242 1.1 jakllsch
243 1.1 jakllsch if (IsDevicePathEnd(DevPath)) {
244 1.1 jakllsch break;
245 1.1 jakllsch }
246 1.1 jakllsch
247 1.1 jakllsch DevPath = NextDevicePathNode(DevPath);
248 1.1 jakllsch }
249 1.1 jakllsch
250 1.1 jakllsch }
251 1.1 jakllsch
252 1.1 jakllsch if (Match == FALSE) {
253 1.1 jakllsch BlockIoBuffer[Index] = NULL;
254 1.1 jakllsch } else {
255 1.1 jakllsch *NoHandles = *NoHandles + 1;
256 1.1 jakllsch }
257 1.1 jakllsch }
258 1.1 jakllsch
259 1.1 jakllsch //
260 1.1 jakllsch // If there are no matches, then return
261 1.1 jakllsch //
262 1.1 jakllsch
263 1.1 jakllsch if (*NoHandles == 0) {
264 1.1 jakllsch FreePool(BlockIoBuffer);
265 1.1 jakllsch *NoHandles = 0;
266 1.1 jakllsch *Buffer = NULL;
267 1.1 jakllsch return EFI_SUCCESS;
268 1.1 jakllsch }
269 1.1 jakllsch
270 1.1 jakllsch //
271 1.1 jakllsch // Allocate space for the return buffer of device handles.
272 1.1 jakllsch //
273 1.1 jakllsch
274 1.1 jakllsch *Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE));
275 1.1 jakllsch
276 1.1 jakllsch if (*Buffer == NULL) {
277 1.1 jakllsch FreePool(BlockIoBuffer);
278 1.1 jakllsch *NoHandles = 0;
279 1.1 jakllsch *Buffer = NULL;
280 1.1 jakllsch return EFI_OUT_OF_RESOURCES;
281 1.1 jakllsch }
282 1.1 jakllsch
283 1.1 jakllsch //
284 1.1 jakllsch // Build list of matching device handles.
285 1.1 jakllsch //
286 1.1 jakllsch
287 1.1 jakllsch *NoHandles = 0;
288 1.1 jakllsch for(Index=0;Index<NoBlockIoHandles;Index++) {
289 1.1 jakllsch if (BlockIoBuffer[Index] != NULL) {
290 1.1 jakllsch (*Buffer)[*NoHandles] = BlockIoBuffer[Index];
291 1.1 jakllsch *NoHandles = *NoHandles + 1;
292 1.1 jakllsch }
293 1.1 jakllsch }
294 1.1 jakllsch
295 1.1 jakllsch FreePool(BlockIoBuffer);
296 1.1 jakllsch
297 1.1 jakllsch return EFI_SUCCESS;
298 1.1 jakllsch }
299 1.1 jakllsch
300 1.1 jakllsch EFI_FILE_HANDLE
301 1.1 jakllsch LibOpenRoot (
302 1.1 jakllsch IN EFI_HANDLE DeviceHandle
303 1.1 jakllsch )
304 1.1 jakllsch {
305 1.1 jakllsch EFI_STATUS Status;
306 1.1 jakllsch EFI_FILE_IO_INTERFACE *Volume;
307 1.1 jakllsch EFI_FILE_HANDLE File;
308 1.1 jakllsch
309 1.1 jakllsch
310 1.1 jakllsch //
311 1.1 jakllsch // File the file system interface to the device
312 1.1 jakllsch //
313 1.1 jakllsch
314 1.1 jakllsch Status = uefi_call_wrapper(BS->HandleProtocol, 3, DeviceHandle, &FileSystemProtocol, (VOID*)&Volume);
315 1.1 jakllsch
316 1.1 jakllsch //
317 1.1 jakllsch // Open the root directory of the volume
318 1.1 jakllsch //
319 1.1 jakllsch
320 1.1 jakllsch if (!EFI_ERROR(Status)) {
321 1.1 jakllsch Status = uefi_call_wrapper(Volume->OpenVolume, 2, Volume, &File);
322 1.1 jakllsch }
323 1.1 jakllsch
324 1.1 jakllsch //
325 1.1 jakllsch // Done
326 1.1 jakllsch //
327 1.1 jakllsch
328 1.1 jakllsch return EFI_ERROR(Status) ? NULL : File;
329 1.1 jakllsch }
330 1.1 jakllsch
331 1.1 jakllsch EFI_FILE_INFO *
332 1.1 jakllsch LibFileInfo (
333 1.1 jakllsch IN EFI_FILE_HANDLE FHand
334 1.1 jakllsch )
335 1.1 jakllsch {
336 1.1 jakllsch EFI_STATUS Status;
337 1.1 jakllsch EFI_FILE_INFO *Buffer;
338 1.1 jakllsch UINTN BufferSize;
339 1.1 jakllsch
340 1.1 jakllsch //
341 1.1 jakllsch // Initialize for GrowBuffer loop
342 1.1 jakllsch //
343 1.1 jakllsch
344 1.4 jmcneill Status = EFI_SUCCESS;
345 1.1 jakllsch Buffer = NULL;
346 1.1 jakllsch BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
347 1.1 jakllsch
348 1.1 jakllsch //
349 1.1 jakllsch // Call the real function
350 1.1 jakllsch //
351 1.1 jakllsch
352 1.1 jakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
353 1.1 jakllsch Status = uefi_call_wrapper(
354 1.1 jakllsch FHand->GetInfo,
355 1.1 jakllsch 4,
356 1.1 jakllsch FHand,
357 1.1 jakllsch &GenericFileInfo,
358 1.1 jakllsch &BufferSize,
359 1.1 jakllsch Buffer
360 1.1 jakllsch );
361 1.1 jakllsch }
362 1.1 jakllsch
363 1.1 jakllsch return Buffer;
364 1.1 jakllsch }
365 1.1 jakllsch
366 1.1 jakllsch
367 1.1 jakllsch EFI_FILE_SYSTEM_INFO *
368 1.1 jakllsch LibFileSystemInfo (
369 1.1 jakllsch IN EFI_FILE_HANDLE FHand
370 1.1 jakllsch )
371 1.1 jakllsch {
372 1.1 jakllsch EFI_STATUS Status;
373 1.1 jakllsch EFI_FILE_SYSTEM_INFO *Buffer;
374 1.1 jakllsch UINTN BufferSize;
375 1.1 jakllsch
376 1.1 jakllsch //
377 1.1 jakllsch // Initialize for GrowBuffer loop
378 1.1 jakllsch //
379 1.1 jakllsch
380 1.4 jmcneill Status = EFI_SUCCESS;
381 1.1 jakllsch Buffer = NULL;
382 1.1 jakllsch BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200;
383 1.1 jakllsch
384 1.1 jakllsch //
385 1.1 jakllsch // Call the real function
386 1.1 jakllsch //
387 1.1 jakllsch
388 1.1 jakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
389 1.1 jakllsch Status = uefi_call_wrapper(
390 1.1 jakllsch FHand->GetInfo,
391 1.1 jakllsch 4,
392 1.1 jakllsch FHand,
393 1.1 jakllsch &FileSystemInfo,
394 1.1 jakllsch &BufferSize,
395 1.1 jakllsch Buffer
396 1.1 jakllsch );
397 1.1 jakllsch }
398 1.1 jakllsch
399 1.1 jakllsch return Buffer;
400 1.1 jakllsch }
401 1.1 jakllsch
402 1.1 jakllsch EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
403 1.1 jakllsch LibFileSystemVolumeLabelInfo (
404 1.1 jakllsch IN EFI_FILE_HANDLE FHand
405 1.1 jakllsch )
406 1.1 jakllsch {
407 1.1 jakllsch EFI_STATUS Status;
408 1.1 jakllsch EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
409 1.1 jakllsch UINTN BufferSize;
410 1.1 jakllsch
411 1.1 jakllsch //
412 1.1 jakllsch // Initialize for GrowBuffer loop
413 1.1 jakllsch //
414 1.1 jakllsch
415 1.4 jmcneill Status = EFI_SUCCESS;
416 1.1 jakllsch Buffer = NULL;
417 1.1 jakllsch BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
418 1.1 jakllsch
419 1.1 jakllsch //
420 1.1 jakllsch // Call the real function
421 1.1 jakllsch //
422 1.1 jakllsch
423 1.1 jakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
424 1.1 jakllsch Status = uefi_call_wrapper(
425 1.1 jakllsch FHand->GetInfo,
426 1.1 jakllsch 4,
427 1.1 jakllsch FHand,
428 1.1 jakllsch &FileSystemVolumeLabelInfo,
429 1.1 jakllsch &BufferSize,
430 1.1 jakllsch Buffer
431 1.1 jakllsch );
432 1.1 jakllsch }
433 1.1 jakllsch
434 1.1 jakllsch return Buffer;
435 1.1 jakllsch }
436 1.1 jakllsch
437 1.1 jakllsch
438 1.1 jakllsch
439 1.1 jakllsch EFI_STATUS
440 1.1 jakllsch LibInstallProtocolInterfaces (
441 1.1 jakllsch IN OUT EFI_HANDLE *Handle,
442 1.1 jakllsch ...
443 1.1 jakllsch )
444 1.1 jakllsch {
445 1.1 jakllsch va_list args;
446 1.1 jakllsch EFI_STATUS Status;
447 1.1 jakllsch EFI_GUID *Protocol;
448 1.1 jakllsch VOID *Interface;
449 1.1 jakllsch EFI_TPL OldTpl;
450 1.1 jakllsch UINTN Index;
451 1.1 jakllsch EFI_HANDLE OldHandle;
452 1.1 jakllsch
453 1.1 jakllsch //
454 1.1 jakllsch // Syncronize with notifcations
455 1.1 jakllsch //
456 1.1 jakllsch
457 1.1 jakllsch OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
458 1.1 jakllsch OldHandle = *Handle;
459 1.1 jakllsch
460 1.1 jakllsch //
461 1.1 jakllsch // Install the protocol interfaces
462 1.1 jakllsch //
463 1.1 jakllsch
464 1.1 jakllsch Index = 0;
465 1.1 jakllsch Status = EFI_SUCCESS;
466 1.1 jakllsch va_start (args, Handle);
467 1.1 jakllsch
468 1.1 jakllsch while (!EFI_ERROR(Status)) {
469 1.1 jakllsch
470 1.1 jakllsch //
471 1.1 jakllsch // If protocol is NULL, then it's the end of the list
472 1.1 jakllsch //
473 1.1 jakllsch
474 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
475 1.1 jakllsch if (!Protocol) {
476 1.1 jakllsch break;
477 1.1 jakllsch }
478 1.1 jakllsch
479 1.1 jakllsch Interface = va_arg(args, VOID *);
480 1.1 jakllsch
481 1.1 jakllsch //
482 1.1 jakllsch // Install it
483 1.1 jakllsch //
484 1.1 jakllsch
485 1.1 jakllsch DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface));
486 1.1 jakllsch Status = uefi_call_wrapper(BS->InstallProtocolInterface, 4, Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
487 1.1 jakllsch if (EFI_ERROR(Status)) {
488 1.1 jakllsch break;
489 1.1 jakllsch }
490 1.1 jakllsch
491 1.1 jakllsch Index += 1;
492 1.1 jakllsch }
493 1.1 jakllsch
494 1.2 christos va_end (args);
495 1.2 christos
496 1.1 jakllsch //
497 1.1 jakllsch // If there was an error, remove all the interfaces that were
498 1.1 jakllsch // installed without any errors
499 1.1 jakllsch //
500 1.1 jakllsch
501 1.1 jakllsch if (EFI_ERROR(Status)) {
502 1.1 jakllsch va_start (args, Handle);
503 1.1 jakllsch while (Index) {
504 1.1 jakllsch
505 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
506 1.1 jakllsch Interface = va_arg(args, VOID *);
507 1.1 jakllsch uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface);
508 1.1 jakllsch
509 1.1 jakllsch Index -= 1;
510 1.1 jakllsch }
511 1.2 christos va_end (args);
512 1.1 jakllsch
513 1.1 jakllsch *Handle = OldHandle;
514 1.1 jakllsch }
515 1.1 jakllsch
516 1.1 jakllsch //
517 1.1 jakllsch // Done
518 1.1 jakllsch //
519 1.1 jakllsch
520 1.1 jakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
521 1.1 jakllsch return Status;
522 1.1 jakllsch }
523 1.1 jakllsch
524 1.1 jakllsch
525 1.1 jakllsch VOID
526 1.1 jakllsch LibUninstallProtocolInterfaces (
527 1.1 jakllsch IN EFI_HANDLE Handle,
528 1.1 jakllsch ...
529 1.1 jakllsch )
530 1.1 jakllsch {
531 1.1 jakllsch va_list args;
532 1.1 jakllsch EFI_STATUS Status;
533 1.1 jakllsch EFI_GUID *Protocol;
534 1.1 jakllsch VOID *Interface;
535 1.1 jakllsch
536 1.1 jakllsch
537 1.1 jakllsch va_start (args, Handle);
538 1.1 jakllsch for (; ;) {
539 1.1 jakllsch
540 1.1 jakllsch //
541 1.1 jakllsch // If protocol is NULL, then it's the end of the list
542 1.1 jakllsch //
543 1.1 jakllsch
544 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
545 1.1 jakllsch if (!Protocol) {
546 1.1 jakllsch break;
547 1.1 jakllsch }
548 1.1 jakllsch
549 1.1 jakllsch Interface = va_arg(args, VOID *);
550 1.1 jakllsch
551 1.1 jakllsch //
552 1.1 jakllsch // Uninstall it
553 1.1 jakllsch //
554 1.1 jakllsch
555 1.1 jakllsch Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface);
556 1.1 jakllsch if (EFI_ERROR(Status)) {
557 1.1 jakllsch DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle));
558 1.1 jakllsch }
559 1.1 jakllsch }
560 1.2 christos va_end (args);
561 1.1 jakllsch }
562 1.1 jakllsch
563 1.1 jakllsch
564 1.1 jakllsch EFI_STATUS
565 1.1 jakllsch LibReinstallProtocolInterfaces (
566 1.1 jakllsch IN OUT EFI_HANDLE *Handle,
567 1.1 jakllsch ...
568 1.1 jakllsch )
569 1.1 jakllsch {
570 1.1 jakllsch va_list args;
571 1.1 jakllsch EFI_STATUS Status;
572 1.1 jakllsch EFI_GUID *Protocol;
573 1.1 jakllsch VOID *OldInterface, *NewInterface;
574 1.1 jakllsch EFI_TPL OldTpl;
575 1.1 jakllsch UINTN Index;
576 1.1 jakllsch
577 1.1 jakllsch //
578 1.1 jakllsch // Syncronize with notifcations
579 1.1 jakllsch //
580 1.1 jakllsch
581 1.1 jakllsch OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
582 1.1 jakllsch
583 1.1 jakllsch //
584 1.1 jakllsch // Install the protocol interfaces
585 1.1 jakllsch //
586 1.1 jakllsch
587 1.1 jakllsch Index = 0;
588 1.1 jakllsch Status = EFI_SUCCESS;
589 1.1 jakllsch va_start (args, Handle);
590 1.1 jakllsch
591 1.1 jakllsch while (!EFI_ERROR(Status)) {
592 1.1 jakllsch
593 1.1 jakllsch //
594 1.1 jakllsch // If protocol is NULL, then it's the end of the list
595 1.1 jakllsch //
596 1.1 jakllsch
597 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
598 1.1 jakllsch if (!Protocol) {
599 1.1 jakllsch break;
600 1.1 jakllsch }
601 1.1 jakllsch
602 1.1 jakllsch OldInterface = va_arg(args, VOID *);
603 1.1 jakllsch NewInterface = va_arg(args, VOID *);
604 1.1 jakllsch
605 1.1 jakllsch //
606 1.1 jakllsch // Reinstall it
607 1.1 jakllsch //
608 1.1 jakllsch
609 1.1 jakllsch Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface);
610 1.1 jakllsch if (EFI_ERROR(Status)) {
611 1.1 jakllsch break;
612 1.1 jakllsch }
613 1.1 jakllsch
614 1.1 jakllsch Index += 1;
615 1.1 jakllsch }
616 1.1 jakllsch
617 1.2 christos va_end (args);
618 1.2 christos
619 1.1 jakllsch //
620 1.1 jakllsch // If there was an error, undo all the interfaces that were
621 1.1 jakllsch // reinstalled without any errors
622 1.1 jakllsch //
623 1.1 jakllsch
624 1.1 jakllsch if (EFI_ERROR(Status)) {
625 1.1 jakllsch va_start (args, Handle);
626 1.1 jakllsch while (Index) {
627 1.1 jakllsch
628 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
629 1.1 jakllsch OldInterface = va_arg(args, VOID *);
630 1.1 jakllsch NewInterface = va_arg(args, VOID *);
631 1.1 jakllsch
632 1.1 jakllsch uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface);
633 1.1 jakllsch
634 1.1 jakllsch Index -= 1;
635 1.1 jakllsch }
636 1.2 christos va_end (args);
637 1.1 jakllsch }
638 1.1 jakllsch
639 1.1 jakllsch //
640 1.1 jakllsch // Done
641 1.1 jakllsch //
642 1.1 jakllsch
643 1.1 jakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
644 1.1 jakllsch return Status;
645 1.1 jakllsch }
646