+ struct wim_lookup_table_entry *lte;
+ for (unsigned i = 0; i <= inode->i_num_ads; i++) {
+ lte = inode_stream_lte(inode, i, table);
+ if (lte) {
+ if (lte->out_refcnt == 0) {
+ if (lte->unhashed)
+ stream_size_table_insert(lte, tab);
+ list_add_tail(<e->write_streams_list, stream_list);
+ }
+ lte->out_refcnt += inode->i_nlink;
+ }
+ }
+ return 0;
+}
+
+static int
+image_find_streams_to_write(WIMStruct *w)
+{
+ struct wim_image_metadata *imd;
+ struct find_streams_ctx *ctx;
+ struct wim_inode *inode;
+ struct wim_lookup_table_entry *lte;
+
+ ctx = w->private;
+ imd = wim_get_current_image_metadata(w);
+
+ image_for_each_unhashed_stream(lte, imd) {
+ lte->out_refcnt = 0;
+ wimlib_assert(lte->unhashed);
+ wimlib_assert(lte->my_ptr != NULL);
+ }
+
+ /* Go through this image's inodes to find any streams that have not been
+ * found yet. */
+ image_for_each_inode(inode, imd) {
+ inode_find_streams_to_write(inode, w->lookup_table,
+ &ctx->stream_list,
+ &ctx->stream_size_tab);
+ }
+ return 0;
+}
+
+/* Given a WIM that from which one or all of the images is being written, build
+ * the list of unique streams ('struct wim_lookup_table_entry's) that must be
+ * written, plus any unhashed streams that need to be written but may be
+ * identical to other hashed or unhashed streams being written. These unhashed
+ * streams are checksummed while the streams are being written. To aid this
+ * process, the member @unique_size is set to 1 on streams that have a unique
+ * size and therefore must be written.
+ *
+ * The out_refcnt member of each 'struct wim_lookup_table_entry' is set to
+ * indicate the number of times the stream is referenced in only the streams
+ * that are being written; this may still be adjusted later when unhashed
+ * streams are being resolved.
+ */
+static int
+prepare_stream_list(WIMStruct *wim, int image, struct list_head *stream_list)
+{
+ int ret;
+ struct find_streams_ctx ctx;
+
+ for_lookup_table_entry(wim->lookup_table, lte_zero_out_refcnt, NULL);
+ ret = init_stream_size_table(&ctx.stream_size_tab, 9001);
+ if (ret)
+ return ret;
+ for_lookup_table_entry(wim->lookup_table, stream_size_table_insert,
+ &ctx.stream_size_tab);
+ INIT_LIST_HEAD(&ctx.stream_list);
+ wim->private = &ctx;
+ for_image(wim, image, image_find_streams_to_write);
+ destroy_stream_size_table(&ctx.stream_size_tab);
+
+ INIT_LIST_HEAD(stream_list);
+ list_splice(&ctx.stream_list, stream_list);
+ return 0;