Example #1
0
static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file,
					  efi_uintn_t *buffer_size,
					  void *buffer)
{
	struct file_handle *fh = to_fh(file);
	efi_status_t ret = EFI_SUCCESS;
	loff_t actwrite;

	EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer);

	if (set_blk_dev(fh)) {
		ret = EFI_DEVICE_ERROR;
		goto error;
	}

	if (fs_write(fh->path, (ulong)buffer, fh->offset, *buffer_size,
		     &actwrite)) {
		ret = EFI_DEVICE_ERROR;
		goto error;
	}

	*buffer_size = actwrite;
	fh->offset += actwrite;

error:
	return EFI_EXIT(ret);
}
Example #2
0
static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file)
{
	struct file_handle *fh = to_fh(file);
	EFI_ENTRY("%p", file);
	file_close(fh);
	return EFI_EXIT(EFI_WARN_DELETE_FAILURE);
}
Example #3
0
static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *file,
					 efi_uintn_t *buffer_size, void *buffer)
{
	struct file_handle *fh = to_fh(file);
	efi_status_t ret = EFI_SUCCESS;
	u64 bs;

	EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer);

	if (!buffer_size || !buffer) {
		ret = EFI_INVALID_PARAMETER;
		goto error;
	}

	if (set_blk_dev(fh)) {
		ret = EFI_DEVICE_ERROR;
		goto error;
	}

	bs = *buffer_size;
	if (fh->isdir)
		ret = dir_read(fh, &bs, buffer);
	else
		ret = file_read(fh, &bs, buffer);
	if (bs <= SIZE_MAX)
		*buffer_size = bs;
	else
		*buffer_size = SIZE_MAX;

error:
	return EFI_EXIT(ret);
}
Example #4
0
static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file,
					   efi_uintn_t *pos)
{
	struct file_handle *fh = to_fh(file);

	EFI_ENTRY("%p, %p", file, pos);

	if (fh->offset <= SIZE_MAX) {
		*pos = fh->offset;
		return EFI_EXIT(EFI_SUCCESS);
	} else {
		return EFI_EXIT(EFI_DEVICE_ERROR);
	}
}
Example #5
0
static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file,
		struct efi_file_handle **new_handle,
		s16 *file_name, u64 open_mode, u64 attributes)
{
	struct file_handle *fh = to_fh(file);

	EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, file_name,
		  open_mode, attributes);

	*new_handle = file_open(fh->fs, fh, file_name, open_mode);
	if (!*new_handle)
		return EFI_EXIT(EFI_NOT_FOUND);

	return EFI_EXIT(EFI_SUCCESS);
}
Example #6
0
/**
 * efi_file_getpos() - get current position in file
 *
 * This function implements the GetPosition service of the EFI file protocol.
 * See the UEFI spec for details.
 *
 * @file:	file handle
 * @pos:	pointer to file position
 * Return:	status code
 */
static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file,
					   u64 *pos)
{
	efi_status_t ret = EFI_SUCCESS;
	struct file_handle *fh = to_fh(file);

	EFI_ENTRY("%p, %p", file, pos);

	if (fh->isdir) {
		ret = EFI_UNSUPPORTED;
		goto out;
	}

	*pos = fh->offset;
out:
	return EFI_EXIT(ret);
}
Example #7
0
static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file,
		struct efi_file_handle **new_handle,
		u16 *file_name, u64 open_mode, u64 attributes)
{
	struct file_handle *fh = to_fh(file);
	efi_status_t ret;

	EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle,
		  (wchar_t *)file_name, open_mode, attributes);

	/* Check parameters */
	if (!file || !new_handle || !file_name) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}
	if (open_mode != EFI_FILE_MODE_READ &&
	    open_mode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE) &&
	    open_mode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
			 EFI_FILE_MODE_CREATE)) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}
	/*
	 * The UEFI spec requires that attributes are only set in create mode.
	 * The SCT does not care about this and sets EFI_FILE_DIRECTORY in
	 * read mode. EDK2 does not check that attributes are zero if not in
	 * create mode.
	 *
	 * So here we only check attributes in create mode and do not check
	 * that they are zero otherwise.
	 */
	if ((open_mode & EFI_FILE_MODE_CREATE) &&
	    (attributes & (EFI_FILE_READ_ONLY | ~EFI_FILE_VALID_ATTR))) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	/* Open file */
	*new_handle = file_open(fh->fs, fh, file_name, open_mode, attributes);
	if (*new_handle)
		ret = EFI_SUCCESS;
	else
		ret = EFI_NOT_FOUND;
out:
	return EFI_EXIT(ret);
}
Example #8
0
static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file)
{
	struct file_handle *fh = to_fh(file);
	efi_status_t ret = EFI_SUCCESS;

	EFI_ENTRY("%p", file);

	if (set_blk_dev(fh)) {
		ret = EFI_DEVICE_ERROR;
		goto error;
	}

	if (fs_unlink(fh->path))
		ret = EFI_DEVICE_ERROR;
	file_close(fh);

error:
	return EFI_EXIT(ret);
}
Example #9
0
static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file,
		efi_uintn_t pos)
{
	struct file_handle *fh = to_fh(file);
	efi_status_t ret = EFI_SUCCESS;

	EFI_ENTRY("%p, %zu", file, pos);

	if (fh->isdir) {
		if (pos != 0) {
			ret = EFI_UNSUPPORTED;
			goto error;
		}
		fs_closedir(fh->dirs);
		fh->dirs = NULL;
	}

	if (pos == ~0ULL) {
		loff_t file_size;

		if (set_blk_dev(fh)) {
			ret = EFI_DEVICE_ERROR;
			goto error;
		}

		if (fs_size(fh->path, &file_size)) {
			ret = EFI_DEVICE_ERROR;
			goto error;
		}

		pos = file_size;
	}

	fh->offset = pos;

error:
	return EFI_EXIT(ret);
}
Example #10
0
static efi_status_t EFIAPI efi_file_getinfo(struct efi_file_handle *file,
					    const efi_guid_t *info_type,
					    efi_uintn_t *buffer_size,
					    void *buffer)
{
	struct file_handle *fh = to_fh(file);
	efi_status_t ret = EFI_SUCCESS;

	EFI_ENTRY("%p, %p, %p, %p", file, info_type, buffer_size, buffer);

	if (!guidcmp(info_type, &efi_file_info_guid)) {
		struct efi_file_info *info = buffer;
		char *filename = basename(fh);
		unsigned int required_size;
		loff_t file_size;

		/* check buffer size: */
		required_size = sizeof(*info) + 2 * (strlen(filename) + 1);
		if (*buffer_size < required_size) {
			*buffer_size = required_size;
			ret = EFI_BUFFER_TOO_SMALL;
			goto error;
		}

		if (set_blk_dev(fh)) {
			ret = EFI_DEVICE_ERROR;
			goto error;
		}

		if (fs_size(fh->path, &file_size)) {
			ret = EFI_DEVICE_ERROR;
			goto error;
		}

		memset(info, 0, required_size);

		info->size = required_size;
		info->file_size = file_size;
		info->physical_size = file_size;

		if (fh->isdir)
			info->attribute |= EFI_FILE_DIRECTORY;

		ascii2unicode((u16 *)info->file_name, filename);
	} else if (!guidcmp(info_type, &efi_file_system_info_guid)) {
		struct efi_file_system_info *info = buffer;
		disk_partition_t part;
		efi_uintn_t required_size;
		int r;

		if (fh->fs->part >= 1)
			r = part_get_info(fh->fs->desc, fh->fs->part, &part);
		else
			r = part_get_info_whole_disk(fh->fs->desc, &part);
		if (r < 0) {
			ret = EFI_DEVICE_ERROR;
			goto error;
		}
		required_size = sizeof(info) + 2 *
				(strlen((const char *)part.name) + 1);
		if (*buffer_size < required_size) {
			*buffer_size = required_size;
			ret = EFI_BUFFER_TOO_SMALL;
			goto error;
		}

		memset(info, 0, required_size);

		info->size = required_size;
		info->read_only = true;
		info->volume_size = part.size * part.blksz;
		info->free_space = 0;
		info->block_size = part.blksz;
		/*
		 * TODO: The volume label is not available in U-Boot.
		 * Use the partition name as substitute.
		 */
		ascii2unicode((u16 *)info->volume_label,
			      (const char *)part.name);
	} else {
		ret = EFI_UNSUPPORTED;
	}

error:
	return EFI_EXIT(ret);
}
Example #11
0
static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file)
{
	struct file_handle *fh = to_fh(file);
	EFI_ENTRY("%p", file);
	return EFI_EXIT(file_close(fh));
}