fileio.c
来自「SD卡驱动」· C语言 代码 · 共 2,353 行 · 第 1/5 页
C
2,353 行
return(c);
}
/******************************************************************************
* Function: WORD FATReadQueued( DISK *dsk, WORD ccls)
*
* PreCondition: Disk mounted
*
* Input: dsk - Disk structure
*
* Output: c - Cluster; 0 if failed
*
* Side Effects: None
*
* Overview: Queue based FAT read
*
* Note: Should not be called by user
*****************************************************************************/
WORD FATReadQueued( DISK *dsk, WORD ccls)
// dsk disk structure
// ccls current cluster
{
WORD p, c;
DWORD l;
if ( dsk->type != FAT16)
return CLUSTER_FAIL;
gBufferOwner = NULL;
// get address of current cluster in fat
p = ccls;
// cluster = 0xabcd
// packed as: 0 | 1 | 2 | 3 |
// word p 0 1 | 2 3 | 4 5 | 6 7 |..
// cd ab| cd ab| cd ab| cd ab|
// load the fat sector containing the cluster
if((ccls & 0xFF) == 0x00)
{
l = dsk->fat + (p >> 8 ); // 256 clusters per sector
if( !SECTORread( l, dsk->buffer) )
return CLUSTER_FAIL;
}
// get the next cluster value
c = RAMreadW( dsk->buffer, ((p & 0xFF)<<1));
if(c >= LAST_CLUSTER_FAT16)
c = LAST_CLUSTER;
return c;
} // FATReadQueued
/******************************************************************************
* Function: CETYPE __fclose(FILEOBJ fo)
*
* PreCondition: File opened
*
* Input: fo - Pointer to file structure
*
* Output: CE_GOOD - File closed successfully
* CE_WRITE_ERROR - Could not write to the sector
* CE_FILENOTOPENED - File not opened for the write
*
* Side Effects: None
*
* Overview: Close a file
*
* Note:
*****************************************************************************/
CETYPE __fclose(FILEOBJ fo)
{
WORD fHandle, fIndex;
CETYPE error = 72;
DIRENTRY dir;
fHandle = fo->entry;
if(fo->Flags.write)
{
// Get the entry
dir = LoadDirAttrib(fo, &fHandle);
// update the time
IncrementTimeStamp(dir);
dir->DIR_FileSize = fo->size;
// just write the last entry in
if(Write_File_Entry(fo,&fHandle))
error = CE_GOOD;
else
error = CE_WRITE_ERROR;
// its now closed!
fo->Flags.write = FALSE;
}
#ifdef FAT16_DYNAMIC_MEM
FAT16_free((unsigned char *)fo);
#else
for( fIndex = 0; fIndex < FAT16_MAX_FILES_OPEN; fIndex++ )
{
if( fo == &gFileArray[fIndex] )
{
gFileSlotOpen[fIndex] = TRUE;
break;
}
}
#endif
if (error == 72)
error = CE_GOOD;
return(error);
} // my_fclose
/******************************************************************************
* Function: void IncrementTimeStamp(DIRENTRY dir)
*
* PreCondition: File opened
*
* Input: dir - Pointer to directory structure
*
* Output: void
*
* Side Effects: None
*
* Overview: Touch the time so we can keep track of the files
*
* Note: None
*****************************************************************************/
void IncrementTimeStamp(DIRENTRY dir)
{
BYTE seconds;
BYTE minutes;
BYTE hours;
BYTE day;
BYTE month;
BYTE year;
seconds = (dir->DIR_WrtTime & 0x1f);
minutes = ((dir->DIR_WrtTime & 0x07E0) >> 5);
hours = ((dir->DIR_WrtTime & 0xF800) >> 11);
day = (dir->DIR_WrtDate & 0x1f);
month = ((dir->DIR_WrtDate & 0x01E0) >> 5);
year = ((dir->DIR_WrtDate & 0xFE00) >> 9);
if(seconds < 29)
seconds++;
else
{
seconds = 0x00;
if(minutes < 59)
{
minutes++;
}
else
{
minutes = 0;
if(hours < 23)
{
hours++;
}
else
{
hours = 0;
// new day!... only 28 in a month
if(day < 28)
{
day++;
}
else
{
day = 1;
if(month < 12)
{
month++;
}
else
{
month = 1;
// new year
year++;
// HOPEFULLY we never go past 2107
}
}
}
}
}
dir->DIR_WrtTime = (WORD)(seconds);
dir->DIR_WrtTime |= ((WORD)(minutes) << 5);
dir->DIR_WrtTime |= ((WORD)(hours) << 11);
dir->DIR_WrtDate = (WORD)(day);
dir->DIR_WrtDate |= ((WORD)(month) << 5);
dir->DIR_WrtDate |= ((WORD)(year) << 9);
}
/******************************************************************************
* Function: BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
*
* PreCondition: Disk mounted
*
* Input: fo - Pointer to file structure
* fHandle - Passed member's location
*
* Output: FOUND - Operation successful
* NOT_FOUND - Operation failed
*
* Side Effects: None
*
* Overview: Fill the passed file object with the passed member's (fHandle) information
*
* Note: Should not be called by user
*****************************************************************************/
BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
{
DIRENTRY dir;
BYTE index, a;
BYTE character;
BYTE status;
DWORD temp;
BYTE test = 0;
// Get the entry
dir = Cache_File_Entry( fo, fHandle, FALSE);
// Read the first char of the file name
a = dir->DIR_Name[0];
// Make sure there is a directory left
if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
{
status = NO_MORE;
}
else
{
// Check for empty or deleted directory
if ( a == DIR_DEL)
status = NOT_FOUND;
else
{
// Get the attributes
a = dir->DIR_Attr;
/* Short File Name */
// 2.1.1 print the file name and extension
for (index=0; index < DIR_NAMESIZE; index++)
{
character = dir->DIR_Name[index];
character = (BYTE)toupper(character);
fo->name[test++] = character;
}
// Get the attributes
a = dir->DIR_Attr;
// its possible to have an extension in a directory
character = dir->DIR_Extension[0];
// Get the file extension if its there
for (index=0; index < DIR_EXTENSION; index++)
{
character = dir->DIR_Extension[index];
character = (BYTE)toupper(character);
fo->name[test++] = character;
}
// done and done with the name
// fo->name[++test] = (BYTE)'\0';
// Now store the identifier
fo->entry = *fHandle;
// see if we are still a good file (long file names can erase just the main entry)
a = dir->DIR_Name[0];
if(a == DIR_DEL)
status = NOT_FOUND;
else
status = FOUND;
// Now store the size
fo->size = (dir->DIR_FileSize);
// Now store the cluster
temp = (dir->DIR_FstClusHI);
temp = temp << 16;
temp |= dir->DIR_FstClusLO;
fo->cluster = temp;
// get the date and time
fo->time = (dir->DIR_WrtTime);
fo->date = (dir->DIR_WrtDate);
/// -Get and store the attributes
a = dir->DIR_Attr;
fo->attributes = a;
}// deleted directory
}// Ensure we are still good
return(status);
} // Fill_File_Object
/******************************************************************************
* Function: DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
*
* PreCondition: Disk mounted
*
* Input: fo - Pointer to file structure
* fHandle - Information location
*
* Output: DIRENTRY - The directory entry
*
* Side Effects: None
*
* Overview: Load the current sector for the filename base and return the direntry
*
* Note: Should not be called by user
*****************************************************************************/
DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
{
DIRENTRY dir;
BYTE a;
// Get the entry
dir = Cache_File_Entry( fo, fHandle, TRUE);
// Read the first char of the file name
a = dir->DIR_Name[0];
// Make sure there is a directory left
if(a == DIR_EMPTY)
dir = (DIRENTRY)NULL;
if(dir != (DIRENTRY)NULL)
{
// Check for empty or deleted directory
if ( a == DIR_DEL)
dir = (DIRENTRY)NULL;
else
{
// Get the attributes
a = dir->DIR_Attr;
// scan through all the long dir entries
while(a == ATTR_LONG_NAME)
{
(*fHandle)++;
dir = Cache_File_Entry( fo, fHandle, FALSE);
a = dir->DIR_Attr;
} // long file name while loop
} // deleted dir
}// Ensure we are still good
return(dir);
} // LoadDirAttrib
/******************************************************************************
* Function: CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
*
* PreCondition: File not opened, File exists
*
* Input: fo - Pointer to file structure
* fHandle - Location of file information
* EraseClusters - Remove cluster allocation from FAT?
*
* Output: CE_GOOD - File erased successfully
* CE_FILE_NOT_FOUND - Could not find the file on the card
* CE_ERASE_FAIL - Internal Card erase failed
*
* Side Effects: None
*
* Overview: Erase file
*
* Note: Should not be called by user
*****************************************************************************/
CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
{
DIRENTRY dir;
BYTE a;
CETYPE status = CE_GOOD;
WORD clus;
DISK * disk;
disk = fo->dsk;
// reset the cluster
clus = fo->dirclus;
fo->dirccls = clus;
// load the sector
dir = Cache_File_Entry(fo, fHandle, TRUE);
// Fill up the File Object with the information pointed to by fHandle
a = dir->DIR_Name[0];
// see if there is something in the dir
if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
{
status = CE_FILE_NOT_FOUND;
}
else
{
// Check for empty or deleted directory
if ( a == DIR_DEL)
status = CE_FILE_NOT_FOUND;
else
{
// Get the attributes
a = dir->DIR_Attr;
/* Short File Name - entry*/
dir->DIR_Name[0] = DIR_DEL; // mark as deleted
// Get the starting cluster
clus = dir->DIR_FstClusLO;
// Now write it
if(status != CE_GOOD || !(Write_File_Entry( fo, fHandle)))
status = CE_ERASE_FAIL;
else
{
if(EraseClusters)
{
/* Now my_remove the cluster allocation from the FAT */
status = ((FAT_erase_cluster_chain(clus, disk)) ? CE_GOOD : CE_ERASE_FAIL);
}
}
} // Not already deleted
}// Not existant
return (status);
}
/******************************************************************************
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?