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

📄 attr.c

📁 EM85XX读NTFS修正代码包
💻 C
📖 第 1 页 / 共 2 页
字号:
					rl[i].len - rounded);			if (error)				return error; /* FIXME: Incomplete operation. */			rl[i].len = rounded;			newcount = count + rounded;		}		/* Free all other runs. */		i++;		error = ntfs_deallocate_clusters(ino->vol, rl + i,				attr->d.r.len - i);		if (error)			return error; /* FIXME: Incomplete operation. */		/*		 * Free space for extra runs in memory if enough memory left		 * to do so. FIXME: Only do it if it would free memory. (AIA)		 */		rl_size = ((i + 1) * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &				PAGE_MASK;		if (rl_size < ((attr->d.r.len * sizeof(ntfs_runlist) +				PAGE_SIZE - 1) & PAGE_MASK)) {			rlt = ntfs_vmalloc(rl_size);			if (rlt) {				ntfs_memcpy(rlt, rl, i * sizeof(ntfs_runlist));				ntfs_vfree(rl);				attr->d.r.runlist = rl = rlt;			}		}		rl[i].lcn = (ntfs_cluster_t)-1;		rl[i].len = (ntfs_cluster_t)0;		attr->d.r.len = i;	} else {		error = ntfs_extend_attr(ino, attr, newsize);		if (error)			return error; /* FIXME: Incomplete operation. */		newcount = (newsize + ino->vol->cluster_size - 1) >>				clustersizebits;	}	/* Fill in new sizes. */	attr->allocated = (__s64)newcount << clustersizebits;	attr->size = newsize;	if (attr->initialized > newsize)		attr->initialized = newsize;	if (!newsize)		error = ntfs_make_attr_resident(ino, attr);	return error;}int ntfs_create_attr(ntfs_inode *ino, int anum, char *aname, void *data,		int dsize, ntfs_attribute **rattr){	void *name;	int namelen;	int found, i;	int error;	ntfs_attribute *attr;		if (dsize > ino->vol->mft_record_size)		/* FIXME: Non-resident attributes. */		return -EOPNOTSUPP;	if (aname) {		namelen = strlen(aname);		name = ntfs_malloc(2 * namelen);		if (!name)			return -ENOMEM;		ntfs_ascii2uni(name, aname, namelen);	} else {		name = 0;		namelen = 0;	}	error = ntfs_new_attr(ino, anum, name, namelen, data, dsize, &i,			&found);	if (error || found) {		ntfs_free(name);		return error ? error : -EEXIST;	}	*rattr = attr = ino->attrs + i;	/* Allocate a new number.	 * FIXME: Should this happen on inode writeback?	 * FIXME: Extension records not supported. */	error = ntfs_allocate_attr_number(ino, &i);	if (error)		return error;	attr->attrno = i;	if (attr->attrno + 1 != NTFS_GETU16(ino->attr + 0x28))		ntfs_error("UH OH! attr->attrno (%i) != NTFS_GETU16(ino->attr "				"+ 0x28) (%i)\n", attr->attrno,				NTFS_GETU16(ino->attr + 0x28));	attr->resident = 1;	attr->flags = 0;	attr->cengine = 0;	attr->size = attr->allocated = attr->initialized = dsize;	/* FIXME: INDEXED information should come from $AttrDef	 * Currently, only file names are indexed. As of NTFS v3.0 (Win2k),	 * this is no longer true. Different attributes can be indexed now. */	if (anum == ino->vol->at_file_name)		attr->indexed = 1;	else		attr->indexed = 0;	attr->d.data = ntfs_malloc(dsize);	if (!attr->d.data)		return -ENOMEM;	ntfs_memcpy(attr->d.data, data, dsize);	return 0;}/* * Non-resident attributes are stored in runs (intervals of clusters). * * This function stores in the inode readable information about a non-resident * attribute. */static int ntfs_process_runs(ntfs_inode *ino, ntfs_attribute* attr,		unsigned char *data){	int startvcn, endvcn;	int vcn, cnum;	ntfs_cluster_t cluster;	int len, ctype;	int er = 0;	startvcn = NTFS_GETS64(data + 0x10);	endvcn = NTFS_GETS64(data + 0x18);	/* Check whether this chunk really belongs to the end. Problem with	 * this: this functions can get called on the last extent first, before	 * it is called on the other extents in sequence. This happens when the	 * base mft record contains the last extent instead of the first one	 * and the first extent is stored, like any intermediate extents in	 * extension mft records. This would be difficult to allow the way the	 * runlist is stored in memory. Thus we fix elsewhere by causing the	 * attribute list attribute to be processed immediately when found. The	 * extents will then be processed starting with the first one. */	for (cnum = 0, vcn = 0; cnum < attr->d.r.len; cnum++)		vcn += attr->d.r.runlist[cnum].len;	if (vcn != startvcn) {		ntfs_debug(DEBUG_FILE3, "ntfs_process_runs: ino = 0x%x, "			"attr->type = 0x%x, startvcn = 0x%x, endvcn = 0x%x, "			"vcn = 0x%x, cnum = 0x%x\n", ino->i_number, attr->type,			startvcn, endvcn, vcn, cnum);		if (vcn < startvcn) {			ntfs_error("Problem with runlist in extended record\n");			return -1;		}		/* Tried to insert an already inserted runlist. */		return 0;	}	if (!endvcn) {		if (!startvcn) {			/* Allocated length. */			endvcn = NTFS_GETS64(data + 0x28) - 1;			endvcn >>= ino->vol->cluster_size_bits;		} else {			/* This is an extent. Allocated length is not defined!			 * Extents must have an endvcn though so this is an			 * error. */			ntfs_error("Corrupt attribute extent. (endvcn is "				"missing)\n");			return -1;		}	}	data = data + NTFS_GETU16(data + 0x20);	cnum = attr->d.r.len;	cluster = 0;	for (vcn = startvcn; vcn <= endvcn; vcn += len)	{		if (ntfs_decompress_run(&data, &len, &cluster, &ctype)) {			ntfs_debug(DEBUG_FILE3, "ntfs_process_runs: "				"ntfs_decompress_run failed. i_number = 0x%x\n",				ino->i_number);			return -1;		}		if (ctype)			er = ntfs_insert_run(attr, cnum, -1, len);		else			er = ntfs_insert_run(attr, cnum, cluster, len);		if (er)			break;		cnum++;	}	if (er)		ntfs_error("ntfs_process_runs: ntfs_insert_run failed\n");	ntfs_debug(DEBUG_FILE3, "ntfs_process_runs: startvcn = 0x%x, vcn = 0x%x"				", endvcn = 0x%x, cnum = %i\n", startvcn, vcn,				endvcn, cnum);	return er;}  /* Insert the attribute starting at attr in the inode ino. */int ntfs_insert_attribute(ntfs_inode *ino, unsigned char *attrdata){	int i, found;	int type;	short int *name;	int namelen;	void *data;	ntfs_attribute *attr;	int error;	type = NTFS_GETU32(attrdata);	namelen = NTFS_GETU8(attrdata + 9);	ntfs_debug(DEBUG_FILE3, "ntfs_insert_attribute: ino->i_number 0x%x, "			"attr type 0x%x\n", ino->i_number, type);	/* Read the attribute's name if it has one. */	if (!namelen)		name = 0;	else {		/* 1 Unicode character fits in 2 bytes. */		name = ntfs_malloc(2 * namelen);		if (!name)			return -ENOMEM;		ntfs_memcpy(name, attrdata + NTFS_GETU16(attrdata + 10),			    2 * namelen);	}	/* If resident look for value, too. */	if (NTFS_GETU8(attrdata + 8) == 0)		error = ntfs_new_attr(ino, type, name, namelen,				attrdata + NTFS_GETU16(attrdata + 0x14),				NTFS_GETU16(attrdata + 0x10), &i, &found);	else		error = ntfs_new_attr(ino, type, name, namelen, NULL, 0, &i,				&found);	if (error) {		ntfs_debug(DEBUG_FILE3, "ntfs_insert_attribute: ntfs_new_attr "				"failed.\n");		if (name)			ntfs_free(name);		return error;	}	if (found) {		/* It's already there, if not resident just process the runs. */		if (!ino->attrs[i].resident) {			ntfs_debug(DEBUG_FILE3, "ntfs_insert_attribute:"						" processing runs 1.\n");			/* FIXME: Check error code! (AIA) */			ntfs_process_runs(ino, ino->attrs + i, attrdata);		}		return 0;	}	attr = ino->attrs + i;	attr->resident = NTFS_GETU8(attrdata + 8) == 0;	attr->flags = *(__u16*)(attrdata + 0xC);	attr->attrno = NTFS_GETU16(attrdata + 0xE);  	if (attr->resident) {		attr->size = NTFS_GETU16(attrdata + 0x10);		data = attrdata + NTFS_GETU16(attrdata + 0x14);		attr->d.data = (void*)ntfs_malloc(attr->size);		if (!attr->d.data)			return -ENOMEM;		ntfs_memcpy(attr->d.data, data, attr->size);		attr->indexed = NTFS_GETU8(attrdata + 0x16);	} else {		attr->allocated = NTFS_GETS64(attrdata + 0x28);		attr->size = NTFS_GETS64(attrdata + 0x30);		attr->initialized = NTFS_GETS64(attrdata + 0x38);		attr->cengine = NTFS_GETU16(attrdata + 0x22);		if (attr->flags & ATTR_IS_COMPRESSED)			attr->compsize = NTFS_GETS64(attrdata + 0x40);		ntfs_debug(DEBUG_FILE3, "ntfs_insert_attribute: "			"attr->allocated = 0x%Lx, attr->size = 0x%Lx, "			"attr->initialized = 0x%Lx\n", attr->allocated,			attr->size, attr->initialized);		ino->attrs[i].d.r.runlist = 0;		ino->attrs[i].d.r.len = 0;		ntfs_debug(DEBUG_FILE3, "ntfs_insert_attribute: processing "				"runs 2.\n");		/* FIXME: Check error code! (AIA) */		ntfs_process_runs(ino, attr, attrdata);	}	return 0;}int ntfs_read_zero(ntfs_io *dest, int size){	int i;	char *sparse = ntfs_calloc(512);	if (!sparse)		return -ENOMEM;	i = 512;	while (size) {		if (i > size)			i = size;		dest->fn_put(dest, sparse, i);		size -= i;	}	ntfs_free(sparse);	return 0;}/* Process compressed attributes. */int ntfs_read_compressed(ntfs_inode *ino, ntfs_attribute *attr, __s64 offset,			 ntfs_io *dest){	int error = 0;	int clustersizebits;	int s_vcn, rnum, vcn, got, l1;	__s64 copied, len, chunk, offs1, l, chunk2;	ntfs_cluster_t cluster, cl1;	char *comp = 0, *comp1;	char *decomp = 0;	ntfs_io io;	ntfs_runlist *rl;	l = dest->size;	clustersizebits = ino->vol->cluster_size_bits;	/* Starting cluster of potential chunk. There are three situations:	   a) In a large uncompressible or sparse chunk, s_vcn is in the middle	      of a run.	   b) s_vcn is right on a run border.	   c) When several runs make a chunk, s_vcn is before the chunks. */	s_vcn = offset >> clustersizebits;	/* Round down to multiple of 16. */	s_vcn &= ~15;	rl = attr->d.r.runlist;	for (rnum = vcn = 0; rnum < attr->d.r.len && vcn + rl->len <= s_vcn;								rnum++, rl++)		vcn += rl->len;	if (rnum == attr->d.r.len) {		/* Beyond end of file. */		/* FIXME: Check allocated / initialized. */		dest->size = 0;		return 0;	}	io.do_read = 1;	io.fn_put = ntfs_put;	io.fn_get = 0;	cluster = rl->lcn;	len = rl->len;	copied = 0;	while (l) {		chunk = 0;		if (cluster == (ntfs_cluster_t)-1) {			/* Sparse cluster. */			__s64 ll;			if ((len - (s_vcn - vcn)) & 15)				ntfs_error("Unexpected sparse chunk size.");			ll = ((__s64)(vcn + len) << clustersizebits) - offset;			if (ll > l)				ll = l;			chunk = ll;			error = ntfs_read_zero(dest, ll);			if (error)				goto out;		} else if (dest->do_read) {			if (!comp) {				comp = ntfs_malloc(16 << clustersizebits);				if (!comp) {					error = -ENOMEM;					goto out;				}			}			got = 0;			/* We might need to start in the middle of a run. */			cl1 = cluster + s_vcn - vcn;			comp1 = comp;			do {				int delta;				io.param = comp1;				delta = s_vcn - vcn;				if (delta < 0)					delta = 0;				l1 = len - delta;				if (l1 > 16 - got)					l1 = 16 - got;				io.size = (__s64)l1 << clustersizebits;				error = ntfs_getput_clusters(ino->vol, cl1, 0,					       		     &io);				if (error)					goto out;				if (l1 + delta == len) {					rnum++;					rl++;					vcn += len;					cluster = cl1 = rl->lcn;					len = rl->len;				}				got += l1;				comp1 += (__s64)l1 << clustersizebits;			} while (cluster != (ntfs_cluster_t)-1 && got < 16);							/* Until empty run. */			chunk = 16 << clustersizebits;			if (cluster != (ntfs_cluster_t)-1 || got == 16)				/* Uncompressible */				comp1 = comp;			else {				if (!decomp) {					decomp = ntfs_malloc(16 << 							clustersizebits);					if (!decomp) {						error = -ENOMEM;						goto out;					}				}				/* Make sure there are null bytes after the				 * last block. */				*(ntfs_u32*)comp1 = 0;				ntfs_decompress(decomp, comp, chunk);				comp1 = decomp;			}			offs1 = offset - ((__s64)s_vcn << clustersizebits);			chunk2 = (16 << clustersizebits) - offs1;			if (chunk2 > l)				chunk2 = l;			if (chunk > chunk2)				chunk = chunk2;			dest->fn_put(dest, comp1 + offs1, chunk);		}		l -= chunk;		copied += chunk;		offset += chunk;		s_vcn = (offset >> clustersizebits) & ~15;		if (l && offset >= ((__s64)(vcn + len) << clustersizebits)) {			rnum++;			rl++;			vcn += len;			cluster = rl->lcn;			len = rl->len;		}	}out:	if (comp)		ntfs_free(comp);	if (decomp)		ntfs_free(decomp);	dest->size = copied;	return error;}int ntfs_write_compressed(ntfs_inode *ino, ntfs_attribute *attr, __s64 offset,		ntfs_io *dest){	return -EOPNOTSUPP;}

⌨️ 快捷键说明

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