From 541b65d79e0c73238a25e2c2661711d8593d0684 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 20 Mar 2013 23:53:27 -0500 Subject: [PATCH] Replace rename() --- NEWS | 3 ++- src/add_image.c | 10 +++++----- src/export_image.c | 4 ++-- src/extract_image.c | 15 ++++++++------- src/header.c | 12 ++++++++---- src/integrity.c | 2 +- src/join.c | 37 +++++++++++++++++++++---------------- src/mount_image.c | 10 +++++----- src/ntfs-capture.c | 9 ++++++--- src/split.c | 25 ++++++++++++++----------- src/win32.c | 27 ++++++++++++++++++++++----- src/win32.h | 3 +++ src/write.c | 14 +++++++++++++- src/xml.c | 6 +++--- 14 files changed, 113 insertions(+), 64 deletions(-) diff --git a/NEWS b/NEWS index ad68f6ac..0dd16bce 100644 --- 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'. diff --git a/src/add_image.c b/src/add_image.c index 7c9199c9..cf89e695 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -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, diff --git a/src/export_image.c b/src/export_image.c index ff80eec3..e291ec14 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -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, diff --git a/src/extract_image.c b/src/extract_image.c index d637a106..963f40c7 100644 --- a/src/extract_image.c +++ b/src/extract_image.c @@ -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; diff --git a/src/header.c b/src/header.c index 7ac84160..8dcfcdea 100644 --- a/src/header.c +++ b/src/header.c @@ -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; diff --git a/src/integrity.c b/src/integrity.c index f42133fc..e977055d 100644 --- a/src/integrity.c +++ b/src/integrity.c @@ -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) diff --git a/src/join.c b/src/join.c index 4d059050..205c68d1 100644 --- a/src/join.c +++ b/src/join.c @@ -28,16 +28,17 @@ #include "xml.h" #include -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); } @@ -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; diff --git a/src/mount_image.c b/src/mount_image.c index fc5fa45e..1e0ec76f 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -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" diff --git a/src/ntfs-capture.c b/src/ntfs-capture.c index 5b6e315c..da794480 100644 --- a/src/ntfs-capture.c +++ b/src/ntfs-capture.c @@ -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; diff --git a/src/split.c b/src/split.c index 55b51fe9..6b842f6c 100644 --- a/src/split.c +++ b/src/split.c @@ -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 { diff --git a/src/win32.c b/src/win32.c index 12d0afee..6d3951f5 100644 --- a/src/win32.c +++ b/src/win32.c @@ -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; + } +} diff --git a/src/win32.h b/src/win32.h index 87070a4a..518b30e6 100644 --- a/src/win32.h +++ b/src/win32.h @@ -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 */ diff --git a/src/write.c b/src/write.c index 27b1dbbe..8355a283 100644 --- a/src/write.c +++ b/src/write.c @@ -33,7 +33,7 @@ #endif #ifdef __WIN32__ -# include +# include "win32.h" #endif #include "list.h" @@ -45,6 +45,7 @@ #include "lzx.h" #include "xpress.h" + #ifdef ENABLE_MULTITHREADED_COMPRESSION # include #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'", diff --git a/src/xml.c b/src/xml.c index 79d6b3e6..268b9d9e 100644 --- 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); -- 2.43.0