Only the most important changes more recent than version 0.6 are noted here.
Version 1.3.0:
- Added experimental support for native Windows builds.
+ Added experimental support for native Windows builds. Binaries can be
+ downloaded from the SourceForge page.
--source-list option added to `imagex capture' and `imagex append'.
static int
pattern_list_add_pattern(struct pattern_list *list, const mbchar *pattern)
{
- const char **pats;
+ const mbchar **pats;
if (list->num_pats >= list->num_allocated_pats) {
pats = REALLOC(list->pats,
sizeof(list->pats[0]) * (list->num_allocated_pats + 8));
const struct pattern_list *list)
{
for (size_t i = 0; i < list->num_pats; i++) {
- const char *pat = list->pats[i];
- const char *string;
+ const mbchar *pat = list->pats[i];
+ const mbchar *string;
if (pat[0] == '/')
/* Absolute path from root of capture */
string = path;
attach_branch(struct wim_dentry **root_p, struct wim_dentry *branch,
mbchar *target_path)
{
- char *slash;
+ mbchar *slash;
struct wim_dentry *dentry, *parent, *target;
int ret;
if (!source || !*source)
return WIMLIB_ERR_INVALID_PARAM;
- char *fs_source_path = STRDUP(source);
+ mbchar *fs_source_path = STRDUP(source);
int ret;
struct wimlib_capture_source capture_src = {
.fs_source_path = fs_source_path,
WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim,
int src_image,
WIMStruct *dest_wim,
- const char *dest_name,
- const char *dest_description,
+ const utf8char *dest_name,
+ const utf8char *dest_description,
int export_flags,
WIMStruct **additional_swms,
unsigned num_additional_swms,
/* Extracts a single image or all images from a WIM file to a directory or NTFS
* volume. */
-WIMLIBAPI int wimlib_extract_image(WIMStruct *w,
- int image,
- const char *target,
- int extract_flags,
- WIMStruct **additional_swms,
- unsigned num_additional_swms,
- wimlib_progress_func_t progress_func)
+WIMLIBAPI int
+wimlib_extract_image(WIMStruct *w,
+ int image,
+ const mbchar *target,
+ int extract_flags,
+ WIMStruct **additional_swms,
+ unsigned num_additional_swms,
+ wimlib_progress_func_t progress_func)
{
struct wim_lookup_table *joined_tab, *w_tab_save;
int ret;
'M', 'S', 'W', 'I', 'M', '\0', '\0', '\0' };
/* Reads the header for a WIM file. */
-int read_header(FILE *fp, struct wim_header *hdr, int open_flags)
+int
+read_header(FILE *fp, struct wim_header *hdr, int open_flags)
{
size_t bytes_read;
u8 buf[WIM_HEADER_DISK_SIZE];
* place (the beginning of the file).
* @return: Zero on success, nonzero on failure.
*/
-int write_header(const struct wim_header *hdr, FILE *out_fp)
+int
+write_header(const struct wim_header *hdr, FILE *out_fp)
{
u8 buf[WIM_HEADER_DISK_SIZE];
u8 *p;
/*
* Initializes the header for a WIM file.
*/
-int init_header(struct wim_header *hdr, int ctype)
+int
+init_header(struct wim_header *hdr, int ctype)
{
memset(hdr, 0, sizeof(struct wim_header));
switch (ctype) {
};
/* Prints information from the header of the WIM file associated with @w. */
-WIMLIBAPI void wimlib_print_header(const WIMStruct *w)
+WIMLIBAPI void
+wimlib_print_header(const WIMStruct *w)
{
const struct wim_header *hdr = &w->hdr;
* were no inconsistencies.
* -1 (WIM_INTEGRITY_NOT_OK) if the WIM failed the integrity check.
*/
-static int verify_integrity(FILE *fp, const char *filename,
+static int verify_integrity(FILE *fp, const mbchar *filename,
const struct integrity_table *table,
u64 bytes_to_check,
wimlib_progress_func_t progress_func)
#include "xml.h"
#include <stdlib.h>
-static int move_lte_to_table(struct wim_lookup_table_entry *lte,
- void *other_tab)
+static int
+move_lte_to_table(struct wim_lookup_table_entry *lte, void *other_tab)
{
hlist_del(<e->hash_list);
lookup_table_insert((struct wim_lookup_table*)other_tab, lte);
return 0;
}
-static int lookup_table_join(struct wim_lookup_table *table,
- struct wim_lookup_table *new)
+static int
+lookup_table_join(struct wim_lookup_table *table,
+ struct wim_lookup_table *new)
{
return for_lookup_table_entry(new, move_lte_to_table, table);
}
* The reason we join the lookup tables is so we only have to search one lookup
* table to find the location of a resource in the entire WIM.
*/
-int new_joined_lookup_table(WIMStruct *w,
- WIMStruct **additional_swms,
- unsigned num_additional_swms,
- struct wim_lookup_table **table_ret)
+int
+new_joined_lookup_table(WIMStruct *w,
+ WIMStruct **additional_swms,
+ unsigned num_additional_swms,
+ struct wim_lookup_table **table_ret)
{
struct wim_lookup_table *table;
int ret;
}
-static int join_wims(WIMStruct **swms, unsigned num_swms,
- WIMStruct *joined_wim, int write_flags,
- wimlib_progress_func_t progress_func)
+static int
+join_wims(WIMStruct **swms, unsigned num_swms,
+ WIMStruct *joined_wim, int write_flags,
+ wimlib_progress_func_t progress_func)
{
int ret;
unsigned i;
return ret;
}
-static int cmp_swms_by_part_number(const void *swm1, const void *swm2)
+static int
+cmp_swms_by_part_number(const void *swm1, const void *swm2)
{
u16 partno_1 = (*(const WIMStruct**)swm1)->hdr.part_number;
u16 partno_2 = (*(const WIMStruct**)swm2)->hdr.part_number;
/*
* Join a set of split WIMs into a stand-alone WIM.
*/
-WIMLIBAPI int wimlib_join(const char * const *swm_names, unsigned num_swms,
- const char *output_path, int swm_open_flags,
- int wim_write_flags,
- wimlib_progress_func_t progress_func)
+WIMLIBAPI int
+wimlib_join(const mbchar * const *swm_names, unsigned num_swms,
+ const mbchar *output_path, int swm_open_flags,
+ int wim_write_flags,
+ wimlib_progress_func_t progress_func)
{
int ret;
WIMStruct *joined_wim = NULL;
off_t size,
struct wimfs_context *ctx)
{
- char *staging_file_name;
+ mbchar *staging_file_name;
int ret;
int fd;
struct wim_lookup_table_entry *old_lte, *new_lte;
void **mailbox_ret)
{
long msgsize;
- char *mailbox;
+ void *mailbox;
msgsize = mq_get_msgsize(mq);
#ifdef ENABLE_XATTR
/* Remove an alternate data stream through the XATTR interface */
static int
-wimfs_removexattr(const char *path, const mbchar *name)
+wimfs_removexattr(const mbchar *path, const mbchar *name)
{
struct wim_inode *inode;
struct wim_ads_entry *ads_entry;
const mbchar *staging_dir)
{
int argc;
- char *argv[16];
+ mbchar *argv[16];
int ret;
mbchar *dir_copy;
struct wim_lookup_table *joined_tab, *wim_tab_save;
/*
* We provide the use_ino option to the FUSE mount because we are going
* to assign inode numbers ourselves. */
- char optstring[256] =
+ mbchar optstring[256] =
"use_ino"
",subtype=wimfs"
",attr_timeout=0"
};
static int
-build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p, ntfs_inode *dir_ni,
- ntfs_inode *ni, char path[], size_t path_len,
+build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p,
+ ntfs_inode *dir_ni,
+ ntfs_inode *ni,
+ mbchar *path,
+ size_t path_len,
int name_type,
struct wim_lookup_table *lookup_table,
struct sd_set *sd_set,
{
struct readdir_ctx *ctx;
size_t mbs_name_nbytes;
- char *mbs_name;
+ mbchar *mbs_name;
struct wim_dentry *child;
int ret;
size_t path_len;
struct split_args {
WIMStruct *w;
- char *swm_base_name;
+ mbchar *swm_base_name;
size_t swm_base_name_len;
- const char *swm_suffix;
+ const mbchar *swm_suffix;
struct list_head lte_list;
int cur_part_number;
int write_flags;
union wimlib_progress_info progress;
};
-static int finish_swm(WIMStruct *w, struct list_head *lte_list,
- int write_flags, wimlib_progress_func_t progress_func)
+static int
+finish_swm(WIMStruct *w, struct list_head *lte_list,
+ int write_flags, wimlib_progress_func_t progress_func)
{
off_t lookup_table_offset = ftello(w->out_fp);
int ret;
progress_func);
}
-static int copy_resource_to_swm(struct wim_lookup_table_entry *lte, void *__args)
+static int
+copy_resource_to_swm(struct wim_lookup_table_entry *lte, void *__args)
{
struct split_args *args = (struct split_args*)__args;
WIMStruct *w = args->w;
/* Splits the WIM file @w into multiple parts prefixed by @swm_name with size at
* most @part_size bytes. */
-WIMLIBAPI int wimlib_split(WIMStruct *w, const char *swm_name,
- size_t part_size, int write_flags,
- wimlib_progress_func_t progress_func)
+WIMLIBAPI int
+wimlib_split(WIMStruct *w, const mbchar *swm_name,
+ size_t part_size, int write_flags,
+ wimlib_progress_func_t progress_func)
{
int ret;
struct wim_header hdr_save;
struct split_args args;
- const char *swm_suffix;
+ const mbchar *swm_suffix;
size_t swm_name_len;
size_t swm_base_name_len;
write_flags &= WIMLIB_WRITE_MASK_PUBLIC;
swm_name_len = strlen(swm_name);
- char swm_base_name[swm_name_len + 20];
+ mbchar swm_base_name[swm_name_len + 20];
memcpy(&hdr_save, &w->hdr, sizeof(struct wim_header));
w->hdr.flags |= WIM_HDR_FLAG_SPANNED;
* parts until they are all written). Fix them. */
int total_parts = args.cur_part_number;
for (int i = 1; i <= total_parts; i++) {
- const char *part_name;
+ const mbchar *part_name;
if (i == 1) {
part_name = swm_name;
} else {
{
struct wim_dentry *child;
- char *mbs_name;
+ mbchar *mbs_name;
size_t mbs_name_nbytes;
ret = utf16le_to_mbs(dat.cFileName,
wcslen(dat.cFileName) * sizeof(wchar_t),
if (ret)
goto out_find_close;
- char name[strlen(root_disk_path) + 1 + mbs_name_nbytes + 1];
+ mbchar name[strlen(root_disk_path) + 1 + mbs_name_nbytes + 1];
sprintf(name, "%s/%s", root_disk_path, mbs_name);
FREE(mbs_name);
ret = win32_build_dentry_tree(&child, name, lookup_table,
win32_capture_reparse_point(HANDLE hFile,
struct wim_inode *inode,
struct wim_lookup_table *lookup_table,
- const char *path)
+ const mbchar *path)
{
/* "Reparse point data, including the tag and optional GUID,
* cannot exceed 16 kilobytes." - MSDN */
is_named_stream = (p != colon);
if (is_named_stream) {
/* Allocate an ADS entry for the named stream. */
- char *mbs_stream_name;
+ mbchar *mbs_stream_name;
size_t mbs_stream_name_nbytes;
ret = utf16le_to_mbs(p,
(colon - p) * sizeof(wchar_t),
/* Win32 version of capturing a directory tree */
int
win32_build_dentry_tree(struct wim_dentry **root_ret,
- const char *root_disk_path,
+ const mbchar *root_disk_path,
struct wim_lookup_table *lookup_table,
struct wim_security_data *sd,
const struct capture_config *config,
strcpy(buf, "Unknown");
return buf;
}
+
+/* rename() on Windows fails if the destination file exists. Fix it. */
+int
+rename_replacement(const char *oldpath, const char *newpath)
+{
+ if (MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING)) {
+ return 0;
+ } else {
+ /* As usual, the possible error values are not documented */
+ DWORD err = GetLastError();
+ ERROR("MoveFileExA(): Can't rename \"%s\" to \"%s\"",
+ oldpath, newpath);
+ win32_error(err);
+ errno = 0;
+ return -1;
+ }
+}
extern char *
nl_langinfo(nl_item item);
+extern int rename_replacement(const char *oldpath, const char *newpath);
+#define rename(oldpath, newpath) rename_replacement(oldpath, newpath)
+
#endif /* _WIMLIB_WIN32_H */
#endif
#ifdef __WIN32__
-# include <win32.h>
+# include "win32.h"
#endif
#include "list.h"
#include "lzx.h"
#include "xpress.h"
+
#ifdef ENABLE_MULTITHREADED_COMPRESSION
# include <pthread.h>
#endif
DEBUG("Renaming `%s' to `%s'", 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
+
/* Rename the new file to the old file .*/
if (rename(tmpfile, w->filename) != 0) {
ERROR_WITH_ERRNO("Failed to rename `%s' to `%s'",
node_get_string(const xmlNode *string_node, utf8char **str)
{
xmlNode *child;
- char *p = NULL;
+ utf8char *p = NULL;
for_node_child(string_node, child) {
if (node_is_text(child) && child->content) {
print_image_info(const struct wim_info *wim_info, int image)
{
const struct image_info *image_info;
- const char *desc;
+ const utf8char *desc;
char buf[50];
wimlib_assert(image >= 1 && image <= wim_info->num_images);
WIMLIBAPI int
wimlib_set_image_flags(WIMStruct *w, int image, const utf8char *flags)
{
- char *p;
+ utf8char *p;
if (image < 1 || image > w->hdr.image_count) {
ERROR("%d is not a valid image", image);