📄 fat.c
字号:
}
if(j==0xff)
{
if(!_rmdir_(driver,lpszSecond))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
else if(j)
{
if(!_chdir_(driver,lpszSecond))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
break;
}
if(i==0xff||j==0xff) break;
}
return (DRIVER_INFO*)driver;
}
/**static BOOL read_one_cluster(INFO*driver,FILE*p,DWORD dwClusters)**********
功能:
读取一个簇到文件缓冲区中
入口:
DRIVER_INFO*driver:驱动器结构指针
FILE*p:文件指针
DWORD dwClusters:文件的簇号
出口:
无
调用者:
内部任意
备注:
dwCluster按照Microsoft的PDF,必须保证dwCluster>=2
******************************************************************************************/
static BOOL read_one_cluster(DRIVER_INFO* driver,FILE*p,DWORD dwClusters)
{
BYTE*ptr;
DWORD dwStart;
DWORD dwEnd;
if(!driver||dwClusters<2) return 0;
dwStart=get_first_sector_of_cluster(driver,dwClusters);
dwEnd=dwStart+driver->dwSectorsPerCluster;
ptr=p->lpszBuffers;
for(;dwStart<dwEnd;dwStart++)
{
if(!driver->lpfnRead(dwStart,ptr,driver->dwBytesPerSector,driver->user_data))
return 0;
ptr+=driver->dwBytesPerSector;
}
return 1;
}
/**static BOOL write_one_cluster(DRIVER_INFO*driver,FILE*p,DWORD dwClusters)**********
功能:
把文件缓冲区内容写到一个簇中
入口:
DRIVER_INFO*driver:逻辑驱动器结构指针
FILE*p:文件指针
DWORD dwClusters:文件的簇号
出口:
无
调用者:
内部任意
备注:
dwCluster按照Microsoft的PDF,必须保证dwCluster>=2
******************************************************************************************/
static BOOL write_one_cluster(DRIVER_INFO* driver,FILE*p,DWORD dwClusters)
{
BYTE*ptr;
DWORD dwStart;
DWORD dwEnd;
if(!driver||dwClusters<2) return 0;
dwStart=get_first_sector_of_cluster(driver,dwClusters);
dwEnd=dwStart+driver->dwSectorsPerCluster;
ptr=p->lpszBuffers;
for(;dwStart<dwEnd;dwStart++)
{
#if(MUST_ERASE_BEFORE_WRITE==1)
if(!driver->lpfnErase(dwStart,driver->dwBytesPerSector,driver->user_data))
return 0;
#endif
if(!driver->lpfnWrite(dwStart,ptr,driver->dwBytesPerSector,driver->user_data))
return 0;
ptr+=driver->dwBytesPerSector;
}
return 1;
}
/**static DRIVER_INFO*get_free_driver()*******************************************
功能:
获取空闲的驱动器指针
入口:
无
出口:
调用成功返回有效的驱动器指针,否则返回NULL
调用者:
任意
备注:
无
********************************************************************************/
static DRIVER_INFO*get_free_driver()
{
DWORD i;
for(i=0;i<MAX_DRIVERS_NUMBER;i++)
{
if(drivers[i]) continue;
drivers[i]=(DRIVER_INFO*)SYS_malloc(sizeof(DRIVER_INFO));
if(!drivers[i]) break;
SYS_memset(drivers[i],0,sizeof(DRIVER_INFO));
drivers[i]->lpLinks=(LINK*)SYS_malloc(sizeof(LINK));
if(!drivers[i]->lpLinks)
{
SYS_free(drivers[i]);
drivers[i]=(DRIVER_INFO*)0;
return (DRIVER_INFO*)0;
}
drivers[i]->lpLinks->prev=(void*)0;
drivers[i]->lpLinks->next=(void*)0;
drivers[i]->lpLinks->name[0]=START_DRIVER_LABLE+i;
drivers[i]->lpLinks->name[1]=':';
drivers[i]->lpLinks->name[2]=0;
drivers[i]->lpCurrentDir=drivers[i]->lpLinks;
drivers[i]->DriverName=START_DRIVER_LABLE+i;
return (DRIVER_INFO*)drivers[i];
}
return (DRIVER_INFO*)0;
}
/**static BOOL parse_master_patrition(DWORD dwStart,DWORD dwOffset,DRIVER_INFO*driver)****************************************************************
功能:
主分区参数读取和计算
入口:
DWORD dwStart:本分区开始扇区(相对于0扇区)
DWORD dwOffset:本分区开始计算的扇区数(相对于0扇区或者ext分区0扇区)
DRIVER_INFO*driver:驱动器结构指针
出口:
成功返回1,否则返回0
调用者:
FAT_install()
备注:
无
************************************************************************************************************************************/
static BOOL parse_master_partition(DWORD dwStart,DWORD dwOffset,DRIVER_INFO*driver)
{
BYTE*lpszSectors;
BYTE*info;
BYTE i,bClear;
BYTE NONAME[]="NO NAME ";
WORD BPB_BytsPerSec=0,BPB_RsveSecCnt=0,BPB_RootEntCnt=0,BPB_TotSec16=0,BPB_FATSz16=0,BPB_SecPerTrk=0;
WORD BPB_NumHeads=0;
DWORD BPB_HiddSec=0,BPB_TotSec32=0,BPB_FATSz32=0;
DWORD dwRootClus=0;
BYTE BPB_SecPerClus=0,BPB_NumFATs=0,BPB_Media=0;
if(!driver) return 0;
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(!lpszSectors) return 0;
if(!driver->lpfnRead(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data)) return 0;
info=lpszSectors;
info+=11;
BPB_BytsPerSec=GETWORD(info);
BPB_SecPerClus=*info++;
BPB_RsveSecCnt=GETWORD(info);
BPB_NumFATs=*info++;
BPB_RootEntCnt=GETWORD(info);
BPB_TotSec16=GETWORD(info);
BPB_Media=*info++;
BPB_FATSz16=GETWORD(info);
BPB_SecPerTrk=GETWORD(info);
BPB_NumHeads=GETWORD(info);
BPB_HiddSec=GETDWORD(info);
BPB_TotSec32=GETDWORD(info);
driver->dwNumFATs=BPB_NumFATs;
driver->bFAT32=BPB_FATSz16==0;
if(driver->bFAT32)/*如果是FAT32文件系统*/
{
BPB_FATSz32=GETDWORD(info);
info+=4;
dwRootClus=GETDWORD(info);/*根目录开始簇号,一般是2,但不一定是2*/
info+=19;
driver->dwVOLID=GETDWORD(info);
bClear=1;
for(i=0;i<11;i++)
{
driver->VolLable[i]=*info++;
if(driver->VolLable[i]!=NONAME[i]) bClear=0;
}
if(bClear) i=0;
driver->VolLable[i]=0;
FAT2DOS(driver->VolLable,0);
driver->dwFATsZ=BPB_FATSz32;
}
else
{
info+=3;
driver->dwVOLID=GETDWORD(info);
bClear=1;
for(i=0;i<11;i++)
{
driver->VolLable[i]=*info++;
if(driver->VolLable[i]!=NONAME[i]) bClear=0;
}
if(bClear) i=0;
driver->VolLable[i]=0;
FAT2DOS(driver->VolLable,0);
driver->dwFATsZ=BPB_FATSz16;
}
driver->dwBytesPerSector=BPB_BytsPerSec;
driver->dwSectorsPerCluster=BPB_SecPerClus;
/*开始计算参数*/
driver->dwHideSectorStart=dwOffset;
driver->dwReservedSectorStart=dwStart;
dwStart+=BPB_RsveSecCnt;
for(i=0;i<BPB_NumFATs&&i<2;i++)
{
driver->dwFATSectorStart[i]=dwStart;
if(driver->bFAT32)
dwStart+=BPB_FATSz32;
else
dwStart+=BPB_FATSz16;
}
if(!driver->bFAT32)
driver->dwRootSectorStart=dwStart;
dwStart+=((BPB_RootEntCnt<<5)+(BPB_BytsPerSec-1))/BPB_BytsPerSec;
driver->dwDataSectorStart=dwStart;
if(driver->bFAT32)
driver->dwRootSectorStart=get_first_sector_of_cluster(driver,dwRootClus);
driver->lpCurrentDir->dwSectors=driver->dwRootSectorStart;
driver->dwTotalClusters=((BPB_FATSz32?BPB_FATSz32:BPB_FATSz16)*driver->dwBytesPerSector)/(driver->bFAT32?4:2);
driver->dwFreeClusters=get_total_free_clusters(driver);
if(!thisDriver) thisDriver=driver;
return 1;
}
#if(SUPPORT_EXT_PARTITION==1)
static BYTE parse_ext_partition(DWORD dwStart/*MBR开始扇区*/,DWORD dwBytesPerSector,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)
{
BYTE*lpszSectors;
BYTE*info;
BYTE i;
DWORD dwTotalDisk=0;
DRIVER_INFO*driver;
lpszSectors=(BYTE*)SYS_malloc(dwBytesPerSector);
if(!lpszSectors) return 0;
if(!lpfnRead(dwStart,lpszSectors,dwBytesPerSector,user_data))
return 0;
info=&lpszSectors[dwBytesPerSector-2-64];
for(i=0;i<4;i++)
{
info+=4;
switch(*info)
{
case 0x04:
case 0x06:
case 0x0b:
case 0x0c:
case 0x0e:
info+=4;
if(!(driver=get_free_driver()))
{
return dwTotalDisk;
}
driver->lpfnErase=lpfnErase;
driver->lpfnRead=lpfnRead;
driver->lpfnWrite=lpfnWrite;
driver->user_data=user_data;
driver->dwBytesPerSector=dwBytesPerSector;
driver->dwReservedSectorStart=GETDWORD(info);
info+=4;
dwTotalDisk+=parse_master_partition(driver->dwReservedSectorStart,0x0000,driver);
break;
case 0x05:
case 0x0f:
info+=4;
dwStart=GETDWORD(info);
info+=4;
dwTotalDisk+=parse_ext_partition(dwStart,dwBytesPerSector,lpfnErase,lpfnRead,lpfnWrite,user_data);
break;
default:
info+=12;
}
}
SYS_free(lpszSectors);
return dwTotalDisk;
}
#endif
/**static DWORD detect_bytes_per_sector(SECTOR_READ lpfnRead,void *user_data)******************************
功能:
自动检测每扇区字节数
入口:
SECTOR_READ lpfnRead:扇区读指针
void*user_data:用户数据指针
出口:
成功返回每扇区字节数,否则返回0
调用者:
FAT_install()
备注:
仅仅支持512,1024和2048 3种类型(实际上一般是512)
******************************************************************************************************/
static DWORD detect_bytes_per_sector(SECTOR_READ lpfnRead,void *user_data)
{
BYTE*buff;
buff=(BYTE*)SYS_malloc(2048);
if(!buff) return 0;
if(lpfnRead(0x0000,buff,512,user_data))
{
if(buff[510]!=0x55||buff[511]!=0xaa)
{
if(lpfnRead(0x0000,buff,1024,user_data))
{
if(buff[1022]!=0x55||buff[1023]!=0xaa)
{
if(lpfnRead(0x0000,buff,2048,user_data))
{
if(buff[2046]!=0x55||buff[2047]!=0xaa)
{
SYS_free(buff);
return 0x00;
}
SYS_free(buff);
return 2048;
}
}
SYS_free(buff);
return 1024;
}
}
SYS_free(buff);
return 512;
}
SYS_free(buff);
return 0;
}
#if (SUPPORT_FORMAT==1)
typedef struct
{
DWORD dwDiskSize;
DWORD SecPerCluster;
}CLUSTER_INFO;
static DRIVER_INFO*calc_driver_info(BOOL bFAT32,DWORD dwStart,DWORD dwDiskSize,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)
{
BYTE sector_per_cluster=0;
DWORD i;
DWORD BPB_Total;
DWORD FATsZ;
DWORD dwFreeClusters;
CLUSTER_INFO FAT16[]=
{
{720,1},/*360K以上采用0.5K cluster*/
{32768,2},/*16M以上采用1K cluster*/
{262144,4},/*128M以上采用2K Cluster*/
{524288,8},/*256M以上采用4K cluster*/
{1048576,16},/*512M以上采用8K cluster*/
{2097152,32},/*1G以上采用16K cluster*/
{4194304,64},/*2G以上采用32K cluster*/
{0xffffffff,0},
};
CLUSTER_INFO FAT32[]=
{
#if 1
{65536,1},/*32M以下,必须使用FAT16*/
#else
{524288,1},/*32M-256M,用0.5K cluster*/
#endif
{16777216,8},/*8G以内,用4K cluster*/
{33554432,16},/*16G以内,用8K cluster*/
{67108864,32},/*32G以内,用16K cluster*/
{0xffffffff,0},
};
DRIVER_INFO*driver;
if(bFAT32)
{
if(dwDiskSize<65536) bFAT32=0;
else
{
for(i=0;i<sizeof(FAT32)-1;i++)
{
if(dwDiskSize>=FAT32[i].dwDiskSize&&dwDiskSize<FAT32[i+1].dwDiskSize)
{
sector_per_cluster=FAT32[i].SecPerCluster;
break;
}
}
}
}
if(!bFAT32)
{
if(dwDiskSize<720) return (DRIVER_INFO*)0;
for(i=0;i<sizeof(FAT16)-1;i++)
{
if(dwDiskSize>=FAT16[i].dwDiskSize&&dwDiskSize<FAT16[i+1].dwDiskSize)
{
sector_per_cluster=FAT16[i].SecPerCluster;
break;
}
}
}
if(sector_per_cluster==0x00) return (DRIVER_INFO*)0;
BPB_Total=dwDiskSize-DEFAULT_RESERVED_SECTORS-DEFAULT_ROOT_ENTRY*sector_per_cluster;
BPB_Total=BPB_Total/(DWORD)(((bFAT32?8.0:4.0)/(sector_per_cluster+2)/DEFAULT_BYTES_PER_SECTOR+1));
dwFreeClusters=BPB_Total/sector_per_cluster;
FATsZ=((dwFreeClusters+2)*(bFAT32?4:2))/DEFAULT_BYTES_PER_SECTOR;
driver=(DRIVER_INFO*)get_free_driver();
if(driver)
{
driver->dwBytesPerSector=DEFAULT_BYTES_PER_SECTOR;
driver->dwSectorsPerCluster=sector_per_cluster;
driver->dwReservedSectorStart=dwStart;
driver->dwFATSectorStart[0]=dwStart+DEFAULT_RESERVED_SECTORS;
driver->dwFATSectorStart[1]=driver->dwFATSectorStart[0]+FATsZ;
driver->dwRootSectorStart=driver->dwFATSectorStart[1]+FATsZ;
if(!bFAT32)
driver->dwDataSectorStart=driver->dwRootSectorStart+DEFAULT_ROOT_ENTRY*sector_per_cluster;
else
driver->dwDataSectorStart=driver->dwRootSectorStart;
driver->dwFreeClusters=dwFreeClusters;
driver->dwNumFATs=2;
driver->user_data=user_data;
driver->bFAT32=bFAT32;
driver->dwHideSectorStart=0x00000;
driver->dwFATsZ=FATsZ;
driver->dwTotalClusters=BPB_Total/sector_per_cluster;
driver->lpfnErase=lpfnErase;
driver->lpfnWrite=lpfnWrite;
driver->lpfnRead=(SECTOR_READ)lpfnRead;
driver->VolLable[0]=0;
}
return driver;
}
/**BOOL FAT_format(DRIVER_INFO*driver,BOOL bFAT32,DWORD dwStartSector,DWORD dwDiskSize,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)***************************************************************************************
功能:
格式化一个逻辑驱动器
入口:
DRIVER_INFO*driver:逻辑驱动器指针
BOOL bFAT32:是否使用FAT32格式化
DWORD dwStartSector:开始扇区号
DWORD dwDiskSize:磁盘大小,单位是sectors
SECTOR_ERASE lpfnErase:扇区擦除函数
SECTOR_WRITE lpfnWrite:扇区写函数
void*user_data:用户数据指针
出口:
调用成功返回1,否则返回0
调用者:
任意
备注:
两种使用方法:
1.driver!=NULL,则忽略dwStartSector和dwDiskSize,使用driver的内部数据进行格式化(如一个驱动器被正常装载后有有效的数据,就可以用这方法,该方法不会改变任何参数)
2.driver==NULL,则FAT_format()利用后两个参数dwStartSector,dwDiskSize计算适当的参数(利用默认值)
*****************************************************************************************************************************************************************/
BOOL FAT_format(DRIVER_INFO*that,BOOL bFAT32,DWORD dwStartSector,DWORD dwDiskSize,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)
{
BYTE i;
DWORD j;
FAT_DATE fdate;
FAT_TIME ftime;
DWORD dwStart,dwEnd;
DRIVER_INFO*driver=that;
BYTE DBR[]=
{
0xeb,0x58,0x90,0x4d,0x53,0x44,0x4f,0x53,0x35,0x2e,0x30,0x00,0x02,0x04,0x22,0x00,
0x02,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x3f,0x00,0xff,0x00,0x00,0x00,0x00,0x00,
0x00,0xc4,0x07,0x00,0xdf,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x29,0xed,0x55,0x0b,0xe8,0x4e,0x4f,0x20,0x4e,0x41,0x4d,0x45,0x20,0x20,
0x20,0x20,0x46,0x41,0x54,0x33,0x32,0x20,0x20,0x20,0x33,0xc9,0x8e,0xd1,0xbc,0xf4,
0x7b,0x8e,0xc1,0x8e,0xd9,0xbd,0x00,0x7c,0x88,0x4e,0x02,0x8a,0x56,0x40,0xb4,0x08,
0xcd,0x13,0x73,0x05,0xb9,0xff,0xff,0x8a,0xf1,0x66,0x0f,0xb6,0xc6,0x40,0x66,0x0f,
0xb6,0xd1,0x80,0xe2,0x3f,0xf7,0xe2,0x86,0xcd,0xc0,0xed,0x06,0x41,0x66,0x0f,0xb7,
0xc9,0x66,0xf7,0xe1,0x66,0x89,0x46,0xf8,0x83,0x7e,0x16,0x00,0x75,0x38,0x83,0x7e,
0x2a,0x00,0x77,0x32,0x66,0x8b,0x46,0x1c,0x66,0x83,0xc0,0x0c,0xbb,0x00,0x80,0xb9,
0x01,0x00,0xe8,0x2b,0x00,0xe9,0x48,0x03,0xa0,0xfa,0x7d,0xb4,0x7d,0x8b,0xf0,0xac,
0x84,0xc0,0x74,0x17,0x3c,0xff,0x74,0x09,0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,
0xee,0xa0,0xfb,0x7d,0xeb,0xe5,0xa0,0xf9,0x7d,0xeb,0xe0,0x98,0xcd,0x16,0xcd,0x19,
0x66,0x60,0x66,0x3b,0x46,0xf8,0x0f,0x82,0x4a,0x00,0x66,0x6a,0x00,0x66,0x50,0x06,
0x53,0x66,0x68,0x10,0x00,0x01,0x00,0x80,0x7e,0x02,0x00,0x0f,0x85,0x20,0x00,0xb4,
0x41,0xbb,0xaa,0x55,0x8a,0x56,0x40,0xcd,0x13,0x0f,0x82,0x1c,0x00,0x81,0xfb,0x55,
0xaa,0x0f,0x85,0x14,0x00,0xf6,0xc1,0x01,0x0f,0x84,0x0d,0x00,0xfe,0x46,0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -