X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fresource.c;h=c7eedab0ad61663b30ea7f2045c6553945a90be0;hp=5237b88a37fd646613770df5768e3f56625cd2ab;hb=b5238e5a022184cbc13ebf510bc5081140867abe;hpb=f3e97b29c4a8c564d54b0fd11cd43a9b4cd6a8ad diff --git a/src/resource.c b/src/resource.c index 5237b88a..c7eedab0 100644 --- a/src/resource.c +++ b/src/resource.c @@ -320,11 +320,11 @@ read_compressed_resource(FILE *fp, * 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 */ @@ -463,9 +463,9 @@ put_resource_entry(void *p, const struct resource_entry *entry) static FILE * wim_get_fp(WIMStruct *w) { -#ifdef WITH_FUSE - pthread_mutex_lock(&w->fp_tab_mutex); FILE *fp; +#if defined(WITH_FUSE) || defined(ENABLE_MULTITHREADED_COMPRESSION) + pthread_mutex_lock(&w->fp_tab_mutex); wimlib_assert(w->filename != NULL); @@ -482,9 +482,9 @@ wim_get_fp(WIMStruct *w) 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; } @@ -492,7 +492,7 @@ static int 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); @@ -516,7 +516,7 @@ wim_release_fp(WIMStruct *w, FILE *fp) 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; } @@ -533,22 +533,18 @@ read_partial_wim_resource(const struct wim_lookup_table_entry *lte, 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)) { @@ -576,7 +572,7 @@ read_partial_wim_resource(const struct wim_lookup_table_entry *lte, 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); @@ -593,11 +589,17 @@ read_partial_wim_resource(const struct wim_lookup_table_entry *lte, } 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) @@ -628,6 +630,7 @@ read_wim_resource_prefix(const struct wim_lookup_table_entry *lte, } +#ifndef __WIN32__ static int read_file_on_disk_prefix(const struct wim_lookup_table_entry *lte, u64 size, @@ -674,6 +677,7 @@ out_close: close(fd); return ret; } +#endif /* !__WIN32__ */ static int read_buffer_prefix(const struct wim_lookup_table_entry *lte, @@ -730,7 +734,9 @@ read_resource_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, @@ -806,8 +812,8 @@ extract_wim_resource(const struct wim_lookup_table_entry *lte, 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 { @@ -838,6 +844,29 @@ extract_wim_resource_to_fd(const struct wim_lookup_table_entry *lte, 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