Esempio n. 1
0
/* Create empty named data streams.
 *
 * Since these won't have 'struct wim_lookup_table_entry's, they won't show up
 * in the call to extract_stream_list().  Hence the need for the special case.
 */
static int
ntfs_3g_create_any_empty_ads(ntfs_inode *ni, const struct wim_inode *inode,
			     const struct ntfs_3g_apply_ctx *ctx)
{
	for (u16 i = 0; i < inode->i_num_ads; i++) {
		const struct wim_ads_entry *entry;

		entry = &inode->i_ads_entries[i];

		/* Not named?  */
		if (!entry->stream_name_nbytes)
			continue;

		/* Not empty?  */
		if (entry->lte)
			continue;

		if (ntfs_attr_add(ni, AT_DATA, entry->stream_name,
				  entry->stream_name_nbytes /
					sizeof(utf16lechar),
				  NULL, 0))
		{
			ERROR_WITH_ERRNO("Failed to create named data stream "
					 "of \"%s\"", dentry_full_path(
						inode_first_extraction_dentry(inode)));
			return WIMLIB_ERR_NTFS_3G;
		}
	}
	return 0;
}
Esempio n. 2
0
static int add_object_id(ntfs_inode *ni, int flags)
{
	int res;
	u8 dummy;

	res = -1; /* default return */
	if (!ntfs_attr_exist(ni,AT_OBJECT_ID, AT_UNNAMED,0)) {
		if (!(flags & XATTR_REPLACE)) {
			/*
			 * no object id attribute : add one,
			 * apparently, this does not feed the new value in
			 * Note : NTFS version must be >= 3
			 */
			if (ni->vol->major_ver >= 3) {
				res = ntfs_attr_add(ni, AT_OBJECT_ID,
						AT_UNNAMED, 0, &dummy, (s64)0);
				NInoSetDirty(ni);
			} else
				errno = ENOTSUP;
		} else
			errno = ENODATA;
	} else {
		if (flags & XATTR_CREATE)
			errno = EEXIST;
		else
			res = 0;
	}
	return (res);
}
Esempio n. 3
0
static int ntfs_ibm_add(ntfs_index_context *icx)
{
	u8 bmp[8];

	ntfs_log_trace("Entering\n");
	
	if (ntfs_attr_exist(icx->ni, AT_BITMAP, icx->name, icx->name_len))
		return STATUS_OK;
	/*
	 * AT_BITMAP must be at least 8 bytes.
	 */
	memset(bmp, 0, sizeof(bmp));
	if (ntfs_attr_add(icx->ni, AT_BITMAP, icx->name, icx->name_len,
			  bmp, sizeof(bmp))) {
		ntfs_log_perror("Failed to add AT_BITMAP");
		return STATUS_ERROR;
	}
	
	return STATUS_OK;
}
Esempio n. 4
0
static int ntfs_ia_add(ntfs_index_context *icx)
{
	ntfs_log_trace("Entering\n");

	if (ntfs_ibm_add(icx))
		return -1;
	
	if (!ntfs_attr_exist(icx->ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len)) {
	
		if (ntfs_attr_add(icx->ni, AT_INDEX_ALLOCATION, icx->name,
				  icx->name_len, NULL, 0)) {
			ntfs_log_perror("Failed to add AT_INDEX_ALLOCATION");
			return -1;
		}
	}
	
	icx->ia_na = ntfs_ia_open(icx, icx->ni);
	if (!icx->ia_na)
		return -1;

	return 0;
}
Esempio n. 5
0
status_t
fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name,
	uint32 type, int openMode, void** _cookie)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *node = (vnode*)_node->private_node;
	attrcookie *cookie = NULL;
	ntfschar *uname = NULL;
	int ulen;
	ntfs_inode *ni = NULL;
	ntfs_attr *na = NULL;
	status_t result = B_NO_ERROR;

	TRACE("%s - ENTER\n", __FUNCTION__);

	LOCK_VOL(ns);

	if (node == NULL) {
		result = EINVAL;
		goto exit;
	}

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		ERROR("%s - inode_open: %s\n", __FUNCTION__, strerror(result));
		goto exit;
	}

	// UXA demangling TODO

	// check for EA first... TODO: WRITEME


	// check for a named stream
	if (true) {
		uname = ntfs_calloc(MAX_PATH);
		ulen = ntfs_mbstoucs(name, &uname);
		if (ulen < 0) {
			result = EILSEQ;
			ERROR("%s - mb alloc: %s\n", __FUNCTION__, strerror(result));
			goto exit;
		}

		na = ntfs_attr_open(ni, AT_DATA, uname, ulen);
		if (na) {
			result = EEXIST;
			ERROR("%s - ntfs_attr_open: %s\n", __FUNCTION__,
				strerror(result));
			goto exit;
		}
		//if (ntfs_non_resident_attr_record_add(ni, AT_DATA, uname, ulen, 0, 32,
		//	0) < 0) {
		if (ntfs_attr_add(ni, AT_DATA, uname, ulen, NULL, 0) < 0) {
			result = errno;
			//ERROR("%s - ntfs_non_resident_attr_record_add: %s\n",
			ERROR("%s - ntfs_attr_add: %s\n",				__FUNCTION__, strerror(result));
			goto exit;
		}
		na = ntfs_attr_open(ni, AT_DATA, uname, ulen);
		if (!na) {
			result = errno;
			ERROR("%s - ntfs_attr_open: %s\n", __FUNCTION__,
				strerror(result));
			goto exit;
		}
	}


	cookie = (attrcookie*)ntfs_calloc(sizeof(attrcookie));

	if (cookie != NULL) {
		cookie->omode = openMode;
		*_cookie = (void*)cookie;
		cookie->inode = ni;
		cookie->stream = na;
		ni = NULL;
		na = NULL;
	} else
		result = ENOMEM;

