hand.c revision 1.2 1 1.2 christos /* $NetBSD: hand.c,v 1.2 2015/12/15 12:36:10 christos 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.1 jakllsch EFI_DEVICE_PATH *Start, *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.1 jakllsch BlockIoBuffer = NULL;
132 1.1 jakllsch BufferSize = 50 * sizeof(EFI_HANDLE);
133 1.1 jakllsch
134 1.1 jakllsch //
135 1.1 jakllsch // Call the real function
136 1.1 jakllsch //
137 1.1 jakllsch
138 1.1 jakllsch while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) {
139 1.1 jakllsch
140 1.1 jakllsch //
141 1.1 jakllsch // Get list of device handles that support the BLOCK_IO Protocol.
142 1.1 jakllsch //
143 1.1 jakllsch
144 1.1 jakllsch Status = uefi_call_wrapper(
145 1.1 jakllsch BS->LocateHandle,
146 1.1 jakllsch 5,
147 1.1 jakllsch ByProtocol,
148 1.1 jakllsch &BlockIoProtocol,
149 1.1 jakllsch NULL,
150 1.1 jakllsch &BufferSize,
151 1.1 jakllsch BlockIoBuffer
152 1.1 jakllsch );
153 1.1 jakllsch
154 1.1 jakllsch }
155 1.1 jakllsch
156 1.1 jakllsch NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE);
157 1.1 jakllsch if (EFI_ERROR(Status)) {
158 1.1 jakllsch NoBlockIoHandles = 0;
159 1.1 jakllsch }
160 1.1 jakllsch
161 1.1 jakllsch //
162 1.1 jakllsch // If there was an error or there are no device handles that support
163 1.1 jakllsch // the BLOCK_IO Protocol, then return.
164 1.1 jakllsch //
165 1.1 jakllsch
166 1.1 jakllsch if (NoBlockIoHandles == 0) {
167 1.1 jakllsch FreePool(BlockIoBuffer);
168 1.1 jakllsch *NoHandles = 0;
169 1.1 jakllsch *Buffer = NULL;
170 1.1 jakllsch return Status;
171 1.1 jakllsch }
172 1.1 jakllsch
173 1.1 jakllsch //
174 1.1 jakllsch // Loop through all the device handles that support the BLOCK_IO Protocol
175 1.1 jakllsch //
176 1.1 jakllsch
177 1.1 jakllsch *NoHandles = 0;
178 1.1 jakllsch
179 1.1 jakllsch for(Index=0;Index<NoBlockIoHandles;Index++) {
180 1.1 jakllsch
181 1.1 jakllsch Status = uefi_call_wrapper(
182 1.1 jakllsch BS->HandleProtocol,
183 1.1 jakllsch 3,
184 1.1 jakllsch BlockIoBuffer[Index],
185 1.1 jakllsch &DevicePathProtocol,
186 1.1 jakllsch (VOID*)&DevicePath
187 1.1 jakllsch );
188 1.1 jakllsch
189 1.1 jakllsch //
190 1.1 jakllsch // Search DevicePath for a Hard Drive Media Device Path node.
191 1.1 jakllsch // If one is found, then see if it matches the signature that was
192 1.1 jakllsch // passed in. If it does match, and the next node is the End of the
193 1.1 jakllsch // device path, and the previous node is not a Hard Drive Media Device
194 1.1 jakllsch // Path, then we have found a match.
195 1.1 jakllsch //
196 1.1 jakllsch
197 1.1 jakllsch Match = FALSE;
198 1.1 jakllsch
199 1.1 jakllsch if (DevicePath != NULL) {
200 1.1 jakllsch
201 1.1 jakllsch PreviousNodeIsHardDriveDevicePath = FALSE;
202 1.1 jakllsch
203 1.1 jakllsch DevPath = DevicePath;
204 1.1 jakllsch Start = DevPath;
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.1 jakllsch Buffer = NULL;
345 1.1 jakllsch BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
346 1.1 jakllsch
347 1.1 jakllsch //
348 1.1 jakllsch // Call the real function
349 1.1 jakllsch //
350 1.1 jakllsch
351 1.1 jakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
352 1.1 jakllsch Status = uefi_call_wrapper(
353 1.1 jakllsch FHand->GetInfo,
354 1.1 jakllsch 4,
355 1.1 jakllsch FHand,
356 1.1 jakllsch &GenericFileInfo,
357 1.1 jakllsch &BufferSize,
358 1.1 jakllsch Buffer
359 1.1 jakllsch );
360 1.1 jakllsch }
361 1.1 jakllsch
362 1.1 jakllsch return Buffer;
363 1.1 jakllsch }
364 1.1 jakllsch
365 1.1 jakllsch
366 1.1 jakllsch EFI_FILE_SYSTEM_INFO *
367 1.1 jakllsch LibFileSystemInfo (
368 1.1 jakllsch IN EFI_FILE_HANDLE FHand
369 1.1 jakllsch )
370 1.1 jakllsch {
371 1.1 jakllsch EFI_STATUS Status;
372 1.1 jakllsch EFI_FILE_SYSTEM_INFO *Buffer;
373 1.1 jakllsch UINTN BufferSize;
374 1.1 jakllsch
375 1.1 jakllsch //
376 1.1 jakllsch // Initialize for GrowBuffer loop
377 1.1 jakllsch //
378 1.1 jakllsch
379 1.1 jakllsch Buffer = NULL;
380 1.1 jakllsch BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200;
381 1.1 jakllsch
382 1.1 jakllsch //
383 1.1 jakllsch // Call the real function
384 1.1 jakllsch //
385 1.1 jakllsch
386 1.1 jakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
387 1.1 jakllsch Status = uefi_call_wrapper(
388 1.1 jakllsch FHand->GetInfo,
389 1.1 jakllsch 4,
390 1.1 jakllsch FHand,
391 1.1 jakllsch &FileSystemInfo,
392 1.1 jakllsch &BufferSize,
393 1.1 jakllsch Buffer
394 1.1 jakllsch );
395 1.1 jakllsch }
396 1.1 jakllsch
397 1.1 jakllsch return Buffer;
398 1.1 jakllsch }
399 1.1 jakllsch
400 1.1 jakllsch EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
401 1.1 jakllsch LibFileSystemVolumeLabelInfo (
402 1.1 jakllsch IN EFI_FILE_HANDLE FHand
403 1.1 jakllsch )
404 1.1 jakllsch {
405 1.1 jakllsch EFI_STATUS Status;
406 1.1 jakllsch EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
407 1.1 jakllsch UINTN BufferSize;
408 1.1 jakllsch
409 1.1 jakllsch //
410 1.1 jakllsch // Initialize for GrowBuffer loop
411 1.1 jakllsch //
412 1.1 jakllsch
413 1.1 jakllsch Buffer = NULL;
414 1.1 jakllsch BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
415 1.1 jakllsch
416 1.1 jakllsch //
417 1.1 jakllsch // Call the real function
418 1.1 jakllsch //
419 1.1 jakllsch
420 1.1 jakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
421 1.1 jakllsch Status = uefi_call_wrapper(
422 1.1 jakllsch FHand->GetInfo,
423 1.1 jakllsch 4,
424 1.1 jakllsch FHand,
425 1.1 jakllsch &FileSystemVolumeLabelInfo,
426 1.1 jakllsch &BufferSize,
427 1.1 jakllsch Buffer
428 1.1 jakllsch );
429 1.1 jakllsch }
430 1.1 jakllsch
431 1.1 jakllsch return Buffer;
432 1.1 jakllsch }
433 1.1 jakllsch
434 1.1 jakllsch
435 1.1 jakllsch
436 1.1 jakllsch EFI_STATUS
437 1.1 jakllsch LibInstallProtocolInterfaces (
438 1.1 jakllsch IN OUT EFI_HANDLE *Handle,
439 1.1 jakllsch ...
440 1.1 jakllsch )
441 1.1 jakllsch {
442 1.1 jakllsch va_list args;
443 1.1 jakllsch EFI_STATUS Status;
444 1.1 jakllsch EFI_GUID *Protocol;
445 1.1 jakllsch VOID *Interface;
446 1.1 jakllsch EFI_TPL OldTpl;
447 1.1 jakllsch UINTN Index;
448 1.1 jakllsch EFI_HANDLE OldHandle;
449 1.1 jakllsch
450 1.1 jakllsch //
451 1.1 jakllsch // Syncronize with notifcations
452 1.1 jakllsch //
453 1.1 jakllsch
454 1.1 jakllsch OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
455 1.1 jakllsch OldHandle = *Handle;
456 1.1 jakllsch
457 1.1 jakllsch //
458 1.1 jakllsch // Install the protocol interfaces
459 1.1 jakllsch //
460 1.1 jakllsch
461 1.1 jakllsch Index = 0;
462 1.1 jakllsch Status = EFI_SUCCESS;
463 1.1 jakllsch va_start (args, Handle);
464 1.1 jakllsch
465 1.1 jakllsch while (!EFI_ERROR(Status)) {
466 1.1 jakllsch
467 1.1 jakllsch //
468 1.1 jakllsch // If protocol is NULL, then it's the end of the list
469 1.1 jakllsch //
470 1.1 jakllsch
471 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
472 1.1 jakllsch if (!Protocol) {
473 1.1 jakllsch break;
474 1.1 jakllsch }
475 1.1 jakllsch
476 1.1 jakllsch Interface = va_arg(args, VOID *);
477 1.1 jakllsch
478 1.1 jakllsch //
479 1.1 jakllsch // Install it
480 1.1 jakllsch //
481 1.1 jakllsch
482 1.1 jakllsch DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface));
483 1.1 jakllsch Status = uefi_call_wrapper(BS->InstallProtocolInterface, 4, Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
484 1.1 jakllsch if (EFI_ERROR(Status)) {
485 1.1 jakllsch break;
486 1.1 jakllsch }
487 1.1 jakllsch
488 1.1 jakllsch Index += 1;
489 1.1 jakllsch }
490 1.1 jakllsch
491 1.2 christos va_end (args);
492 1.2 christos
493 1.1 jakllsch //
494 1.1 jakllsch // If there was an error, remove all the interfaces that were
495 1.1 jakllsch // installed without any errors
496 1.1 jakllsch //
497 1.1 jakllsch
498 1.1 jakllsch if (EFI_ERROR(Status)) {
499 1.1 jakllsch va_start (args, Handle);
500 1.1 jakllsch while (Index) {
501 1.1 jakllsch
502 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
503 1.1 jakllsch Interface = va_arg(args, VOID *);
504 1.1 jakllsch uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface);
505 1.1 jakllsch
506 1.1 jakllsch Index -= 1;
507 1.1 jakllsch }
508 1.2 christos va_end (args);
509 1.1 jakllsch
510 1.1 jakllsch *Handle = OldHandle;
511 1.1 jakllsch }
512 1.1 jakllsch
513 1.1 jakllsch //
514 1.1 jakllsch // Done
515 1.1 jakllsch //
516 1.1 jakllsch
517 1.1 jakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
518 1.1 jakllsch return Status;
519 1.1 jakllsch }
520 1.1 jakllsch
521 1.1 jakllsch
522 1.1 jakllsch VOID
523 1.1 jakllsch LibUninstallProtocolInterfaces (
524 1.1 jakllsch IN EFI_HANDLE Handle,
525 1.1 jakllsch ...
526 1.1 jakllsch )
527 1.1 jakllsch {
528 1.1 jakllsch va_list args;
529 1.1 jakllsch EFI_STATUS Status;
530 1.1 jakllsch EFI_GUID *Protocol;
531 1.1 jakllsch VOID *Interface;
532 1.1 jakllsch
533 1.1 jakllsch
534 1.1 jakllsch va_start (args, Handle);
535 1.1 jakllsch for (; ;) {
536 1.1 jakllsch
537 1.1 jakllsch //
538 1.1 jakllsch // If protocol is NULL, then it's the end of the list
539 1.1 jakllsch //
540 1.1 jakllsch
541 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
542 1.1 jakllsch if (!Protocol) {
543 1.1 jakllsch break;
544 1.1 jakllsch }
545 1.1 jakllsch
546 1.1 jakllsch Interface = va_arg(args, VOID *);
547 1.1 jakllsch
548 1.1 jakllsch //
549 1.1 jakllsch // Uninstall it
550 1.1 jakllsch //
551 1.1 jakllsch
552 1.1 jakllsch Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface);
553 1.1 jakllsch if (EFI_ERROR(Status)) {
554 1.1 jakllsch DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle));
555 1.1 jakllsch }
556 1.1 jakllsch }
557 1.2 christos va_end (args);
558 1.1 jakllsch }
559 1.1 jakllsch
560 1.1 jakllsch
561 1.1 jakllsch EFI_STATUS
562 1.1 jakllsch LibReinstallProtocolInterfaces (
563 1.1 jakllsch IN OUT EFI_HANDLE *Handle,
564 1.1 jakllsch ...
565 1.1 jakllsch )
566 1.1 jakllsch {
567 1.1 jakllsch va_list args;
568 1.1 jakllsch EFI_STATUS Status;
569 1.1 jakllsch EFI_GUID *Protocol;
570 1.1 jakllsch VOID *OldInterface, *NewInterface;
571 1.1 jakllsch EFI_TPL OldTpl;
572 1.1 jakllsch UINTN Index;
573 1.1 jakllsch
574 1.1 jakllsch //
575 1.1 jakllsch // Syncronize with notifcations
576 1.1 jakllsch //
577 1.1 jakllsch
578 1.1 jakllsch OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
579 1.1 jakllsch
580 1.1 jakllsch //
581 1.1 jakllsch // Install the protocol interfaces
582 1.1 jakllsch //
583 1.1 jakllsch
584 1.1 jakllsch Index = 0;
585 1.1 jakllsch Status = EFI_SUCCESS;
586 1.1 jakllsch va_start (args, Handle);
587 1.1 jakllsch
588 1.1 jakllsch while (!EFI_ERROR(Status)) {
589 1.1 jakllsch
590 1.1 jakllsch //
591 1.1 jakllsch // If protocol is NULL, then it's the end of the list
592 1.1 jakllsch //
593 1.1 jakllsch
594 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
595 1.1 jakllsch if (!Protocol) {
596 1.1 jakllsch break;
597 1.1 jakllsch }
598 1.1 jakllsch
599 1.1 jakllsch OldInterface = va_arg(args, VOID *);
600 1.1 jakllsch NewInterface = va_arg(args, VOID *);
601 1.1 jakllsch
602 1.1 jakllsch //
603 1.1 jakllsch // Reinstall it
604 1.1 jakllsch //
605 1.1 jakllsch
606 1.1 jakllsch Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface);
607 1.1 jakllsch if (EFI_ERROR(Status)) {
608 1.1 jakllsch break;
609 1.1 jakllsch }
610 1.1 jakllsch
611 1.1 jakllsch Index += 1;
612 1.1 jakllsch }
613 1.1 jakllsch
614 1.2 christos va_end (args);
615 1.2 christos
616 1.1 jakllsch //
617 1.1 jakllsch // If there was an error, undo all the interfaces that were
618 1.1 jakllsch // reinstalled without any errors
619 1.1 jakllsch //
620 1.1 jakllsch
621 1.1 jakllsch if (EFI_ERROR(Status)) {
622 1.1 jakllsch va_start (args, Handle);
623 1.1 jakllsch while (Index) {
624 1.1 jakllsch
625 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *);
626 1.1 jakllsch OldInterface = va_arg(args, VOID *);
627 1.1 jakllsch NewInterface = va_arg(args, VOID *);
628 1.1 jakllsch
629 1.1 jakllsch uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface);
630 1.1 jakllsch
631 1.1 jakllsch Index -= 1;
632 1.1 jakllsch }
633 1.2 christos va_end (args);
634 1.1 jakllsch }
635 1.1 jakllsch
636 1.1 jakllsch //
637 1.1 jakllsch // Done
638 1.1 jakllsch //
639 1.1 jakllsch
640 1.1 jakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
641 1.1 jakllsch return Status;
642 1.1 jakllsch }
643