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