⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 attrlist.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
字号:
/** * attrlist.c - Attribute list attribute handling code.  Part of the Linux-NTFS *		project. * * Copyright (c) 2004-2005 Anton Altaparmakov * Copyright (c) 2004-2005 Yura Pakhuchiy * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program/include file is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (in the main directory of the Linux-NTFS * distribution in the file COPYING); if not, write to the Free Software * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#include "types.h"#include "layout.h"#include "attrib.h"#include "attrlist.h"#include "debug.h"#include "unistr.h"#include "logging.h"/** * ntfs_attrlist_need - check whether inode need attribute list * @ni:		opened ntfs inode for which perform check * * Check whether all are attributes belong to one MFT record, in that case * attribute list is not needed. * * Return 1 if inode need attribute list, 0 if not, -1 on error with errno set * to the error code. If function succeed errno set to 0. The following error * codes are defined: *	EINVAL	- Invalid arguments passed to function or attribute haven't got *		  attribute list. */int ntfs_attrlist_need(ntfs_inode *ni){	ATTR_LIST_ENTRY *ale;	if (!ni) {		ntfs_log_trace("Invalid arguments.\n");		errno = EINVAL;		return -1;	}	ntfs_log_trace("Entering for inode 0x%llx.\n", (long long) ni->mft_no);	if (!NInoAttrList(ni)) {		ntfs_log_trace("Inode haven't got attribute list.\n");		errno = EINVAL;		return -1;	}	if (!ni->attr_list) {		ntfs_log_trace("Corrupt in-memory struct.\n");		errno = EINVAL;		return -1;	}	errno = 0;	ale = (ATTR_LIST_ENTRY *)ni->attr_list;	while ((u8*)ale < ni->attr_list + ni->attr_list_size) {		if (MREF_LE(ale->mft_reference) != ni->mft_no)			return 1;		ale = (ATTR_LIST_ENTRY *)((u8*)ale + le16_to_cpu(ale->length));	}	return 0;}/** * 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 = malloc(ni->attr_list_size + entry_len);	if (!new_al) {		ntfs_log_trace("Not enough memory.\n");		err = ENOMEM;		return -1;	}	/* Find place for the new entry. */	ctx = ntfs_attr_get_search_ctx(ni, NULL);	if (!ctx) {		err = errno;		ntfs_log_trace("Failed to obtain attribute search context.\n");		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;}/** * 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 = malloc(new_al_len);	if (!new_al) {		ntfs_log_trace("Not enough memory.\n");		errno = ENOMEM;		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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -