]> wimlib.net Git - wimlib/blobdiff - src/inode.c
Update progress functions
[wimlib] / src / inode.c
index 539d5667b5949952a3ea65b9b78444f719fef44e..9eab0d7b534ecb2e3f29b90997ca700b6268c50b 100644 (file)
@@ -141,89 +141,51 @@ struct wim_ads_entry *
 inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name,
                    u16 *idx_ret)
 {
-       if (inode->i_num_ads == 0) {
-               return NULL;
-       } else {
-               size_t stream_name_utf16le_nbytes;
-               u16 i;
-               struct wim_ads_entry *result;
+       int ret;
+       const utf16lechar *stream_name_utf16le;
+       size_t stream_name_utf16le_nbytes;
+       u16 i;
+       struct wim_ads_entry *result;
 
-               if (stream_name[0] == T('\0'))
-                       return NULL;
+       if (inode->i_num_ads == 0)
+               return NULL;
 
-       #if TCHAR_IS_UTF16LE
-               const utf16lechar *stream_name_utf16le;
+       if (stream_name[0] == T('\0'))
+               return NULL;
 
-               stream_name_utf16le = stream_name;
-               stream_name_utf16le_nbytes = tstrlen(stream_name) * sizeof(tchar);
-       #else
-               utf16lechar *stream_name_utf16le;
+       ret = tstr_get_utf16le_and_len(stream_name, &stream_name_utf16le,
+                                      &stream_name_utf16le_nbytes);
+       if (ret)
+               return NULL;
 
+       i = 0;
+       result = NULL;
+       do {
+               if (ads_entry_has_name(&inode->i_ads_entries[i],
+                                      stream_name_utf16le,
+                                      stream_name_utf16le_nbytes,
+                                      default_ignore_case))
                {
-                       int ret = tstr_to_utf16le(stream_name,
-                                                 tstrlen(stream_name) *
-                                                     sizeof(tchar),
-                                                 &stream_name_utf16le,
-                                                 &stream_name_utf16le_nbytes);
-                       if (ret)
-                               return NULL;
+                       if (idx_ret)
+                               *idx_ret = i;
+                       result = &inode->i_ads_entries[i];
+                       break;
                }
-       #endif
-               i = 0;
-               result = NULL;
-               do {
-                       if (ads_entry_has_name(&inode->i_ads_entries[i],
-                                              stream_name_utf16le,
-                                              stream_name_utf16le_nbytes,
-                                              default_ignore_case))
-                       {
-                               if (idx_ret)
-                                       *idx_ret = i;
-                               result = &inode->i_ads_entries[i];
-                               break;
-                       }
-               } while (++i != inode->i_num_ads);
-       #if !TCHAR_IS_UTF16LE
-               FREE(stream_name_utf16le);
-       #endif
-               return result;
-       }
-}
+       } while (++i != inode->i_num_ads);
 
-static int
-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));
+       tstr_put_utf16le(stream_name_utf16le);
 
-       if (is_utf16le) {
-               utf16lechar *p = MALLOC(name_nbytes + sizeof(utf16lechar));
-               if (p == NULL)
-                       return WIMLIB_ERR_NOMEM;
-               memcpy(p, name, name_nbytes);
-               p[name_nbytes / 2] = cpu_to_le16(0);
-               ads_entry->stream_name = p;
-               ads_entry->stream_name_nbytes = name_nbytes;
-       } else {
-               if (name && *(const tchar*)name != T('\0')) {
-                       ret = get_utf16le_string(name, &ads_entry->stream_name,
-                                                &ads_entry->stream_name_nbytes);
-               }
-       }
-       return ret;
+       return result;
 }
 
 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)
+do_inode_add_ads(struct wim_inode *inode,
+                utf16lechar *stream_name, size_t stream_name_nbytes)
 {
        u16 num_ads;
        struct wim_ads_entry *ads_entries;
        struct wim_ads_entry *new_entry;
 
-       wimlib_assert(stream_name_nbytes != 0);
-
        if (inode->i_num_ads >= 0xfffe) {
                ERROR("Too many alternate data streams in one inode!");
                return NULL;
@@ -238,8 +200,10 @@ do_inode_add_ads(struct wim_inode *inode, const void *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, stream_name_nbytes, is_utf16le))
-               return NULL;
+
+       memset(new_entry, 0, sizeof(struct wim_ads_entry));
+       new_entry->stream_name = stream_name;
+       new_entry->stream_name_nbytes = stream_name_nbytes;
        new_entry->stream_id = inode->i_next_stream_id++;
        inode->i_num_ads = num_ads;
        return new_entry;
@@ -247,26 +211,49 @@ do_inode_add_ads(struct wim_inode *inode, const void *stream_name,
 
 struct wim_ads_entry *
 inode_add_ads_utf16le(struct wim_inode *inode,
-                     const utf16lechar *stream_name,
-                     size_t stream_name_nbytes)
+                     const utf16lechar *stream_name, size_t stream_name_nbytes)
 {
-       DEBUG("Add alternate data stream \"%"WS"\"", stream_name);
-       return do_inode_add_ads(inode, stream_name, stream_name_nbytes, true);
+       utf16lechar *dup = NULL;
+       struct wim_ads_entry *result;
+
+       if (stream_name_nbytes) {
+               dup = utf16le_dupz(stream_name, stream_name_nbytes);
+               if (!dup)
+                       return NULL;
+       }
+
+       result = do_inode_add_ads(inode, dup, stream_name_nbytes);
+       if (!result)
+               FREE(dup);
+       return result;
 }
 
 /*
  * Add an alternate stream entry to a WIM inode.  On success, returns a pointer
  * to the new entry; on failure, returns NULL.
- *
- * @stream_name must be a nonempty string.
  */
 struct wim_ads_entry *
 inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
 {
-       DEBUG("Add alternate data stream \"%"TS"\"", stream_name);
-       return do_inode_add_ads(inode, stream_name,
-                               tstrlen(stream_name) * sizeof(tchar),
-                               TCHAR_IS_UTF16LE);
+       utf16lechar *stream_name_utf16le = NULL;
+       size_t stream_name_utf16le_nbytes = 0;
+       int ret;
+       struct wim_ads_entry *result;
+
+       if (stream_name && *stream_name) {
+               ret = tstr_to_utf16le(stream_name,
+                                     tstrlen(stream_name) * sizeof(tchar),
+                                     &stream_name_utf16le,
+                                     &stream_name_utf16le_nbytes);
+               if (ret)
+                       return NULL;
+       }
+
+       result = do_inode_add_ads(inode, stream_name_utf16le,
+                                 stream_name_utf16le_nbytes);
+       if (!result)
+               FREE(stream_name_utf16le);
+       return result;
 }
 
 int
@@ -307,10 +294,10 @@ int
 inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
                         struct wim_lookup_table *lookup_table)
 {
+       wimlib_assert(inode->i_resolved);
        inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
        if (inode->i_lte == NULL)
                return WIMLIB_ERR_NOMEM;
-       inode->i_resolved = 1;
        return 0;
 }
 
