Home | History | Annotate | Line # | Download | only in lib
hand.c revision 1.3.12.1
      1  1.3.12.1  pgoyette /*	$NetBSD: hand.c,v 1.3.12.1 2018/09/06 06:56:39 pgoyette 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.3.12.1  pgoyette     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.3.12.1  pgoyette     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.3.12.1  pgoyette     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.3.12.1  pgoyette     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.3.12.1  pgoyette     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