static const u8 wim_magic_chars[WIM_MAGIC_LEN] = {
'M', 'S', 'W', 'I', 'M', '\0', '\0', '\0' };
-/* Reads the header for a WIM file. */
+/* Reads the header from a WIM file. */
int
read_header(filedes_t in_fd, struct wim_header *hdr, int open_flags)
{
size_t bytes_read;
u8 buf[WIM_HEADER_DISK_SIZE];
- const u8 *p;
+ const void *p;
u32 hdr_size;
u32 wim_version;
DEBUG("Reading WIM header.");
- bytes_read = full_read(in_fd, buf, WIM_HEADER_DISK_SIZE);
+ bytes_read = full_pread(in_fd, buf, WIM_HEADER_DISK_SIZE, 0);
if (bytes_read != WIM_HEADER_DISK_SIZE) {
ERROR_WITH_ERRNO("Error reading WIM header");
return WIMLIB_ERR_READ;
}
- /* Byte 8 */
-
p = buf;
-
if (memcmp(p, wim_magic_chars, WIM_MAGIC_LEN)) {
ERROR("Invalid magic characters in WIM header");
return WIMLIB_ERR_NOT_A_WIM_FILE;
}
- p += 8;
- p = get_u32(p, &hdr_size);
-
- /* Byte 12 */
-
+ /* Byte 8 */
+ p = get_u32(p + 8, &hdr_size);
if (hdr_size != WIM_HEADER_DISK_SIZE) {
ERROR("Header is %u bytes (expected %u bytes)",
hdr_size, WIM_HEADER_DISK_SIZE);
return WIMLIB_ERR_INVALID_HEADER_SIZE;
}
+ /* Byte 12 */
p = get_u32(buf + WIM_MAGIC_LEN + sizeof(u32), &wim_version);
-
if (wim_version != WIM_VERSION) {
ERROR("The WIM header says the WIM version is %u, but wimlib "
"only knows about version %u",
*
* @hdr: A pointer to a struct wim_header structure that describes the header.
* @out_fd: The file descriptor to the WIM file, opened for writing.
- * @return: Zero on success, nonzero on failure.
+ *
+ * Returns zero on success, nonzero on failure.
*/
int
write_header(const struct wim_header *hdr, int out_fd)
p = put_u32(p, hdr->flags);
p = put_u32(p, (hdr->flags & WIM_HDR_FLAG_COMPRESSION) ?
WIM_CHUNK_SIZE : 0);
- /* byte 24 */
+ /* Byte 24 */
p = put_bytes(p, WIM_GID_LEN, hdr->guid);
p = put_u16(p, hdr->part_number);
- /* byte 40 */
+ /* Byte 40 */
p = put_u16(p, hdr->total_parts);
p = put_u32(p, hdr->image_count);
p = put_u32(p, hdr->boot_idx);
p = put_resource_entry(p, &hdr->integrity);
p = put_zeroes(p, WIM_UNUSED_LEN);
- assert(p - buf == sizeof(buf));
+ wimlib_assert(p - buf == sizeof(buf));
if (full_pwrite(out_fd, buf, sizeof(buf), 0) != sizeof(buf)) {
ERROR_WITH_ERRNO("Failed to write WIM header");
} else {
FREE(table);
table = NULL;
- ERROR("Failed to allocate memory for lookup table with capacity %zu",
- capacity);
+ ERROR("Failed to allocate memory for lookup table "
+ "with capacity %zu", capacity);
}
}
return table;
int
read_lookup_table(WIMStruct *w)
{
- u64 num_entries;
int ret;
+ size_t num_entries;
struct wim_lookup_table *table;
struct wim_lookup_table_entry *cur_entry, *duplicate_entry;
- void *table_buf;
- size_t table_size;
- const void *p;
+ u8 table_buf[(BUFFER_SIZE / WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE) *
+ WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE];
+ const u8 *p;
+ off_t offset;
+ size_t buf_entries_remaining;
DEBUG("Reading lookup table: offset %"PRIu64", size %"PRIu64"",
w->hdr.lookup_table_res_entry.offset,
return WIMLIB_ERR_COMPRESSED_LOOKUP_TABLE;
}
- table_size = w->hdr.lookup_table_res_entry.size;
- if (table_size != w->hdr.lookup_table_res_entry.size) {
- ERROR("Lookup table is invalid");
- return WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
- }
-
- table_buf = MALLOC(table_size);
- if (!table_buf)
- return WIMLIB_ERR_NOMEM;
-
- if (full_pread(w->in_fd, table_buf, table_size,
- w->hdr.lookup_table_res_entry.offset) != table_size)
- {
- ret = WIMLIB_ERR_READ;
- goto out_free_table_buf;
- }
-
- num_entries = w->hdr.lookup_table_res_entry.original_size /
+ num_entries = w->hdr.lookup_table_res_entry.size /
WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE;
table = new_lookup_table(num_entries * 2 + 1);
- if (!table) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_free_table_buf;
- }
+ if (!table)
+ return WIMLIB_ERR_NOMEM;
w->current_image = 0;
- p = table_buf;
- while (num_entries--) {
+ offset = w->hdr.lookup_table_res_entry.offset;
+ buf_entries_remaining = 0;
+ for (; num_entries != 0; num_entries--, buf_entries_remaining--) {
+ if (buf_entries_remaining == 0) {
+ size_t entries_to_read, bytes_to_read;
+
+ entries_to_read = min(sizeof(table_buf) /
+ WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE,
+ num_entries);
+ bytes_to_read = entries_to_read *
+ WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE;
+ if (full_pread(w->in_fd, table_buf,
+ bytes_to_read, offset) != bytes_to_read)
+ {
+ ERROR_WITH_ERRNO("Error reading lookup table "
+ "(offset=%"PRIu64")", offset);
+ ret = WIMLIB_ERR_READ;
+ goto out_free_lookup_table;
+ }
+ offset += bytes_to_read;
+ p = table_buf;
+ buf_entries_remaining = entries_to_read;
+ }
cur_entry = new_lookup_table_entry();
if (!cur_entry) {
ret = WIMLIB_ERR_NOMEM;
}
}
- if (w->hdr.part_number == 1 &&
- w->current_image != w->hdr.image_count)
+ if (w->hdr.part_number == 1 && w->current_image != w->hdr.image_count)
{
ERROR("The WIM header says there are %u images "
"in the WIM, but we only found %d metadata "
DEBUG("Done reading lookup table.");
w->lookup_table = table;
ret = 0;
- goto out_free_table_buf;
+ goto out;
out_free_cur_entry:
FREE(cur_entry);
out_free_lookup_table:
free_lookup_table(table);
-out_free_table_buf:
- FREE(table_buf);
+out:
w->current_image = 0;
return ret;
}
-/*
- * Writes a lookup table entry to the output file.
- */
-static void *
-write_lookup_table_entry(struct wim_lookup_table_entry *lte, void *buf_p)
+static u8 *
+write_lookup_table_entry(struct wim_lookup_table_entry *lte, u8 *buf_p)
{
buf_p = put_resource_entry(buf_p, <e->output_resource_entry);
buf_p = put_u16(buf_p, lte->part_number);
filedes_t out_fd,
struct resource_entry *out_res_entry)
{
- size_t num_entries;
- struct list_head *pos;
+ int ret;
+ off_t start_offset;
+ u8 table_buf[(BUFFER_SIZE / WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE) *
+ WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE];
+ u8 *buf_p;
size_t table_size;
- void *table_buf;
- void *buf_p;
+ size_t bytes_to_write;
struct wim_lookup_table_entry *lte;
- off_t start_offset;
- int ret;
start_offset = filedes_offset(out_fd);
if (start_offset == -1)
- return WIMLIB_ERR_WRITE;
-
- num_entries = 0;
- list_for_each(pos, stream_list)
- num_entries++;
- table_size = num_entries * WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE;
-
- table_buf = MALLOC(table_size);
- if (!table_buf) {
- ERROR("Failed to allocate lookup table buffer of %zu bytes", table_size);
- return WIMLIB_ERR_NOMEM;
- }
+ goto write_error;
buf_p = table_buf;
- list_for_each_entry(lte, stream_list, lookup_table_list)
- buf_p = write_lookup_table_entry(lte, buf_p);
-
- wimlib_assert(buf_p - table_buf == table_size);
-
- if (full_write(out_fd, table_buf, table_size) != table_size) {
- ERROR_WITH_ERRNO("Failed to write lookup table");
- ret = WIMLIB_ERR_WRITE;
- goto out_free_table_buf;
+ table_size = 0;
+ list_for_each_entry(lte, stream_list, lookup_table_list) {
+ if (buf_p == table_buf + sizeof(table_buf)) {
+ bytes_to_write = sizeof(table_buf);
+ if (full_write(out_fd, table_buf,
+ bytes_to_write) != bytes_to_write)
+ goto write_error;
+ table_size += bytes_to_write;
+ buf_p = table_buf;
+ }
+ buf_p = write_lookup_table_entry(lte, buf_p);
+ }
+ bytes_to_write = buf_p - table_buf;
+ if (bytes_to_write != 0) {
+ if (full_write(out_fd, table_buf,
+ bytes_to_write) != bytes_to_write)
+ goto write_error;
+ table_size += bytes_to_write;
}
-
out_res_entry->offset = start_offset;
out_res_entry->size = table_size;
out_res_entry->original_size = table_size;
out_res_entry->flags = WIM_RESHDR_FLAG_METADATA;
ret = 0;
-out_free_table_buf:
- FREE(table_buf);
+out:
return ret;
+write_error:
+ ERROR_WITH_ERRNO("Failed to write lookup table");
+ ret = WIMLIB_ERR_WRITE;
+ goto out;
}
static int
append_lookup_table_entry(struct wim_lookup_table_entry *lte, void *_list)
{
- struct list_head *list = _list;
-
if (lte->out_refcnt != 0)
- list_add_tail(<e->lookup_table_list, list);
+ list_add_tail(<e->lookup_table_list, (struct list_head*)_list);
return 0;
}
-
/* Writes the WIM lookup table to the output file. */
int
write_lookup_table(WIMStruct *w, int image, struct resource_entry *out_res_entry)
metadata_lte->output_resource_entry.flags |= WIM_RESHDR_FLAG_METADATA;
append_lookup_table_entry(metadata_lte, &stream_list);
}
-
for_lookup_table_entry(w->lookup_table,
append_lookup_table_entry,
&stream_list);
goto out;
}
-/*
- * Reads uncompressed data from an open file stream.
- */
-int
-read_uncompressed_resource(FILE *fp, u64 offset, u64 len, void *contents_ret)
-{
- if (fseeko(fp, offset, SEEK_SET) != 0) {
- ERROR("Failed to seek to byte %"PRIu64" of input file "
- "to read uncompressed resource (len = %"PRIu64")",
- offset, len);
- return WIMLIB_ERR_READ;
- }
- if (fread(contents_ret, 1, len, fp) != len) {
- if (feof(fp)) {
- ERROR("Unexpected EOF in uncompressed file resource");
- } else {
- ERROR("Failed to read %"PRIu64" bytes from "
- "uncompressed resource at offset %"PRIu64,
- len, offset);
- }
- return WIMLIB_ERR_READ;
- }
- return 0;
-}
-
/* Reads the contents of a struct resource_entry, as represented in the on-disk
* format, from the memory pointed to by @p, and fills in the fields of @entry.
* A pointer to the byte after the memory read at @p is returned. */
#include "lookup_table.h"
#include "xml.h"
#include "buffer_io.h"
+#include <unistd.h>
+#include <fcntl.h>
struct split_args {
WIMStruct *w;
int total_parts = args.cur_part_number;
for (int i = 1; i <= total_parts; i++) {
const tchar *part_name;
+ int part_fd;
+ u8 part_data_buf[4];
+ size_t bytes_written;
+
if (i == 1) {
part_name = swm_name;
} else {
part_name = swm_base_name;
}
- FILE *fp = tfopen(part_name, T("r+b"));
- if (!fp) {
+ part_fd = topen(part_name, O_WRONLY);
+ if (part_fd == INVALID_FILEDES) {
ERROR_WITH_ERRNO("Failed to open `%"TS"'", part_name);
ret = WIMLIB_ERR_OPEN;
goto out;
}
- u8 buf[4];
- put_u16(&buf[0], i);
- put_u16(&buf[2], total_parts);
-
- if (fseek(fp, 40, SEEK_SET) != 0 ||
- fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf) ||
- fclose(fp) != 0)
- {
- ERROR_WITH_ERRNO("Error overwriting header of `%"TS"'",
+ put_u16(&part_data_buf[0], i);
+ put_u16(&part_data_buf[2], total_parts);
+
+ bytes_written = full_pwrite(part_fd, part_data_buf,
+ sizeof(part_data_buf), 40);
+ ret = close(part_fd);
+ if (bytes_written != sizeof(part_data_buf) || ret != 0) {
+ ERROR_WITH_ERRNO("Error updating header of `%"TS"'",
part_name);
ret = WIMLIB_ERR_WRITE;
- break;
+ goto out;
}
}
+ ret = 0;
out:
close_wim_writable(w);
memcpy(&w->hdr, &hdr_save, sizeof(struct wim_header));
#include <string.h>
#define _GNU_SOURCE
-#include <unistd.h>
-#include "wimlib_internal.h"
#include "endianness.h"
#include "timestamp.h"
+#include "wimlib_internal.h"
#include <ctype.h>
#include <errno.h>
-#include <stdlib.h>
#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
#ifdef __WIN32__
#include "win32.h"
}
}
-/* Write @n bytes from @buf to the file descriptor @fd, retrying on internupt
- * and on short writes.
- *
- * Returns short count and set errno on failure. */
+/* Like read(), but keep trying until everything has been written or we know for
+ * sure that there was an error (or end-of-file). */
size_t
-full_write(int fd, const void *buf, size_t n)
+full_read(int fd, void *buf, size_t count)
{
- const void *p = buf;
- ssize_t ret;
- ssize_t total = 0;
+ ssize_t bytes_read;
+ size_t bytes_remaining;
- while (total != n) {
- ret = write(fd, p, n);
- if (ret <= 0) {
- if (errno == EINTR)
- continue;
- if (ret == 0)
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_read, buf += bytes_read)
+ {
+ bytes_read = read(fd, buf, bytes_remaining);
+ if (bytes_read <= 0) {
+ if (bytes_read == 0)
errno = EIO;
+ else if (errno == EINTR)
+ continue;
break;
}
- total += ret;
- p += ret;
}
- return total;
+ return count - bytes_remaining;
}
-/* Read @n bytes from the file descriptor @fd to the buffer @buf, retrying on
- * interrupt and on short reads.
- *
- * Returns short count and set errno on failure. */
+/* Like write(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
size_t
-full_read(int fd, void *buf, size_t n)
+full_write(int fd, const void *buf, size_t count)
{
- size_t bytes_remaining = n;
- while (bytes_remaining) {
- ssize_t bytes_read = read(fd, buf, bytes_remaining);
- if (bytes_read <= 0) {
+ ssize_t bytes_written;
+ size_t bytes_remaining;
+
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_written, buf += bytes_written)
+ {
+ bytes_written = write(fd, buf, bytes_remaining);
+ if (bytes_written < 0) {
if (errno == EINTR)
continue;
- if (bytes_read == 0)
- errno = EIO;
break;
}
- bytes_remaining -= bytes_read;
- buf += bytes_read;
}
- return n - bytes_remaining;
+ return count - bytes_remaining;
}
-/* Read @n bytes from the file descriptor @fd at the offset @offset to the
- * buffer @buf, retrying on interrupt and on short reads.
- *
- * Returns short count and set errno on failure. */
+/* Like pread(), but keep trying until everything has been read or we know for
+ * sure that there was an error (or end-of-file) */
size_t
-full_pread(int fd, void *buf, size_t nbyte, off_t offset)
+full_pread(int fd, void *buf, size_t count, off_t offset)
{
- size_t bytes_remaining = nbyte;
ssize_t bytes_read;
+ size_t bytes_remaining;
- while (bytes_remaining) {
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_read, buf += bytes_read,
+ offset += bytes_read)
+ {
bytes_read = pread(fd, buf, bytes_remaining, offset);
if (bytes_read <= 0) {
- if (errno == EINTR)
- continue;
if (bytes_read == 0)
errno = EIO;
+ else if (errno == EINTR)
+ continue;
break;
}
- bytes_remaining -= bytes_read;
- buf += bytes_read;
- offset += bytes_read;
}
- return nbyte - bytes_remaining;
+ return count - bytes_remaining;
}
/* Like pwrite(), but keep trying until everything has been written or we know
size_t
full_pwrite(int fd, const void *buf, size_t count, off_t offset)
{
- ssize_t bytes_remaining = count;
ssize_t bytes_written;
+ size_t bytes_remaining;
- while (bytes_remaining > 0) {
+ for (bytes_remaining = count;
+ bytes_remaining != 0;
+ bytes_remaining -= bytes_written, buf += bytes_written,
+ offset += bytes_written)
+ {
bytes_written = pwrite(fd, buf, bytes_remaining, offset);
- if (bytes_written <= 0) {
+ if (bytes_written < 0) {
if (errno == EINTR)
continue;
- if (bytes_written == 0)
- errno = EIO;
break;
}
- bytes_remaining -= bytes_written;
- buf += bytes_written;
- offset += bytes_written;
}
return count - bytes_remaining;
}
+/* Like writev(), but keep trying until everything has been written or we know
+ * for sure that there was an error. */
+size_t
+full_writev(int fd, struct iovec *iov, int iovcnt)
+{
+ size_t total_bytes_written = 0;
+ while (iovcnt > 0) {
+ ssize_t bytes_written;
+
+ bytes_written = writev(fd, iov, iovcnt);
+ if (bytes_written < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ total_bytes_written += bytes_written;
+ while (bytes_written) {
+ if (bytes_written >= iov[0].iov_len) {
+ bytes_written -= iov[0].iov_len;
+ iov++;
+ iovcnt--;
+ } else {
+ iov[0].iov_base += bytes_written;
+ iov[0].iov_len -= bytes_written;
+ bytes_written = 0;
+ }
+ }
+ }
+ return total_bytes_written;
+}
off_t
filedes_offset(filedes_t fd)
full_pread(filedes_t fd, void *buf, size_t nbyte, off_t offset);
extern size_t
-full_pwrite(int fd, const void *buf, size_t count, off_t offset);
+full_pwrite(filedes_t fd, const void *buf, size_t count, off_t offset);
+
+struct iovec;
+
+extern size_t
+full_writev(int fd, struct iovec *iov, int iovcnt);
extern off_t
filedes_offset(filedes_t fd);
new_wim_struct()
{
WIMStruct *w = CALLOC(1, sizeof(WIMStruct));
- w->in_fd = INVALID_FILEDES;
- w->out_fd = INVALID_FILEDES;
- w->current_image = WIMLIB_NO_IMAGE;
+ if (w) {
+ w->in_fd = INVALID_FILEDES;
+ w->out_fd = INVALID_FILEDES;
+ }
return w;
}
{
int fd;
- fd = open(filename, O_RDONLY);
- if (fd == -1) {
+ fd = topen(filename, O_RDONLY);
+ if (fd == INVALID_FILEDES) {
ERROR_WITH_ERRNO("Can't open \"%"TS"\" read-only", filename);
return WIMLIB_ERR_OPEN;
}
int
close_wim(WIMStruct *w)
{
- close(w->in_fd);
- w->in_fd = INVALID_FILEDES;
+ if (w->in_fd != INVALID_FILEDES) {
+ close(w->in_fd);
+ w->in_fd = INVALID_FILEDES;
+ }
return 0;
}
* not been opened or there is no associated file backing it yet. */
filedes_t in_fd;
- /* FILE pointer for the WIM file (if any) currently being written. */
+ /* File descriptor, opened either for writing only or for
+ * reading+writing, for the WIM file (if any) currently being written.
+ * */
filedes_t out_fd;
/* The name of the WIM file (if any) that has been opened. */
return 0;
} else {
/* As usual, the possible error values are not documented */
- DWORD err = GetLastError();
- ERROR("MoveFileEx(): Can't rename \"%ls\" to \"%ls\"",
- oldpath, newpath);
- win32_error(err);
errno = -1;
return -1;
}
#include <limits.h>
-#include <sys/uio.h> /* writev() */
-
/* Chunk table that's located at the beginning of each compressed resource in
* the WIM. (This is not the on-disk format; the on-disk format just has an
* array of offsets.) */
*
* @chunk: Uncompressed data of the chunk.
* @chunk_size: Size of the chunk (<= WIM_CHUNK_SIZE)
- * @out_fd: FILE descriptor to write the chunk to.
+ * @out_fd: File descriptor to write the chunk to.
* @compress: Compression function to use (NULL if writing uncompressed
* data).
* @chunk_tab: Pointer to chunk table being created. It is updated with the
* @lte: Lookup table entry for the resource, which could be in another WIM,
* in an external file, or in another location.
*
- * @out_fp: File descriptor opened to the output WIM.
+ * @out_fd: File descriptor opened to the output WIM.
*
* @out_ctype: One of the WIMLIB_COMPRESSION_TYPE_* constants to indicate
* which compression algorithm to use.
write_wim_chunks(struct message *msg, filedes_t out_fd,
struct chunk_table *chunk_tab)
{
- ssize_t bytes_remaining = msg->total_out_bytes;
- struct iovec *vecs = msg->out_chunks;
- unsigned nvecs = msg->num_chunks;
- int ret;
-
- wimlib_assert(nvecs != 0);
- wimlib_assert(msg->total_out_bytes != 0);
-
for (unsigned i = 0; i < msg->num_chunks; i++) {
*chunk_tab->cur_offset_p++ = chunk_tab->cur_offset;
- chunk_tab->cur_offset += vecs[i].iov_len;
- }
- for (;;) {
- ssize_t bytes_written;
-
- bytes_written = writev(out_fd, vecs, nvecs);
- if (bytes_written <= 0) {
- if (bytes_written < 0 && errno == EINTR)
- continue;
- else if (bytes_written == 0)
- errno = EIO;
- ERROR_WITH_ERRNO("Failed to write WIM chunks");
- ret = WIMLIB_ERR_WRITE;
- break;
- }
- bytes_remaining -= bytes_written;
- if (bytes_remaining <= 0) {
- ret = 0;
- break;
- }
- while (bytes_written >= 0) {
- wimlib_assert(nvecs != 0);
- if (bytes_written >= vecs[0].iov_len) {
- vecs++;
- nvecs--;
- bytes_written -= vecs[0].iov_len;
- } else {
- vecs[0].iov_base += bytes_written;
- vecs[0].iov_len -= bytes_written;
- bytes_written = 0;
- }
- }
+ chunk_tab->cur_offset += msg->out_chunks[i].iov_len;
}
- return ret;
+ if (full_writev(out_fd, msg->out_chunks,
+ msg->num_chunks) != msg->total_out_bytes)
+ {
+ ERROR_WITH_ERRNO("Failed to write WIM chunks");
+ return WIMLIB_ERR_WRITE;
+ }
+ return 0;
}
struct main_writer_thread_ctx {
return ret;
}
-/* Writes the streams for the specified @image in @wim to @wim->out_fp.
+/* Writes the streams for the specified @image in @wim to @wim->out_fd.
*/
static int
write_wim_streams(WIMStruct *wim, int image, int write_flags,
static int
open_wim_writable(WIMStruct *w, const tchar *path, int open_flags)
{
- wimlib_assert(w->out_fd == INVALID_FILEDES);
w->out_fd = open(path, open_flags, 0644);
if (w->out_fd == INVALID_FILEDES) {
ERROR_WITH_ERRNO("Failed to open `%"TS"' for writing", path);
ret = write_header(&w->hdr, w->out_fd);
if (ret)
return ret;
- if (lseek(w->out_fd, 0, SEEK_END) == -1) {
- ERROR_WITH_ERRNO("Failed to seek to end of WIM");
+ if (lseek(w->out_fd, WIM_HEADER_DISK_SIZE, SEEK_SET) == -1) {
+ ERROR_WITH_ERRNO("Failed to seek to end of WIM header");
return WIMLIB_ERR_WRITE;
}
return 0;
goto out_unlink;
}
- DEBUG("Renaming `%"TS"' to `%"TS"'", tmpfile, w->filename);
-
-#ifdef __WIN32__
- /* Windows won't let you delete open files unless FILE_SHARE_DELETE was
- * specified to CreateFile(). The WIM was opened with fopen(), which
- * didn't provided this flag to CreateFile, so the handle must be closed
- * before executing the rename(). */
- if (w->fp != NULL) {
- fclose(w->fp);
- w->fp = NULL;
- }
-#endif
+ close_wim(w);
+ DEBUG("Renaming `%"TS"' to `%"TS"'", tmpfile, w->filename);
/* Rename the new file to the old file .*/
if (trename(tmpfile, w->filename) != 0) {
ERROR_WITH_ERRNO("Failed to rename `%"TS"' to `%"TS"'",
# define tputs _putws
# define tfputs fputws
# define tfopen _wfopen
+# define topen _wopen
# define tstat _wstati64
# define tstrtol wcstol
# define tstrtod wcstod
# define tputs puts
# define tfputs fputs
# define tfopen fopen
+# define topen open
# define tstat stat
# define tunlink unlink
# define tstrerror strerror