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