1530d68baSNigel Croxon /*++ 2530d68baSNigel Croxon 3530d68baSNigel Croxon Copyright (c) 1998 Intel Corporation 4530d68baSNigel Croxon 5530d68baSNigel Croxon Module Name: 6530d68baSNigel Croxon 7530d68baSNigel Croxon hand.c 8530d68baSNigel Croxon 9530d68baSNigel Croxon Abstract: 10530d68baSNigel Croxon 11530d68baSNigel Croxon 12530d68baSNigel Croxon 13530d68baSNigel Croxon 14530d68baSNigel Croxon Revision History 15530d68baSNigel Croxon 16530d68baSNigel Croxon --*/ 17530d68baSNigel Croxon 18530d68baSNigel Croxon #include "lib.h" 19530d68baSNigel Croxon #include "efistdarg.h" // !!! 20530d68baSNigel Croxon 21530d68baSNigel Croxon 22530d68baSNigel Croxon EFI_STATUS 23530d68baSNigel Croxon LibLocateProtocol ( 24530d68baSNigel Croxon IN EFI_GUID *ProtocolGuid, 25530d68baSNigel Croxon OUT VOID **Interface 26530d68baSNigel Croxon ) 27530d68baSNigel Croxon // 28530d68baSNigel Croxon // Find the first instance of this Protocol in the system and return it's interface 29530d68baSNigel Croxon // 30530d68baSNigel Croxon { 31530d68baSNigel Croxon EFI_STATUS Status; 32530d68baSNigel Croxon UINTN NumberHandles, Index; 33530d68baSNigel Croxon EFI_HANDLE *Handles; 34530d68baSNigel Croxon 35530d68baSNigel Croxon 36530d68baSNigel Croxon *Interface = NULL; 37530d68baSNigel Croxon Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles); 38530d68baSNigel Croxon if (EFI_ERROR(Status)) { 39530d68baSNigel Croxon DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n")); 40530d68baSNigel Croxon return Status; 41530d68baSNigel Croxon } 42530d68baSNigel Croxon 43530d68baSNigel Croxon for (Index=0; Index < NumberHandles; Index++) { 44530d68baSNigel Croxon Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handles[Index], ProtocolGuid, Interface); 45530d68baSNigel Croxon if (!EFI_ERROR(Status)) { 46530d68baSNigel Croxon break; 47530d68baSNigel Croxon } 48530d68baSNigel Croxon } 49530d68baSNigel Croxon 50530d68baSNigel Croxon if (Handles) { 51530d68baSNigel Croxon FreePool (Handles); 52530d68baSNigel Croxon } 53530d68baSNigel Croxon 54530d68baSNigel Croxon return Status; 55530d68baSNigel Croxon } 56530d68baSNigel Croxon 57530d68baSNigel Croxon EFI_STATUS 58530d68baSNigel Croxon LibLocateHandle ( 59530d68baSNigel Croxon IN EFI_LOCATE_SEARCH_TYPE SearchType, 60530d68baSNigel Croxon IN EFI_GUID *Protocol OPTIONAL, 61530d68baSNigel Croxon IN VOID *SearchKey OPTIONAL, 62530d68baSNigel Croxon IN OUT UINTN *NoHandles, 63530d68baSNigel Croxon OUT EFI_HANDLE **Buffer 64530d68baSNigel Croxon ) 65530d68baSNigel Croxon 66530d68baSNigel Croxon { 67530d68baSNigel Croxon EFI_STATUS Status; 68530d68baSNigel Croxon UINTN BufferSize; 69530d68baSNigel Croxon 70530d68baSNigel Croxon // 71530d68baSNigel Croxon // Initialize for GrowBuffer loop 72530d68baSNigel Croxon // 73530d68baSNigel Croxon 74530d68baSNigel Croxon Status = EFI_SUCCESS; 75530d68baSNigel Croxon *Buffer = NULL; 76530d68baSNigel Croxon BufferSize = 50 * sizeof(EFI_HANDLE); 77530d68baSNigel Croxon 78530d68baSNigel Croxon // 79530d68baSNigel Croxon // Call the real function 80530d68baSNigel Croxon // 81530d68baSNigel Croxon 82530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) { 83530d68baSNigel Croxon 84530d68baSNigel Croxon Status = uefi_call_wrapper( 85530d68baSNigel Croxon BS->LocateHandle, 86530d68baSNigel Croxon 5, 87530d68baSNigel Croxon SearchType, 88530d68baSNigel Croxon Protocol, 89530d68baSNigel Croxon SearchKey, 90530d68baSNigel Croxon &BufferSize, 91530d68baSNigel Croxon *Buffer 92530d68baSNigel Croxon ); 93530d68baSNigel Croxon 94530d68baSNigel Croxon } 95530d68baSNigel Croxon 96530d68baSNigel Croxon *NoHandles = BufferSize / sizeof (EFI_HANDLE); 97530d68baSNigel Croxon if (EFI_ERROR(Status)) { 98530d68baSNigel Croxon *NoHandles = 0; 99530d68baSNigel Croxon } 100530d68baSNigel Croxon 101530d68baSNigel Croxon return Status; 102530d68baSNigel Croxon } 103530d68baSNigel Croxon 104530d68baSNigel Croxon EFI_STATUS 105530d68baSNigel Croxon LibLocateHandleByDiskSignature ( 106530d68baSNigel Croxon IN UINT8 MBRType, 107530d68baSNigel Croxon IN UINT8 SignatureType, 108530d68baSNigel Croxon IN VOID *Signature, 109530d68baSNigel Croxon IN OUT UINTN *NoHandles, 110530d68baSNigel Croxon OUT EFI_HANDLE **Buffer 111530d68baSNigel Croxon ) 112530d68baSNigel Croxon 113530d68baSNigel Croxon { 114530d68baSNigel Croxon EFI_STATUS Status; 115530d68baSNigel Croxon UINTN BufferSize; 116530d68baSNigel Croxon UINTN NoBlockIoHandles; 117530d68baSNigel Croxon EFI_HANDLE *BlockIoBuffer; 118530d68baSNigel Croxon EFI_DEVICE_PATH *DevicePath; 119530d68baSNigel Croxon UINTN Index; 1201ecae7d4SNigel Croxon EFI_DEVICE_PATH *Next, *DevPath; 121530d68baSNigel Croxon HARDDRIVE_DEVICE_PATH *HardDriveDevicePath; 122530d68baSNigel Croxon BOOLEAN Match; 123530d68baSNigel Croxon BOOLEAN PreviousNodeIsHardDriveDevicePath; 124530d68baSNigel Croxon 125530d68baSNigel Croxon // 126530d68baSNigel Croxon // Initialize for GrowBuffer loop 127530d68baSNigel Croxon // 128530d68baSNigel Croxon 129530d68baSNigel Croxon Status = EFI_SUCCESS; 130530d68baSNigel Croxon BlockIoBuffer = NULL; 131530d68baSNigel Croxon BufferSize = 50 * sizeof(EFI_HANDLE); 132530d68baSNigel Croxon 133530d68baSNigel Croxon // 134530d68baSNigel Croxon // Call the real function 135530d68baSNigel Croxon // 136530d68baSNigel Croxon 137530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) { 138530d68baSNigel Croxon 139530d68baSNigel Croxon // 140530d68baSNigel Croxon // Get list of device handles that support the BLOCK_IO Protocol. 141530d68baSNigel Croxon // 142530d68baSNigel Croxon 143530d68baSNigel Croxon Status = uefi_call_wrapper( 144530d68baSNigel Croxon BS->LocateHandle, 145530d68baSNigel Croxon 5, 146530d68baSNigel Croxon ByProtocol, 147530d68baSNigel Croxon &BlockIoProtocol, 148530d68baSNigel Croxon NULL, 149530d68baSNigel Croxon &BufferSize, 150530d68baSNigel Croxon BlockIoBuffer 151530d68baSNigel Croxon ); 152530d68baSNigel Croxon 153530d68baSNigel Croxon } 154530d68baSNigel Croxon 155530d68baSNigel Croxon NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE); 156530d68baSNigel Croxon if (EFI_ERROR(Status)) { 157530d68baSNigel Croxon NoBlockIoHandles = 0; 158530d68baSNigel Croxon } 159530d68baSNigel Croxon 160530d68baSNigel Croxon // 161530d68baSNigel Croxon // If there was an error or there are no device handles that support 162530d68baSNigel Croxon // the BLOCK_IO Protocol, then return. 163530d68baSNigel Croxon // 164530d68baSNigel Croxon 165530d68baSNigel Croxon if (NoBlockIoHandles == 0) { 166530d68baSNigel Croxon FreePool(BlockIoBuffer); 167530d68baSNigel Croxon *NoHandles = 0; 168530d68baSNigel Croxon *Buffer = NULL; 169530d68baSNigel Croxon return Status; 170530d68baSNigel Croxon } 171530d68baSNigel Croxon 172530d68baSNigel Croxon // 173530d68baSNigel Croxon // Loop through all the device handles that support the BLOCK_IO Protocol 174530d68baSNigel Croxon // 175530d68baSNigel Croxon 176530d68baSNigel Croxon *NoHandles = 0; 177530d68baSNigel Croxon 178530d68baSNigel Croxon for(Index=0;Index<NoBlockIoHandles;Index++) { 179530d68baSNigel Croxon 180530d68baSNigel Croxon Status = uefi_call_wrapper( 181530d68baSNigel Croxon BS->HandleProtocol, 182530d68baSNigel Croxon 3, 183530d68baSNigel Croxon BlockIoBuffer[Index], 184530d68baSNigel Croxon &DevicePathProtocol, 185530d68baSNigel Croxon (VOID*)&DevicePath 186530d68baSNigel Croxon ); 187530d68baSNigel Croxon 188530d68baSNigel Croxon // 189530d68baSNigel Croxon // Search DevicePath for a Hard Drive Media Device Path node. 190530d68baSNigel Croxon // If one is found, then see if it matches the signature that was 191530d68baSNigel Croxon // passed in. If it does match, and the next node is the End of the 192530d68baSNigel Croxon // device path, and the previous node is not a Hard Drive Media Device 193530d68baSNigel Croxon // Path, then we have found a match. 194530d68baSNigel Croxon // 195530d68baSNigel Croxon 196530d68baSNigel Croxon Match = FALSE; 197530d68baSNigel Croxon 198530d68baSNigel Croxon if (DevicePath != NULL) { 199530d68baSNigel Croxon 200530d68baSNigel Croxon PreviousNodeIsHardDriveDevicePath = FALSE; 201530d68baSNigel Croxon 202530d68baSNigel Croxon DevPath = DevicePath; 203530d68baSNigel Croxon 204530d68baSNigel Croxon // 205530d68baSNigel Croxon // Check for end of device path type 206530d68baSNigel Croxon // 207530d68baSNigel Croxon 208530d68baSNigel Croxon for (; ;) { 209530d68baSNigel Croxon 210530d68baSNigel Croxon if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) && 211530d68baSNigel Croxon (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) { 212530d68baSNigel Croxon 213530d68baSNigel Croxon HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath); 214530d68baSNigel Croxon 215530d68baSNigel Croxon if (PreviousNodeIsHardDriveDevicePath == FALSE) { 216530d68baSNigel Croxon 217530d68baSNigel Croxon Next = NextDevicePathNode(DevPath); 218530d68baSNigel Croxon if (IsDevicePathEndType(Next)) { 219530d68baSNigel Croxon if ((HardDriveDevicePath->MBRType == MBRType) && 220530d68baSNigel Croxon (HardDriveDevicePath->SignatureType == SignatureType)) { 221530d68baSNigel Croxon switch(SignatureType) { 222530d68baSNigel Croxon case SIGNATURE_TYPE_MBR: 223530d68baSNigel Croxon if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) { 224530d68baSNigel Croxon Match = TRUE; 225530d68baSNigel Croxon } 226530d68baSNigel Croxon break; 227530d68baSNigel Croxon case SIGNATURE_TYPE_GUID: 228530d68baSNigel Croxon if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0]))) == 0) { 229530d68baSNigel Croxon Match = TRUE; 230530d68baSNigel Croxon } 231530d68baSNigel Croxon break; 232530d68baSNigel Croxon } 233530d68baSNigel Croxon } 234530d68baSNigel Croxon } 235530d68baSNigel Croxon } 236530d68baSNigel Croxon PreviousNodeIsHardDriveDevicePath = TRUE; 237530d68baSNigel Croxon } else { 238530d68baSNigel Croxon PreviousNodeIsHardDriveDevicePath = FALSE; 239530d68baSNigel Croxon } 240530d68baSNigel Croxon 241530d68baSNigel Croxon if (IsDevicePathEnd(DevPath)) { 242530d68baSNigel Croxon break; 243530d68baSNigel Croxon } 244530d68baSNigel Croxon 245530d68baSNigel Croxon DevPath = NextDevicePathNode(DevPath); 246530d68baSNigel Croxon } 247530d68baSNigel Croxon 248530d68baSNigel Croxon } 249530d68baSNigel Croxon 250530d68baSNigel Croxon if (Match == FALSE) { 251530d68baSNigel Croxon BlockIoBuffer[Index] = NULL; 252530d68baSNigel Croxon } else { 253530d68baSNigel Croxon *NoHandles = *NoHandles + 1; 254530d68baSNigel Croxon } 255530d68baSNigel Croxon } 256530d68baSNigel Croxon 257530d68baSNigel Croxon // 258530d68baSNigel Croxon // If there are no matches, then return 259530d68baSNigel Croxon // 260530d68baSNigel Croxon 261530d68baSNigel Croxon if (*NoHandles == 0) { 262530d68baSNigel Croxon FreePool(BlockIoBuffer); 263530d68baSNigel Croxon *NoHandles = 0; 264530d68baSNigel Croxon *Buffer = NULL; 265530d68baSNigel Croxon return EFI_SUCCESS; 266530d68baSNigel Croxon } 267530d68baSNigel Croxon 268530d68baSNigel Croxon // 269530d68baSNigel Croxon // Allocate space for the return buffer of device handles. 270530d68baSNigel Croxon // 271530d68baSNigel Croxon 272530d68baSNigel Croxon *Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE)); 273530d68baSNigel Croxon 274530d68baSNigel Croxon if (*Buffer == NULL) { 275530d68baSNigel Croxon FreePool(BlockIoBuffer); 276530d68baSNigel Croxon *NoHandles = 0; 277530d68baSNigel Croxon *Buffer = NULL; 278530d68baSNigel Croxon return EFI_OUT_OF_RESOURCES; 279530d68baSNigel Croxon } 280530d68baSNigel Croxon 281530d68baSNigel Croxon // 282530d68baSNigel Croxon // Build list of matching device handles. 283530d68baSNigel Croxon // 284530d68baSNigel Croxon 285530d68baSNigel Croxon *NoHandles = 0; 286530d68baSNigel Croxon for(Index=0;Index<NoBlockIoHandles;Index++) { 287530d68baSNigel Croxon if (BlockIoBuffer[Index] != NULL) { 288530d68baSNigel Croxon (*Buffer)[*NoHandles] = BlockIoBuffer[Index]; 289530d68baSNigel Croxon *NoHandles = *NoHandles + 1; 290530d68baSNigel Croxon } 291530d68baSNigel Croxon } 292530d68baSNigel Croxon 293530d68baSNigel Croxon FreePool(BlockIoBuffer); 294530d68baSNigel Croxon 295530d68baSNigel Croxon return EFI_SUCCESS; 296530d68baSNigel Croxon } 297530d68baSNigel Croxon 298530d68baSNigel Croxon EFI_FILE_HANDLE 299530d68baSNigel Croxon LibOpenRoot ( 300530d68baSNigel Croxon IN EFI_HANDLE DeviceHandle 301530d68baSNigel Croxon ) 302530d68baSNigel Croxon { 303530d68baSNigel Croxon EFI_STATUS Status; 304530d68baSNigel Croxon EFI_FILE_IO_INTERFACE *Volume; 305530d68baSNigel Croxon EFI_FILE_HANDLE File; 306530d68baSNigel Croxon 307530d68baSNigel Croxon 308530d68baSNigel Croxon // 309530d68baSNigel Croxon // File the file system interface to the device 310530d68baSNigel Croxon // 311530d68baSNigel Croxon 312530d68baSNigel Croxon Status = uefi_call_wrapper(BS->HandleProtocol, 3, DeviceHandle, &FileSystemProtocol, (VOID*)&Volume); 313530d68baSNigel Croxon 314530d68baSNigel Croxon // 315530d68baSNigel Croxon // Open the root directory of the volume 316530d68baSNigel Croxon // 317530d68baSNigel Croxon 318530d68baSNigel Croxon if (!EFI_ERROR(Status)) { 319530d68baSNigel Croxon Status = uefi_call_wrapper(Volume->OpenVolume, 2, Volume, &File); 320530d68baSNigel Croxon } 321530d68baSNigel Croxon 322530d68baSNigel Croxon // 323530d68baSNigel Croxon // Done 324530d68baSNigel Croxon // 325530d68baSNigel Croxon 326530d68baSNigel Croxon return EFI_ERROR(Status) ? NULL : File; 327530d68baSNigel Croxon } 328530d68baSNigel Croxon 329530d68baSNigel Croxon EFI_FILE_INFO * 330530d68baSNigel Croxon LibFileInfo ( 331530d68baSNigel Croxon IN EFI_FILE_HANDLE FHand 332530d68baSNigel Croxon ) 333530d68baSNigel Croxon { 334530d68baSNigel Croxon EFI_STATUS Status; 335530d68baSNigel Croxon EFI_FILE_INFO *Buffer; 336530d68baSNigel Croxon UINTN BufferSize; 337530d68baSNigel Croxon 338530d68baSNigel Croxon // 339530d68baSNigel Croxon // Initialize for GrowBuffer loop 340530d68baSNigel Croxon // 341530d68baSNigel Croxon 342530d68baSNigel Croxon Status = EFI_SUCCESS; 343530d68baSNigel Croxon Buffer = NULL; 344530d68baSNigel Croxon BufferSize = SIZE_OF_EFI_FILE_INFO + 200; 345530d68baSNigel Croxon 346530d68baSNigel Croxon // 347530d68baSNigel Croxon // Call the real function 348530d68baSNigel Croxon // 349530d68baSNigel Croxon 350530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) { 351530d68baSNigel Croxon Status = uefi_call_wrapper( 352530d68baSNigel Croxon FHand->GetInfo, 353530d68baSNigel Croxon 4, 354530d68baSNigel Croxon FHand, 355530d68baSNigel Croxon &GenericFileInfo, 356530d68baSNigel Croxon &BufferSize, 357530d68baSNigel Croxon Buffer 358530d68baSNigel Croxon ); 359530d68baSNigel Croxon } 360530d68baSNigel Croxon 361530d68baSNigel Croxon return Buffer; 362530d68baSNigel Croxon } 363530d68baSNigel Croxon 364530d68baSNigel Croxon 365530d68baSNigel Croxon EFI_FILE_SYSTEM_INFO * 366530d68baSNigel Croxon LibFileSystemInfo ( 367530d68baSNigel Croxon IN EFI_FILE_HANDLE FHand 368530d68baSNigel Croxon ) 369530d68baSNigel Croxon { 370530d68baSNigel Croxon EFI_STATUS Status; 371530d68baSNigel Croxon EFI_FILE_SYSTEM_INFO *Buffer; 372530d68baSNigel Croxon UINTN BufferSize; 373530d68baSNigel Croxon 374530d68baSNigel Croxon // 375530d68baSNigel Croxon // Initialize for GrowBuffer loop 376530d68baSNigel Croxon // 377530d68baSNigel Croxon 378530d68baSNigel Croxon Status = EFI_SUCCESS; 379530d68baSNigel Croxon Buffer = NULL; 380530d68baSNigel Croxon BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200; 381530d68baSNigel Croxon 382530d68baSNigel Croxon // 383530d68baSNigel Croxon // Call the real function 384530d68baSNigel Croxon // 385530d68baSNigel Croxon 386530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) { 387530d68baSNigel Croxon Status = uefi_call_wrapper( 388530d68baSNigel Croxon FHand->GetInfo, 389530d68baSNigel Croxon 4, 390530d68baSNigel Croxon FHand, 391530d68baSNigel Croxon &FileSystemInfo, 392530d68baSNigel Croxon &BufferSize, 393530d68baSNigel Croxon Buffer 394530d68baSNigel Croxon ); 395530d68baSNigel Croxon } 396530d68baSNigel Croxon 397530d68baSNigel Croxon return Buffer; 398530d68baSNigel Croxon } 399530d68baSNigel Croxon 400530d68baSNigel Croxon EFI_FILE_SYSTEM_VOLUME_LABEL_INFO * 401530d68baSNigel Croxon LibFileSystemVolumeLabelInfo ( 402530d68baSNigel Croxon IN EFI_FILE_HANDLE FHand 403530d68baSNigel Croxon ) 404530d68baSNigel Croxon { 405530d68baSNigel Croxon EFI_STATUS Status; 406530d68baSNigel Croxon EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer; 407530d68baSNigel Croxon UINTN BufferSize; 408530d68baSNigel Croxon 409530d68baSNigel Croxon // 410530d68baSNigel Croxon // Initialize for GrowBuffer loop 411530d68baSNigel Croxon // 412530d68baSNigel Croxon 413530d68baSNigel Croxon Status = EFI_SUCCESS; 414530d68baSNigel Croxon Buffer = NULL; 415530d68baSNigel Croxon BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200; 416530d68baSNigel Croxon 417530d68baSNigel Croxon // 418530d68baSNigel Croxon // Call the real function 419530d68baSNigel Croxon // 420530d68baSNigel Croxon 421530d68baSNigel Croxon while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) { 422530d68baSNigel Croxon Status = uefi_call_wrapper( 423530d68baSNigel Croxon FHand->GetInfo, 424530d68baSNigel Croxon 4, 425530d68baSNigel Croxon FHand, 426530d68baSNigel Croxon &FileSystemVolumeLabelInfo, 427530d68baSNigel Croxon &BufferSize, 428530d68baSNigel Croxon Buffer 429530d68baSNigel Croxon ); 430530d68baSNigel Croxon } 431530d68baSNigel Croxon 432530d68baSNigel Croxon return Buffer; 433530d68baSNigel Croxon } 434530d68baSNigel Croxon 435530d68baSNigel Croxon 436530d68baSNigel Croxon 437530d68baSNigel Croxon EFI_STATUS 438530d68baSNigel Croxon LibInstallProtocolInterfaces ( 439530d68baSNigel Croxon IN OUT EFI_HANDLE *Handle, 440530d68baSNigel Croxon ... 441530d68baSNigel Croxon ) 442530d68baSNigel Croxon { 443530d68baSNigel Croxon va_list args; 444530d68baSNigel Croxon EFI_STATUS Status; 445530d68baSNigel Croxon EFI_GUID *Protocol; 446530d68baSNigel Croxon VOID *Interface; 447530d68baSNigel Croxon EFI_TPL OldTpl; 448530d68baSNigel Croxon UINTN Index; 449530d68baSNigel Croxon EFI_HANDLE OldHandle; 450530d68baSNigel Croxon 451530d68baSNigel Croxon // 452530d68baSNigel Croxon // Syncronize with notifcations 453530d68baSNigel Croxon // 454530d68baSNigel Croxon 455530d68baSNigel Croxon OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY); 456530d68baSNigel Croxon OldHandle = *Handle; 457530d68baSNigel Croxon 458530d68baSNigel Croxon // 459530d68baSNigel Croxon // Install the protocol interfaces 460530d68baSNigel Croxon // 461530d68baSNigel Croxon 462530d68baSNigel Croxon Index = 0; 463530d68baSNigel Croxon Status = EFI_SUCCESS; 464530d68baSNigel Croxon va_start (args, Handle); 465530d68baSNigel Croxon 466530d68baSNigel Croxon while (!EFI_ERROR(Status)) { 467530d68baSNigel Croxon 468530d68baSNigel Croxon // 469530d68baSNigel Croxon // If protocol is NULL, then it's the end of the list 470530d68baSNigel Croxon // 471530d68baSNigel Croxon 472530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *); 473530d68baSNigel Croxon if (!Protocol) { 474530d68baSNigel Croxon break; 475530d68baSNigel Croxon } 476530d68baSNigel Croxon 477530d68baSNigel Croxon Interface = va_arg(args, VOID *); 478530d68baSNigel Croxon 479530d68baSNigel Croxon // 480530d68baSNigel Croxon // Install it 481530d68baSNigel Croxon // 482530d68baSNigel Croxon 483530d68baSNigel Croxon DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface)); 484530d68baSNigel Croxon Status = uefi_call_wrapper(BS->InstallProtocolInterface, 4, Handle, Protocol, EFI_NATIVE_INTERFACE, Interface); 485530d68baSNigel Croxon if (EFI_ERROR(Status)) { 486530d68baSNigel Croxon break; 487530d68baSNigel Croxon } 488530d68baSNigel Croxon 489530d68baSNigel Croxon Index += 1; 490530d68baSNigel Croxon } 4910ec661b3SHeinrich Schuchardt va_end (args); 492530d68baSNigel Croxon 493530d68baSNigel Croxon // 494530d68baSNigel Croxon // If there was an error, remove all the interfaces that were 495530d68baSNigel Croxon // installed without any errors 496530d68baSNigel Croxon // 497530d68baSNigel Croxon 498530d68baSNigel Croxon if (EFI_ERROR(Status)) { 499530d68baSNigel Croxon va_start (args, Handle); 500530d68baSNigel Croxon while (Index) { 501530d68baSNigel Croxon 502530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *); 503530d68baSNigel Croxon Interface = va_arg(args, VOID *); 504530d68baSNigel Croxon uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface); 505530d68baSNigel Croxon 506530d68baSNigel Croxon Index -= 1; 507530d68baSNigel Croxon } 508530d68baSNigel Croxon 509530d68baSNigel Croxon *Handle = OldHandle; 5100ec661b3SHeinrich Schuchardt va_end (args); 511530d68baSNigel Croxon } 512530d68baSNigel Croxon 513530d68baSNigel Croxon // 514530d68baSNigel Croxon // Done 515530d68baSNigel Croxon // 516530d68baSNigel Croxon 517530d68baSNigel Croxon uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl); 518530d68baSNigel Croxon return Status; 519530d68baSNigel Croxon } 520530d68baSNigel Croxon 521530d68baSNigel Croxon 522530d68baSNigel Croxon VOID 523530d68baSNigel Croxon LibUninstallProtocolInterfaces ( 524530d68baSNigel Croxon IN EFI_HANDLE Handle, 525530d68baSNigel Croxon ... 526530d68baSNigel Croxon ) 527530d68baSNigel Croxon { 528530d68baSNigel Croxon va_list args; 529530d68baSNigel Croxon EFI_STATUS Status; 530530d68baSNigel Croxon EFI_GUID *Protocol; 531530d68baSNigel Croxon VOID *Interface; 532530d68baSNigel Croxon 533530d68baSNigel Croxon 534530d68baSNigel Croxon va_start (args, Handle); 535530d68baSNigel Croxon for (; ;) { 536530d68baSNigel Croxon 537530d68baSNigel Croxon // 538530d68baSNigel Croxon // If protocol is NULL, then it's the end of the list 539530d68baSNigel Croxon // 540530d68baSNigel Croxon 541530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *); 542530d68baSNigel Croxon if (!Protocol) { 543530d68baSNigel Croxon break; 544530d68baSNigel Croxon } 545530d68baSNigel Croxon 546530d68baSNigel Croxon Interface = va_arg(args, VOID *); 547530d68baSNigel Croxon 548530d68baSNigel Croxon // 549530d68baSNigel Croxon // Uninstall it 550530d68baSNigel Croxon // 551530d68baSNigel Croxon 552530d68baSNigel Croxon Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface); 553530d68baSNigel Croxon if (EFI_ERROR(Status)) { 554530d68baSNigel Croxon DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle)); 555530d68baSNigel Croxon } 556530d68baSNigel Croxon } 5570ec661b3SHeinrich Schuchardt va_end (args); 558530d68baSNigel Croxon } 559530d68baSNigel Croxon 560530d68baSNigel Croxon 561530d68baSNigel Croxon EFI_STATUS 562530d68baSNigel Croxon LibReinstallProtocolInterfaces ( 563530d68baSNigel Croxon IN OUT EFI_HANDLE *Handle, 564530d68baSNigel Croxon ... 565530d68baSNigel Croxon ) 566530d68baSNigel Croxon { 567530d68baSNigel Croxon va_list args; 568530d68baSNigel Croxon EFI_STATUS Status; 569530d68baSNigel Croxon EFI_GUID *Protocol; 570530d68baSNigel Croxon VOID *OldInterface, *NewInterface; 571530d68baSNigel Croxon EFI_TPL OldTpl; 572530d68baSNigel Croxon UINTN Index; 573530d68baSNigel Croxon 574530d68baSNigel Croxon // 575530d68baSNigel Croxon // Syncronize with notifcations 576530d68baSNigel Croxon // 577530d68baSNigel Croxon 578530d68baSNigel Croxon OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY); 579530d68baSNigel Croxon 580530d68baSNigel Croxon // 581530d68baSNigel Croxon // Install the protocol interfaces 582530d68baSNigel Croxon // 583530d68baSNigel Croxon 584530d68baSNigel Croxon Index = 0; 585530d68baSNigel Croxon Status = EFI_SUCCESS; 586530d68baSNigel Croxon va_start (args, Handle); 587530d68baSNigel Croxon 588530d68baSNigel Croxon while (!EFI_ERROR(Status)) { 589530d68baSNigel Croxon 590530d68baSNigel Croxon // 591530d68baSNigel Croxon // If protocol is NULL, then it's the end of the list 592530d68baSNigel Croxon // 593530d68baSNigel Croxon 594530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *); 595530d68baSNigel Croxon if (!Protocol) { 596530d68baSNigel Croxon break; 597530d68baSNigel Croxon } 598530d68baSNigel Croxon 599530d68baSNigel Croxon OldInterface = va_arg(args, VOID *); 600530d68baSNigel Croxon NewInterface = va_arg(args, VOID *); 601530d68baSNigel Croxon 602530d68baSNigel Croxon // 603530d68baSNigel Croxon // Reinstall it 604530d68baSNigel Croxon // 605530d68baSNigel Croxon 606530d68baSNigel Croxon Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface); 607530d68baSNigel Croxon if (EFI_ERROR(Status)) { 608530d68baSNigel Croxon break; 609530d68baSNigel Croxon } 610530d68baSNigel Croxon 611530d68baSNigel Croxon Index += 1; 612530d68baSNigel Croxon } 613*70402aa9SHeinrich Schuchardt va_end (args); 614530d68baSNigel Croxon 615530d68baSNigel Croxon // 616530d68baSNigel Croxon // If there was an error, undo all the interfaces that were 617530d68baSNigel Croxon // reinstalled without any errors 618530d68baSNigel Croxon // 619530d68baSNigel Croxon 620530d68baSNigel Croxon if (EFI_ERROR(Status)) { 621530d68baSNigel Croxon va_start (args, Handle); 622530d68baSNigel Croxon while (Index) { 623530d68baSNigel Croxon 624530d68baSNigel Croxon Protocol = va_arg(args, EFI_GUID *); 625530d68baSNigel Croxon OldInterface = va_arg(args, VOID *); 626530d68baSNigel Croxon NewInterface = va_arg(args, VOID *); 627530d68baSNigel Croxon 628530d68baSNigel Croxon uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface); 629530d68baSNigel Croxon 630530d68baSNigel Croxon Index -= 1; 631530d68baSNigel Croxon } 632*70402aa9SHeinrich Schuchardt va_end (args); 633530d68baSNigel Croxon } 634530d68baSNigel Croxon 635530d68baSNigel Croxon // 636530d68baSNigel Croxon // Done 637530d68baSNigel Croxon // 638530d68baSNigel Croxon 639530d68baSNigel Croxon uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl); 640530d68baSNigel Croxon return Status; 641530d68baSNigel Croxon } 642