home *** CD-ROM | disk | FTP | other *** search
Wrap
#include "part.h" struct boot_ms_dos { unsigned char jmp[3]; /* Must be 0xEB, 0x3C, 0x90 */ unsigned char sys_id[8]; /* Probably: "MSDOS5.0" */ unsigned short sect_size; /* Sector size in bytes (512) */ unsigned char clust_size; /* Sectors per cluster (1,2,4,...,128) */ unsigned short res_sects; /* Reserved sectors at the beginning */ unsigned char num_fats; /* Number of FAT copies (1 or 2) */ unsigned short root_entr; /* Root directory entries */ unsigned short total_sect; /* Total sectors (if less 64k) */ unsigned char media_desc; /* Media descriptor byte (F8h for HD) */ unsigned short fat_size; /* Sectors per fat */ unsigned short num_sects; /* Sectors per track */ unsigned short num_sides; /* Sides */ unsigned long hid_sects; /* Special hidden sectors */ unsigned long big_total; /* Big total number of sectors */ unsigned short drive_num; /* Drive number */ unsigned char ext_signat; /* Extended Boot Record signature (29h) */ unsigned long serial_num; /* Volume serial number */ unsigned char label[11]; /* Volume label */ unsigned char fs_id[8]; /* File system id */ unsigned char xcode[448]; /* Loader executable code */ unsigned short magic; /* Magic number (Must be 0xAA55) */ }; #define BBT_SIZE 16000 extern struct boot_ms_dos BOOT_FAT12, BOOT_FAT16; #define F_NORM 0 #define F_QUICK 1 #define F_DESTR 2 #define ROOT_SIZE (512/16) /* 512 entries in root directory 16/sector */ #define MAX_CLUST12 (4084) /* Maximum number of clusters in FAT12 system */ #define MAX_CLUST16 (65524) /* Maximum number of clusters in FAT16 system */ /* 0x01, "DOS FAT-12" */ /* 0x04, "DOS FAT-16 (<=32Mb)" */ /* 0x06, "BIGDOS FAT-16 (>=32Mb)" */ int format_fat(struct disk_info *dinfo, struct part_long *p, char **argv, int (*progress)(char*) ) { char tmp[60]; struct boot_ms_dos b; unsigned short int *fat; unsigned long num_clust, base_sect, base_clust, *bbt; int i, j, k, wr_sect, ret_code, fat_size, sys_type, next_bad; unsigned int num_bad=0; unsigned int clust_size=4; unsigned int form_type=F_NORM; #if 0 if( p->rel_sect==1008 ) /* I don't want to format my own disk by chance :) */ { progress("Are you crazy!!! This is your own hard disk!!!"); return FORMAT_FAILED; } #endif if( p->os_id!=0x06 && p->num_sect>65535L ) { progress(" Please choose BIGDOS file system for partitions greater than 32M. "); return FORMAT_FAILED; } if( p->num_sect<3+ROOT_SIZE+64 ) { progress(" Common! Partition is so small it isn't even funny. "); return FORMAT_FAILED; } while(*argv!=0) { if( strcmpi(*argv,"/destructive")==0 ) form_type=F_DESTR; else if( strcmpi(*argv,"/quick")==0 ) form_type=F_QUICK; else if( strncmpi(*argv,"/c:", 3)==0 ) { k=atoi((*argv)+3); for( i=k/2, j=0 ; i!=0 && j<7 ; j++, i/=2 ); clust_size=1<<j; if( clust_size!=k ) { progress("^Invalid cluster size."); return FORMAT_FAILED; } } else { progress("^Unknown option:"); progress(*argv); return FORMAT_FAILED; } argv++; } if( p->os_id==0x04 || p->os_id==0x06 ) /* FAT16 */ { while( clust_size<128 ) { if( 1+512+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST16 > p->num_sect) break; clust_size*=2; } fat_size = (p->num_sect-ROOT_SIZE-1+2*clust_size)/(clust_size*256+2)+1; num_clust = (p->num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size); memmove(&b,&BOOT_FAT16,512); sys_type=16; } if( p->os_id==0x01 || num_clust<MAX_CLUST12 ) /* FAT12 */ { while( clust_size<128 ) { if( 1+24+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST12 > p->num_sect ) break; clust_size*=2; } fat_size = (p->num_sect-ROOT_SIZE-1+2*clust_size)/((long)clust_size*512*2/3+2)+1; num_clust = (p->num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size); memmove(&b,&BOOT_FAT12,512); sys_type=12; } b.fat_size=fat_size; b.clust_size=clust_size; b.drive_num=dinfo->disk; b.num_sects=dinfo->num_sects; b.num_sides=dinfo->num_heads; b.hid_sects=p->rel_sect; b.big_total=p->num_sect; if( p->num_sect<65536L ) /* Not nessessary, really */ { b.big_total=0; b.total_sect=p->num_sect; } if( (bbt=malloc(BBT_SIZE*sizeof(long)))==0 ) { progress(ERROR_MALLOC); return FORMAT_FAILED; } if( (fat=malloc(6144))==0 ) /* (fat=malloc(256*sizeof(short)))==0 */ { progress(ERROR_MALLOC); free(bbt); return FORMAT_FAILED; } if( form_type==F_QUICK ) ret_code=0; else if( form_type==F_DESTR ) ret_code=generic_format(dinfo,p,BBT_SIZE,bbt,progress); else ret_code=generic_verify(dinfo,p,BBT_SIZE,bbt,progress); if( ret_code<0 ) /* format failed or canceled */ { free(bbt); free(fat); return ret_code; } num_bad=ret_code; disk_lock(dinfo->disk); progress("^Initializing file system ..."); if( num_bad!=0 && bbt[0] < 1+2*fat_size+ROOT_SIZE ) { progress("Beginning of the partition is unusable. Try to move it up."); goto FAILED; } progress("Writing boot sector ..."); if( disk_write_rel(dinfo,p,0,&b,1)==-1 ) /* Writing boot sector */ { progress("Error writing boot sector."); goto FAILED; } sleep(1); progress("Writing FAT tables ..."); wr_sect = 1; if( sys_type==16 ) { for( k=0 ; k<2 ; k++ ) /* Writing two copies of FAT16 */ { next_bad = 0; base_sect = 1 + 2*fat_size + ROOT_SIZE; for( i=0 ; i<fat_size ; i++ ) { memset(fat,0,512); if( i==0 ) { fat[0]=0xFFF8; fat[1]=0xFFFF; while(next_bad!=num_bad && bbt[next_bad]<base_sect+clust_size*254) fat[ (bbt[next_bad++]-base_sect)/clust_size+2 ]=0xFFF7; base_sect+=clust_size*254; } else { while(next_bad!=num_bad && bbt[next_bad]<base_sect+clust_size*256) fat[ (bbt[next_bad++]-base_sect)/clust_size ]=0xFFF7; base_sect+=clust_size*256; } if( disk_write_rel(dinfo,p,wr_sect++,fat,1)==-1 ) { progress("Error writing FAT."); goto FAILED; } } } }/* fat16 */ else /* Writing two copies of FAT12 */ { struct fat12 { unsigned c0:12; unsigned c1:12; } *fat12 = (struct fat12*)fat; memset(fat,0,6144); fat12[0].c0=0xFF8; fat12[0].c1=0xFFF; next_bad = 0; base_sect = 1 + 2*fat_size + ROOT_SIZE; while( next_bad!=num_bad ) { j=(bbt[next_bad++]-base_sect)/clust_size+2; if( j%2==0 ) fat12[j/2].c0=0xFF7; else fat12[j/2].c1=0xFF7; } for( k=0 ; k<2 ; k++ ) for( i=0 ; i<fat_size ; i++ ) if( disk_write_rel(dinfo,p,wr_sect++,fat+i*256,1)==-1 ) { progress("Error writing FAT."); goto FAILED; } }/* fat12 */ memset(fat,0,512); sleep(1); progress("Writing root directory ..."); for( i=0 ; i<ROOT_SIZE ; i++ ) if( disk_write_rel(dinfo,p,wr_sect++,fat,1)==-1 ) { progress("Error writing root directory."); goto FAILED; } sleep(1); disk_unlock(dinfo->disk); free(bbt); free(fat); return FORMAT_OK; FAILED: disk_unlock(dinfo->disk); free(bbt); free(fat); return FORMAT_FAILED; }/* format_fat */ int print_fat(struct disk_info *dinfo, struct part_long *p ) { int i; struct boot_ms_dos b; char tmp1[20], tmp2[20]; if( disk_read_rel(dinfo,p,0,&b,1)==-1 ) { fprintf(stderr,"Error reading boot sector.\n"); return -1; } printf("\n DOS Boot Sector Data Expected Value\n\n"); printf(" System id: %-.8s\n", b.sys_id ); printf(" Sector size: %-3d 512\n", b.sect_size ); printf(" Sectors per cluster: %d\n", b.clust_size ); printf("Reserved sectors at the beginning: %d\n", b.res_sects ); printf(" Number of FAT copies: %d\n", b.num_fats ); printf(" Root directory entries: %d\n", b.root_entr ); printf(" Total sectors on disk: %-5u %u\n", b.total_sect, (b.total_sect==0 || p->num_sect>65535L)?0:p->num_sect ); printf(" Media descriptor byte: %02Xh F8h\n", b.media_desc ); printf(" Sectors per FAT: %d\n", b.fat_size ); printf(" Sectors per track: %-2d %d\n", b.num_sects, dinfo->num_sects ); printf(" Number of sides: %-3d %d\n", b.num_sides, dinfo->num_heads ); printf("Hidden sectors prior to partition: %-10s %-10s\n", sprintf_long(tmp1,b.hid_sects), sprintf_long(tmp2,p->rel_sect) ); printf(" Big total number of sectors: %-10s %-10s\n", b.big_total==0?"0":sprintf_long(tmp1,b.big_total), (b.total_sect==0 || p->num_sect>65535L)?sprintf_long(tmp2,p->num_sect):"0" ); printf(" Drive number: %-3d %d\n", b.drive_num, dinfo->disk ); printf(" Extended boot record signature: %02Xh\n", b.ext_signat ); printf(" Volume serial number: %08lX\n", b.serial_num ); printf(" Volume label: %-.11s\n", b.label ); printf(" File system type: %-.8s %s\n", b.fs_id, (b.clust_size==0)?("?"):(p->num_sect/b.clust_size<4096?"FAT12":"FAT16") ); printf(" Boot sector magic number: 0%04Xh 0AA55h\n", b.magic ); return 0; }/* print_fat */