From 9e5404f2c773173ebaae519d7ebacb2d802b263f Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 24 Jun 2014 20:08:39 -0500 Subject: [PATCH] extract.c: Pass orig stream to callbacks when reading tmpfile Needed for "WIMBoot" extraction --- include/wimlib/resource.h | 4 ---- src/extract.c | 31 +++++++++++++++++++++++++------ src/resource.c | 2 +- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/include/wimlib/resource.h b/include/wimlib/resource.h index f17d5f3a..ae077553 100644 --- a/include/wimlib/resource.h +++ b/include/wimlib/resource.h @@ -295,10 +295,6 @@ read_stream_list(struct list_head *stream_list, const struct read_stream_list_callbacks *cbs, int flags); -extern int -read_full_stream_with_cbs(struct wim_lookup_table_entry *lte, - const struct read_stream_list_callbacks *cbs); - /* Functions to extract streams. */ extern int diff --git a/src/extract.c b/src/extract.c index e62fa8a8..3cc9959d 100644 --- a/src/extract.c +++ b/src/extract.c @@ -392,12 +392,12 @@ extract_chunk_wrapper(const void *chunk, size_t size, void *_ctx) } static int -extract_from_tmpfile(const tchar *tmpfile_name, - struct wim_lookup_table_entry *orig_lte, - struct apply_ctx *ctx) +extract_from_tmpfile(const tchar *tmpfile_name, struct apply_ctx *ctx) { struct wim_lookup_table_entry tmpfile_lte; + struct wim_lookup_table_entry *orig_lte = ctx->cur_stream; const struct stream_owner *owners = stream_owners(orig_lte); + const struct read_stream_list_callbacks *cbs = ctx->saved_cbs; int ret; /* Copy the stream's data from the temporary file to each of its @@ -414,9 +414,29 @@ extract_from_tmpfile(const tchar *tmpfile_name, for (u32 i = 0; i < orig_lte->out_refcnt; i++) { tmpfile_lte.inline_stream_owners[0] = owners[i]; - ret = read_full_stream_with_cbs(&tmpfile_lte, ctx->saved_cbs); + + /* Note: it usually doesn't matter whether we pass the original + * stream entry to callbacks provided by the extraction backend + * as opposed to the tmpfile stream entry, since they shouldn't + * actually read data from the stream other than through the + * read_stream_prefix() call below. But for + * WIMLIB_EXTRACT_FLAG_WIMBOOT mode on Windows it does matter + * because it needs the original stream location in order to + * create the external backing reference. */ + + ret = (*cbs->begin_stream)(orig_lte, 0, + cbs->begin_stream_ctx); if (ret) return ret; + + /* Extra SHA-1 isn't necessary here, but it shouldn't hurt as + * this case is very rare anyway. */ + ret = extract_stream(&tmpfile_lte, tmpfile_lte.size, + cbs->consume_chunk, + cbs->consume_chunk_ctx); + + return (*cbs->end_stream)(orig_lte, ret, + cbs->end_stream_ctx); } return 0; } @@ -430,8 +450,7 @@ end_extract_stream_wrapper(struct wim_lookup_table_entry *stream, if (unlikely(filedes_valid(&ctx->tmpfile_fd))) { filedes_close(&ctx->tmpfile_fd); if (!status) - status = extract_from_tmpfile(ctx->tmpfile_name, - stream, ctx); + status = extract_from_tmpfile(ctx->tmpfile_name, ctx); filedes_invalidate(&ctx->tmpfile_fd); tunlink(ctx->tmpfile_name); FREE(ctx->tmpfile_name); diff --git a/src/resource.c b/src/resource.c index 470b63ec..300aec8f 100644 --- a/src/resource.c +++ b/src/resource.c @@ -1167,7 +1167,7 @@ out_next_cb: return (*ctx->cbs.end_stream)(lte, ret, ctx->cbs.end_stream_ctx); } -int +static int read_full_stream_with_cbs(struct wim_lookup_table_entry *lte, const struct read_stream_list_callbacks *cbs) { -- 2.43.0