/* Set attributes, security descriptor, and timestamps on the NTFS inode @ni. */ static int ntfs_3g_set_metadata(ntfs_inode *ni, const struct wim_inode *inode, const struct ntfs_3g_apply_ctx *ctx) { int extract_flags; const struct wim_security_data *sd; struct wim_dentry *one_dentry; int ret; extract_flags = ctx->common.extract_flags; sd = wim_get_current_security_data(ctx->common.wim); one_dentry = inode_first_extraction_dentry(inode); /* Attributes */ if (!(extract_flags & WIMLIB_EXTRACT_FLAG_NO_ATTRIBUTES)) { u32 attrib = inode->i_attributes; attrib &= ~(FILE_ATTRIBUTE_SPARSE_FILE | FILE_ATTRIBUTE_ENCRYPTED); if (ntfs_set_ntfs_attrib(ni, (const char *)&attrib, sizeof(attrib), 0)) { ERROR_WITH_ERRNO("Failed to set attributes on \"%s\" " "in NTFS volume", dentry_full_path(one_dentry)); return WIMLIB_ERR_SET_ATTRIBUTES; } } /* Security descriptor */ if ((inode->i_security_id >= 0) && !(extract_flags & WIMLIB_EXTRACT_FLAG_NO_ACLS)) { const void *desc; size_t desc_size; desc = sd->descriptors[inode->i_security_id]; desc_size = sd->sizes[inode->i_security_id]; ret = ntfs_3g_set_security_descriptor(ni, desc, desc_size); if (ret) { if (wimlib_print_errors) { ERROR_WITH_ERRNO("Failed to set security descriptor " "on \"%s\" in NTFS volume", dentry_full_path(one_dentry)); fprintf(wimlib_error_file, "The security descriptor is: "); print_byte_field(desc, desc_size, wimlib_error_file); fprintf(wimlib_error_file, "\n"); } return ret; } } /* Timestamps */ ret = ntfs_3g_set_timestamps(ni, inode); if (ret) { ERROR_WITH_ERRNO("Failed to set timestamps on \"%s\" " "in NTFS volume", dentry_full_path(one_dentry)); return ret; } return 0; }
int ntfs_xattr_system_setxattr(struct SECURITY_CONTEXT *scx, enum SYSTEMXATTRS attr, ntfs_inode *ni, ntfs_inode *dir_ni, const char *value, size_t size, int flags) { int res; int i; char buf[4*sizeof(u64)]; #if POSIXACLS #if __BYTE_ORDER == __BIG_ENDIAN struct POSIX_ACL *acl; #endif #endif switch (attr) { case XATTR_NTFS_ACL : res = ntfs_set_ntfs_acl(scx, ni, value, size, flags); break; #if POSIXACLS #if __BYTE_ORDER == __BIG_ENDIAN case XATTR_POSIX_ACC : acl = (struct POSIX_ACL*)ntfs_malloc(size); if (acl) { if (!le_acl_to_cpu((const struct LE_POSIX_ACL*)value, size, acl)) { res = ntfs_set_posix_acl(scx ,ni , nf_ns_xattr_posix_access, (char*)acl, size, flags); } else res = -errno; free(acl); } else res = -errno; break; case XATTR_POSIX_DEF : acl = (struct POSIX_ACL*)ntfs_malloc(size); if (acl) { if (!le_acl_to_cpu((const struct LE_POSIX_ACL*)value, size, acl)) { res = ntfs_set_posix_acl(scx ,ni , nf_ns_xattr_posix_default, (char*)acl, size, flags); } else res = -errno; free(acl); } else res = -errno; break; #else case XATTR_POSIX_ACC : res = ntfs_set_posix_acl(scx ,ni , nf_ns_xattr_posix_access, value, size, flags); break; case XATTR_POSIX_DEF : res = ntfs_set_posix_acl(scx, ni, nf_ns_xattr_posix_default, value, size, flags); break; #endif #endif case XATTR_NTFS_ATTRIB : res = ntfs_set_ntfs_attrib(ni, value, size, flags); break; case XATTR_NTFS_ATTRIB_BE : if (value && (size >= 4)) { memcpy(buf,value,4); fix_big_endian(buf,4); res = ntfs_set_ntfs_attrib(ni, buf, 4, flags); } else res = ntfs_set_ntfs_attrib(ni, value, size, flags); break; case XATTR_NTFS_EFSINFO : if (ni->vol->efs_raw) res = ntfs_set_efs_info(ni, value, size, flags); else res = -EPERM; break; case XATTR_NTFS_REPARSE_DATA : res = ntfs_set_ntfs_reparse_data(ni, value, size, flags); break; case XATTR_NTFS_OBJECT_ID : res = ntfs_set_ntfs_object_id(ni, value, size, flags); break; case XATTR_NTFS_DOS_NAME: if (dir_ni) /* warning : this closes both inodes */ res = ntfs_set_ntfs_dos_name(ni, dir_ni, value, size, flags); else res = -errno; break; case XATTR_NTFS_TIMES: res = ntfs_inode_set_times(ni, value, size, flags); break; case XATTR_NTFS_TIMES_BE: if (value && (size > 0) && (size <= 4*sizeof(u64))) { memcpy(buf,value,size); for (i=0; (i+1)*sizeof(u64)<=size; i++) fix_big_endian(&buf[i*sizeof(u64)], sizeof(u64)); res = ntfs_inode_set_times(ni, buf, size, flags); } else res = ntfs_inode_set_times(ni, value, size, flags); break; case XATTR_NTFS_CRTIME: res = ntfs_inode_set_times(ni, value, (size >= sizeof(u64) ? sizeof(u64) : size), flags); break; case XATTR_NTFS_CRTIME_BE: if (value && (size >= sizeof(u64))) { memcpy(buf,value,sizeof(u64)); fix_big_endian(buf,sizeof(u64)); res = ntfs_inode_set_times(ni, buf, sizeof(u64), flags); } else res = ntfs_inode_set_times(ni, value, size, flags); break; case XATTR_NTFS_EA : res = ntfs_set_ntfs_ea(ni, value, size, flags); break; default : errno = ENOTSUP; res = -errno; break; } return (res); }