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

📄 inode.c

📁 NTFS 磁盘系统 加载源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	lowseconds |= result << 16;	numerator2  = ((numerator2-result*D)<<8) | ((L>>8)&0xff);	result      = (numerator2 / D);   /* shifted 8 right!! */	lowseconds |= result << 8;	numerator2  = ((numerator2-result*D)<<8) | (L&0xff);	result      = (numerator2 / D);   /* not shifted */	lowseconds |= result;	return lowseconds;}ntfs_time64_t ntfs_unixutc2ntutc (ntfs_time_t t){	return ((t + (ntfs_time64_t)(369*365+89)*24*3600) * 10000000);}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,cluster,rclus,len,offset,coffs;	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){			*(rec+offset)|=1;			NTFS_PUTU8(rec+offset+1,len);			coffs=2;		}else if(len<0x10000){			*(rec+offset)|=2;			NTFS_PUTU16(rec+offset+1,len);			coffs=3;		}else if(len<0x1000000){			*(rec+offset)|=3;			NTFS_PUTU24(rec+offset+1,len);			coffs=4;		}else{			*(rec+offset)|=4;			NTFS_PUTU32(rec+offset+1,len);			coffs=5;		}    		if(rl[i].cluster==0) /*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{			*(rec+offset)|=0x40;			NTFS_PUTS32(rec+offset+coffs,rclus);			coffs+=4;		}		offset+=coffs;		if(rl[i].cluster)			cluster=rl[i].cluster;	}	*offs=offset;	return 0;}static void count_runs(ntfs_attribute *attr,char *buf){	int 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_PUTU32(buf+0x10,first);	NTFS_PUTU32(buf+0x18,last);} /* Try to layout ino into store. Return 0 on success,   E2BIG if it does not fit,    ENOMEM if memory allocation problem,   EOPNOTSUP if beyound our capabilities */int layout_inode(ntfs_inode *ino,ntfs_disk_inode *store){	int offset,next,i;	ntfs_attribute *attr;	unsigned char *rec;	int size,asize,aoffset;	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;		/* 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(RESIDENT(&attr->header)){			asize=DATASIZE(&attr->header);			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;		}		next=(next+7) & ~7; /* align to DWORD */		NTFS_PUTU16(rec+offset+4,next-offset);		offset=next;	}	/* terminating attribute */	if(offset+8<size){		NTFS_PUTU32(rec+offset,0xFFFFFFFF);		offset+=4;		NTFS_PUTU32(rec+offset,0);		offset+=4;	}else		return E2BIG;	NTFS_PUTU32(rec+0x18,offset);	return 0;}  int update_inode(ntfs_inode *ino){	int error;	ntfs_disk_inode store;	ntfs_io io;	int i,l;	store.count=store.size=0;	store.records=0;	error=layout_inode(ino,&store);	if(error==E2BIG){		/* should try:		   make attributes non-resident		   introduce extension records		   */		ntfs_error("cannot handle saving inode %x\n",ino->i_number);		deallocate_store(&store);		return EOPNOTSUPP;	}	if(error){		deallocate_store(&store);		return error;	}	io.fn_get=ntfs_get;	io.fn_put=0;	for(i=0;i<store.count;i++){		ntfs_insert_fixups(store.records[i].record,ino->vol->blocksize);		io.param=store.records[i].record;		/* FIXME: is this the right way? */		l=ntfs_write_attr(ino->vol->mft_ino,AT_DATA,0,				  store.records[i].recno*ino->vol->mft_recordsize,				  &io,ino->vol->mft_recordsize);		if(l!=ino->vol->mft_recordsize){			/* big trouble, partially written file */			ntfs_error("Please unmount: write error in inode %x\n",ino->i_number);			deallocate_store(&store);			/* FIXME: error code */			return EIO;		}	}	return 0;}void ntfs_decompress(unsigned char* dest,unsigned char*src,ntfs_size_t l){	int head;	int copied=0;	unsigned char *stop;	int bits;	int tag=0;	int clear_pos;	while(1)	{		head = NTFS_GETU16(src) & 0xFFF;		src += 2;		stop = src+head;		bits = 0;		clear_pos=0;		if(head==0xFFF) /* uncompressible */		{			ntfs_memcpy(dest,src,0x1000);			dest+=0x1000;			copied+=0x1000;			if(l==copied)				return;			continue;		}		while(src<=stop)		{			if(clear_pos>4096)			{				ntfs_error("Error 1 in decompress\n");				return;			}			if(!bits){				tag=NTFS_GETU8(src);				bits=8;				src++;				if(src>stop)					break;			}			if(tag & 1){				int i,len,delta,code,lmask,dshift;				code = NTFS_GETU16(src);				src+=2;				if(!clear_pos)				{					ntfs_error("Error 2 in decompress\n");					return;				}				for(i=clear_pos-1,lmask=0xFFF,dshift=12;i>=0x10;i>>=1)				{					lmask >>= 1;					dshift--;				}				delta = code >> dshift;				len = (code & lmask) + 3;				for(i=0; i<len; i++)				{					dest[clear_pos]=dest[clear_pos-delta-1];					clear_pos++;					copied++;					if(copied==l)						return;				}			}else{				dest[clear_pos++]=NTFS_GETU8(src);				src++;				copied++;				if(copied==l)					return;			}			tag>>=1;			bits--;		}		dest+=clear_pos;	}}/* Caveat: No range checking in either ntfs_set_bit or ntfs_clear_bit */void ntfs_set_bit (unsigned char *byte, int bit){	byte += (bit >> 3);	bit &= 7;	*byte |= (1 << bit);}void ntfs_clear_bit (unsigned char *byte, int bit){	byte += (bit >> 3);	bit &= 7;	*byte &= ~(1 << bit);}/* We have to skip the 16 metafiles and the 8 reserved entries */int ntfs_new_inode (unsigned char *buffer, int length, int* result){	int byte;	int bit;	unsigned char value;	for (byte = 3; byte < length; byte++)	{		value = buffer[byte];		for (bit = 0; bit < 8; bit++, value >>= 1)		{			if (!(value & 1)){				*result=byte*8+bit;				return 0;			}		}	}	/* There is no free space.  We must first extend the MFT. */	return EOPNOTSUPP;}static int add_mft_header (ntfs_inode *ino){	unsigned short fixup = 1;	int fixup_count;	int fixup_offset;	int attr_offset;	int record_size;	unsigned char* mft;	ntfs_volume *vol=ino->vol;	fixup_offset = 0x2a;		record_size = vol->mft_recordsize;	fixup_count = record_size / vol->blocksize + 1;	attr_offset = (0x2a + (2 * fixup_count) + 7) & ~7;	mft=ino->attr;	ntfs_bzero (mft, record_size);	NTFS_PUTU32(mft + 0x00, 0x454c4946);	     /* file */	NTFS_PUTU16(mft + 0x04, 0x2a);		     /* offset to fixup */	NTFS_PUTU16(mft + 0x06, fixup_count);	     /* Number of fixups */	/* FIXME: sequence number. Regis recommended 5. */	NTFS_PUTU16(mft + 0x10, 5);	NTFS_PUTU16(mft + 0x12, 1);                  /* hard link count */	NTFS_PUTU16(mft + 0x14, attr_offset);	     /* Offset to attributes */	NTFS_PUTU16(mft + 0x16, 1);                  /*FIXME: flags ?? */	NTFS_PUTU32(mft + 0x18, attr_offset + 0x08);	/* In use */	NTFS_PUTU32(mft + 0x1c, record_size);	     /* Total size */	NTFS_PUTU16(mft + fixup_offset, fixup);		/* Fixup word */	NTFS_PUTU32(mft + attr_offset, 0xffffffff);	/* End marker */	return 0;}/* We need 0x48 bytes in total */static int add_standard_information (ntfs_inode *ino){	ntfs_time64_t now;	char data[0x30];	char *position=data;	int error;	now = ntfs_now();	NTFS_PUTU64(position + 0x00, now);		/* File creation */	NTFS_PUTU64(position + 0x08, now);		/* Last modification */	NTFS_PUTU64(position + 0x10, now);		/* Last mod for MFT */	NTFS_PUTU64(position + 0x18, now);		/* Last access */	NTFS_PUTU64(position + 0x20, 0x00);		/* MSDOS file perms */	NTFS_PUTU64(position + 0x28, 0);               /* unknown */	error=ntfs_create_attr(ino,AT_STANDARD_INFORMATION,0,data,sizeof(data));	return error;}static int add_filename (ntfs_inode* ino, ntfs_inode* dir, 			 const unsigned char *filename, int length){	unsigned char   *position;	unsigned int    size;	ntfs_time64_t   now;	int		count;	int error;	unsigned char* data;	ntfs_u64 ino_dir;	/* work out the size */	size = 0x42 + 2 * length;	data = ntfs_malloc(size);	ntfs_bzero(data,size);	/* search for a position */	position = data;	ino_dir=dir->i_number;	ino_dir|= ((ntfs_u64)(*(unsigned short*)(dir->attr+0x10)))<<48;	NTFS_PUTU64(position, ino_dir);	/* Inode num of dir */	now = ntfs_now();	NTFS_PUTU64(position + 0x08, now);		/* File creation */	NTFS_PUTU64(position + 0x10, now);		/* Last modification */	NTFS_PUTU64(position + 0x18, now);		/* Last mod for MFT */	NTFS_PUTU64(position + 0x20, now);		/* Last access */	/* Don't know */	NTFS_PUTU8(position+0x38, 0x20);  /*archive*/	NTFS_PUTU8(position + 0x40, length);	      /* Filename length */	NTFS_PUTU8(position + 0x41, 0x01);	      /* File type (Win32) */	position += 0x42;	for (count = 0; count < length; count++)	{		NTFS_PUTU16(position + 2 * count, filename[count]);	}	error=ntfs_create_attr(ino,AT_FILE_NAME,0,data,size);	ntfs_free(data);	return error;}int add_security (ntfs_inode* ino, ntfs_inode* dir){	int error;	char *buf;	int size;	ntfs_attribute* attr;	ntfs_io io;	attr=ntfs_find_attr(dir,AT_SECURITY_DESCRIPTOR,0);	if(!attr)		return EOPNOTSUPP; /* need security in directory */	size = DATASIZE(&(attr->header));	if(size>512)		return EOPNOTSUPP;	buf=ntfs_malloc(size);	if(!buf)		return ENOMEM;	io.fn_get=ntfs_get;	io.fn_put=ntfs_put;	io.param=buf;	if(ntfs_read_attr(dir,AT_SECURITY_DESCRIPTOR,0,0,&io,size)!=size){		ntfs_free(buf);		return EIO; /* FIXME */	}	/* FIXME: consider ACL inheritance */	error=ntfs_create_attr(ino,AT_SECURITY_DESCRIPTOR,0,buf,size);	ntfs_free(buf);	return error;}static int add_data (ntfs_inode* ino, unsigned char *data, int length){	int error;	error=ntfs_create_attr(ino,AT_DATA,0,data,length);	return error;}/* We _could_ use 'dir' to help optimise inode allocation */int ntfs_alloc_inode (ntfs_inode*dir, ntfs_inode *result, 		      char *filename, int namelen){	unsigned char buffer[512];	ntfs_io io;	int size;	int error;	ntfs_volume* vol=dir->vol;	io.fn_put = ntfs_put;	io.fn_get = ntfs_get;	io.param  = buffer;	size = ntfs_read_attr (vol->mft_ino, AT_BITMAP, 0, 0, &io, 512);	if (size < 1)		return (0);	error=ntfs_new_inode (buffer, size, &(result->i_number));	if(error)	{		ntfs_error ("ntfs_get_empty_inode: no free inodes\n");		return error;	}	io.param = buffer;	ntfs_set_bit (buffer, result->i_number); 	size = ntfs_write_attr (vol->mft_ino, AT_BITMAP, 0, 0, &io, size);	if (size < 1)		return ENOSPC;	result->vol=vol;	result->attr=ntfs_malloc(vol->mft_recordsize);	result->attr_count=0;	result->attrs=0;	result->record_count=1;	result->records=ntfs_malloc(8*sizeof(int));	result->records[0]=result->i_number;	error=add_mft_header(result);	if(error)		return error;	error=add_standard_information(result);	if(error)		return error;	error=add_filename(result,dir,filename,namelen);	if(error)		return error;	error=add_security(result,dir);	/*FIXME: check error */	error=add_data(result,0,0);	if(error)		return error;	return 0;}/* * Local variables: * c-file-style: "linux" * End: */

⌨️ 快捷键说明

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