- ni = ntfs_3g_apply_pathname_to_inode(path, ctx);
- if (!ni)
- return WIMLIB_ERR_OPEN;
- if (ntfs_set_ntfs_attrib(ni, (const char*)&attributes, sizeof(u32), 0))
- ret = WIMLIB_ERR_SET_ATTRIBUTES;
- if (ntfs_inode_close(ni))
- ret = WIMLIB_ERR_WRITE;
+ first_dentry = ntfs_3g_first_extraction_alias(inode);
+
+ /* Create first link. */
+
+ dir_ni = ntfs_inode_open(ctx->vol, first_dentry->d_parent->d_inode->i_mft_no);
+ if (!dir_ni) {
+ ERROR_WITH_ERRNO("Can't open \"%s\" in NTFS volume",
+ dentry_full_path(first_dentry->d_parent));
+ return WIMLIB_ERR_NTFS_3G;
+ }
+
+ ni = ntfs_create(dir_ni, 0, first_dentry->d_extraction_name,
+ first_dentry->d_extraction_name_nchars, S_IFREG);
+
+ if (!ni) {
+ ERROR_WITH_ERRNO("Can't create \"%s\" in NTFS volume",
+ dentry_full_path(first_dentry));
+ ntfs_inode_close(dir_ni);
+ return WIMLIB_ERR_NTFS_3G;
+ }
+
+ inode->i_mft_no = ni->mft_no;
+
+ /* Set short name if present. */
+ if (dentry_has_short_name(first_dentry)) {
+
+ ret = ntfs_3g_restore_dos_name(ni, dir_ni, first_dentry, ctx->vol);
+
+ /* ntfs_3g_restore_dos_name() closed both 'ni' and 'dir_ni'. */
+
+ if (ret)
+ return ret;
+
+ /* Reopen the inode. */
+ ni = ntfs_inode_open(ctx->vol, inode->i_mft_no);
+ if (!ni) {
+ ERROR_WITH_ERRNO("Failed to reopen \"%s\" "
+ "in NTFS volume",
+ dentry_full_path(first_dentry));
+ return WIMLIB_ERR_NTFS_3G;
+ }
+ } else {
+ /* Close the directory in which the first link was created. */
+ if (ntfs_inode_close(dir_ni)) {
+ ERROR_WITH_ERRNO("Failed to close \"%s\" in NTFS volume",
+ dentry_full_path(first_dentry->d_parent));
+ ret = WIMLIB_ERR_NTFS_3G;
+ goto out_close_ni;
+ }
+ }
+
+ /* Create additional links if present. */
+ inode_for_each_extraction_alias(dentry, inode) {
+ if (dentry != first_dentry) {
+ ret = ntfs_3g_add_link(ni, dentry);
+ if (ret)
+ goto out_close_ni;
+ }
+ }
+
+ /* Set metadata. */
+ ret = ntfs_3g_set_metadata(ni, inode, ctx);
+ if (ret)
+ goto out_close_ni;
+
+ ret = ntfs_3g_create_empty_attributes(ni, inode, ctx);
+
+out_close_ni:
+ /* Close the inode. */
+ if (ntfs_inode_close(ni) && !ret) {
+ ERROR_WITH_ERRNO("Error closing \"%s\" in NTFS volume",
+ dentry_full_path(first_dentry));
+ ret = WIMLIB_ERR_NTFS_3G;
+ }