-/*
- * Writes a dentry to an output buffer.
- *
- * @dentry: The dentry structure.
- * @p: The memory location to write the data to.
- * @return: Pointer to the byte after the last byte we wrote as part of the
- * dentry.
- */
-static u8 *write_dentry(const struct dentry *dentry, u8 *p)
-{
- u8 *orig_p = p;
- unsigned padding;
-
- p = put_u64(p, dentry->length);
- p = put_u32(p, dentry->attributes);
- p = put_u32(p, dentry->security_id);
- p = put_u64(p, dentry->subdir_offset);
- p = put_u64(p, 0); /* unused1 */
- p = put_u64(p, 0); /* unused2 */
- p = put_u64(p, dentry->creation_time);
- p = put_u64(p, dentry->last_access_time);
- p = put_u64(p, dentry->last_write_time);
- p = put_bytes(p, WIM_HASH_SIZE, dentry->hash);
- if (dentry->attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
- p = put_zeroes(p, 4);
- p = put_u32(p, dentry->reparse_tag);
- p = put_zeroes(p, 4);
- } else {
- u64 hard_link;
- p = put_u32(p, dentry->reparse_tag);
- if (dentry->link_group_list.next == &dentry->link_group_list)
- hard_link = 0;
- else
- hard_link = dentry->hard_link;
- p = put_u64(p, hard_link);
- }
- p = put_u16(p, dentry->num_ads);
- p = put_u16(p, dentry->short_name_len);
- p = put_u16(p, dentry->file_name_len);
- p = put_bytes(p, dentry->file_name_len, (u8*)dentry->file_name);
- p = put_u16(p, 0); /* filename padding, 2 bytes. */
- p = put_bytes(p, dentry->short_name_len, (u8*)dentry->short_name);
-
- wimlib_assert(p - orig_p <= dentry->length);
- if (p - orig_p < dentry->length)
- p = put_zeroes(p, dentry->length - (p - orig_p));
-
- p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
-
- for (u16 i = 0; i < dentry->num_ads; i++) {
- p = put_u64(p, ads_entry_length(&dentry->ads_entries[i]));
- p = put_u64(p, 0); /* Unused */
- p = put_bytes(p, WIM_HASH_SIZE, dentry->ads_entries[i].hash);
- p = put_u16(p, dentry->ads_entries[i].stream_name_len);
- p = put_bytes(p, dentry->ads_entries[i].stream_name_len,
- (u8*)dentry->ads_entries[i].stream_name);
- p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
- }
- return p;
-}
-
-/* Recursive function that writes a dentry tree rooted at @tree, not including
- * @tree itself, which has already been written, except in the case of the root
- * dentry, which is written right away, along with an end-of-directory entry. */
-u8 *write_dentry_tree(const struct dentry *tree, u8 *p)
-{
- const struct dentry *child;
-
- if (dentry_is_root(tree)) {
- p = write_dentry(tree, p);
-
- /* write end of directory entry */
- p = put_u64(p, 0);
- } else {
- /* Nothing to do for non-directories */
- if (!dentry_is_directory(tree))
- return p;
- }
-
- /* Write child dentries and end-of-directory entry. */
- child = tree->children;
- if (child) {
- do {
- p = write_dentry(child, p);
- child = child->next;
- } while (child != tree->children);
- }
-
- /* write end of directory entry */
- p = put_u64(p, 0);
-
- /* Recurse on children. */
- if (child) {
- do {
- p = write_dentry_tree(child, p);
- child = child->next;
- } while (child != tree->children);
- }
- return p;
-}
-