コード例 #1
0
ファイル: index.c プロジェクト: AllardJ/Tomato
static INDEX_BLOCK *ntfs_ib_alloc(VCN ib_vcn, u32 ib_size, 
				  INDEX_HEADER_FLAGS node_type)
{
	INDEX_BLOCK *ib;
	int ih_size = sizeof(INDEX_HEADER);
	
	ntfs_log_trace("ib_vcn: %lld ib_size: %u\n", (long long)ib_vcn, ib_size);
	
	ib = ntfs_calloc(ib_size);
	if (!ib)
		return NULL;
	
	ib->magic = magic_INDX;
	ib->usa_ofs = cpu_to_le16(sizeof(INDEX_BLOCK));
	ib->usa_count = cpu_to_le16(ib_size / NTFS_BLOCK_SIZE + 1);
	/* Set USN to 1 */
	*(u16 *)((char *)ib + le16_to_cpu(ib->usa_ofs)) = cpu_to_le16(1);
	ib->lsn = cpu_to_le64(0);
	
	ib->index_block_vcn = cpu_to_sle64(ib_vcn);
	
	ib->index.entries_offset = cpu_to_le32((ih_size +
			le16_to_cpu(ib->usa_count) * 2 + 7) & ~7);
	ib->index.index_length = 0;
	ib->index.allocated_size = cpu_to_le32(ib_size - 
					       (sizeof(INDEX_BLOCK) - ih_size));
	ib->index.ih_flags = node_type;
	
	return ib;
}	
コード例 #2
0
ファイル: inode.c プロジェクト: gnils/usbloader-gx
/**
 * __ntfs_inode_allocate - Create and initialise an NTFS inode object
 * @vol:
 *
 * Description...
 *
 * Returns:
 */
static ntfs_inode *__ntfs_inode_allocate(ntfs_volume *vol)
{
	ntfs_inode *ni;

	ni = (ntfs_inode*)ntfs_calloc(sizeof(ntfs_inode));
	if (ni)
		ni->vol = vol;
	return ni;
}
コード例 #3
0
status_t
fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *node = (vnode*)_node->private_node;
	attrdircookie *cookie = NULL;
	ntfs_inode *ni = NULL;
	ntfs_attr_search_ctx *ctx = NULL;

	status_t result = B_NO_ERROR;

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

	LOCK_VOL(ns);

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}

	ctx = ntfs_attr_get_search_ctx(ni, NULL);
	if (ctx == NULL) {
		result = errno;
		goto exit;
	}

	cookie = (attrdircookie*)ntfs_calloc(sizeof(attrdircookie));
	if (cookie == NULL) {
		result = ENOMEM;
		goto exit;
	}

	cookie->inode = ni;
	cookie->ctx = ctx;
	ni = NULL;
	ctx = NULL;
	*_cookie = cookie;
	
exit:

	if (ctx)
		ntfs_attr_put_search_ctx(ctx);
	if (ni)
		ntfs_inode_close(ni);
	
	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));
	
	UNLOCK_VOL(ns);
	
	return result;
}
コード例 #4
0
status_t
fs_opendir(fs_volume *_vol, fs_vnode *_node, void** _cookie)
{
	nspace		*ns = (nspace*)_vol->private_volume;
	vnode		*node = (vnode*)_node->private_node;
	dircookie	*cookie = NULL;
	int			result = B_NO_ERROR;
	ntfs_inode	*ni = NULL;

	LOCK_VOL(ns);

	TRACE("fs_opendir - ENTER\n");

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = ENOENT;
		goto exit;
	}

	if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
		result = EMFILE;
		goto exit;
	}

	cookie = (dircookie*)ntfs_calloc(sizeof(dircookie));
	if (cookie != NULL) {
		cookie->pos = 0;
		cookie->ino = 0;
		cookie->readed = 0;
		cookie->last = 0;
		cookie->name[0] = 0;
		cookie->show_sys_files = ns->show_sys_files;
		*_cookie = (void*)cookie;
	} else
		result = ENOMEM;

