+ targets[blob->out_refcnt].inode = inode;
+ targets[blob->out_refcnt].stream = strm;
+ blob->out_refcnt++;
+ return 0;
+}
+
+static int
+ref_stream_if_needed(struct wim_dentry *dentry, struct wim_inode *inode,
+ struct wim_inode_stream *strm, struct apply_ctx *ctx)
+{
+ 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;
+ }
+ break;