From: Eric Biggers Date: Sat, 25 Aug 2012 04:02:34 +0000 (-0500) Subject: Fixes for Windows ADS interface X-Git-Tag: v1.0.0~87 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=23521f356bcb64df8974faf21def7e79122b85f2 Fixes for Windows ADS interface --- diff --git a/src/dentry.c b/src/dentry.c index c07ab5ea..d8b3e60e 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -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; diff --git a/src/lookup_table.c b/src/lookup_table.c index 0546f958..1fb2d4bd 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -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) diff --git a/src/mount.c b/src/mount.c index 8763be1e..03626cf4 100644 --- a/src/mount.c +++ b/src/mount.c @@ -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; diff --git a/src/resource.c b/src/resource.c index 2dde8d55..b1bc947d 100644 --- a/src/resource.c +++ b/src/resource.c @@ -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);