exit:
	if (ni)
		ntfs_inode_close(ni);

	TRACE("fs_opendir - EXIT\n");

	UNLOCK_VOL(ns);

	return result;
}
コード例 #5
0
ファイル: index.c プロジェクト: AllardJ/Tomato
/**
 * ntfs_index_add_filename - add filename to directory index
 * @ni:		ntfs inode describing directory to which index add filename
 * @fn:		FILE_NAME attribute to add
 * @mref:	reference of the inode which @fn describes
 *
 * Return 0 on success or -1 on error with errno set to the error code.
 */
int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn, MFT_REF mref)
{
	INDEX_ENTRY *ie;
	ntfs_index_context *icx;
	int fn_size, ie_size, err, ret = -1;

	ntfs_log_trace("Entering\n");
	
	if (!ni || !fn) {
		ntfs_log_error("Invalid arguments.\n");
		errno = EINVAL;
		return -1;
	}
	
	fn_size = (fn->file_name_length * sizeof(ntfschar)) +
			sizeof(FILE_NAME_ATTR);
	ie_size = (sizeof(INDEX_ENTRY_HEADER) + fn_size + 7) & ~7;
	
	ie = ntfs_calloc(ie_size);
	if (!ie)
		return -1;

	ie->indexed_file = cpu_to_le64(mref);
	ie->length 	 = cpu_to_le16(ie_size);
	ie->key_length 	 = cpu_to_le16(fn_size);
	memcpy(&ie->key, fn, fn_size);
	
	icx = ntfs_index_ctx_get(ni, NTFS_INDEX_I30, 4);
	if (!icx)
		goto out;
	
	ret = ntfs_ie_add(icx, ie);
	err = errno;
	ntfs_index_ctx_put(icx);
	errno = err;
out:
	free(ie);
	return ret;
}
コード例 #6
0
ファイル: index.c プロジェクト: AllardJ/Tomato
/**
 * ntfs_index_ctx_get - allocate and initialize a new index context
 * @ni:		ntfs inode with which to initialize the context
 * @name:	name of the which context describes
 * @name_len:	length of the index name
 *
 * Allocate a new index context, initialize it with @ni and return it.
 * Return NULL if allocation failed.
 */
ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *ni,
				       ntfschar *name, u32 name_len)
{
	ntfs_index_context *icx;

	ntfs_log_trace("Entering\n");
	
	if (!ni) {
		errno = EINVAL;
		return NULL;
	}
	if (ni->nr_extents == -1)
		ni = ni->base_ni;
	icx = ntfs_calloc(sizeof(ntfs_index_context));
	if (icx)
		*icx = (ntfs_index_context) {
			.ni = ni,
			.name = name,
			.name_len = name_len,
		};
	return icx;
}
コード例 #7
0
status_t
fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name,
	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;
		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;
			goto exit;
		}

		na = ntfs_attr_open(ni, AT_DATA, uname, ulen);
		if (na) {
			if (openMode & O_TRUNC) {
				if (ntfs_attr_truncate(na, 0))
					result = errno;
			}
		} else {
			result = ENOENT;
			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;
}
コード例 #8
0
ファイル: attrlist.c プロジェクト: JohnTroony/vector-edk
/**
 * ntfs_attrlist_entry_rm - remove an attribute list attribute entry
 * @ctx:	attribute search context describing the attribute list entry
 *
 * Remove the attribute list entry @ctx->al_entry from the attribute list.
 *
 * Return 0 on success and -1 on error with errno set to the error code.
 */
