Character encoding changes (IN PROGRESS)
authorEric Biggers <ebiggers3@gmail.com>
Wed, 20 Mar 2013 05:35:52 +0000 (00:35 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Wed, 20 Mar 2013 05:35:52 +0000 (00:35 -0500)
19 files changed:
src/add_image.c
src/buffer_io.h
src/dentry.c
src/dentry.h
src/encoding.c
src/lookup_table.c
src/lookup_table.h
src/mount_image.c
src/ntfs-apply.c
src/ntfs-capture.c
src/resource.c
src/symlink.c
src/util.c
src/util.h
src/verify.c
src/wim.c
src/wimlib_internal.h
src/write.c
src/xml.c

index 4dce5bb..0d410a1 100644 (file)
@@ -214,16 +214,10 @@ unix_build_dentry_tree(struct wim_dentry **root_ret,
                goto out;
        }
 
-       root = new_dentry_with_timeless_inode(path_basename(root_disk_path));
-       if (!root) {
-               if (errno == EILSEQ)
-                       ret = WIMLIB_ERR_INVALID_UTF8_STRING;
-               else if (errno == ENOMEM)
-                       ret = WIMLIB_ERR_NOMEM;
-               else
-                       ret = WIMLIB_ERR_ICONV_NOT_AVAILABLE;
+       ret = new_dentry_with_timeless_inode(path_basename(root_disk_path),
+                                            &root);
+       if (ret)
                goto out;
-       }
 
        inode = root->d_inode;
 
@@ -777,19 +771,21 @@ check_sorted_sources(struct wimlib_capture_source *sources, size_t num_sources,
 
 /* Creates a new directory to place in the WIM image.  This is to create parent
  * directories that are not part of any target as needed.  */
-static struct wim_dentry *
-new_filler_directory(const mbchar *name)
+static int
+new_filler_directory(const mbchar *name, struct wim_dentry **dentry_ret)
 {
+       int ret;
        struct wim_dentry *dentry;
+
        DEBUG("Creating filler directory \"%s\"", name);
-       dentry = new_dentry_with_inode(name);
-       if (dentry) {
+       ret = new_dentry_with_inode(name, &dentry);
+       if (ret == 0) {
                /* Leave the inode number as 0 for now.  The final inode number
                 * will be assigned later by assign_inode_numbers(). */
                dentry->d_inode->i_resolved = 1;
                dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY;
        }
-       return dentry;
+       return ret;
 }
 
 /* Transfers the children of @branch to @target.  It is an error if @target is
@@ -846,6 +842,7 @@ attach_branch(struct wim_dentry **root_p, struct wim_dentry *branch,
 {
        char *slash;
        struct wim_dentry *dentry, *parent, *target;
+       int ret;
 
        DEBUG("Attaching branch \"%W\" => \"%s\"",
              branch->file_name, target_path);
@@ -865,9 +862,9 @@ attach_branch(struct wim_dentry **root_p, struct wim_dentry *branch,
        /* Adding a non-root branch.  Create root if it hasn't been created
         * already. */
        if (!*root_p) {
-               *root_p = new_filler_directory("");
-               if (!*root_p)
-                       return WIMLIB_ERR_NOMEM;
+               ret  = new_filler_directory("", root_p);
+               if (ret)
+                       return ret;
        }
 
        /* Walk the path to the branch, creating filler directories as needed.
@@ -877,9 +874,9 @@ attach_branch(struct wim_dentry **root_p, struct wim_dentry *branch,
                *slash = '\0';
                dentry = get_dentry_child_with_name(parent, target_path);
                if (!dentry) {
-                       dentry = new_filler_directory(target_path);
-                       if (!dentry)
-                               return WIMLIB_ERR_NOMEM;
+                       ret = new_filler_directory(target_path, &dentry);
+                       if (ret)
+                               return ret;
                        dentry_add_child(parent, dentry);
                }
                parent = dentry;
@@ -894,7 +891,8 @@ attach_branch(struct wim_dentry **root_p, struct wim_dentry *branch,
 
        /* If the target path already existed, overlay the branch onto it.
         * Otherwise, set the branch as the target path. */
-       target = get_dentry_child_with_utf16le_name(parent, branch->file_name);
+       target = get_dentry_child_with_utf16le_name(parent, branch->file_name,
+                                                   branch->file_name_nbytes);
        if (target) {
                return do_overlay(target, branch);
        } else {
@@ -978,8 +976,8 @@ wimlib_add_image_multisource(WIMStruct *w,
        }
 
        if (wimlib_image_name_in_use(w, name)) {
-               ERROR("There is already an image named \"%s\" in `%s'",
-                     name, w->filename);
+               ERROR("There is already an image named \"%U\" in the WIM!",
+                     name);
                return WIMLIB_ERR_IMAGE_NAME_COLLISION;
        }
 
@@ -1012,11 +1010,9 @@ wimlib_add_image_multisource(WIMStruct *w,
 
        DEBUG("Building dentry tree.");
        if (num_sources == 0) {
-               root_dentry = new_filler_directory("");
-               if (!root_dentry) {
-                       ret = WIMLIB_ERR_NOMEM;
+               ret = new_filler_directory("", &root_dentry);
+               if (ret)
                        goto out_free_security_data;
-               }
        } else {
                size_t i;
 
index 685ffa8..9a38286 100644 (file)
  * the output location, with the size indicated in the function name, in little
  * endian format.  A pointer to the input location directly following the bytes
  * read is returned. */
-static inline const u8 *get_u8(const u8 *p, u8 *res)
+static inline const void *
+get_u8(const void *p, u8 *res)
 {
-       *res = *p;
+       *res = *(const u8*)p;
        return p + 1;
 }
 
-
-static inline const u8 *get_u16(const u8 *p, u16 *res)
+static inline const void *
+get_u16(const void *p, u16 *res)
 {
-       *res = le16_to_cpu(*(u16*)p);
+       *res = le16_to_cpu(*(const u16*)p);
        return p + 2;
 }
 
 
 
-static inline const u8 *get_u32(const u8 *p, u32 *res)
+static inline const void *
+get_u32(const void *p, u32 *res)
 {
-       *res = le32_to_cpu(*(u32*)p);
+       *res = le32_to_cpu(*(const u32*)p);
        return p + 4;
 }
 
 
-static inline const u8 *get_u56(const u8 *p, u64 *res)
+static inline const void *
+get_u56(const void *p, u64 *res)
 {
-       *res = le64_to_cpu(*(u64*)p) & 0x00ffffffffffffff;
+       *res = le64_to_cpu(*(const u64*)p) & 0x00ffffffffffffff;
        return p + 7;
 }
 
 
-static inline const u8 *get_u64(const u8 *p, u64 *res)
+static inline const void *
+get_u64(const void *p, u64 *res)
 {
-       *res = le64_to_cpu(*(u64*)p);
+       *res = le64_to_cpu(*(const u64*)p);
        return p + 8;
 }
 
@@ -61,25 +65,29 @@ static inline const u8 *get_u64(const u8 *p, u64 *res)
  * location in little-endian format as the data type indicated in the function
  * name, and a pointer to the output location directory following the bytes
  * written is returned. */
-static inline u8 *put_u8(u8 *res, u8 val)
+static inline void *
+put_u8(void *res, u8 val)
 {
-       *res = val;
+       *(u8*)res = val;
        return res + 1;
 }
 
-static inline u8 *put_u16(u8 *res, u16 val)
+static inline void *
+put_u16(void *res, u16 val)
 {
        *(uint16_t*)res = cpu_to_le16(val);
        return res + 2;
 }
 
-static inline u8 *put_u32(u8 *res, u32 val)
+static inline void *
+put_u32(void *res, u32 val)
 {
        *(uint32_t*)res = cpu_to_le32(val);
        return res + 4;
 }
 
-static inline u8 *put_u56(u8 *res, u64 val)
+static inline void *
+put_u56(void *res, u64 val)
 {
        const u8 *__p = (const u8*)&val;
 #ifdef WORDS_BIGENDIAN
@@ -96,24 +104,28 @@ static inline u8 *put_u56(u8 *res, u64 val)
        return res + 7;
 }
 
-static inline u8 *put_u64(u8 *res, u64 val)
+static inline void *
+put_u64(void *res, u64 val)
 {
        *(u64*)res = cpu_to_le64(val);
        return res + 8;
 }
 
-static inline const u8 *get_bytes(const u8 *p, size_t num_bytes, void *res)
+static inline const void *
+get_bytes(const void *p, size_t num_bytes, void *res)
 {
        memcpy(res, p, num_bytes);
        return p + num_bytes;
 }
 
-static inline u8 *put_zeroes(u8 *p, size_t num_bytes)
+static inline void *
+put_zeroes(void *p, size_t num_bytes)
 {
        return (u8*)memset(p, 0, num_bytes) + num_bytes;
 }
 
-static inline u8 *put_bytes(u8 *p, size_t num_bytes, const void *input)
+static inline void *
+put_bytes(void *p, size_t num_bytes, const void *input)
 {
        return (u8*)memcpy(p, input, num_bytes) + num_bytes;
 }
index ea2cdb1..683a11e 100644 (file)
@@ -89,15 +89,16 @@ get_utf16le_name(const mbchar *name, utf16lechar **name_utf16le_ret,
 
        ret = mbs_to_utf16le(name, strlen(name), &name_utf16le,
                             &name_utf16le_nbytes);
-       if (name_utf16le_nbytes > 0xffff) {
-               FREE(name_utf16le);
-               ERROR("Multibyte string \"%s\" is too long!", name);
-               ret = WIMLIB_ERR_INVALID_UTF8_STRING;
-       }
        if (ret == 0) {
-               FREE(*name_utf16le_ret);
-               *name_utf16le_ret = name_utf16le;
-               *name_utf16le_nbytes_ret = name_utf16le_nbytes;
+               if (name_utf16le_nbytes > 0xffff) {
+                       FREE(name_utf16le);
+                       ERROR("Multibyte string \"%s\" is too long!", name);
+                       ret = WIMLIB_ERR_INVALID_UTF8_STRING;
+               } else {
+                       FREE(*name_utf16le_ret);
+                       *name_utf16le_ret = name_utf16le;
+                       *name_utf16le_nbytes_ret = name_utf16le_nbytes;
+               }
        }
        return ret;
 }
@@ -111,7 +112,7 @@ set_dentry_name(struct wim_dentry *dentry, const mbchar *new_name)
                               &dentry->file_name_nbytes);
        if (ret == 0) {
                /* Clear the short name and recalculate the dentry length */
-               if (dentry->short_name_nbytes) {
+               if (dentry_has_short_name(dentry)) {
                        FREE(dentry->short_name);
                        dentry->short_name = NULL;
                        dentry->short_name_nbytes = 0;
@@ -284,7 +285,6 @@ calculate_dentry_full_path(struct wim_dentry *dentry, void *ignore)
                char *parent_full_path;
                u32 parent_full_path_nbytes;
                const struct wim_dentry *parent;
-               char *name_mbs;
                size_t name_mbs_nbytes;
                int ret;
 
@@ -370,25 +370,36 @@ calculate_subdir_offsets(struct wim_dentry *dentry, u64 *subdir_offset_p)
 }
 
 static int
-dentry_compare_names(const struct wim_dentry *d1, const struct wim_dentry *d2)
+compare_utf16le_names(const utf16lechar *name1, size_t nbytes1,
+                     const utf16lechar *name2, size_t nbytes2)
 {
-       int result = memcmp(d1->file_name, d2->file_name,
-                           min(d1->file_name_nbytes, d2->file_name_nbytes));
+       int result = memcmp(name1, name2, min(nbytes1, nbytes2));
        if (result)
                return result;
        else
-               return d1->file_name_nbytes - d2->file_name_nbytes;
+               return (int)nbytes1 - (int)nbytes2;
+}
+
+static int
+dentry_compare_names(const struct wim_dentry *d1, const struct wim_dentry *d2)
+{
+       return compare_utf16le_names(d1->file_name, d1->file_name_nbytes,
+                                    d2->file_name, d2->file_name_nbytes);
 }
 
 
 struct wim_dentry *
 get_dentry_child_with_utf16le_name(const struct wim_dentry *dentry,
-                                  const utf16lechar *name)
+                                  const utf16lechar *name,
+                                  size_t name_nbytes)
 {
        struct rb_node *node = dentry->d_inode->i_children.rb_node;
+       struct wim_dentry *child;
        while (node) {
-               struct wim_dentry *child = rbnode_dentry(node);
-               int result = dentry_compare_names(dentry, child);
+               child = rbnode_dentry(node);
+               int result = compare_utf16le_names(name, name_nbytes,
+                                                  child->file_name,
+                                                  child->file_name_nbytes);
                if (result < 0)
                        node = node->rb_left;
                else if (result > 0)
@@ -415,7 +426,8 @@ get_dentry_child_with_name(const struct wim_dentry *dentry, const mbchar *name)
                child = NULL;
        } else {
                child = get_dentry_child_with_utf16le_name(dentry,
-                                                          utf16le_name);
+                                                          utf16le_name,
+                                                          utf16le_name_nbytes);
                FREE(utf16le_name);
        }
        return child;
@@ -431,35 +443,31 @@ get_dentry(WIMStruct *w, const mbchar *path)
        int ret;
        struct wim_dentry *cur_dentry, *parent_dentry;
        utf16lechar *p, *pp;
-       utf16lechar save;
 
        ret = mbs_to_utf16le(path, strlen(path), &path_utf16le,
                             &path_utf16le_nbytes);
-       if (ret) {
-               errno = ENOMEM;
+       if (ret)
                return NULL;
-       }
 
        parent_dentry = wim_root_dentry(w);
        p = path_utf16le;
 
        while (1) {
-               while (*p == '/')
+               while (*p == cpu_to_le16('/'))
                        p++;
                cur_dentry = parent_dentry;
                if (*p == '\0')
                        break;
                pp = p;
-               while (*pp != '/' && *pp != '\0')
+               while (*pp != cpu_to_le16('/') && *pp != '\0')
                        pp++;
 
-               save = *pp;
-               *pp = '\0';
-               cur_dentry = get_dentry_child_with_utf16le_name(parent_dentry, p);
+               cur_dentry = get_dentry_child_with_utf16le_name(parent_dentry, p,
+                                                               (void*)pp - (void*)p);
                if (cur_dentry == NULL)
                        break;
-               *pp = save;
                p = pp;
+               parent_dentry = cur_dentry;
        }
        FREE(path_utf16le);
        if (cur_dentry == NULL) {
@@ -484,7 +492,8 @@ wim_pathname_to_inode(WIMStruct *w, const mbchar *path)
 
 /* Returns the dentry that corresponds to the parent directory of @path, or NULL
  * if the dentry is not found. */
-struct wim_dentry *get_parent_dentry(WIMStruct *w, const mbchar *path)
+struct wim_dentry *
+get_parent_dentry(WIMStruct *w, const mbchar *path)
 {
        size_t path_len = strlen(path);
        mbchar buf[path_len + 1];
@@ -495,7 +504,8 @@ struct wim_dentry *get_parent_dentry(WIMStruct *w, const mbchar *path)
 }
 
 /* Prints the full path of a dentry. */
-int print_dentry_full_path(struct wim_dentry *dentry, void *ignore)
+int
+print_dentry_full_path(struct wim_dentry *dentry, void *ignore)
 {
        if (dentry->full_path)
                puts(dentry->full_path);
@@ -529,7 +539,8 @@ struct file_attr_flag file_attr_flags[] = {
 /* Prints a directory entry.  @lookup_table is a pointer to the lookup table, if
  * available.  If the dentry is unresolved and the lookup table is NULL, the
  * lookup table entries will not be printed.  Otherwise, they will be. */
-int print_dentry(struct wim_dentry *dentry, void *lookup_table)
+int
+print_dentry(struct wim_dentry *dentry, void *lookup_table)
 {
        const u8 *hash;
        struct wim_lookup_table_entry *lte;
@@ -559,9 +570,12 @@ int print_dentry(struct wim_dentry *dentry, void *lookup_table)
        printf("Hard Link Group   = 0x%"PRIx64"\n", inode->i_ino);
        printf("Hard Link Group Size = %"PRIu32"\n", inode->i_nlink);
        printf("Number of Alternate Data Streams = %hu\n", inode->i_num_ads);
-       wimlib_printf("Filename = \"%W\"\n", dentry->file_name);
-       wimlib_printf("Short Name \"%W\"\n", dentry->short_name);
-       printf("Full Path = \"%s\"\n", dentry->full_path);
+       if (dentry_has_long_name(dentry))
+               wimlib_printf("Filename = \"%W\"\n", dentry->file_name);
+       if (dentry_has_short_name(dentry))
+               wimlib_printf("Short Name \"%W\"\n", dentry->short_name);
+       if (dentry->full_path)
+               printf("Full Path = \"%s\"\n", dentry->full_path);
 
        lte = inode_stream_lte(dentry->d_inode, 0, lookup_table);
        if (lte) {
@@ -593,13 +607,15 @@ int print_dentry(struct wim_dentry *dentry, void *lookup_table)
 }
 
 /* Initializations done on every `struct wim_dentry'. */
-static void dentry_common_init(struct wim_dentry *dentry)
+static void
+dentry_common_init(struct wim_dentry *dentry)
 {
        memset(dentry, 0, sizeof(struct wim_dentry));
        dentry->refcnt = 1;
 }
 
-static struct wim_inode *new_timeless_inode()
+static struct wim_inode *
+new_timeless_inode()
 {
        struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
        if (inode) {
@@ -618,7 +634,8 @@ static struct wim_inode *new_timeless_inode()
        return inode;
 }
 
-static struct wim_inode *new_inode()
+static struct wim_inode *
+new_inode()
 {
        struct wim_inode *inode = new_timeless_inode();
        if (inode) {
@@ -630,76 +647,87 @@ static struct wim_inode *new_inode()
        return inode;
 }
 
-/*
- * Creates an unlinked directory entry.
- *
- * @name:  The UTF-8 filename of the new dentry.
- *
- * Returns a pointer to the new dentry, or NULL if out of memory.
- */
-struct wim_dentry *new_dentry(const mbchar *name)
+/* Creates an unlinked directory entry. */
+int new_dentry(const mbchar *name, struct wim_dentry **dentry_ret)
 {
        struct wim_dentry *dentry;
+       int ret;
 
        dentry = MALLOC(sizeof(struct wim_dentry));
        if (!dentry)
-               goto err;
+               return WIMLIB_ERR_NOMEM;
 
        dentry_common_init(dentry);
-       if (set_dentry_name(dentry, name) != 0)
-               goto err;
-
-       dentry->parent = dentry;
-
-       return dentry;
-err:
-       FREE(dentry);
-       ERROR_WITH_ERRNO("Failed to create new dentry with name \"%s\"", name);
-       return NULL;
+       ret = set_dentry_name(dentry, name);
+       if (ret == 0) {
+               dentry->parent = dentry;
+               *dentry_ret = dentry;
+       } else {
+               FREE(dentry);
+               ERROR("Failed to set name on new dentry with name \"%s\"", name);
+       }
+       return ret;
 }
 
 
-static struct wim_dentry *
-__new_dentry_with_inode(const mbchar *name, bool timeless)
+static int
+__new_dentry_with_inode(const mbchar *name, struct wim_dentry **dentry_ret,
+                       bool timeless)
 {
        struct wim_dentry *dentry;
-       dentry = new_dentry(name);
-       if (dentry) {
-               if (timeless)
-                       dentry->d_inode = new_timeless_inode();
-               else
-                       dentry->d_inode = new_inode();
-               if (dentry->d_inode) {
-                       inode_add_dentry(dentry, dentry->d_inode);
-               } else {
-                       free_dentry(dentry);
-                       dentry = NULL;
-               }
+       int ret;
+
+       ret = new_dentry(name, &dentry);
+       if (ret)
+               return ret;
+
+       if (timeless)
+               dentry->d_inode = new_timeless_inode();
+       else
+               dentry->d_inode = new_inode();
+       if (!dentry->d_inode) {
+               free_dentry(dentry);
+               return WIMLIB_ERR_NOMEM;
        }
-       return dentry;
+
+       inode_add_dentry(dentry, dentry->d_inode);
+       *dentry_ret = dentry;
+       return 0;
 }
 
-struct wim_dentry *
-new_dentry_with_timeless_inode(const mbchar *name)
+int
+new_dentry_with_timeless_inode(const mbchar *name, struct wim_dentry **dentry_ret)
 {
-       return __new_dentry_with_inode(name, true);
+       return __new_dentry_with_inode(name, dentry_ret, true);
 }
 
-struct wim_dentry *
-new_dentry_with_inode(const mbchar *name)
+int
+new_dentry_with_inode(const mbchar *name, struct wim_dentry **dentry_ret)
 {
-       return __new_dentry_with_inode(name, false);
+       return __new_dentry_with_inode(name, dentry_ret, false);
 }
 
 
 static int
-init_ads_entry(struct wim_ads_entry *ads_entry, const mbchar *name)
+init_ads_entry(struct wim_ads_entry *ads_entry, const void *name,
+              size_t name_nbytes, bool is_utf16le)
 {
        int ret = 0;
        memset(ads_entry, 0, sizeof(*ads_entry));
-       if (name && *name) {
-               ret = get_utf16le_name(name, &ads_entry->stream_name,
-                                      &ads_entry->stream_name_nbytes);
+
+       if (is_utf16le) {
+               utf16lechar *p = MALLOC(name_nbytes + sizeof(utf16lechar));
+               if (!p)
+                       return WIMLIB_ERR_NOMEM;
+               memcpy(p, name, name_nbytes);
+               p[name_nbytes / 2] = 0;
+               ads_entry->stream_name = p;
+               ads_entry->stream_name_nbytes = name_nbytes;
+       } else {
+               if (name && *(const char*)name) {
+                       ret = get_utf16le_name(name, &ads_entry->stream_name,
+                                              &ads_entry->stream_name_nbytes);
+               }
        }
        return ret;
 }
@@ -897,12 +925,9 @@ inode_get_ads_entry(struct wim_inode *inode, const mbchar *stream_name,
        }
 }
 
-/*
- * Add an alternate stream entry to a WIM inode and return a pointer to it, or
- * NULL if memory could not be allocated.
- */
-struct wim_ads_entry *
-inode_add_ads(struct wim_inode *inode, const char *stream_name)
+static struct wim_ads_entry *
+do_inode_add_ads(struct wim_inode *inode, const void *stream_name,
+                size_t stream_name_nbytes, bool is_utf16le)
 {
        u16 num_ads;
        struct wim_ads_entry *ads_entries;
@@ -924,7 +949,7 @@ inode_add_ads(struct wim_inode *inode, const char *stream_name)
        inode->i_ads_entries = ads_entries;
 
        new_entry = &inode->i_ads_entries[num_ads - 1];
-       if (init_ads_entry(new_entry, stream_name) != 0)
+       if (init_ads_entry(new_entry, stream_name, stream_name_nbytes, is_utf16le))
                return NULL;
 #ifdef WITH_FUSE
        new_entry->stream_id = inode->i_next_stream_id++;
@@ -933,6 +958,24 @@ inode_add_ads(struct wim_inode *inode, const char *stream_name)
        return new_entry;
 }
 
+struct wim_ads_entry *
+inode_add_ads_utf16le(struct wim_inode *inode,
+                     const utf16lechar *stream_name,
+                     size_t stream_name_nbytes)
+{
+       return do_inode_add_ads(inode, stream_name, stream_name_nbytes, true);
+}
+
+/*
+ * Add an alternate stream entry to a WIM inode and return a pointer to it, or
+ * NULL if memory could not be allocated.
+ */
+struct wim_ads_entry *
+inode_add_ads(struct wim_inode *inode, const char *stream_name)
+{
+       return do_inode_add_ads(inode, stream_name, strlen(stream_name), false);
+}
+
 int
 inode_add_ads_with_data(struct wim_inode *inode, const mbchar *name,
                        const void *value, size_t size,
@@ -1141,7 +1184,6 @@ read_ads_entries(const u8 *p, struct wim_inode *inode, u64 remaining_size)
                u64 length;
                u64 length_no_padding;
                u64 total_length;
-               size_t utf8_len;
                const u8 *p_save = p;
 
                cur_entry = &ads_entries[i];
@@ -1160,7 +1202,7 @@ read_ads_entries(const u8 *p, struct wim_inode *inode, u64 remaining_size)
 
                p = get_u64(p, &length);
                p += 8; /* Skip the reserved field */
-               p = get_bytes(p, SHA1_HASH_SIZE, (u8*)cur_entry->hash);
+               p = get_bytes(p, SHA1_HASH_SIZE, cur_entry->hash);
                p = get_u16(p, &cur_entry->stream_name_nbytes);
 
                cur_entry->stream_name = NULL;
@@ -1201,8 +1243,7 @@ read_ads_entries(const u8 *p, struct wim_inode *inode, u64 remaining_size)
                }
 
                if (cur_entry->stream_name_nbytes) {
-                       cur_entry->stream_name = MALLOC((size_t)
-                                                       cur_entry->stream_name_nbytes + 2);
+                       cur_entry->stream_name = MALLOC(cur_entry->stream_name_nbytes + 2);
                        if (!cur_entry->stream_name) {
                                ret = WIMLIB_ERR_NOMEM;
                                goto out_free_ads_entries;
@@ -1373,14 +1414,14 @@ read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
        /* Read the filename if present.  Note: if the filename is empty, there
         * is no null terminator following it. */
        if (file_name_nbytes) {
-               file_name = MALLOC((size_t)file_name_nbytes + 2);
+               file_name = MALLOC(file_name_nbytes + 2);
                if (!file_name) {
-                       ERROR("Failed to allocate %zu bytes for dentry file name",
-                             (size_t)file_name_nbytes + 2);
+                       ERROR("Failed to allocate %d bytes for dentry file name",
+                             file_name_nbytes + 2);
                        ret = WIMLIB_ERR_NOMEM;
                        goto out_free_inode;
                }
-               p = get_bytes(p, (size_t)file_name_nbytes + 2, file_name);
+               p = get_bytes(p, file_name_nbytes + 2, file_name);
                if (file_name[file_name_nbytes / 2] != 0) {
                        file_name[file_name_nbytes / 2] = 0;
                        WARNING("File name in WIM dentry \"%W\" is not "
@@ -1423,14 +1464,14 @@ read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
        /* Read the short filename if present.  Note: if there is no short
         * filename, there is no null terminator following it. */
        if (short_name_nbytes) {
-               short_name = MALLOC((size_t)short_name_nbytes + 2);
+               short_name = MALLOC(short_name_nbytes + 2);
                if (!short_name) {
-                       ERROR("Failed to allocate %zu bytes for dentry short name",
-                             (size_t)short_name_nbytes + 2);
+                       ERROR("Failed to allocate %d bytes for dentry short name",
+                             short_name_nbytes + 2);
                        ret = WIMLIB_ERR_NOMEM;
                        goto out_free_file_name;
                }
-               p = get_bytes(p, (size_t)short_name_nbytes + 2, short_name);
+               p = get_bytes(p, short_name_nbytes + 2, short_name);
                if (short_name[short_name_nbytes / 2] != 0) {
                        short_name[short_name_nbytes / 2] = 0;
                        WARNING("Short name in WIM dentry \"%W\" is not "
@@ -1621,11 +1662,11 @@ write_dentry(const struct wim_dentry *dentry, u8 *p)
        p = put_u16(p, inode->i_num_ads);
        p = put_u16(p, dentry->short_name_nbytes);
        p = put_u16(p, dentry->file_name_nbytes);
-       if (dentry->file_name_nbytes) {
+       if (dentry_has_long_name(dentry)) {
                p = put_bytes(p, dentry->file_name_nbytes + 2,
                              dentry->file_name);
        }
-       if (dentry->short_name_nbytes) {
+       if (dentry_has_short_name(dentry)) {
                p = put_bytes(p, dentry->short_name_nbytes + 2,
                              dentry->short_name);
        }
index dfbcafc..6442b10 100644 (file)
@@ -358,7 +358,8 @@ get_dentry_child_with_name(const struct wim_dentry *dentry,
 
 extern struct wim_dentry *
 get_dentry_child_with_utf16le_name(const struct wim_dentry *dentry,
-                                  const utf16lechar *name);
+                                  const utf16lechar *name,
+                                  size_t name_nbytes);
 
 extern struct wim_dentry *
 get_parent_dentry(struct WIMStruct *w, const mbchar *path);
@@ -369,14 +370,14 @@ print_dentry(struct wim_dentry *dentry, void *lookup_table);
 extern int
 print_dentry_full_path(struct wim_dentry *entry, void *ignore);
 
-extern struct
-wim_dentry *new_dentry(const mbchar *name);
+extern int
+new_dentry(const mbchar *name, struct wim_dentry **dentry_ret);
 
-extern struct wim_dentry *
-new_dentry_with_inode(const mbchar *name);
+extern int
+new_dentry_with_inode(const mbchar *name, struct wim_dentry **dentry_ret);
 
-extern struct wim_dentry *
-new_dentry_with_timeless_inode(const mbchar *name);
+extern int
+new_dentry_with_timeless_inode(const mbchar *name, struct wim_dentry **dentry_ret);
 
 extern void
 free_inode(struct wim_inode *inode);
@@ -406,6 +407,11 @@ inode_get_ads_entry(struct wim_inode *inode, const mbchar *stream_name,
                    u16 *idx_ret);
 
 extern struct wim_ads_entry *
+inode_add_ads_utf16le(struct wim_inode *inode,
+                     const utf16lechar *stream_name,
+                     size_t stream_name_nbytes);
+
+extern struct wim_ads_entry *
 inode_add_ads(struct wim_inode *dentry, const mbchar *stream_name);
 
 extern int
@@ -417,9 +423,12 @@ extern void
 inode_remove_ads(struct wim_inode *inode, u16 idx,
                 struct wim_lookup_table *lookup_table);
 
+
 #define WIMLIB_UNIX_DATA_TAG "$$__wimlib_UNIX_data"
+#define WIMLIB_UNIX_DATA_TAG_NBYTES (sizeof(WIMLIB_UNIX_DATA_TAG) - 1)
 
-#define WIMLIB_UNIX_DATA_TAG_LEN (sizeof(WIMLIB_UNIX_DATA_TAG) - 1)
+#define WIMLIB_UNIX_DATA_TAG_UTF16LE "$\0$\0_\0_\0w\0i\0m\0l\0i\0b\0_\0U\0N\0I\0X\0_\0d\0a\0t\0a\0"
+#define WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES (sizeof(WIMLIB_UNIX_DATA_TAG_UTF16LE) - 1)
 
 /* Format for special alternate data stream entries to store UNIX data for files
  * and directories (see: WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA) */
@@ -514,4 +523,16 @@ dentry_has_children(const struct wim_dentry *dentry)
        return inode_has_children(dentry->d_inode);
 }
 
+static inline bool
+dentry_has_short_name(const struct wim_dentry *dentry)
+{
+       return dentry->short_name_nbytes != 0;
+}
+
+static inline bool
+dentry_has_long_name(const struct wim_dentry *dentry)
+{
+       return dentry->file_name_nbytes != 0;
+}
+
 #endif
index de04358..e0f4e2d 100644 (file)
@@ -54,219 +54,193 @@ struct iconv_list_head name = {                           \
        .mutex = PTHREAD_MUTEX_INITIALIZER,             \
 }
 
-static ICONV_LIST(iconv_mbs_to_utf16le, "", "UTF-16LE");
-static ICONV_LIST(iconv_utf16le_to_mbs, "UTF-16LE", "");
-
 static iconv_t *
 get_iconv(struct iconv_list_head *head)
 {
        iconv_t cd;
+       iconv_t *cd_p;
        struct iconv_node *i;
 
        pthread_mutex_lock(&head->mutex);
        if (list_empty(&head->list)) {
                cd = iconv_open(head->to_encoding, head->from_encoding);
                if (cd == (iconv_t)-1) {
-                       goto out_unlock;
+                       ERROR_WITH_ERRNO("Failed to open iconv from %s to %s",
+                                        head->from_encoding, head->to_encoding);
+                       cd_p = NULL;
                } else {
                        i = MALLOC(sizeof(struct iconv_node));
-                       if (!i) {
+                       if (i) {
+                               i->head = head;
+                               i->cd = cd;
+                               cd_p = &i->cd;
+                       } else {
                                iconv_close(cd);
-                               cd = (iconv_t)-1;
-                               goto out_unlock;
+                               cd_p = NULL;
                        }
-                       i->head = head;
                }
        } else {
                i = container_of(head->list.next, struct iconv_node, list);
                list_del(head->list.next);
+               cd_p = &i->cd;
        }
-       cd = i->cd;
-out_unlock:
        pthread_mutex_unlock(&head->mutex);
-       return cd;
+       return cd_p;
 }
 
 static void
 put_iconv(iconv_t *cd)
 {
+       int errno_save = errno;
        struct iconv_node *i = container_of(cd, struct iconv_node, cd);
        struct iconv_list_head *head = i->head;
        
        pthread_mutex_lock(&head->mutex);
        list_add(&i->list, &head->list);
        pthread_mutex_unlock(&head->mutex);
+       errno = errno_save;
 }
 
-int
-mbs_to_utf16le_nbytes(const mbchar *mbs, size_t mbs_nbytes,
-                     size_t *utf16le_nbytes_ret)
-{
-       iconv_t *cd = get_iconv(&iconv_mbs_to_utf16le);
-       if (*cd == (iconv_t)-1)
-               return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
-
-       /* Worst case length */
-       utf16lechar buf[mbs_nbytes * 2];
-       char *inbuf = (char*)mbs;
-       char *outbuf = (char*)buf;
-       size_t outbytesleft = sizeof(buf);
-       size_t inbytesleft = mbs_nbytes;
-       size_t len;
-       int ret;
-
-       len = iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
-       if (len == (size_t)-1) {
-               ret = WIMLIB_ERR_INVALID_MULTIBYTE_STRING;
-       } else {
-               *utf16le_nbytes_ret = sizeof(buf) - outbytesleft;
-               ret = 0;
-       }
-       put_iconv(cd);
-       return ret;
+#define DEFINE_CHAR_CONVERSION_FUNCTIONS(varname1, longname1, chartype1,\
+                                        varname2, longname2, chartype2,\
+                                        worst_case_len_expr,           \
+                                        err_return,                    \
+                                        err_msg)                       \
+static ICONV_LIST(iconv_##varname1##_to_##varname2,                    \
+                 longname1, longname2);                                \
+                                                                       \
+int                                                                    \
+varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
+                                 size_t *out_nbytes_ret)               \
+{                                                                      \
+       iconv_t *cd = get_iconv(&iconv_##varname1##_to_##varname2);     \
+       if (cd == NULL)                                                 \
+               return WIMLIB_ERR_ICONV_NOT_AVAILABLE;                  \
+                                                                       \
+       /* Worst case length */                                         \
+       chartype2 buf[worst_case_len_expr];                             \
+       char *inbuf = (char*)in;                                        \
+       size_t inbytesleft = in_nbytes;                                 \
+       char *outbuf = (char*)buf;                                      \
+       size_t outbytesleft = sizeof(buf);                              \
+       size_t len;                                                     \
+       int ret;                                                        \
+                                                                       \
+       len = iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); \
+       if (len == (size_t)-1) {                                        \
+               err_msg;                                                \
+               ret = err_return;                                       \
+       } else {                                                        \
+               *out_nbytes_ret = sizeof(buf) - outbytesleft;           \
+               ret = 0;                                                \
+       }                                                               \
+       put_iconv(cd);                                                  \
+       return ret;                                                     \
+}                                                                      \
+                                                                       \
+int                                                                    \
+varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes,  \
+                              chartype2 *out)                          \
+{                                                                      \
+       iconv_t *cd = get_iconv(&iconv_##varname1##_to_##varname2);     \
+       if (cd == NULL)                                                 \
+               return WIMLIB_ERR_ICONV_NOT_AVAILABLE;                  \
+                                                                       \
+       char *inbuf = (char*)in;                                        \
+       size_t inbytesleft = in_nbytes;                                 \
+       char *outbuf = (char*)out;                                      \
+       const size_t LARGE_NUMBER = 1000000000;                         \
+       size_t outbytesleft = LARGE_NUMBER;                             \
+       size_t len;                                                     \
+       int ret;                                                        \
+                                                                       \
+       len = iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); \
+       if (len == (size_t)-1) {                                        \
+               err_msg;                                                \
+               ret = err_return;                                       \
+       } else {                                                        \
+               out[(LARGE_NUMBER-outbytesleft)/sizeof(chartype2)] = 0; \
+               ret = 0;                                                \
+       }                                                               \
+       put_iconv(cd);                                                  \
+       return ret;                                                     \
+}                                                                      \
+                                                                       \
+int                                                                    \
+varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes,                \
+                        chartype2 **out_ret,                           \
+                        size_t *out_nbytes_ret)                        \
+{                                                                      \
+       int ret;                                                        \
+       chartype2 *out;                                                 \
+       size_t out_nbytes;                                              \
+                                                                       \
+       ret = varname1##_to_##varname2##_nbytes(in, in_nbytes,          \
+                                               &out_nbytes);           \
+       if (ret)                                                        \
+               return ret;                                             \
+                                                                       \
+       out = MALLOC(out_nbytes + sizeof(chartype2));                   \
+       if (!out)                                                       \
+               return WIMLIB_ERR_NOMEM;                                \
+                                                                       \
+       ret = varname1##_to_##varname2##_buf(in, in_nbytes, out);       \
+       if (ret) {                                                      \
+               int errno_save = errno;                                 \
+               FREE(out);                                              \
+               errno = errno_save;                                     \
+       } else {                                                        \
+               *out_ret = out;                                         \
+               *out_nbytes_ret = out_nbytes;                           \
+       }                                                               \
+       return ret;                                                     \
 }
 
+DEFINE_CHAR_CONVERSION_FUNCTIONS(utf16le, "UTF-16LE", utf16lechar,
+                                mbs, "", mbchar,
+                                in_nbytes / 2 * MB_CUR_MAX,
+                                WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE,
+                                ERROR_WITH_ERRNO("Failed to convert UTF-16LE "
+                                                 "string %U to multibyte string", in))
 
-int
-utf16le_to_mbs_nbytes(const utf16lechar *utf16le_str, size_t utf16le_nbytes,
-                     size_t *mbs_nbytes_ret)
-{
-       iconv_t *cd = get_iconv(&iconv_utf16le_to_mbs);
-       if (*cd == (iconv_t)-1)
-               return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
+DEFINE_CHAR_CONVERSION_FUNCTIONS(mbs, "", mbchar,
+                                utf16le, "UTF-16LE", utf16lechar,
+                                in_nbytes * 2,
+                                WIMLIB_ERR_INVALID_MULTIBYTE_STRING,
+                                ERROR_WITH_ERRNO("Failed to convert multibyte "
+                                                 "string %s to UTF-16LE string", in))
 
-       /* Worst case length */
-       mbchar buf[utf16le_nbytes / 2 * MB_CUR_MAX];
-       char *inbuf = (char*)utf16le_str;
-       char *outbuf = (char*)buf;
-       size_t outbytesleft = sizeof(buf);
-       size_t inbytesleft = utf16le_nbytes;
-       size_t len;
-       int ret;
+DEFINE_CHAR_CONVERSION_FUNCTIONS(utf8, "UTF-8", utf8char,
+                                mbs, "", mbchar,
+                                in_nbytes,
+                                WIMLIB_ERR_INVALID_UTF8_STRING,
+                                ERROR_WITH_ERRNO("Failed to convert UTF-8 "
+                                                 "string %U to multibyte string", in))
 
-       len = iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
-       if (len == (size_t)-1) {
-               ERROR("Could not convert \"%W\" to encoding of current locale",
-                     utf16le_str);
-               /* EILSEQ is supposed to mean that the *input* is invalid, but
-                * it's also returned if any input characters are not
-                * representable in the output encoding.  (The actual behavior
-                * in this case is undefined for some reason...).  Assume it's
-                * the latter error case. */
-               ret = WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE;
-       } else {
-               *mbs_nbytes_ret  = sizeof(buf) - outbytesleft;
-               ret = 0;
-       }
-       put_iconv(cd);
-       return ret;
-}
-
-int
-mbs_to_utf16le_buf(const mbchar *mbs, size_t mbs_nbytes,
-                  utf16lechar *utf16le_str)
-{
-       iconv_t *cd = get_iconv(&iconv_mbs_to_utf16le);
-       if (*cd == (iconv_t)-1)
-               return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
-
-       char *inbuf = (char*)mbs;
-       size_t inbytesleft = mbs_nbytes;
-       char *outbuf = (char*)utf16le_str;
-       size_t outbytesleft = SIZE_MAX;
-       size_t len;
-       int ret;
-
-       len = iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
-       if (len == (size_t)-1) {
-               ret = WIMLIB_ERR_INVALID_MULTIBYTE_STRING;
-       } else {
-               ret = 0;
-       }
-       put_iconv(cd);
-       return ret;
-}
 
-int
-utf16le_to_mbs_buf(const utf16lechar *utf16le_str, size_t utf16le_nbytes,
-                  mbchar *mbs)
+static void
+iconv_cleanup(struct iconv_list_head *head)
 {
-       int ret;
-       iconv_t *cd = get_iconv(&iconv_utf16le_to_mbs);
-       if (*cd == (iconv_t)-1)
-               return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
-
-       char *inbuf = (char*)utf16le_str;
-       size_t inbytesleft;
-       char *outbuf = (char*)mbs;
-       size_t outbytesleft = SIZE_MAX;
-       size_t len;
-
-       len = iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
-       if (len == (size_t)-1) {
-               ret = WIMLIB_ERR_INVALID_UTF16_STRING;
-       } else {
-               ret = 0;
+       pthread_mutex_destroy(&head->mutex);
+       while (!list_empty(&head->list)) {
+               struct iconv_node *i;
+               
+               i = container_of(head->list.next, struct iconv_node, list);
+               list_del(&i->list);
+               iconv_close(i->cd);
+               FREE(i);
        }
-       mbs[SIZE_MAX - inbytesleft] = '\0';
-       put_iconv(cd);
-       return ret;
 }
 
-int
-mbs_to_utf16le(const mbchar *mbs, size_t mbs_nbytes,
-              utf16lechar **utf16le_ret, size_t *utf16le_nbytes_ret)
+void
+iconv_global_cleanup()
 {
-       int ret;
-       utf16lechar *utf16le_str;
-       size_t utf16le_nbytes;
-
-       ret = mbs_to_utf16le_nbytes(mbs, mbs_nbytes,
-                                   &utf16le_nbytes);
-       if (ret)
-               return ret;
-
-       utf16le_str = MALLOC(utf16le_nbytes + 1);
-       if (!utf16le_str)
-               return WIMLIB_ERR_NOMEM;
-
-       ret = mbs_to_utf16le_buf(mbs, mbs_nbytes, utf16le_str);
-       if (ret) {
-               FREE(utf16le_str);
-       } else {
-               *utf16le_ret = utf16le_str;
-               *utf16le_nbytes_ret = utf16le_nbytes;
-       }
-       return ret;
+       iconv_cleanup(&iconv_utf16le_to_mbs);
+       iconv_cleanup(&iconv_mbs_to_utf16le);
+       iconv_cleanup(&iconv_utf8_to_mbs);
 }
 
 
-int
-utf16le_to_mbs(const utf16lechar *utf16le_str, size_t utf16le_nbytes,
-              mbchar **mbs_ret, size_t *mbs_nbytes_ret)
-{
-       int ret;
-       mbchar *mbs;
-       size_t mbs_nbytes;
-
-       ret = utf16le_to_mbs_nbytes(utf16le_str, utf16le_nbytes,
-                                   &mbs_nbytes);
-       if (ret)
-               return ret;
-
-       mbs = MALLOC(mbs_nbytes + 1);
-       if (!mbs)
-               return WIMLIB_ERR_NOMEM;
-
-       ret = utf16le_to_mbs_buf(utf16le_str, utf16le_nbytes, mbs);
-       if (ret) {
-               FREE(mbs);
-       } else {
-               *mbs_ret = mbs;
-               *mbs_nbytes_ret = mbs_nbytes;
-       }
-       return ret;
-}
 
 bool
 utf8_str_contains_nonascii_chars(const utf8char *utf8_str)
index d9301c2..f8a2aef 100644 (file)
@@ -110,18 +110,18 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *old)
                        if (!loc)
                                goto out_free;
                        memcpy(loc, old->ntfs_loc, sizeof(*loc));
-                       loc->path_utf8 = NULL;
-                       loc->stream_name_utf16 = NULL;
+                       loc->path = NULL;
+                       loc->stream_name = NULL;
                        new->ntfs_loc = loc;
-                       loc->path_utf8 = STRDUP(old->ntfs_loc->path_utf8);
-                       if (!loc->path_utf8)
+                       loc->path = STRDUP(old->ntfs_loc->path);
+                       if (!loc->path)
                                goto out_free;
-                       loc->stream_name_utf16 = MALLOC(loc->stream_name_utf16_num_chars * 2);
-                       if (!loc->stream_name_utf16)
+                       loc->stream_name = MALLOC((loc->stream_name_nchars + 1) * 2);
+                       if (!loc->stream_name)
                                goto out_free;
-                       memcpy(loc->stream_name_utf16,
-                              old->ntfs_loc->stream_name_utf16,
-                              loc->stream_name_utf16_num_chars * 2);
+                       memcpy(loc->stream_name,
+                              old->ntfs_loc->stream_name,
+                              (loc->stream_name_nchars + 1) * 2);
                }
                break;
 #endif
@@ -153,8 +153,8 @@ void free_lookup_table_entry(struct wim_lookup_table_entry *lte)
 #ifdef WITH_NTFS_3G
                case RESOURCE_IN_NTFS_VOLUME:
                        if (lte->ntfs_loc) {
-                               FREE(lte->ntfs_loc->path_utf8);
-                               FREE(lte->ntfs_loc->stream_name_utf16);
+                               FREE(lte->ntfs_loc->path);
+                               FREE(lte->ntfs_loc->stream_name);
                                FREE(lte->ntfs_loc);
                        }
                        break;
@@ -590,7 +590,7 @@ lookup_resource(WIMStruct *w,
        if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
                stream_name = path_stream_name(path);
                if (stream_name) {
-                       p = (char*)stream_name - 1;
+                       p = (mbchar*)stream_name - 1;
                        *p = '\0';
                }
        }
@@ -599,7 +599,7 @@ lookup_resource(WIMStruct *w,
        if (p)
                *p = ':';
        if (!dentry)
-               return -ENOENT;
+               return -errno;
 
        inode = dentry->d_inode;
 
index 699e16e..d172cac 100644 (file)
@@ -32,9 +32,9 @@ struct wim_lookup_table {
 
 #ifdef WITH_NTFS_3G
 struct ntfs_location {
-       utf8char *path_utf8;
-       utf16lechar *stream_name_utf16;
-       u16 stream_name_utf16_num_chars;
+       mbchar *path;
+       utf16lechar *stream_name;
+       u16 stream_name_nchars;
        struct _ntfs_volume **ntfs_vol_p;
        bool is_reparse_point;
 };
index 2f09ce7..fc5fa45 100644 (file)
@@ -312,6 +312,7 @@ create_dentry(struct fuse_context *fuse_ctx, const mbchar *path,
        struct wim_dentry *new;
        const mbchar *basename;
        struct wimfs_context *wimfs_ctx = WIMFS_CTX(fuse_ctx);
+       int ret;
 
        parent = get_parent_dentry(wimfs_ctx->wim, path);
        if (!parent)
@@ -324,9 +325,9 @@ create_dentry(struct fuse_context *fuse_ctx, const mbchar *path,
        if (get_dentry_child_with_name(parent, basename))
                return -EEXIST;
 
-       new = new_dentry_with_inode(basename);
-       if (!new)
-               return -errno;
+       ret = new_dentry_with_inode(basename, &new);
+       if (ret)
+               return -ENOMEM;
 
        new->d_inode->i_resolved = 1;
        new->d_inode->i_ino = wimfs_ctx->next_ino++;
@@ -1737,6 +1738,7 @@ wimfs_link(const mbchar *to, const mbchar *from)
        struct wim_lookup_table_entry *lte;
        WIMStruct *w = wimfs_get_WIMStruct();
        u16 i;
+       int ret;
 
        inode = wim_pathname_to_inode(w, to);
        if (!inode)
@@ -1755,9 +1757,10 @@ wimfs_link(const mbchar *to, const mbchar *from)
        link_name = path_basename(from);
        if (get_dentry_child_with_name(from_dentry_parent, link_name))
                return -EEXIST;
-       from_dentry = new_dentry(link_name);
-       if (!from_dentry)
-               return -errno;
+
+       ret = new_dentry(link_name, &from_dentry);
+       if (ret)
+               return -ENOMEM;
 
        inode_add_dentry(from_dentry, inode);
        from_dentry->d_inode = inode;
@@ -2386,7 +2389,6 @@ wimfs_write(const mbchar *path, const char *buf, size_t size,
 {
        struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh;
        int ret;
-       u64 now;
 
        if (!fd)
                return -EBADF;
index 9dcf6b0..8bc6c49 100644 (file)
@@ -41,8 +41,9 @@
 #include <ntfs-3g/reparse.h>
 #include <ntfs-3g/xattrs.h>
 #include <string.h>
+#include <locale.h>
 
-static int extract_wim_chunk_to_ntfs_attr(const u8 *buf, size_t len,
+static int extract_wim_chunk_to_ntfs_attr(const void *buf, size_t len,
                                          u64 offset, void *arg)
 {
        ntfs_attr *na = arg;
@@ -87,36 +88,34 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct wim_dentry *dent
        int ret = 0;
        unsigned stream_idx = 0;
        ntfschar *stream_name = AT_UNNAMED;
-       u32 stream_name_len = 0;
-       const char *stream_name_utf8;
+       u32 stream_name_nbytes = 0;
        const struct wim_inode *inode = dentry->d_inode;
        struct wim_lookup_table_entry *lte;
 
        DEBUG("Writing %u NTFS data stream%s for `%s'",
              inode->i_num_ads + 1,
              (inode->i_num_ads == 0 ? "" : "s"),
-             dentry->full_path_utf8);
+             dentry->full_path);
 
        lte = inode->i_lte;
        while (1) {
-               if (stream_name_len) {
-
+               if (stream_name_nbytes) {
                        /* Skip special UNIX data entries (see documentation for
                         * WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA) */
-                       if (stream_name_len == WIMLIB_UNIX_DATA_TAG_LEN
-                           && !memcmp(stream_name_utf8,
-                                      WIMLIB_UNIX_DATA_TAG,
-                                      WIMLIB_UNIX_DATA_TAG_LEN))
+                       if (stream_name_nbytes == WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES
+                           && !memcmp(stream_name,
+                                      WIMLIB_UNIX_DATA_TAG_UTF16LE,
+                                      WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES))
                                goto cont;
 
                        /* Create an empty named stream. */
                        ret = ntfs_attr_add(ni, AT_DATA, stream_name,
-                                           stream_name_len, NULL, 0);
+                                           stream_name_nbytes / 2, NULL, 0);
                        if (ret != 0) {
-                               ERROR_WITH_ERRNO("Failed to create name data "
+                               ERROR_WITH_ERRNO("Failed to create named data "
                                                 "stream for extracted file "
                                                 "`%s'",
-                                                dentry->full_path_utf8);
+                                                dentry->full_path);
                                ret = WIMLIB_ERR_NTFS_3G;
                                break;
 
@@ -128,11 +127,12 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct wim_dentry *dent
                if (lte) {
                        ntfs_attr *na;
 
-                       na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len);
+                       na = ntfs_attr_open(ni, AT_DATA, stream_name,
+                                           stream_name_nbytes / 2);
                        if (!na) {
                                ERROR_WITH_ERRNO("Failed to open a data stream of "
                                                 "extracted file `%s'",
-                                                dentry->full_path_utf8);
+                                                dentry->full_path);
                                ret = WIMLIB_ERR_NTFS_3G;
                                break;
                        }
@@ -163,9 +163,8 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct wim_dentry *dent
                        break;
 
                /* Get the name and lookup table entry for the next stream. */
-               stream_name = (ntfschar*)inode->i_ads_entries[stream_idx].stream_name;
-               stream_name_utf8 = inode->i_ads_entries[stream_idx].stream_name_utf8;
-               stream_name_len = inode->i_ads_entries[stream_idx].stream_name_len / 2;
+               stream_name = inode->i_ads_entries[stream_idx].stream_name;
+               stream_name_nbytes = inode->i_ads_entries[stream_idx].stream_name_nbytes;
                lte = inode->i_ads_entries[stream_idx].lte;
                stream_idx++;
        }
@@ -174,22 +173,22 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct wim_dentry *dent
 
 /* Open the NTFS inode that corresponds to the parent of a WIM dentry.  Returns
  * the opened inode, or NULL on failure. */
-static ntfs_inode *dentry_open_parent_ni(const struct wim_dentry *dentry,
-                                        ntfs_volume *vol)
+static ntfs_inode *
+dentry_open_parent_ni(const struct wim_dentry *dentry, ntfs_volume *vol)
 {
-       char *p;
-       const char *dir_name;
+       mbchar *p;
+       const mbchar *dir_name;
        ntfs_inode *dir_ni;
-       char orig;
+       mbchar orig;
 
-       p = dentry->full_path_utf8 + dentry->full_path_utf8_len;
+       p = dentry->full_path + dentry->full_path_nbytes;
        do {
                p--;
        } while (*p != '/');
 
        orig = *p;
        *p = '\0';
-       dir_name = dentry->full_path_utf8;
+       dir_name = dentry->full_path;
        dir_ni = ntfs_pathname_to_inode(vol, NULL, dir_name);
        if (!dir_ni) {
                ERROR_WITH_ERRNO("Could not find NTFS inode for `%s'",
@@ -206,7 +205,7 @@ static ntfs_inode *dentry_open_parent_ni(const struct wim_dentry *dentry,
  * directory specified by @dir_ni, and it is made to point to the previously
  * extracted file located at @inode->i_extracted_file.
  *
- * Or, in other words, this adds a new name @from_dentry->full_path_utf8 to an
+ * Or, in other words, this adds a new name @from_dentry->full_path to an
  * existing NTFS inode which already has a name @inode->i_extracted_file.
  *
  * The new name is made in the POSIX namespace (this is the behavior of
@@ -214,9 +213,10 @@ static ntfs_inode *dentry_open_parent_ni(const struct wim_dentry *dentry,
  *
  * Return 0 on success, nonzero on failure.  dir_ni is closed either way.
  */
-static int apply_ntfs_hardlink(const struct wim_dentry *from_dentry,
-                              const struct wim_inode *inode,
-                              ntfs_inode *dir_ni)
+static int
+apply_ntfs_hardlink(const struct wim_dentry *from_dentry,
+                   const struct wim_inode *inode,
+                   ntfs_inode *dir_ni)
 {
        int ret;
        ntfs_inode *to_ni;
@@ -230,7 +230,7 @@ static int apply_ntfs_hardlink(const struct wim_dentry *from_dentry,
        }
 
        DEBUG("Extracting NTFS hard link `%s' => `%s'",
-             from_dentry->full_path_utf8, inode->i_extracted_file);
+             from_dentry->full_path, inode->i_extracted_file);
 
        to_ni = ntfs_pathname_to_inode(vol, NULL, inode->i_extracted_file);
        if (!to_ni) {
@@ -246,13 +246,13 @@ static int apply_ntfs_hardlink(const struct wim_dentry *from_dentry,
        }
 
        ret = ntfs_link(to_ni, dir_ni,
-                       (ntfschar*)from_dentry->file_name,
-                       from_dentry->file_name_len / 2);
+                       from_dentry->file_name,
+                       from_dentry->file_name_nbytes / 2);
        ret |= ntfs_inode_close(dir_ni);
        ret |= ntfs_inode_close(to_ni);
        if (ret) {
                ERROR_WITH_ERRNO("Could not create hard link `%s' => `%s'",
-                                from_dentry->full_path_utf8,
+                                from_dentry->full_path,
                                 inode->i_extracted_file);
                ret = WIMLIB_ERR_NTFS_3G;
        }
@@ -284,7 +284,7 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
        inode = dentry->d_inode;
 
        DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32,
-             dentry->full_path_utf8, inode->i_attributes);
+             dentry->full_path, inode->i_attributes);
 
        attributes_le32 = cpu_to_le32(inode->i_attributes);
        memset(&ctx, 0, sizeof(ctx));
@@ -295,7 +295,7 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
                                         sizeof(u32), 0);
        if (ret != 0) {
                ERROR("Failed to set NTFS file attributes on `%s'",
-                      dentry->full_path_utf8);
+                      dentry->full_path);
                return WIMLIB_ERR_NTFS_3G;
        }
        if (inode->i_security_id != -1) {
@@ -306,7 +306,7 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
                wimlib_assert(inode->i_security_id < sd->num_entries);
                desc = (const char *)sd->descriptors[inode->i_security_id];
                DEBUG("Applying security descriptor %d to `%s'",
-                     inode->i_security_id, dentry->full_path_utf8);
+                     inode->i_security_id, dentry->full_path);
 
                ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ACL,
                                                 ni, dir_ni, desc,
@@ -314,7 +314,7 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
 
                if (ret != 0) {
                        ERROR_WITH_ERRNO("Failed to set security data on `%s'",
-                                       dentry->full_path_utf8);
+                                       dentry->full_path);
                        return WIMLIB_ERR_NTFS_3G;
                }
        }
@@ -333,17 +333,17 @@ static int apply_reparse_data(ntfs_inode *ni, const struct wim_dentry *dentry,
 
        lte = inode_unnamed_lte_resolved(dentry->d_inode);
 
-       DEBUG("Applying reparse data to `%s'", dentry->full_path_utf8);
+       DEBUG("Applying reparse data to `%s'", dentry->full_path);
 
        if (!lte) {
                ERROR("Could not find reparse data for `%s'",
-                     dentry->full_path_utf8);
+                     dentry->full_path);
                return WIMLIB_ERR_INVALID_DENTRY;
        }
 
        if (wim_resource_size(lte) >= 0xffff) {
                ERROR("Reparse data of `%s' is too long (%"PRIu64" bytes)",
-                     dentry->full_path_utf8, wim_resource_size(lte));
+                     dentry->full_path, wim_resource_size(lte));
                return WIMLIB_ERR_INVALID_DENTRY;
        }
 
@@ -362,7 +362,7 @@ static int apply_reparse_data(ntfs_inode *ni, const struct wim_dentry *dentry,
                                         wim_resource_size(lte) + 8, 0);
        if (ret != 0) {
                ERROR_WITH_ERRNO("Failed to set NTFS reparse data on `%s'",
-                                dentry->full_path_utf8);
+                                dentry->full_path);
                return WIMLIB_ERR_NTFS_3G;
        }
        progress_info->extract.completed_bytes += wim_resource_size(lte);
@@ -377,8 +377,9 @@ static int apply_reparse_data(ntfs_inode *ni, const struct wim_dentry *dentry,
  *
  * @return:  0 on success; nonzero on failure.
  */
-static int do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni,
-                               struct apply_args *args)
+static int
+do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni,
+                    struct apply_args *args)
 {
        int ret = 0;
        mode_t type;
@@ -404,7 +405,7 @@ static int do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni,
                                 * extracted yet, so go ahead and extract the
                                 * first one. */
                                FREE(inode->i_extracted_file);
-                               inode->i_extracted_file = STRDUP(dentry->full_path_utf8);
+                               inode->i_extracted_file = STRDUP(dentry->full_path);
                                if (!inode->i_extracted_file) {
                                        ret = WIMLIB_ERR_NOMEM;
                                        goto out_close_dir_ni;
@@ -418,12 +419,12 @@ static int do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni,
         * Note: For symbolic links that are not directory junctions, S_IFREG is
         * passed here, since the reparse data and file attributes are set
         * later. */
-       ni = ntfs_create(dir_ni, 0, (ntfschar*)dentry->file_name,
-                        dentry->file_name_len / 2, type);
+       ni = ntfs_create(dir_ni, 0, dentry->file_name,
+                        dentry->file_name_nbytes / 2, type);
 
        if (!ni) {
                ERROR_WITH_ERRNO("Could not create NTFS inode for `%s'",
-                                dentry->full_path_utf8);
+                                dentry->full_path);
                ret = WIMLIB_ERR_NTFS_3G;
                goto out_close_dir_ni;
        }
@@ -437,7 +438,6 @@ static int do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni,
                        goto out_close_dir_ni;
        }
 
-
        ret = apply_file_attributes_and_security_data(ni, dir_ni, dentry,
                                                      args->w);
        if (ret != 0)
@@ -450,25 +450,25 @@ static int do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni,
        }
 
        /* Set DOS (short) name if given */
-       if (dentry->short_name_len != 0) {
-               char *short_name_utf8;
-               size_t short_name_utf8_len;
-               ret = utf16_to_utf8(dentry->short_name,
-                                   dentry->short_name_len,
-                                   &short_name_utf8,
-                                   &short_name_utf8_len);
+       if (dentry_has_short_name(dentry)) {
+               mbchar *short_name_mbs;
+               size_t short_name_mbs_nbytes;
+               ret = utf16le_to_mbs(dentry->short_name,
+                                    dentry->short_name_nbytes,
+                                    &short_name_mbs,
+                                    &short_name_mbs_nbytes);
                if (ret != 0)
                        goto out_close_dir_ni;
 
                DEBUG("Setting short (DOS) name of `%s' to %s",
-                     dentry->full_path_utf8, short_name_utf8);
+                     dentry->full_path, short_name_mbs);
 
-               ret = ntfs_set_ntfs_dos_name(ni, dir_ni, short_name_utf8,
-                                            short_name_utf8_len, 0);
-               FREE(short_name_utf8);
+               ret = ntfs_set_ntfs_dos_name(ni, dir_ni, short_name_mbs,
+                                            short_name_mbs_nbytes, 0);
+               FREE(short_name_mbs);
                if (ret != 0) {
                        ERROR_WITH_ERRNO("Could not set DOS (short) name for `%s'",
-                                        dentry->full_path_utf8);
+                                        dentry->full_path);
                        ret = WIMLIB_ERR_NTFS_3G;
                }
                /* inodes have been closed by ntfs_set_ntfs_dos_name(). */
@@ -481,22 +481,23 @@ out_close_dir_ni:
                                if (ret == 0)
                                        ret = WIMLIB_ERR_NTFS_3G;
                                ERROR_WITH_ERRNO("Failed to close inode for `%s'",
-                                                dentry->full_path_utf8);
+                                                dentry->full_path);
                        }
                }
                if (ntfs_inode_close(dir_ni)) {
                        if (ret == 0)
                                ret = WIMLIB_ERR_NTFS_3G;
                        ERROR_WITH_ERRNO("Failed to close inode of directory "
-                                        "containing `%s'", dentry->full_path_utf8);
+                                        "containing `%s'", dentry->full_path);
                }
        }
 out:
        return ret;
 }
 
-static int apply_root_dentry_ntfs(const struct wim_dentry *dentry,
-                                 ntfs_volume *vol, const WIMStruct *w)
+static int
+apply_root_dentry_ntfs(const struct wim_dentry *dentry,
+                      ntfs_volume *vol, const WIMStruct *w)
 {
        ntfs_inode *ni;
        int ret = 0;
@@ -516,7 +517,8 @@ static int apply_root_dentry_ntfs(const struct wim_dentry *dentry,
 }
 
 /* Applies a WIM dentry to the NTFS volume */
-int apply_dentry_ntfs(struct wim_dentry *dentry, void *arg)
+int
+apply_dentry_ntfs(struct wim_dentry *dentry, void *arg)
 {
        struct apply_args *args = arg;
        ntfs_volume *vol = args->vol;
@@ -562,7 +564,7 @@ int apply_dentry_ntfs(struct wim_dentry *dentry, void *arg)
         * file.  So, this implies that the correct ordering of function calls
         * to extract a NTFS file are:
         *
-        *      if (file has a DOS name) {
+               if (file has a DOS name) {
         *              - Call ntfs_create() to create long name associated with
         *              the DOS name (this initially creates a POSIX name)
         *              - Call ntfs_set_ntfs_dos_name() to associate a DOS name
@@ -579,10 +581,10 @@ int apply_dentry_ntfs(struct wim_dentry *dentry, void *arg)
 again:
        orig_dentry = NULL;
        if (!dentry->d_inode->i_dos_name_extracted &&
-           dentry->short_name_len == 0)
+           !dentry_has_short_name(dentry))
        {
                inode_for_each_dentry(other, dentry->d_inode) {
-                       if (other->short_name_len != 0) {
+                       if (dentry_has_short_name(other)) {
                                orig_dentry = dentry;
                                dentry = other;
                                break;
@@ -605,7 +607,8 @@ again:
 
 /* Transfers the 100-nanosecond precision timestamps from a WIM dentry to a NTFS
  * inode */
-int apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg)
+int
+apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg)
 {
        struct apply_args *args = arg;
        ntfs_volume *vol = args->vol;
@@ -614,12 +617,12 @@ int apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg)
        ntfs_inode *ni;
        int ret;
 
-       DEBUG("Setting timestamps on `%s'", dentry->full_path_utf8);
+       DEBUG("Setting timestamps on `%s'", dentry->full_path);
 
-       ni = ntfs_pathname_to_inode(vol, NULL, dentry->full_path_utf8);
+       ni = ntfs_pathname_to_inode(vol, NULL, dentry->full_path);
        if (!ni) {
                ERROR_WITH_ERRNO("Could not find NTFS inode for `%s'",
-                                dentry->full_path_utf8);
+                                dentry->full_path);
                return WIMLIB_ERR_NTFS_3G;
        }
 
@@ -630,7 +633,7 @@ int apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg)
        ret = ntfs_inode_set_times(ni, (const char*)buf, 3 * sizeof(u64), 0);
        if (ret != 0) {
                ERROR_WITH_ERRNO("Failed to set NTFS timestamps on `%s'",
-                                dentry->full_path_utf8);
+                                dentry->full_path);
                ret = WIMLIB_ERR_NTFS_3G;
        }
 
@@ -638,7 +641,13 @@ int apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg)
                if (ret == 0)
                        ret = WIMLIB_ERR_NTFS_3G;
                ERROR_WITH_ERRNO("Failed to close NTFS inode for `%s'",
-                                dentry->full_path_utf8);
+                                dentry->full_path);
        }
        return ret;
 }
+
+void
+libntfs3g_global_init()
+{
+       ntfs_set_char_encoding(setlocale(LC_ALL, ""));
+}
index d692633..7c04e9b 100644 (file)
@@ -52,7 +52,8 @@
 #include <alloca.h>
 #endif
 
-static inline ntfschar *attr_record_name(ATTR_RECORD *ar)
+static inline ntfschar *
+attr_record_name(ATTR_RECORD *ar)
 {
        return (ntfschar*)((u8*)ar + le16_to_cpu(ar->name_offset));
 }
@@ -68,10 +69,11 @@ static inline ntfschar *attr_record_name(ATTR_RECORD *ar)
  *
  * Return 0 on success or nonzero on error.
  */
-static int ntfs_attr_sha1sum(ntfs_inode *ni, ATTR_RECORD *ar,
-                            u8 md[SHA1_HASH_SIZE],
-                            bool is_reparse_point,
-                            u32 *reparse_tag_ret)
+static int
+ntfs_attr_sha1sum(ntfs_inode *ni, ATTR_RECORD *ar,
+                 u8 md[SHA1_HASH_SIZE],
+                 bool is_reparse_point,
+                 u32 *reparse_tag_ret)
 {
        s64 pos = 0;
        s64 bytes_remaining;
@@ -116,11 +118,14 @@ out_error:
 
 /* Load the streams from a file or reparse point in the NTFS volume into the WIM
  * lookup table */
-static int capture_ntfs_streams(struct wim_dentry *dentry, ntfs_inode *ni,
-                               char path[], size_t path_len,
-                               struct wim_lookup_table *lookup_table,
-                               ntfs_volume **ntfs_vol_p,
-                               ATTR_TYPES type)
+static int
+capture_ntfs_streams(struct wim_dentry *dentry,
+                    ntfs_inode *ni,
+                    mbchar *path,
+                    size_t path_len,
+                    struct wim_lookup_table *lookup_table,
+                    ntfs_volume **ntfs_vol_p,
+                    ATTR_TYPES type)
 {
        ntfs_attr_search_ctx *actx;
        u8 attr_hash[SHA1_HASH_SIZE];
@@ -142,11 +147,9 @@ static int capture_ntfs_streams(struct wim_dentry *dentry, ntfs_inode *ni,
        while (!ntfs_attr_lookup(type, NULL, 0,
                                 CASE_SENSITIVE, 0, NULL, 0, actx))
        {
-               char *stream_name_utf8;
                u32 reparse_tag;
                u64 data_size = ntfs_get_attribute_value_length(actx->attr);
                u64 name_length = actx->attr->name_length;
-
                if (data_size == 0) {
                        if (errno != 0) {
                                ERROR_WITH_ERRNO("Failed to get size of attribute of "
@@ -183,18 +186,18 @@ static int capture_ntfs_streams(struct wim_dentry *dentry, ntfs_inode *ni,
                                if (!ntfs_loc)
                                        goto out_put_actx;
                                ntfs_loc->ntfs_vol_p = ntfs_vol_p;
-                               ntfs_loc->path_utf8 = MALLOC(path_len + 1);
-                               if (!ntfs_loc->path_utf8)
+                               ntfs_loc->path = MALLOC(path_len + 1);
+                               if (!ntfs_loc->path)
                                        goto out_free_ntfs_loc;
-                               memcpy(ntfs_loc->path_utf8, path, path_len + 1);
+                               memcpy(ntfs_loc->path, path, path_len + 1);
                                if (name_length) {
-                                       ntfs_loc->stream_name_utf16 = MALLOC(name_length * 2);
-                                       if (!ntfs_loc->stream_name_utf16)
+                                       ntfs_loc->stream_name = MALLOC(name_length * 2);
+                                       if (!ntfs_loc->stream_name)
                                                goto out_free_ntfs_loc;
-                                       memcpy(ntfs_loc->stream_name_utf16,
+                                       memcpy(ntfs_loc->stream_name,
                                               attr_record_name(actx->attr),
                                               actx->attr->name_length * 2);
-                                       ntfs_loc->stream_name_utf16_num_chars = name_length;
+                                       ntfs_loc->stream_name_nchars = name_length;
                                }
 
                                lte = new_lookup_table_entry();
@@ -212,9 +215,6 @@ static int capture_ntfs_streams(struct wim_dentry *dentry, ntfs_inode *ni,
                                        lte->resource_entry.size = data_size;
                                }
                                ntfs_loc = NULL;
-                               DEBUG("Add resource for `%s' (size = %"PRIu64")",
-                                     dentry->file_name_utf8,
-                                     lte->resource_entry.original_size);
                                copy_hash(lte->hash, attr_hash);
                                lookup_table_insert(lookup_table, lte);
                        }
@@ -222,15 +222,6 @@ static int capture_ntfs_streams(struct wim_dentry *dentry, ntfs_inode *ni,
                if (name_length == 0) {
                        /* Unnamed data stream.  Put the reference to it in the
                         * dentry's inode. */
-               #if 0
-                       if (dentry->d_inode->i_lte) {
-                               ERROR("Found two un-named data streams for "
-                                     "`%s'", path);
-                               ret = WIMLIB_ERR_NTFS_3G;
-                               goto out_free_lte;
-                       }
-                       dentry->d_inode->i_lte = lte;
-               #else
                        if (dentry->d_inode->i_lte) {
                                WARNING("Found two un-named data streams for "
                                        "`%s'", path);
@@ -238,26 +229,17 @@ static int capture_ntfs_streams(struct wim_dentry *dentry, ntfs_inode *ni,
                        } else {
                                dentry->d_inode->i_lte = lte;
                        }
-               #endif
                } else {
                        /* Named data stream.  Put the reference to it in the
                         * alternate data stream entries */
                        struct wim_ads_entry *new_ads_entry;
-                       size_t stream_name_utf8_len;
 
-                       ret = utf16_to_utf8((const char*)attr_record_name(actx->attr),
-                                           name_length * 2,
-                                           &stream_name_utf8,
-                                           &stream_name_utf8_len);
-                       if (ret != 0)
-                               goto out_free_lte;
-                       new_ads_entry = inode_add_ads(dentry->d_inode, stream_name_utf8);
-                       FREE(stream_name_utf8);
+                       new_ads_entry = inode_add_ads_utf16le(dentry->d_inode,
+                                                             attr_record_name(actx->attr),
+                                                             name_length * 2);
                        if (!new_ads_entry)
                                goto out_free_lte;
-
-                       wimlib_assert(new_ads_entry->stream_name_len == name_length * 2);
-
+                       wimlib_assert(new_ads_entry->stream_name_nbytes == name_length * 2);
                        new_ads_entry->lte = lte;
                }
        }
@@ -267,8 +249,8 @@ out_free_lte:
        free_lookup_table_entry(lte);
 out_free_ntfs_loc:
        if (ntfs_loc) {
-               FREE(ntfs_loc->path_utf8);
-               FREE(ntfs_loc->stream_name_utf16);
+               FREE(ntfs_loc->path);
+               FREE(ntfs_loc->stream_name);
                FREE(ntfs_loc);
        }
 out_put_actx:
@@ -288,33 +270,33 @@ struct dos_name_map {
 struct dos_name_node {
        struct rb_node rb_node;
        char dos_name[24];
-       int name_len_bytes;
+       int name_nbytes;
        u64 ntfs_ino;
 };
 
 /* Inserts a new DOS name into the map */
-static int insert_dos_name(struct dos_name_map *map,
-                          const ntfschar *dos_name, int name_len,
-                          u64 ntfs_ino)
+static int
+insert_dos_name(struct dos_name_map *map, const ntfschar *dos_name,
+               size_t name_nbytes, u64 ntfs_ino)
 {
        struct dos_name_node *new_node;
        struct rb_node **p;
        struct rb_root *root;
        struct rb_node *rb_parent;
 
-       DEBUG("DOS name_len = %d", name_len);
+       DEBUG("DOS name_len = %zu", name_nbytes);
        new_node = MALLOC(sizeof(struct dos_name_node));
        if (!new_node)
                return -1;
 
        /* DOS names are supposed to be 12 characters max (that's 24 bytes,
         * assuming 2-byte ntfs characters) */
-       wimlib_assert(name_len * sizeof(ntfschar) <= sizeof(new_node->dos_name));
+       wimlib_assert(name_nbytes <= sizeof(new_node->dos_name));
 
        /* Initialize the DOS name, DOS name length, and NTFS inode number of
         * the red-black tree node */
-       memcpy(new_node->dos_name, dos_name, name_len * sizeof(ntfschar));
-       new_node->name_len_bytes = name_len * sizeof(ntfschar);
+       memcpy(new_node->dos_name, dos_name, name_nbytes);
+       new_node->name_nbytes = name_nbytes;
        new_node->ntfs_ino = ntfs_ino;
 
        /* Insert the red-black tree node */
@@ -364,7 +346,8 @@ lookup_dos_name(const struct dos_name_map *map, u64 ntfs_ino)
        return NULL;
 }
 
-static int set_dentry_dos_name(struct wim_dentry *dentry, void *arg)
+static int
+set_dentry_dos_name(struct wim_dentry *dentry, void *arg)
 {
        const struct dos_name_map *map = arg;
        const struct dos_name_node *node;
@@ -372,12 +355,13 @@ static int set_dentry_dos_name(struct wim_dentry *dentry, void *arg)
        if (dentry->is_win32_name) {
                node = lookup_dos_name(map, dentry->d_inode->i_ino);
                if (node) {
-                       dentry->short_name = MALLOC(node->name_len_bytes);
+                       dentry->short_name = MALLOC(node->name_nbytes + 2);
                        if (!dentry->short_name)
                                return WIMLIB_ERR_NOMEM;
                        memcpy(dentry->short_name, node->dos_name,
-                              node->name_len_bytes);
-                       dentry->short_name_len = node->name_len_bytes;
+                              node->name_nbytes);
+                       dentry->short_name[node->name_nbytes / 2] = 0;
+                       dentry->short_name_nbytes = node->name_nbytes;
                        DEBUG("Assigned DOS name to ino %"PRIu64,
                              dentry->d_inode->i_ino);
                } else {
@@ -389,7 +373,8 @@ static int set_dentry_dos_name(struct wim_dentry *dentry, void *arg)
        return 0;
 }
 
-static void free_dos_name_tree(struct rb_node *node) {
+static void
+free_dos_name_tree(struct rb_node *node) {
        if (node) {
                free_dos_name_tree(node->rb_left);
                free_dos_name_tree(node->rb_right);
@@ -397,7 +382,8 @@ static void free_dos_name_tree(struct rb_node *node) {
        }
 }
 
-static void destroy_dos_name_map(struct dos_name_map *map)
+static void 
+destroy_dos_name_map(struct dos_name_map *map)
 {
        free_dos_name_tree(map->rb_root.rb_node);
 }
@@ -405,7 +391,7 @@ static void destroy_dos_name_map(struct dos_name_map *map)
 struct readdir_ctx {
        struct wim_dentry *parent;
        ntfs_inode *dir_ni;
-       char *path;
+       mbchar *path;
        size_t path_len;
        struct wim_lookup_table *lookup_table;
        struct sd_set *sd_set;
@@ -427,43 +413,45 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p, ntfs_inode *dir_ni,
                                 int add_image_flags,
                                 wimlib_progress_func_t progress_func);
 
-static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
-                                   const int name_len, const int name_type,
-                                   const s64 pos, const MFT_REF mref,
-                                   const unsigned dt_type)
+static int
+wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
+                        const int name_nchars, const int name_type,
+                        const s64 pos, const MFT_REF mref,
+                        const unsigned dt_type)
 {
        struct readdir_ctx *ctx;
-       size_t utf8_name_len;
-       char *utf8_name;
+       size_t mbs_name_nbytes;
+       char *mbs_name;
        struct wim_dentry *child;
        int ret;
        size_t path_len;
+       size_t name_nbytes = name_nchars * sizeof(ntfschar);
 
        ctx = dirent;
        if (name_type & FILE_NAME_DOS) {
                /* If this is the entry for a DOS name, store it for later. */
                ret = insert_dos_name(ctx->dos_name_map, name,
-                                     name_len, mref & MFT_REF_MASK_CPU);
+                                     name_nbytes, mref & MFT_REF_MASK_CPU);
 
                /* Return now if an error occurred or if this is just a DOS name
                 * and not a Win32+DOS name. */
                if (ret != 0 || name_type == FILE_NAME_DOS)
                        return ret;
        }
-       ret = utf16_to_utf8((const char*)name, name_len * 2,
-                           &utf8_name, &utf8_name_len);
+       ret = utf16le_to_mbs(name, name_nbytes,
+                            &mbs_name, &mbs_name_nbytes);
        if (ret != 0)
                return -1;
 
-       if (utf8_name[0] == '.' &&
-            (utf8_name[1] == '\0' ||
-             (utf8_name[1] == '.' && utf8_name[2] == '\0'))) {
+       if (mbs_name[0] == '.' &&
+            (mbs_name[1] == '\0' ||
+             (mbs_name[1] == '.' && mbs_name[2] == '\0'))) {
                /* . or .. entries
                 *
                 * note: name_type is POSIX for these, so DOS names will not
                 * have been inserted for them.  */
                ret = 0;
-               goto out_free_utf8_name;
+               goto out_free_mbs_name;
        }
 
        /* Open the inode for this directory entry and recursively capture the
@@ -471,13 +459,13 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
        ntfs_inode *ni = ntfs_inode_open(ctx->dir_ni->vol, mref);
        if (!ni) {
                ERROR_WITH_ERRNO("Failed to open NTFS inode");
-               goto out_free_utf8_name;
+               goto out_free_mbs_name;
        }
        path_len = ctx->path_len;
        if (path_len != 1)
                ctx->path[path_len++] = '/';
-       memcpy(ctx->path + path_len, utf8_name, utf8_name_len + 1);
-       path_len += utf8_name_len;
+       memcpy(ctx->path + path_len, mbs_name, mbs_name_nbytes + 1);
+       path_len += mbs_name_nbytes;
        child = NULL;
        ret = build_dentry_tree_ntfs_recursive(&child, ctx->dir_ni,
                                               ni, ctx->path, path_len, name_type,
@@ -488,8 +476,8 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
        if (child)
                dentry_add_child(ctx->parent, child);
        ntfs_inode_close(ni);
-out_free_utf8_name:
-       FREE(utf8_name);
+out_free_mbs_name:
+       FREE(mbs_name);
        return ret;
 }
 
@@ -497,18 +485,19 @@ out_free_utf8_name:
  * At the same time, update the WIM lookup table with lookup table entries for
  * the NTFS streams, and build an array of security descriptors.
  */
-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,
-                                           int name_type,
-                                           struct wim_lookup_table *lookup_table,
-                                           struct sd_set *sd_set,
-                                           const struct capture_config *config,
-                                           ntfs_volume **ntfs_vol_p,
-                                           int add_image_flags,
-                                           wimlib_progress_func_t progress_func)
+static int
+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,
+                                const struct capture_config *config,
+                                ntfs_volume **ntfs_vol_p,
+                                int add_image_flags,
+                                wimlib_progress_func_t progress_func)
 {
        u32 attributes;
        int ret;
@@ -552,15 +541,10 @@ static int build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p,
        }
 
        /* Create the new WIM dentry */
-       root = new_dentry_with_timeless_inode(path_basename(path));
-       if (!root) {
-               if (errno == EILSEQ)
-                       return WIMLIB_ERR_INVALID_UTF8_STRING;
-               else if (errno == ENOMEM)
-                       return WIMLIB_ERR_NOMEM;
-               else
-                       return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
-       }
+       ret = new_dentry_with_timeless_inode(path_basename(path), &root);
+       if (ret)
+               return ret;
+
        *root_p = root;
 
        if (name_type & FILE_NAME_WIN32) /* Win32 or Win32+DOS name */
@@ -645,14 +629,15 @@ static int build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p,
        return ret;
 }
 
-int build_dentry_tree_ntfs(struct wim_dentry **root_p,
-                          const char *device,
-                          struct wim_lookup_table *lookup_table,
-                          struct wim_security_data *sd,
-                          const struct capture_config *config,
-                          int add_image_flags,
-                          wimlib_progress_func_t progress_func,
-                          void *extra_arg)
+int
+build_dentry_tree_ntfs(struct wim_dentry **root_p,
+                      const mbchar *device,
+                      struct wim_lookup_table *lookup_table,
+                      struct wim_security_data *sd,
+                      const struct capture_config *config,
+                      int add_image_flags,
+                      wimlib_progress_func_t progress_func,
+                      void *extra_arg)
 {
        ntfs_volume *vol;
        ntfs_inode *root_ni;
@@ -693,9 +678,9 @@ int build_dentry_tree_ntfs(struct wim_dentry **root_p,
                goto out;
        }
 
-       /* Currently we assume that all the UTF-8 paths fit into this length and
-        * there is no check for overflow. */
-       char *path = MALLOC(32768);
+       /* Currently we assume that all the paths fit into this length and there
+        * is no check for overflow. */
+       mbchar *path = MALLOC(32768);
        if (!path) {
                ERROR("Could not allocate memory for NTFS pathname");
                ret = WIMLIB_ERR_NOMEM;
index 0bffb3a..24730ab 100644 (file)
@@ -590,7 +590,7 @@ read_wim_resource(const struct wim_lookup_table_entry *lte, void *buf,
                if (ntfs_attr_pread(lte->attr, offset, size, buf) != size) {
                        ERROR_WITH_ERRNO("Error reading NTFS attribute "
                                         "at `%s'",
-                                        lte->ntfs_loc->path_utf8);
+                                        lte->ntfs_loc->path);
                        ret = WIMLIB_ERR_NTFS_3G;
                }
                break;
index 5c8417c..49f2053 100644 (file)
  * entry resource length.
  */
 static ssize_t
-get_symlink_name(const void *resource, size_t resource_len,
-                void *buf, size_t buf_len,
-                u32 reparse_tag)
+get_symlink_name(const void *resource, size_t resource_len, mbchar *buf,
+                size_t buf_len, u32 reparse_tag)
 {
        const u8 *p = resource;
        u16 substitute_name_offset;
        u16 substitute_name_len;
        u16 print_name_offset;
        u16 print_name_len;
-       char *link_target;
+       mbchar *link_target;
        size_t link_target_len;
        ssize_t ret;
        unsigned header_size;
-       char *translated_target;
+       mbchar *translated_target;
        bool is_absolute;
        u32 flags;
 
@@ -79,7 +78,7 @@ get_symlink_name(const void *resource, size_t resource_len,
        if (header_size + substitute_name_offset + substitute_name_len > resource_len)
                return -EIO;
 
-       ret = utf16_to_utf8((const char *)p + substitute_name_offset,
+       ret = utf16le_to_mbs((const utf16lechar*)(p + substitute_name_offset),
                            substitute_name_len,
                            &link_target, &link_target_len);
        if (ret == WIMLIB_ERR_INVALID_UTF16_STRING)
@@ -133,37 +132,37 @@ static int
 make_symlink_reparse_data_buf(const mbchar *symlink_target,
                              size_t *len_ret, void **buf_ret)
 {
-       size_t utf8_len = strlen(symlink_target);
-       char *name_utf16;
-       size_t utf16_len;
+       utf16lechar *name_utf16le;
+       size_t name_utf16le_nbytes;
        int ret;
 
-       ret = utf8_to_utf16(symlink_target, utf8_len,
-                           &name_utf16, &utf16_len);
+       ret = mbs_to_utf16le(symlink_target, strlen(symlink_target),
+                            &name_utf16le, &name_utf16le_nbytes);
        if (ret != 0)
                return ret;
 
-       for (size_t i = 0; i < utf16_len / 2; i++)
-               if (((u16*)name_utf16)[i] == cpu_to_le16('/'))
-                       ((u16*)name_utf16)[i] = cpu_to_le16('\\');
-       size_t len = 12 + utf16_len * 2;
+       for (size_t i = 0; i < name_utf16le_nbytes / 2; i++)
+               if (name_utf16le[i] == cpu_to_le16('/'))
+                       name_utf16le[i] = cpu_to_le16('\\');
+
+       size_t len = 12 + name_utf16le_nbytes * 2;
        void *buf = MALLOC(len);
        if (buf) {
                u8 *p = buf;
-               p = put_u16(p, utf16_len); /* Substitute name offset */
-               p = put_u16(p, utf16_len); /* Substitute name length */
+               p = put_u16(p, name_utf16le_nbytes); /* Substitute name offset */
+               p = put_u16(p, name_utf16le_nbytes); /* Substitute name length */
                p = put_u16(p, 0); /* Print name offset */
-               p = put_u16(p, utf16_len); /* Print name length */
+               p = put_u16(p, name_utf16le_nbytes); /* Print name length */
                p = put_u32(p, 1); /* flags: 0 iff *full* target, including drive letter??? */
-               p = put_bytes(p, utf16_len, (const u8*)name_utf16);
-               p = put_bytes(p, utf16_len, (const u8*)name_utf16);
+               p = put_bytes(p, name_utf16le_nbytes, name_utf16le);
+               p = put_bytes(p, name_utf16le_nbytes, name_utf16le);
                *len_ret = len;
                *buf_ret = buf;
                ret = 0;
        } else {
                ret = WIMLIB_ERR_NOMEM;
        }
-       FREE(name_utf16);
+       FREE(name_utf16le);
        return ret;
 }
 
index 626fba4..eb0ea9a 100644 (file)
@@ -51,7 +51,7 @@
 static size_t utf16le_strlen(const utf16lechar *s)
 {
        const utf16lechar *p = s;
-       while (p)
+       while (*p)
                p++;
        return (p - s) / sizeof(utf16lechar);
 }
@@ -67,31 +67,31 @@ wimlib_vfprintf(FILE *fp, const char *format, va_list va)
        const char *p;
 
        for (p = format; *p; p++)
-               if (*p == '%' && ((*p + 1) == 'W' || *(p + 1) == 'U'))
+               if (*p == '%' && (*(p + 1) == 'W' || *(p + 1) == 'U'))
                        goto special;
        return vfprintf(fp, format, va);
 special:
        ;
        int n = 0;
        for (p = format; *p; p++) {
-               if (*p == '%' && ((*p + 1) == 'W' || *(p + 1) == 'U')) {
+               if (*p == '%' && (*(p + 1) == 'W' || *(p + 1) == 'U')) {
                        int ret;
                        mbchar *mbs;
-                       size_t mbs_len;
+                       size_t mbs_nbytes;
 
                        if (*(p + 1) == 'W') {
                                utf16lechar *ucs = va_arg(va, utf16lechar*);
                                size_t ucs_nbytes = utf16le_strlen(ucs);
                                ret = utf16le_to_mbs(ucs, ucs_nbytes,
-                                                    &mbs, &mbs_len);
+                                                    &mbs, &mbs_nbytes);
                        } else {
                                utf8char *ucs = va_arg(va, utf8char*);
                                size_t ucs_nbytes = strlen(ucs);
                                ret = utf8_to_mbs(ucs, ucs_nbytes,
-                                                 &mbs, &mbs_len);
+                                                 &mbs, &mbs_nbytes);
                        }
                        if (ret) {
-                               ret = fprintf(fp, "???");
+                               ret = fprintf(fp, "???CONVERSION FAILURE???");
                        } else {
                                ret = fprintf(fp, "%s", mbs);
                                FREE(mbs);
@@ -100,6 +100,7 @@ special:
                                return -1;
                        else
                                n += ret;
+                       p++;
                } else {
                        if (putc(*p, fp) == EOF)
                                return -1;
@@ -348,7 +349,7 @@ static const mbchar *error_strings[] = {
 WIMLIBAPI const mbchar *
 wimlib_get_error_string(enum wimlib_error_code code)
 {
-       if (code < WIMLIB_ERR_SUCCESS || code > WIMLIB_ERR_XML)
+       if (code < 0 || code >= ARRAY_LEN(error_strings))
                return NULL;
        else
                return error_strings[code];
index 71590ff..58a2f2b 100644 (file)
@@ -67,6 +67,40 @@ typedef char utf8char;
 /* A pointer to 'utf16lechar' indicates a UTF-16LE encoded string */
 typedef u16 utf16lechar;
 
+/* encoding.c */
+extern void
+iconv_global_cleanup();
+
+extern bool wimlib_mbs_is_utf8;
+
+#define DECLARE_CHAR_CONVERSION_FUNCTIONS(varname1, varname2,          \
+                                         chartype1, chartype2)         \
+                                                                       \
+extern int                                                             \
+varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
+                                 size_t *out_nbytes_ret);              \
+                                                                       \
+extern int                                                             \
+varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes,  \
+                              chartype2 *out);                         \
+                                                                       \
+extern int                                                             \
+varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes,                \
+                        chartype2 **out_ret,                           \
+                        size_t *out_nbytes_ret);                       \
+
+/* multi-byte string to UTF16-LE string */
+DECLARE_CHAR_CONVERSION_FUNCTIONS(mbs, utf16le, mbchar, utf16lechar);
+
+/* UTF16-LE string to multi-byte string */
+DECLARE_CHAR_CONVERSION_FUNCTIONS(utf16le, mbs, utf16lechar, mbchar);
+
+/* UTF-8 string to multi-byte string */
+DECLARE_CHAR_CONVERSION_FUNCTIONS(utf8, mbs, utf8char, mbchar);
+
+extern bool
+utf8_str_contains_nonascii_chars(const utf8char *utf8_str);
+
 #ifndef min
 #define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
                                        (__a < __b) ? __a : __b; })
index eae4b38..62e9547 100644 (file)
@@ -43,15 +43,15 @@ static int verify_inode(struct wim_inode *inode, const WIMStruct *w)
         * image's security descriptors table. */
        if (inode->i_security_id < -1) {
                ERROR("Dentry `%s' has an invalid security ID (%d)",
-                       first_dentry->full_path_utf8, inode->i_security_id);
+                       first_dentry->full_path, inode->i_security_id);
                goto out;
        }
 
        if (inode->i_security_id >= sd->num_entries) {
                ERROR("Dentry `%s' has an invalid security ID (%d) "
                      "(there are only %u entries in the security table)",
-                       first_dentry->full_path_utf8, inode->i_security_id,
-                       sd->num_entries);
+                     first_dentry->full_path, inode->i_security_id,
+                     sd->num_entries);
                goto out;
        }
 
@@ -68,7 +68,7 @@ static int verify_inode(struct wim_inode *inode, const WIMStruct *w)
                        lte = __lookup_resource(table, hash);
                        if (!lte && !is_zero_hash(hash)) {
                                ERROR("Could not find lookup table entry for stream "
-                                     "%u of dentry `%s'", i, first_dentry->full_path_utf8);
+                                     "%u of dentry `%s'", i, first_dentry->full_path);
                                goto out;
                        }
                        if (lte)
@@ -119,12 +119,12 @@ static int verify_inode(struct wim_inode *inode, const WIMStruct *w)
        for (unsigned i = 0; i <= inode->i_num_ads; i++) {
                const u8 *hash;
                hash = inode_stream_hash_unresolved(inode, i);
-               if (inode_stream_name_len(inode, i) == 0 && !is_zero_hash(hash))
+               if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
                        num_unnamed_streams++;
        }
        if (num_unnamed_streams > 1) {
                ERROR("Dentry `%s' has multiple (%u) un-named streams",
-                     first_dentry->full_path_utf8, num_unnamed_streams);
+                     first_dentry->full_path, num_unnamed_streams);
                goto out;
        }
 
@@ -133,12 +133,12 @@ static int verify_inode(struct wim_inode *inode, const WIMStruct *w)
         * Source: NTFS-3g authors. */
        const struct wim_dentry *dentry_with_dos_name = NULL;
        inode_for_each_dentry(dentry, inode) {
-               if (dentry->short_name_len) {
+               if (dentry_has_short_name(dentry)) {
                        if (dentry_with_dos_name) {
                                ERROR("Hard-linked file has a DOS name at "
                                      "both `%s' and `%s'",
-                                     dentry_with_dos_name->full_path_utf8,
-                                     dentry->full_path_utf8);
+                                     dentry_with_dos_name->full_path,
+                                     dentry->full_path);
                                goto out;
                        }
                        dentry_with_dos_name = dentry;
@@ -148,7 +148,7 @@ static int verify_inode(struct wim_inode *inode, const WIMStruct *w)
        /* Directories with multiple links have not been tested. XXX */
        if (inode->i_nlink > 1 && inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) {
                ERROR("Hard-linked directory `%s' is unsupported",
-                     first_dentry->full_path_utf8);
+                     first_dentry->full_path);
                goto out;
        }
 
@@ -179,15 +179,14 @@ int verify_dentry(struct wim_dentry *dentry, void *wim)
         * into a single WIM dentry, even if they are stored separately on NTFS.
         * (This seems to be the case...) */
        if (dentry_is_root(dentry)) {
-               if (dentry->file_name_len || dentry->short_name_len) {
-                       ERROR("The root dentry is named `%s', but it must "
-                             "be unnamed", dentry->file_name_utf8);
+               if (dentry_has_long_name(dentry) || dentry_has_short_name(dentry)) {
+                       ERROR("The root dentry has a nonempty name!");
                        return WIMLIB_ERR_INVALID_DENTRY;
                }
        } else {
-               if (!dentry->file_name_len) {
-                       ERROR("Dentry `%s' has no long name",
-                             dentry->full_path_utf8);
+               if (!dentry_has_long_name(dentry)) {
+                       ERROR("Dentry `%s' has no long name!",
+                             dentry->full_path);
                        return WIMLIB_ERR_INVALID_DENTRY;
                }
        }
index 6df2c71..45b9fd6 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -48,7 +48,8 @@
 #include "wimlib_internal.h"
 #include "xml.h"
 
-static int image_print_metadata(WIMStruct *w)
+static int
+image_print_metadata(WIMStruct *w)
 {
        DEBUG("Printing metadata for image %d", w->current_image);
        print_security_data(wim_security_data(w));
@@ -57,13 +58,15 @@ static int image_print_metadata(WIMStruct *w)
 }
 
 
-static int image_print_files(WIMStruct *w)
+static int
+image_print_files(WIMStruct *w)
 {
        return for_dentry_in_tree(wim_root_dentry(w), print_dentry_full_path,
                                  NULL);
 }
 
-static WIMStruct *new_wim_struct()
+static WIMStruct *
+new_wim_struct()
 {
        WIMStruct *w = CALLOC(1, sizeof(WIMStruct));
 #ifdef WITH_FUSE
@@ -83,7 +86,8 @@ static WIMStruct *new_wim_struct()
  * current image in turn.  If @image is a certain image, @visitor is called on
  * the WIM only once, with that image selected.
  */
-int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *))
+int
+for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *))
 {
        int ret;
        int start;
@@ -110,7 +114,8 @@ int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *))
        return 0;
 }
 
-static int sort_image_metadata_by_position(const void *p1, const void *p2)
+static int
+sort_image_metadata_by_position(const void *p1, const void *p2)
 {
        const struct wim_image_metadata *imd1 = p1;
        const struct wim_image_metadata *imd2 = p2;
@@ -128,8 +133,8 @@ static int sort_image_metadata_by_position(const void *p1, const void *p2)
  * If @lte points to a metadata resource, append it to the list of metadata
  * resources in the WIMStruct.  Otherwise, do nothing.
  */
-static int append_metadata_resource_entry(struct wim_lookup_table_entry *lte,
-                                         void *wim_p)
+static int
+append_metadata_resource_entry(struct wim_lookup_table_entry *lte, void *wim_p)
 {
        WIMStruct *w = wim_p;
        int ret = 0;
@@ -153,7 +158,8 @@ static int append_metadata_resource_entry(struct wim_lookup_table_entry *lte,
 }
 
 /* Returns the compression type given in the flags of a WIM header. */
-static int wim_hdr_flags_compression_type(int wim_hdr_flags)
+static int
+wim_hdr_flags_compression_type(int wim_hdr_flags)
 {
        if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESSION) {
                if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESS_LZX)
@@ -170,7 +176,8 @@ static int wim_hdr_flags_compression_type(int wim_hdr_flags)
 /*
  * Creates a WIMStruct for a new WIM file.
  */
-WIMLIBAPI int wimlib_create_new_wim(int ctype, WIMStruct **w_ret)
+WIMLIBAPI int
+wimlib_create_new_wim(int ctype, WIMStruct **w_ret)
 {
        WIMStruct *w;
        struct wim_lookup_table *table;
@@ -201,12 +208,14 @@ out_free:
        return ret;
 }
 
-WIMLIBAPI int wimlib_get_num_images(const WIMStruct *w)
+WIMLIBAPI int
+wimlib_get_num_images(const WIMStruct *w)
 {
        return w->hdr.image_count;
 }
 
-int select_wim_image(WIMStruct *w, int image)
+int
+select_wim_image(WIMStruct *w, int image)
 {
        struct wim_image_metadata *imd;
        int ret;
@@ -258,12 +267,14 @@ int select_wim_image(WIMStruct *w, int image)
 
 
 /* Returns the compression type of the WIM file. */
-WIMLIBAPI int wimlib_get_compression_type(const WIMStruct *w)
+WIMLIBAPI int
+wimlib_get_compression_type(const WIMStruct *w)
 {
        return wim_hdr_flags_compression_type(w->hdr.flags);
 }
 
-WIMLIBAPI const char *wimlib_get_compression_type_string(int ctype)
+WIMLIBAPI const char *
+wimlib_get_compression_type_string(int ctype)
 {
        switch (ctype) {
                case WIMLIB_COMPRESSION_TYPE_NONE:
@@ -282,7 +293,8 @@ WIMLIBAPI const char *wimlib_get_compression_type_string(int ctype)
  * the number of the image, or the name of the image.  The images are numbered
  * starting at 1.
  */
-WIMLIBAPI int wimlib_resolve_image(WIMStruct *w, const char *image_name_or_num)
+WIMLIBAPI int
+wimlib_resolve_image(WIMStruct *w, const utf8char *image_name_or_num)
 {
        char *p;
        int image;
@@ -311,7 +323,8 @@ WIMLIBAPI int wimlib_resolve_image(WIMStruct *w, const char *image_name_or_num)
 
 
 /* Prints some basic information about a WIM file. */
-WIMLIBAPI void wimlib_print_wim_information(const WIMStruct *w)
+WIMLIBAPI void
+wimlib_print_wim_information(const WIMStruct *w)
 {
        const struct wim_header *hdr;
 
@@ -333,12 +346,14 @@ WIMLIBAPI void wimlib_print_wim_information(const WIMStruct *w)
        putchar('\n');
 }
 
-WIMLIBAPI bool wimlib_has_integrity_table(const WIMStruct *w)
+WIMLIBAPI bool
+wimlib_has_integrity_table(const WIMStruct *w)
 {
        return w->hdr.integrity.size != 0;
 }
 
-WIMLIBAPI void wimlib_print_available_images(const WIMStruct *w, int image)
+WIMLIBAPI void
+wimlib_print_available_images(const WIMStruct *w, int image)
 {
        int first;
        int last;
@@ -367,7 +382,8 @@ WIMLIBAPI void wimlib_print_available_images(const WIMStruct *w, int image)
 
 /* Prints the metadata for the specified image, which may be WIMLIB_ALL_IMAGES, but
  * not WIMLIB_NO_IMAGE. */
-WIMLIBAPI int wimlib_print_metadata(WIMStruct *w, int image)
+WIMLIBAPI int
+wimlib_print_metadata(WIMStruct *w, int image)
 {
        if (w->hdr.part_number != 1) {
                ERROR("Cannot show the metadata from part %hu of a %hu-part split WIM!",
@@ -378,7 +394,8 @@ WIMLIBAPI int wimlib_print_metadata(WIMStruct *w, int image)
        return for_image(w, image, image_print_metadata);
 }
 
-WIMLIBAPI int wimlib_print_files(WIMStruct *w, int image)
+WIMLIBAPI int
+wimlib_print_files(WIMStruct *w, int image)
 {
        if (w->hdr.part_number != 1) {
                ERROR("Cannot list the files from part %hu of a %hu-part split WIM!",
@@ -390,7 +407,8 @@ WIMLIBAPI int wimlib_print_files(WIMStruct *w, int image)
 }
 
 /* Sets the index of the bootable image. */
-WIMLIBAPI int wimlib_set_boot_idx(WIMStruct *w, int boot_idx)
+WIMLIBAPI int
+wimlib_set_boot_idx(WIMStruct *w, int boot_idx)
 {
        if (w->hdr.total_parts != 1) {
                ERROR("Cannot modify the boot index of a split WIM!");
@@ -413,7 +431,8 @@ WIMLIBAPI int wimlib_set_boot_idx(WIMStruct *w, int boot_idx)
        return 0;
 }
 
-WIMLIBAPI int wimlib_get_part_number(const WIMStruct *w, int *total_parts_ret)
+WIMLIBAPI int
+wimlib_get_part_number(const WIMStruct *w, int *total_parts_ret)
 {
        if (total_parts_ret)
                *total_parts_ret = w->hdr.total_parts;
@@ -421,7 +440,8 @@ WIMLIBAPI int wimlib_get_part_number(const WIMStruct *w, int *total_parts_ret)
 }
 
 
-WIMLIBAPI int wimlib_get_boot_idx(const WIMStruct *w)
+WIMLIBAPI int
+wimlib_get_boot_idx(const WIMStruct *w)
 {
        return w->hdr.boot_idx;
 }
@@ -430,8 +450,9 @@ WIMLIBAPI int wimlib_get_boot_idx(const WIMStruct *w)
  * Begins the reading of a WIM file; opens the file and reads its header and
  * lookup table, and optionally checks the integrity.
  */
-static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags,
-                     wimlib_progress_func_t progress_func)
+static int
+begin_read(WIMStruct *w, const mbchar *in_wim_path, int open_flags,
+          wimlib_progress_func_t progress_func)
 {
        int ret;
        int xml_num_images;
@@ -563,13 +584,13 @@ static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags,
        return 0;
 }
 
-
 /*
  * Opens a WIM file and creates a WIMStruct for it.
  */
-WIMLIBAPI int wimlib_open_wim(const char *wim_file, int open_flags,
-                             WIMStruct **w_ret,
-                             wimlib_progress_func_t progress_func)
+WIMLIBAPI int
+wimlib_open_wim(const mbchar *wim_file, int open_flags,
+               WIMStruct **w_ret,
+               wimlib_progress_func_t progress_func)
 {
        WIMStruct *w;
        int ret;
@@ -589,8 +610,9 @@ WIMLIBAPI int wimlib_open_wim(const char *wim_file, int open_flags,
        return ret;
 }
 
-void destroy_image_metadata(struct wim_image_metadata *imd,
-                           struct wim_lookup_table *table)
+void
+destroy_image_metadata(struct wim_image_metadata *imd,
+                      struct wim_lookup_table *table)
 {
        free_dentry_tree(imd->root_dentry, table);
        free_security_data(imd->security_data);
@@ -605,7 +627,8 @@ void destroy_image_metadata(struct wim_image_metadata *imd,
 
 /* Frees the memory for the WIMStruct, including all internal memory; also
  * closes all files associated with the WIMStruct.  */
-WIMLIBAPI void wimlib_free(WIMStruct *w)
+WIMLIBAPI void
+wimlib_free(WIMStruct *w)
 {
        DEBUG("Freeing WIMStruct");
 
@@ -650,18 +673,21 @@ bool wimlib_mbs_is_utf8;
 
 /* Get global memory allocations out of the way.  Not strictly necessary in
  * single-threaded programs like 'imagex'. */
-WIMLIBAPI int wimlib_global_init()
+WIMLIBAPI int
+wimlib_global_init()
 {
-       char *encoding;
-
        libxml_global_init();
+#ifdef WITH_NTFS_3G
+       libntfs3g_global_init();
+#endif
        wimlib_mbs_is_utf8 = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0);
-       return iconv_global_init();
+       return 0;
 }
 
 /* Free global memory allocations.  Not strictly necessary if the process using
  * wimlib is just about to exit (as is the case for 'imagex'). */
-WIMLIBAPI void wimlib_global_cleanup()
+WIMLIBAPI void
+wimlib_global_cleanup()
 {
        libxml_global_cleanup();
        iconv_global_cleanup();
index 580960f..be06daf 100644 (file)
@@ -376,54 +376,6 @@ extern int
 add_new_dentry_tree(WIMStruct *dest_wim, struct wim_dentry *root,
                    struct wim_security_data *sd);
 
-/* encoding.c */
-
-#if defined(WITH_NTFS_3G) || defined(__WIN32__)
-
-static inline int
-iconv_global_init()
-{
-       return 0;
-}
-
-static inline void
-iconv_global_cleanup() { }
-#else
-extern int
-iconv_global_init();
-
-extern void
-iconv_global_cleanup();
-#endif
-
-extern bool wimlib_mbs_is_utf8;
-
-extern bool
-utf8_str_contains_nonascii_chars(const utf8char *utf8_str);
-
-extern int
-mbs_to_utf16le_nbytes(const mbchar *mbs, size_t mbs_nbytes,
-                     size_t *utf16le_nbytes_ret);
-
-extern int
-utf16le_to_mbs_nbytes(const utf16lechar *utf16le_str,
-                     size_t utf16le_nbytes, size_t *mbs_nbytes_ret);
-
-extern int
-mbs_to_utf16le_buf(const mbchar *mbs, size_t mbs_nbytes,
-                  utf16lechar *utf16le_str);
-
-extern int
-utf16le_to_mbs_buf(const utf16lechar *utf16le_str, size_t utf16le_nbytes,
-                  mbchar *mbs);
-
-extern int
-mbs_to_utf16le(const mbchar *mbs, size_t mbs_nbytes,
-              utf16lechar **utf16le_str_ret, size_t *utf16le_nbytes_ret);
-
-extern int
-utf16le_to_mbs(const utf16lechar *utf16le_str, size_t utf16le_nbytes,
-              mbchar **mbs_ret, size_t *mbs_nbytes_ret);
 
 /* extract_image.c */
 
@@ -504,6 +456,9 @@ apply_dentry_ntfs(struct wim_dentry *dentry, void *arg);
 extern int
 apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg);
 
+extern void
+libntfs3g_global_init();
+
 /* ntfs-capture.c */
 extern int
 build_dentry_tree_ntfs(struct wim_dentry **root_p,
index a05d281..bd5b05e 100644 (file)
@@ -67,7 +67,8 @@
 
 #include <limits.h>
 
-static int fflush_and_ftruncate(FILE *fp, off_t size)
+static int
+fflush_and_ftruncate(FILE *fp, off_t size)
 {
        int ret;
 
@@ -161,7 +162,8 @@ out:
  */
 typedef int (*compress_func_t)(const void *, unsigned, void *, unsigned *);
 
-compress_func_t get_compress_func(int out_ctype)
+compress_func_t
+get_compress_func(int out_ctype)
 {
        if (out_ctype == WIMLIB_COMPRESSION_TYPE_LZX)
                return lzx_compress;
@@ -182,9 +184,10 @@ compress_func_t get_compress_func(int out_ctype)
  *
  * Returns 0 on success; nonzero on failure.
  */
-static int write_wim_resource_chunk(const u8 chunk[], unsigned chunk_size,
-                                   FILE *out_fp, compress_func_t compress,
-                                   struct chunk_table *chunk_tab)
+static int
+write_wim_resource_chunk(const u8 chunk[], unsigned chunk_size,
+                        FILE *out_fp, compress_func_t compress,
+                        struct chunk_table *chunk_tab)
 {
        const u8 *out_chunk;
        unsigned out_chunk_size;
@@ -256,12 +259,13 @@ finish_wim_resource_chunk_tab(struct chunk_table *chunk_tab,
 
 /* Prepare for multiple reads to a resource by caching a FILE * or NTFS
  * attribute pointer in the lookup table entry. */
-static int prepare_resource_for_read(struct wim_lookup_table_entry *lte
+static int
+prepare_resource_for_read(struct wim_lookup_table_entry *lte
 
-                                       #ifdef WITH_NTFS_3G
-                                       , ntfs_inode **ni_ret
-                                       #endif
-               )
+                               #ifdef WITH_NTFS_3G
+                               , ntfs_inode **ni_ret
+                               #endif
+                       )
 {
        switch (lte->resource_location) {
        case RESOURCE_IN_FILE_ON_DISK:
@@ -280,19 +284,19 @@ static int prepare_resource_for_read(struct wim_lookup_table_entry *lte
                        struct ntfs_location *loc = lte->ntfs_loc;
                        ntfs_inode *ni;
                        wimlib_assert(loc);
-                       ni = ntfs_pathname_to_inode(*loc->ntfs_vol_p, NULL, loc->path_utf8);
+                       ni = ntfs_pathname_to_inode(*loc->ntfs_vol_p, NULL, loc->path);
                        if (!ni) {
                                ERROR_WITH_ERRNO("Failed to open inode `%s' in NTFS "
-                                                "volume", loc->path_utf8);
+                                                "volume", loc->path);
                                return WIMLIB_ERR_NTFS_3G;
                        }
                        lte->attr = ntfs_attr_open(ni,
                                                   loc->is_reparse_point ? AT_REPARSE_POINT : AT_DATA,
-                                                  (ntfschar*)loc->stream_name_utf16,
-                                                  loc->stream_name_utf16_num_chars);
+                                                  loc->stream_name,
+                                                  loc->stream_name_nchars);
                        if (!lte->attr) {
                                ERROR_WITH_ERRNO("Failed to open attribute of `%s' in "
-                                                "NTFS volume", loc->path_utf8);
+                                                "NTFS volume", loc->path);
                                ntfs_inode_close(ni);
                                return WIMLIB_ERR_NTFS_3G;
                        }
@@ -317,11 +321,12 @@ static int prepare_resource_for_read(struct wim_lookup_table_entry *lte
 
 /* Undo prepare_resource_for_read() by closing the cached FILE * or NTFS
  * attribute. */
-static void end_wim_resource_read(struct wim_lookup_table_entry *lte
-                               #ifdef WITH_NTFS_3G
-                                       , ntfs_inode *ni
-                               #endif
-                                       )
+static void 
+end_wim_resource_read(struct wim_lookup_table_entry *lte
+                       #ifdef WITH_NTFS_3G
+                               , ntfs_inode *ni
+                       #endif
+                       )
 {
        if (lte->resource_location == RESOURCE_IN_FILE_ON_DISK
            && lte->file_on_disk_fp)
@@ -391,10 +396,11 @@ write_uncompressed_resource_and_truncate(struct wim_lookup_table_entry *lte,
  *
  * Returns 0 on success; nonzero on failure.
  */
-int write_wim_resource(struct wim_lookup_table_entry *lte,
-                      FILE *out_fp, int out_ctype,
-                      struct resource_entry *out_res_entry,
-                      int flags)
+int
+write_wim_resource(struct wim_lookup_table_entry *lte,
+                  FILE *out_fp, int out_ctype,
+                  struct resource_entry *out_res_entry,
+                  int flags)
 {
        u64 bytes_remaining;
        u64 original_size;
@@ -588,7 +594,8 @@ struct shared_queue {
        pthread_cond_t space_avail_cond;
 };
 
-static int shared_queue_init(struct shared_queue *q, unsigned size)
+static int
+shared_queue_init(struct shared_queue *q, unsigned size)
 {
        wimlib_assert(size != 0);
        q->array = CALLOC(sizeof(q->array[0]), size);
@@ -604,7 +611,8 @@ static int shared_queue_init(struct shared_queue *q, unsigned size)
        return 0;
 }
 
-static void shared_queue_destroy(struct shared_queue *q)
+static void
+shared_queue_destroy(struct shared_queue *q)
 {
        FREE(q->array);
        pthread_mutex_destroy(&q->lock);
@@ -612,7 +620,8 @@ static void shared_queue_destroy(struct shared_queue *q)
        pthread_cond_destroy(&q->space_avail_cond);
 }
 
-static void shared_queue_put(struct shared_queue *q, void *obj)
+static void
+shared_queue_put(struct shared_queue *q, void *obj)
 {
        pthread_mutex_lock(&q->lock);
        while (q->filled_slots == q->size)
@@ -626,7 +635,8 @@ static void shared_queue_put(struct shared_queue *q, void *obj)
        pthread_mutex_unlock(&q->lock);
 }
 
-static void *shared_queue_get(struct shared_queue *q)
+static void *
+shared_queue_get(struct shared_queue *q)
 {
        void *obj;
 
@@ -665,7 +675,8 @@ struct message {
        u64 begin_chunk;
 };
 
-static void compress_chunks(struct message *msg, compress_func_t compress)
+static void
+compress_chunks(struct message *msg, compress_func_t compress)
 {
        for (unsigned i = 0; i < msg->num_chunks; i++) {
                DEBUG2("compress chunk %u of %u", i, msg->num_chunks);
@@ -687,7 +698,8 @@ static void compress_chunks(struct message *msg, compress_func_t compress)
  * res_to_compress_queue, compress them, and put them in the
  * compressed_res_queue.  A NULL pointer indicates that the thread should stop.
  * */
-static void *compressor_thread_proc(void *arg)
+static void *
+compressor_thread_proc(void *arg)
 {
        struct compressor_thread_params *params = arg;
        struct shared_queue *res_to_compress_queue = params->res_to_compress_queue;
@@ -703,14 +715,15 @@ static void *compressor_thread_proc(void *arg)
        DEBUG("Compressor thread terminating");
        return NULL;
 }
-#endif
+#endif /* ENABLE_MULTITHREADED_COMPRESSION */
 
-static int do_write_stream_list(struct list_head *my_resources,
-                               FILE *out_fp,
-                               int out_ctype,
-                               wimlib_progress_func_t progress_func,
-                               union wimlib_progress_info *progress,
-                               int write_resource_flags)
+static int
+do_write_stream_list(struct list_head *my_resources,
+                    FILE *out_fp,
+                    int out_ctype,
+                    wimlib_progress_func_t progress_func,
+                    union wimlib_progress_info *progress,
+                    int write_resource_flags)
 {
        int ret;
        struct wim_lookup_table_entry *lte, *tmp;
@@ -735,12 +748,13 @@ static int do_write_stream_list(struct list_head *my_resources,
        return 0;
 }
 
-static int write_stream_list_serial(struct list_head *stream_list,
-                                   FILE *out_fp,
-                                   int out_ctype,
-                                   int write_flags,
-                                   wimlib_progress_func_t progress_func,
-                                   union wimlib_progress_info *progress)
+static int
+write_stream_list_serial(struct list_head *stream_list,
+                        FILE *out_fp,
+                        int out_ctype,
+                        int write_flags,
+                        wimlib_progress_func_t progress_func,
+                        union wimlib_progress_info *progress)
 {
        int write_resource_flags;
 
@@ -757,8 +771,9 @@ static int write_stream_list_serial(struct list_head *stream_list,
 }
 
 #ifdef ENABLE_MULTITHREADED_COMPRESSION
-static int write_wim_chunks(struct message *msg, FILE *out_fp,
-                           struct chunk_table *chunk_tab)
+static int
+write_wim_chunks(struct message *msg, FILE *out_fp,
+                struct chunk_table *chunk_tab)
 {
        for (unsigned i = 0; i < msg->num_chunks; i++) {
                unsigned chunk_csize = msg->compressed_chunk_sizes[i];
@@ -791,15 +806,16 @@ static int write_wim_chunks(struct message *msg, FILE *out_fp,
  * res_to_compress_queue, and it is passed back through the
  * compressed_res_queue.
  */
-static int main_writer_thread_proc(struct list_head *stream_list,
-                                  FILE *out_fp,
-                                  int out_ctype,
-                                  struct shared_queue *res_to_compress_queue,
-                                  struct shared_queue *compressed_res_queue,
-                                  size_t num_messages,
-                                  int write_flags,
-                                  wimlib_progress_func_t progress_func,
-                                  union wimlib_progress_info *progress)
+static int
+main_writer_thread_proc(struct list_head *stream_list,
+                       FILE *out_fp,
+                       int out_ctype,
+                       struct shared_queue *res_to_compress_queue,
+                       struct shared_queue *compressed_res_queue,
+                       size_t num_messages,
+                       int write_flags,
+                       wimlib_progress_func_t progress_func,
+                       union wimlib_progress_info *progress)
 {
        int ret;
        struct chunk_table *cur_chunk_tab = NULL;
@@ -1211,7 +1227,8 @@ out:
        return ret;
 }
 
-static long get_default_num_threads()
+static long
+get_default_num_threads()
 {
 #ifdef __WIN32__
        return win32_get_number_of_processors();
@@ -1220,13 +1237,14 @@ static long get_default_num_threads()
 #endif
 }
 
-static int write_stream_list_parallel(struct list_head *stream_list,
-                                     FILE *out_fp,
-                                     int out_ctype,
-                                     int write_flags,
-                                     unsigned num_threads,
-                                     wimlib_progress_func_t progress_func,
-                                     union wimlib_progress_info *progress)
+static int
+write_stream_list_parallel(struct list_head *stream_list,
+                          FILE *out_fp,
+                          int out_ctype,
+                          int write_flags,
+                          unsigned num_threads,
+                          wimlib_progress_func_t progress_func,
+                          union wimlib_progress_info *progress)
 {
        int ret;
        struct shared_queue res_to_compress_queue;
@@ -1328,10 +1346,11 @@ out_serial:
  * Write a list of streams to a WIM (@out_fp) using the compression type
  * @out_ctype and up to @num_threads compressor threads.
  */
-static int write_stream_list(struct list_head *stream_list, FILE *out_fp,
-                            int out_ctype, int write_flags,
-                            unsigned num_threads,
-                            wimlib_progress_func_t progress_func)
+static int
+write_stream_list(struct list_head *stream_list, FILE *out_fp,
+                 int out_ctype, int write_flags,
+                 unsigned num_threads,
+                 wimlib_progress_func_t progress_func)
 {
        struct wim_lookup_table_entry *lte;
        size_t num_streams = 0;
@@ -1381,7 +1400,8 @@ struct lte_overwrite_prepare_args {
        struct list_head *stream_list;
 };
 
-static int lte_overwrite_prepare(struct wim_lookup_table_entry *lte, void *arg)
+static int
+lte_overwrite_prepare(struct wim_lookup_table_entry *lte, void *arg)
 {
        struct lte_overwrite_prepare_args *args = arg;
 
@@ -1407,8 +1427,9 @@ static int lte_overwrite_prepare(struct wim_lookup_table_entry *lte, void *arg)
        return 0;
 }
 
-static int wim_find_new_streams(WIMStruct *wim, off_t end_offset,
-                               struct list_head *stream_list)
+static int
+wim_find_new_streams(WIMStruct *wim, off_t end_offset,
+                    struct list_head *stream_list)
 {
        struct lte_overwrite_prepare_args args = {
                .wim         = wim,
@@ -1420,9 +1441,10 @@ static int wim_find_new_streams(WIMStruct *wim, off_t end_offset,
                                      lte_overwrite_prepare, &args);
 }
 
-static int inode_find_streams_to_write(struct wim_inode *inode,
-                                      struct wim_lookup_table *table,
-                                      struct list_head *stream_list)
+static int
+inode_find_streams_to_write(struct wim_inode *inode,
+                           struct wim_lookup_table *table,
+                           struct list_head *stream_list)
 {
        struct wim_lookup_table_entry *lte;
        for (unsigned i = 0; i <= inode->i_num_ads; i++) {
@@ -1436,7 +1458,8 @@ static int inode_find_streams_to_write(struct wim_inode *inode,
        return 0;
 }
 
-static int image_find_streams_to_write(WIMStruct *w)
+static int
+image_find_streams_to_write(WIMStruct *w)
 {
        struct wim_inode *inode;
        struct hlist_node *cur;
@@ -1450,7 +1473,8 @@ static int image_find_streams_to_write(WIMStruct *w)
        return 0;
 }
 
-static int write_wim_streams(WIMStruct *w, int image, int write_flags,
+static int
+write_wim_streams(WIMStruct *w, int image, int write_flags,
                             unsigned num_threads,
                             wimlib_progress_func_t progress_func)
 {
@@ -1493,8 +1517,9 @@ static int write_wim_streams(WIMStruct *w, int image, int write_flags,
  *             fsync() the output file before closing it.
  *
  */
-int finish_write(WIMStruct *w, int image, int write_flags,
-                wimlib_progress_func_t progress_func)
+int
+finish_write(WIMStruct *w, int image, int write_flags,
+            wimlib_progress_func_t progress_func)
 {
        int ret;
        struct wim_header hdr;
@@ -1627,7 +1652,8 @@ out:
 }
 
 #if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
-int lock_wim(WIMStruct *w, FILE *fp)
+int
+lock_wim(WIMStruct *w, FILE *fp)
 {
        int ret = 0;
        if (fp && !w->wim_locked) {
@@ -1651,8 +1677,9 @@ int lock_wim(WIMStruct *w, FILE *fp)
 }
 #endif
 
-static int open_wim_writable(WIMStruct *w, const char *path,
-                            bool trunc, bool readable)
+static int
+open_wim_writable(WIMStruct *w, const mbchar *path,
+                 bool trunc, bool readable)
 {
        const char *mode;
        if (trunc)
@@ -1674,7 +1701,8 @@ static int open_wim_writable(WIMStruct *w, const char *path,
 }
 
 
-void close_wim_writable(WIMStruct *w)
+void
+close_wim_writable(WIMStruct *w)
 {
        if (w->out_fp) {
                if (fclose(w->out_fp) != 0) {
@@ -1685,7 +1713,8 @@ void close_wim_writable(WIMStruct *w)
 }
 
 /* Open file stream and write dummy header for WIM. */
-int begin_write(WIMStruct *w, const char *path, int write_flags)
+int
+begin_write(WIMStruct *w, const mbchar *path, int write_flags)
 {
        int ret;
        ret = open_wim_writable(w, path, true,
@@ -1697,9 +1726,10 @@ int begin_write(WIMStruct *w, const char *path, int write_flags)
 }
 
 /* Writes a stand-alone WIM to a file.  */
-WIMLIBAPI int wimlib_write(WIMStruct *w, const char *path,
-                          int image, int write_flags, unsigned num_threads,
-                          wimlib_progress_func_t progress_func)
+WIMLIBAPI int
+wimlib_write(WIMStruct *w, const mbchar *path,
+            int image, int write_flags, unsigned num_threads,
+            wimlib_progress_func_t progress_func)
 {
        int ret;
 
@@ -1743,7 +1773,8 @@ out:
        return ret;
 }
 
-static bool any_images_modified(WIMStruct *w)
+static bool
+any_images_modified(WIMStruct *w)
 {
        for (int i = 0; i < w->hdr.image_count; i++)
                if (w->image_metadata[i].modified)
@@ -1808,9 +1839,10 @@ static bool any_images_modified(WIMStruct *w)
  * table, xml data, and integrity table were.  (These usually only take up a
  * small amount of space compared to the streams, however.)
  */
-static int overwrite_wim_inplace(WIMStruct *w, int write_flags,
-                                unsigned num_threads,
-                                wimlib_progress_func_t progress_func)
+static int
+overwrite_wim_inplace(WIMStruct *w, int write_flags,
+                     unsigned num_threads,
+                     wimlib_progress_func_t progress_func)
 {
        int ret;
        struct list_head stream_list;
@@ -1913,9 +1945,10 @@ out_ftruncate:
        return ret;
 }
 
-static int overwrite_wim_via_tmpfile(WIMStruct *w, int write_flags,
-                                    unsigned num_threads,
-                                    wimlib_progress_func_t progress_func)
+static int
+overwrite_wim_via_tmpfile(WIMStruct *w, int write_flags,
+                         unsigned num_threads,
+                         wimlib_progress_func_t progress_func)
 {
        size_t wim_name_len;
        int ret;
@@ -1925,7 +1958,7 @@ static int overwrite_wim_via_tmpfile(WIMStruct *w, int write_flags,
        /* Write the WIM to a temporary file in the same directory as the
         * original WIM. */
        wim_name_len = strlen(w->filename);
-       char tmpfile[wim_name_len + 10];
+       mbchar tmpfile[wim_name_len + 10];
        memcpy(tmpfile, w->filename, wim_name_len);
        randomize_char_array_with_alnum(tmpfile + wim_name_len, 9);
        tmpfile[wim_name_len + 9] = '\0';
@@ -1981,9 +2014,10 @@ err:
 /*
  * Writes a WIM file to the original file that it was read from, overwriting it.
  */
-WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags,
-                              unsigned num_threads,
-                              wimlib_progress_func_t progress_func)
+WIMLIBAPI int
+wimlib_overwrite(WIMStruct *w, int write_flags,
+                unsigned num_threads,
+                wimlib_progress_func_t progress_func)
 {
        write_flags &= WIMLIB_WRITE_MASK_PUBLIC;
 
index 6515ee9..0ea13f8 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -1074,7 +1074,7 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg)
 
        if (inode->i_nlink >= 2 && dentry_is_first_in_inode(dentry)) {
                for (unsigned i = 0; i < inode->i_num_ads; i++) {
-                       if (inode->i_ads_entries[i].stream_name_len) {
+                       if (inode->i_ads_entries[i].stream_name_nbytes) {
                                lte = inode_stream_lte(inode, i + 1, lookup_table);
                                if (lte) {
                                        info->hard_link_bytes += inode->i_nlink *
@@ -1266,8 +1266,8 @@ read_xml_data(FILE *fp, const struct resource_entry *res_entry,
 
        DEBUG("Parsing XML using libxml2 to create XML tree");
 
-       doc = xmlReadMemory(xml_data, res_entry->size,
-                           "noname.xml", "UTF-16", 0);
+       doc = xmlReadMemory((const char *)xml_data,
+                           res_entry->size, "noname.xml", "UTF-16", 0);
 
        if (!doc) {
                ERROR("Failed to parse XML data");