+ if (ret != 0)
+ break;
+ if (stream_idx == dentry->num_ads)
+ break;
+ stream_name = (ntfschar*)dentry->ads_entries[stream_idx].stream_name;
+ stream_name_len = dentry->ads_entries[stream_idx].stream_name_len / 2;
+ stream_idx++;
+ }
+ return ret;
+}
+
+/*
+ * Makes a NTFS hard link
+ *
+ * It is named @from_dentry->file_name and is located under the directory
+ * specified by @dir_ni, and it is made to point to the previously extracted
+ * file located at @to_dentry->extracted_file.
+ *
+ * Return 0 on success, nonzero on failure.
+ */
+static int wim_apply_hardlink_ntfs(const struct dentry *from_dentry,
+ const struct dentry *to_dentry,
+ ntfs_inode *dir_ni)
+{
+ int ret;
+ ntfs_inode *to_ni;
+
+ DEBUG("Extracting NTFS hard link `%s' => `%s'",
+ from_dentry->full_path_utf8, to_dentry->extracted_file);
+
+ to_ni = ntfs_pathname_to_inode(dir_ni->vol, NULL,
+ to_dentry->extracted_file);
+ if (!to_ni) {
+ ERROR_WITH_ERRNO("Could not find NTFS inode for `%s'",
+ to_dentry->extracted_file);
+ return WIMLIB_ERR_NTFS_3G;
+ }
+ ret = ntfs_link(to_ni, dir_ni,
+ (ntfschar*)from_dentry->file_name,
+ from_dentry->file_name_len / 2);
+ if (ret != 0) {
+ ERROR_WITH_ERRNO("Could not create hard link `%s' => `%s'",
+ from_dentry->full_path_utf8,
+ to_dentry->extracted_file);
+ ret = WIMLIB_ERR_NTFS_3G;
+ }
+ if (ntfs_inode_close(to_ni) != 0) {
+ ERROR_WITH_ERRNO("Failed to close NTFS inode for `%s'",
+ to_dentry->extracted_file);
+ ret = WIMLIB_ERR_NTFS_3G;
+ }
+ return ret;
+}
+
+static int
+apply_file_attributes_and_security_data(ntfs_inode *ni,
+ const struct dentry *dentry,
+ const WIMStruct *w)
+{
+ DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32,
+ dentry->full_path_utf8, dentry->attributes);
+ if (!_ntfs_set_file_attributes(ni, dentry->attributes)) {
+ ERROR("Failed to set NTFS file attributes on `%s'",
+ dentry->full_path_utf8);
+ return WIMLIB_ERR_NTFS_3G;