#include "wimlib/wim.h"
#ifdef __WIN32__
-/* for read_win32_file_prefix(), read_win32_encrypted_file_prefix() */
+/* for read_winnt_file_prefix(), read_win32_encrypted_file_prefix() */
# include "wimlib/win32.h"
#endif
int errno_save;
u64 *chunk_offsets = NULL;
+ u8 *_ubuf = NULL;
u8 *ubuf = NULL;
void *cbuf = NULL;
bool chunk_offsets_malloced = false;
struct filedes * const in_fd = &rspec->wim->in_fd;
/* Determine if we're reading a pipable resource from a pipe or not. */
- const bool is_pipe_read = !filedes_is_seekable(in_fd);
+ const bool is_pipe_read = (rspec->is_pipable && !filedes_is_seekable(in_fd));
- /* Determine if the chunk table is in an altenate format. */
+ /* Determine if the chunk table is in an alternate format. */
const bool alt_chunk_table = (rspec->flags & WIM_RESHDR_FLAG_PACKED_STREAMS)
&& !is_pipe_read;
"expected power-of-2 chunk size (got %"PRIu32")",
chunk_size);
ret = WIMLIB_ERR_INVALID_CHUNK_SIZE;
+ errno = EINVAL;
goto out_free_memory;
}
} else {
ret = wimlib_create_decompressor(ctype, chunk_size, NULL,
&decompressor);
- if (ret)
+ if (ret) {
+ if (ret != WIMLIB_ERR_NOMEM)
+ errno = EINVAL;
goto out_free_memory;
+ }
}
const u32 chunk_order = bsr32(chunk_size);
/* Allocate buffer for holding the uncompressed data of each chunk. */
if (chunk_size <= STACK_MAX) {
- ubuf = alloca(chunk_size);
+ _ubuf = alloca(chunk_size + 15);
} else {
- ubuf = MALLOC(chunk_size);
- if (ubuf == NULL)
+ _ubuf = MALLOC(chunk_size + 15);
+ if (_ubuf == NULL)
goto oom;
ubuf_malloced = true;
}
+ ubuf = (u8 *)(((uintptr_t)_ubuf + 15) & ~15);
/* Allocate a temporary buffer for reading compressed chunks, each of
* which can be at most @chunk_size - 1 bytes. This excludes compressed
if (chunk_offsets_malloced)
FREE(chunk_offsets);
if (ubuf_malloced)
- FREE(ubuf);
+ FREE(_ubuf);
if (cbuf_malloced)
FREE(cbuf);
errno = errno_save;
cb, cb_ctx);
}
-#ifndef __WIN32__
/* This function handles reading stream data that is located in an external
* file, such as a file that has been added to the WIM image through execution
* of a wimlib_add_command.
DEBUG("Reading %"PRIu64" bytes from \"%"TS"\"", size, lte->file_on_disk);
- raw_fd = open(lte->file_on_disk, O_BINARY | O_RDONLY);
+ raw_fd = topen(lte->file_on_disk, O_BINARY | O_RDONLY);
if (raw_fd < 0) {
ERROR_WITH_ERRNO("Can't open \"%"TS"\"", lte->file_on_disk);
return WIMLIB_ERR_OPEN;
filedes_close(&fd);
return ret;
}
-#endif /* !__WIN32__ */
+
+#ifdef WITH_FUSE
+static int
+read_staging_file_prefix(const struct wim_lookup_table_entry *lte, u64 size,
+ consume_data_callback_t cb, void *cb_ctx)
+{
+ int raw_fd;
+ struct filedes fd;
+ int ret;
+
+ wimlib_assert(size <= lte->size);
+
+ DEBUG("Reading %"PRIu64" bytes from staging file \"%s\"",
+ size, lte->staging_file_name);
+
+ raw_fd = openat(lte->staging_dir_fd, lte->staging_file_name,
+ O_RDONLY | O_NOFOLLOW);
+ if (raw_fd < 0) {
+ ERROR_WITH_ERRNO("Can't open staging file \"%s\"",
+ lte->staging_file_name);
+ return WIMLIB_ERR_OPEN;
+ }
+ filedes_init(&fd, raw_fd);
+ ret = read_raw_file_data(&fd, 0, size, cb, cb_ctx);
+ filedes_close(&fd);
+ return ret;
+}
+#endif
/* This function handles the trivial case of reading stream data that is, in
* fact, already located in an in-memory buffer. */
{
static const read_stream_prefix_handler_t handlers[] = {
[RESOURCE_IN_WIM] = read_wim_stream_prefix,
- #ifdef __WIN32__
- [RESOURCE_IN_FILE_ON_DISK] = read_win32_file_prefix,
- #else
[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,
+ [RESOURCE_IN_STAGING_FILE] = read_staging_file_prefix,
#endif
#ifdef WITH_NTFS_3G
[RESOURCE_IN_NTFS_VOLUME] = read_ntfs_file_prefix,
#endif
#ifdef __WIN32__
+ [RESOURCE_IN_WINNT_FILE_ON_DISK] = read_winnt_file_prefix,
[RESOURCE_WIN32_ENCRYPTED] = read_win32_encrypted_file_prefix,
#endif
};
wimlib_assert(size <= ctx->cur_stream->size - ctx->cur_stream_offset);
if (ctx->cur_stream_offset == 0) {
- u32 flags;
/* Starting a new stream. */
DEBUG("Begin new stream (size=%"PRIu64").",
ctx->cur_stream->size);
- flags = BEGIN_STREAM_FLAG_PARTIAL_RESOURCE;
- if (size == ctx->cur_stream->size)
- flags |= BEGIN_STREAM_FLAG_WHOLE_STREAM;
ret = (*ctx->cbs.begin_stream)(ctx->cur_stream,
- flags,
ctx->cbs.begin_stream_ctx);
if (ret)
return ret;
/* Consume the chunk. */
ret = (*ctx->cbs.consume_chunk)(chunk, size,
ctx->cbs.consume_chunk_ctx);
+ ctx->cur_stream_offset += size;
if (ret)
return ret;
- ctx->cur_stream_offset += size;
if (ctx->cur_stream_offset == ctx->cur_stream->size) {
/* Finished reading all the data for a stream. */
/* Callback for starting to read a stream while calculating its SHA1 message
* digest. */
static int
-hasher_begin_stream(struct wim_lookup_table_entry *lte, u32 flags,
- void *_ctx)
+hasher_begin_stream(struct wim_lookup_table_entry *lte, void *_ctx)
{
struct hasher_context *ctx = _ctx;
if (ctx->cbs.begin_stream == NULL)
return 0;
else
- return (*ctx->cbs.begin_stream)(lte, flags,
- ctx->cbs.begin_stream_ctx);
+ return (*ctx->cbs.begin_stream)(lte, ctx->cbs.begin_stream_ctx);
}
/* A consume_data_callback_t implementation that continues calculating the SHA1
{
int ret;
- ret = (*cbs->begin_stream)(lte, 0, cbs->begin_stream_ctx);
+ ret = (*cbs->begin_stream)(lte, cbs->begin_stream_ctx);
if (ret)
return ret;