+ if (ret == 0)
+ DEBUG("Successfully captured NTFS streams from `%s'", path);
+ else
+ DEBUG("Failed to capture NTFS streams from `%s", path);
+ return ret;
+}
+
+struct readdir_ctx {
+ struct dentry *parent;
+ ntfs_inode *dir_ni;
+ char *path;
+ size_t path_len;
+ struct lookup_table *lookup_table;
+ struct sd_set *sd_set;
+ const struct capture_config *config;
+ ntfs_volume **ntfs_vol_p;
+};
+
+static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni,
+ char path[], size_t path_len,
+ struct lookup_table *lookup_table,
+ struct sd_set *sd_set,
+ const struct capture_config *config,
+ ntfs_volume **ntfs_vol_p);
+
+
+static int wim_ntfs_capture_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;
+
+ if (utf8_name[0] == '.' &&
+ (utf8_name[1] == '\0' ||
+ (utf8_name[1] == '.' && utf8_name[2] == '\0'))) {
+ DEBUG("Skipping dentry `%s'", utf8_name);
+ ret = 0;
+ goto out_free_utf8_name;
+ }
+
+ DEBUG("Opening inode for `%s'", utf8_name);
+
+ 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;
+ }
+ path_len = ctx->path_len;
+ if (path_len != 1)
+ ctx->path[path_len++] = '/';
+ memcpy(ctx->path + path_len, utf8_name, utf8_name_len + 1);
+ path_len += utf8_name_len;
+ ret = __build_dentry_tree_ntfs(&child, ni, ctx->path, path_len,
+ ctx->lookup_table, ctx->sd_set,
+ ctx->config, ctx->ntfs_vol_p);
+ DEBUG("Linking dentry `%s' with parent `%s'",
+ child->file_name_utf8, ctx->parent->file_name_utf8);
+
+ link_dentry(child, ctx->parent);
+ DEBUG("Return %d", ret);
+out_close_ni:
+ ntfs_inode_close(ni);
+out_free_utf8_name:
+ FREE(utf8_name);
+out: