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

📄 inode.c

📁 EM85XX读NTFS修正代码包
💻 C
📖 第 1 页 / 共 5 页
字号:
		data = ntfs_find_attr(ino, ino->vol->at_data, 0);	if (!data || data->resident || data->flags & (ATTR_IS_COMPRESSED |			ATTR_IS_ENCRYPTED))		return -2;	if (data->size <= (__s64)vcn << ino->vol->cluster_size_bits)		return -2;	if (data->initialized <= (__s64)vcn << ino->vol->cluster_size_bits)		return -1;	for (rnum = 0; rnum < data->d.r.len &&			vcn >= data->d.r.runlist[rnum].len; rnum++)		vcn -= data->d.r.runlist[rnum].len;	if (data->d.r.runlist[rnum].lcn >= 0)		return data->d.r.runlist[rnum].lcn + vcn;	return data->d.r.runlist[rnum].lcn + vcn;}static int allocate_store(ntfs_volume *vol, ntfs_disk_inode *store, int count){	int i;		if (store->count > count)		return 0;	if (store->size < count) {		ntfs_mft_record *n = ntfs_malloc((count + 4) * 						 sizeof(ntfs_mft_record));		if (!n)			return -ENOMEM;		if (store->size) {			for (i = 0; i < store->size; i++)				n[i] = store->records[i];			ntfs_free(store->records);		}		store->size = count + 4;		store->records = n;	}	for (i = store->count; i < count; i++) {		store->records[i].record = ntfs_malloc(vol->mft_record_size);		if (!store->records[i].record)			return -ENOMEM;		store->count++;	}	return 0;}static void deallocate_store(ntfs_disk_inode* store){	int i;		for (i = 0; i < store->count; i++)		ntfs_free(store->records[i].record);	ntfs_free(store->records);	store->count = store->size = 0;	store->records = 0;}/** * layout_runs - compress runlist into mapping pairs array * @attr:	attribute containing the runlist to compress * @rec:	destination buffer to hold the mapping pairs array * @offs:	current position in @rec (in/out variable) * @size:	size of the buffer @rec * * layout_runs walks the runlist in @attr, compresses it and writes it out the * resulting mapping pairs array into @rec (up to a maximum of @size bytes are * written). On entry @offs is the offset in @rec at which to begin writing the * mapping pairs array. On exit, it contains the offset in @rec of the first * byte after the end of the mapping pairs array. */static int layout_runs(ntfs_attribute *attr, char *rec, int *offs, int size){	int i, len, offset, coffs;	/* ntfs_cluster_t MUST be signed! (AIA) */	ntfs_cluster_t cluster, rclus;	ntfs_runlist *rl = attr->d.r.runlist;	cluster = 0;	offset = *offs;	for (i = 0; i < attr->d.r.len; i++) {		/*		 * We cheat with this check on the basis that lcn will never		 * be less than -1 and the lcn delta will fit in signed		 * 32-bits (ntfs_cluster_t). (AIA)		 */		if (rl[i].lcn < (ntfs_cluster_t)-1) {			ntfs_error("layout_runs() encountered an out of bounds "					"cluster delta, lcn = %i.\n",					rl[i].lcn);			return -ERANGE;		}		rclus = rl[i].lcn - cluster;		len = rl[i].len;		rec[offset] = 0; 		if (offset + 9 > size)			return -E2BIG; /* It might still fit, but this					* simplifies testing. */		/*		 * Run length is stored as signed number, so deal with it		 * properly, i.e. observe that a negative number will have all		 * its most significant bits set to 1 but we don't store that		 * in the mapping pairs array. We store the smallest type of		 * negative number required, thus in the first if we check		 * whether len fits inside a signed byte and if so we store it		 * as such, the next ifs check for a signed short, then a signed		 * 24-bit and finally the full blown signed 32-bit. Same goes		 * for rlus below. (AIA)		 */		if (len >= -0x80 && len <= 0x7f) {			NTFS_PUTU8(rec + offset + 1, len & 0xff);			coffs = 1; 		} else if (len >= -0x8000 && len <= 0x7fff) {			NTFS_PUTU16(rec + offset + 1, len & 0xffff);			coffs = 2; 		} else if (len >= -0x800000 && len <= 0x7fffff) {			NTFS_PUTU24(rec + offset + 1, len & 0xffffff);			coffs = 3;		} else /* if (len >= -0x80000000LL && len <= 0x7fffffff */ {			NTFS_PUTU32(rec + offset + 1, len);			coffs = 4;		} /* else ... FIXME: When len becomes 64-bit we need to extend		   * 		     the else if () statements. (AIA) */		*(rec + offset) |= coffs++;		if (rl[i].lcn == (ntfs_cluster_t)-1) /* Compressed run. */			/* Nothing */;		else if (rclus >= -0x80 && rclus <= 0x7f) {			*(rec + offset) |= 0x10;			NTFS_PUTS8(rec + offset + coffs, rclus & 0xff);			coffs += 1;		} else if (rclus >= -0x8000 && rclus <= 0x7fff) {			*(rec + offset) |= 0x20;			NTFS_PUTS16(rec + offset + coffs, rclus & 0xffff);			coffs += 2;		} else if (rclus >= -0x800000 && rclus <= 0x7fffff) {			*(rec + offset) |= 0x30;			NTFS_PUTS24(rec + offset + coffs, rclus & 0xffffff);			coffs += 3;		} else /* if (rclus >= -0x80000000LL && rclus <= 0x7fffffff)*/ {			*(rec + offset) |= 0x40;			NTFS_PUTS32(rec + offset + coffs, rclus							/* & 0xffffffffLL */);			coffs += 4;		} /* FIXME: When rclus becomes 64-bit.		else if (rclus >= -0x8000000000 && rclus <= 0x7FFFFFFFFF) {			*(rec + offset) |= 0x50;			NTFS_PUTS40(rec + offset + coffs, rclus &							0xffffffffffLL);			coffs += 5;		} else if (rclus >= -0x800000000000 && 						rclus <= 0x7FFFFFFFFFFF) {			*(rec + offset) |= 0x60;			NTFS_PUTS48(rec + offset + coffs, rclus &							0xffffffffffffLL);			coffs += 6;		} else if (rclus >= -0x80000000000000 && 						rclus <= 0x7FFFFFFFFFFFFF) {			*(rec + offset) |= 0x70;			NTFS_PUTS56(rec + offset + coffs, rclus &							0xffffffffffffffLL);			coffs += 7;		} else {			*(rec + offset) |= 0x80;			NTFS_PUTS64(rec + offset + coffs, rclus);			coffs += 8;		} */		offset += coffs;		if (rl[i].lcn)			cluster = rl[i].lcn;	}	if (offset >= size)		return -E2BIG;	/* Terminating null. */	*(rec + offset++) = 0;	*offs = offset;	return 0;}static void count_runs(ntfs_attribute *attr, char *buf){	ntfs_u32 first, count, last, i;		first = 0;	for (i = 0, count = 0; i < attr->d.r.len; i++)		count += attr->d.r.runlist[i].len;	last = first + count - 1;	NTFS_PUTU64(buf + 0x10, first);	NTFS_PUTU64(buf + 0x18, last);} /** * layout_attr - convert in memory attribute to on disk attribute record * @attr:	in memory attribute to convert * @buf:	destination buffer for on disk attribute record * @size:	size of the destination buffer * @psize:	size of converted on disk attribute record (out variable) * * layout_attr() takes the attribute @attr and converts it into the appropriate * on disk structure, writing it into @buf (up to @size bytes are written). * * On success we return 0 and set @*psize to the actual byte size of the on- * disk attribute that was written into @buf. */static int layout_attr(ntfs_attribute *attr, char *buf, int size, int *psize){	int nameoff, hdrsize, asize;		if (attr->resident) {		nameoff = 0x18;		hdrsize = (nameoff + 2 * attr->namelen + 7) & ~7;		asize = (hdrsize + attr->size + 7) & ~7;		if (size < asize)			return -E2BIG;		NTFS_PUTU32(buf + 0x10, attr->size);		NTFS_PUTU8(buf + 0x16, attr->indexed);		NTFS_PUTU16(buf + 0x14, hdrsize);		if (attr->size)			ntfs_memcpy(buf + hdrsize, attr->d.data, attr->size);	} else {		int error;		if (attr->flags & ATTR_IS_COMPRESSED) 			nameoff = 0x48; 		else 			nameoff = 0x40; 		hdrsize = (nameoff + 2 * attr->namelen + 7) & ~7; 		if (size < hdrsize) 			return -E2BIG; 		/* Make asize point at the end of the attribute record header,		   i.e. at the beginning of the mapping pairs array. */ 		asize = hdrsize; 		error = layout_runs(attr, buf, &asize, size); 		/* Now, asize points one byte beyond the end of the mapping		   pairs array. */		if (error) 			return error; 		/* The next attribute has to begin on 8-byte boundary. */		asize = (asize + 7) & ~7;		/* FIXME: fragments */		count_runs(attr, buf);		NTFS_PUTU16(buf + 0x20, hdrsize);		NTFS_PUTU16(buf + 0x22, attr->cengine);		NTFS_PUTU32(buf + 0x24, 0);		NTFS_PUTS64(buf + 0x28, attr->allocated);		NTFS_PUTS64(buf + 0x30, attr->size);		NTFS_PUTS64(buf + 0x38, attr->initialized);		if (attr->flags & ATTR_IS_COMPRESSED)			NTFS_PUTS64(buf + 0x40, attr->compsize);	}	NTFS_PUTU32(buf, attr->type);	NTFS_PUTU32(buf + 4, asize);	NTFS_PUTU8(buf + 8, attr->resident ? 0 : 1);	NTFS_PUTU8(buf + 9, attr->namelen);	NTFS_PUTU16(buf + 0xa, nameoff);	NTFS_PUTU16(buf + 0xc, attr->flags);	NTFS_PUTU16(buf + 0xe, attr->attrno);	if (attr->namelen)		ntfs_memcpy(buf + nameoff, attr->name, 2 * attr->namelen);	*psize = asize;	return 0;}/** * layout_inode - convert an in-memory inode into on disk mft record(s) * @ino:	in memory inode to convert * @store:	on disk inode, contain buffers for the on disk mft record(s) * * layout_inode takes the in memory inode @ino, converts it into a (sequence of) * mft record(s) and writes them to the appropriate buffers in the @store. * * Return 0 on success, * the required mft record count (>0) if the inode does not fit, * -ENOMEM if memory allocation problem, or * -EOPNOTSUP if beyond our capabilities. * * TODO: We at the moment do not support extension mft records. (AIA) */int layout_inode(ntfs_inode *ino, ntfs_disk_inode *store){	int offset, i, size, psize, error, count, recno;	ntfs_attribute *attr;	unsigned char *rec;	error = allocate_store(ino->vol, store, ino->record_count);	if (error)		return error;	size = ino->vol->mft_record_size; 	count = i = 0; 	do { 		if (count < ino->record_count) { 			recno = ino->records[count]; 		} else { 			error = allocate_store(ino->vol, store, count + 1); 			if (error) 				return error;	 		recno = -1;		}		/*		 * FIXME: We need to support extension records properly.		 * At the moment they wouldn't work. Probably would "just" get		 * corrupted if we write to them... (AIA)		 */	 	store->records[count].recno = recno; 		rec = store->records[count].record;	 	count++; 		/* Copy mft record header. */	 	offset = NTFS_GETU16(ino->attr + 0x14); /* attrs_offset */		ntfs_memcpy(rec, ino->attr, offset);	 	/* Copy attributes. */ 		while (i < ino->attr_count) { 			attr = ino->attrs + i;	 		error = layout_attr(attr, rec + offset,					size - offset - 8, &psize);	 		if (error == -E2BIG && offset != NTFS_GETU16(ino->attr					+ 0x14)) 				break; 			if (error) 				return error; 			offset += psize; 			i++; 		} 		/* Terminating attribute. */		NTFS_PUTU32(rec + offset, 0xFFFFFFFF);		offset += 4;		NTFS_PUTU32(rec + offset, 0);		offset += 4;		NTFS_PUTU32(rec + 0x18, offset);	} while (i < ino->attr_count || count < ino->record_count);	return count - ino->record_count;}/* * FIXME: ntfs_update_inode() calls layout_inode() to create the mft record on * disk structure corresponding to the inode @ino. After that, ntfs_write_attr() * is called to write out the created mft record to disk. * We shouldn't need to re-layout every single time we are updating an mft * record. No wonder the ntfs driver is slow like hell. (AIA) */int ntfs_update_inode(ntfs_inode *ino){	int error, i;	ntfs_disk_inode store;	ntfs_io io;	ntfs_bzero(&store, sizeof(store));	error = layout_inode(ino, &store);	if (error == -E2BIG) {		i = ntfs_split_indexroot(ino);		if (i != -ENOTDIR) {			if (!i)				i = layout_inode(ino, &store);			error = i;		}	}	if (error == -E2BIG) {		error = ntfs_attr_allnonresident(ino);		if (!error)			error = layout_inode(ino, &store);	}	if (error > 0) {		/* FIXME: Introduce extension records. */		error = -E2BIG;	}	if (error) {		if (error == -E2BIG)			ntfs_error("Cannot handle saving inode 0x%x.\n",				   ino->i_number);		deallocate_store(&store);		return error;	}	io.fn_get = ntfs_get;	io.fn_put = 0;	for (i = 0; i < store.count; i++) {		error = ntfs_insert_fixups(store.records[i].record,				ino->vol->mft_record_size);		if (error) {			printk(KERN_ALERT "NTFS: ntfs_update_inode() caught "					"corrupt %s mtf record ntfs record "					"header. Refusing to write corrupt "					"data to disk. Unmount and run chkdsk "					"immediately!\n", i ? "extension":					"base");			deallocate_store(&store);			return -EIO;		}		io.param = store.records[i].record;		io.size = ino->vol->mft_record_size;		error = ntfs_write_attr(ino->vol->mft_ino, ino->vol->at_data,				0, (__s64)store.records[i].recno <<				ino->vol->mft_record_size_bits, &io);		if (error || io.size != ino->vol->mft_record_size) {			/* Big trouble, partially written file. */			ntfs_error("Please unmount: Write error in inode "					"0x%x\n", ino->i_number);			deallocate_store(&store);			return error ? error : -EIO;		}	}	deallocate_store(&store);	return 0;}	void ntfs_decompress(unsigned char *dest, unsigned char *src, ntfs_size_t l){	int head, comp;	int copied = 0;	unsigned char *stop;	int bits;	int tag = 0;	int clear_pos;		while (1) {		head = NTFS_GETU16(src) & 0xFFF;		/* High bit indicates that compression was performed. */

⌨️ 快捷键说明

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