int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
{
	u8 *new_al;
	int new_al_len;
	ntfs_inode *base_ni;
	ntfs_attr *na;
	ATTR_LIST_ENTRY *ale;
	int err;

	if (!ctx || !ctx->ntfs_ino || !ctx->al_entry) {
		ntfs_log_trace("Invalid arguments.\n");
		errno = EINVAL;
		return -1;
	}

	if (ctx->base_ntfs_ino)
		base_ni = ctx->base_ntfs_ino;
	else
		base_ni = ctx->ntfs_ino;
	ale = ctx->al_entry;

	ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, lowest_vcn %lld.\n",
			(long long) ctx->ntfs_ino->mft_no,
			(unsigned) le32_to_cpu(ctx->al_entry->type),
			(long long) le64_to_cpu(ctx->al_entry->lowest_vcn));

	if (!NInoAttrList(base_ni)) {
		ntfs_log_trace("Attribute list isn't present.\n");
		errno = ENOENT;
		return -1;
	}

	/* Allocate memory for new attribute list. */
	new_al_len = base_ni->attr_list_size - le16_to_cpu(ale->length);
	new_al = (u8 *) ntfs_calloc(new_al_len);
	if (!new_al)
		return -1;

	/* Reisze $ATTRIBUTE_LIST to new length. */
	na = ntfs_attr_open(base_ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);
	if (!na) {
		err = errno;
		ntfs_log_trace("Failed to open $ATTRIBUTE_LIST attribute.\n");
		goto err_out;
	}
	if (ntfs_attr_truncate(na, new_al_len)) {
		err = errno;
		ntfs_log_trace("$ATTRIBUTE_LIST resize failed.\n");
		goto err_out;
	}

	/* Copy entries from old attribute list to new. */
	memcpy(new_al, base_ni->attr_list, (u8*)ale - base_ni->attr_list);
	memcpy(new_al + ((u8*)ale - base_ni->attr_list), (u8*)ale + le16_to_cpu(
		ale->length), new_al_len - ((u8*)ale - base_ni->attr_list));

	/* Set new runlist. */
	free(base_ni->attr_list);
	base_ni->attr_list = new_al;
	base_ni->attr_list_size = new_al_len;
	NInoAttrListSetDirty(base_ni);
	/* Done! */
	ntfs_attr_close(na);
	return 0;
err_out:
	if (na)
		ntfs_attr_close(na);
	free(new_al);
	errno = err;
	return -1;
}
コード例 #9
0
ファイル: attrlist.c プロジェクト: JohnTroony/vector-edk
/**
 * ntfs_attrlist_entry_add - add an attribute list attribute entry
 * @ni:		opened ntfs inode, which contains that attribute
 * @attr:	attribute record to add to attribute list
 *
 * Return 0 on success and -1 on error with errno set to the error code. The
 * following error codes are defined:
 *	EINVAL	- Invalid arguments passed to function.
 *	ENOMEM	- Not enough memory to allocate necessary buffers.
 *	EIO	- I/O error occurred or damaged filesystem.
 *	EEXIST	- Such attribute already present in attribute list.
 */
