ads entries
authorEric Biggers <ebiggers3@gmail.com>
Tue, 4 Sep 2012 03:13:47 +0000 (22:13 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Tue, 4 Sep 2012 03:13:47 +0000 (22:13 -0500)
src/dentry.c
src/dentry.h
src/hardlink.c
src/lookup_table.c
src/lookup_table.h
src/mount.c
src/ntfs-apply.c
src/ntfs-capture.c

index 235971106daed81876ea754f1778d3ac85b97f0c..58782eb865e559606d47ee52ef4a1987b629de38 100644 (file)
@@ -79,7 +79,7 @@ static u64 __dentry_total_length(const struct dentry *dentry, u64 length)
 {
        const struct inode *inode = dentry->inode;
        for (u16 i = 0; i < inode->num_ads; i++)
-               length += ads_entry_total_length(inode->ads_entries[i]);
+               length += ads_entry_total_length(&inode->ads_entries[i]);
        return (length + 7) & ~7;
 }
 
@@ -118,16 +118,53 @@ void stbuf_to_inode(const struct stat *stbuf, struct inode *inode)
        inode->last_access_time = timespec_to_wim_timestamp(&stbuf->st_atim);
 }
 
-
-/* Sets all the timestamp fields of the dentry to the current time. */
-void inode_update_all_timestamps(struct inode *inode)
+#ifdef WITH_FUSE
+/* Transfers file attributes from a struct inode to a `stat' buffer. 
+ *
+ * The lookup table entry tells us which stream in the inode we are statting.
+ * For a named data stream, everything returned is the same as the unnamed data
+ * stream except possibly the size and block count. */
+int inode_to_stbuf(const struct inode *inode, struct lookup_table_entry *lte,
+                  struct stat *stbuf)
 {
-       u64 now = get_wim_timestamp();
-       inode->creation_time    = now;
-       inode->last_access_time = now;
-       inode->last_write_time  = now;
+       if (inode_is_symlink(inode))
+               stbuf->st_mode = S_IFLNK | 0777;
+       else if (inode_is_directory(inode))
+               stbuf->st_mode = S_IFDIR | 0755;
+       else
+               stbuf->st_mode = S_IFREG | 0644;
+
+       stbuf->st_ino   = (ino_t)inode->ino;
+       stbuf->st_nlink = inode->link_count;
+       stbuf->st_uid   = getuid();
+       stbuf->st_gid   = getgid();
+
+       if (lte) {
+               if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
+                       wimlib_assert(lte->staging_file_name);
+                       struct stat native_stat;
+                       if (stat(lte->staging_file_name, &native_stat) != 0) {
+                               DEBUG("Failed to stat `%s': %m",
+                                     lte->staging_file_name);
+                               return -errno;
+                       }
+                       stbuf->st_size = native_stat.st_size;
+               } else {
+                       stbuf->st_size = wim_resource_size(lte);
+               }
+       } else {
+               stbuf->st_size = 0;
+       }
+
+       stbuf->st_atime   = wim_timestamp_to_unix(inode->last_access_time);
+       stbuf->st_mtime   = wim_timestamp_to_unix(inode->last_write_time);
+       stbuf->st_ctime   = wim_timestamp_to_unix(inode->creation_time);
+       stbuf->st_blocks  = (stbuf->st_size + 511) / 512;
+       return 0;
 }
+#endif
 
