📄 sdfat.c
字号:
InitFileInfo(pFileInfo, dwPartNo, Partition[dwPartNo].StartingRootEntry, 0, DIRENTRY_SUBDIR);
}
else{
InitFileInfo(pFileInfo, dwPartNo, FAT_ROOTCLUSTER, Partition[dwPartNo].RootEntryLength, DIRENTRY_SUBDIR);
}
return TRUE;
}
else{
return FALSE;
}
}
static BOOL FindNextDirEntry(PFILEINFO pFileInfo, PCSTR* ppCurItem){
DIRENTRY drEntry;
// search...
while(1){
// read one DIRENTRY
if(!GetDirEntryEx(pFileInfo, &drEntry)){
break; // fail, exit loop
}
if(drEntry.FileName[0] == DIRENTRY_NEVERUSED){
break; // no used entry, exit
}
// compare filename, if match update ppCurItem to next
if(CompareFileName(drEntry.FileName, ppCurItem)){
// update pFileInfo to new entry
InitFileInfo(pFileInfo, pFileInfo->PartitionNumber,
drEntry.StartingCluster, drEntry.FileLength, drEntry.Attribute);
return TRUE;
}
}
return FALSE;
}
// help routine for initialization
static DWORD GetDefaultSectorSize(){
return DEFAULT_SECTOR_SIZE;
}
static BOOL InitPartition(BOOL fBootable, DWORD dwFileSystem, DWORD dwStart, DWORD dwLength){
DWORD dwFileType;
DWORD dwFATSectors, dwTotalSectors;
DWORD dwRootStart, dwRootSectors, dwRootLength;
DWORD dwDataStart, dwDataSectors, dwDataClusters;
UINT8 buf[DEFAULT_SECTOR_SIZE];
PRAWPARTITION pPart = (PRAWPARTITION)buf;
// we just support 26 partition
if(PartitionNumber >= MAX_PARTITION){
return FALSE;
}
// read first sector
if(FATReadDisk(pPart, sizeof(*pPart), dwStart) != sizeof(*pPart)){
return FALSE;
}
// check field
if(pPart->SectorSize == 0){
return FALSE;
}
if(pPart->SectorPerCluster == 0){
return FALSE;
}
if(pPart->ReservedSector == 0){
return FALSE;
}
if(pPart->NumberOfFAT == 0){
return FALSE;
}
if(pPart->NumberOfRootEntry==0 && pPart->FAT32.RootEntryCluster==0){
return FALSE;
}
if(pPart->TotalSector != 0){
if(pPart->TotalSector2 != 0){
return FALSE;
}
}
else if(pPart->TotalSector2 == 0){
return FALSE;
}
if(pPart->SectorPerFAT==0 && pPart->FAT32.SectorPerFAT==0){
return FALSE;
}
if(pPart->EFDCSignature!=RAWPARTITION_EFDCSIGNATURE &&
pPart->FAT32.EFDCSignature!=RAWPARTITION_EFDCSIGNATURE){
return FALSE;
}
if(pPart->Signature != RAWPARTITION_SIGNATURE){
return FALSE;
}
// determine FAT type
if(pPart->SectorPerFAT){
dwFATSectors = pPart->NumberOfFAT*pPart->SectorPerFAT;
}
else{
dwFATSectors = pPart->NumberOfFAT*pPart->FAT32.SectorPerFAT;
}
if(pPart->TotalSector){
dwTotalSectors = pPart->TotalSector;
}
else{
dwTotalSectors = pPart->TotalSector2;
}
dwRootStart = pPart->SectorSize*(pPart->ReservedSector+dwFATSectors);
dwRootLength = 32*pPart->NumberOfRootEntry;
dwRootSectors = (dwRootLength+pPart->SectorSize-1)/pPart->SectorSize;
dwDataStart = dwRootStart+pPart->SectorSize*dwRootSectors;
dwDataSectors = dwTotalSectors-pPart->ReservedSector-dwFATSectors-dwRootSectors;
dwDataClusters = dwDataSectors/pPart->SectorPerCluster;
if(dwDataClusters < 4085){
dwFileType = PART_FAT12;
}
else if(dwDataClusters < 65525){
dwFileType = PART_FAT16;
}
else{
dwFileType = PART_FAT32;
dwRootStart = pPart->FAT32.RootEntryCluster;
}
// check consistent
if(dwFileSystem != dwFileType){
if(dwFileSystem != PART_UNKNOWN){
return FALSE;
}
}
// validated FAT, update global state
Partition[PartitionNumber].Bootable = fBootable;
Partition[PartitionNumber].FileSystem = dwFileType;
Partition[PartitionNumber].StartingPartition = dwStart;
Partition[PartitionNumber].PartitionLength = dwLength;
Partition[PartitionNumber].StartingFATEntry = pPart->SectorSize*pPart->ReservedSector;
Partition[PartitionNumber].FATEntryNumber = dwDataClusters+2; // +2 for format identifier
Partition[PartitionNumber].StartingRootEntry = dwRootStart;
Partition[PartitionNumber].RootEntryLength = dwRootLength;
Partition[PartitionNumber].StartingCluster = dwDataStart;
Partition[PartitionNumber].LengthPerCluster = pPart->SectorSize*pPart->SectorPerCluster;
memcpy(&RawPartition[PartitionNumber++], pPart, sizeof(*pPart));
return TRUE;
}
static BOOL InitMasterBootRecord(DWORD dwStart, DWORD dwLength){
int i, j;
BOOL fBootable;
UINT8 buf[DEFAULT_SECTOR_SIZE];
PARTITION_TABLE EmptyPart = {0}; // all zero
PPARTITION_TABLE pPart1, pPart2;
DWORD dwPartStart, dwPartLength;
PMASTERBOOT_RECORD pMBR = (PMASTERBOOT_RECORD)buf;
// we just support 26 MBR
if(MasterBootRecordNumber >= MAX_PARTITION){
return FALSE;
}
// read first sector
if(FATReadDisk(pMBR, sizeof(*pMBR), dwStart) != sizeof(*pMBR)){
return FALSE;
}
// check signature
if(pMBR->Signature != MASTERBOOT_SIGNATURE){
return FALSE;
}
// check partition table
for(i = 0; i < PARTITION_NUMBER; ++i){
pPart1 = &pMBR->Partition[i];
// check empty partition
if(pPart1->SystemId == PARTITION_EMPTY){
if(memcmp(pPart1, &EmptyPart, sizeof(EmptyPart)) != 0){
return FALSE; // empty partition should be all zero
}
continue; // skip follow check
}
// check boot indicator
if(pPart1->BootIndicator!=PARTITION_NORMAL && pPart1->BootIndicator!=PARTITION_SYSTEM){
return FALSE;
}
// check header(0-254)
if(pPart1->StartingHead==0xFF || pPart1->EndingHead==0xFF){
return FALSE;
}
// check sector(1-63)
if(pPart1->StartingSector==0 || pPart1->EndingSector==0){
return FALSE;
}
// check start&length
dwPartStart = pPart1->RelativeSector*GetDefaultSectorSize();
dwPartLength = pPart1->TotalSector*GetDefaultSectorSize();
if(dwPartStart >= dwLength){
return FALSE;
}
if(dwPartLength==0 || dwPartStart+dwPartLength>dwLength){
return FALSE;
}
// check overlap
for(j = i+1; j < PARTITION_NUMBER; ++j){
pPart2 = &pMBR->Partition[j];
// skip empty
if(pPart2->SystemId == PARTITION_EMPTY){
continue;
}
// check start point
if(pPart2->RelativeSector>=pPart1->RelativeSector &&
pPart2->RelativeSector<pPart1->RelativeSector+pPart1->TotalSector){
return FALSE;
}
// check end point
if(pPart2->RelativeSector+pPart2->TotalSector>pPart1->RelativeSector &&
pPart2->RelativeSector+pPart2->TotalSector<=pPart1->RelativeSector+pPart1->TotalSector){
return FALSE;
}
}
}
// validated MBR, copy it!
memcpy(&MasterBootRecord[MasterBootRecordNumber++], pMBR, sizeof(*pMBR));
// init individual partition
for(i = 0; i < PARTITION_NUMBER; ++i){
pPart1 = &pMBR->Partition[i];
fBootable = (pPart1->BootIndicator==PARTITION_SYSTEM);
dwPartStart = dwStart + GetDefaultSectorSize()*pPart1->RelativeSector;
dwPartLength = GetDefaultSectorSize()*pPart1->TotalSector;
switch(pPart1->SystemId){
case PARTITION_FAT12: // FAT12
InitPartition(fBootable, PART_FAT12, dwPartStart, dwPartLength);
break;
case PARTITION_FAT16: // FAT16
case PARTITION_FAT16B:
case PARTITION_FAT16L:
InitPartition(fBootable, PART_FAT16, dwPartStart, dwPartLength);
break;
case PARTITION_FAT32: // FAT32
case PARTITION_FAT32L:
InitPartition(fBootable, PART_FAT32, dwPartStart, dwPartLength);
break;
case PARTITION_EXT: // Extend
case PARTITION_EXTL:
InitMasterBootRecord(dwPartStart, dwPartLength); // recursion!
break;
case PARTITION_EMPTY:
break; // no action
default:
//InitPartition(PART_UNKNOWN, dwPartStart, dwPartLength); // try it?
break;
}
}
return TRUE;
}
// disk function
BOOL FATInitDisk(){
// init hardware
if(!SDInitializeHardware()){
return FALSE;
}
// try to init MBR
if(InitMasterBootRecord(0, FATGetDiskSize())){
return TRUE;
}
// no MBR, try to init partition
if(InitPartition(TRUE, PART_UNKNOWN, 0, FATGetDiskSize())){
return TRUE;
}
// no FAT partition, fail!
return FALSE;
}
DWORD FATGetDiskSize(){
return 0xFFFFFFFF; // TODO: get from SD Card
}
DWORD FATReadDisk(PVOID pBuffer, DWORD dwLength, DWORD dwPos){
// parameter check
if(dwPos >= FATGetDiskSize()){
return 0;
}
// adjust dwLength if need
if(dwPos+dwLength > FATGetDiskSize()){
dwLength = FATGetDiskSize()-dwPos;
}
return SDReadDataBlock(pBuffer, dwLength, dwPos)?dwLength:FAT_ERROR;
}
// partition function
DWORD FATGetPartitionNumber(){
return PartitionNumber;
}
DWORD FATGetPartitionSize(DWORD dwPartNo){
return dwPartNo<PartitionNumber?Partition[dwPartNo].PartitionLength:FAT_ERROR;
}
DWORD FATReadPartition(DWORD dwPartNo, PVOID pBuffer, DWORD dwLength, DWORD dwPos){
// parameter check
if(dwPartNo >= PartitionNumber){
return FAT_ERROR;
}
if(dwPos >= Partition[dwPartNo].PartitionLength){
return 0;
}
// adjust dwLength if need
if(dwPos+dwLength > Partition[dwPartNo].PartitionLength){
dwLength = Partition[dwPartNo].PartitionLength-dwPos;
}
return FATReadDisk(pBuffer, dwLength, Partition[dwPartNo].StartingPartition+dwPos);
}
// file function
BOOL FATOpenFile(PFILEINFO pFileInfo, PCSTR pFileName){
FILEINFO fnFileInfo;
// invalid pFileInfo
ClearFileInfo(pFileInfo);
// find root directory
if(!FindRootDirEntry(&fnFileInfo, &pFileName)){
return FALSE;
}
// find each directory and last file
while(*pFileName){
if(!FATIsDirectory(&fnFileInfo)){ // not directory
return FALSE;
}
if(!FindNextDirEntry(&fnFileInfo, &pFileName)){
return FALSE;
}
}
// copy it
memcpy(pFileInfo, &fnFileInfo, sizeof(*pFileInfo));
return TRUE;
}
BOOL FATCloseFile(PFILEINFO pFileInfo){
ClearFileInfo(pFileInfo);
return TRUE;
}
BOOL FATIsReadOnly(PFILEINFO pFileInfo){
return (pFileInfo->FileAttribute&DIRENTRY_READONLY) != 0;
}
BOOL FATIsHidden(PFILEINFO pFileInfo){
return (pFileInfo->FileAttribute&DIRENTRY_HIDDEN) != 0;
}
BOOL FATIsSystem(PFILEINFO pFileInfo){
return (pFileInfo->FileAttribute&DIRENTRY_SYSTEM) != 0;
}
BOOL FATIsVolumeLabel(PFILEINFO pFileInfo){
return (pFileInfo->FileAttribute&DIRENTRY_VOLUMELABEL) != 0;
}
BOOL FATIsDirectory(PFILEINFO pFileInfo){
return (pFileInfo->FileAttribute&DIRENTRY_SUBDIR) != 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -