1 1.4 jmcneill /* $NetBSD: hand.c,v 1.5 2021/09/30 19:02:48 jmcneill 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.4 jmcneill 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.4 jmcneill 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.4 jmcneill 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.4 jmcneill 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.4 jmcneill 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.5 jmcneill va_end (args); 494 1.1 jakllsch 495 1.2 christos va_end (args); 496 1.2 christos 497 1.1 jakllsch // 498 1.1 jakllsch // If there was an error, remove all the interfaces that were 499 1.1 jakllsch // installed without any errors 500 1.1 jakllsch // 501 1.1 jakllsch 502 1.1 jakllsch if (EFI_ERROR(Status)) { 503 1.1 jakllsch va_start (args, Handle); 504 1.1 jakllsch while (Index) { 505 1.1 jakllsch 506 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *); 507 1.1 jakllsch Interface = va_arg(args, VOID *); 508 1.1 jakllsch uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface); 509 1.1 jakllsch 510 1.1 jakllsch Index -= 1; 511 1.1 jakllsch } 512 1.2 christos va_end (args); 513 1.1 jakllsch 514 1.1 jakllsch *Handle = OldHandle; 515 1.5 jmcneill va_end (args); 516 1.1 jakllsch } 517 1.1 jakllsch 518 1.1 jakllsch // 519 1.1 jakllsch // Done 520 1.1 jakllsch // 521 1.1 jakllsch 522 1.1 jakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl); 523 1.1 jakllsch return Status; 524 1.1 jakllsch } 525 1.1 jakllsch 526 1.1 jakllsch 527 1.1 jakllsch VOID 528 1.1 jakllsch LibUninstallProtocolInterfaces ( 529 1.1 jakllsch IN EFI_HANDLE Handle, 530 1.1 jakllsch ... 531 1.1 jakllsch ) 532 1.1 jakllsch { 533 1.1 jakllsch va_list args; 534 1.1 jakllsch EFI_STATUS Status; 535 1.1 jakllsch EFI_GUID *Protocol; 536 1.1 jakllsch VOID *Interface; 537 1.1 jakllsch 538 1.1 jakllsch 539 1.1 jakllsch va_start (args, Handle); 540 1.1 jakllsch for (; ;) { 541 1.1 jakllsch 542 1.1 jakllsch // 543 1.1 jakllsch // If protocol is NULL, then it's the end of the list 544 1.1 jakllsch // 545 1.1 jakllsch 546 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *); 547 1.1 jakllsch if (!Protocol) { 548 1.1 jakllsch break; 549 1.1 jakllsch } 550 1.1 jakllsch 551 1.1 jakllsch Interface = va_arg(args, VOID *); 552 1.1 jakllsch 553 1.1 jakllsch // 554 1.1 jakllsch // Uninstall it 555 1.1 jakllsch // 556 1.1 jakllsch 557 1.1 jakllsch Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface); 558 1.1 jakllsch if (EFI_ERROR(Status)) { 559 1.1 jakllsch DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle)); 560 1.1 jakllsch } 561 1.1 jakllsch } 562 1.2 christos va_end (args); 563 1.1 jakllsch } 564 1.1 jakllsch 565 1.1 jakllsch 566 1.1 jakllsch EFI_STATUS 567 1.1 jakllsch LibReinstallProtocolInterfaces ( 568 1.1 jakllsch IN OUT EFI_HANDLE *Handle, 569 1.1 jakllsch ... 570 1.1 jakllsch ) 571 1.1 jakllsch { 572 1.1 jakllsch va_list args; 573 1.1 jakllsch EFI_STATUS Status; 574 1.1 jakllsch EFI_GUID *Protocol; 575 1.1 jakllsch VOID *OldInterface, *NewInterface; 576 1.1 jakllsch EFI_TPL OldTpl; 577 1.1 jakllsch UINTN Index; 578 1.1 jakllsch 579 1.1 jakllsch // 580 1.1 jakllsch // Syncronize with notifcations 581 1.1 jakllsch // 582 1.1 jakllsch 583 1.1 jakllsch OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY); 584 1.1 jakllsch 585 1.1 jakllsch // 586 1.1 jakllsch // Install the protocol interfaces 587 1.1 jakllsch // 588 1.1 jakllsch 589 1.1 jakllsch Index = 0; 590 1.1 jakllsch Status = EFI_SUCCESS; 591 1.1 jakllsch va_start (args, Handle); 592 1.1 jakllsch 593 1.1 jakllsch while (!EFI_ERROR(Status)) { 594 1.1 jakllsch 595 1.1 jakllsch // 596 1.1 jakllsch // If protocol is NULL, then it's the end of the list 597 1.1 jakllsch // 598 1.1 jakllsch 599 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *); 600 1.1 jakllsch if (!Protocol) { 601 1.1 jakllsch break; 602 1.1 jakllsch } 603 1.1 jakllsch 604 1.1 jakllsch OldInterface = va_arg(args, VOID *); 605 1.1 jakllsch NewInterface = va_arg(args, VOID *); 606 1.1 jakllsch 607 1.1 jakllsch // 608 1.1 jakllsch // Reinstall it 609 1.1 jakllsch // 610 1.1 jakllsch 611 1.1 jakllsch Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface); 612 1.1 jakllsch if (EFI_ERROR(Status)) { 613 1.1 jakllsch break; 614 1.1 jakllsch } 615 1.1 jakllsch 616 1.1 jakllsch Index += 1; 617 1.1 jakllsch } 618 1.5 jmcneill va_end (args); 619 1.1 jakllsch 620 1.2 christos va_end (args); 621 1.2 christos 622 1.1 jakllsch // 623 1.1 jakllsch // If there was an error, undo all the interfaces that were 624 1.1 jakllsch // reinstalled without any errors 625 1.1 jakllsch // 626 1.1 jakllsch 627 1.1 jakllsch if (EFI_ERROR(Status)) { 628 1.1 jakllsch va_start (args, Handle); 629 1.1 jakllsch while (Index) { 630 1.1 jakllsch 631 1.1 jakllsch Protocol = va_arg(args, EFI_GUID *); 632 1.1 jakllsch OldInterface = va_arg(args, VOID *); 633 1.1 jakllsch NewInterface = va_arg(args, VOID *); 634 1.1 jakllsch 635 1.1 jakllsch uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface); 636 1.1 jakllsch 637 1.1 jakllsch Index -= 1; 638 1.5 jmcneill } 639 1.5 jmcneill va_end (args); 640 1.1 jakllsch } 641 1.1 jakllsch 642 1.1 jakllsch // 643 1.1 jakllsch // Done 644 1.1 jakllsch // 645 1.1 jakllsch 646 1.1 jakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl); 647 1.1 jakllsch return Status; 648 1.1 jakllsch } 649