@@ -327,8 +314,6 @@ inode_remove_ads(struct wim_inode *inode, u16 idx,
 
        ads_entry = &inode->i_ads_entries[idx];
 
-       DEBUG("Remove alternate data stream \"%"WS"\"", ads_entry->stream_name);
-
        lte = ads_entry->lte;
        if (lte)
                lte_decrement_refcnt(lte, lookup_table);
@@ -341,87 +326,6 @@ inode_remove_ads(struct wim_inode *inode, u16 idx,
        inode->i_num_ads--;
 }
 
-bool
-inode_has_unix_data(const struct wim_inode *inode)
-{
-       for (u16 i = 0; i < inode->i_num_ads; i++)
-               if (ads_entry_is_unix_data(&inode->i_ads_entries[i]))
-                       return true;
-       return false;
-}
-
-#ifndef __WIN32__
-int
-inode_get_unix_data(const struct wim_inode *inode,
-                   struct wimlib_unix_data *unix_data,
-                   u16 *stream_idx_ret)
-{
-       const struct wim_ads_entry *ads_entry;
-       const struct wim_lookup_table_entry *lte;
-       size_t size;
-       int ret;
-
-       wimlib_assert(inode->i_resolved);
-
-       ads_entry = inode_get_ads_entry((struct wim_inode*)inode,
-                                       WIMLIB_UNIX_DATA_TAG, NULL);
-       if (ads_entry == NULL)
-               return NO_UNIX_DATA;
-
-       if (stream_idx_ret)
-               *stream_idx_ret = ads_entry - inode->i_ads_entries;
-
-       lte = ads_entry->lte;
-       if (lte == NULL)
-               return NO_UNIX_DATA;
-
-       size = lte->size;
-       if (size != sizeof(struct wimlib_unix_data))
-               return BAD_UNIX_DATA;
-
-       ret = read_full_stream_into_buf(lte, unix_data);
-       if (ret)
-               return ret;
-
-       if (unix_data->version != 0)
-               return BAD_UNIX_DATA;
-       return 0;
-}
-
-int
-inode_set_unix_data(struct wim_inode *inode, u16 uid, u16 gid, u16 mode,
-                   struct wim_lookup_table *lookup_table, int which)
-{
-       struct wimlib_unix_data unix_data;
-       int ret;
-       bool have_good_unix_data = false;
-       bool have_unix_data = false;
-       u16 stream_idx;
-
-       if (!(which & UNIX_DATA_CREATE)) {
-               ret = inode_get_unix_data(inode, &unix_data, &stream_idx);
-               if (ret == 0 || ret == BAD_UNIX_DATA || ret > 0)
-                       have_unix_data = true;
-               if (ret == 0)
-                       have_good_unix_data = true;
-       }
-       unix_data.version = 0;
-       if (which & UNIX_DATA_UID || !have_good_unix_data)
-               unix_data.uid = uid;
-       if (which & UNIX_DATA_GID || !have_good_unix_data)
-               unix_data.gid = gid;
-       if (which & UNIX_DATA_MODE || !have_good_unix_data)
-               unix_data.mode = mode;
-       ret = inode_add_ads_with_data(inode, WIMLIB_UNIX_DATA_TAG,
-                                     &unix_data,
-                                     sizeof(struct wimlib_unix_data),
-                                     lookup_table);
-       if (ret == 0 && have_unix_data)
-               inode_remove_ads(inode, stream_idx, lookup_table);
-       return ret;
-}
-#endif /* __WIN32__  */
-
 /*
  * Resolve an inode's lookup table entries.
  *
@@ -737,14 +641,10 @@ read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
                            cur_entry->stream_name_nbytes > length)
                                goto out_invalid;
 
-                       cur_entry->stream_name = MALLOC(cur_entry->stream_name_nbytes + 2);
+                       cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name,
+                                                             cur_entry->stream_name_nbytes);
                        if (cur_entry->stream_name == NULL)
                                goto out_of_memory;
-
-                       memcpy(cur_entry->stream_name,
-                              disk_entry->stream_name,
-                              cur_entry->stream_name_nbytes);
-                       cur_entry->stream_name[cur_entry->stream_name_nbytes / 2] = cpu_to_le16(0);
                } else {
                        /* Mark inode as having weird stream entries.  */
                        inode->i_canonical_streams = 0;
@@ -798,8 +698,6 @@ out:
 int
 verify_inode(struct wim_inode *inode, const struct wim_security_data *sd)
 {
-       struct wim_dentry *dentry;
-
        /* Check the security ID.  -1 is valid and means "no security
         * descriptor".  Anything else has to be a valid index into the WIM
         * image's security descriptors table. */
@@ -825,30 +723,6 @@ verify_inode(struct wim_inode *inode, const struct wim_security_data *sd)
                        inode_first_full_path(inode), num_unnamed_streams);
        }
 
-       /* Files cannot have multiple DOS names, even if they have multiple
-        * names in multiple directories (i.e. hard links).
-        * Source: NTFS-3g authors. */
-       struct wim_dentry *dentry_with_dos_name = NULL;
-       inode_for_each_dentry(dentry, inode) {
-               if (dentry_has_short_name(dentry)) {
-                       if (dentry_with_dos_name) {
-                               /* This was previously an error, but if we
-                                * capture a WIM from UDF on Windows, hard links
-                                * are supported but DOS names are automatically
-                                * generated for all names for an inode.  */
-                       #if 0
-                               ERROR("Hard-linked file has a DOS name at "
-                                     "both `%"TS"' and `%"TS"'",
-                                     dentry_full_path(dentry_with_dos_name),
-                                     dentry_full_path(dentry));
-                               return WIMLIB_ERR_INVALID_METADATA_RESOURCE;
-                       #else
-                               dentry->dos_name_invalid = 1;
-                       #endif
-                       }
-                       dentry_with_dos_name = dentry;
-               }
-       }
        return 0;
 }
 
@@ -863,6 +737,20 @@ inode_ref_streams(struct wim_inode *inode)
        }
 }
 
+void
+inode_unref_streams(struct wim_inode *inode,
+                   struct wim_lookup_table *lookup_table)
+{
+       struct wim_lookup_table_entry *lte;
+       unsigned i;
+
+       for (i = 0; i <= inode->i_num_ads; i++) {
+               lte = inode_stream_lte(inode, i, lookup_table);
+               if (lte)
+                       lte_decrement_refcnt(lte, lookup_table);
+       }
+}
+
 int
 init_inode_table(struct wim_inode_table *table, size_t capacity)
 {