int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
{
	ATTR_LIST_ENTRY *ale;
	MFT_REF mref;
	ntfs_attr *na = NULL;
	ntfs_attr_search_ctx *ctx;
	u8 *new_al;
	int entry_len, entry_offset, err;

	ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
			(long long) ni->mft_no,
			(unsigned) le32_to_cpu(attr->type));

	if (!ni || !attr) {
		ntfs_log_trace("Invalid arguments.\n");
		errno = EINVAL;
		return -1;
	}

	mref = MK_LE_MREF(ni->mft_no, le16_to_cpu(ni->mrec->sequence_number));

	if (ni->nr_extents == -1)
		ni = ni->base_ni;

	if (!NInoAttrList(ni)) {
		ntfs_log_trace("Attribute list isn't present.\n");
		errno = ENOENT;
		return -1;
	}

	/* Determine size and allocate memory for new attribute list. */
	entry_len = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) *
			attr->name_length + 7) & ~7;
	new_al = (u8 *) ntfs_calloc(ni->attr_list_size + entry_len);
	if (!new_al)
		return -1;

	/* Find place for the new entry. */
	ctx = ntfs_attr_get_search_ctx(ni, NULL);
	if (!ctx) {
		err = errno;
		goto err_out;
	}
	if (!ntfs_attr_lookup(attr->type, (attr->name_length) ? (ntfschar*)
			((u8*)attr + le16_to_cpu(attr->name_offset)) :
			AT_UNNAMED, attr->name_length, CASE_SENSITIVE,
			(attr->non_resident) ? le64_to_cpu(attr->lowest_vcn) :
			0, (attr->non_resident) ? NULL : ((u8*)attr +
			le16_to_cpu(attr->value_offset)), (attr->non_resident) ?
			0 : le32_to_cpu(attr->value_length), ctx)) {
		/* Found some extent, check it to be before new extent. */
		if (ctx->al_entry->lowest_vcn == attr->lowest_vcn) {
			err = EEXIST;
			ntfs_log_trace("Such attribute already present in the "
					"attribute list.\n");
			ntfs_attr_put_search_ctx(ctx);
			goto err_out;
		}
		/* Add new entry after this extent. */
		ale = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry +
				le16_to_cpu(ctx->al_entry->length));
	} else {
		/* Check for real errors. */
		if (errno != ENOENT) {
			err = errno;
			ntfs_log_trace("Attribute lookup failed.\n");
			ntfs_attr_put_search_ctx(ctx);
			goto err_out;
		}
		/* No previous extents found. */
		ale = ctx->al_entry;
	}
	/* Don't need it anymore, @ctx->al_entry points to @ni->attr_list. */
	ntfs_attr_put_search_ctx(ctx);

	/* Determine new entry offset. */
	entry_offset = ((u8 *)ale - ni->attr_list);
	/* Set pointer to new entry. */
	ale = (ATTR_LIST_ENTRY *)(new_al + entry_offset);
	/* Zero it to fix valgrind warning. */
	memset(ale, 0, entry_len);
	/* Form new entry. */
	ale->type = attr->type;
	ale->length = cpu_to_le16(entry_len);
	ale->name_length = attr->name_length;
	ale->name_offset = offsetof(ATTR_LIST_ENTRY, name);
	if (attr->non_resident)
		ale->lowest_vcn = attr->lowest_vcn;
	else
		ale->lowest_vcn = 0;
	ale->mft_reference = mref;
	ale->instance = attr->instance;
	memcpy(ale->name, (u8 *)attr + le16_to_cpu(attr->name_offset),
			attr->name_length * sizeof(ntfschar));

	/* Resize $ATTRIBUTE_LIST to new length. */
	na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);
	if (!na) {
		err = errno;
		ntfs_log_trace("Failed to open $ATTRIBUTE_LIST attribute.\n");
		goto err_out;
	}
	if (ntfs_attr_truncate(na, ni->attr_list_size + entry_len)) {
		err = errno;
		ntfs_log_trace("$ATTRIBUTE_LIST resize failed.\n");
		goto err_out;
	}

	/* Copy entries from old attribute list to new. */
	memcpy(new_al, ni->attr_list, entry_offset);
	memcpy(new_al + entry_offset + entry_len, ni->attr_list +
			entry_offset, ni->attr_list_size - entry_offset);

	/* Set new runlist. */
	free(ni->attr_list);
	ni->attr_list = new_al;
	ni->attr_list_size = ni->attr_list_size + entry_len;
	NInoAttrListSetDirty(ni);
	/* Done! */
	ntfs_attr_close(na);
	return 0;
err_out:
	if (na)
		ntfs_attr_close(na);
	free(new_al);
	errno = err;
	return -1;
}
コード例 #10
0
ファイル: attributes.c プロジェクト: DonCN/haiku
status_t
fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name)
{
	nspace *ns = (nspace *)_vol->private_volume;
	vnode *node = (vnode *)_node->private_node;
	char ntfs_attr_name[MAX_PATH]={0};
	ntfschar *uname = NULL;
	int ulen;
	ntfs_inode *ni = NULL;		
	status_t result = B_NO_ERROR;

	TRACE("%s - ENTER - name: [%s]\n", __FUNCTION__, name);
	
	if (ns->flags & B_FS_IS_READONLY) {
		ERROR("ntfs is read-only\n");
		return B_READ_ONLY_DEVICE;
	}

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

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}		
	
	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;
		goto exit;
	}	
	
	if (ntfs_attr_remove(ni, AT_DATA, uname, ulen)) {
		result = ENOENT;
		goto exit;
	}

	if (!(ni->flags & FILE_ATTR_ARCHIVE)) {
		ni->flags |= FILE_ATTR_ARCHIVE;
		NInoFileNameSetDirty(ni);
	}
	notify_attribute_changed(ns->id, MREF(ni->mft_no), name, B_ATTR_REMOVED);
