📄 s_fat16.c
字号:
#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_num; /* Magic number (Must be 0xAA55) */
};
#define BBT_SIZE 12000
#define F_NORM 0
#define F_QUICK 1
#define F_DESTR 2
#define ROOT_ENTR (512)
#define ROOT_SIZE (ROOT_ENTR/16)
#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 part_long *p, char **argv)
{
char *data_pool;
struct boot_ms_dos *b;
unsigned short int *fat;
int i, j, k, wr_sect, ret_code, fat_size, sys_type, next_bad;
unsigned long l, num_clust, u_num_sect, x_num_sect, base_sect, base_clust, *bbt;
unsigned int num_bad=0;
unsigned int clust_size=4;
unsigned int form_type=F_NORM;
if( (data_pool=malloc(SECT_SIZE+6144+BBT_SIZE*sizeof(long)))==0 )
{
show_error(ERROR_MALLOC);
return FAILED;
}
b = (struct boot_ms_dos*)(data_pool);
fat = (unsigned short*)(data_pool+SECT_SIZE);
bbt = (unsigned long*)(data_pool+SECT_SIZE+6144);
memmove(b,FAT_BOOT,SECT_SIZE);
memmove(b->sys_id,"MSDOS5.0",8);
b->sect_size=SECT_SIZE;
b->res_sects=1;
b->num_fats=2;
b->root_entr=ROOT_ENTR;
b->media_desc=0xF8;
b->ext_signat=0x29;
memmove(b->label,"NO NAME ",11);
b->magic_num=MBR_MAGIC_NUM;
u_num_sect=p->num_sect;
x_num_sect=p->num_sect;
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.");
goto failed;
}
}
else if( strncmpi(*argv,"/x:", 3)==0 )
{
if( strcmpi(*argv,"/x:disk")==0 )
l=dinfo.total_sects;
else
l=atol((*argv)+3);
if( l>x_num_sect ) x_num_sect=l;
}
else if( strncmpi(*argv,"/l:", 3)==0 )
{
strncpy(tmp,(*argv)+3,11);
tmp[11]=0;
for( i=0 ; tmp[i]!=0 && i<11 ; i++ ) b->label[i]=tmp[i];
for( ; i<11 ; i++ ) b->label[i]=' ';
}
else
{
progress("^Unknown option:");
progress(*argv);
goto failed;
}
argv++;
}
if( p->os_id==0x0400 || p->os_id==0x0600 || /* FAT16 */
p->os_id==0x1400 || p->os_id==0x1600 )
{
l=1+512+ROOT_SIZE+64L*MAX_CLUST16;
if( l<u_num_sect ) u_num_sect=l;
if( l<x_num_sect ) x_num_sect=l;
while( clust_size<64 )
{
if(1+512+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST16 > x_num_sect)
break;
clust_size*=2;
}
fat_size = (x_num_sect-ROOT_SIZE-1+2*clust_size)/(clust_size*256+2)+1;
num_clust = (x_num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size);
memmove(b->fs_id,"FAT16 ",8);
sys_type=16;
}
if( p->os_id==0x0100 || p->os_id==0x1100 || num_clust<MAX_CLUST12 )/* FAT12 */
{
l=1+512+ROOT_SIZE+64L*MAX_CLUST12;
if( l<u_num_sect ) u_num_sect=l;
if( l<x_num_sect ) x_num_sect=l;
while( clust_size<64 )
{
if( 1+24+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST12 > x_num_sect )
break;
clust_size*=2;
}
fat_size = (x_num_sect-ROOT_SIZE-1+2*clust_size)/((long)clust_size*512*2/3+2)+1;
num_clust = (x_num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size);
memmove(b->fs_id,"FAT12 ",8);
sys_type=12;
}
if( fat_size<0 || 1+2*fat_size+ROOT_SIZE+clust_size > p->num_sect )
{
progress("^Partition is too small.");
goto failed;
}
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->total_sect = (u_num_sect<65536L) ? u_num_sect : 0;
b->big_total = (u_num_sect<65536L) ? 0 : u_num_sect;
b->serial_num=((p->rel_sect<<16)+(p->num_sect*((long)b%451)) )+
((dinfo.total_sects%12345L)^(dinfo.total_sects*67891L))+
((dinfo.disk*123L)^(dinfo.num_heads%7))+clock();
flush_caches();
if( form_type==F_QUICK ) ret_code=0;
else if( form_type==F_DESTR )
ret_code=generic_format(p,BBT_SIZE,bbt);
else
ret_code=generic_verify(p,BBT_SIZE,bbt);
if( ret_code<0 ) /* format failed or canceled */
{
free(data_pool);
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 forward.");
goto failed;
}
progress("~Writing boot sector ...");
if( disk_write_rel(p,0,b,1)==-1 ) /* Writing boot sector */
{
progress("Error writing boot sector.");
goto failed;
}
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(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(p,wr_sect++,fat+i*256,1)==-1 )
{
progress("Error writing FAT.");
goto failed;
}
}/* fat12 */
memset(fat,0,512);
progress("~Writing root directory ...");
for( i=0 ; i<ROOT_SIZE ; i++ )
if( disk_write_rel(p,wr_sect++,fat,1)==-1 )
{
progress("Error writing root directory.");
goto failed;
}
disk_unlock(dinfo.disk);
free(data_pool);
return OK;
failed:
disk_unlock(dinfo.disk);
free(data_pool);
return FAILED;
}/* format_fat */
int format_embr(struct part_long *p, char **argv)
{
struct mbr *mbr=(struct mbr *)&tmp;
flush_caches();
disk_lock(dinfo.disk);
progress("^Initializing Extended DOS partition ...");
progress("~Writing Extended Master Boot Record ...");
memset(mbr,0,SECT_SIZE);
memmove(mbr->x.std.code, EMP_IPL, EMP_SIZE );
strncpy(mbr->x.std.code + EMP_SIZE, MESG_EXT_NONBOOT,
sizeof(mbr->x.std.code)-EMP_SIZE);
mbr->magic_num=MBR_MAGIC_NUM;
if( disk_write_rel(p,0,mbr,1)==-1 )
{
progress("Error Writing Extended Master Boot Record.");
disk_unlock(dinfo.disk);
return FAILED;
}
argv++; /* so compiler will not show warning */
disk_unlock(dinfo.disk);
return OK;
}/* format_embr */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -