#include "vfat_fat_info.h"
#include <string.h>
int init_fat_info(struct vfat_fat_info_struct *fat_info, const void *buf)
{
memcpy(&fat_info->boot_sect, buf, sizeof (bootSector_t));
if (fat_info->boot_sect.BPB_BytsPerSec != 512
&& fat_info->boot_sect.BPB_BytsPerSec != 1024
&& fat_info->boot_sect.BPB_BytsPerSec != 2048
&& fat_info->boot_sect.BPB_BytsPerSec != 4096)
return 0;
if (fat_info->boot_sect.BPB_SecPerClus != 1
&& fat_info->boot_sect.BPB_SecPerClus != 2
&& fat_info->boot_sect.BPB_SecPerClus != 4
&& fat_info->boot_sect.BPB_SecPerClus != 8
&& fat_info->boot_sect.BPB_SecPerClus != 16
&& fat_info->boot_sect.BPB_SecPerClus != 32
&& fat_info->boot_sect.BPB_SecPerClus != 64
&& fat_info->boot_sect.BPB_SecPerClus != 128)
return 0;
if (fat_info->boot_sect.BPB_ResvdSecCnt == 0)
return 0;
if (fat_info->boot_sect.BPB_NumFATs < 1)
return 0;
fat_info->RootDirSectors = ((fat_info->boot_sect.BPB_RootEntCnt * 32) + (fat_info->boot_sect.BPB_BytsPerSec - 1)) / fat_info->boot_sect.BPB_BytsPerSec;
if (fat_info->boot_sect.BPB_FATSz16 != 0)
fat_info->FATSz = fat_info->boot_sect.BPB_FATSz16;
else
fat_info->FATSz = fat_info->boot_sect.fat32.BPB_FATSz32;
if (fat_info->boot_sect.BPB_TotSec16 != 0)
fat_info->TotSec = fat_info->boot_sect.BPB_TotSec16;
else
fat_info->TotSec = fat_info->boot_sect.BPB_TotSec32;
fat_info->FirstDataSector = fat_info->boot_sect.BPB_ResvdSecCnt + (fat_info->boot_sect.BPB_NumFATs * fat_info->FATSz) + fat_info->RootDirSectors;
fat_info->DataSec = fat_info->TotSec - (fat_info->boot_sect.BPB_ResvdSecCnt + (fat_info->boot_sect.BPB_NumFATs * fat_info->FATSz) + fat_info->RootDirSectors);
fat_info->CountofClusters = fat_info->DataSec / fat_info->boot_sect.BPB_SecPerClus;
if (fat_info->CountofClusters < 4085)
fat_info->FATType = FAT12;
else if (fat_info->CountofClusters < 65525)
fat_info->FATType = FAT16;
else
fat_info->FATType = FAT32;
if (fat_info->FATType == FAT32 && fat_info->boot_sect.BPB_RootEntCnt != 0)
return 0;
if (fat_info->boot_sect.BPB_TotSec16 == 0 && fat_info->boot_sect.BPB_TotSec32 == 0)
return 0;
if (fat_info->FATType == FAT32 && fat_info->boot_sect.BPB_TotSec16 != 0)
return 0;
if (fat_info->boot_sect.BPB_Media != 0xf0
&& fat_info->boot_sect.BPB_Media != 0xf8
&& fat_info->boot_sect.BPB_Media != 0xf9
&& fat_info->boot_sect.BPB_Media != 0xfa
&& fat_info->boot_sect.BPB_Media != 0xfb
&& fat_info->boot_sect.BPB_Media != 0xfc
&& fat_info->boot_sect.BPB_Media != 0xfd
&& fat_info->boot_sect.BPB_Media != 0xfe
&& fat_info->boot_sect.BPB_Media != 0xff)
return 0;
if (fat_info->FATType == FAT32 && fat_info->boot_sect.BPB_FATSz16 != 0)
return 0;
if (fat_info->FATType == FAT32 && fat_info->boot_sect.BPB_TotSec32 == 0)
return 0;
if (fat_info->FATType == FAT12 || fat_info->FATType == FAT16)
fat_info->FirstRootDirSecNum = fat_info->boot_sect.BPB_ResvdSecCnt + (fat_info->boot_sect.BPB_NumFATs * fat_info->boot_sect.BPB_FATSz16);
return 1;
}
unsigned long get_FATClusEntryVal(const unsigned char SecBuff[], const struct vfat_fat_info_struct *fat_info, unsigned long N)
{
unsigned long FATClusEntryVal;
if (fat_info->FATType == FAT12) {
FATClusEntryVal = *((const WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]);
if (N & 0x0001)
return FATClusEntryVal >> 4;
else
return FATClusEntryVal & 0x0fff;
}
else if (fat_info->FATType == FAT16)
return *((const WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]);
else
return (*((const DWORD *)&SecBuff[ThisFATEntOffset(fat_info, N)])) & 0x0fffffff;
}
void set_FATClusEntryVal(unsigned char SecBuff[], const struct vfat_fat_info_struct *fat_info, unsigned long N, unsigned long FATClusEntryVal)
{
if (fat_info->FATType == FAT12) {
if (N & 0x0001) {
FATClusEntryVal = FATClusEntryVal << 4;
*((WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]) = (*((WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)])) & 0x000f;
}
else {
FATClusEntryVal = FATClusEntryVal & 0x0fff;
*((WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]) = (*((WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)])) & 0xf000;
}
*((WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]) = (*((WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)])) | FATClusEntryVal;
}
else if (fat_info->FATType == FAT16)
*((WORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]) = FATClusEntryVal;
else {
FATClusEntryVal = FATClusEntryVal & 0x0fffffff;
*((DWORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]) = (*((DWORD *)&SecBuff[ThisFATEntOffset(fat_info, N)])) & 0xf0000000;
*((DWORD *)&SecBuff[ThisFATEntOffset(fat_info, N)]) = (*((DWORD *)&SecBuff[ThisFATEntOffset(fat_info, N)])) | FATClusEntryVal;
}
}
int IsEOF(const struct vfat_fat_info_struct *fat_info, unsigned long FATContent)
{
if (fat_info->FATType == FAT12) {
if (FATContent >= 0x0ff8)
return TRUE;
}
else if (fat_info->FATType == FAT16) {
if (FATContent >= 0xfff8)
return TRUE;
}
else {
if (FATContent >= 0x0ffffff8)
return TRUE;
}
return FALSE;
}