+ struct hasher_context *ctx = _ctx;
+ u8 hash[SHA1_HASH_SIZE];
+ int ret;
+
+ if (unlikely(status)) {
+ /* Error occurred; the full blob may not have been read. */
+ ret = status;
+ goto out_next_cb;
+ }
+
+ /* Retrieve the final SHA-1 message digest. */
+ sha1_final(hash, &ctx->sha_ctx);
+
+ /* Set the SHA-1 message digest of the blob, or compare the calculated
+ * value with stored value. */
+ if (blob->unhashed) {
+ if (ctx->flags & COMPUTE_MISSING_BLOB_HASHES)
+ copy_hash(blob->hash, hash);
+ } else if ((ctx->flags & VERIFY_BLOB_HASHES) &&
+ unlikely(!hashes_equal(hash, blob->hash)))
+ {
+ if (wimlib_print_errors) {
+ tchar expected_hashstr[SHA1_HASH_SIZE * 2 + 1];
+ tchar actual_hashstr[SHA1_HASH_SIZE * 2 + 1];
+ sprint_hash(blob->hash, expected_hashstr);
+ sprint_hash(hash, actual_hashstr);
+ ERROR("The data is corrupted!\n"
+ " (Expected SHA-1=%"TS", got SHA-1=%"TS")",
+ expected_hashstr, actual_hashstr);
+ }
+ ret = WIMLIB_ERR_INVALID_RESOURCE_HASH;
+ goto out_next_cb;
+ }
+ ret = 0;
+out_next_cb:
+ return call_end_blob(blob, ret, &ctx->cbs);
+}
+
+/* Read the full data of the specified blob, passing the data into the specified
+ * callbacks (all of which are optional) and either checking or computing the
+ * SHA-1 message digest of the blob. */
+int
+read_blob_with_sha1(struct blob_descriptor *blob,
+ const struct read_blob_callbacks *cbs)
+{
+ struct hasher_context hasher_ctx = {
+ .flags = VERIFY_BLOB_HASHES | COMPUTE_MISSING_BLOB_HASHES,
+ .cbs = *cbs,
+ };
+ struct read_blob_callbacks hasher_cbs = {
+ .begin_blob = hasher_begin_blob,
+ .consume_chunk = hasher_consume_chunk,
+ .end_blob = hasher_end_blob,
+ .ctx = &hasher_ctx,
+ };
+ return read_blob_with_cbs(blob, &hasher_cbs);
+}
+
+static int
+read_blobs_in_solid_resource(struct blob_descriptor *first_blob,
+ struct blob_descriptor *last_blob,
+ size_t blob_count,
+ size_t list_head_offset,
+ const struct read_blob_callbacks *sink_cbs)
+{
+ struct data_range *ranges;
+ bool ranges_malloced;
+ struct blob_descriptor *cur_blob;
+ size_t i;
+ int ret;
+ u64 ranges_alloc_size;
+
+ /* Setup data ranges array (one range per blob to read); this way
+ * read_compressed_wim_resource() does not need to be aware of blobs.
+ */
+
+ ranges_alloc_size = (u64)blob_count * sizeof(ranges[0]);