- if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
- /* NTFS-3g extraction mode requested */
-#ifdef WITH_NTFS_3G
- if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
- WIMLIB_EXTRACT_FLAG_HARDLINK))) {
- ERROR("Cannot specify symlink or hardlink flags when applying\n"
- " directly to a NTFS volume");
- return WIMLIB_ERR_INVALID_PARAM;
- }
- if (!is_entire_image &&
- (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS))
- {
- ERROR("When applying directly to a NTFS volume you can "
- "only extract a full image, not part of one");
- return WIMLIB_ERR_INVALID_PARAM;
- }
- if (extract_flags & WIMLIB_EXTRACT_FLAG_UNIX_DATA) {
- ERROR("Cannot restore UNIX-specific data in "
- "the NTFS extraction mode");
- return WIMLIB_ERR_INVALID_PARAM;
- }
-#else
- ERROR("wimlib was compiled without support for NTFS-3g, so");
- ERROR("we cannot apply a WIM image directly to a NTFS volume");
+/* Tally features necessary to extract a dentry and the corresponding inode. */
+static void
+dentry_tally_features(struct wim_dentry *dentry, struct wim_features *features)
+{
+ struct wim_inode *inode = dentry->d_inode;
+
+ if (dentry_has_short_name(dentry))
+ features->short_names++;
+
+ if (inode->i_visited) {
+ features->hard_links++;
+ } else {
+ inode_tally_features(inode, features);
+ inode->i_visited = 1;
+ }
+}
+
+/* Tally the features necessary to extract the specified dentries. */
+static void
+dentry_list_get_features(struct list_head *dentry_list,
+ struct wim_features *features)
+{
+ struct wim_dentry *dentry;
+
+ list_for_each_entry(dentry, dentry_list, d_extraction_list_node)
+ dentry_tally_features(dentry, features);
+
+ list_for_each_entry(dentry, dentry_list, d_extraction_list_node)
+ dentry->d_inode->i_visited = 0;
+}
+
+static int
+do_feature_check(const struct wim_features *required_features,
+ const struct wim_features *supported_features,
+ int extract_flags)
+{
+ /* File attributes. */
+ if (!(extract_flags & WIMLIB_EXTRACT_FLAG_NO_ATTRIBUTES)) {
+ /* Note: Don't bother the user about FILE_ATTRIBUTE_ARCHIVE.
+ * We're an archive program, so theoretically we can do what we
+ * want with it. */
+
+ if (required_features->hidden_files &&
+ !supported_features->hidden_files)
+ WARNING("Ignoring FILE_ATTRIBUTE_HIDDEN of %lu files",
+ required_features->hidden_files);
+
+ if (required_features->system_files &&
+ !supported_features->system_files)
+ WARNING("Ignoring FILE_ATTRIBUTE_SYSTEM of %lu files",
+ required_features->system_files);
+
+ if (required_features->compressed_files &&
+ !supported_features->compressed_files)
+ WARNING("Ignoring FILE_ATTRIBUTE_COMPRESSED of %lu files",
+ required_features->compressed_files);
+
+ if (required_features->not_context_indexed_files &&
+ !supported_features->not_context_indexed_files)
+ WARNING("Ignoring FILE_ATTRIBUTE_NOT_CONTENT_INDEXED of %lu files",
+ required_features->not_context_indexed_files);
+
+ if (required_features->sparse_files &&
+ !supported_features->sparse_files)
+ WARNING("Ignoring FILE_ATTRIBUTE_SPARSE_FILE of %lu files",
+ required_features->sparse_files);
+
+ if (required_features->encrypted_directories &&
+ !supported_features->encrypted_directories)
+ WARNING("Ignoring FILE_ATTRIBUTE_ENCRYPTED of %lu directories",
+ required_features->encrypted_directories);
+ }
+
+ /* Encrypted files. */
+ if (required_features->encrypted_files &&
+ !supported_features->encrypted_files)
+ WARNING("Ignoring %lu encrypted files",
+ required_features->encrypted_files);
+
+ /* Named data streams. */
+ if (required_features->named_data_streams &&
+ (!supported_features->named_data_streams))
+ WARNING("Ignoring named data streams of %lu files",
+ required_features->named_data_streams);
+
+ /* Hard links. */
+ if (required_features->hard_links && !supported_features->hard_links)
+ WARNING("Extracting %lu hard links as independent files",
+ required_features->hard_links);
+
+ /* Symbolic links and reparse points. */
+ if ((extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_SYMLINKS) &&
+ required_features->symlink_reparse_points &&
+ !supported_features->symlink_reparse_points &&
+ !supported_features->reparse_points)
+ {
+ ERROR("Extraction backend does not support symbolic links!");