Replace rename()
authorEric Biggers <ebiggers3@gmail.com>
Thu, 21 Mar 2013 04:53:27 +0000 (23:53 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Thu, 21 Mar 2013 04:53:27 +0000 (23:53 -0500)
14 files changed:
NEWS
src/add_image.c
src/export_image.c
src/extract_image.c
src/header.c
src/integrity.c
src/join.c
src/mount_image.c
src/ntfs-capture.c
src/split.c
src/win32.c
src/win32.h
src/write.c
src/xml.c

diff --git a/NEWS b/NEWS
index ad68f6a..0dd16bc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,8 @@
 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'.
 
index 7c9199c..cf89e69 100644 (file)
@@ -452,7 +452,7 @@ destroy_capture_config(struct capture_config *config)
 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));
@@ -584,8 +584,8 @@ static bool match_pattern(const mbchar *path,
                          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;
@@ -841,7 +841,7 @@ static int
 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;
 
@@ -1123,7 +1123,7 @@ wimlib_add_image(WIMStruct *w,
        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,
index ff80eec..e291ec1 100644 (file)
@@ -95,8 +95,8 @@ static void inode_move_ltes_to_table(struct wim_inode *inode,
 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,
index d637a10..963f40c 100644 (file)
@@ -922,13 +922,14 @@ extract_all_images(WIMStruct *w, const mbchar *target,
 
 /* 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;
index 7ac8416..8dcfcde 100644 (file)
@@ -32,7 +32,8 @@ static const u8 wim_magic_chars[WIM_MAGIC_LEN] = {
                        '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];
@@ -169,7 +170,8 @@ err:
  *             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;
@@ -207,7 +209,8 @@ int write_header(const struct wim_header *hdr, FILE *out_fp)
 /*
  * 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) {
@@ -251,7 +254,8 @@ struct hdr_flag hdr_flags[] = {
 };
 
 /* 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;
 
index f42133f..e977055 100644 (file)
@@ -454,7 +454,7 @@ out_free_old_table:
  *     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)
index 4d05905..205c68d 100644 (file)
 #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(&lte->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);
 }
@@ -56,10 +57,11 @@ static int lookup_table_join(struct wim_lookup_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;
@@ -85,9 +87,10 @@ out_free_table:
 }
 
 
-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;
@@ -150,7 +153,8 @@ static int join_wims(WIMStruct **swms, unsigned num_swms,
        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;
@@ -160,10 +164,11 @@ static int cmp_swms_by_part_number(const void *swm1, const void *swm2)
 /*
  * 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;
index fc5fa45..1e0ec76 100644 (file)
@@ -542,7 +542,7 @@ extract_resource_to_staging_dir(struct wim_inode *inode,
                                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;
@@ -1051,7 +1051,7 @@ get_mailbox(mqd_t mq, long needed_msgsize, long *msgsize_ret,
            void **mailbox_ret)
 {
        long msgsize;
-       char *mailbox;
+       void *mailbox;
 
        msgsize = mq_get_msgsize(mq);
 
@@ -2093,7 +2093,7 @@ wimfs_releasedir(const mbchar *path, struct fuse_file_info *fi)
 #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;
@@ -2480,7 +2480,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const mbchar *dir,
                   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;
@@ -2594,7 +2594,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const mbchar *dir,
        /*
         * 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"
index 5b6e315..da79448 100644 (file)
@@ -403,8 +403,11 @@ struct readdir_ctx {
 };
 
 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,
@@ -421,7 +424,7 @@ wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
 {
        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;
index 55b51fe..6b842f6 100644 (file)
@@ -30,9 +30,9 @@
 
 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;
@@ -42,8 +42,9 @@ struct split_args {
        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;
@@ -70,7 +71,8 @@ static int finish_swm(WIMStruct *w, struct list_head *lte_list,
                            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;
@@ -123,14 +125,15 @@ static int copy_resource_to_swm(struct wim_lookup_table_entry *lte, void *__args
 
 /* 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;
 
@@ -143,7 +146,7 @@ WIMLIBAPI int wimlib_split(WIMStruct *w, const char *swm_name,
        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;
@@ -216,7 +219,7 @@ WIMLIBAPI int wimlib_split(WIMStruct *w, const char *swm_name,
         * 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 {
index 12d0afe..6d3951f 100644 (file)
@@ -242,7 +242,7 @@ win32_recurse_directory(struct wim_dentry *root,
                {
                        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),
@@ -251,7 +251,7 @@ win32_recurse_directory(struct wim_dentry *root,
                        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,
@@ -294,7 +294,7 @@ static int
 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  */
@@ -414,7 +414,7 @@ win32_capture_stream(const wchar_t *path_utf16,
        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),
@@ -562,7 +562,7 @@ out_find_close:
 /* 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,
@@ -1203,3 +1203,20 @@ nl_langinfo(nl_item item)
        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;
+       }
+}
index 87070a4..518b30e 100644 (file)
@@ -73,4 +73,7 @@ typedef enum {
 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 */
index 27b1dbb..8355a28 100644 (file)
@@ -33,7 +33,7 @@
 #endif
 
 #ifdef __WIN32__
-#  include <win32.h>
+#  include "win32.h"
 #endif
 
 #include "list.h"
@@ -45,6 +45,7 @@
 #include "lzx.h"
 #include "xpress.h"
 
+
 #ifdef ENABLE_MULTITHREADED_COMPRESSION
 #  include <pthread.h>
 #endif
@@ -1981,6 +1982,17 @@ overwrite_wim_via_tmpfile(WIMStruct *w, int write_flags,
 
        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'",
index 79d6b3e..268b9d9 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -155,7 +155,7 @@ static int
 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) {
@@ -1164,7 +1164,7 @@ void
 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);
@@ -1555,7 +1555,7 @@ wimlib_set_image_descripton(WIMStruct *w, int image,
 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);