From 43f92ce30b2398d1823e34e39ff248de521d015c Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 14 Dec 2016 20:49:55 -0800 Subject: [PATCH] resource: pass blob and offset to consume_chunk This makes it so that users don't need to keep track of the current blob and offset themselves. --- include/wimlib/apply.h | 2 - include/wimlib/ntfs_3g.h | 4 +- include/wimlib/resource.h | 31 +++++-- include/wimlib/win32.h | 4 +- src/extract.c | 33 ++++---- src/ntfs-3g_apply.c | 14 ++-- src/ntfs-3g_capture.c | 4 +- src/resource.c | 169 ++++++++++++++++++++++++-------------- src/unix_apply.c | 5 +- src/verify.c | 21 +---- src/win32_apply.c | 20 ++--- src/win32_capture.c | 18 ++-- src/write.c | 22 ++--- 13 files changed, 189 insertions(+), 158 deletions(-) diff --git a/include/wimlib/apply.h b/include/wimlib/apply.h index f77f9e95..da9087a7 100644 --- a/include/wimlib/apply.h +++ b/include/wimlib/apply.h @@ -72,8 +72,6 @@ struct apply_ctx { unsigned long num_blobs_remaining; struct list_head blob_list; const struct read_blob_callbacks *saved_cbs; - struct blob_descriptor *cur_blob; - u64 cur_blob_offset; struct filedes tmpfile_fd; tchar *tmpfile_name; unsigned int count_until_file_progress; diff --git a/include/wimlib/ntfs_3g.h b/include/wimlib/ntfs_3g.h index 0328348f..7909e43e 100644 --- a/include/wimlib/ntfs_3g.h +++ b/include/wimlib/ntfs_3g.h @@ -6,12 +6,12 @@ #include "wimlib/types.h" struct blob_descriptor; +struct consume_chunk_callback; struct ntfs_location; -struct read_blob_callbacks; extern int read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs); + const struct consume_chunk_callback *cb); extern struct ntfs_location * clone_ntfs_location(const struct ntfs_location *loc); diff --git a/include/wimlib/resource.h b/include/wimlib/resource.h index 2fea2f57..05ceed70 100644 --- a/include/wimlib/resource.h +++ b/include/wimlib/resource.h @@ -192,6 +192,25 @@ wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim, extern int skip_wim_resource(const struct wim_resource_descriptor *rdesc); +/* + * Callback function for reading chunks. Called whenever the next chunk of + * uncompressed data is available, passing 'ctx' as the last argument. 'size' is + * guaranteed to be nonzero. Must return 0 on success, or a positive wimlib + * error code on failure. + */ +struct consume_chunk_callback { + int (*func)(const void *chunk, size_t size, void *ctx); + void *ctx; +}; + +/* Pass a chunk of data to the specified consume_chunk callback */ +static inline int +consume_chunk(const struct consume_chunk_callback *cb, + const void *chunk, size_t size) +{ + return (*cb->func)(chunk, size, cb->ctx); +} + /* Callback functions for reading blobs */ struct read_blob_callbacks { @@ -205,7 +224,8 @@ struct read_blob_callbacks { /* Called when the next chunk of uncompressed data is available. 'size' * is guaranteed to be nonzero. Must return 0 on success, or a positive * wimlib error code on failure. */ - int (*consume_chunk)(const void *chunk, size_t size, void *ctx); + int (*continue_blob)(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *ctx); /* Called when a blob has been successfully read (status=0), or when * begin_blob() was successfully called but an error occurred before the @@ -228,14 +248,15 @@ call_begin_blob(struct blob_descriptor *blob, return (*cbs->begin_blob)(blob, cbs->ctx); } -/* Call cbs->consume_chunk() if present. */ +/* Call cbs->continue_blob() if present. */ static inline int -call_consume_chunk(const void *chunk, size_t size, +call_continue_blob(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, const struct read_blob_callbacks *cbs) { - if (!cbs->consume_chunk) + if (!cbs->continue_blob) return 0; - return (*cbs->consume_chunk)(chunk, size, cbs->ctx); + return (*cbs->continue_blob)(blob, offset, chunk, size, cbs->ctx); } /* Call cbs->end_blob() if present. */ diff --git a/include/wimlib/win32.h b/include/wimlib/win32.h index f0f99cc7..94511a87 100644 --- a/include/wimlib/win32.h +++ b/include/wimlib/win32.h @@ -10,7 +10,7 @@ #include "wimlib/types.h" struct blob_descriptor; -struct read_blob_callbacks; +struct consume_chunk_callback; struct windows_file; extern struct windows_file * @@ -25,7 +25,7 @@ cmp_windows_files(const struct windows_file *file1, extern int read_windows_file_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs); + const struct consume_chunk_callback *cb); extern int win32_global_init(int init_flags); diff --git a/src/extract.c b/src/extract.c index 01bc1a5b..d3df861f 100644 --- a/src/extract.c +++ b/src/extract.c @@ -356,13 +356,10 @@ retry: } static int -begin_extract_blob_wrapper(struct blob_descriptor *blob, void *_ctx) +begin_extract_blob(struct blob_descriptor *blob, void *_ctx) { struct apply_ctx *ctx = _ctx; - ctx->cur_blob = blob; - ctx->cur_blob_offset = 0; - if (unlikely(blob->out_refcnt > MAX_OPEN_FILES)) return create_temporary_file(&ctx->tmpfile_fd, &ctx->tmpfile_name); @@ -370,29 +367,29 @@ begin_extract_blob_wrapper(struct blob_descriptor *blob, void *_ctx) } static int -extract_chunk_wrapper(const void *chunk, size_t size, void *_ctx) +extract_chunk(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_ctx) { struct apply_ctx *ctx = _ctx; union wimlib_progress_info *progress = &ctx->progress; + bool last = (offset + size == blob->size); int ret; - ctx->cur_blob_offset += size; - if (likely(ctx->supported_features.hard_links)) { progress->extract.completed_bytes += - (u64)size * ctx->cur_blob->out_refcnt; - if (ctx->cur_blob_offset == ctx->cur_blob->size) - progress->extract.completed_streams += ctx->cur_blob->out_refcnt; + (u64)size * blob->out_refcnt; + if (last) + progress->extract.completed_streams += blob->out_refcnt; } else { const struct blob_extraction_target *targets = - blob_extraction_targets(ctx->cur_blob); - for (u32 i = 0; i < ctx->cur_blob->out_refcnt; i++) { + blob_extraction_targets(blob); + for (u32 i = 0; i < blob->out_refcnt; i++) { const struct wim_inode *inode = targets[i].inode; const struct wim_dentry *dentry; inode_for_each_extraction_alias(dentry, inode) { progress->extract.completed_bytes += size; - if (ctx->cur_blob_offset == ctx->cur_blob->size) + if (last) progress->extract.completed_streams++; } } @@ -419,7 +416,7 @@ extract_chunk_wrapper(const void *chunk, size_t size, void *_ctx) return ret; } - return call_consume_chunk(chunk, size, ctx->saved_cbs); + return call_continue_blob(blob, offset, chunk, size, ctx->saved_cbs); } /* Copy the blob's data from the temporary file to each of its targets. @@ -450,7 +447,7 @@ extract_from_tmpfile(const tchar *tmpfile_name, } static int -end_extract_blob_wrapper(struct blob_descriptor *blob, int status, void *_ctx) +end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx) { struct apply_ctx *ctx = _ctx; @@ -489,9 +486,9 @@ int extract_blob_list(struct apply_ctx *ctx, const struct read_blob_callbacks *cbs) { struct read_blob_callbacks wrapper_cbs = { - .begin_blob = begin_extract_blob_wrapper, - .consume_chunk = extract_chunk_wrapper, - .end_blob = end_extract_blob_wrapper, + .begin_blob = begin_extract_blob, + .continue_blob = extract_chunk, + .end_blob = end_extract_blob, .ctx = ctx, }; ctx->saved_cbs = cbs; diff --git a/src/ntfs-3g_apply.c b/src/ntfs-3g_apply.c index 3697b333..27b0ab90 100644 --- a/src/ntfs-3g_apply.c +++ b/src/ntfs-3g_apply.c @@ -87,9 +87,6 @@ struct ntfs_3g_apply_ctx { struct reparse_buffer_disk rpbuf; u8 *reparse_ptr; - /* Offset in the blob currently being read */ - u64 offset; - unsigned num_reparse_inodes; ntfs_inode *ntfs_reparse_inodes[MAX_OPEN_FILES]; struct wim_inode *wim_reparse_inodes[MAX_OPEN_FILES]; @@ -756,7 +753,6 @@ ntfs_3g_cleanup_blob_extract(struct ntfs_3g_apply_ctx *ctx) } ctx->num_open_inodes = 0; - ctx->offset = 0; ctx->reparse_ptr = NULL; ctx->num_reparse_inodes = 0; return ret; @@ -842,13 +838,14 @@ ntfs_3g_full_pwrite(ntfs_attr *na, u64 offset, size_t size, const u8 *data) } static int -ntfs_3g_extract_chunk(const void *chunk, size_t size, void *_ctx) +ntfs_3g_extract_chunk(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_ctx) { struct ntfs_3g_apply_ctx *ctx = _ctx; for (unsigned i = 0; i < ctx->num_open_attrs; i++) { - if (!ntfs_3g_full_pwrite(ctx->open_attrs[i], - ctx->offset, size, chunk)) + if (!ntfs_3g_full_pwrite(ctx->open_attrs[i], offset, + size, chunk)) { ERROR_WITH_ERRNO("Error writing data to NTFS volume"); return WIMLIB_ERR_NTFS_3G; @@ -856,7 +853,6 @@ ntfs_3g_extract_chunk(const void *chunk, size_t size, void *_ctx) } if (ctx->reparse_ptr) ctx->reparse_ptr = mempcpy(ctx->reparse_ptr, chunk, size); - ctx->offset += size; return 0; } @@ -960,7 +956,7 @@ ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) /* Extract blobs. */ struct read_blob_callbacks cbs = { .begin_blob = ntfs_3g_begin_extract_blob, - .consume_chunk = ntfs_3g_extract_chunk, + .continue_blob = ntfs_3g_extract_chunk, .end_blob = ntfs_3g_end_extract_blob, .ctx = ctx, }; diff --git a/src/ntfs-3g_capture.c b/src/ntfs-3g_capture.c index b496e02a..ca8d1b2f 100644 --- a/src/ntfs-3g_capture.c +++ b/src/ntfs-3g_capture.c @@ -117,7 +117,7 @@ open_ntfs_attr(ntfs_inode *ni, const struct ntfs_location *loc) int read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { const struct ntfs_location *loc = blob->ntfs_loc; ntfs_volume *vol = loc->volume->vol; @@ -154,7 +154,7 @@ read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size, } pos += to_read; bytes_remaining -= to_read; - ret = call_consume_chunk(buf, to_read, cbs); + ret = consume_chunk(cb, buf, to_read); if (ret) goto out_close_ntfs_attr; } diff --git a/src/resource.c b/src/resource.c index 385f9f65..9f119c47 100644 --- a/src/resource.c +++ b/src/resource.c @@ -93,11 +93,11 @@ struct data_range { * read, sorted by increasing offset. * @num_ranges * Number of ranges in @ranges; must be at least 1. - * @cbs - * Structure which provides the consume_chunk() callback to feed the data - * being read. Each call provides the next chunk of the requested data, - * uncompressed. Each chunk will be nonempty and will not cross range - * boundaries but otherwise will be of unspecified size. + * @cb + * Structure which provides the consume_chunk callback into which to feed + * the data being read. Each call provides the next chunk of the requested + * data, uncompressed. Each chunk will be nonempty and will not cross + * range boundaries but otherwise will be of unspecified size. * * Possible return values: * @@ -108,13 +108,13 @@ struct data_range { * WIMLIB_ERR_DECOMPRESSION (errno set to EINVAL) * WIMLIB_ERR_INVALID_CHUNK_SIZE (errno set to EINVAL) * - * or other error code returned by the cbs->consume_chunk() function. + * or other error code returned by the callback function. */ static int read_compressed_wim_resource(const struct wim_resource_descriptor * const rdesc, const struct data_range * const ranges, const size_t num_ranges, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { int ret; u64 *chunk_offsets = NULL; @@ -473,7 +473,7 @@ read_compressed_wim_resource(const struct wim_resource_descriptor * const rdesc, end = min(cur_range_end, chunk_end_offset) - chunk_start_offset; size = end - start; - ret = call_consume_chunk(&ubuf[start], size, cbs); + ret = consume_chunk(cb, &ubuf[start], size); if (unlikely(ret)) goto out_cleanup; @@ -533,10 +533,10 @@ read_error: } /* Read raw data from a file descriptor at the specified offset, feeding the - * data in nonempty chunks into the cbs->consume_chunk() function. */ + * data in nonempty chunks into the specified callback function. */ static int read_raw_file_data(struct filedes *in_fd, u64 offset, u64 size, - const struct read_blob_callbacks *cbs, + const struct consume_chunk_callback *cb, const tchar *filename) { u8 buf[BUFFER_SIZE]; @@ -548,7 +548,7 @@ read_raw_file_data(struct filedes *in_fd, u64 offset, u64 size, ret = full_pread(in_fd, buf, bytes_to_read, offset); if (unlikely(ret)) goto read_error; - ret = call_consume_chunk(buf, bytes_to_read, cbs); + ret = consume_chunk(cb, buf, bytes_to_read); if (unlikely(ret)) return ret; size -= bytes_to_read; @@ -568,7 +568,7 @@ read_error: return ret; } -/* A consume_chunk() implementation that simply concatenates all chunks into an +/* A consume_chunk implementation which simply concatenates all chunks into an * in-memory buffer. */ static int bufferer_cb(const void *chunk, size_t size, void *_ctx) @@ -581,7 +581,7 @@ bufferer_cb(const void *chunk, size_t size, void *_ctx) /* * Read @size bytes at @offset in the WIM resource described by @rdesc and feed - * the data into the @cbs->consume_chunk callback function. + * the data into the @cb callback function. * * @offset and @size are assumed to have already been validated against the * resource's uncompressed size. @@ -592,7 +592,7 @@ bufferer_cb(const void *chunk, size_t size, void *_ctx) static int read_partial_wim_resource(const struct wim_resource_descriptor *rdesc, const u64 offset, const u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { if (rdesc->flags & (WIM_RESHDR_FLAG_COMPRESSED | WIM_RESHDR_FLAG_SOLID)) @@ -604,13 +604,13 @@ read_partial_wim_resource(const struct wim_resource_descriptor *rdesc, .offset = offset, .size = size, }; - return read_compressed_wim_resource(rdesc, &range, 1, cbs); + return read_compressed_wim_resource(rdesc, &range, 1, cb); } /* Uncompressed resource */ return read_raw_file_data(&rdesc->wim->in_fd, rdesc->offset_in_wim + offset, - size, cbs, NULL); + size, cb, NULL); } /* Read the specified range of uncompressed data from the specified blob, which @@ -619,32 +619,39 @@ int read_partial_wim_blob_into_buf(const struct blob_descriptor *blob, u64 offset, size_t size, void *buf) { - struct read_blob_callbacks cbs = { - .consume_chunk = bufferer_cb, - .ctx = &buf, + struct consume_chunk_callback cb = { + .func = bufferer_cb, + .ctx = &buf, }; return read_partial_wim_resource(blob->rdesc, blob->offset_in_res + offset, size, - &cbs); + &cb); +} + +static int +noop_cb(const void *chunk, size_t size, void *_ctx) +{ + return 0; } /* Skip over the data of the specified WIM resource. */ int skip_wim_resource(const struct wim_resource_descriptor *rdesc) { - struct read_blob_callbacks cbs = { + struct consume_chunk_callback cb = { + .func = noop_cb, }; return read_partial_wim_resource(rdesc, 0, - rdesc->uncompressed_size, &cbs); + rdesc->uncompressed_size, &cb); } static int read_wim_blob_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { return read_partial_wim_resource(blob->rdesc, blob->offset_in_res, - size, cbs); + size, cb); } /* This function handles reading blob data that is located in an external file, @@ -657,7 +664,7 @@ read_wim_blob_prefix(const struct blob_descriptor *blob, u64 size, * encrypted), so Windows uses its own code for its equivalent case. */ static int read_file_on_disk_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { int ret; int raw_fd; @@ -669,7 +676,7 @@ read_file_on_disk_prefix(const struct blob_descriptor *blob, u64 size, return WIMLIB_ERR_OPEN; } filedes_init(&fd, raw_fd); - ret = read_raw_file_data(&fd, 0, size, cbs, blob->file_on_disk); + ret = read_raw_file_data(&fd, 0, size, cb, blob->file_on_disk); filedes_close(&fd); return ret; } @@ -677,7 +684,7 @@ read_file_on_disk_prefix(const struct blob_descriptor *blob, u64 size, #ifdef WITH_FUSE static int read_staging_file_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { int raw_fd; struct filedes fd; @@ -691,7 +698,7 @@ read_staging_file_prefix(const struct blob_descriptor *blob, u64 size, return WIMLIB_ERR_OPEN; } filedes_init(&fd, raw_fd); - ret = read_raw_file_data(&fd, 0, size, cbs, blob->staging_file_name); + ret = read_raw_file_data(&fd, 0, size, cb, blob->staging_file_name); filedes_close(&fd); return ret; } @@ -701,32 +708,31 @@ read_staging_file_prefix(const struct blob_descriptor *blob, u64 size, * already located in an in-memory buffer. */ static int read_buffer_prefix(const struct blob_descriptor *blob, - u64 size, const struct read_blob_callbacks *cbs) + u64 size, const struct consume_chunk_callback *cb) { if (unlikely(!size)) return 0; - return call_consume_chunk(blob->attached_buffer, size, cbs); + return consume_chunk(cb, blob->attached_buffer, size); } typedef int (*read_blob_prefix_handler_t)(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs); + const struct consume_chunk_callback *cb); /* * Read the first @size bytes from a generic "blob", which may be located in any * one of several locations, such as in a WIM resource (possibly compressed), in * an external file, or directly in an in-memory buffer. The blob data will be - * fed to the cbs->consume_chunk() callback function in chunks that are nonempty - * but otherwise are of unspecified size. + * fed to @cb in chunks that are nonempty but otherwise are of unspecified size. * * Returns 0 on success; nonzero on error. A nonzero value will be returned if * the blob data cannot be successfully read (for a number of different reasons, - * depending on the blob location), or if cbs->consume_chunk() returned nonzero - * in which case that error code will be returned. + * depending on the blob location), or if @cb returned nonzero in which case + * that error code will be returned. */ static int read_blob_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { static const read_blob_prefix_handler_t handlers[] = { [BLOB_IN_WIM] = read_wim_blob_prefix, @@ -745,7 +751,24 @@ read_blob_prefix(const struct blob_descriptor *blob, u64 size, wimlib_assert(blob->blob_location < ARRAY_LEN(handlers) && handlers[blob->blob_location] != NULL); wimlib_assert(size <= blob->size); - return handlers[blob->blob_location](blob, size, cbs); + return handlers[blob->blob_location](blob, size, cb); +} + +struct blob_chunk_ctx { + const struct blob_descriptor *blob; + const struct read_blob_callbacks *cbs; + u64 offset; +}; + +static int +consume_blob_chunk(const void *chunk, size_t size, void *_ctx) +{ + struct blob_chunk_ctx *ctx = _ctx; + int ret; + + ret = call_continue_blob(ctx->blob, ctx->offset, chunk, size, ctx->cbs); + ctx->offset += size; + return ret; } /* Read the full data of the specified blob, passing the data into the specified @@ -755,12 +778,21 @@ read_blob_with_cbs(struct blob_descriptor *blob, const struct read_blob_callbacks *cbs) { int ret; + struct blob_chunk_ctx ctx = { + .blob = blob, + .offset = 0, + .cbs = cbs, + }; + struct consume_chunk_callback cb = { + .func = consume_blob_chunk, + .ctx = &ctx, + }; ret = call_begin_blob(blob, cbs); if (unlikely(ret)) return ret; - ret = read_blob_prefix(blob, blob->size, cbs); + ret = read_blob_prefix(blob, blob->size, &cb); return call_end_blob(blob, ret, cbs); } @@ -771,11 +803,11 @@ read_blob_with_cbs(struct blob_descriptor *blob, int read_blob_into_buf(const struct blob_descriptor *blob, void *buf) { - struct read_blob_callbacks cbs = { - .consume_chunk = bufferer_cb, - .ctx = &buf, + struct consume_chunk_callback cb = { + .func = bufferer_cb, + .ctx = &buf, }; - return read_blob_prefix(blob, blob->size, &cbs); + return read_blob_prefix(blob, blob->size, &cb); } /* Retrieve the full uncompressed data of the specified blob. A buffer large @@ -861,9 +893,10 @@ next_blob(struct blob_descriptor *blob, size_t list_head_offset) return (struct blob_descriptor*)((u8*)cur->next - list_head_offset); } -/* A consume_chunk() implementation that translates raw resource data into - * blobs, calling the begin_blob, consume_chunk, and end_blob callbacks as - * appropriate. */ +/* + * A consume_chunk implementation that translates raw resource data into blobs, + * calling the begin_blob, continue_blob, and end_blob callbacks as appropriate. + */ static int blobifier_cb(const void *chunk, size_t size, void *_ctx) { @@ -880,9 +913,9 @@ blobifier_cb(const void *chunk, size_t size, void *_ctx) return ret; } + ret = call_continue_blob(ctx->cur_blob, ctx->cur_blob_offset, + chunk, size, &ctx->cbs); ctx->cur_blob_offset += size; - - ret = call_consume_chunk(chunk, size, &ctx->cbs); if (ret) return ret; @@ -926,18 +959,21 @@ hasher_begin_blob(struct blob_descriptor *blob, void *_ctx) return call_begin_blob(blob, &ctx->cbs); } -/* A consume_chunk() implementation that continues calculating the SHA-1 message +/* + * A continue_blob() implementation that continues calculating the SHA-1 message * digest of the blob being read, then optionally passes the data on to another - * consume_chunk() implementation. This allows checking the SHA-1 message - * digest of a blob being extracted, for example. */ + * continue_blob() implementation. This allows checking the SHA-1 message + * digest of a blob being extracted, for example. + */ static int -hasher_consume_chunk(const void *chunk, size_t size, void *_ctx) +hasher_continue_blob(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_ctx) { struct hasher_context *ctx = _ctx; sha1_update(&ctx->sha_ctx, chunk, size); - return call_consume_chunk(chunk, size, &ctx->cbs); + return call_continue_blob(blob, offset, chunk, size, &ctx->cbs); } static int @@ -1043,7 +1079,7 @@ read_blob_with_sha1(struct blob_descriptor *blob, }; struct read_blob_callbacks hasher_cbs = { .begin_blob = hasher_begin_blob, - .consume_chunk = hasher_consume_chunk, + .continue_blob = hasher_continue_blob, .end_blob = hasher_end_blob, .ctx = &hasher_ctx, }; @@ -1099,13 +1135,13 @@ read_blobs_in_solid_resource(struct blob_descriptor *first_blob, .final_blob = last_blob, .list_head_offset = list_head_offset, }; - struct read_blob_callbacks cbs = { - .consume_chunk = blobifier_cb, - .ctx = &blobifier_ctx, + struct consume_chunk_callback cb = { + .func = blobifier_cb, + .ctx = &blobifier_ctx, }; ret = read_compressed_wim_resource(first_blob->rdesc, ranges, - blob_count, &cbs); + blob_count, &cb); if (ranges_malloced) FREE(ranges); @@ -1185,7 +1221,7 @@ read_blob_list(struct list_head *blob_list, size_t list_head_offset, sink_cbs = alloca(sizeof(*sink_cbs)); *sink_cbs = (struct read_blob_callbacks) { .begin_blob = hasher_begin_blob, - .consume_chunk = hasher_consume_chunk, + .continue_blob = hasher_continue_blob, .end_blob = hasher_end_blob, .ctx = hasher_ctx, }; @@ -1261,17 +1297,24 @@ extract_chunk_to_fd(const void *chunk, size_t size, void *_fd) return ret; } +static int +extract_blob_chunk_to_fd(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_fd) +{ + return extract_chunk_to_fd(chunk, size, _fd); +} + /* Extract the first @size bytes of the specified blob to the specified file * descriptor. This does *not* check the SHA-1 message digest. */ int extract_blob_prefix_to_fd(struct blob_descriptor *blob, u64 size, struct filedes *fd) { - struct read_blob_callbacks cbs = { - .consume_chunk = extract_chunk_to_fd, - .ctx = fd, + struct consume_chunk_callback cb = { + .func = extract_chunk_to_fd, + .ctx = fd, }; - return read_blob_prefix(blob, size, &cbs); + return read_blob_prefix(blob, size, &cb); } /* Extract the full uncompressed contents of the specified blob to the specified @@ -1280,7 +1323,7 @@ int extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd) { struct read_blob_callbacks cbs = { - .consume_chunk = extract_chunk_to_fd, + .continue_blob = extract_blob_chunk_to_fd, .ctx = fd, }; return read_blob_with_sha1(blob, &cbs); diff --git a/src/unix_apply.c b/src/unix_apply.c index 3746f504..672f39e7 100644 --- a/src/unix_apply.c +++ b/src/unix_apply.c @@ -611,7 +611,8 @@ unix_begin_extract_blob(struct blob_descriptor *blob, void *_ctx) /* Called when the next chunk of a blob has been read for extraction */ static int -unix_extract_chunk(const void *chunk, size_t size, void *_ctx) +unix_extract_chunk(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_ctx) { struct unix_apply_ctx *ctx = _ctx; int ret; @@ -765,7 +766,7 @@ unix_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) struct read_blob_callbacks cbs = { .begin_blob = unix_begin_extract_blob, - .consume_chunk = unix_extract_chunk, + .continue_blob = unix_extract_chunk, .end_blob = unix_end_extract_blob, .ctx = ctx, }; diff --git a/src/verify.c b/src/verify.c index e11561ef..41fcff78 100644 --- a/src/verify.c +++ b/src/verify.c @@ -44,28 +44,16 @@ struct verify_blob_list_ctx { void *progctx; union wimlib_progress_info *progress; u64 next_progress; - u64 cur_blob_offset; - u64 cur_blob_size; }; static int -verify_begin_blob(struct blob_descriptor *blob, void *_ctx) -{ - struct verify_blob_list_ctx *ctx = _ctx; - - ctx->cur_blob_offset = 0; - ctx->cur_blob_size = blob->size; - return 0; -} - -static int -verify_consume_chunk(const void *chunk, size_t size, void *_ctx) +verify_continue_blob(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_ctx) { struct verify_blob_list_ctx *ctx = _ctx; union wimlib_progress_info *progress = ctx->progress; - ctx->cur_blob_offset += size; - if (ctx->cur_blob_offset == ctx->cur_blob_size) + if (offset + size == blob->size) progress->verify_streams.completed_streams++; progress->verify_streams.completed_bytes += size; @@ -110,8 +98,7 @@ wimlib_verify_wim(WIMStruct *wim, int verify_flags) struct verify_blob_list_ctx ctx; struct blob_descriptor *blob; struct read_blob_callbacks cbs = { - .begin_blob = verify_begin_blob, - .consume_chunk = verify_consume_chunk, + .continue_blob = verify_continue_blob, .ctx = &ctx, }; diff --git a/src/win32_apply.c b/src/win32_apply.c index a4f81751..b55ce924 100644 --- a/src/win32_apply.c +++ b/src/win32_apply.c @@ -2257,9 +2257,9 @@ retry: return 0; } -/* Called when starting to read a blob for extraction on Windows */ +/* Called when starting to read a blob for extraction */ static int -begin_extract_blob(struct blob_descriptor *blob, void *_ctx) +win32_begin_extract_blob(struct blob_descriptor *blob, void *_ctx) { struct win32_apply_ctx *ctx = _ctx; const struct blob_extraction_target *targets = blob_extraction_targets(blob); @@ -2302,10 +2302,10 @@ fail: return ret; } -/* Called when the next chunk of a blob has been read for extraction on Windows - */ +/* Called when the next chunk of a blob has been read for extraction */ static int -extract_chunk(const void *chunk, size_t size, void *_ctx) +win32_extract_chunk(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_ctx) { struct win32_apply_ctx *ctx = _ctx; @@ -2590,9 +2590,9 @@ handle_system_compression(struct blob_descriptor *blob, struct win32_apply_ctx * } } -/* Called when a blob has been fully read for extraction on Windows */ +/* Called when a blob has been fully read for extraction */ static int -end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx) +win32_end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx) { struct win32_apply_ctx *ctx = _ctx; int ret; @@ -3071,9 +3071,9 @@ win32_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) goto out; struct read_blob_callbacks cbs = { - .begin_blob = begin_extract_blob, - .consume_chunk = extract_chunk, - .end_blob = end_extract_blob, + .begin_blob = win32_begin_extract_blob, + .continue_blob = win32_extract_chunk, + .end_blob = win32_end_extract_blob, .ctx = ctx, }; ret = extract_blob_list(&ctx->common, &cbs); diff --git a/src/win32_capture.c b/src/win32_capture.c index b5b8bc5c..a93427ec 100644 --- a/src/win32_capture.c +++ b/src/win32_capture.c @@ -315,7 +315,7 @@ windows_file_to_string(const struct windows_file *file, u8 *buf, size_t bufsize) static int read_winnt_stream_prefix(const struct windows_file *file, - u64 size, const struct read_blob_callbacks *cbs) + u64 size, const struct consume_chunk_callback *cb) { IO_STATUS_BLOCK iosb; UNICODE_STRING name = { @@ -401,7 +401,7 @@ read_winnt_stream_prefix(const struct windows_file *file, bytes_read = iosb.Information; bytes_remaining -= bytes_read; - ret = call_consume_chunk(buf, bytes_read, cbs); + ret = consume_chunk(cb, buf, bytes_read); if (ret) break; } @@ -410,7 +410,7 @@ read_winnt_stream_prefix(const struct windows_file *file, } struct win32_encrypted_read_ctx { - const struct read_blob_callbacks *cbs; + const struct consume_chunk_callback *cb; int wimlib_err_code; u64 bytes_remaining; }; @@ -425,7 +425,7 @@ win32_encrypted_export_cb(unsigned char *data, void *_ctx, unsigned long len) if (bytes_to_consume == 0) return ERROR_SUCCESS; - ret = call_consume_chunk(data, bytes_to_consume, ctx->cbs); + ret = consume_chunk(ctx->cb, data, bytes_to_consume); if (ret) { ctx->wimlib_err_code = ret; /* It doesn't matter what error code is returned here, as long @@ -438,7 +438,7 @@ win32_encrypted_export_cb(unsigned char *data, void *_ctx, unsigned long len) static int read_win32_encrypted_file_prefix(const wchar_t *path, bool is_dir, u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { struct win32_encrypted_read_ctx export_ctx; DWORD err; @@ -449,7 +449,7 @@ read_win32_encrypted_file_prefix(const wchar_t *path, bool is_dir, u64 size, if (is_dir) flags |= CREATE_FOR_DIR; - export_ctx.cbs = cbs; + export_ctx.cb = cb; export_ctx.wimlib_err_code = 0; export_ctx.bytes_remaining = size; @@ -487,16 +487,16 @@ read_win32_encrypted_file_prefix(const wchar_t *path, bool is_dir, u64 size, * described by @blob. */ int read_windows_file_prefix(const struct blob_descriptor *blob, u64 size, - const struct read_blob_callbacks *cbs) + const struct consume_chunk_callback *cb) { const struct windows_file *file = blob->windows_file; if (unlikely(file->is_encrypted)) { bool is_dir = (blob->file_inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY); - return read_win32_encrypted_file_prefix(file->path, is_dir, size, cbs); + return read_win32_encrypted_file_prefix(file->path, is_dir, size, cb); } - return read_winnt_stream_prefix(file, size, cbs); + return read_winnt_stream_prefix(file, size, cb); } /* diff --git a/src/write.c b/src/write.c index f5a9935d..7eaa0df6 100644 --- a/src/write.c +++ b/src/write.c @@ -377,12 +377,6 @@ struct write_blobs_ctx { * @blobs_being_compressed only when writing a solid resource. */ struct list_head blobs_in_solid_resource; - /* Current uncompressed offset in the blob being read. */ - u64 cur_read_blob_offset; - - /* Uncompressed size of the blob currently being read. */ - u64 cur_read_blob_size; - /* Current uncompressed offset in the blob being written. */ u64 cur_write_blob_offset; @@ -689,9 +683,6 @@ write_blob_begin_read(struct blob_descriptor *blob, void *_ctx) wimlib_assert(blob->size > 0); - ctx->cur_read_blob_offset = 0; - ctx->cur_read_blob_size = blob->size; - /* As an optimization, we allow some blobs to be "unhashed", meaning * their SHA-1 message digests are unknown. This is the case with blobs * that are added by scanning a directory tree with wimlib_add_image(), @@ -1019,7 +1010,8 @@ prepare_chunk_buffer(struct write_blobs_ctx *ctx) /* Process the next chunk of data to be written to a WIM resource. */ static int -write_blob_process_chunk(const void *chunk, size_t size, void *_ctx) +write_blob_process_chunk(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *_ctx) { struct write_blobs_ctx *ctx = _ctx; int ret; @@ -1032,7 +1024,6 @@ write_blob_process_chunk(const void *chunk, size_t size, void *_ctx) ret = write_chunk(ctx, chunk, size, size); if (ret) return ret; - ctx->cur_read_blob_offset += size; return 0; } @@ -1056,8 +1047,7 @@ write_blob_process_chunk(const void *chunk, size_t size, void *_ctx) } else { needed_chunk_size = min(ctx->out_chunk_size, ctx->cur_chunk_buf_filled + - (ctx->cur_read_blob_size - - ctx->cur_read_blob_offset)); + (blob->size - offset)); } bytes_consumed = min(chunkend - chunkptr, @@ -1067,7 +1057,7 @@ write_blob_process_chunk(const void *chunk, size_t size, void *_ctx) chunkptr, bytes_consumed); chunkptr += bytes_consumed; - ctx->cur_read_blob_offset += bytes_consumed; + offset += bytes_consumed; ctx->cur_chunk_buf_filled += bytes_consumed; if (ctx->cur_chunk_buf_filled == needed_chunk_size) { @@ -1088,8 +1078,6 @@ write_blob_end_read(struct blob_descriptor *blob, int status, void *_ctx) { struct write_blobs_ctx *ctx = _ctx; - wimlib_assert(ctx->cur_read_blob_offset == ctx->cur_read_blob_size || status); - if (!blob->will_be_in_output_wim) { /* The blob was a duplicate. Now that its data has finished * being read, it is being discarded in favor of the duplicate @@ -1616,7 +1604,7 @@ write_blob_list(struct list_head *blob_list, struct read_blob_callbacks cbs = { .begin_blob = write_blob_begin_read, - .consume_chunk = write_blob_process_chunk, + .continue_blob = write_blob_process_chunk, .end_blob = write_blob_end_read, .ctx = &ctx, }; -- 2.43.0