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

📄 inode.c

📁 一个linux下NTFS文件格式源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	/* 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 ntfs_update_inode(ntfs_inode *ino){	int error;	ntfs_disk_inode store;	ntfs_io io;	int i;	store.count=store.size=0;	store.records=0;	error=layout_inode(ino,&store);	if(error==E2BIG){		error = ntfs_split_indexroot(ino);		if(!error)			error = layout_inode(ino,&store);	}	if(error == E2BIG){		error = ntfs_attr_allnonresident(ino);		if(!error)			error = layout_inode(ino,&store);	}	if(error == E2BIG){		/* should try:		   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;		io.size=ino->vol->mft_recordsize;		/* FIXME: is this the right way? */		error=ntfs_write_attr(			ino->vol->mft_ino,ino->vol->at_data,0,			store.records[i].recno*ino->vol->mft_recordsize,&io);		if(error || io.size!=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);			return error?error:EIO;		}	}	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 */		comp = NTFS_GETU16(src) & 0x8000;		src += 2;		stop = src+head;		bits = 0;		clear_pos=0;		if(head==0)			/* block is not used */			return;/* FIXME: copied */		if(!comp) /* uncompressible */		{			ntfs_memcpy(dest,src,0x1000);			dest+=0x1000;			copied+=0x1000;			src+=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 */static int new_inode (ntfs_volume* vol,int* result){	int byte,error;	int bit;	int size,length;	unsigned char value;	ntfs_u8 *buffer;	ntfs_io io;	ntfs_attribute *data;	buffer=ntfs_malloc(2048);	if(!buffer)return ENOMEM;	io.fn_put=ntfs_put;	io.fn_get=ntfs_get;	io.param=buffer;	/* FIXME: bitmaps larger than 2048 bytes */	io.size=2048;	error=ntfs_read_attr(vol->mft_ino,vol->at_bitmap,0,0,&io);	if(error){		ntfs_free(buffer);		return error;	}	size=io.size;	data=ntfs_find_attr(vol->mft_ino,vol->at_data,0);	length=data->size/vol->mft_recordsize;	/* SRD: start at byte 0: bits for system files _are_ already set in bitmap */	for (byte = 0; 8*byte < length; byte++)	{		value = buffer[byte];		if(value==0xFF)			continue;		for (bit = 0; (bit < 8) && (8*byte+bit<length); 		     bit++, value >>= 1)		{			if (!(value & 1)){				*result=byte*8+bit;				return 0;			}		}	}	/* There is no free space.  We must first extend the MFT. */	return ENOSPC;}static int add_mft_header (ntfs_inode *ino){	unsigned char* mft;	ntfs_volume *vol=ino->vol;	mft=ino->attr;	ntfs_bzero(mft, vol->mft_recordsize);	ntfs_fill_mft_header(mft,vol->mft_recordsize,vol->blocksize,			ino->sequence_number);	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;	ntfs_attribute *si;	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,ino->vol->at_standard_information,0,			       data,sizeof(data),&si);	return error;}static int add_filename (ntfs_inode* ino, ntfs_inode* dir, 	      const unsigned char *filename, int length, ntfs_u32 flags){	unsigned char   *position;	unsigned int    size;	ntfs_time64_t   now;	int		count;	int error;	unsigned char* data;	ntfs_attribute *fn;	/* work out the size */	size = 0x42 + 2 * length;	data = ntfs_malloc(size);	if( !data )		return ENOMEM;	ntfs_bzero(data,size);	/* search for a position */	position = data;	NTFS_PUTINUM(position, 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_PUTU32(position+0x38, flags);	NTFS_PUTU8(position + 0x40, length);	      /* Filename length */	NTFS_PUTU8(position + 0x41, 0x0);	      /* only long name */	position += 0x42;	for (count = 0; count < length; count++)	{		NTFS_PUTU16(position + 2 * count, filename[count]);	}	error=ntfs_create_attr(ino,ino->vol->at_file_name,0,data,size,&fn);	if(!error)		error=ntfs_dir_add(dir,ino,fn);	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;	ntfs_attribute *se;	attr=ntfs_find_attr(dir,ino->vol->at_security_descriptor,0);	if(!attr)		return EOPNOTSUPP; /* need security in directory */	size = attr->size;	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;	io.size=size;	error=ntfs_read_attr(dir,ino->vol->at_security_descriptor,0,0,&io);	if(!error && io.size!=size)ntfs_error("wrong size in add_security");	if(error){		ntfs_free(buf);		return error;	}	/* FIXME: consider ACL inheritance */	error=ntfs_create_attr(ino,ino->vol->at_security_descriptor,			       0,buf,size,&se);	ntfs_free(buf);	return error;}static int add_data (ntfs_inode* ino, unsigned char *data, int length){	int error;	ntfs_attribute *da;	error=ntfs_create_attr(ino,ino->vol->at_data,0,data,length,&da);	return error;}/* We _could_ use 'dir' to help optimise inode allocation */int ntfs_alloc_inode (ntfs_inode *dir, ntfs_inode *result, 		      const char *filename, int namelen, ntfs_u32 flags){	ntfs_io io;	int error;	ntfs_u8 buffer[2];	ntfs_volume* vol=dir->vol;	int byte,bit;	error=new_inode (vol,&(result->i_number));	if(error==ENOSPC){		error=ntfs_extend_mft(vol);		if(error)return error;		error=new_inode(vol,&(result->i_number));	}	if(error){		ntfs_error ("ntfs_get_empty_inode: no free inodes\n");		return error;	}	byte=result->i_number/8;	bit=result->i_number & 7;	io.fn_put = ntfs_put;	io.fn_get = ntfs_get;	io.param = buffer;	io.size=1;	/* set a single bit */	error=ntfs_read_attr(vol->mft_ino,vol->at_bitmap,0,byte,&io);	if(error)return error;	if(io.size!=1)		return EIO;	ntfs_set_bit (buffer, bit);	io.param = buffer;	io.size = 1; 	error = ntfs_write_attr (vol->mft_ino, vol->at_bitmap, 0, byte, &io);	if(error)return error;	if (io.size != 1)		return EIO;	/*FIXME: Should change MFT on disk	  error=ntfs_update_inode(vol->mft_ino);	  if(error)return error;	  */	/* get the sequence number */	io.param = buffer;	io.size = 2;	error = ntfs_read_attr(vol->mft_ino, vol->at_data, 0, 			       result->i_number*vol->mft_recordsize+0x10,&io);	if(error)		return error;	result->sequence_number=NTFS_GETU16(buffer)+1;	result->vol=vol;	result->attr=ntfs_malloc(vol->mft_recordsize);	if( !result->attr )		return ENOMEM;	result->attr_count=0;	result->attrs=0;	result->record_count=1;	result->records=ntfs_malloc(8*sizeof(int));	if( !result->records ) {		ntfs_free( result->attr );		result->attr = 0;		return ENOMEM;	}	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,flags);	if(error)		return error;	error=add_security(result,dir);	/*FIXME: check error */	return 0;}intntfs_alloc_file(ntfs_inode *dir, ntfs_inode *result, char *filename,		int namelen){	int error = ntfs_alloc_inode(dir,result,filename,namelen,0);	if(error)		return error;	error = add_data(result,0,0);	return error;}/* * Local variables: * c-file-style: "linux" * End: */

⌨️ 快捷键说明

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