📄 fat_ioct.c
字号:
}
#if (FS_FAT_NOFAT32==0)
else {
/* FAT32 */
/* FATSz32 */
buffer[36] = (char)(bpb.FATSz32 & 0xff);
buffer[37] = (char)((FS_u32)(bpb.FATSz32 & 0x0000ff00UL) >> 8);
buffer[38] = (char)((FS_u32)(bpb.FATSz32 & 0x00ff0000UL) >> 16);
buffer[39] = (char)((FS_u32)(bpb.FATSz32 & 0xff000000UL) >> 24);
/* EXTFlags */
buffer[40] = (char)(bpb.ExtFlags & 0xff);
buffer[41] = (char)((unsigned int)(bpb.ExtFlags & 0xff00) >> 8);
/* FSVer = 0:0 */
buffer[42] = 0x00;
buffer[43] = 0x00;
/* RootClus */
buffer[44] = (char)(bpb.RootClus & 0xff);
buffer[45] = (char)((FS_u32)(bpb.RootClus & 0x0000ff00UL) >> 8);
buffer[46] = (char)((FS_u32)(bpb.RootClus & 0x00ff0000UL) >> 16);
buffer[47] = (char)((FS_u32)(bpb.RootClus & 0xff000000UL) >> 24);
/* FSInfo */
buffer[48] = (char)(bpb.FSInfo & 0xff);
buffer[49] = (char)((unsigned int)(bpb.FSInfo & 0xff00) >> 8);
/* BkBootSec = 0x0006; */
buffer[50] = 0x06;
buffer[51] = 0x00;
/* Reserved */
for (i = 52; i < 64; i++) {
buffer[i] = (char)0x00;
}
/* DrvNum = 0x00 (floppy) */
buffer[64] = (char)0x00;
/* Reserved1 = 0x00 (floppy) */
buffer[65] = (char)0x00;
/* BootSig = 0x00 (next three fields are not 'present') */
buffer[66] = (char)0x00;
/* VolID = 0x00000000 (serial number, e.g. date/time) */
for (i = 67; i < 71; i++) {
buffer[i] = (char)0x00;
}
/* VolLab = ' ' */
for (i = 71; i < 82; i++) {
buffer[i] = (char)0x20;
}
/* FilSysType = 'FAT12' */
FS__CLIB_strncpy(&buffer[82], "FAT32 ", 8);
}
#endif /* FS_FAT_NOFAT32==0 */
/* Signature = 0xAA55 */
buffer[510] = (char)0x55;
buffer[511] = (char)0xaa;
/* Write BPB to media */
i = FS__lb_write(pDriver, Unit, 0, (void*)buffer);
if (i < 0) {
FS__fat_free(buffer);
return -1;
}
if (FSysType == 2) {
/* Write backup BPB */
i = FS__lb_write(pDriver, Unit, 6, (void*)buffer);
if (i<0) {
FS__fat_free(buffer);
return -1;
}
}
/* Init FAT 1 & 2 */
FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE);
for (sector = 0; sector < 2 * (bpb.FATSz16 + bpb.FATSz32); sector++) {
value = sector % (bpb.FATSz16 + bpb.FATSz32);
if (value != 0) {
i = FS__lb_write(pDriver, Unit, bpb.RsvdSecCnt + sector, (void*)buffer);
if (i<0) {
FS__fat_free(buffer);
return -1;
}
}
}
buffer[0] = (char)Media;
buffer[1] = (char)0xff;
buffer[2] = (char)0xff;
if (FSysType != 0) {
buffer[3] = (char)0xff;
}
#if (FS_FAT_NOFAT32==0)
if (FSysType == 2) {
buffer[4] = (char)0xff;
buffer[5] = (char)0xff;
buffer[6] = (char)0xff;
buffer[7] = (char)0x0f;
buffer[8] = (char)0xff;
buffer[9] = (char)0xff;
buffer[10] = (char)0xff;
buffer[11] = (char)0x0f;
}
#endif /* FS_FAT_NOFAT32==0 */
for (i = 0; i < 2; i++) {
j = FS__lb_write(pDriver, Unit, (FS_u32)bpb.RsvdSecCnt + i * ((FS_u32)bpb.FATSz16+bpb.FATSz32), (void*)buffer);
if (j < 0) {
FS__fat_free(buffer);
return -1;
} // two fat table
}
/* Init root directory area */
FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE);
if (bpb.RootEntCnt != 0) {
/* FAT12/FAT16 */
n = (((FS_u32)bpb.RootEntCnt * 32) / (FS_u32)512); //n show the sectors accupied by root directory entries
for (i = 0; i < n; i++) {
j = FS__lb_write(pDriver, Unit, bpb.RsvdSecCnt + 2 * bpb.FATSz16 + i, (void*)buffer); //reserved sectors under fat12/16 is 1
if (j < 0) {
FS__fat_free(buffer);
return -1;
}
}
}
#if (FS_FAT_NOFAT32==0)
else {
/* FAT32 */
n = bpb.SecPerClus;
for (i = 0; i < n; i++) {
j = FS__lb_write(pDriver, Unit, bpb.RsvdSecCnt + 2 * bpb.FATSz32 + (bpb.RootClus - 2) * n + i, (void*)buffer);
if (j < 0) {
FS__fat_free(buffer);
return -1;
}
}
}
#endif /* FS_FAT_NOFAT32==0 */
#if (FS_FAT_NOFAT32==0)
if (FSysType == 2) {
/* Init FSInfo */
FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE);
/* LeadSig = 0x41615252 */
buffer[0] = (char)0x52;
buffer[1] = (char)0x52;
buffer[2] = (char)0x61;
buffer[3] = (char)0x41;
/* StructSig = 0x61417272 */
buffer[484] = (char)0x72;
buffer[485] = (char)0x72;
buffer[486] = (char)0x41;
buffer[487] = (char)0x61;
/* Invalidate last known free cluster count */
buffer[488] = (char)0xff;
buffer[489] = (char)0xff;
buffer[490] = (char)0xff;
buffer[491] = (char)0xff;
/* Give hint for free cluster search */
buffer[492] = (char)0xff;
buffer[493] = (char)0xff;
buffer[494] = (char)0xff;
buffer[495] = (char)0xff;
/* TrailSig = 0xaa550000 */
buffer[508] = (char)0x00;
buffer[509] = (char)0x00;
buffer[510] = (char)0x55;
buffer[511] = (char)0xaa;
i = FS__lb_write(pDriver, Unit, bpb.FSInfo, (void*)buffer);
if (i < 0) {
FS__fat_free(buffer);
return -1;
}
}
#endif /* FS_FAT_NOFAT32==0 */
FS__fat_free(buffer);
return 0;
}
/*********************************************************************
*
* _FS_FAT_AutoFormat
*
Description:
FS internal function. Get information about the media from the
device driver. Based on that informaton, calculate parameters for
formatting that media and call the format routine.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
Return value:
>=0 - Media has been formatted.
<0 - An error has occured.
*/
static int _FS_FAT_AutoFormat(int Idx, FS_u32 Unit) {
struct {
FS_u32 hiddennum;
FS_u32 headnum;
FS_u32 secnum;
FS_u32 partsize;
} devinfo;
FS_u32 rootentcnt;
FS_u32 fatsz;
FS_u32 rootdirsectors;
FS_u32 tmpval1;
FS_u32 tmpval2;
FS_u32 fatsz32;
FS_u32 totsec32;
FS_u32 resvdseccnt;
FS_u16 totsec16;
FS_u16 fatsz16;
int i;
unsigned char secperclust;
char fsystype;
/* Get info from device */
devinfo.hiddennum = 0x00001111UL;
devinfo.headnum = 0x00002222UL;
devinfo.secnum = 0x00003333UL;
devinfo.partsize = 0x00004444UL;
i = FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_GET_DEVINFO, 0, (void*)&devinfo);
if (i) {
return -1;
}
/* Check if the driver really supports FS_CMD_GET_DEVINFO */
if (devinfo.hiddennum == 0x00001111UL) {
if (devinfo.headnum == 0x00002222UL) {
if (devinfo.secnum == 0x00003333UL) {
if (devinfo.partsize == 0x00004444UL) {
return -1;
}
}
}
}
if (devinfo.partsize <= 1048576UL) {
fsystype = 1; /* FAT16 */
}
#if (FS_FAT_NOFAT32==0)
else {
fsystype = 2; /* FAT32 */
}
#else
else {
/* FAT32 disabled */
return -1;
}
#endif /* FS_FAT_NOFAT32==0 */
/* Set correct RootEntCnt & ResvdSecCnt */
if (fsystype != 2) {
/* FAT16 */
i = 0;
while (_FS_auto_rootcnt[i].SecNum < devinfo.partsize) {
i++;
}
rootentcnt = (FS_u16)_FS_auto_rootcnt[i].Num;
resvdseccnt = 1;
}
#if (FS_FAT_NOFAT32==0)
else {
/* FAT32 */
rootentcnt = 0;
resvdseccnt = 0x20;
}
#endif /* FS_FAT_NOFAT32==0 */
/* Determinate SecPerClust */
i = 0;
while (_FS_auto_secperclust[i].SecNum < devinfo.partsize) {
i++;
}
secperclust = (unsigned char) _FS_auto_secperclust[i].Num;
/*
FAT16/FAT32 FAT size calculation
The formula used is following the Microsoft specification
version 1.03 very closely. Therefore the calculated FAT
size can be up to 8 sectors bigger than required for the
media. This is a waste of up to 8 sectors, but not a problem
regarding correctness of the media's data.
*/
rootdirsectors = ((rootentcnt * 32 ) + 511) / 512;
tmpval1 = devinfo.partsize - (resvdseccnt + rootdirsectors);
tmpval2 = (256 * secperclust) + 2;
#if (FS_FAT_NOFAT32==0)
if (fsystype == 2) {
tmpval2 = tmpval2 / 2;
}
#endif /* FS_FAT_NOFAT32==0 */
fatsz = (tmpval1 + (tmpval2 - 1)) / tmpval2;
if (fsystype != 2) {
fatsz16 = (FS_u16)fatsz;
fatsz32 = 0;
}
#if (FS_FAT_NOFAT32==0)
else {
fatsz16 = 0;
fatsz32 = fatsz;
}
#endif /* FS_FAT_NOFAT32==0 */
/* Number of total sectors (512 byte units) of the media
This is independent of FAT type (FAT12/FAT16/FAT32) */
if (devinfo.partsize < 0x10000UL) {
totsec16 = (FS_u16)devinfo.partsize;
totsec32 = 0;
}
else {
totsec16 = 0;
totsec32 = devinfo.partsize;
}
/* Format media using calculated values */
i = _FS_fat_format(FS__pDevInfo[Idx].devdriver,
Unit,
secperclust,
(FS_u16)rootentcnt,
totsec16,
totsec32,
(char)0xf8,
fatsz16,
fatsz32,
(FS_u16)devinfo.secnum,
(FS_u16)devinfo.headnum,
devinfo.hiddennum,
fsystype);
return i;
}
#endif /* FS_FAT_NOFORMAT==0 */
#if FS_FAT_DISKINFO
/*********************************************************************
*
* _FS_fat_GetTotalFree
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -