Exemplo n.º 1
0
/**
  Attempt to download the boot file through HTTP message exchange.

  @param[in]          Private         The pointer to the driver's private data.
  @param[in, out]     BufferSize      On input the size of Buffer in bytes. On output with a return
                                      code of EFI_SUCCESS, the amount of data transferred to
                                      Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
                                      the size of Buffer required to retrieve the requested file.
  @param[in]          Buffer          The memory buffer to transfer the file to. If Buffer is NULL,
                                      then the size of the requested file is returned in
                                      BufferSize.
  @param[out]         ImageType       The image type of the downloaded file.

  @retval EFI_SUCCESS                 Boot file was loaded successfully.
  @retval EFI_INVALID_PARAMETER       Private is NULL, or ImageType is NULL, or BufferSize is NULL.
  @retval EFI_INVALID_PARAMETER       *BufferSize is not zero, and Buffer is NULL.
  @retval EFI_NOT_STARTED             The driver is in stopped state.
  @retval EFI_BUFFER_TOO_SMALL        The BufferSize is too small to read the boot file. BufferSize has 
                                      been updated with the size needed to complete the request.
  @retval EFI_DEVICE_ERROR            An unexpected network error occurred.
  @retval Others                      Other errors as indicated.
  
**/
EFI_STATUS
HttpBootLoadFile (
  IN     HTTP_BOOT_PRIVATE_DATA       *Private,
  IN OUT UINTN                        *BufferSize,
  IN     VOID                         *Buffer,       OPTIONAL
     OUT HTTP_BOOT_IMAGE_TYPE         *ImageType
  )
{
  EFI_STATUS             Status;

  if (Private == NULL || ImageType == NULL || BufferSize == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  if (*BufferSize != 0 && Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  if (!Private->Started) {
    return EFI_NOT_STARTED;
  }

  Status = EFI_DEVICE_ERROR;

  if (Private->BootFileUri == NULL) {
    //
    // Parse the cached offer to get the boot file URL first.
    //
    Status = HttpBootDiscoverBootInfo (Private);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (!Private->HttpCreated) {
    //
    // Create HTTP child.
    //
    Status = HttpBootCreateHttpIo (Private);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (Private->BootFileSize == 0) {
    //
    // Discover the information about the bootfile if we haven't.
    //

    //
    // Try to use HTTP HEAD method.
    //
    Status = HttpBootGetBootFile (
               Private,
               TRUE,
               &Private->BootFileSize,
               NULL,
               &Private->ImageType
               );
    if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
      //
      // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
      //
      ASSERT (Private->BootFileSize == 0);
      Status = HttpBootGetBootFile (
                 Private,
                 FALSE,
                 &Private->BootFileSize,
                 NULL,
                 &Private->ImageType
                 );
      if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
        return Status;
      }
    }
  }

  if (*BufferSize < Private->BootFileSize) {
    *BufferSize = Private->BootFileSize;
    *ImageType = Private->ImageType;
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Load the boot file into Buffer
  //
  return  HttpBootGetBootFile (
            Private,
            FALSE,
            BufferSize,
            Buffer,
            ImageType
            );
}
Exemplo n.º 2
0
/**
  Attempt to download the boot file through HTTP message exchange.

  @param[in]          Private         The pointer to the driver's private data.
  @param[in, out]     BufferSize      On input the size of Buffer in bytes. On output with a return
                                      code of EFI_SUCCESS, the amount of data transferred to
                                      Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
                                      the size of Buffer required to retrieve the requested file.
  @param[in]          Buffer          The memory buffer to transfer the file to. If Buffer is NULL,
                                      then the size of the requested file is returned in
                                      BufferSize.
  @param[out]         ImageType       The image type of the downloaded file.

  @retval EFI_SUCCESS                 Boot file was loaded successfully.
  @retval EFI_INVALID_PARAMETER       Private is NULL, or ImageType is NULL, or BufferSize is NULL.
  @retval EFI_INVALID_PARAMETER       *BufferSize is not zero, and Buffer is NULL.
  @retval EFI_NOT_STARTED             The driver is in stopped state.
  @retval EFI_BUFFER_TOO_SMALL        The BufferSize is too small to read the boot file. BufferSize has
                                      been updated with the size needed to complete the request.
  @retval EFI_DEVICE_ERROR            An unexpected network error occurred.
  @retval Others                      Other errors as indicated.

**/
EFI_STATUS
HttpBootLoadFile (
  IN     HTTP_BOOT_PRIVATE_DATA       *Private,
  IN OUT UINTN                        *BufferSize,
  IN     VOID                         *Buffer,       OPTIONAL
     OUT HTTP_BOOT_IMAGE_TYPE         *ImageType
  )
{
  EFI_STATUS             Status;

  if (Private == NULL || ImageType == NULL || BufferSize == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  if (*BufferSize != 0 && Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!Private->Started) {
    return EFI_NOT_STARTED;
  }

  Status = HttpBootInstallCallback (Private);
  if (EFI_ERROR(Status)) {
    goto ON_EXIT;
  }

  if (Private->BootFileUri == NULL) {
    //
    // Parse the cached offer to get the boot file URL first.
    //
    Status = HttpBootDiscoverBootInfo (Private);
    if (EFI_ERROR (Status)) {
      AsciiPrint ("\n  Error: Could not retrieve NBP file size from HTTP server.\n");
      goto ON_EXIT;
    }
  }

  if (!Private->HttpCreated) {
    //
    // Create HTTP child.
    //
    Status = HttpBootCreateHttpIo (Private);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  if (Private->BootFileSize == 0) {
    //
    // Discover the information about the bootfile if we haven't.
    //

    //
    // Try to use HTTP HEAD method.
    //
    Status = HttpBootGetBootFile (
               Private,
               TRUE,
               &Private->BootFileSize,
               NULL,
               &Private->ImageType
               );
    if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
      //
      // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
      //
      ASSERT (Private->BootFileSize == 0);
      Status = HttpBootGetBootFile (
                 Private,
                 FALSE,
                 &Private->BootFileSize,
                 NULL,
                 &Private->ImageType
                 );
      if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
        AsciiPrint ("\n  Error: Could not retrieve NBP file size from HTTP server.\n");
        goto ON_EXIT;
      }
    }
  }

  if (*BufferSize < Private->BootFileSize) {
    *BufferSize = Private->BootFileSize;
    *ImageType = Private->ImageType;
    Status = EFI_BUFFER_TOO_SMALL;
    goto ON_EXIT;
  }

  //
  // Load the boot file into Buffer
  //
  Status = HttpBootGetBootFile (
             Private,
             FALSE,
             BufferSize,
             Buffer,
             ImageType
             );

ON_EXIT:
  HttpBootUninstallCallback (Private);

  if (EFI_ERROR (Status)) {
    if (Status == EFI_ACCESS_DENIED) {
      AsciiPrint ("\n  Error: Could not establish connection with HTTP server.\n");
    } else if (Status == EFI_BUFFER_TOO_SMALL && Buffer != NULL) {
      AsciiPrint ("\n  Error: Buffer size is smaller than the requested file.\n");
    } else if (Status == EFI_OUT_OF_RESOURCES) {
      AsciiPrint ("\n  Error: Could not allocate I/O buffers.\n");
    } else if (Status == EFI_DEVICE_ERROR) {
      AsciiPrint ("\n  Error: Network device error.\n");
    } else if (Status == EFI_TIMEOUT) {
      AsciiPrint ("\n  Error: Server response timeout.\n");
    } else if (Status == EFI_ABORTED) {
      AsciiPrint ("\n  Error: Remote boot cancelled.\n");
    } else if (Status != EFI_BUFFER_TOO_SMALL) {
      AsciiPrint ("\n  Error: Unexpected network error.\n");
    }
  }

  return Status;
}