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

📄 inode.c

📁 一个linux下NTFS文件格式源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#if 0 /* Keep for future, in case ntfs_cluster_t ever becomes 64bit */	case 0x50: *cluster += NTFS_GETS40(*data);break;	case 0x60: *cluster += NTFS_GETS48(*data);break;	case 0x70: *cluster += NTFS_GETS56(*data);break;	case 0x80: *cluster += NTFS_GETS64(*data);break;	#endif	default:		ntfs_error("Can't decode run type field %x\n",type);		return -1;	}	*data+=(type >> 4);	return 0;}/* Reads l bytes of the attribute (attr,name) of ino starting at offset   on vol into buf. Returns the number of bytes read in the ntfs_io struct.   Returns 0 on success, errno on failure */int ntfs_readwrite_attr(ntfs_inode *ino, ntfs_attribute *attr, int offset,	ntfs_io *dest){	int rnum;	ntfs_cluster_t cluster,s_cluster,vcn,len;	int l,chunk,copied;	int s_vcn;	int clustersize;	int error;	clustersize=ino->vol->clustersize;	l=dest->size;	if(l==0)		return 0;	if(dest->do_read)	{		/* if read _starts_ beyond end of stream, return nothing */		if(offset>=attr->size){			dest->size=0;			return 0;		}		/* if read _extends_ beyond end of stream, return as much			initialised data as we have */		if(offset+l>=attr->size) 			l=dest->size=attr->size-offset;	}else {		/* fixed by CSA: if writing beyond end, extend attribute */		/* if write extends beyond _allocated_ size, extend attrib */		if (offset+l>attr->allocated) {			error=ntfs_resize_attr(ino,attr,offset+l);			if(error)				return error;		}		/* the amount of initialised data has increased; update */		/* FIXME: shouldn't we zero-out the section between the old			initialised length and the write start? */		if (offset+l > attr->initialized) {			attr->initialized = offset+l;			attr->size = offset+l;		}	}	if(attr->resident)	{		if(dest->do_read)			dest->fn_put(dest,(ntfs_u8*)attr->d.data+offset,l);		else			dest->fn_get((ntfs_u8*)attr->d.data+offset,dest,l);		dest->size=l;		return 0;	}	/* read uninitialized data */	if(offset>=attr->initialized && dest->do_read)		return ntfs_read_zero(dest,l);	if(offset+l>attr->initialized && dest->do_read)	{		dest->size = chunk = offset+l - attr->initialized;		error = ntfs_readwrite_attr(ino,attr,offset,dest);		if(error)			return error;				return ntfs_read_zero(dest,l-chunk);	}	if(attr->compressed){		if(dest->do_read)			return ntfs_read_compressed(ino,attr,offset,dest);		else			return ntfs_write_compressed(ino,attr,offset,dest);	}	vcn=0;	s_vcn = offset/clustersize;	for(rnum=0;rnum<attr->d.r.len && 		    vcn+attr->d.r.runlist[rnum].len<=s_vcn;rnum++)		vcn+=attr->d.r.runlist[rnum].len;	if(rnum==attr->d.r.len)		/*FIXME: should extend runlist */		return EOPNOTSUPP;		copied=0;	while(l)	{		s_vcn = offset/clustersize;		cluster=attr->d.r.runlist[rnum].cluster;		len=attr->d.r.runlist[rnum].len;		s_cluster = cluster+s_vcn-vcn;					chunk=min((vcn+len)*clustersize-offset,l);		dest->size=chunk;		error=ntfs_getput_clusters(ino->vol,s_cluster,					   offset-s_vcn*clustersize,dest);		if(error)/* FIXME: maybe return failure */		{			ntfs_error("Read error\n");			dest->size=copied;			return 0;		}		l-=chunk;		copied+=chunk;		offset+=chunk;		if(l && offset>=((vcn+len)*clustersize))		{			rnum++;			vcn+=len;			cluster = attr->d.r.runlist[rnum].cluster;			len = attr->d.r.runlist[rnum].len;		}	}	dest->size=copied;	return 0;}int ntfs_read_attr(ntfs_inode *ino, int type, char *name, int offset,        ntfs_io *buf){	ntfs_attribute *attr;	buf->do_read=1;	attr=ntfs_find_attr(ino,type,name);	if(!attr)		return EINVAL;	return ntfs_readwrite_attr(ino,attr,offset,buf);}int ntfs_write_attr(ntfs_inode *ino, int type, char *name, int offset,		ntfs_io *buf){	ntfs_attribute *attr;	buf->do_read=0;	attr=ntfs_find_attr(ino,type,name);	if(!attr)		return EINVAL;	return ntfs_readwrite_attr(ino,attr,offset,buf);}int ntfs_vcn_to_lcn(ntfs_inode *ino,int vcn){	int rnum;	ntfs_attribute *data;	data=ntfs_find_attr(ino,ino->vol->at_data,0);	/* It's hard to give an error code */	if(!data)return -1;	if(data->resident)return -1;	if(data->compressed)return -1;	if(data->size <= vcn*ino->vol->clustersize)return -1;	/* For Linux, block number 0 represents a hole.	   Hopefully, nobody will attempt to bmap $Boot. */	if(data->initialized <= vcn*ino->vol->clustersize)		return 0;	for(rnum=0;rnum<data->d.r.len && 		    vcn>data->d.r.runlist[rnum].len;rnum++)		vcn-=data->d.r.runlist[rnum].len;		return data->d.r.runlist[rnum].cluster+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_recordsize);		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;}int layout_runs(ntfs_attribute *attr,char* rec,int* offs,int size){	int i,len,offset,coffs;	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++){		rclus=rl[i].cluster-cluster;		len=rl[i].len;		rec[offset]=0;		if(offset+8>size)			return E2BIG; /* it might still fit, but this simplifies testing */		if(len<0x100){			NTFS_PUTU8(rec+offset+1,len);			coffs=1;		}else if(len<0x10000){			NTFS_PUTU16(rec+offset+1,len);			coffs=2;		}else if(len<0x1000000){			NTFS_PUTU24(rec+offset+1,len);			coffs=3;		}else{			NTFS_PUTU32(rec+offset+1,len);			coffs=4;		}    		*(rec+offset)|=coffs++;		if(rl[i].cluster==MAX_CLUSTER_T) /*compressed run*/			/*nothing*/;		else if(rclus>-0x80 && rclus<0x7F){			*(rec+offset)|=0x10;			NTFS_PUTS8(rec+offset+coffs,rclus);			coffs+=1;		}else if(rclus>-0x8000 && rclus<0x7FFF){			*(rec+offset)|=0x20;			NTFS_PUTS16(rec+offset+coffs,rclus);			coffs+=2;		}else if(rclus>-0x800000 && rclus<0x7FFFFF){			*(rec+offset)|=0x30;			NTFS_PUTS24(rec+offset+coffs,rclus);			coffs+=3;		}else#if 0 /* In case ntfs_cluster_t ever becomes 64bit */	       	if (rclus>-0x80000000LL && rclus<0x7FFFFFFF)#endif		{			*(rec+offset)|=0x40;			NTFS_PUTS32(rec+offset+coffs,rclus);			coffs+=4;		}#if 0 /* For 64-bit ntfs_cluster_t */		else if (rclus>-0x8000000000 && rclus<0x7FFFFFFFFF){			*(rec+offset)|=0x50;			NTFS_PUTS40(rec+offset+coffs,rclus);			coffs+=5;		}else if (rclus>-0x800000000000 && rclus<0x7FFFFFFFFFFF){			*(rec+offset)|=0x60;			NTFS_PUTS48(rec+offset+coffs,rclus);			coffs+=6;		}else if (rclus>-0x80000000000000 && rclus<0x7FFFFFFFFFFFFF){			*(rec+offset)|=0x70;			NTFS_PUTS56(rec+offset+coffs,rclus);			coffs+=7;		}else{			*(rec+offset)|=0x80;			NTFS_PUTS64(rec+offset+coffs,rclus);			coffs+=8;		}#endif		offset+=coffs;		if(rl[i].cluster)			cluster=rl[i].cluster;	}	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);} static intlayout_attr(ntfs_attribute* attr,char*buf, int size,int *psize){	int asize,error;	if(size<10)return E2BIG;	NTFS_PUTU32(buf,attr->type);	/* fill in length later */	NTFS_PUTU8(buf+8,attr->resident ? 0:1);	NTFS_PUTU8(buf+9,attr->namelen);	/* fill in offset to name later */	NTFS_PUTU16(buf+0xA,0);	NTFS_PUTU16(buf+0xC,attr->compressed);	/* FIXME: assign attribute ID??? */	NTFS_PUTU16(buf+0xE,attr->attrno);	if(attr->resident){		if(size<attr->size+0x18+attr->namelen)return E2BIG;		asize=0x18;		NTFS_PUTU32(buf+0x10,attr->size);		NTFS_PUTU16(buf+0x16,attr->indexed);		if(attr->name){			ntfs_memcpy(buf+asize,attr->name,2*attr->namelen);			NTFS_PUTU16(buf+0xA,asize);			asize+=2*attr->namelen;			asize=(asize+7) & ~7;		}		NTFS_PUTU16(buf+0x14,asize);		ntfs_memcpy(buf+asize,attr->d.data,attr->size);		asize+=attr->size;	}else{		/* FIXME: fragments */		count_runs(attr,buf);		/* offset to data is added later */		NTFS_PUTU16(buf+0x22,attr->cengine);		NTFS_PUTU32(buf+0x24,0);		NTFS_PUTU64(buf+0x28,attr->allocated);		NTFS_PUTU64(buf+0x30,attr->size);		NTFS_PUTU64(buf+0x38,attr->initialized);		if(attr->compressed){			NTFS_PUTU64(buf+0x40,attr->compsize);			asize=0x48;		}else			asize=0x40;		if(attr->name){			NTFS_PUTU16(buf+0xA,asize);			ntfs_memcpy(buf+asize,attr->name,2*attr->namelen);			asize+=2*attr->namelen;			/* SRD: you whaaa?			asize=(asize+7) & ~7;*/		}		/* asize points at the beginning of the data */		NTFS_PUTU16(buf+0x20,asize);		error=layout_runs(attr,buf,&asize,size);		/* now asize pointes at the end of the data */		if(error)			return error;	}	asize=(asize+7) & ~7;	NTFS_PUTU32(buf+4,asize);	*psize=asize;	return 0;}				/* Try to layout ino into store. Return 0 on success,   E2BIG if it does not fit,    ENOMEM if memory allocation problem,   EOPNOTSUP if beyond our capabilities */int layout_inode(ntfs_inode *ino,ntfs_disk_inode *store){	int offset,i;	ntfs_attribute *attr;	unsigned char *rec;	int size,psize;	int error;	if(ino->record_count>1)	{		ntfs_error("layout_inode: attribute lists not supported\n");		return EOPNOTSUPP;	}	error=allocate_store(ino->vol,store,1);	if(error)		return error;	rec=store->records[0].record;	size=ino->vol->mft_recordsize;	store->records[0].recno=ino->records[0];	/* copy header */	offset=NTFS_GETU16(ino->attr+0x14);	ntfs_memcpy(rec,ino->attr,offset);	for(i=0;i<ino->attr_count;i++){		attr=ino->attrs+i;		error=layout_attr(attr,rec+offset,size-offset,&psize);		if(error)return error;		offset+=psize;#if 0		/* copy attribute header */		ntfs_memcpy(rec+offset,attr->header,			    min(sizeof(attr->header),size-offset)); /* consider overrun */		if(attr->namelen)			/* named attributes are added later */			return EOPNOTSUPP;		/* FIXME: assign attribute ID??? */		if(attr->resident){			asize=attr->size;			aoffset=NTFS_GETU16(rec+offset+0x14);			if(offset+aoffset+asize>size)				return E2BIG;			ntfs_memcpy(rec+offset+aoffset,attr->d.data,asize);			next=offset+aoffset+asize;		}else{			count_runs(attr,rec+offset);			aoffset=NTFS_GETU16(rec+offset+0x20);			next=offset+aoffset;			error=layout_runs(attr,rec,&next,size);			if(error)				return error;		}		/* SRD: umm..		next=(next+7) & ~7; */		/* is this setting the length? if so maybe we could get		   away with rounding up so long as we set the length first..		   ..except, is the length the only way to get to the next attr?		 */		NTFS_PUTU16(rec+offset+4,next-offset);		offset=next;#endif

⌨️ 快捷键说明

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