extract.c: Pass orig stream to callbacks when reading tmpfile
authorEric Biggers <ebiggers3@gmail.com>
Wed, 25 Jun 2014 01:08:39 +0000 (20:08 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Wed, 25 Jun 2014 01:08:46 +0000 (20:08 -0500)
Needed for "WIMBoot" extraction

include/wimlib/resource.h
src/extract.c
src/resource.c

index f17d5f3a007a0f912b3bf344c5d0b2726480d76d..ae0775536b726e138000cfc4fd77dcbbd8feba48 100644 (file)
@@ -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
index e62fa8a890cc27927f9fbe22290db85045d9cb8b..3cc9959d27df0ebf57bd98853adcff152e1a52fd 100644 (file)
@@ -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);
index 470b63ece37e3dcbca4042c8213255c68d889d9e..300aec8f1cbec29e0b919bba8243984e7e518271 100644 (file)
@@ -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)
 {