exit:	
	if (uname != NULL)
		free(uname);

	if (ni != NULL)
		ntfs_inode_close(ni);
		
	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));

	UNLOCK_VOL(ns);
	
	return result;
}
コード例 #11
0
ファイル: attributes.c プロジェクト: DonCN/haiku
status_t
fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name,
	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;
	uint32	type = B_XATTR_TYPE;

	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;
		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;
			goto exit;
		}

		na = ntfs_attr_open(ni, AT_DATA, uname, ulen);
		if (na != NULL) {
			if (openMode & O_TRUNC) {
				if (ns->flags & B_FS_IS_READONLY) {		
					result = B_READ_ONLY_DEVICE;
					goto exit;
				} else {
					if (ntfs_attr_truncate(na, sizeof(uint32))) {
						result = errno;
						goto exit;
					}
				}
			}
			if (ntfs_attr_pread(na, 0, sizeof(uint32), &type) != sizeof(uint32)) {
				result = errno;
				goto exit;
			}
		} else {
			result = ENOENT;
			goto exit;
		}
	}


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

	if (cookie != NULL) {
		cookie->omode = openMode;
		cookie->vnid = node->vnid;
		cookie->uname = uname;
		cookie->uname_len = ulen;
		cookie->type = type;
		*_cookie = (void*)cookie;
		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;
}
コード例 #12
0
ファイル: fs_func.c プロジェクト: mmanley/Antares
status_t
fs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
	uint32 *_flags, bool reenter)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *newNode = NULL;
	ntfs_inode *ni = NULL;
	status_t result = B_NO_ERROR;

	if (!reenter)
		LOCK_VOL(ns);

	ERRPRINT("fs_read_vnode - ENTER\n");

	_node->private_node = NULL;
	_node->ops = &gNTFSVnodeOps;
	_flags = 0;

	newNode = (vnode*)ntfs_calloc(sizeof(vnode));
	if (newNode != NULL) {
		char *name = NULL;

		ni = ntfs_inode_open(ns->ntvol, vnid);
		if (ni == NULL) {
			result = ENOENT;
			goto exit;
		}

		// get the node type
		result = get_node_type(ni, _type);
		if (result != B_OK)
			goto exit;

		newNode->vnid = vnid;
		newNode->parent_vnid = ntfs_get_parent_ref(ni);

		if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
			set_mime(newNode, ".***");
		else {
			name = (char*)malloc(MAX_PATH);
			if (name != NULL) {
				if (utils_inode_get_name(ni, name,MAX_PATH) == 1)
					set_mime(newNode, name);
				free(name);
			}
		}

		_node->private_node = newNode;
	} else
		result = ENOMEM;

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

	if (result != B_OK && newNode != NULL)
		free(newNode);

	ERRPRINT("fs_read_vnode - EXIT, result is %s\n", strerror(result));

	if (!reenter)
		UNLOCK_VOL(ns);

	return result;
}
コード例 #13
0
ファイル: fs_func.c プロジェクト: mmanley/Antares
status_t
fs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *vnid)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *baseNode = (vnode*)_dir->private_node;
	vnode *newNode = NULL;
	ntfschar *unicode = NULL;
	ntfs_inode *bi = NULL;
	status_t result = B_NO_ERROR;
	int len;

	LOCK_VOL(ns);

	ERRPRINT("fs_walk - ENTER : find for \"%s\"\n",file);

	if (ns == NULL || _dir == NULL || file == NULL || vnid == NULL) {
		result = EINVAL;
		goto exit;
	}

	if (!strcmp(file, ".")) {
		*vnid = baseNode->vnid;
		if (get_vnode(_vol, *vnid, (void**)&newNode) != 0)
			result = ENOENT;
	} else if (!strcmp(file, "..") && baseNode->vnid != FILE_root) {
		*vnid = baseNode->parent_vnid;
		if (get_vnode(_vol, *vnid, (void**)&newNode) != 0)
			result = ENOENT;
	} else {
		unicode = ntfs_calloc(MAX_PATH);
		len = ntfs_mbstoucs(file, &unicode);
		if (len < 0) {
			result = EILSEQ;
			goto exit;
		}

		bi = ntfs_inode_open(ns->ntvol, baseNode->vnid);
		if (!bi) {
			result = ENOENT;
			goto exit;
		}

		*vnid = MREF(ntfs_inode_lookup_by_name(bi, unicode, len));
		ERRPRINT("fs_walk - VNID = %d\n",*vnid);

		ntfs_inode_close(bi);
		free(unicode);

		if (*vnid == (u64)-1) {
			result = EINVAL;
			goto exit;
		}

		if (get_vnode(_vol, *vnid, (void**)&newNode) != 0)
			result = ENOENT;

		if (newNode!=NULL)
			newNode->parent_vnid = baseNode->vnid;
	}

