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

📄 mkntfs.c

📁 一个linux下NTFS文件格式源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	ntfs_update_inode( mirr_ino ); 	/* read critical MFT entries and write to MFTMirr */	mirror_data = malloc( attr->allocated );	io.size = attr->allocated;	io.param = mirror_data; io.fn_get = ntfs_get; io.fn_put = ntfs_put;	ntfs_read_attr( mft_ino, ATTR_DATA, NULL, 0, &io );	io.param = mirror_data;		ntfs_write_attr( mirr_ino, ATTR_DATA, NULL, 0, &io );	free( mirror_data );	ntfs_update_inode( mirr_ino );	add_root_ent( "$MFTMirr", mirr_ino );	free( mirr_ino );}void init_empty( char *name, int inum ){	ntfs_attribute *attr;	ntfs_inode *ino;	ino = add_mft_entry( inum );	ntfs_create_attr( ino, ATTR_DATA, NULL, NULL, 0, &attr );	ntfs_update_inode( ino );	add_root_ent( name, ino );	free( ino );}void init_root( void ){	/* make new MFT record */	root_ino = add_mft_entry( FILE_ROOT );	/* do dir stuff */	root_ino->attr[0x16] |= 2;	/* is directory */	ntfs_add_index_root( root_ino, ATTR_FILE_NAME );	/* flush to disk */	verbose( "Adding root directory (indexed on type 0x%x, inode %d)...",		ATTR_FILE_NAME, FILE_ROOT );	ntfs_update_inode( root_ino );	verbose( "done.\n" );	/* add entries */	add_root_ent( ".", root_ino );	add_root_ent( "$MFT", mft_ino );	add_root_ent( "$Boot", boot_ino );}	void init_bitmap( void ){	ntfs_attribute *attr;	ntfs_inode *bitmap_ino;		long dev_clusters;	ntfs_runlist *rl;	ntfs_cluster_t location; 	/* these two for ntfs_alloc_clust */	int count;		/* make new MFT record */	bitmap_ino = add_mft_entry( FILE_BITMAP );	/* create the attribute */	ntfs_create_attr( bitmap_ino, ATTR_DATA, NULL, NULL, 0, &attr );	dev_clusters = dev_size / ( cluster_size / 512 ); /* num clusters */	verbose( "%ld clusters on device, %ld bytes wasted.\n",		dev_clusters, ( dev_size - ( dev_clusters * ( cluster_size /		512 ) )  ) * 512 );	attr->resident = 0;	attr->initialized = attr->size = ( dev_clusters + 7 ) / 8;	attr->allocated = ( ( attr->size + cluster_size - 1 ) / cluster_size )		* cluster_size;	rl = ntfs_malloc( sizeof( ntfs_runlist ) );	rl->len = attr->allocated / cluster_size;	rl->cluster = mftmirr_lcn - rl->len;	/* bitmap before MFT mirror */	attr->d.r.runlist = rl; attr->d.r.len = 1;	verbose( "Allocated %d clusters (%d bytes) for bitmap at LCN %d\n",		rl->len, attr->allocated, rl->cluster );	/* flush to disk */	ntfs_update_inode( bitmap_ino );	/* now we have a bitmap inode, update struct */	vol->bitmap = bitmap_ino;	/* clear bitmap */	ntfs_deallocate_clusters( vol, 0, dev_clusters );	/* allocate cluster ranges we've used already */	location = 0; count = 1;	/* boot cluster */	ntfs_allocate_clusters( vol, &location, &count, ALLOC_REQUIRE_LOCATION |		ALLOC_REQUIRE_SIZE );	location = mft_lcn; count = 0x10 * file_rec_size; /* MFT */	ntfs_allocate_clusters( vol, &location, &count,		 ALLOC_REQUIRE_LOCATION | ALLOC_REQUIRE_SIZE );	location = mftmirr_lcn - rl->len; count = rl->len; /* bmap */	ntfs_allocate_clusters( vol, &location, &count,		ALLOC_REQUIRE_LOCATION | ALLOC_REQUIRE_SIZE );	location = mftmirr_lcn; count = file_rec_size * 4; /* MFT mirror */	ntfs_allocate_clusters( vol, &location, &count,		ALLOC_REQUIRE_LOCATION | ALLOC_REQUIRE_SIZE );	add_root_ent( "$Bitmap", vol->bitmap );}		int write_empty_mft( void ){	char *mftent;	int rc;	int attr_off;	char *attrs, *rl;	char mftbmap[2] = { 0xff, 0xff };	ntfs_attribute *attr;	int i;	ntfs_io io;	mftent = calloc( file_rec_size, cluster_size );		/* initialise MFT entry 0 */	ntfs_fill_mft_header( (ntfs_u8 *)mftent, file_rec_size * cluster_size,		cluster_size, 0 );	attr_off = NTFS_GETU16( mftent+0x14 );		/* offset of attribs */	attrs = mftent + attr_off;			/* location of attrs */	/* insert $DATA attribute */	/* all this palaver is probably not needed - can we just leap in and		call Martin's routines straight away? */	NTFS_PUTU32( attrs, ATTR_DATA );		/* type */	NTFS_PUTU32( attrs + 0x4, 0x49 );		/* length */	NTFS_PUTU8( attrs + 0x8, 0x01 );		/* not resident */	NTFS_PUTU8( attrs + 0x9, 0x00 );		/* name len = 0 */	NTFS_PUTU16( attrs + 0xA, 0x40 );		/* offset to content */	NTFS_PUTU16( attrs + 0xC, 0x0000 );		/* not compressed */	NTFS_PUTU16( attrs + 0xE, 0x0000 );		/* huh? */	NTFS_PUTU64( attrs + 0x10, 0x0 );		/* starting VCN */	NTFS_PUTU64( attrs + 0x18, 0x0 );		/* ending VCN */	NTFS_PUTU16( attrs + 0x20, 0x40 );		/* offset to run list */	NTFS_PUTU16( attrs + 0x22, 0x0000 );		/* no cengine */	NTFS_PUTU64( attrs + 0x28, 0x10 * file_rec_size *		cluster_size );				/* we contain 16 file rec */	NTFS_PUTU64( attrs + 0x30, 0x10 * file_rec_size *		cluster_size );				/* real size as above */	NTFS_PUTU64( attrs + 0x38, 0x10 * file_rec_size *		cluster_size 	);			/* init size as above */		verbose( "Initial MFT size is 16 records (%d clusters, %d bytes)\n",			0x10 * file_rec_size, 0x10 * file_rec_size * cluster_size );	/* name + run list start at 0x40 from attr start */	rl = attrs + 0x40;	NTFS_PUTU8( rl, 0x44 );				/* sizeof(off,len)=4 */	NTFS_PUTU32( rl + 0x1, 0x10 * file_rec_size );	NTFS_PUTU32( rl + 0x5, mft_lcn );		/* 1st LCN of run */		attrs = rl + 0x09;	verbose( "$MFT data attribute (type 0x%x) run at LCN %d, length %d\n",		ATTR_DATA, mft_lcn, 0x10 * file_rec_size );	/* mark end of attribs */	NTFS_PUTU32( attrs, 0xffffffff );	ntfs_insert_fixups( (unsigned char*)mftent, sector_size );	verbose( "Writing bootstrap MFT entry... " );	lseek( fd, mft_lcn * cluster_size, SEEK_SET );	write( fd, mftent, file_rec_size * cluster_size );	verbose( "done.\n" );	/* now things are initialised enough to hand over to Martin's		routines - phew */	vol->mft = mftent;	mft_ino = (ntfs_inode *)ntfs_malloc( sizeof( ntfs_inode ) );	rc = ntfs_init_inode( mft_ino, vol, FILE_MFT );	vol->mft_ino = mft_ino;	if( rc ) {		fprintf( stderr, "Couldn't init inode for $MFT: %s\n",			strerror( rc ) );		return rc;	}	/* insert the bitmap attribute */	ntfs_create_attr( mft_ino, ATTR_BITMAP, NULL, &mftbmap, 2, &attr );	/* write out null MFT entries for slots 1-15 */	verbose( "Writing 15 (0xf) empty MFT entries " );	for( i = 1; i < 16; i++ ) {			ntfs_fill_mft_header( (ntfs_u8 *)mftent,			file_rec_size * cluster_size, cluster_size, 0 );		io.fn_get = ntfs_get; io.fn_put = ntfs_put;		io.size = file_rec_size * cluster_size;		io.param = mftent;		ntfs_write_attr( mft_ino, ATTR_DATA, NULL, file_rec_size *			cluster_size * i, &io );		verbose( "." );	}	verbose( " done.\n" );			/* commit MFT entry */	verbose( "Flushing MFT info to disk... " );	ntfs_update_inode( mft_ino );	verbose( "done\n" );	return 0;}		void write_boot( void ){	char *bootblk;	bootblk = calloc( cluster_size, 1 );		NTFS_PUTU32( bootblk+3, *(int *)"NTFS" );	/* signature */	NTFS_PUTU16( bootblk+0xb, sector_size );	/* sector size */	NTFS_PUTU8( bootblk+0xd, cluster_size /		/* sectors per cluster */		sector_size );	NTFS_PUTU8( bootblk+0x15, 0xf8 );		/* media descriptor */	NTFS_PUTU16( bootblk+0x18, sect_per_trk );	/* sectors per track */	NTFS_PUTU16( bootblk+0x1a, heads );		/* no. of heads */	NTFS_PUTU16( bootblk+0x24, 0x0080 );		/* ??? */	NTFS_PUTU16( bootblk+0x26, 0x0080 );		/* ??? */	NTFS_PUTU64( bootblk+0x28, dev_size *		( sector_size / 512 ) );		/* device size (sectors) */	NTFS_PUTU64( bootblk+0x30, mft_lcn );		/* LCN of MFT */	NTFS_PUTU64( bootblk+0x38, mftmirr_lcn );	/* LCN of mirror of MFT */	NTFS_PUTU32( bootblk+0x40, file_rec_size );	/* len of FILE record */	NTFS_PUTU32( bootblk+0x44, indx_buf_size );	/* len of INDX buffer */	NTFS_PUTU32( bootblk+0x48, 0x0f000f00 );	/* volume serial num */	NTFS_PUTU16( bootblk+0x1fe, 0xaa55 );		/* boot sector magic */		/* copy to end of boot cluster */	if( cluster_size - 0x200 >= 0x200 ) {		memcpy( bootblk + cluster_size - 0x200, bootblk, 0x200 );		verbose( "Boot block info duplicated at offset 0x%x\n",			 cluster_size - 0x200 );	}		verbose( "Writing boot block... " );	lseek( fd, 0, SEEK_SET );	/* seek to cluster 0 */	write( fd, bootblk, cluster_size );	verbose( "done.\n" );	/* init volume info */	vol = (ntfs_volume *)ntfs_malloc( sizeof( ntfs_volume ) );	ntfs_init_volume( vol, bootblk );	NTFS_FD(vol) = fd;	free( bootblk );}	char *short_opts="hVs:u:t:H:n:cvl:";#ifdef HAVE_GETOPT_Hstruct option options[]={	{"help",0,0,'h'},	{"version",0,0,'V'},	{"sectsize",1,0,'s'},	{"clustersize",1,0,'u'},	{"tracksize",1,0,'t'},	{"heads",1,0,'H'},	{"label",1,0,'n'},	{0,0,0,0}};#endifstatic char const rcsid[] = "$Id: mkntfs.c,v 1.1 1999/04/11 18:32:49 martin Exp $";char usage_str[]="\nmkntfs " NTFS_VERSION "\n""Usage: mkntfs [-cv] [-s sectsize] [-u clustersize] [-t sectors] [-H heads] \\\n""		[-n label] [-l filename] device\n""       mkntfs [-hV]\n""  --sectsize, -s <n>\t\tSector size of media, default 512\n""  --clustersize, -u <n>\t\tCluster size of new filesystem, default varies\n""  --tracksize, -t <n>\t\tSectors per track, no default\n""  --heads, -H <n>\t\tNumber of heads, no default\n""  --label, -n <s>\t\tVolume label, no default\n""  -c\t\t\t\tCheck the device for bad blocks first\n""  -v\t\t\t\tVerbose output\n""  -l <s>\t\t\tFile from which to read list of bad blocks\n""  --help, -h\t\t\tDisplay this message\n""  --version, -V\t\t\tDisplay version number\n""\n";void usage(void){	fprintf(stderr,usage_str);}int main(int argc,char *argv[]){	int c;	char *device=0;	opterr=1;	while((c=getopt_long(argc,argv,short_opts,options,NULL))>0)		switch(c) {		case 'u': cluster_size=strtol(optarg,NULL,0);break;		case 's': sector_size=strtol(optarg,NULL,0);break;		case 't': sect_per_trk=strtol(optarg,NULL,0);break;		case 'n': vol_label=optarg;break;		case 'h': usage();exit(0);break;		case 'V': printf("mkntfs " NTFS_VERSION "\n\t%s\n",rcsid);exit(0);break;		case 'c':		case 'l':			fprintf( stderr, "Sorry -c and -l not yet supported.\n" );			exit(1);			break;		case 'v': verbose_flag = 1; break;		default: usage();exit(1);		}	if( argc - optind != 1 ) {		usage(); exit(1);	}	device=argv[optind];	fd = open( device, O_RDWR );	if( fd == -1 ) {		fprintf( stderr, "Couldn't open %s: %s\n", device,			strerror(errno) );		exit( 2 );	}		printf( "\n" );	get_blkdev_info();	/* get device info, calculate `things' */	write_boot();		/* write boot cluster based on above info */	write_empty_mft();	/* initialise the MFT */	add_boot_file();	/* add an MFT record for the boot cluster */	init_root();		/* initialise the root directory */	init_bitmap();		/* initialise the volume bitmap */	init_volume();		/* initialise the volume info */	init_attrdef();		/* initialise attribute list */	init_empty( "$LogFile", FILE_LOGFILE );	init_empty( "$BadClus", FILE_BADCLUS );	init_empty( "$Quota", FILE_QUOTA );	init_empty( "$UpCase", FILE_UPCASE );	init_mftmirr();		/* make copy of important MFT records:				   do this last */	close( fd );	free( mft_ino );	free( vol->mft );	free( vol );	verbose( "\n" );	return 0;}

⌨️ 快捷键说明

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