📄 fat.c
字号:
if(entrycount == entry)
{
// desired entry has been found, break out
gotEntry = 1;
break;
}
// otherwise
entrycount++; // increment entry counter
}
}
}
// next directory entry
de++;
// next index
index++;
}
// we have a file/dir to return
// store file/dir starting cluster (start of data)
FileInfo.StartCluster = (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
// store file/dir size
// (note: size field for subdirectory entries is always zero)
FileInfo.Size = de->deFileSize;
// store file/dir attributes
FileInfo.Attr = de->deAttributes;
// store file/dir creation time
FileInfo.CreateTime = de->deCTime[0] | de->deCTime[1]<<8;
// store file/dir creation date
FileInfo.CreateTime = de->deCDate[0] | de->deCDate[1]<<8;
return gotEntry;
}
///////////////////////////////////////////////////////////////////////////////////
/*
index = 16; // crank it up
do
{
if(index == 16) // time for next sector ?
{
ataReadSectors( DRIVE0, sector++, 1, SectorBuffer);
de = (struct direntry *) SectorBuffer;
index = 0;
}
// check if this is a deleted entry slot
if(de->deName[0] != 0xE5)
{
// a valid entry
// is it a part of a long file/dir name?
if(de->deAttributes == ATTR_LONG_FILENAME)
{
// we have a long name entry
// cast this directory entry as a "windows" (LFN: LongFileName) entry
we = (struct winentry *) de;
b = WIN_ENTRY_CHARS*( (we->weCnt-1) & 0x0f); // index into string
fnbPtr = &FileNameBuffer[b];
for (i=0;i<5;i++) *fnbPtr++ = we->wePart1[i*2]; // copy first part
for (i=0;i<6;i++) *fnbPtr++ = we->wePart2[i*2]; // second part
for (i=0;i<2;i++) *fnbPtr++ = we->wePart3[i*2]; // and third part
if (we->weCnt & 0x40) *fnbPtr = 0; // in case dirnamelength is multiple of 13
if ((we->weCnt & 0x0f) == 1) hasBuffer = 1; // mark that we have a long entry
}
else
{
// we have a short name entry
// check if this is the end of a multi-part long name entry
if(hasBuffer)
{
// a long entry name has been collected
if(entrycount == entry)
{
// desired entry has been found, break out
break;
}
hasBuffer = 0; // clear buffer
entrycount++; // increment entry counter
}
else
{
// entry is a short name (8.3 format)
fnbPtr = FileNameBuffer;
for (i=0;i<8;i++) *fnbPtr++ = de->deName[i]; // copy name
*fnbPtr++ = '.'; // insert '.'
for (i=0;i<3;i++) *fnbPtr++ = de->deExtension[i]; // copy extension
*fnbPtr = 0; // null-terminate
if(entrycount == entry)
{
// desired entry has been found, break out
hasBuffer = 1;
break;
}
entrycount++; // increment entry counter
}
}
}
// next directory entry
de++;
// next index
index++;
} while (*(de->deName) || index == 16); // 0 in de->deName[0] if no more entries
*/
///////////////////////////////////////////////////////////////////////////////////
// is it a directory ?
/* if(de->deAttributes == ATTR_DIRECTORY)
{
unsigned long save = FirstDirCluster;
unsigned int save2 = baseentry;
unsigned long rval;
strcpy(DirNameBuffer,FileNameBuffer);
strcat(DirNameBuffer,"/");
// rprintfStr(FileNameBuffer); rprintfStr("/"); //EOL();
// call recursively
FirstDirCluster = ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
rval = fatGetDirEntry(entry,1);
FirstDirCluster = save;
baseentry = save2;
if (rval)
return rval;
else
{
// reload original sector
ataReadSectors( DRIVE0, sector-1, 1, SectorBuffer);
entrycount--; // decrement entry counter
*DirNameBuffer = 0;
}
}
else // normal file entry
*/
//////////////////////////////////////////////////////////////////////////////////
// change directory into
unsigned char fatChangeDirectory(unsigned short entry)
{
// get the requested directory entry
if( fatGetDirEntry(entry) )
{
// make sure the entry is a directory
if(FileInfo.Attr & ATTR_DIRECTORY)
{
// change directories into this directory
// check to see if we are changing back to root directory
if(FileInfo.StartCluster)
{
// standard change directory
CurrentDirStartCluster = FileInfo.StartCluster;
}
else
{
// if startCluster pointer is zero,
// a change to the root directory is intended
// change directory to root
CurrentDirStartCluster = RootDirStartCluster;
}
// TODO: handle pathname properly for going up a directory
// set path string
strcat(PathNameBuffer, FileNameBuffer);
strcat(PathNameBuffer, "\\");
// return success
return TRUE;
}
else
{
// not a directory, cannot CD into a file!
return FALSE;
}
}
else
{
// not a valid entry, cannot CD!
return FALSE;
}
}
void fatPrintDirEntry(void)
{
// print a formatted dir-style output for most recent file
// print date
rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_MONTH_MASK)>>DD_MONTH_SHIFT ); // month
rprintfChar('/');
rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_DAY_MASK)>>DD_DAY_SHIFT ); // day
rprintfChar('/');
rprintfNum(10, 4, FALSE, '0', (FileInfo.CreateDate&DD_YEAR_MASK)>>DD_YEAR_SHIFT ); // year
rprintfChar(' ');
// print time
rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_HOURS_MASK)>>DT_HOURS_SHIFT ); // month
rprintfChar(':');
rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_MINUTES_MASK)>>DT_MINUTES_SHIFT ); // day
rprintfChar(':');
rprintfNum(10, 2, FALSE, '0', 2*(FileInfo.CreateTime&DT_2SECONDS_MASK)>>DT_2SECONDS_SHIFT ); // seconds
rprintfChar(' ');
// print attributes
if(FileInfo.Attr & ATTR_VOLUME) rprintfChar('V'); else rprintfChar('-');
if(FileInfo.Attr & ATTR_DIRECTORY) rprintfChar('D'); else rprintfChar('-');
if(FileInfo.Attr & ATTR_READONLY) rprintfChar('R'); else rprintfChar('-');
if(FileInfo.Attr & ATTR_HIDDEN) rprintfChar('H'); else rprintfChar('-');
if(FileInfo.Attr & ATTR_SYSTEM) rprintfChar('S'); else rprintfChar('-');
if(FileInfo.Attr & ATTR_ARCHIVE) rprintfChar('A'); else rprintfChar('-');
rprintfChar(' ');
// print filesize
rprintfNum(10, 8, FALSE, ' ', FileInfo.Size); // filesize
rprintfChar(' ');
// print filename
rprintfStr(FileNameBuffer);
}
void fatDumpDirSlot(unsigned short slot)
{
unsigned long sector;
// load correct sector
sector = fatClustToSect(CurrentDirStartCluster);
sector += slot/DIRENTRIES_PER_SECTOR;
// print the entry as a hex table
debugPrintHexTable(32, SectorBuffer+(slot<<5) );
}
struct FileInfoStruct* fatGetFileInfo(void)
{
return &FileInfo;
}
// return the size of the last directory entry
unsigned long fatGetFilesize(void)
{
return FileInfo.Size;
}
// return the long name of the last directory entry
char* fatGetFilename(void)
{
return FileNameBuffer;
}
// return the directory of the last directory entry
char* fatGetDirname(void)
{
return PathNameBuffer;
}
// load a clusterfull of data
void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
{
register unsigned char i;
// read cluster
//while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0);
for(i=0; i<SectorsPerCluster; i++)
{
ataReadSectors( DRIVE0, fatClustToSect(cluster)+i, 1, buffer+(i<<9) );
// temporary fix for wierd misaligned cluster problem
// (only when using FAT16?)
// ataReadSectors( DRIVE0, fatClustToSect(cluster+8)+i, 1, buffer+(i<<9) );
}
}
// find next cluster in the FAT chain
unsigned long fatNextCluster(unsigned long cluster)
{
unsigned long nextCluster;
unsigned long fatMask;
unsigned long fatOffset;
unsigned long sector;
unsigned int offset;
// get fat offset in bytes
if(Fat32Enabled)
{
// four FAT bytes (32 bits) for every cluster
fatOffset = cluster << 2;
// set the FAT bit mask
fatMask = FAT32_MASK;
}
else
{
// two FAT bytes (16 bits) for every cluster
fatOffset = cluster << 1;
// set the FAT bit mask
fatMask = FAT16_MASK;
}
// calculate the FAT sector that we're interested in
sector = FirstFATSector + (fatOffset / BytesPerSector);
// calculate offset of the our entry within that FAT sector
offset = fatOffset % BytesPerSector;
// if we don't already have this FAT chunk loaded, go get it
if (sector != FatInCache)
{
// read sector of FAT table
while (ataReadSectors( DRIVE0, sector, 1, (unsigned char*)FAT_CACHE_ADDR) != 0);
FatInCache = sector;
}
// read the nextCluster value
nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;
// check to see if we're at the end of the chain
if (nextCluster == (CLUST_EOFE & fatMask))
nextCluster = 0;
#ifdef DEBUG_FAT
rprintfStr(">");
rprintfu32(nextCluster);
rprintfCRLF();
#endif
return nextCluster;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -