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