📄 fat.c
字号:
// SERPRINT("INFO: %d: File name '%s' File size = 0x%x Attrib(0x%X) %x\r\n", j, pDirEntry->FileName, pDirEntry->FileSize, pDirEntry->FATTr , pDirEntry);
result = pDirEntry;
break;
}
}
//SERPRINT( "INFO: Entries checked(%d): files(%d), dirs(%d), longFnames(%d)\r\n", (lfCnt + dirCnt + fileCnt), fileCnt, dirCnt, lfCnt );
return( result );
}
PDIRENTRY SearchFAT12And16ForFile(
PCHAR pFileName
)
{
PDIRENTRY result = NULL;
USHORT i = 0;
ULONG DirLBA = 0;
UCHAR Sector[SECTOR_SIZE];
USHORT numEntriesInSector = g_FATParms.BytesPerSect / sizeof( DIRENTRY );
//
// Look for the filename in directory list.
//
for ( i = 0, DirLBA = g_FATParms.RootDirLBA;
(result == NULL) && (i < g_FATParms.NumRootEntries + 1);
DirLBA++, i += numEntriesInSector )
{
memset( &Sector[0], 0, SECTOR_SIZE );
//SERPRINT("INFO: Reading root directory sector (LBA=0x%x)...\r\n", DirLBA);
//
// Read a sector from the root directory.
//
if (!ReadSectors( g_FATParms.DriveId, DirLBA, 1, (PUCHAR) Sector ))
{
SERPRINT("ERROR: Couldn't read root directory sector (LBA=0x%x).\r\n", DirLBA);
return(0);
}
// EdbgDumpHexBuf((PUCHAR) Sector, SECTOR_SIZE);
result = SearchBufferForFile( pFileName, &Sector[0], 1 );
}
return( result );
}
PDIRENTRY SearchFAT32ForFile(
PCHAR pFileName
)
{
PDIRENTRY result = NULL;
ULONG Cluster = g_FATParms.RootDirCluster; // Where the Root starts
do
{
// Read the cluster...
if (!ReadSectors( g_FATParms.DriveId, Cluster2LBA( Cluster ),
g_FATParms.SectsPerClust, (PUCHAR) READ_BUFFER_START ) )
{
SERPRINT( "OpenFile ERROR: Couldn't read root directory's cluster %ld(LBA: 0x%04lx)\r\n",
Cluster, Cluster2LBA( Cluster ) );
return( result );
}
// EdbgDumpHexBuf((PUCHAR) READ_BUFFER_START, SECTOR_SIZE);
//
// Try to find the specified file in the root directory...
//
result = SearchBufferForFile( pFileName, (PUCHAR) READ_BUFFER_START,
g_FATParms.SectsPerClust );
if ( result != NULL )
{
// the file has been found...
break;
}
// Root directory in FAT-32 is the same as any other directory...
// so, get the next cluster...
Cluster = GetNextCluster( Cluster );
} while ( TRUE == IsDataCluster( Cluster) );
return( result );
}
//
// Open filename specified and return the size.
//
ULONG OpenFile(PCHAR pFileName)
{
USHORT i = 0;
USHORT j = 0;
BOOL bFound = FALSE;
#if defined( NDEF_DWF_USE_NEW_DIR_READ )
ULONG DirLBA = 0;
#if !defined( NDEF_DWF_USE_OLD_READ )
UCHAR Sector[SECTOR_SIZE];
#else // ( NDEF_DWF_USE_OLD_READ )
CHAR Sector[SECTOR_SIZE];
#endif // ( NDEF_DWF_USE_OLD_READ )
#endif // ( NDEF_DWF_USE_NEW_DIR_READ )
PDIRENTRY pDirEntry = NULL;
CHAR FileName[11] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
SERPRINT("OpenFile %s\r\n", pFileName);
//
// Check caller's parameters.
//
if (pFileName == NULL)
return(0);
//
// Convert the filename to the form stored on disk.
//
for (i = 0 ; i < 8 && *(pFileName + i) != '\0' && *(pFileName + i) != '.' ; i++)
{
FileName[i] = TO_UPPER(*(pFileName + i));
}
if (*(pFileName + i) == '.')
{
i++;
for (j=0 ; i < 12 && *(pFileName + i) != '\0' ; i++, j++)
FileName[8 + j] = TO_UPPER(*(pFileName + i));
}
#if !defined( NDEF_DWF_USE_NEW_DIR_READ )
bFound = FALSE;
if (g_FATParms.FATType != FAT_32)
{
SERPRINT("Searching FAT (fat12 or fat16).... \r\n");
pDirEntry = SearchFAT12And16ForFile( FileName );
}
else
{
SERPRINT("Searching FAT (fat32).... \"%s\" \r\n", FileName);
pDirEntry = SearchFAT32ForFile( FileName );
}
bFound = (pDirEntry != NULL);
SERPRINT("Found FAT Entry %x pDirEntry %x\r\n", bFound, pDirEntry);
#else // ( NDEF_DWF_USE_NEW_DIR_READ )
//
// Look for the filename in directory list.
//
for (bFound = FALSE, i = 0, DirLBA = g_FATParms.RootDirLBA ; !bFound && i < g_FATParms.NumRootEntries ; DirLBA++)
{
memset(&Sector[0], 0, SECTOR_SIZE);
// SERPRINT("INFO: Reading root directory sector (LBA=0x%x)...\r\n", DirLBA);
//
// Read a sector from the root directory.
//
#if defined( NDEF_DWF_USE_OLD_READ )
if (0 != read_sector( DirLBA, Sector ) )
{
SERPRINT("ERROR: Couldn't read root directory sector (LBA=0x%x).\r\n", DirLBA);
return(0);
}
#else // ( NDEF_DWF_USE_OLD_READ )
if (!ReadSectors(g_FATParms.DriveId, DirLBA, 1, (PUCHAR) Sector))
{
SERPRINT("ERROR: Couldn't read root directory sector (LBA=0x%x).\r\n", DirLBA);
return(0);
}
// EdbgDumpHexBuf((PUCHAR)&Sector[0],SECTOR_SIZE);
#endif // ( NDEF_DWF_USE_OLD_READ )
//
// Try to find the specified file in the root directory...
//
for (pDirEntry = (PDIRENTRY)Sector, j = 0 ; j < (g_FATParms.BytesPerSect / sizeof(DIRENTRY)) && i < g_FATParms.NumRootEntries ; j++, i++, pDirEntry++)
{
// SERPRINT("INFO: %d: File name '%s' File size = 0x%x\r\n", j, pDirEntry->FileName, pDirEntry->FileSize);
if (!memcmp(FileName, (void *)pDirEntry->FileName, 11))
{
//
// Found it.
//
bFound = TRUE;
break;
}
}
}
#endif // ( NDEF_DWF_USE_NEW_DIR_READ )
if (!bFound)
{
SERPRINT("ERROR: Couldn't find file '%s'.\r\n", pFileName);
return(0);
}
else
{
SERPRINT("INFO: Found file '%s' (start cluster = 0x%X:%X size = 0x%x)\r\n", pFileName, pDirEntry->FirstClusterHigh, pDirEntry->FirstClusterLow, pDirEntry->FileSize);
}
//
// Save file parameters
//
g_FileInfo.FileSize = pDirEntry->FileSize;
g_FileInfo.FirstCluster = (pDirEntry->FirstClusterHigh << 16);
g_FileInfo.FirstCluster += pDirEntry->FirstClusterLow;
g_FileInfo.CurrentCluster = g_FileInfo.FirstCluster;
g_FileInfo.NumContigClusters = 0;
g_FileInfo.pCurReadBuffAddr = g_pReadBuffStart;
g_FileInfo.NumReadBuffBytes = 0;
g_FileInfo.pTotalReadByte = 0;
return(g_FileInfo.FileSize);
}
void CloseFile(void)
{
memset(&g_FileInfo, 0, sizeof(g_FileInfo));
return;
}
static BOOL InitReadBuffer(ULONG pStartAddress, ULONG Length)
{
// Check arguments.
//
if (pStartAddress == 0)
return(FALSE);
// Determine how many clusters are in the read buffer.
//
Length /= (g_FATParms.BytesPerSect * g_FATParms.SectsPerClust);
if (!Length)
{
SERPRINT("ERROR: Read buffer should be at least a cluster size in length.\r\n");
return(FALSE);
}
// Store read buffer start and the adjusted length.
//
g_pReadBuffStart = (UCHAR *)pStartAddress;
g_ReadBuffLenInClusters = Length;
return(TRUE);
}
CLUSTTYPE GetNextClusterGroup(ULONG StartCluster, PULONG pNumberClusters)
{
ULONG CurrentCluster = 0;
ULONG NextCluster = 0;
*pNumberClusters = 0;
// TODO - could be a bad cluster - check for it here.
// Determine number of contiguous clusters.
//
NextCluster = StartCluster;
do
{
CurrentCluster = NextCluster;
*pNumberClusters = *pNumberClusters + 1;
NextCluster = GetNextCluster(CurrentCluster);
if (NextCluster != (CurrentCluster + 1))
{
break;
}
} while(IsDataCluster(NextCluster));
// Why did we break out of the above loop?
//
if (IsEOFCluster(NextCluster))
return(EOF_CLUSTER);
if (IsBadCluster(NextCluster))
return(BAD_CLUSTER);
if (IsRsvdCluster(NextCluster))
return(RSVD_CLUSTER);
return(DATA_CLUSTER);
}
BOOL lReadFile(PUCHAR pAddress, ULONG Length)
{
ULONG ClustersToRead = 0;
// Validate callers parameters.
//
if (!pAddress || Length == 0)
return(FALSE);
// SERPRINT("lReadFile address=%x length = %x\r\n",pAddress,Length);
// Make sure callers called InitReadBuffer before calling us.
//
if (!g_pReadBuffStart || g_ReadBuffLenInClusters == 0)
{
SERPRINT("ERROR: InitReadBuffer must be called before reading a file.\r\n");
return(FALSE);
}
do
{
// Is there data in the read buffer?
//
if (g_FileInfo.NumReadBuffBytes)
{
if (Length <= g_FileInfo.NumReadBuffBytes)
{
// We can satisfy the read request with what's in the read buffer already.
//
memcpy(pAddress, g_FileInfo.pCurReadBuffAddr, Length);
g_FileInfo.NumReadBuffBytes -= Length;
g_FileInfo.pCurReadBuffAddr += Length;
pAddress += Length;
return(TRUE);
}
else
{
// Empty the read buffer before loading more.
//
memcpy(pAddress, g_FileInfo.pCurReadBuffAddr, g_FileInfo.NumReadBuffBytes);
Length -= g_FileInfo.NumReadBuffBytes;
pAddress += g_FileInfo.NumReadBuffBytes;
}
}
//
// Load the entire read buffer with more data.
//
// Determine next grouping of clusters that are contiguous (on the storage device).
if (g_FileInfo.NumContigClusters == 0)
{
// If the current cluster isn't the first cluster in the file, then the value is +1 from the last
// cluster in the contiguous grouping. Subtract one, follow the link and seek a new grouping.
//
if (g_FileInfo.CurrentCluster != g_FileInfo.FirstCluster)
{
--g_FileInfo.CurrentCluster;
if (IsEOFCluster(g_FileInfo.CurrentCluster))
{
SERPRINT("INFO: Reached EOF cluster in FAT file chain.\r\n");
return(FALSE);
}
g_FileInfo.CurrentCluster = GetNextCluster(g_FileInfo.CurrentCluster);
}
// Get the next contiguous grouping of cluster and return the type of the last cluster in the list.
//
switch(GetNextClusterGroup(g_FileInfo.CurrentCluster, &g_FileInfo.NumContigClusters))
{
case DATA_CLUSTER:
// SERPRINT("INFO: 0x%x contiguous clusters starting with 0x%x.\r\n", g_FileInfo.NumContigClusters, g_FileInfo.CurrentCluster);
break;
case EOF_CLUSTER:
// SERPRINT("INFO: 0x%x contiguous clusters starting with 0x%x (EOF terminator).\r\n", g_FileInfo.NumContigClusters, g_FileInfo.CurrentCluster);
break;
case RSVD_CLUSTER:
SERPRINT("ERROR: Found reserved cluster in FAT file chain.\r\n");
return(FALSE);
break;
case BAD_CLUSTER:
SERPRINT("ERROR: Found bad cluster in FAT file chain.\r\n");
return(FALSE);
break;
default:
SERPRINT("ERROR: Unable to determine contiguous cluster grouping (start cluster = 0x%x).\r\n", g_FileInfo.CurrentCluster);
return(FALSE);
}
}
// Determine the number of clusters we can read at this time.
//
ClustersToRead = MIN(g_ReadBuffLenInClusters, g_FileInfo.NumContigClusters);
// Read data from storage.
//
if (!ReadSectors(g_FATParms.DriveId, Cluster2LBA(g_FileInfo.CurrentCluster), (USHORT)(ClustersToRead * g_FATParms.SectsPerClust), g_pReadBuffStart))
{
SERPRINT("ERROR: Failed to read data from storage (starting cluster = 0x%x number of clusters = 0x%x).\r\n", g_FileInfo.CurrentCluster, ClustersToRead);
return(FALSE);
}
// EdbgDumpHexBuf((PUCHAR)g_pReadBuffStart,512*2);
// Update read management data.
//
g_FileInfo.NumContigClusters -= ClustersToRead;
g_FileInfo.CurrentCluster += ClustersToRead;
g_FileInfo.pCurReadBuffAddr = g_pReadBuffStart;
g_FileInfo.NumReadBuffBytes = (ClustersToRead * g_FATParms.SectsPerClust * g_FATParms.BytesPerSect);
if(g_FileInfo.pTotalReadByte ==0)
EdbgOutputDebugString("Reading Image File.");
g_FileInfo.pTotalReadByte += g_FileInfo.NumReadBuffBytes;
if((g_FileInfo.pTotalReadByte & 0xfffff ) ==0)
EdbgOutputDebugString(".");
else if(g_FileInfo.pTotalReadByte >= g_FileInfo.FileSize)
EdbgOutputDebugString("OK\r\n");
}
while (Length);
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -