From: Eric Biggers Date: Sat, 18 Aug 2012 04:59:17 +0000 (-0500) Subject: Alternate stream entries fixes X-Git-Tag: v1.0.0~149 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=91525408b4c14f6defd5c4d304515f564e0b3b01 Alternate stream entries fixes --- diff --git a/src/dentry.c b/src/dentry.c index d3399acb..85512990 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -39,14 +39,33 @@ #include #include +/* Real length of a dentry, including the alternate data stream entries, which + * are not included in the dentry->length field... */ +u64 dentry_total_length(const struct dentry *dentry) +{ + u64 length = dentry->length; + if (dentry->num_ads) { + u16 i = 0; + do { + length += WIM_ADS_ENTRY_DISK_SIZE + + dentry->ads_entries[i].stream_name_len; + } while (++i != dentry->num_ads); + /* If there are Alternate Stream Entries, we apparently need to + * round up to the NEXT 8-byte boundary, even if we are already + * aligned on one... */ + length++; + } + /* Round to 8 byte boundary. */ + return (length + 7) & ~7; +} /* Transfers file attributes from a `stat' buffer to a struct dentry. */ void stbuf_to_dentry(const struct stat *stbuf, struct dentry *dentry) { if (S_ISDIR(stbuf->st_mode)) - dentry->attributes = WIM_FILE_ATTRIBUTE_DIRECTORY; + dentry->attributes = FILE_ATTRIBUTE_DIRECTORY; else - dentry->attributes = WIM_FILE_ATTRIBUTE_NORMAL; + dentry->attributes = FILE_ATTRIBUTE_NORMAL; } /* Transfers file attributes from a struct dentry to a `stat' buffer. */ @@ -210,7 +229,7 @@ void calculate_subdir_offsets(struct dentry *dentry, u64 *subdir_offset_p) /* Advance the subdir offset by the amount of space the children * of this dentry take up. */ do { - *subdir_offset_p += child->length; + *subdir_offset_p += dentry_total_length(child); child = child->next; } while (child != dentry->children); @@ -314,21 +333,21 @@ struct file_attr_flag { const char *name; }; struct file_attr_flag file_attr_flags[] = { - {WIM_FILE_ATTRIBUTE_READONLY, "READONLY"}, - {WIM_FILE_ATTRIBUTE_HIDDEN, "HIDDEN"}, - {WIM_FILE_ATTRIBUTE_SYSTEM, "SYSTEM"}, - {WIM_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY"}, - {WIM_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE"}, - {WIM_FILE_ATTRIBUTE_DEVICE, "DEVICE"}, - {WIM_FILE_ATTRIBUTE_NORMAL, "NORMAL"}, - {WIM_FILE_ATTRIBUTE_TEMPORARY, "TEMPORARY"}, - {WIM_FILE_ATTRIBUTE_SPARSE_FILE, "SPARSE_FILE"}, - {WIM_FILE_ATTRIBUTE_REPARSE_POINT, "REPARSE_POINT"}, - {WIM_FILE_ATTRIBUTE_COMPRESSED, "COMPRESSED"}, - {WIM_FILE_ATTRIBUTE_OFFLINE, "OFFLINE"}, - {WIM_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,"NOT_CONTENT_INDEXED"}, - {WIM_FILE_ATTRIBUTE_ENCRYPTED, "ENCRYPTED"}, - {WIM_FILE_ATTRIBUTE_VIRTUAL, "VIRTUAL"}, + {FILE_ATTRIBUTE_READONLY, "READONLY"}, + {FILE_ATTRIBUTE_HIDDEN, "HIDDEN"}, + {FILE_ATTRIBUTE_SYSTEM, "SYSTEM"}, + {FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY"}, + {FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE"}, + {FILE_ATTRIBUTE_DEVICE, "DEVICE"}, + {FILE_ATTRIBUTE_NORMAL, "NORMAL"}, + {FILE_ATTRIBUTE_TEMPORARY, "TEMPORARY"}, + {FILE_ATTRIBUTE_SPARSE_FILE, "SPARSE_FILE"}, + {FILE_ATTRIBUTE_REPARSE_POINT, "REPARSE_POINT"}, + {FILE_ATTRIBUTE_COMPRESSED, "COMPRESSED"}, + {FILE_ATTRIBUTE_OFFLINE, "OFFLINE"}, + {FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,"NOT_CONTENT_INDEXED"}, + {FILE_ATTRIBUTE_ENCRYPTED, "ENCRYPTED"}, + {FILE_ATTRIBUTE_VIRTUAL, "VIRTUAL"}, }; /* Prints a directory entry. @lookup_table is a pointer to the lookup table, or @@ -343,11 +362,11 @@ int print_dentry(struct dentry *dentry, void *lookup_table) printf("Attributes = 0x%x\n", dentry->attributes); for (i = 0; i < ARRAY_LEN(file_attr_flags); i++) if (file_attr_flags[i].flag & dentry->attributes) - printf(" WIM_FILE_ATTRIBUTE_%s is set\n", + printf(" FILE_ATTRIBUTE_%s is set\n", file_attr_flags[i].name); printf("Security ID = %d\n", dentry->security_id); printf("Subdir offset = %"PRIu64"\n", dentry->subdir_offset); - /*printf("Unused1 = %"PRIu64"\n", dentry->unused1);*/ + /*printf("Unused1 = 0x%"PRIu64"\n", dentry->unused1);*/ /*printf("Unused2 = %"PRIu64"\n", dentry->unused2);*/ printf("Creation Time = %"PRIu64"\n", dentry->creation_time); printf("Last Access Time = %"PRIu64"\n", dentry->last_access_time); @@ -356,8 +375,8 @@ int print_dentry(struct dentry *dentry, void *lookup_table) printf("Hash = "); print_hash(dentry->hash); putchar('\n'); - printf("Reparse Tag = %u\n", dentry->reparse_tag); - printf("Hard Link Group = %"PRIu64"\n", dentry->hard_link); + printf("Reparse Tag = 0x%"PRIx32"\n", dentry->reparse_tag); + printf("Hard Link Group = 0x%"PRIx64"\n", dentry->hard_link); printf("Number of Alternate Data Streams = %hu\n", dentry->num_ads); printf("Filename = \""); print_string(dentry->file_name, dentry->file_name_len); @@ -379,6 +398,15 @@ int print_dentry(struct dentry *dentry, void *lookup_table) } else { putchar('\n'); } + for (u16 i = 0; i < dentry->num_ads; i++) { + printf("[Alternate Stream Entry %u]\n", i); + printf("Name = \"%s\"\n", dentry->ads_entries[i].stream_name_utf8); + lte = lookup_resource(lookup_table, dentry->ads_entries[i].hash); + if (lte) + print_lookup_table_entry(lte, NULL); + else + putchar('\n'); + } return 0; } @@ -611,40 +639,52 @@ void calculate_dir_tree_statistics(struct dentry *root, struct lookup_table *tab } static int read_ads_entries(const u8 *p, struct dentry *dentry, - unsigned remaining_size) + u64 remaining_size) { u16 num_ads = dentry->num_ads; struct ads_entry *ads_entries = CALLOC(num_ads, sizeof(struct ads_entry)); int ret; if (!ads_entries) { - ERROR("Could not allocate memory for %u alternate data stream " - "entries", num_ads); + ERROR("Could not allocate memory for %"PRIu16" " + "alternate data stream entries", num_ads); return WIMLIB_ERR_NOMEM; } + DEBUG2("Reading %"PRIu16" alternate data streams " + "(remaining size = %"PRIu64")", num_ads, remaining_size); + for (u16 i = 0; i < num_ads; i++) { struct ads_entry *cur_entry = &ads_entries[i]; u64 length; size_t utf8_len; /* Read the base stream entry, excluding the stream name. */ if (remaining_size < WIM_ADS_ENTRY_DISK_SIZE) { - ERROR("Stream entries go past end of directory entry"); + ERROR("Stream entries go past end of metadata resource"); ret = WIMLIB_ERR_INVALID_DENTRY; goto out_free_ads_entries; } remaining_size -= WIM_ADS_ENTRY_DISK_SIZE; + /*print_string(p + 40, 10);*/ + /*print_byte_field(p, 50);*/ p = get_u64(p, &length); /* ADS entry length */ + + DEBUG2("ADS length = %"PRIu64, length); + p += 8; /* Unused */ p = get_bytes(p, WIM_HASH_SIZE, (u8*)cur_entry->hash); p = get_u16(p, &cur_entry->stream_name_len); + + DEBUG2("Stream name length = %u", cur_entry->stream_name_len); + cur_entry->stream_name = NULL; cur_entry->stream_name_utf8 = NULL; - if (remaining_size < cur_entry->stream_name_len) { - ERROR("Stream entries go past end of directory entry"); + if (remaining_size < cur_entry->stream_name_len + 2) { + ERROR("Stream entries go past end of metadata resource"); ret = WIMLIB_ERR_INVALID_DENTRY; goto out_free_ads_entries; } + remaining_size -= cur_entry->stream_name_len + 2; cur_entry->stream_name = MALLOC(cur_entry->stream_name_len); if (!cur_entry->stream_name) { @@ -653,10 +693,12 @@ static int read_ads_entries(const u8 *p, struct dentry *dentry, } p = get_bytes(p, cur_entry->stream_name_len, (u8*)cur_entry->stream_name); + p += 2; /* NULL terminator of stream name */ cur_entry->stream_name_utf8 = utf16_to_utf8(cur_entry->stream_name, cur_entry->stream_name_len, &utf8_len); cur_entry->stream_name_len_utf8 = utf8_len; + print_byte_field(p, 16); if (!cur_entry->stream_name_utf8) { ret = WIMLIB_ERR_NOMEM; @@ -705,6 +747,7 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, * terminates the list of sibling directory entries. */ p = get_u64(&metadata_resource[offset], &dentry->length); + DEBUG("length = %zu, %zu\n", dentry->length, *(u64*)(&metadata_resource[offset])); /* A zero length field (really a length of 8, since that's how big the * directory entry is...) indicates that this is the end of directory @@ -736,6 +779,8 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, /* 2 unused fields */ p += 2 * sizeof(u64); + /*p = get_u64(p, &dentry->unused1);*/ + /*p = get_u64(p, &dentry->unused2);*/ p = get_u64(p, &dentry->creation_time); p = get_u64(p, &dentry->last_access_time); @@ -743,11 +788,29 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, p = get_bytes(p, WIM_HASH_SIZE, dentry->hash); - p = get_u32(p, &dentry->reparse_tag); + /* + * I don't know what's going on here. It seems like M$ screwed up the + * reparse points, then put the fields in the same place and didn't + * document it. The WIM_HDR_FLAG_RP_FIX flag in the WIM header might + * have something to do with this, but it's not documented. + */ + if (dentry->attributes & FILE_ATTRIBUTE_REPARSE_POINT) { + /* ??? */ + u32 u1, u2; + p = get_u32(p, &u1); + /*p += 4;*/ + p = get_u32(p, &dentry->reparse_tag); + p = get_u32(p, &u2); + /*p += 4;*/ + dentry->hard_link = (u64)(u1) | ((u64)(u2) << 32); + } else { + p = get_u32(p, &dentry->reparse_tag); + p = get_u64(p, &dentry->hard_link); + } - /* The reparse_reserved field does not actually exist. */ + /* By the way, the reparse_reserved field does not actually exist (at + * least when the file is not a reparse point) */ - p = get_u64(p, &dentry->hard_link); p = get_u16(p, &dentry->num_ads); @@ -799,11 +862,44 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, goto out_free_file_name_utf8; } - get_bytes(p, short_name_len, short_name); + p = get_bytes(p, short_name_len, short_name); + + /* Some directory entries inexplicibly have a little over 70 bytes of + * extra data. The exact amount of data seems to be 72 bytes, but it is + * aligned on the next 8-byte boundary. Here's an example of the + * aligned data: + * + * 01000000400000006c786bbac58ede11b0bb00261870892ab6adb76fe63a3 + * e468fca86530d2effa16c786bbac58ede11b0bb00261870892a0000000000 + * 0000000000000000000000 + * + * Here's one interpretation of how the data is laid out. + * + * struct unknown { + * u32 field1; (always 0x00000001) + * u32 field2; (always 0x40000000) + * u16 field3; + * u32 field4; + * u32 field5; + * u32 field6; + * u8 data[48]; (???) + * u64 reserved1; (always 0) + * u64 reserved2; (always 0) + * };*/ +#if 0 + if (dentry->length - calculated_size >= WIM_ADS_ENTRY_DISK_SIZE) { + printf("%s: %lu / %lu (", file_name_utf8, + calculated_size, dentry->length); + print_string(p + WIM_ADS_ENTRY_DISK_SIZE, dentry->length - calculated_size - WIM_ADS_ENTRY_DISK_SIZE); + puts(")"); + print_byte_field(p, dentry->length - calculated_size); + putchar('\n'); + } +#endif if (dentry->num_ads != 0) { ret = read_ads_entries(p, dentry, - dentry->length - calculated_size); + metadata_resource_len - offset - calculated_size); if (ret != 0) goto out_free_short_name; } @@ -845,10 +941,7 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p) p = put_u64(p, dentry->creation_time); p = put_u64(p, dentry->last_access_time); p = put_u64(p, dentry->last_write_time); - if (!is_empty_file_hash(dentry->hash)) - memcpy(p, dentry->hash, WIM_HASH_SIZE); - else - DEBUG("zero hash for %s\n", dentry->file_name_utf8); + memcpy(p, dentry->hash, WIM_HASH_SIZE); p += WIM_HASH_SIZE; p = put_u32(p, dentry->reparse_tag); p = put_u64(p, dentry->hard_link); @@ -983,7 +1076,7 @@ int read_dentry_tree(const u8 metadata_resource[], u64 metadata_resource_len, } /* Advance to the offset of the next child. */ - cur_offset += child->length; + cur_offset += dentry_total_length(child); } /* Link last child to first one, and set parent's diff --git a/src/dentry.h b/src/dentry.h index ac2eeafe..2f51ecd8 100644 --- a/src/dentry.h +++ b/src/dentry.h @@ -2,12 +2,49 @@ #define _WIMLIB_DENTRY_H #include "util.h" +#include "config.h" #include /* Size of the struct dentry up to and including the file_name_len. */ -#define WIM_DENTRY_DISK_SIZE 102 +#define WIM_DENTRY_DISK_SIZE 102 -#define WIM_ADS_ENTRY_DISK_SIZE (2 * sizeof(u64) + WIM_HASH_SIZE + sizeof(u16)) +#define WIM_ADS_ENTRY_DISK_SIZE 38 + +#ifndef WITH_NTFS_3G +/* + * Reparse tags documented at + * http://msdn.microsoft.com/en-us/library/dd541667(v=prot.10).aspx + * + * IO_REPARSE_TAG_SYMLINK is the only one we really care about. + */ +#define IO_REPARSE_TAG_RESERVED_ZERO 0x00000000 +#define IO_REPARSE_TAG_RESERVED_ONE 0x00000001 +#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 +#define IO_REPARSE_TAG_HSM 0xC0000004 +#define IO_REPARSE_TAG_HSM2 0x80000006 +#define IO_REPARSE_TAG_DRIVER_EXTENDER 0x80000005 +#define IO_REPARSE_TAG_SIS 0x80000007 +#define IO_REPARSE_TAG_DFS 0x8000000A +#define IO_REPARSE_TAG_DFSR 0x80000012 +#define IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B +#define IO_REPARSE_TAG_SYMLINK 0xA000000C +#endif /* !WITH_NTFS_3G */ + +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define FILE_ATTRIBUTE_DEVICE 0x00000040 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 +#define FILE_ATTRIBUTE_VIRTUAL 0x00010000 /* Alternate data stream entry */ struct ads_entry { @@ -68,8 +105,8 @@ struct dentry { u64 subdir_offset; /* Reserved for future disuse. Currently ignoring these fields. */ - //u64 unused1; - //u64 unused2; + u64 unused1; + u64 unused2; /* Timestamps for the entry. The timestamps are the number of * 100-nanosecond intervals that have elapsed since 12:00 A.M., January @@ -88,7 +125,9 @@ struct dentry { /* 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. */ + * 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; /* If the reparse_reserved field existed, there would be a 4-byte gap @@ -135,21 +174,7 @@ struct dentry { int refcnt; }; -#define WIM_FILE_ATTRIBUTE_READONLY 0x00000001 -#define WIM_FILE_ATTRIBUTE_HIDDEN 0x00000002 -#define WIM_FILE_ATTRIBUTE_SYSTEM 0x00000004 -#define WIM_FILE_ATTRIBUTE_DIRECTORY 0x00000010 -#define WIM_FILE_ATTRIBUTE_ARCHIVE 0x00000020 -#define WIM_FILE_ATTRIBUTE_DEVICE 0x00000040 -#define WIM_FILE_ATTRIBUTE_NORMAL 0x00000080 -#define WIM_FILE_ATTRIBUTE_TEMPORARY 0x00000100 -#define WIM_FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 -#define WIM_FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 -#define WIM_FILE_ATTRIBUTE_COMPRESSED 0x00000800 -#define WIM_FILE_ATTRIBUTE_OFFLINE 0x00001000 -#define WIM_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 -#define WIM_FILE_ATTRIBUTE_ENCRYPTED 0x00004000 -#define WIM_FILE_ATTRIBUTE_VIRTUAL 0x00010000 +extern u64 dentry_total_length(const struct dentry *dentry); extern void stbuf_to_dentry(const struct stat *stbuf, struct dentry *dentry); @@ -235,7 +260,7 @@ static inline bool dentry_is_only_child(const struct dentry *dentry) static inline bool dentry_is_directory(const struct dentry *dentry) { - return (dentry->attributes & WIM_FILE_ATTRIBUTE_DIRECTORY) != 0; + return (dentry->attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } static inline bool dentry_is_regular_file(const struct dentry *dentry) diff --git a/src/extract.c b/src/extract.c index f3b8da06..80549a6b 100644 --- a/src/extract.c +++ b/src/extract.c @@ -37,6 +37,7 @@ #ifdef WITH_NTFS_3G #include +#include #endif /* Sets and creates the directory to which files are to be extracted when @@ -88,7 +89,8 @@ done: */ static int extract_regular_file(WIMStruct *w, const struct dentry *dentry, - const char *output_path) + const char *output_path, + int extract_flags) { struct lookup_table_entry *lte; int ret; @@ -100,12 +102,12 @@ static int extract_regular_file(WIMStruct *w, /* If we already extracted the same file or a hard link copy of it, we * may be able to simply create a link. The exact action is specified * by the current @link_type. */ - if ((w->extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) && + if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) && lte && lte->out_refcnt != 0) { wimlib_assert(lte->file_on_disk); - if (w->extract_flags & WIMLIB_EXTRACT_FLAG_HARDLINK) { + if (extract_flags & WIMLIB_EXTRACT_FLAG_HARDLINK) { if (link(lte->file_on_disk, output_path) != 0) { ERROR_WITH_ERRNO("Failed to hard link " "`%s' to `%s'", @@ -222,6 +224,13 @@ static int extract_directory(struct dentry *dentry, const char *output_path) return 0; } +struct extract_args { + WIMStruct *w; + int extract_flags; +#ifdef WITH_NTFS_3G + struct SECURITY_API *scapi; +#endif +}; /* * Extracts a file or directory from the WIM archive. For use in @@ -232,11 +241,13 @@ static int extract_directory(struct dentry *dentry, const char *output_path) */ static int extract_regular_file_or_directory(struct dentry *dentry, void *arg) { - WIMStruct *w = (WIMStruct*)arg; + struct extract_args *args = arg; + WIMStruct *w = args->w; + int extract_flags = args->extract_flags; size_t len = strlen(w->output_dir); char output_path[len + dentry->full_path_utf8_len + 1]; - if (w->extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE) + if (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE) puts(dentry->full_path_utf8); memcpy(output_path, w->output_dir, len); @@ -244,7 +255,7 @@ static int extract_regular_file_or_directory(struct dentry *dentry, void *arg) output_path[len + dentry->full_path_utf8_len] = '\0'; if (dentry_is_regular_file(dentry)) { - return extract_regular_file(w, dentry, output_path); + return extract_regular_file(w, dentry, output_path, extract_flags); } else { if (dentry_is_root(dentry)) /* Root doesn't need to be extracted. */ return 0; @@ -253,7 +264,8 @@ static int extract_regular_file_or_directory(struct dentry *dentry, void *arg) } } -static int extract_single_image(WIMStruct *w, int image) + +static int extract_single_image(WIMStruct *w, int image, int extract_flags) { DEBUG("Extracting image %d", image); @@ -262,14 +274,22 @@ static int extract_single_image(WIMStruct *w, int image) if (ret != 0) return ret; + struct extract_args args = { + .w = w, + .extract_flags = extract_flags, + #ifdef WITH_NTFS_3G + .scapi = NULL + #endif + }; + return for_dentry_in_tree(wim_root_dentry(w), - extract_regular_file_or_directory, w); + extract_regular_file_or_directory, &args); } /* Extracts all images from the WIM to w->output_dir, with the images placed in * subdirectories named by their image names. */ -static int extract_all_images(WIMStruct *w) +static int extract_all_images(WIMStruct *w, int extract_flags) { size_t image_name_max_len = max(xml_get_max_image_name_len(w), 20); size_t output_path_len = strlen(w->output_dir); @@ -294,7 +314,7 @@ static int extract_all_images(WIMStruct *w) ret = set_output_dir(w, buf); if (ret != 0) goto done; - ret = extract_single_image(w, image); + ret = extract_single_image(w, image, extract_flags); if (ret != 0) goto done; } @@ -344,13 +364,12 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image, return WIMLIB_ERR_UNSUPPORTED; #endif } - w->extract_flags = flags; if (image == WIM_ALL_IMAGES) { w->is_multi_image_extraction = true; - ret = extract_all_images(w); + ret = extract_all_images(w, flags); } else { w->is_multi_image_extraction = false; - ret = extract_single_image(w, image); + ret = extract_single_image(w, image, flags); } return ret; diff --git a/src/modify.c b/src/modify.c index fde95d09..5694ec20 100644 --- a/src/modify.c +++ b/src/modify.c @@ -478,7 +478,7 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir, if (ret != 0) goto out_free_dentry_tree; - root_dentry->attributes |= WIM_FILE_ATTRIBUTE_DIRECTORY; + root_dentry->attributes |= FILE_ATTRIBUTE_DIRECTORY; /* Construct the dentry tree from the outside filesystem. */ if (stat(dir, &root_stat) != 0) { diff --git a/src/mount.c b/src/mount.c index bf194da4..c6ce5588 100644 --- a/src/mount.c +++ b/src/mount.c @@ -495,7 +495,7 @@ static int wimfs_mkdir(const char *path, mode_t mode) return -EEXIST; newdir = new_dentry(basename); - newdir->attributes |= WIM_FILE_ATTRIBUTE_DIRECTORY; + newdir->attributes |= FILE_ATTRIBUTE_DIRECTORY; link_dentry(newdir, parent); return 0; }