- struct wim_inode *inode = dentry->d_inode;
- int ret;
- unsigned stream_idx;
- struct wim_lookup_table_entry *stream;
-
- if (unlikely(inode_is_encrypted_directory(inode)))
- return 0;
-
- if (unlikely(ctx->apply_ops->will_externally_back)) {
- ret = (*ctx->apply_ops->will_externally_back)(dentry, ctx);
- if (ret >= 0) {
- if (ret) /* Error */
- return ret;
- /* Will externally back */
- return 0;
+ bool need_stream = false;
+ switch (strm->stream_type) {
+ case STREAM_TYPE_DATA:
+ if (stream_is_named(strm)) {
+ /* Named data stream */
+ if (ctx->supported_features.named_data_streams)
+ need_stream = true;
+ } else if (!(inode->i_attributes & (FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_ENCRYPTED))
+ && !(inode_is_symlink(inode)
+ && !ctx->supported_features.reparse_points
+ && ctx->supported_features.symlink_reparse_points))
+ {
+ /*
+ * Unnamed data stream. Skip if any of the following is true:
+ *
+ * - file is a directory
+ * - file is encrypted
+ * - backend needs to create the file as UNIX symlink
+ * - backend will extract the stream as externally
+ * backed from the WIM archive itself
+ */
+ if (ctx->apply_ops->will_back_from_wim) {
+ int ret = (*ctx->apply_ops->will_back_from_wim)(dentry, ctx);
+ if (ret > 0) /* Error? */
+ return ret;
+ if (ret < 0) /* Won't externally back? */
+ need_stream = true;
+ } else {
+ need_stream = true;
+ }
+ }
+ break;
+ case STREAM_TYPE_REPARSE_POINT:
+ wimlib_assert(inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT);
+ if (ctx->supported_features.reparse_points ||
+ (inode_is_symlink(inode) &&
+ ctx->supported_features.symlink_reparse_points))
+ need_stream = true;
+ break;
+ case STREAM_TYPE_EFSRPC_RAW_DATA:
+ wimlib_assert(inode->i_attributes & FILE_ATTRIBUTE_ENCRYPTED);
+ if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if (ctx->supported_features.encrypted_directories)
+ need_stream = true;
+ } else {
+ if (ctx->supported_features.encrypted_files)
+ need_stream = true;