exit:
	ERRPRINT("fs_walk - EXIT, result is %s\n", strerror(result));

	UNLOCK_VOL(ns);

	return result;
}
コード例 #14
0
ファイル: fs_func.c プロジェクト: mmanley/Antares
status_t
fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args,
	ino_t *_rootID)
{
	nspace *ns;
	vnode *newNode = NULL;
	char lockname[32];
	void *handle;
	unsigned long mountFlags = 0;
	status_t result = B_NO_ERROR;

	ERRPRINT("fs_mount - ENTER\n");

	ns = ntfs_malloc(sizeof(nspace));
	if (!ns) {
		result = ENOMEM;
		goto exit;
	}

	*ns = (nspace) {
		.state = NF_FreeClustersOutdate | NF_FreeMFTOutdate,
		.show_sys_files = false,
		.ro = false,
		.flags = 0
	};

	strcpy(ns->devicePath,device);

	sprintf(lockname, "ntfs_lock %lx", ns->id);
	recursive_lock_init_etc(&(ns->vlock), lockname, MUTEX_FLAG_CLONE_NAME);

	handle = load_driver_settings("ntfs");
	ns->show_sys_files = ! (strcasecmp(get_driver_parameter(handle,
		"hide_sys_files", "true", "true"), "true") == 0);
	ns->ro = strcasecmp(get_driver_parameter(handle, "read_only", "false",
		"false"), "false") != 0;
	ns->noatime = strcasecmp(get_driver_parameter(handle, "no_atime", "true",
		"true"), "true") == 0;
	unload_driver_settings(handle);

	if (ns->ro || (flags & B_MOUNT_READ_ONLY) != 0) {
		mountFlags |= MS_RDONLY;
		ns->flags |= B_FS_IS_READONLY;
	}

	// TODO: this does not take read-only volumes into account!
	ns->ntvol = utils_mount_volume(device, mountFlags, true);
	if (ns->ntvol != NULL)
		result = B_NO_ERROR;
	else
		result = errno;

	if (result == B_NO_ERROR) {
		*_rootID = FILE_root;
		ns->id = _vol->id;
		_vol->private_volume = (void *)ns;
		_vol->ops = &gNTFSVolumeOps;

		newNode = (vnode*)ntfs_calloc(sizeof(vnode));
		if (newNode == NULL)
			result = ENOMEM;
		else {
			newNode->vnid = *_rootID;
			newNode->parent_vnid = -1;

			result = publish_vnode(_vol, *_rootID, (void*)newNode,
				&gNTFSVnodeOps, S_IFDIR, 0);
			if (result != B_NO_ERROR) {
				free(ns);
				result = EINVAL;
				goto exit;
			} else {
				result = B_NO_ERROR;
				ntfs_mark_free_space_outdated(ns);
				ntfs_calc_free_space(ns);
			}
		}
	}

exit:
	ERRPRINT("fs_mount - EXIT, result code is %s\n", strerror(result));

	return result;
}


status_t
fs_unmount(fs_volume *_vol)
{
	nspace *ns = (nspace*)_vol->private_volume;
	status_t result = B_NO_ERROR;

	ERRPRINT("fs_unmount - ENTER\n");

	ntfs_umount(ns->ntvol, true);

	recursive_lock_destroy(&(ns->vlock));

	free(ns);

	ERRPRINT("fs_unmount - EXIT, result is %s\n", strerror(result));

	return result;
}
コード例 #15
0
ファイル: security.c プロジェクト: geocar/winback
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;
}