+#ifdef WITH_FUSE
 /* Returns the alternate data stream entry belonging to @inode that has the
  * stream name @stream_name. */
 struct ads_entry *inode_get_ads_entry(struct inode *inode,
@@ -141,33 +178,46 @@ struct ads_entry *inode_get_ads_entry(struct inode *inode,
                u16 i = 0;
                stream_name_len = strlen(stream_name);
                do {
-                       if (ads_entry_has_name(inode->ads_entries[i],
+                       if (ads_entry_has_name(&inode->ads_entries[i],
                                               stream_name, stream_name_len))
                        {
                                if (idx_ret)
                                        *idx_ret = i;
-                               return inode->ads_entries[i];
+                               return &inode->ads_entries[i];
                        }
                } while (++i != inode->num_ads);
        }
        return NULL;
 }
+#endif
 
 
-static struct ads_entry *new_ads_entry(const char *name)
+static int init_ads_entry(struct ads_entry *ads_entry, const char *name)
 {
-       struct ads_entry *ads_entry = CALLOC(1, sizeof(struct ads_entry));
-       if (!ads_entry)
-               return NULL;
-       if (name && *name) {
-               if (change_ads_name(ads_entry, name)) {
-                       FREE(ads_entry);
-                       return NULL;
-               }
+       int ret = 0;
+       memset(ads_entry, 0, sizeof(*ads_entry));
+       if (name && *name)
+               ret = change_ads_name(ads_entry, name);
+       return ret;
+}
+
+static void destroy_ads_entry(struct ads_entry *ads_entry)
+{
+       FREE(ads_entry->stream_name);
+       FREE(ads_entry->stream_name_utf8);
+}
+
+
+void inode_free_ads_entries(struct inode *inode)
+{
+       if (inode->ads_entries) {
+               for (u16 i = 0; i < inode->num_ads; i++)
+                       destroy_ads_entry(&inode->ads_entries[i]);
+               FREE(inode->ads_entries);
        }
-       return ads_entry;
 }
 
+#if defined(WITH_FUSE) || defined(WITH_NTFS_3G)
 /* 
  * Add an alternate stream entry to an inode and return a pointer to it, or NULL
  * if memory could not be allocated.
@@ -175,7 +225,7 @@ static struct ads_entry *new_ads_entry(const char *name)
 struct ads_entry *inode_add_ads(struct inode *inode, const char *stream_name)
 {
        u16 num_ads;
-       struct ads_entry **ads_entries;
+       struct ads_entry *ads_entries;
        struct ads_entry *new_entry;
 
        if (inode->num_ads >= 0xfffe) {
@@ -191,17 +241,43 @@ struct ads_entry *inode_add_ads(struct inode *inode, const char *stream_name)
        }
        inode->ads_entries = ads_entries;
 
-       new_entry = new_ads_entry(stream_name);
-       if (!new_entry)
+       new_entry = &inode->ads_entries[num_ads - 1];
+       if (init_ads_entry(new_entry, stream_name) != 0)
                return NULL;
-       inode->num_ads = num_ads;
-       ads_entries[num_ads - 1] = new_entry;
 #ifdef WITH_FUSE
        new_entry->stream_id = inode->next_stream_id++;
 #endif
        return new_entry;
 }
+#endif
 
+#ifdef WITH_FUSE
+/* Remove an alternate data stream from the inode  */
+void inode_remove_ads(struct inode *inode, u16 idx,
+                     struct lookup_table *lookup_table)
+{
+       struct ads_entry *ads_entry;
+       struct lookup_table_entry *lte;
+
+       ads_entry = &inode->ads_entries[idx];
+
+       wimlib_assert(ads_entry);
+       wimlib_assert(inode->resolved);
+
+       lte = ads_entry->lte;
+
+       if (lte)
+               lte_decrement_refcnt(lte, lookup_table);
+
+       destroy_ads_entry(ads_entry);
+
+       wimlib_assert(inode->num_ads);
+       memcpy(&inode->ads_entries[idx],
+              &inode->ads_entries[idx + 1],
+              (inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0]));
+       inode->num_ads--;
+}
+#endif
 
 /* 
  * Calls a function on all directory entries in a directory tree.  It is called
@@ -525,9 +601,9 @@ int print_dentry(struct dentry *dentry, void *lookup_table)
        }
        for (u16 i = 0; i < inode->num_ads; i++) {
                printf("[Alternate Stream Entry %u]\n", i);
-               printf("Name = \"%s\"\n", inode->ads_entries[i]->stream_name_utf8);
+               printf("Name = \"%s\"\n", inode->ads_entries[i].stream_name_utf8);
                printf("Name Length (UTF-16) = %u\n",
-                       inode->ads_entries[i]->stream_name_len);
+                       inode->ads_entries[i].stream_name_len);
                hash = inode_stream_hash(inode, i + 1);
                if (hash) {
                        printf("Hash              = 0x"); 
@@ -630,23 +706,6 @@ struct dentry *new_dentry_with_inode(const char *name)
        return __new_dentry_with_inode(name, false);
 }
 
-void free_ads_entry(struct ads_entry *entry)
-{
-       if (entry) {
-               FREE(entry->stream_name);
-               FREE(entry->stream_name_utf8);
-               FREE(entry);
-       }
-}
-
-void inode_free_ads_entries(struct inode *inode)
-{
-       if (inode->ads_entries) {
-               for (u16 i = 0; i < inode->num_ads; i++)
-                       free_ads_entry(inode->ads_entries[i]);
-               FREE(inode->ads_entries);
-       }
-}
 
 /* Frees an inode. */
 void free_inode(struct inode *inode)
@@ -707,30 +766,6 @@ void put_dentry(struct dentry *dentry)
                free_dentry(dentry);
 }
 
-#if 0
-/* Partically clones a dentry.
- *
- * Beware:
- *     - memory for file names is not cloned (the pointers are all set to NULL
- *       and the lengths are set to zero)
- *     - next, prev, and children pointers and not touched
- */
-struct dentry *clone_dentry(struct dentry *old)
-{
-       struct dentry *new = MALLOC(sizeof(struct dentry));
-       if (!new)
-               return NULL;
-       memcpy(new, old, sizeof(struct dentry));
-       new->file_name          = NULL;
-       new->file_name_len      = 0;
-       new->file_name_utf8     = NULL;
-       new->file_name_utf8_len = 0;
-       new->short_name         = NULL;
-       new->short_name_len     = 0;
-       return new;
-}
-#endif
-
 /* 
  * This function is passed as an argument to for_dentry_in_tree_depth() in order
  * to free a directory tree.  __args is a pointer to a `struct free_dentry_args'.
@@ -978,7 +1013,7 @@ static int read_ads_entries(const u8 *p, struct inode *inode,
                            u64 remaining_size)
 {
        u16 num_ads;
-       struct ads_entry **ads_entries;
+       struct ads_entry *ads_entries;
        int ret;
 
        num_ads = inode->num_ads;
@@ -997,16 +1032,10 @@ static int read_ads_entries(const u8 *p, struct inode *inode,
                size_t utf8_len;
                const u8 *p_save = p;
 
-               cur_entry = new_ads_entry(NULL);
-               if (!cur_entry) {
-                       ret = WIMLIB_ERR_NOMEM;
-                       goto out_free_ads_entries;
-               }
-
-               ads_entries[i] = cur_entry;
+               cur_entry = &ads_entries[i];
 
        #ifdef WITH_FUSE
-               ads_entries[i]->stream_id = i + 1;
+               ads_entries[i].stream_id = i + 1;
        #endif
 
                /* Read the base stream entry, excluding the stream name. */
@@ -1099,7 +1128,7 @@ static int read_ads_entries(const u8 *p, struct inode *inode,
        return 0;
 out_free_ads_entries:
        for (u16 i = 0; i < num_ads; i++)
-               free_ads_entry(ads_entries[i]);
+               destroy_ads_entry(&ads_entries[i]);
        FREE(ads_entries);
        return ret;
 }
@@ -1555,14 +1584,14 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
         * read_ads_entries() for comments about the format of the on-disk
         * alternate data stream entries. */
        for (u16 i = 0; i < inode->num_ads; i++) {
-               p = put_u64(p, ads_entry_total_length(inode->ads_entries[i]));
+               p = put_u64(p, ads_entry_total_length(&inode->ads_entries[i]));
                p = put_u64(p, 0); /* Unused */
                hash = inode_stream_hash(inode, i + 1);
                p = put_bytes(p, SHA1_HASH_SIZE, hash);
-               p = put_u16(p, inode->ads_entries[i]->stream_name_len);
-               if (inode->ads_entries[i]->stream_name_len) {
-                       p = put_bytes(p, inode->ads_entries[i]->stream_name_len,
-                                        (u8*)inode->ads_entries[i]->stream_name);
+               p = put_u16(p, inode->ads_entries[i].stream_name_len);
+               if (inode->ads_entries[i].stream_name_len) {
+                       p = put_bytes(p, inode->ads_entries[i].stream_name_len,
+                                        (u8*)inode->ads_entries[i].stream_name);
                        p = put_u16(p, 0);
                }
                p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
index f87353e93eb9a7a460020ca501b1746820ecb08d..d1027f76b7f29a129e946bb7b8ee8235b1df2a55 100644 (file)
@@ -7,10 +7,13 @@
 #include "sha1.h"
 #include <string.h>
 
-
 struct stat;
 struct lookup_table;
 struct WIMStruct;
+struct lookup_table_entry;
+struct wimlib_fd;
+struct inode;
+struct dentry;
 
 /* Size of the struct dentry up to and including the file_name_len. */
 #define WIM_DENTRY_DISK_SIZE    102
@@ -52,7 +55,6 @@ struct WIMStruct;
 #define FILE_ATTRIBUTE_ENCRYPTED           0x00004000
 #define FILE_ATTRIBUTE_VIRTUAL             0x00010000
 
-struct lookup_table_entry;
 
 /* Alternate data stream entry.
  *
@@ -114,108 +116,32 @@ static inline bool ads_entries_have_same_name(const struct ads_entry *entry_1,
                      entry_1->stream_name_len) == 0;
 }
 
-struct wimlib_fd;
-
-struct inode {
-       /* Timestamps for the inode.  The timestamps are the number of
-        * 100-nanosecond intervals that have elapsed since 12:00 A.M., January
-        * 1st, 1601, UTC.  This is the same format used in NTFS inodes. */
-       u64 creation_time;
-       u64 last_access_time;
-       u64 last_write_time;
-
-       /* The file attributes associated with this inode.  This is a bitwise OR
-        * of the FILE_ATTRIBUTE_* flags. */
-       u32 attributes;
-
-       /* The index of the security descriptor in the WIM image's table of
-        * security descriptors that contains this file's security information.
-        * If -1, no security information exists for this file.  */
-       int32_t security_id;
-
-       /* %true iff the inode's lookup table entries has been resolved (i.e.
-        * the @lte field is valid, but the @hash field is not valid) 
-        *
-        * (This is not an on-disk field.) */
-       u8 resolved : 1;
-
-       u8 verified : 1;
-
-       u16 num_ads;
-
-       /* A hash of the file's contents, or a pointer to the lookup table entry
-        * for this dentry if the lookup table entries have been resolved.
-        *
-        * More specifically, this is for the un-named default file stream, as
-        * opposed to the alternate (named) file streams, which may have their
-        * own lookup table entries.  */
-       union {
-               u8 hash[SHA1_HASH_SIZE];
-               struct lookup_table_entry *lte;
-       };
-
-       /* Identity of a reparse point.  See
-        * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx
-        * for what a reparse point is. */
-       u32 reparse_tag;
-
-       u32 link_count;
-
-       struct ads_entry **ads_entries;
-
-       /* If the file is part of a hard link set, all the directory entries in
-        * the set will share the same value for this field. 
-        *
-        * Unfortunately, in some WIMs it is NOT the case that all dentries that
-        * share this field are actually in the same hard link set, although the
-        * WIMs that wimlib writes maintain this restriction. */
-       u64 ino;
-
-       struct list_head dentry_list;
-       struct hlist_node hlist;
-       char *extracted_file;
-
-       struct dentry *children;
-
-#ifdef WITH_FUSE
-       u16 num_opened_fds;
-       u16 num_allocated_fds;
-       struct wimlib_fd **fds;
-       u32 next_stream_id;
-#endif
-};
-
-#define inode_for_each_dentry(dentry, inode) \
-               list_for_each_entry((dentry), &(inode)->dentry_list, inode_dentry_list)
-
-#define inode_add_dentry(dentry, inode) \
-       ({                                                              \
-               wimlib_assert((inode)->dentry_list.next != NULL);               \
-               list_add(&(dentry)->inode_dentry_list, &(inode)->dentry_list);  \
-       })
-
 /* 
  * In-memory structure for a WIM directory entry (dentry).  There is a directory
  * tree for each image in the WIM. 
  *
- * Please note that this is a directory entry and not an inode.  Since NTFS
- * allows hard links, it's possible for a NTFS inode to correspond to multiple
- * WIM dentries.  The @hard_link field tells you the number of the NTFS inode
- * that the dentry corresponds to.
+ * Note that this is a directory entry and not an inode.  Since NTFS allows hard
+ * links, it's possible for a NTFS inode to correspond to multiple WIM dentries.
+ * The hard_link field on the on-disk WIM dentry tells us the number of the NTFS
+ * inode that the dentry corresponds to.
  *
  * Unfortunately, WIM files do not have an analogue to an inode; instead certain
  * information, such as file attributes, the security descriptor, and file
  * streams is replicated in each hard-linked dentry, even though this
- * information really is associated with an inode.
+ * information really is associated with an inode.  In-memory, we fix up this
+ * flaw by allocating a `struct inode' for each dentry that contains some of
+ * this duplicated information, then combining the inodes for each hard link
+ * group together.
  *
- * Confusingly, it's also possible for stream information to be missing from a
- * dentry in a hard link set, in which case the stream information needs to be
- * gotten from one of the other dentries in the hard link set.  In addition, it
- * is possible for dentries to have inconsistent security IDs, file attributes,
- * or file streams when they share the same hard link ID (don't even ask.  I
- * hope that Microsoft may have fixed this problem, since I've only noticed it
- * in the 'install.wim' for Windows 7).  For those dentries, we have to use the
- * conflicting fields to split up the hard link groups.
+ * Confusingly, it's possible for stream information to be missing from a dentry
+ * in a hard link set, in which case the stream information needs to be gotten
+ * from one of the other dentries in the hard link set.  In addition, it is
+ * possible for dentries to have inconsistent security IDs, file attributes, or
+ * file streams when they share the same hard link ID (don't even ask.  I hope
+ * that Microsoft may have fixed this problem, since I've only noticed it in the
+ * 'install.wim' for Windows 7).  For those dentries, we have to use the
+ * conflicting fields to split up the hard link groups.  (See fix_inodes() in
+ * hardlink.c).
  */
 struct dentry {
        /* The inode for this dentry */
@@ -248,22 +174,12 @@ struct dentry {
         */
        u64 length;
 
-
        /* The offset, from the start of the uncompressed WIM metadata resource
         * for this image, of this dentry's child dentries.  0 if the directory
         * entry has no children, which is the case for regular files or reparse
         * points. */
        u64 subdir_offset;
 
-
-       /* Although M$'s documentation does not tell you this, it seems that the
-        * reparse_reserved field does not actually exist.  So the hard_link
-        * field directly follows the reparse_tag on disk.  EXCEPT when the
-        * dentry is actually a reparse point... well, just take a look at the
-        * read_dentry() function. */
-       //u32 reparse_reserved;
-
-
        /* Length of short filename, in bytes, not including the terminating
         * zero wide-character. */
        u16 short_name_len;
@@ -293,20 +209,110 @@ struct dentry {
         * WIMStructs */
        u32 refcnt;
 
-       /* List of dentries in the hard link set */
+       /* List of dentries in the inode (hard link set)  */
        struct list_head inode_dentry_list;
+
        union {
                struct list_head tmp_list;
                bool is_extracted;
        };
 };
 
+/*
+ * WIM inode.
+ *
+ * As mentioned above, in the WIM file that is no on-disk analogue of a real
+ * inode, as most of these fields are duplicated in the dentries.
+ */
+struct inode {
+       /* Timestamps for the inode.  The timestamps are the number of
+        * 100-nanosecond intervals that have elapsed since 12:00 A.M., January
+        * 1st, 1601, UTC.  This is the same format used in NTFS inodes. */
+       u64 creation_time;
+       u64 last_access_time;
+       u64 last_write_time;
+
+       /* The file attributes associated with this inode.  This is a bitwise OR
+        * of the FILE_ATTRIBUTE_* flags. */
+       u32 attributes;
+
+       /* The index of the security descriptor in the WIM image's table of
+        * security descriptors that contains this file's security information.
+        * If -1, no security information exists for this file.  */
+       int32_t security_id;
+
+       /* %true iff the inode's lookup table entries has been resolved (i.e.
+        * the @lte field is valid, but the @hash field is not valid) 
+        *
+        * (This is not an on-disk field.) */
+       u8 resolved : 1;
+
+       /* %true iff verify_inode() has run on this dentry. */
+       u8 verified : 1;
+
+       /* Number of alternate data streams associated with this inode */
+       u16 num_ads;
+
+       /* A hash of the file's contents, or a pointer to the lookup table entry
+        * for this dentry if the lookup table entries have been resolved.
+        *
+        * More specifically, this is for the un-named default file stream, as
+        * opposed to the alternate (named) file streams, which may have their
+        * own lookup table entries.  */
+       union {
+               u8 hash[SHA1_HASH_SIZE];
+               struct lookup_table_entry *lte;
+       };
+
+       /* Identity of a reparse point.  See
+        * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx
+        * for what a reparse point is. */
+       u32 reparse_tag;
+
+       /* Number of dentries that reference this inode */
+       u32 link_count;
+
+       /* Alternate data stream entries. */
+       struct ads_entry *ads_entries;
+
+       /* Inode number */
+       u64 ino;
+
+       /* List of dentries that reference this inode (there should be
+        * link_count of them) */
+       struct list_head dentry_list;
+       struct hlist_node hlist;
+       char *extracted_file;
+
+       /* If non-NULL, the children of this inode (implies the inode is a
+        * directory) */
+       struct dentry *children;
+
+#ifdef WITH_FUSE
+       /* wimfs file descriptors table for the inode */
+       u16 num_opened_fds;
+       u16 num_allocated_fds;
+       struct wimlib_fd **fds;
+
+       /* Next alternate data stream ID to be assigned */
+       u32 next_stream_id;
+#endif
+};
+
+#define inode_for_each_dentry(dentry, inode) \
+               list_for_each_entry((dentry), &(inode)->dentry_list, inode_dentry_list)
+
+#define inode_add_dentry(dentry, inode) \
+       ({                                                              \
+               wimlib_assert((inode)->dentry_list.next != NULL);               \
+               list_add(&(dentry)->inode_dentry_list, &(inode)->dentry_list);  \
+       })
+
 static inline bool dentry_is_extracted(const struct dentry *dentry)
 {
        return dentry->is_extracted;
 }
 
-
 extern struct ads_entry *inode_get_ads_entry(struct inode *inode,
                                             const char *stream_name,
                                             u16 *idx_ret);
@@ -314,12 +320,17 @@ extern struct ads_entry *inode_get_ads_entry(struct inode *inode,
 extern struct ads_entry *inode_add_ads(struct inode *dentry,
                                       const char *stream_name);
 
+extern void inode_remove_ads(struct inode *inode, u16 idx,
+                            struct lookup_table *lookup_table);
+
 extern const char *path_stream_name(const char *path);
 
 extern u64 dentry_total_length(const struct dentry *dentry);
 extern u64 dentry_correct_total_length(const struct dentry *dentry);
 
 extern void stbuf_to_inode(const struct stat *stbuf, struct inode *inode);
+extern int inode_to_stbuf(const struct inode *inode,
+                         struct lookup_table_entry *lte, struct stat *stbuf);
 
 extern int for_dentry_in_tree(struct dentry *root, 
                              int (*visitor)(struct dentry*, void*), 
@@ -357,7 +368,6 @@ extern struct inode *new_timeless_inode();
 extern struct dentry *new_dentry_with_inode(const char *name);
 extern struct dentry *new_dentry_with_timeless_inode(const char *name);
 
-extern void free_ads_entry(struct ads_entry *entry);
 extern void inode_free_ads_entries(struct inode *inode);
 extern struct inode *free_dentry(struct dentry *dentry);
 extern void free_inode(struct inode *inode);
index d9f0640d2982ca3db1a9583b3ce27d5aa76a24af..2927a789a942e0dfa5ac05ff8abce8b468823c34 100644 (file)
@@ -184,8 +184,8 @@ static bool ref_inodes_consistent(const struct inode * restrict ref_inode_1,
                ref_2_hash = inode_stream_hash(ref_inode_2, i);
                if (!hashes_equal(ref_1_hash, ref_2_hash))
                        return false;
-               if (i && !ads_entries_have_same_name(ref_inode_1->ads_entries[i - 1],
-                                                    ref_inode_2->ads_entries[i - 1]))
+               if (i && !ads_entries_have_same_name(&ref_inode_1->ads_entries[i - 1],
+                                                    &ref_inode_2->ads_entries[i - 1]))
                        return false;
 
        }
@@ -209,8 +209,8 @@ static bool inodes_consistent(const struct inode * restrict ref_inode,
                hash = inode_stream_hash(inode, i);
                if (!hashes_equal(ref_hash, hash) && !is_zero_hash(hash))
                        return false;
-               if (i && !ads_entries_have_same_name(ref_inode->ads_entries[i - 1],
-                                                    inode->ads_entries[i - 1]))
+               if (i && !ads_entries_have_same_name(&ref_inode->ads_entries[i - 1],
+                                                    &inode->ads_entries[i - 1]))
                        return false;
        }
        return true;
index e28c12c6194c7330e149b763f87e743e97ea2b31..e0fca5d47ea1cb596b5ffc65c30d86cb1f8548da 100644 (file)
@@ -457,6 +457,7 @@ __lookup_resource(const struct lookup_table *table, const u8 hash[])
        return NULL;
 }
 
+#ifdef WITH_FUSE
 /* 
  * Finds the dentry, lookup table entry, and stream index for a WIM file stream,
  * given a path name.
@@ -523,6 +524,7 @@ out:
                *stream_idx_ret = stream_idx;
        return 0;
 }
+#endif
 
 static void inode_resolve_ltes(struct inode *inode, struct lookup_table *table)
 {
@@ -535,8 +537,7 @@ static void inode_resolve_ltes(struct inode *inode, struct lookup_table *table)
 
        /* Resolve the alternate data streams */
        for (u16 i = 0; i < inode->num_ads; i++) {
-               struct ads_entry *cur_entry = inode->ads_entries[i];
-
+               struct ads_entry *cur_entry = &inode->ads_entries[i];
                lte = __lookup_resource(table, cur_entry->hash);
                cur_entry->lte = lte;
        }
index 8735468c75f74e712dfb93be2901b4344d0a5e99..f23a864a45796fee19a3e10dc5b3d1e9daac324e 100644 (file)
@@ -307,7 +307,7 @@ inode_stream_lte_resolved(const struct inode *inode, unsigned stream_idx)
        if (stream_idx == 0)
                return inode->lte;
        else
-               return inode->ads_entries[stream_idx - 1]->lte;
+               return inode->ads_entries[stream_idx - 1].lte;
 }
 
 static inline struct lookup_table_entry *
@@ -323,7 +323,7 @@ inode_stream_lte_unresolved(const struct inode *inode, unsigned stream_idx,
        else
                return __lookup_resource(table,
                                         inode->ads_entries[
-                                               stream_idx - 1]->hash);
+                                               stream_idx - 1].hash);
 }
 /* 
  * Returns the lookup table entry for stream @stream_idx of the inode, where
@@ -351,7 +351,7 @@ static inline const u8 *inode_stream_hash_unresolved(const struct inode *inode,
        if (stream_idx == 0)
                return inode->hash;
        else
-               return inode->ads_entries[stream_idx - 1]->hash;
+               return inode->ads_entries[stream_idx - 1].hash;
 }
 
 
@@ -389,7 +389,7 @@ static inline u16 inode_stream_name_len(const struct inode *inode,
        if (stream_idx == 0)
                return 0;
        else
-               return inode->ads_entries[stream_idx - 1]->stream_name_len;
+               return inode->ads_entries[stream_idx - 1].stream_name_len;
 }
 
 static inline struct lookup_table_entry *
index 1a6f1dcecff8e48ad8c513c64d23fd5a414fdc0d..1241800dc63fe4a2637184d8205d6a5265c78001 100644 (file)
@@ -227,76 +227,6 @@ static void remove_dentry(struct dentry *dentry,
        put_dentry(dentry);
 }
 
-/* Remove an alternate data stream from the inode  */
-static void inode_remove_ads(struct inode *inode, u16 idx,
-                            struct lookup_table *lookup_table)
-{
-       struct ads_entry *ads_entry;
-       struct lookup_table_entry *lte;
-
-       ads_entry = inode->ads_entries[idx];
-
-       wimlib_assert(ads_entry);
-
-       lte = ads_entry->lte;
-
-       if (lte)
-               lte_decrement_refcnt(lte, lookup_table);
-
-       free_ads_entry(ads_entry);
-
-       wimlib_assert(inode->num_ads);
-       memcpy(&inode->ads_entries[idx],
-              &inode->ads_entries[idx + 1],
-              (inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0]));
-       inode->num_ads--;
-}
-
-/* Transfers file attributes from a struct inode to a `stat' buffer. 
- *
- * The lookup table entry tells us which stream in the inode we are statting.
- * For a named data stream, everything returned is the same as the unnamed data
- * stream except possibly the size and block count. */
-int inode_to_stbuf(const struct inode *inode, struct lookup_table_entry *lte,
-                  struct stat *stbuf)
-{
-       if (inode_is_symlink(inode))
-               stbuf->st_mode = S_IFLNK | 0777;
-       else if (inode_is_directory(inode))
-               stbuf->st_mode = S_IFDIR | 0755;
-       else
-               stbuf->st_mode = S_IFREG | 0644;
-
-       stbuf->st_ino   = (ino_t)inode->ino;
-       stbuf->st_nlink = inode->link_count;
-       stbuf->st_uid   = getuid();
-       stbuf->st_gid   = getgid();
-
-       if (lte) {
-               if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
-                       wimlib_assert(mount_flags & WIMLIB_MOUNT_FLAG_READWRITE);
-                       wimlib_assert(lte->staging_file_name);
-                       struct stat native_stat;
-                       if (stat(lte->staging_file_name, &native_stat) != 0) {
-                               DEBUG("Failed to stat `%s': %m",
-                                     lte->staging_file_name);
-                               return -errno;
-                       }
-                       stbuf->st_size = native_stat.st_size;
-               } else {
-                       stbuf->st_size = wim_resource_size(lte);
-               }
-       } else {
-               stbuf->st_size = 0;
-       }
-
-       stbuf->st_atime   = wim_timestamp_to_unix(inode->last_access_time);
-       stbuf->st_mtime   = wim_timestamp_to_unix(inode->last_write_time);
-       stbuf->st_ctime   = wim_timestamp_to_unix(inode->creation_time);
-       stbuf->st_blocks  = (stbuf->st_size + 511) / 512;
-       return 0;
-}
-
 /* Creates a new staging file and returns its file descriptor opened for
  * writing.
  *
@@ -470,8 +400,8 @@ static int extract_resource_to_staging_dir(struct inode *inode,
                inode->lte = new_lte;
        else
                for (u16 i = 0; i < inode->num_ads; i++)
-                       if (inode->ads_entries[i]->stream_id == stream_id)
-                               inode->ads_entries[i]->lte = new_lte;
+                       if (inode->ads_entries[i].stream_id == stream_id)
+                               inode->ads_entries[i].lte = new_lte;
 
        lookup_table_insert(w->lookup_table, new_lte);
        list_add(&new_lte->staging_list, &staging_list);
@@ -1054,15 +984,15 @@ static int wimfs_listxattr(const char *path, char *list, size_t size)
        if (size == 0) {
                needed_size = 0;
                for (i = 0; i < inode->num_ads; i++)
-                       needed_size += inode->ads_entries[i]->stream_name_utf8_len + 6;
+                       needed_size += inode->ads_entries[i].stream_name_utf8_len + 6;
                return needed_size;
        } else {
                for (i = 0; i < inode->num_ads; i++) {
-                       needed_size = inode->ads_entries[i]->stream_name_utf8_len + 6;
+                       needed_size = inode->ads_entries[i].stream_name_utf8_len + 6;
                        if (needed_size > size)
                                return -ERANGE;
                        p += sprintf(p, "user.%s",
-                                    inode->ads_entries[i]->stream_name_utf8) + 1;
+                                    inode->ads_entries[i].stream_name_utf8) + 1;
                        size -= needed_size;
                }
                return p - list;
@@ -1172,7 +1102,7 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi)
        if (stream_idx == 0)
                stream_id = 0;
        else
-               stream_id = inode->ads_entries[stream_idx - 1]->stream_id;
+               stream_id = inode->ads_entries[stream_idx - 1].stream_id;
 
        /* The file resource may be in the staging directory (read-write mounts
         * only) or in the WIM.  If it's in the staging directory, we need to
@@ -1568,7 +1498,7 @@ static int wimfs_truncate(const char *path, off_t size)
        if (stream_idx == 0)
                stream_id = 0;
        else
-               stream_id = inode->ads_entries[stream_idx - 1]->stream_id;
+               stream_id = inode->ads_entries[stream_idx - 1].stream_id;
 
        if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
                wimlib_assert(lte->staging_file_name);
index 1a97e72c46aefe8e2d63d0ed2a52dec033b4c0eb..9628e25edafa0bb890f1b473f002be2d1f0ae9a2 100644 (file)
@@ -162,8 +162,8 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct dentry *dentry,
                }
                if (stream_idx == inode->num_ads)
                        break;
-               stream_name = (ntfschar*)inode->ads_entries[stream_idx]->stream_name;
-               stream_name_len = inode->ads_entries[stream_idx]->stream_name_len / 2;
+               stream_name = (ntfschar*)inode->ads_entries[stream_idx].stream_name;
+               stream_name_len = inode->ads_entries[stream_idx].stream_name_len / 2;
                stream_idx++;
        }
        return ret;
@@ -241,8 +241,6 @@ static int wim_apply_hardlink_ntfs(const struct dentry *from_dentry,
        return ret;
 }
 
-/*#define HAVE_NTFS_INODE_FUNCTIONS*/
-
 static int
 apply_file_attributes_and_security_data(ntfs_inode *ni,
                                        ntfs_inode *dir_ni,
@@ -252,9 +250,6 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
        DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32,
              dentry->full_path_utf8, dentry->inode->attributes);
        int ret;
-#ifdef HAVE_NTFS_INODE_FUNCTIONS
-       ret = ntfs_set_inode_attributes(ni, dentry->inode->attributes);
-#else
        struct SECURITY_CONTEXT ctx;
        u32 attributes_le32;
        attributes_le32 = cpu_to_le32(dentry->inode->attributes);
@@ -264,7 +259,6 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
                                         ni, dir_ni,
                                         (const char*)&attributes_le32,
                                         sizeof(u32), 0);
-#endif
        if (ret != 0) {
                ERROR("Failed to set NTFS file attributes on `%s'",
                       dentry->full_path_utf8);
@@ -280,17 +274,9 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
                DEBUG("Applying security descriptor %d to `%s'",
                      dentry->inode->security_id, dentry->full_path_utf8);
 
-       #ifdef HAVE_NTFS_INODE_FUNCTIONS
-               u32 selection = OWNER_SECURITY_INFORMATION |
-                               GROUP_SECURITY_INFORMATION |
-                               DACL_SECURITY_INFORMATION  |
-                               SACL_SECURITY_INFORMATION;
-               ret = ntfs_set_inode_security(ni, selection, descriptor);
-       #else
                ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ACL,
                                                 ni, dir_ni, descriptor,
                                                 sd->sizes[dentry->inode->security_id], 0);
-       #endif
                                
                if (ret != 0) {
                        ERROR_WITH_ERRNO("Failed to set security data on `%s'",
index 7c92c9e240005782d674c14e0602e04a56f7aef4..bc7bc954c66ba6767de9871ce676a2767bf55c51 100644 (file)
 #include <unistd.h>
 #include <errno.h>
 
-#if 0
-extern int ntfs_get_inode_security(ntfs_inode *ni, u32 selection, char *buf,
-                                  u32 buflen, u32 *psize);
-
-extern u32 ntfs_get_inode_attributes(ntfs_inode *ni);
-#endif
-
 /* Structure that allows searching the security descriptors by SHA1 message
  * digest. */
 struct sd_set {
@@ -521,9 +514,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p,
        struct dentry *root;
 
        mrec_flags = ni->mrec->flags;
-#ifdef HAVE_NTFS_INODE_FUNCTIONS
-       attributes = ntfs_get_inode_attributes(ni);
-#else
        struct SECURITY_CONTEXT ctx;
        memset(&ctx, 0, sizeof(ctx));
        ctx.vol = ni->vol;
@@ -535,7 +525,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p,
                                 path);
                return WIMLIB_ERR_NTFS_3G;
        }
-#endif
 
        if (exclude_path(path, config, false)) {
                if (flags & WIMLIB_ADD_IMAGE_FLAG_VERBOSE) {
@@ -622,41 +611,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p,
        if (ret != 0)
                return ret;
 
-#ifdef HAVE_NTFS_INODE_FUNCTIONS
-       ret = ntfs_get_inode_security(ni,
-                                     OWNER_SECURITY_INFORMATION |
-                                     GROUP_SECURITY_INFORMATION |
-                                     DACL_SECURITY_INFORMATION  |
-                                     SACL_SECURITY_INFORMATION,
-                                     NULL, 0, &sd_size);
-       char sd[sd_size];
-       ret = ntfs_get_inode_security(ni,
-                                     OWNER_SECURITY_INFORMATION |
-                                     GROUP_SECURITY_INFORMATION |
-                                     DACL_SECURITY_INFORMATION  |
-                                     SACL_SECURITY_INFORMATION,
-                                     sd, sd_size, &sd_size);
-       if (ret == 0) {
-               ERROR_WITH_ERRNO("Failed to get security information from "
-                                "`%s'", path);
-               ret = WIMLIB_ERR_NTFS_3G;
-       } else {
-               if (ret > 0) {
-                       /*print_security_descriptor(sd, sd_size);*/
-                       root->security_id = sd_set_add_sd(sd_set, sd, ret);
-                       if (root->security_id == -1) {
-                               ERROR("Out of memory");
-                               return WIMLIB_ERR_NOMEM;
-                       }
-                       DEBUG("Added security ID = %u for `%s'",
-                             root->security_id, path);
-               } else { 
-                       root->security_id = -1;
-                       DEBUG("No security ID for `%s'", path);
-               }
-               ret = 0;
-       }
-#else
        char _sd[1];
        char *sd = _sd;
        errno = 0;
@@ -685,7 +639,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p,
                root->inode->security_id = -1;
                DEBUG("No security ID for `%s'", path);
        }
-#endif
        return ret;
 }