exit:
	if (uname)
		free(uname);

	if (na)
		ntfs_attr_close(na);

	if (ni)
		ntfs_inode_close(ni);

	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));

	UNLOCK_VOL(ns);

	return result;
}
Esempio n. 6
0
bool ntfsSetVolumeName (const char *name, const char *volumeName)
{
    ntfs_vd *vd = NULL;
    ntfs_attr *na = NULL;
    ntfschar *ulabel = NULL;
    int ulabel_len;

    // Sanity check
    if (!name) {
        errno = EINVAL;
        return false;
    }

    // Get the devices volume descriptor
    vd = ntfsGetVolume(name);
    if (!vd) {
        errno = ENODEV;
        return false;
    }

    // Lock
    ntfsLock(vd);

    // Convert the new volume name to unicode
    ulabel_len = ntfsLocalToUnicode(volumeName, &ulabel) * sizeof(ntfschar);
    if (ulabel_len < 0) {
        ntfsUnlock(vd);
        errno = EINVAL;
        return false;
    }

    // Check if the volume name attribute exists
    na = ntfs_attr_open(vd->vol->vol_ni, AT_VOLUME_NAME, NULL, 0);
    if (na) {

        // It does, resize it to match the length of the new volume name
        if (ntfs_attr_truncate(na, ulabel_len)) {
            ntfs_free(ulabel);
            ntfsUnlock(vd);
            return false;
        }

        // Write the new volume name
        if (ntfs_attr_pwrite(na, 0, ulabel_len, ulabel) != ulabel_len) {
            ntfs_free(ulabel);
            ntfsUnlock(vd);
            return false;
        }

    } else {

        // It doesn't, create it now
        if (ntfs_attr_add(vd->vol->vol_ni, AT_VOLUME_NAME, NULL, 0, (u8*)ulabel, ulabel_len)) {
            ntfs_free(ulabel);
            ntfsUnlock(vd);
            return false;
        }

    }

    // Reset the volumes name cache (as it has now been changed)
    vd->name[0] = '\0';

    // Close the volume name attribute
    if (na)
        ntfs_attr_close(na);

    // Sync the volume node
    if (ntfs_inode_sync(vd->vol->vol_ni)) {
        ntfs_free(ulabel);
        ntfsUnlock(vd);
        return false;
    }

    // Clean up
    ntfs_free(ulabel);

    // Unlock
    ntfsUnlock(vd);

    return true;
}
Esempio n. 7
0
status_t
fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name,
	uint32 type, int openMode, void** _cookie)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *node = (vnode*)_node->private_node;
	attrcookie *cookie = NULL;
	ntfschar *uname = NULL;
	int ulen;
	ntfs_inode *ni = NULL;
	ntfs_attr *na = NULL;
	status_t result = B_NO_ERROR;	

	if (ns->flags & B_FS_IS_READONLY) {		
		return B_READ_ONLY_DEVICE;
	}

	TRACE("%s - ENTER - name: [%s] vnid: %d\n", __FUNCTION__, name, node->vnid);

	LOCK_VOL(ns);

	if (node == NULL) {
		result = EINVAL;
		goto exit;
	}

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		TRACE("%s - inode_open: %s\n", __FUNCTION__, strerror(result));
		goto exit;
	}

	// UXA demangling TODO

	// check for EA first... TODO: WRITEME


	// check for a named stream
	if (true) {
		char ntfs_attr_name[MAX_PATH] = {0};
		strcat(ntfs_attr_name, kHaikuAttrPrefix);
		strcat(ntfs_attr_name,name);
		
		uname = ntfs_calloc(MAX_PATH);
		ulen = ntfs_mbstoucs(ntfs_attr_name, &uname);
		if (ulen < 0) {
			result = EILSEQ;
			TRACE("%s - mb alloc: %s\n", __FUNCTION__, strerror(result));
			goto exit;
		}

		na = ntfs_attr_open(ni, AT_DATA, uname, ulen);
		if (na != NULL) {
			if (ntfs_attr_truncate(na, 0)) {				
				result = errno;
				goto exit;
			}
		} else {
			if (ntfs_attr_add(ni, AT_DATA, uname, ulen, NULL, 0) < 0) {
				result = errno;
				TRACE("%s - ntfs_attr_add: %s\n", __FUNCTION__,
					strerror(result));
				goto exit;
			}
			na = ntfs_attr_open(ni, AT_DATA, uname, ulen);
			if (na == NULL) {
				result = errno;
				TRACE("%s - ntfs_attr_open: %s\n", __FUNCTION__,
					strerror(result));
				goto exit;
			}			
		}
		if(ntfs_attr_pwrite(na, 0, sizeof(uint32), &type) < 0 ) {
			result = errno;
			goto exit;
		}
	}

	cookie = (attrcookie*)ntfs_calloc(sizeof(attrcookie));

	if (cookie != NULL) {
		cookie->omode = openMode;
		*_cookie = (void*)cookie;
		cookie->vnid = node->vnid;
		cookie->uname = uname;
		cookie->uname_len = ulen;
		cookie->type = type;
		uname = NULL;
	} else
		result = ENOMEM;

