?? mkntfs.c
字號:
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 + -