- /* Recursively write the rest of the dentry tree. */
- return write_dentry_tree_recursive(root, p);
-}
-
-
-static int
-init_wimlib_dentry(struct wimlib_dir_entry *wdentry,
- struct wim_dentry *dentry,
- const WIMStruct *wim)
-{
- int ret;
- size_t dummy;
- const struct wim_inode *inode = dentry->d_inode;
- struct wim_lookup_table_entry *lte;
-
-#if TCHAR_IS_UTF16LE
- wdentry->filename = dentry->file_name;
- wdentry->dos_name = dentry->short_name;
-#else
- if (dentry_has_long_name(dentry)) {
- ret = utf16le_to_tstr(dentry->file_name,
- dentry->file_name_nbytes,
- (tchar**)&wdentry->filename,
- &dummy);
- if (ret)
- return ret;
- }
- if (dentry_has_short_name(dentry)) {
- ret = utf16le_to_tstr(dentry->short_name,
- dentry->short_name_nbytes,
- (tchar**)&wdentry->dos_name,
- &dummy);
- if (ret)
- return ret;
- }
-#endif
- ret = calculate_dentry_full_path(dentry);
- if (ret)
- return ret;
- wdentry->full_path = dentry->_full_path;
-
- for (struct wim_dentry *d = dentry; !dentry_is_root(d); d = d->parent)
- wdentry->depth++;
-
- if (inode->i_security_id >= 0) {
- const struct wim_security_data *sd = wim_const_security_data(wim);
- wdentry->security_descriptor = sd->descriptors[inode->i_security_id];
- wdentry->security_descriptor_size = sd->sizes[inode->i_security_id];
- }
- wdentry->reparse_tag = inode->i_reparse_tag;
- wdentry->num_links = inode->i_nlink;
- wdentry->attributes = inode->i_attributes;
- wdentry->hard_link_group_id = inode->i_ino;
- wdentry->creation_time = wim_timestamp_to_timespec(inode->i_creation_time);
- wdentry->last_write_time = wim_timestamp_to_timespec(inode->i_last_write_time);
- wdentry->last_access_time = wim_timestamp_to_timespec(inode->i_last_access_time);
-
- lte = inode_unnamed_lte(inode, wim->lookup_table);
- if (lte)
- lte_to_wimlib_resource_entry(lte, &wdentry->streams[0].resource);
-
- for (unsigned i = 0; i < inode->i_num_ads; i++) {
- if (inode->i_ads_entries[i].stream_name == NULL)
- continue;
- lte = inode_stream_lte(inode, i + 1, wim->lookup_table);
- wdentry->num_named_streams++;
- if (lte) {
- lte_to_wimlib_resource_entry(lte, &wdentry->streams[
- wdentry->num_named_streams].resource);
- }
- #if TCHAR_IS_UTF16LE
- wdentry->streams[wdentry->num_named_streams].stream_name =
- inode->i_ads_entries[i].stream_name;
- #else
- size_t dummy;
-
- ret = utf16le_to_tstr(inode->i_ads_entries[i].stream_name,
- inode->i_ads_entries[i].stream_name_nbytes,
- (tchar**)&wdentry->streams[
- wdentry->num_named_streams].stream_name,
- &dummy);
- if (ret)
- return ret;
- #endif
- }
- return 0;
-}
-
-static void
-free_wimlib_dentry(struct wimlib_dir_entry *wdentry)
-{
-#if !TCHAR_IS_UTF16LE
- FREE((tchar*)wdentry->filename);
- FREE((tchar*)wdentry->dos_name);
- for (unsigned i = 1; i <= wdentry->num_named_streams; i++)
- FREE((tchar*)wdentry->streams[i].stream_name);
-#endif
- FREE(wdentry);
-}
-
-struct iterate_dir_tree_ctx {
- WIMStruct *wim;
- int flags;
- wimlib_iterate_dir_tree_callback_t cb;
- void *user_ctx;
-};
-
-static int
-do_iterate_dir_tree(WIMStruct *wim,
- struct wim_dentry *dentry, int flags,
- wimlib_iterate_dir_tree_callback_t cb,
- void *user_ctx);
-
-static int
-call_do_iterate_dir_tree(struct wim_dentry *dentry, void *_ctx)
-{
- struct iterate_dir_tree_ctx *ctx = _ctx;
- return do_iterate_dir_tree(ctx->wim, dentry, ctx->flags,
- ctx->cb, ctx->user_ctx);
-}
-
-static int
-do_iterate_dir_tree(WIMStruct *wim,
- struct wim_dentry *dentry, int flags,
- wimlib_iterate_dir_tree_callback_t cb,
- void *user_ctx)
-{
- u32 level;
- struct wimlib_dir_entry *wdentry;
- int ret = WIMLIB_ERR_NOMEM;
-
-
- wdentry = CALLOC(1, sizeof(struct wimlib_dir_entry) +
- (1 + dentry->d_inode->i_num_ads) *
- sizeof(struct wimlib_stream_entry));
- if (!wdentry)
- goto out;
-
- ret = init_wimlib_dentry(wdentry, dentry, wim);
- if (ret)
- goto out_free_wimlib_dentry;
-
- if (!(flags & WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN)) {
- ret = (*cb)(wdentry, user_ctx);
- if (ret)
- goto out_free_wimlib_dentry;
- }
-
- if (flags & (WIMLIB_ITERATE_DIR_TREE_FLAG_RECURSIVE |
- WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN))
- {
- struct iterate_dir_tree_ctx ctx = {
- .wim = wim,
- .flags = flags &= ~WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN,
- .cb = cb,
- .user_ctx = user_ctx,
- };
- ret = for_dentry_child(dentry, call_do_iterate_dir_tree, &ctx);
- }
-out_free_wimlib_dentry:
- free_wimlib_dentry(wdentry);
-out:
- return ret;
-}
-
-struct image_iterate_dir_tree_ctx {
- const tchar *path;
- int flags;
- wimlib_iterate_dir_tree_callback_t cb;
- void *user_ctx;
-};
-