From: Eric Biggers Date: Wed, 29 Aug 2012 22:18:17 +0000 (-0500) Subject: NTFS apply ADS fixes X-Git-Tag: v1.0.0~43 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=bf9f9a8533a6f216068bdf61cafb1681ed1b7e1c NTFS apply ADS fixes --- diff --git a/src/ntfs-apply.c b/src/ntfs-apply.c index e8e86c1e..d465e576 100644 --- a/src/ntfs-apply.c +++ b/src/ntfs-apply.c @@ -1,9 +1,8 @@ /* * ntfs-apply.c * - * Apply a WIM image to a NTFS volume, restoring everything we can, including - * security data and alternate data streams. There should be no loss of - * information. + * Apply a WIM image to a NTFS volume. We restore everything we can, including + * security data and alternate data streams. */ /* @@ -119,19 +118,38 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct dentry *dentry, ntfs_attr *na; lte = dentry_stream_lte(dentry, stream_idx, w->lookup_table); - na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len); - if (!na) { - ERROR_WITH_ERRNO("Failed to open a data stream of " - "extracted file `%s'", - dentry->full_path_utf8); - ret = WIMLIB_ERR_NTFS_3G; - break; + + if (stream_name_len) { + /* Create an empty named stream. */ + ret = ntfs_attr_add(ni, AT_DATA, stream_name, + stream_name_len, NULL, 0); + if (ret != 0) { + ERROR_WITH_ERRNO("Failed to create name data " + "stream for extracted file " + "`%s'", + dentry->full_path_utf8); + ret = WIMLIB_ERR_NTFS_3G; + break; + + } } - if (lte) + /* If there's no lookup table entry, it's an empty stream. + * Otherwise, we must open the attribute and extract the data. + * */ + if (lte) { + na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len); + if (!na) { + ERROR_WITH_ERRNO("Failed to open a data stream of " + "extracted file `%s'", + dentry->full_path_utf8); + ret = WIMLIB_ERR_NTFS_3G; + break; + } ret = extract_wim_resource_to_ntfs_attr(lte, na); - ntfs_attr_close(na); - if (ret != 0) - break; + if (ret != 0) + break; + ntfs_attr_close(na); + } if (stream_idx == dentry->num_ads) break; stream_name = (ntfschar*)dentry->ads_entries[stream_idx].stream_name; @@ -669,10 +687,18 @@ static int do_wim_apply_image_ntfs(WIMStruct *w, const char *device, int extract if (ret != 0) goto out; - DEBUG("Setting NTFS timestamps"); + if (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE) + printf("Setting timestamps of extracted files on NTFS " + "volume `%s'\n", device); ret = for_dentry_in_tree_depth(wim_root_dentry(w), wim_apply_dentry_timestamps, &args); + if (ret == 0 && (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE)) + printf("Finished applying image %d of %s to NTFS " + "volume `%s'\n", + w->current_image, + w->filename ? w->filename : "WIM", + device); out: DEBUG("Unmounting NTFS volume `%s'", device); if (ntfs_umount(vol, FALSE) != 0) { diff --git a/src/ntfs-capture.c b/src/ntfs-capture.c index f16850eb..1fe9ee13 100644 --- a/src/ntfs-capture.c +++ b/src/ntfs-capture.c @@ -2,8 +2,7 @@ * ntfs-capture.c * * Capture a WIM image from a NTFS volume. We capture everything we can, - * including security data and alternate data streams. There should be no loss - * of information. + * including security data and alternate data streams. */ /* @@ -272,6 +271,7 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, size_t stream_name_utf16_len; 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) { @@ -308,14 +308,16 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, if (!ntfs_loc->path_utf8) goto out_free_ntfs_loc; memcpy(ntfs_loc->path_utf8, path, path_len + 1); - ntfs_loc->stream_name_utf16 = MALLOC(actx->attr->name_length * 2); - if (!ntfs_loc->stream_name_utf16) - goto out_free_ntfs_loc; - memcpy(ntfs_loc->stream_name_utf16, - attr_record_name(actx->attr), - actx->attr->name_length * 2); + if (name_length) { + ntfs_loc->stream_name_utf16 = MALLOC(name_length * 2); + if (!ntfs_loc->stream_name_utf16) + goto out_free_ntfs_loc; + memcpy(ntfs_loc->stream_name_utf16, + attr_record_name(actx->attr), + actx->attr->name_length * 2); + ntfs_loc->stream_name_utf16_num_chars = name_length; + } - ntfs_loc->stream_name_utf16_num_chars = actx->attr->name_length; lte = new_lookup_table_entry(); if (!lte) goto out_free_ntfs_loc; @@ -333,13 +335,13 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, } ntfs_loc = NULL; DEBUG("Add resource for `%s' (size = %zu)", - dentry->file_name_utf8, - lte->resource_entry.original_size); + dentry->file_name_utf8, + lte->resource_entry.original_size); copy_hash(lte->hash, attr_hash); lookup_table_insert(lookup_table, lte); } } - if (actx->attr->name_length == 0) { + if (name_length == 0) { /* Unnamed data stream. Put the reference to it in the * dentry. */ if (dentry->lte) { @@ -355,7 +357,7 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, struct ads_entry *new_ads_entry; size_t stream_name_utf8_len; stream_name_utf8 = utf16_to_utf8((const char*)attr_record_name(actx->attr), - actx->attr->name_length, + name_length * 2, &stream_name_utf8_len); if (!stream_name_utf8) goto out_free_lte; @@ -363,6 +365,8 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, FREE(stream_name_utf8); if (!new_ads_entry) goto out_free_lte; + + wimlib_assert(new_ads_entry->stream_name_len == name_length * 2); new_ads_entry->lte = lte; } diff --git a/src/resource.c b/src/resource.c index fd75a629..59c1d9c6 100644 --- a/src/resource.c +++ b/src/resource.c @@ -748,6 +748,8 @@ static int write_wim_resource(struct lookup_table_entry *lte, ntfs_inode *ni = NULL; #endif + wimlib_assert(lte); + /* Original size of the resource */ original_size = wim_resource_size(lte);