* is equal to the uncompressed chunk size. */
if (compressed_chunk_size == uncompressed_chunk_size) {
/* Uncompressed chunk */
-
if (start_offset != 0)
if (fseeko(fp, start_offset, SEEK_CUR))
goto read_error;
- if (fread(out_p, 1, partial_chunk_size, fp) != partial_chunk_size)
+ if (fread(cb ? out_p + start_offset : out_p,
+ 1, partial_chunk_size, fp) != partial_chunk_size)
goto read_error;
} else {
/* Compressed chunk */
static FILE *
wim_get_fp(WIMStruct *w)
{
-#ifdef WITH_FUSE
+#if defined(WITH_FUSE) || defined(ENABLE_MULTITHREADED_COMPRESSION)
pthread_mutex_lock(&w->fp_tab_mutex);
FILE *fp;
ERROR_WITH_ERRNO("Failed to open `%"TS"'", w->filename);
out_unlock:
pthread_mutex_unlock(&w->fp_tab_mutex);
-#else /* WITH_FUSE */
+#else /* WITH_FUSE || ENABLE_MULTITHREADED_COMPRESSION */
fp = w->fp;
-#endif /* !WITH_FUSE */
+#endif /* !WITH_FUSE && !ENABLE_MULTITHREADED_COMPRESSION */
return fp;
}
wim_release_fp(WIMStruct *w, FILE *fp)
{
int ret = 0;
-#ifdef WITH_FUSE
+#if defined(WITH_FUSE) || defined(ENABLE_MULTITHREADED_COMPRESSION)
FILE **fp_tab;
pthread_mutex_lock(&w->fp_tab_mutex);
w->num_allocated_fps += 4;
out_unlock:
pthread_mutex_unlock(&w->fp_tab_mutex);
-#endif /* WITH_FUSE */
+#endif /* WITH_FUSE || ENABLE_MULTITHREADED_COMPRESSION */
return ret;
}
int ret;
wimlib_assert(lte->resource_location == RESOURCE_IN_WIM);
- wimlib_assert(offset + size <= lte->resource_entry.original_size);
wim = lte->wim;
-
if (flags & WIMLIB_RESOURCE_FLAG_THREADSAFE_READ) {
wim_fp = wim_get_fp(wim);
if (!wim_fp) {
- ret = -1;
+ ret = WIMLIB_ERR_READ;
goto out;
}
} else {
wim_fp = lte->wim->fp;
}
- wimlib_assert(wim_fp != NULL);
-
if (lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED &&
!(flags & WIMLIB_RESOURCE_FLAG_RAW))
{
while (size) {
size_t bytes_to_read = min(WIM_CHUNK_SIZE, size);
size_t bytes_read = fread(buf, 1, bytes_to_read, wim_fp);
-
+
if (bytes_read != bytes_to_read)
goto read_error;
ret = cb(buf, bytes_read, ctx_or_buf);
}
goto out_release_fp;
read_error:
- ERROR_WITH_ERRNO("Error reading data from WIM");
+ if (ferror(wim_fp))
+ ERROR_WITH_ERRNO("Error reading data from WIM");
+ else
+ ERROR("Unexpected EOF in WIM!");
ret = WIMLIB_ERR_READ;
out_release_fp:
- if (flags & WIMLIB_RESOURCE_FLAG_THREADSAFE_READ)
- ret |= wim_release_fp(wim, wim_fp);
+ if (flags & WIMLIB_RESOURCE_FLAG_THREADSAFE_READ) {
+ int ret2 = wim_release_fp(wim, wim_fp);
+ if (ret == 0)
+ ret = ret2;
+ }
out:
if (ret) {
if (errno == 0)
}
+#ifndef __WIN32__
static int
read_file_on_disk_prefix(const struct wim_lookup_table_entry *lte,
u64 size,
close(fd);
return ret;
}
+#endif /* !__WIN32__ */
static int
read_buffer_prefix(const struct wim_lookup_table_entry *lte,
{
static const read_resource_prefix_handler_t handlers[] = {
[RESOURCE_IN_WIM] = read_wim_resource_prefix,
+ #ifndef __WIN32__
[RESOURCE_IN_FILE_ON_DISK] = read_file_on_disk_prefix,
+ #endif
[RESOURCE_IN_ATTACHED_BUFFER] = read_buffer_prefix,
#ifdef WITH_FUSE
[RESOURCE_IN_STAGING_FILE] = read_file_on_disk_prefix,
print_lookup_table_entry(lte, stderr);
if (lte->resource_location == RESOURCE_IN_WIM)
ERROR("The WIM file appears to be corrupt!");
- ret = WIMLIB_ERR_INVALID_RESOURCE_HASH;
#endif
+ ret = WIMLIB_ERR_INVALID_RESOURCE_HASH;
}
}
} else {
return extract_wim_resource(lte, size, extract_wim_chunk_to_fd, &fd);
}
+
+static int
+sha1_chunk(const void *buf, size_t len, void *ctx)
+{
+ sha1_update(ctx, buf, len);
+ return 0;
+}
+
+/* Calculate the SHA1 message digest of a stream. */
+int
+sha1_resource(struct wim_lookup_table_entry *lte)
+{
+ int ret;
+ SHA_CTX sha_ctx;
+
+ sha1_init(&sha_ctx);
+ ret = read_resource_prefix(lte, wim_resource_size(lte),
+ sha1_chunk, &sha_ctx, 0);
+ if (ret == 0)
+ sha1_final(lte->hash, &sha_ctx);
+ return ret;
+}
+
/*
* Copies the file resource specified by the lookup table entry @lte from the
* input WIM to the output WIM that has its FILE * given by