exit:
	if (uname != NULL)
		free(uname);

	if (na != NULL)
		ntfs_attr_close(na);

	if (ni != NULL)
		ntfs_inode_close(ni);

	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));

	UNLOCK_VOL(ns);

	return result;
}
Esempio n. 8
0
int ntfs_sd_add_everyone(ntfs_inode *ni)
{
	SECURITY_DESCRIPTOR_ATTR *sd;
	ACL *acl;
	ACCESS_ALLOWED_ACE *ace;
	SID *sid;
	int ret, sd_len;
	
	/* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */
	/*
	 * Calculate security descriptor length. We have 2 sub-authorities in
	 * owner and group SIDs, but structure SID contain only one, so add
	 * 4 bytes to every SID.
	 */
	sd_len = sizeof(SECURITY_DESCRIPTOR_ATTR) + 2 * (sizeof(SID) + 4) +
		sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); 
	sd = ntfs_calloc(sd_len);
	if (!sd)
		return -1;
	
	sd->revision = 1;
	sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
	
	sid = (SID *)((u8 *)sd + sizeof(SECURITY_DESCRIPTOR_ATTR));
	sid->revision = 1;
	sid->sub_authority_count = 2;
	sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
	sid->identifier_authority.value[5] = 5;
	sd->owner = cpu_to_le32((u8 *)sid - (u8 *)sd);
	
	sid = (SID *)((u8 *)sid + sizeof(SID) + 4); 
	sid->revision = 1;
	sid->sub_authority_count = 2;
	sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
	sid->identifier_authority.value[5] = 5;
	sd->group = cpu_to_le32((u8 *)sid - (u8 *)sd);
	
	acl = (ACL *)((u8 *)sid + sizeof(SID) + 4);
	acl->revision = 2;
	acl->size = cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE));
	acl->ace_count = cpu_to_le16(1);
	sd->dacl = cpu_to_le32((u8 *)acl - (u8 *)sd);
	
	ace = (ACCESS_ALLOWED_ACE *)((u8 *)acl + sizeof(ACL));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
	ace->size = cpu_to_le16(sizeof(ACCESS_ALLOWED_ACE));
	ace->mask = cpu_to_le32(0x1f01ff); /* FIXME */
	ace->sid.revision = 1;
	ace->sid.sub_authority_count = 1;
	ace->sid.sub_authority[0] = 0;
	ace->sid.identifier_authority.value[5] = 1;
	
	ret = ntfs_attr_add(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0, (u8 *)sd,
			    sd_len);
	if (ret)
		ntfs_log_perror("Failed to add SECURITY_DESCRIPTOR\n");
	
	free(sd);
	return ret;
}
Esempio n. 9
0
int ntfs_set_ntfs_reparse_data(ntfs_inode *ni,
			const char *value, size_t size, int flags)
{
	int res;
	u8 dummy;
	ntfs_inode *xrni;
	ntfs_index_context *xr;

	res = 0;
	if (ni && valid_reparse_data(ni, (const REPARSE_POINT*)value, size)) {
		xr = open_reparse_index(ni->vol);
		if (xr) {
			if (!ntfs_attr_exist(ni,AT_REPARSE_POINT,
						AT_UNNAMED,0)) {
				if (!(flags & XATTR_REPLACE)) {
			/*
			 * no reparse data attribute : add one,
			 * apparently, this does not feed the new value in
			 * Note : NTFS version must be >= 3
			 */
					if (ni->vol->major_ver >= 3) {
						res = ntfs_attr_add(ni,
							AT_REPARSE_POINT,
							AT_UNNAMED,0,&dummy,
							(s64)0);
						if (!res) {
						    ni->flags |=
							FILE_ATTR_REPARSE_POINT;
						    NInoFileNameSetDirty(ni);
						}
						NInoSetDirty(ni);
					} else {
						errno = EOPNOTSUPP;
						res = -1;
					}
				} else {
					errno = ENODATA;
					res = -1;
				}
			} else {
				if (flags & XATTR_CREATE) {
					errno = EEXIST;
					res = -1;
				}
			}
			if (!res) {
					/* update value and index */
				res = update_reparse_data(ni,xr,value,size);
			}
			xrni = xr->ni;
			ntfs_index_entry_mark_dirty(xr);
			NInoSetDirty(xrni);
			ntfs_index_ctx_put(xr);
			ntfs_inode_close(xrni);
		} else {
			res = -1;
		}
	} else {
		errno = EINVAL;
		res = -1;
	}
	return (res ? -1 : 0);
}