return 0;
}
+static int
+do_calculate_dentry_full_path(struct wim_dentry *dentry, void *_ignore)
+{
+ return calculate_dentry_full_path(dentry);
+}
+
+int
+calculate_dentry_tree_full_paths(struct wim_dentry *root)
+{
+ return for_dentry_in_tree(root, do_calculate_dentry_full_path, NULL);
+}
+
tchar *
dentry_full_path(struct wim_dentry *dentry)
{
int
print_dentry_full_path(struct wim_dentry *dentry, void *_ignore)
{
- tchar *full_path = dentry_full_path(dentry);
- if (!full_path)
- return WIMLIB_ERR_NOMEM;
- tprintf(T("%"TS"\n"), full_path);
- FREE(full_path);
- dentry->_full_path = 0;
- dentry->full_path_nbytes = 0;
+ int ret = calculate_dentry_full_path(dentry);
+ if (ret)
+ return ret;
+ tprintf(T("%"TS"\n"), dentry->_full_path);
return 0;
}
wim_timestamp_to_str(inode->i_last_write_time, buf, sizeof(buf));
tprintf(T("Last Write Time = %"TS"\n"), buf);
- tprintf(T("Reparse Tag = 0x%"PRIx32"\n"), inode->i_reparse_tag);
+ if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ tprintf(T("Reparse Tag = 0x%"PRIx32"\n"), inode->i_reparse_tag);
+ tprintf(T("Reparse Point Flags = 0x%"PRIx16"\n"),
+ inode->i_not_rpfixed);
+ tprintf(T("Reparse Point Unknown 2 = 0x%"PRIx32"\n"),
+ inode->i_rp_unknown_2);
+ }
+ tprintf(T("Reparse Point Unknown 1 = 0x%"PRIx32"\n"),
+ inode->i_rp_unknown_1);
tprintf(T("Hard Link Group = 0x%"PRIx64"\n"), inode->i_ino);
tprintf(T("Hard Link Group Size = %"PRIu32"\n"), inode->i_nlink);
tprintf(T("Number of Alternate Data Streams = %hu\n"), inode->i_num_ads);
inode->i_security_id = -1;
inode->i_nlink = 1;
inode->i_next_stream_id = 1;
+ inode->i_not_rpfixed = 1;
#ifdef WITH_FUSE
if (pthread_mutex_init(&inode->i_mutex, NULL) != 0) {
ERROR_WITH_ERRNO("Error initializing mutex");
* @parent: The dentry that will be the parent of @dentry.
* @dentry: The dentry to link.
*/
-bool
+struct wim_dentry *
dentry_add_child(struct wim_dentry * restrict parent,
struct wim_dentry * restrict child)
{
else if (result > 0)
new = &((*new)->rb_right);
else
- return false;
+ return this;
}
child->parent = parent;
rb_link_node(&child->rb_node, rb_parent, new);
rb_insert_color(&child->rb_node, root);
- return true;
+ return NULL;
}
/* Unlink a WIM dentry from the directory entry tree. */
}
#endif /* !__WIN32__ */
+static void
+replace_forbidden_characters(utf16lechar *name)
+{
+ utf16lechar *p;
+
+ for (p = name; *p; p++) {
+ #ifdef __WIN32__
+ if (wcschr(L"<>:\"/\\|?*", (wchar_t)*p))
+ #else
+ if (*p == '/')
+ #endif
+ {
+ if (name) {
+ WARNING("File, directory, or stream name \"%"WS"\"\n"
+ " contains forbidden characters; "
+ "replacing them with Unicode codepoint U+001A",
+ name);
+ name = NULL;
+ }
+ *p = 0x1a;
+ }
+ }
+}
+
/*
* Reads the alternate data stream entries of a WIM dentry.
*
get_bytes(p, cur_entry->stream_name_nbytes,
cur_entry->stream_name);
cur_entry->stream_name[cur_entry->stream_name_nbytes / 2] = 0;
+ replace_forbidden_characters(cur_entry->stream_name);
}
/* It's expected that the size of every ADS entry is a multiple
* of 8. However, to be safe, I'm allowing the possibility of
* reparse points, then put the fields in the same place and didn't
* document it. */
if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
- p += 4;
+ p = get_u32(p, &inode->i_rp_unknown_1);
p = get_u32(p, &inode->i_reparse_tag);
- p += 4;
+ p = get_u16(p, &inode->i_rp_unknown_2);
+ p = get_u16(p, &inode->i_not_rpfixed);
} else {
- p += 4;
- /* i_reparse_tag is irrelevant; just leave it at 0. */
+ p = get_u32(p, &inode->i_rp_unknown_1);
p = get_u64(p, &inode->i_ino);
}
WARNING("File name in WIM dentry \"%"WS"\" is not "
"null-terminated!", file_name);
}
+ replace_forbidden_characters(file_name);
}
/* Align the calculated size */
WARNING("Short name in WIM dentry \"%"WS"\" is not "
"null-terminated!", file_name);
}
+ replace_forbidden_characters(short_name);
}
/*
hash = inode_stream_hash(inode, 0);
p = put_bytes(p, SHA1_HASH_SIZE, hash);
if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
- p = put_zeroes(p, 4);
+ p = put_u32(p, 0);
p = put_u32(p, inode->i_reparse_tag);
- p = put_zeroes(p, 4);
+ p = put_u16(p, 0);
+ p = put_u16(p, inode->i_not_rpfixed);
} else {
u64 link_group_id;
p = put_u32(p, 0);