Fixes for Windows ADS interface
authorEric Biggers <ebiggers3@gmail.com>
Sat, 25 Aug 2012 04:02:34 +0000 (23:02 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sat, 25 Aug 2012 04:02:34 +0000 (23:02 -0500)
src/dentry.c
src/lookup_table.c
src/mount.c
src/resource.c

index c07ab5ea5504672c28a4c9645118921ebe58c734..d8b3e60edd156a68e4c532131b0b437537b1c824 100644 (file)
@@ -124,6 +124,9 @@ struct ads_entry *dentry_add_ads(struct dentry *dentry, const char *stream_name)
        struct ads_entry *ads_entries;
        struct ads_entry *new_entry;
 
+       DEBUG("Add alternate data stream %s:%s",
+              dentry->file_name_utf8, stream_name);
+
        if (dentry->num_ads == 0xffff)
                return NULL;
        num_ads = dentry->num_ads + 1;
@@ -139,13 +142,13 @@ struct ads_entry *dentry_add_ads(struct dentry *dentry, const char *stream_name)
                        cur->next->prev = cur;
                }
        }
-       dentry->ads_entries = ads_entries;
 
        new_entry = &ads_entries[num_ads - 1];
+       ads_entry_init(new_entry);
        if (change_ads_name(new_entry, stream_name) != 0)
                return NULL;
+       dentry->ads_entries = ads_entries;
        dentry->num_ads = num_ads;
-       ads_entry_init(new_entry);
        return new_entry;
 }
 
@@ -751,7 +754,7 @@ int change_ads_name(struct ads_entry *entry, const char *new_name)
        return get_names(&entry->stream_name, &entry->stream_name_utf8,
                         &entry->stream_name_len,
                         &entry->stream_name_utf8_len,
-                         new_name);
+                        new_name);
 }
 
 /* Parameters for calculate_dentry_statistics(). */
@@ -1152,7 +1155,7 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
        if (p - orig_p < dentry->length)
                p = put_zeroes(p, dentry->length - (p - orig_p));
 
-       p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
+       p = put_zeroes(p, (8 - dentry->length % 8) % 8);
 
        for (u16 i = 0; i < dentry->num_ads; i++) {
                p = put_u64(p, ads_entry_length(&dentry->ads_entries[i]));
@@ -1165,6 +1168,7 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
                p = put_u16(p, dentry->ads_entries[i].stream_name_len);
                p = put_bytes(p, dentry->ads_entries[i].stream_name_len,
                                 (u8*)dentry->ads_entries[i].stream_name);
+               p = put_u16(p, 0);
                p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
        }
        return p;
index 0546f958a3108f41dc2b3dffc884a576567b8ea3..1fb2d4bdac747c1e4732da3f1526ec38a6dfd795 100644 (file)
@@ -393,7 +393,20 @@ int lookup_resource(WIMStruct *w, const char *path,
        struct dentry *dentry;
        struct lookup_table_entry *lte;
        unsigned stream_idx;
+       const char *stream_name;
+       char *p = NULL;
+
+       if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
+               stream_name = path_stream_name(path);
+               if (stream_name) {
+                       p = (char*)stream_name - 1;
+                       *p = '\0';
+               }
+       }
+
        dentry = get_dentry(w, path);
+       if (p)
+               *p = ':';
        if (!dentry)
                return -ENOENT;
 
@@ -404,22 +417,19 @@ int lookup_resource(WIMStruct *w, const char *path,
              && dentry_is_directory(dentry))
                return -EISDIR;
        stream_idx = 0;
-       if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
-               const char *stream_name = path_stream_name(path);
-               if (stream_name) {
-                       size_t stream_name_len = strlen(stream_name);
-                       for (u16 i = 0; i < dentry->num_ads; i++) {
-                               if (ads_entry_has_name(&dentry->ads_entries[i],
-                                                      stream_name,
-                                                      stream_name_len))
-                               {
-                                       stream_idx = i + 1;
-                                       lte = dentry->ads_entries[i].lte;
-                                       goto out;
-                               }
+       if (stream_name) {
+               size_t stream_name_len = strlen(stream_name);
+               for (u16 i = 0; i < dentry->num_ads; i++) {
+                       if (ads_entry_has_name(&dentry->ads_entries[i],
+                                              stream_name,
+                                              stream_name_len))
+                       {
+                               stream_idx = i + 1;
+                               lte = dentry->ads_entries[i].lte;
+                               goto out;
                        }
-                       return -ENOENT;
                }
+               return -ENOENT;
        }
 out:
        if (dentry_ret)
index 8763be1e2fbcc0307468caf462311c32ff633ca4..03626cf4b1a551740147f9ce983c528291a4cb6d 100644 (file)
@@ -966,9 +966,14 @@ static int wimfs_ftruncate(const char *path, off_t size,
  */
 static int wimfs_getattr(const char *path, struct stat *stbuf)
 {
-       struct dentry *dentry = get_dentry(w, path);
-       if (!dentry)
-               return -ENOENT;
+       const char *stream_name;
+       char *p = NULL;
+       struct dentry *dentry;
+       int ret;
+
+       ret = lookup_resource(w, path, get_lookup_flags(), &dentry, NULL, NULL);
+       if (ret != 0)
+               return ret;
        return dentry_to_stbuf(dentry, stbuf);
 }
 
@@ -1071,12 +1076,17 @@ static int wimfs_mkdir(const char *path, mode_t mode)
 static int wimfs_mknod(const char *path, mode_t mode, dev_t rdev)
 {
        const char *stream_name;
+       const char *file_name;
        if ((mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS)
             && (stream_name = path_stream_name(path))) {
                /* Make an alternate data stream */
                struct ads_entry *new_entry;
                struct dentry *dentry;
 
+               char *p = (char*)stream_name - 1;
+               wimlib_assert(*p == ':');
+               *p = '\0';
+
                dentry = get_dentry(w, path);
                if (!dentry || !dentry_is_regular_file(dentry))
                        return -ENOENT;
index 2dde8d55578435c39b64151746a6c1e1dbe88abd..b1bc947d9f61fdfbd9b17686773a25d3c4dc8028 100644 (file)
@@ -1185,11 +1185,9 @@ int write_metadata_resource(WIMStruct *w)
 
        root = wim_root_dentry(w);
 
-       struct wim_security_data *sd = wim_security_data(w);
-       if (sd)
-               subdir_offset = sd->total_length + root->length + 8;
-       else
-               subdir_offset = 8 + root->length + 8;
+       const struct wim_security_data *sd = wim_security_data(w);
+       wimlib_assert(sd);
+       subdir_offset = sd->total_length + root->length + 8;
        calculate_subdir_offsets(root, &subdir_offset);
        metadata_original_size = subdir_offset + random_tail_len;
        buf = MALLOC(metadata_original_size);
@@ -1216,7 +1214,7 @@ int write_metadata_resource(WIMStruct *w)
        lookup_table_unlink(w->lookup_table, lte);
        lookup_table_insert(w->lookup_table, lte);
        wimlib_assert(lte->out_refcnt == 0);
-       lte->out_refcnt++;
+       lte->out_refcnt = 1;
        lte->output_resource_entry.flags |= WIM_RESHDR_FLAG_METADATA;
 out:
        FREE(buf);