+struct readdir_ctx {
+ struct dentry *dentry;
+ ntfs_inode *dir_ni;
+ char *path;
+ size_t path_len;
+ struct lookup_table *lookup_table;
+ struct sd_tree *tree;
+ ntfs_volume **ntfs_vol_p;
+};
+
+static int __build_dentry_tree_ntfs(struct dentry *dentry, ntfs_inode *ni,
+ char path[], size_t path_len,
+ struct lookup_table *lookup_table,
+ struct sd_tree *tree,
+ ntfs_volume **ntfs_vol_p);
+
+
+static int filldir(void *dirent, const ntfschar *name,
+ const int name_len, const int name_type, const s64 pos,
+ const MFT_REF mref, const unsigned dt_type)
+{
+ struct readdir_ctx *ctx;
+ size_t utf8_name_len;
+ char *utf8_name;
+ struct dentry *child;
+ int ret;
+ size_t path_len;
+
+ ret = -1;
+
+ utf8_name = utf16_to_utf8((const u8*)name, name_len * 2,
+ &utf8_name_len);
+ if (!utf8_name)
+ goto out;
+
+ ctx = dirent;
+
+ ntfs_inode *ni = ntfs_inode_open(ctx->dir_ni->vol, mref);
+ if (!ni) {
+ ERROR_WITH_ERRNO("Failed to open NTFS inode");
+ ret = 1;
+ }
+ child = new_dentry(utf8_name);
+ if (!child)
+ goto out_close_ni;
+
+ memcpy(ctx->path + ctx->path_len, utf8_name, utf8_name_len + 1);
+ path_len = ctx->path_len + utf8_name_len;
+ ret = __build_dentry_tree_ntfs(child, ni, ctx->path, path_len,
+ ctx->lookup_table, ctx->tree,
+ ctx->ntfs_vol_p);
+ link_dentry(child, ctx->dentry);
+out_close_ni:
+ ntfs_inode_close(ni);
+out_free_utf8_name:
+ FREE(utf8_name);
+out:
+ return ret;
+}
+
+/* Recursively build a WIM dentry tree corresponding to a NTFS volume.
+ * At the same time, update the WIM lookup table with lookup table entries for
+ * the NTFS streams, and build an array of security descriptors.
+ */