+
+#if 0
+static bool dentries_have_same_ads(const struct dentry *d1,
+ const struct dentry *d2)
+{
+ wimlib_assert(d1->num_ads == d2->num_ads);
+ /* Verify stream names and hashes are the same */
+ for (u16 i = 0; i < d1->num_ads; i++) {
+ if (strcmp(d1->ads_entries[i].stream_name_utf8,
+ d2->ads_entries[i].stream_name_utf8) != 0)
+ return false;
+ if (!hashes_equal(d1->ads_entries[i].hash,
+ d2->ads_entries[i].hash))
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Share the alternate stream entries between hard-linked dentries.
+ *
+ * Notes:
+ * - If you use 'imagex.exe' (version 6.1.7600.16385) to create a WIM containing
+ * hard-linked files, only one dentry in the hard link set will refer to data
+ * streams, including all alternate data streams. The rest of the dentries in
+ * the hard link set will be marked as having 0 alternate data streams and
+ * will not refer to any main file stream (the SHA1 message digest will be all
+ * 0's).
+ *
+ * - However, if you look at the WIM's that Microsoft actually distributes (e.g.
+ * Windows 7/8 boot.wim, install.wim), it's not the same as above. The
+ * dentries in hard link sets will have stream information duplicated. I
+ * can't say anything about the alternate data streams because these WIMs do
+ * not contain alternate data streams.
+ *
+ * - Windows 7 'install.wim' contains hard link sets containing dentries with
+ * inconsistent streams and other inconsistent information such as security
+ * ID. The only way I can think to handle these is to treat the hard link
+ * grouping as erroneous and split up the hard link group.
+ */
+static int share_dentry_ads(struct dentry *owner, struct dentry *user)
+{
+ const char *mismatch_type;
+ bool data_streams_shared = true;
+ wimlib_assert(owner->num_ads == 0 ||
+ owner->ads_entries != user->ads_entries);
+ if (owner->attributes != user->attributes) {
+ mismatch_type = "attributes";
+ goto mismatch;
+ }
+ if (owner->attributes & FILE_ATTRIBUTE_DIRECTORY) {
+ WARNING("`%s' is hard-linked to `%s', which is a directory ",
+ user->full_path_utf8, owner->full_path_utf8);
+ return WIMLIB_ERR_INVALID_DENTRY;
+ }
+ if (owner->security_id != user->security_id) {
+ mismatch_type = "security ID";
+ goto mismatch;
+ }
+ if (!hashes_equal(owner->hash, user->hash)) {
+ if (is_zero_hash(user->hash)) {
+ data_streams_shared = false;
+ copy_hash(user->hash, owner->hash);
+ } else {
+ mismatch_type = "main file resource";
+ goto mismatch;
+ }
+ }
+ if (data_streams_shared) {
+ if (!dentries_have_same_ads(owner, user)) {
+ mismatch_type = "Alternate Stream Entries";
+ goto mismatch;
+ }
+ }
+ if (owner->last_access_time != user->last_access_time
+ || owner->last_write_time != user->last_write_time
+ || owner->creation_time != user->creation_time) {
+ }
+ dentry_free_ads_entries(user);
+ user->ads_entries = owner->ads_entries;
+ user->ads_entries_status = ADS_ENTRIES_USER;
+ return 0;
+mismatch:
+ WARNING("Dentries `%s' and `%s' are supposedly in the same hard-link "
+ "group but do not share the same %s",
+ owner->full_path_utf8, user->full_path_utf8,
+ mismatch_type);
+ return WIMLIB_ERR_INVALID_DENTRY;
+}
+#endif