📄 fat.c
字号:
if (FAT_32 == g_FATParms.FATType)
{
SERPRINT( "INFO: The dump of Root directory for FAT-32 is not done yet!\n" );
}
else
{
SERPRINT( "DumpRootDir: FAT-12/FAT16\n" );
SERPRINT( "Entry DirName Cluster Filesize \n" );
// 0x0001 12345678.123 0x0000:0000 0x000000001
for (sector = g_FATParms.RootDirLBA;
(sector < (g_FATParms.RootDirLBA + g_FATParms.SectorsPerFAT)) && !bEndOfDir;
sector++)
{
if (FALSE == ReadSectors( g_FATParms.DriveId, sector, 1, g_pReadBuffStart ) )
{
SERPRINT( "ERROR: Couldn't read non-FAT-32 root dir for dump!\r\n" );
return;
}
pDirEntry = (DIRENTRY *) g_pReadBuffStart;
for (i = 0; i < numEntriesPerSector; ++i, pDirEntry++)
{
// Since Long filename entries have all 4 lower bits set, we must test for it first...
if ((pDirEntry->FATTr & 0x0F) != FAT_ATTR_LONG_NAME)
{
memcpy( fName, (UCHAR *)pDirEntry->FileName, (sizeof( fName ) - 1) );
SERPRINT( "0x%04lX %11.11s 0x%X:%X 0x%08lX\n",
((sector - g_FATParms.RootDirLBA) * numEntriesPerSector) + i + 1,
fName, pDirEntry->FirstClusterHigh,
pDirEntry->FirstClusterLow,
pDirEntry->FileSize );
}
if (pDirEntry->FileName[0] == 0x00)
{
// According to Microsoft documentation, there are
// no other entries after this one to look at...
// So, should I trust the documentation??? I don't know!
bEndOfDir = TRUE;
}
}
}
}
return;
}
#endif // ( DUMP_ROOT_DIR )
#if defined( DUMP_FAT_TABLE )
void DumpFATTable( void )
{
unsigned int Cluster;
unsigned int numClusters;
BOOL bDumpFATTable = FALSE;
USHORT uShort1, uShort2;
ULONG byteOffset;
ULONG numFATSectors2Read =
MIN( g_FATParms.SectorsPerFAT,
(READ_BUFFER_LENGTH_MAX / g_FATParms.BytesPerSect) );
ULONG clusterValue = 0;
if ( !bDumpFATTable )
{
SERPRINT( "\r\nFAT Table dump is currently disabled\r\n" );
return;
}
// Dump the entire FAT table to SERPRINT...
SERPRINT("\r\nFAT table dump: FAT starts at LBA(0x%04lX) Size(0x%04lX)\r\n", g_FATParms.FATLBA, g_FATParms.SectorsPerFAT );
SERPRINT("\r\n");
if (FALSE == ReadSectors( g_FATParms.DriveId, g_FATParms.FATLBA,
numFATSectors2Read, g_pReadBuffStart ) )
{
SERPRINT( "ERROR: Couldn't read FAT table for dump!\r\n" );
return;
}
switch( g_FATParms.FATType )
{
case FAT_12:
// each cluster takes 12 bits...
numClusters =
MIN( g_FATParms.CountOfClusters,
((numFATSectors2Read * g_FATParms.BytesPerSect * 3) / 2 ) );
break;
case FAT_32:
// each cluster takes 32 bits...
numClusters =
MIN( g_FATParms.CountOfClusters,
(numFATSectors2Read * g_FATParms.BytesPerSect)/ sizeof( ULONG ) );
numClusters = 0x18B0; // too many clusters otherwise!!!
break;
case FAT_16:
default:
// each cluster takes 16 bits...
numClusters =
MIN( g_FATParms.CountOfClusters,
(numFATSectors2Read * g_FATParms.BytesPerSect)/ sizeof( USHORT ) );
break;
}
SERPRINT( "\r\nCluster Value\r\n" );
//0x00000000 0x00000000
// The first cluster is 2...
for (Cluster = 2; Cluster < (numClusters + 1); ++Cluster)
{
switch(g_FATParms.FATType)
{
case FAT_12:
// each cluster takes 12 bits...
// Cluster: 2 3 4 5 6 7 8 9 A B C D
// 22 23 33 44 45 55 66 67 77 88 89 99 AA AB BB CC CD DD
// Cluster: E F 10 11 12 13 14 15 16 17 18 19
// EE EF FF 00 01 11 22 23 33 44 45 55 66 67 77 88 89 99
// Cluster: 1A 1B 1C 1D
// AA AB BB CC CD DD
byteOffset = (Cluster * 3)/2;
// Get the bytes to be processed...
uShort1 = *((PUCHAR) (g_pReadBuffStart + byteOffset));
uShort2 = *((PUCHAR) (g_pReadBuffStart + byteOffset + 1));
// determine if the cluster is odd or even...
if (Cluster & 0x01)
{
// how odd, an odd cluster number!
uShort1 = (uShort1 >> 4);
uShort2 = (uShort2 << 4);
clusterValue = uShort1 | uShort2;
}
else
{
// must be an even cluster, uShort1 does not change...
uShort2 = (uShort2 & 0x0F);
uShort2 = (uShort2 << 8);
clusterValue = uShort1 | uShort2;
}
break;
case FAT_32:
byteOffset = Cluster * sizeof( ULONG );
clusterValue = *((PULONG) (g_pReadBuffStart + byteOffset));
break;
case FAT_16:
default:
byteOffset = Cluster * sizeof( USHORT );
clusterValue = *((PUSHORT) (g_pReadBuffStart + byteOffset));
break;
}
SERPRINT( "0x%08X 0x%08lX\r\n", Cluster, clusterValue );
}
SERPRINT( "\r\nEnd of FAT table dump\n" );
}
#endif // ( DUMP_FAT_TABLE )
//
// Initialize the FAT subsystem.
//
BOOL InitFAT(ULONG uFirstPartitionLBA)
{
UCHAR bsect[SECTOR_SIZE];
PBIOSPB pBPB = NULL;
tOffset36_FAT16 *pFAT16Extension = NULL;
tOffset36_FAT32 *pFAT32Extension = NULL;
ULONG ReadBufferLen = 0;
UCHAR FATType[9];
#if defined( NDEF_DWF_PARTIIONS )
pPARTITION_ENTRY pPartition = NULL;
int i;
#endif // ( NDEF_DWF_PARTIIONS )
// Locate and verify single active partition in MBR.
memset (&bsect[0], 0, SECTOR_SIZE);
if (FALSE == ReadSectors( g_FATParms.DriveId, uFirstPartitionLBA, 1, (PUCHAR) &bsect[0] ) )
{
SERPRINT( "ERROR: Couldn't read BOOT in FAT.\r\n" );
return(-1);
}
// EdbgDumpHexBuf((PUCHAR)&bsect[0],SECTOR_SIZE);
//
// The BIOS parameter block is in the MBR just read, so point to that block...
//
pBPB = (PBIOSPB)&bsect[0];
// setup the extension ptrs for later use...
pFAT16Extension = (tOffset36_FAT16 *)&pBPB->Offset36Extension[ 0 ];
pFAT32Extension = (tOffset36_FAT32 *)&pBPB->Offset36Extension[ 0 ];
//
// Determine FAT type by determining the "count of cluster" on the volume.
//
// First find the number of sectors in the root directory. This will always
// be zero for FAT32 volumes because pBPB->NumRootEntries will be zero!
//
g_FATParms.RootDirSectors =
((pBPB->NumRootEntries * 32) + (pBPB->BytesPerSect - 1)) / pBPB->BytesPerSect + uFirstPartitionLBA;
// Determine size of FAT tables...
if ( pBPB->SectsPerFAT16 != 0 )
{
g_FATParms.SectorsPerFAT = pBPB->SectsPerFAT16;
}
else
{
// it is beginning to look a lot like FAT32!!!
// but we are not done yet!
g_FATParms.SectorsPerFAT = pFAT32Extension->SectsPerFAT32;
}
if ( pBPB->TotalSectors16 != 0 )
{
g_FATParms.TotalSectors = pBPB->TotalSectors16;
}
else
{
g_FATParms.TotalSectors = pBPB->TotalSectors32;
}
g_FATParms.NumFATs = pBPB->NumFATs;
g_FATParms.ReservedSects = pBPB->RsvdSects;
g_FATParms.NumHiddenSectors = pBPB->NumHiddenSectors;
g_FATParms.DataRegionSectors =
g_FATParms.TotalSectors -
(g_FATParms.ReservedSects + (g_FATParms.NumFATs * g_FATParms.SectorsPerFAT) +
g_FATParms.RootDirSectors);
// It is okay that the following calculation rounds down!
g_FATParms.CountOfClusters = g_FATParms.DataRegionSectors / pBPB->SectsPerClust;
if ( g_FATParms.CountOfClusters < 4085 )
{
g_FATParms.FATType = FAT_12;
}
else if ( g_FATParms.CountOfClusters < 65525 )
{
g_FATParms.FATType = FAT_16;
}
else
{
g_FATParms.FATType = FAT_32;
}
//
// Get the FAT filesystem description.
//
if ( (g_FATParms.FATType == FAT_12) ||
(g_FATParms.FATType == FAT_16) )
{
memcpy(FATType, (void *)pFAT16Extension->TypeFAT16, 8);
}
else
{
memcpy(FATType, (void *)pFAT32Extension->TypeFAT32, 8);
}
FATType[8] = '\0';
//
// Compute LBA for various disk regions.
//
// The start of the data region, the first sector of cluster 2 is...
g_FATParms.DataStartLBA = g_FATParms.ReservedSects +
(g_FATParms.NumFATs * g_FATParms.SectorsPerFAT) +
g_FATParms.RootDirSectors;
g_FATParms.NumRootEntries = pBPB->NumRootEntries;
g_FATParms.BytesPerSect = pBPB->BytesPerSect;
if (g_FATParms.FATType == FAT_32)
{
g_FATParms.RootDirCluster = pFAT32Extension->RootFirstCluster;
g_FATParms.RootDirLBA = Cluster2LBA( g_FATParms.RootDirCluster );
g_FATParms.DriveId = pFAT32Extension->DriveId32;
// FAT LBA starts right after the reserved sectors
g_FATParms.FATLBA = g_FATParms.ReservedSects + uFirstPartitionLBA;
}
else
{
// FAT-12/16 FAT root is not an allocated cluster!
g_FATParms.RootDirCluster = 0;
// Since it is not an allocated cluster, then calculate the LBA
// here...
g_FATParms.RootDirLBA =
g_FATParms.DataStartLBA -
((sizeof(DIRENTRY) * g_FATParms.NumRootEntries) / g_FATParms.BytesPerSect);
g_FATParms.DriveId = pFAT16Extension->DriveId16;
// FAT LBA starts right after the reserved sectors
g_FATParms.FATLBA = g_FATParms.ReservedSects + uFirstPartitionLBA;
}
if ((sizeof(DIRENTRY) * g_FATParms.NumRootEntries) % g_FATParms.BytesPerSect)
{
--g_FATParms.RootDirLBA;
}
g_FATParms.SectsPerClust = pBPB->SectsPerClust;
g_FATParms.NumHeads = (USHORT) pBPB->NumHeads;
g_FATParms.SectsPerTrack = pBPB->SectsPerTrack;
// Some BIOS/floppy combinations don't support multi-sector reads.
// On a PC BIOS based system, a drive ID < 0x80 is a floppy disk.
// We will not have that here! So, set the ReadBufferLen to the
// maximum rather than the number of bytes per sector!
// ReadBufferLen = ((pBPB->DriveId < 0x80) ? g_FATParms.BytesPerSect : READ_BUFFER_LENGTH_MAX);
ReadBufferLen = READ_BUFFER_LENGTH_MAX;
//
// Initialize the read buffer.
//
if (!InitReadBuffer(READ_BUFFER_START, ReadBufferLen))
{
SERPRINT("ERROR: Failed to initialize read buffer.\r\n");
return(FALSE);
}
#if defined( DUMP_FAT_INFO )
SERPRINT("\r\nDrive Info:\r\n");
SERPRINT(" - Drive ID ................... 0x%x\r\n", g_FATParms.DriveId);
SERPRINT(" - Heads ...................... 0x%x\r\n", g_FATParms.NumHeads);
SERPRINT(" - Number of Sectors Per Track 0x%x\r\n", g_FATParms.SectsPerTrack);
SERPRINT(" - Sector Size ............... 0x%x\r\n\r\n", g_FATParms.BytesPerSect);
SERPRINT("FAT Info:\r\n");
SERPRINT(" - FAT Type ................... %s(%d)\r\n", FATType, g_FATParms.FATType );
SERPRINT(" - Cluster Size ............... 0x%x\r\n", (g_FATParms.SectsPerClust * g_FATParms.BytesPerSect));
SERPRINT(" - Number of FATs ............. 0x%x\r\n", g_FATParms.NumFATs);
SERPRINT(" - Number of Sectors Per FAT .. 0x%x\r\n", g_FATParms.SectorsPerFAT);
SERPRINT(" - Number of Hidden Sectors ... 0x%x\r\n", g_FATParms.NumHiddenSectors);
SERPRINT(" - Number of Reserved Sectors . 0x%x\r\n\r\n", g_FATParms.ReservedSects);
SERPRINT(" - Root dir location (LBA) .... 0x%x\r\n", g_FATParms.RootDirLBA);
SERPRINT(" - FAT location (LBA) ......... 0x%x\r\n", g_FATParms.FATLBA);
SERPRINT(" - Data location (LBA) ........ 0x%x\r\n\r\n", g_FATParms.DataStartLBA);
#if defined( DUMP_ROOT_DIR )
DumpRootDir();
#endif // (DUMP_ROOT_DIR )
#if defined( DUMP_FAT_TABLE )
DumpFATTable();
#endif // ( DUMP_FAT_TABLE )
#endif // ( DUMP_FAT_INFO )
#if defined( NDEF_DWF_PARTIIONS )
i = 0;
pPartition = (pPARTITION_ENTRY) &bsect[ 446 ];
while (i < 4)
{
SERPRINT(" - partion %2d: bootFlag(0x%X) type(0x%X) LBA(0x%08lX)\r\n",
i, pPartition->ucBootFlag, pPartition->ucPartitionType,
pPartition->startLBA );
pPartition++;
++i;
}
#endif // ( NDEF_DWF_PARTIIONS )
return(TRUE);
}
PDIRENTRY SearchBufferForFile(
PCHAR pFileName,
PUCHAR pBuffer,
USHORT uiNumSectors
)
{
PDIRENTRY result = NULL;
PDIRENTRY pDirEntry = NULL;
USHORT j = 0;
int dirCnt = 0;
int lfCnt = 0;
int fileCnt = 0;
//
// Try to find the specified file in the root directory...
//
for ( pDirEntry = (PDIRENTRY) pBuffer, j = 0;
j < (g_FATParms.BytesPerSect * uiNumSectors) / sizeof(DIRENTRY);
j++, pDirEntry++ )
{
// Since Long filename entries have all 4 lower bits set, we must test for it first...
if ((pDirEntry->FATTr & 0x0F) == FAT_ATTR_LONG_NAME)
{
lfCnt++;
// SERPRINT( "INFO: Skipped Long Filename entry ('%s'), attrib(0x%X)\r\n", pDirEntry->FileName, pDirEntry->FATTr );
continue;
}
if ((pDirEntry->FATTr & 0x10) == FAT_ATTR_DIRECTORY)
{
dirCnt++;
// SERPRINT( "INFO: Skipped directory entry ('%s'), attrib(0x%X)\r\n", pDirEntry->FileName, pDirEntry->FATTr );
continue;
}
fileCnt++;
if (!memcmp(pFileName, (void *)pDirEntry->FileName, 11))
{
//
// Found it, so get ready to return a ptr to it...
//
// SERPRINT("INFO: Found the file!!\r\n" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -