Exemple #1
0
/**
  Uninstalls a list of protocol interface in the boot services environment.
  This function calls UnisatllProtocolInterface() in a loop. This is
  basically a lib function to save space.

  @param  Handle                 The handle to uninstall the protocol
  @param  ...                    EFI_GUID followed by protocol instance. A NULL
                                 terminates the  list. The pairs are the
                                 arguments to UninstallProtocolInterface(). All
                                 the protocols are added to Handle.

  @return Status code

**/
EFI_STATUS
EFIAPI
CoreUninstallMultipleProtocolInterfaces (
  IN EFI_HANDLE           Handle,
  ...
  )
{
  EFI_STATUS      Status;
  VA_LIST         Args;
  EFI_GUID        *Protocol;
  VOID            *Interface;
  UINTN           Index;

  VA_START (Args, Handle);
  for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
    //
    // If protocol is NULL, then it's the end of the list
    //
    Protocol = VA_ARG (Args, EFI_GUID *);
    if (Protocol == NULL) {
      break;
    }

    Interface = VA_ARG (Args, VOID *);

    //
    // Uninstall it
    //
    Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface);
  }
  VA_END (Args);

  //
  // If there was an error, add all the interfaces that were
  // uninstalled without any errors
  //
  if (EFI_ERROR (Status)) {
    //
    // Reset the va_arg back to the first argument.
    //
    VA_START (Args, Handle);
    for (; Index > 1; Index--) {
      Protocol = VA_ARG(Args, EFI_GUID *);
      Interface = VA_ARG(Args, VOID *);
      CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
    }
    VA_END (Args);
  }

  return Status;
}
Exemple #2
0
/**
  This notification function is invoked when an instance of the
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL is produced.  It layers an instance of the
  EFI_FIRMWARE_VOLUME2_PROTOCOL on the same handle.  This is the function where
  the actual initialization of the EFI_FIRMWARE_VOLUME2_PROTOCOL is done.

  @param  Event                 The event that occured
  @param  Context               For EFI compatiblity.  Not used.

**/
VOID
EFIAPI
NotifyFwVolBlock (
  IN  EFI_EVENT Event,
  IN  VOID      *Context
  )
{
  EFI_HANDLE                            Handle;
  EFI_STATUS                            Status;
  UINTN                                 BufferSize;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;
  EFI_FIRMWARE_VOLUME2_PROTOCOL         *Fv;
  FV_DEVICE                             *FvDevice;
  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;
  //
  // Examine all new handles
  //
  for (;;) {
    //
    // Get the next handle
    //
    BufferSize = sizeof (Handle);
    Status = CoreLocateHandle (
              ByRegisterNotify,
              NULL,
              gEfiFwVolBlockNotifyReg,
              &BufferSize,
              &Handle
              );

    //
    // If not found, we're done
    //
    if (EFI_NOT_FOUND == Status) {
      break;
    }

    if (EFI_ERROR (Status)) {
      continue;
    }

    //
    // Get the FirmwareVolumeBlock protocol on that handle
    //
    Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
    ASSERT_EFI_ERROR (Status);
    ASSERT (Fvb != NULL);

    //
    // Make sure the Fv Header is O.K.
    //
    Status = GetFwVolHeader (Fvb, &FwVolHeader);
    if (EFI_ERROR (Status)) {
      return;
    }
    ASSERT (FwVolHeader != NULL);

    if (!VerifyFvHeaderChecksum (FwVolHeader)) {
      CoreFreePool (FwVolHeader);
      continue;
    }


    //
    // Check to see that the file system is indeed formatted in a way we can
    // understand it...
    //
    if ((!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid)) &&
        (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid))) {
      continue;
    }

    //
    // Check if there is an FV protocol already installed in that handle
    //
    Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
    if (!EFI_ERROR (Status)) {
      //
      // Update Fv to use a new Fvb
      //
      FvDevice = BASE_CR (Fv, FV_DEVICE, Fv);
      if (FvDevice->Signature == FV2_DEVICE_SIGNATURE) {
        //
        // Only write into our device structure if it's our device structure
        //
        FvDevice->Fvb = Fvb;
      }

    } else {
      //
      // No FwVol protocol on the handle so create a new one
      //
      FvDevice = AllocateCopyPool (sizeof (FV_DEVICE), &mFvDevice);
      if (FvDevice == NULL) {
        return;
      }

      FvDevice->Fvb             = Fvb;
      FvDevice->Handle          = Handle;
      FvDevice->FwVolHeader     = FwVolHeader;
      FvDevice->IsFfs3Fv        = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
      FvDevice->Fv.ParentHandle = Fvb->ParentHandle;

      if (Fvb->ParentHandle != NULL) {
        //
        // Inherit the authentication status from FVB.
        //
        FvDevice->AuthenticationStatus = GetFvbAuthenticationStatus (Fvb);
      }
      
      if (!EFI_ERROR (FvCheck (FvDevice))) {
        //
        // Install an New FV protocol on the existing handle
        //
        Status = CoreInstallProtocolInterface (
                    &Handle,
                    &gEfiFirmwareVolume2ProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    &FvDevice->Fv
                    );
        ASSERT_EFI_ERROR (Status);
      } else {
        //
        // Free FvDevice Buffer for the corrupt FV image.
        //
        CoreFreePool (FvDevice);
      }
    }
  }

  return;
}
Exemple #3
0
/**
  Installs a list of protocol interface into the boot services environment.
  This function calls InstallProtocolInterface() in a loop. If any error
  occures all the protocols added by this function are removed. This is
  basically a lib function to save space.

  @param  Handle                 The pointer to a handle to install the new
                                 protocol interfaces on, or a pointer to NULL
                                 if a new handle is to be allocated.
  @param  ...                    EFI_GUID followed by protocol instance. A NULL
                                 terminates the  list. The pairs are the
                                 arguments to InstallProtocolInterface(). All the
                                 protocols are added to Handle.

  @retval EFI_SUCCESS            All the protocol interface was installed.
  @retval EFI_OUT_OF_RESOURCES   There was not enough memory in pool to install all the protocols.
  @retval EFI_ALREADY_STARTED    A Device Path Protocol instance was passed in that is already present in
                                 the handle database.
  @retval EFI_INVALID_PARAMETER  Handle is NULL.
  @retval EFI_INVALID_PARAMETER  Protocol is already installed on the handle specified by Handle.

**/
EFI_STATUS
EFIAPI
CoreInstallMultipleProtocolInterfaces (
  IN OUT EFI_HANDLE           *Handle,
  ...
  )
{
  VA_LIST                   Args;
  EFI_STATUS                Status;
  EFI_GUID                  *Protocol;
  VOID                      *Interface;
  EFI_TPL                   OldTpl;
  UINTN                     Index;
  EFI_HANDLE                OldHandle;
  EFI_HANDLE                DeviceHandle;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  if (Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Syncronize with notifcations.
  //
  OldTpl = CoreRaiseTpl (TPL_NOTIFY);
  OldHandle = *Handle;

  //
  // Check for duplicate device path and install the protocol interfaces
  //
  VA_START (Args, Handle);
  for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
    //
    // If protocol is NULL, then it's the end of the list
    //
    Protocol = VA_ARG (Args, EFI_GUID *);
    if (Protocol == NULL) {
      break;
    }

    Interface = VA_ARG (Args, VOID *);

    //
    // Make sure you are installing on top a device path that has already been added.
    //
    if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) {
      DeviceHandle = NULL;
      DevicePath   = Interface;
      Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);
      if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(DevicePath)) {
        Status = EFI_ALREADY_STARTED;
        continue;
      }
    }

    //
    // Install it
    //
    Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
  }
  VA_END (Args);

  //
  // If there was an error, remove all the interfaces that were installed without any errors
  //
  if (EFI_ERROR (Status)) {
    //
    // Reset the va_arg back to the first argument.
    //
    VA_START (Args, Handle);
    for (; Index > 1; Index--) {
      Protocol = VA_ARG (Args, EFI_GUID *);
      Interface = VA_ARG (Args, VOID *);
      CoreUninstallProtocolInterface (*Handle, Protocol, Interface);
    }
    VA_END (Args);
    
    *Handle = OldHandle;
  }

  //
  // Done
  //
  CoreRestoreTpl (OldTpl);
  return Status;
}