/** 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 ); }
/** 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; }