}
static int
-read_blobs_from_pipe(struct apply_ctx *ctx,
- const struct read_blob_list_callbacks *cbs)
+read_blobs_from_pipe(struct apply_ctx *ctx, const struct read_blob_callbacks *cbs)
{
int ret;
u8 hash[SHA1_HASH_SIZE];
if (ret)
return ret;
- wim_res_hdr_to_desc(&reshdr, ctx->wim, &rdesc);
-
- if (!(rdesc.flags & WIM_RESHDR_FLAG_METADATA)
+ if (!(reshdr.flags & WIM_RESHDR_FLAG_METADATA)
&& (blob = lookup_blob(ctx->wim->blob_table, hash))
&& (blob->out_refcnt))
{
- blob_set_is_located_in_nonsolid_wim_resource(blob, &rdesc);
-
- ret = (*cbs->begin_blob)(blob, cbs->begin_blob_ctx);
-
- if (!ret) {
- ret = extract_blob(blob, blob->size,
- cbs->consume_chunk,
- cbs->consume_chunk_ctx);
-
- ret = (*cbs->end_blob)(blob, ret,
- cbs->end_blob_ctx);
- }
+ wim_reshdr_to_desc_and_blob(&reshdr, ctx->wim, &rdesc, blob);
+ ret = read_blob_with_sha1(blob, cbs);
blob_unset_is_located_in_wim_resource(blob);
if (ret)
return ret;
ctx->num_blobs_remaining--;
} else {
+ wim_reshdr_to_desc(&reshdr, ctx->wim, &rdesc);
ret = skip_wim_resource(&rdesc);
if (ret)
return ret;
if (unlikely(blob->out_refcnt > MAX_OPEN_FILES))
return create_temporary_file(&ctx->tmpfile_fd, &ctx->tmpfile_name);
- else
- return (*ctx->saved_cbs->begin_blob)(blob, ctx->saved_cbs->begin_blob_ctx);
+
+ return call_begin_blob(blob, ctx->saved_cbs);
}
static int
ctx->tmpfile_name);
}
return ret;
- } else {
- return (*ctx->saved_cbs->consume_chunk)(chunk, size,
- ctx->saved_cbs->consume_chunk_ctx);
}
+
+ return call_consume_chunk(chunk, size, ctx->saved_cbs);
}
+/* Copy the blob's data from the temporary file to each of its targets.
+ *
+ * This is executed only in the very uncommon case that a blob is being
+ * extracted to more than MAX_OPEN_FILES targets! */
static int
-extract_from_tmpfile(const tchar *tmpfile_name, struct apply_ctx *ctx)
+extract_from_tmpfile(const tchar *tmpfile_name,
+ const struct blob_descriptor *orig_blob,
+ const struct read_blob_callbacks *cbs)
{
struct blob_descriptor tmpfile_blob;
- struct blob_descriptor *orig_blob = ctx->cur_blob;
- const struct read_blob_list_callbacks *cbs = ctx->saved_cbs;
+ const struct blob_extraction_target *targets = blob_extraction_targets(orig_blob);
int ret;
- const u32 orig_refcnt = orig_blob->out_refcnt;
-
- BUILD_BUG_ON(MAX_OPEN_FILES <
- ARRAY_LEN(orig_blob->inline_blob_extraction_targets));
-
- struct blob_extraction_target *targets = orig_blob->blob_extraction_targets;
-
- /* Copy the blob's data from the temporary file to each of its targets.
- *
- * This is executed only in the very uncommon case that a blob is being
- * extracted to more than MAX_OPEN_FILES targets! */
memcpy(&tmpfile_blob, orig_blob, sizeof(struct blob_descriptor));
tmpfile_blob.blob_location = BLOB_IN_FILE_ON_DISK;
- tmpfile_blob.file_on_disk = ctx->tmpfile_name;
- ret = 0;
- for (u32 i = 0; i < orig_refcnt; i++) {
-
- /* Note: it usually doesn't matter whether we pass the original
- * blob descriptor to callbacks provided by the extraction
- * backend as opposed to the tmpfile blob descriptor, since they
- * shouldn't actually read data from the blob other than through
- * the read_blob_prefix() call below. But for
- * WIMLIB_EXTRACT_FLAG_WIMBOOT mode on Windows it does matter
- * because it needs access to the original WIM resource
- * descriptor in order to create the external backing reference.
- */
-
- orig_blob->out_refcnt = 1;
- orig_blob->inline_blob_extraction_targets[0] = targets[i];
-
- ret = (*cbs->begin_blob)(orig_blob, cbs->begin_blob_ctx);
- if (ret)
- break;
-
- /* Extra SHA-1 isn't necessary here, but it shouldn't hurt as
- * this case is very rare anyway. */
- ret = extract_blob(&tmpfile_blob, tmpfile_blob.size,
- cbs->consume_chunk,
- cbs->consume_chunk_ctx);
+ tmpfile_blob.file_on_disk = (tchar *)tmpfile_name;
+ tmpfile_blob.out_refcnt = 1;
- ret = (*cbs->end_blob)(orig_blob, ret, cbs->end_blob_ctx);
+ for (u32 i = 0; i < orig_blob->out_refcnt; i++) {
+ tmpfile_blob.inline_blob_extraction_targets[0] = targets[i];
+ ret = read_blob_with_cbs(&tmpfile_blob, cbs);
if (ret)
- break;
+ return ret;
}
- FREE(targets);
- orig_blob->out_refcnt = 0;
- return ret;
+ return 0;
}
static int
if (unlikely(filedes_valid(&ctx->tmpfile_fd))) {
filedes_close(&ctx->tmpfile_fd);
if (!status)
- status = extract_from_tmpfile(ctx->tmpfile_name, ctx);
+ status = extract_from_tmpfile(ctx->tmpfile_name, blob,
+ ctx->saved_cbs);
filedes_invalidate(&ctx->tmpfile_fd);
tunlink(ctx->tmpfile_name);
FREE(ctx->tmpfile_name);
return status;
- } else {
- return (*ctx->saved_cbs->end_blob)(blob, status,
- ctx->saved_cbs->end_blob_ctx);
}
+
+ return call_end_blob(blob, status, ctx->saved_cbs);
}
/*
*
* This also handles sending WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS.
*
- * This also works if the WIM is being read from a pipe, whereas attempting to
- * read blobs directly (e.g. with read_full_blob_into_buf()) will not.
+ * This also works if the WIM is being read from a pipe.
*
* This also will split up blobs that will need to be extracted to more than
* MAX_OPEN_FILES locations, as measured by the 'out_refcnt' of each blob.
* destination file system might not support hard links).
*/
int
-extract_blob_list(struct apply_ctx *ctx,
- const struct read_blob_list_callbacks *cbs)
+extract_blob_list(struct apply_ctx *ctx, const struct read_blob_callbacks *cbs)
{
- struct read_blob_list_callbacks wrapper_cbs = {
- .begin_blob = begin_extract_blob_wrapper,
- .begin_blob_ctx = ctx,
- .consume_chunk = extract_chunk_wrapper,
- .consume_chunk_ctx = ctx,
- .end_blob = end_extract_blob_wrapper,
- .end_blob_ctx = ctx,
+ struct read_blob_callbacks wrapper_cbs = {
+ .begin_blob = begin_extract_blob_wrapper,
+ .consume_chunk = extract_chunk_wrapper,
+ .end_blob = end_extract_blob_wrapper,
+ .ctx = ctx,
};
ctx->saved_cbs = cbs;
if (ctx->extract_flags & WIMLIB_EXTRACT_FLAG_FROM_PIPE) {
}
filedes_init(&_stdout, STDOUT_FILENO);
- return extract_full_blob_to_fd(blob, &_stdout);
+ return extract_blob_to_fd(blob, &_stdout);
}
static int
else
features->other_reparse_points++;
}
- if (inode->i_security_id != -1)
+ if (inode_has_security_descriptor(inode))
features->security_descriptors++;
if (inode_has_unix_data(inode))
features->unix_data++;
metadata_rdesc = MALLOC(sizeof(struct wim_resource_descriptor));
if (!metadata_rdesc)
goto out_wimlib_free;
- wim_res_hdr_to_desc(&reshdr, pwm, metadata_rdesc);
- blob_set_is_located_in_nonsolid_wim_resource(imd->metadata_blob,
- metadata_rdesc);
+ wim_reshdr_to_desc_and_blob(&reshdr, pwm, metadata_rdesc,
+ imd->metadata_blob);
if (i == image) {
/* Metadata resource is for the image being extracted.