📄 sma_fat16.c
字号:
fat16_read_sectors (file_data->fat_data,
file_data->dir_data, file_data->sector_dir,
file_data->fat_data->cfat.root_sectors);
}
valid = 0;
}
return valid;
}
/***********************************************************************
*
* Function: fat16_get_dirname
*
* Purpose:
* Returns the name and type of the entry in the active directory (in
* unpadded 8.3 format).
*
* Processing:
* See function.
*
* Parameters:
* file_data : Pointer to a file data structure
* name : Pointer of where to return name
* etype : Pointer of where to return dir entry type
* empty : Pointer of where to return dir entry use flag
* last : If set, this was the last entry in the directory
*
* Outputs:
* None
*
* Returns:
* The index to the active directory entry (only valid if empty and
* last are not set).
*
* Notes:
* The type and empty flags should be checked after a call to this
* function. If empty is set(1), the dir entry is not used.
*
**********************************************************************/
INT_32 fat16_get_dirname (file_type *file_data, CHAR *name,
UNS_8 *etype, INT_32 *empty, INT_32 *last)
{
INT_32 index, i, catch_char;
index = i = 0;
catch_char = 1;
while ((catch_char == 1) && (i < 8))
{
// Look for spaces marking end of name string
if (file_data->dir_data [file_data->dir_index].name [i] == ' ')
{
// Space found,
catch_char = 0;
}
else
{
// Not the end of the string, copy into name
name [index] =
file_data->dir_data [file_data->dir_index].name [i];
index++;
}
i++;
}
i = 0;
catch_char = 1;
while ((catch_char == 1) && (i < 3))
{
// Look for spaces marking end of extension string
if (file_data->dir_data [file_data->dir_index].ext [i] == ' ')
{
// Space found,
catch_char = 0;
}
else
{
// Add dot for extension seperation
if (i == 0)
{
name [index] = '.';
index++;
}
// Not the end of the string, copy into name
name [index] =
file_data->dir_data [file_data->dir_index].ext [i];
index++;
}
i++;
}
// Terminate string
name [index] = '\0';
// Save type of entry
*etype = file_data->dir_data [file_data->dir_index].attribute;
// Set state of empty flag based on if the directory is used
if (file_data->dir_data [file_data->dir_index].name [0] ==
DIR_FREE)
{
// This is the last entry in the directory
*empty = 1;
*last = 1;
// Loop back to first entry number
file_data->dir_index = 0;
}
else if (file_data->dir_data [file_data->dir_index].name [0] ==
DIR_ERASED)
{
*empty = 1;
file_data->dir_index++;
}
else
{
*empty = 0;
index = file_data->dir_index;
file_data->dir_index++;
}
// Rollover dir index if it goes too far (should never make it here)
if (file_data->dir_index >=
file_data->fat_data->pat_hdr.root_entries)
{
fat16_set_dir_index (file_data, 0);
}
return index;
}
/***********************************************************************
*
* Function: fat16_set_dir_index
*
* Purpose:
* Resets the directory index to a location of the directory (used
* with get_dirname)
*
* Processing:
* See function.
*
* Parameters:
* file_data : Pointer to a file data structure
* index : DIR entry index to set the active dir entry to
*
* Outputs:
* None
*
* Returns:
* Nothing
*
* Notes:
* None
*
**********************************************************************/
void fat16_set_dir_index (file_type *file_data, INT_32 index)
{
// Limit index value to valid range
if ((index >= 0) &&
(index < file_data->fat_data->pat_hdr.root_entries))
{
file_data->dir_index = index;
}
}
/***********************************************************************
*
* Function: fat16_delete
*
* Purpose:
* Deletes a file in the active directory.
*
* Processing:
* See function.
*
* Parameters:
* file_data : Pointer to a file data structure
* name : Name of file to delete
*
* Outputs:
* None
*
* Returns:
* '1' if the operation was successful, '0' otherwise.
*
* Notes:
* None
*
**********************************************************************/
INT_32 fat16_delete (file_type *file_data, CHAR *name)
{
INT_32 dir_index, loop;
UNS_16 cluster_num, next_cluster;
INT_32 valid = 0;
// Find the directory entry for the file
dir_index = fat16_find_file (name, file_data);
// Continue if the directory is valid
if (dir_index >= 0)
{
// Get first cluster number
cluster_num = file_data->dir_data [dir_index].clusternum;
valid = 1;
// Continue until all clusters are cleared
loop = 1;
while (loop == 1)
{
// Get next cluster
next_cluster = fat16_get_next_cluster (
file_data->fat_data, cluster_num);
// Free this cluster
file_data->fat_data->clusters [cluster_num] = CLUSTER_AV;
// Exit conditions
if (next_cluster > CLUSTERR_MAX)
{
loop = 0;
}
else
{
cluster_num = next_cluster;
}
}
// Free up the directory entry
file_data->dir_data [dir_index].name [0] = DIR_ERASED;
// Update FAT and directory update flags
file_data->dir_commit = 1;
file_data->fat_data->fat_commit = 1;
}
return valid;
}
/***********************************************************************
*
* Function: fat16_open_file
*
* Purpose:
* Open a file for reading or writing.
*
* Processing:
* See function.
*
* Parameters:
* name : Name of file
* file_data : Pointer to a FILE data structure to use
* mode : File mode (FREAD or FWRITE)
*
* Outputs:
* None
*
* Returns:
* '1' if the operation was successful, '0' otherwise.
*
* Notes:
* None
*
**********************************************************************/
INT_32 fat16_open_file (CHAR *name, file_type *file_data, INT_32 mode)
{
INT_32 dir_index;
INT_32 valid = 0;
// If file is already open, then exit with error
if (file_data->fmode == FINVALID)
{
// Find the file or see if it already exists
dir_index = fat16_find_file (name, file_data);
// Reset buffer pointer index
file_data->buf_index = 0;
if ((mode == FREAD) && (dir_index >= 0))
{
// Read operation
// Make sure the type is a archive file
if ((file_data->dir_data [dir_index].attribute &
ATTB_ARCHIVE) != 0)
{
// Save active file entry
file_data->file_dir_entry = dir_index;
// Set cluster pointer to start of file
file_data->clusternum =
file_data->dir_data [dir_index].clusternum;
file_data->fmode = FREAD;
// Save filesize
file_data->filesize =
file_data->dir_data [dir_index].filesize;
// Perform an initial cluster read
fat16_read_sectors (file_data->fat_data,
file_data->data,
fat16_translate_cluster_to_sector (
file_data->fat_data, file_data->clusternum),
(UNS_32) file_data->fat_data->pat_hdr.sectors_cluster);
valid = 1;
}
}
else if (mode == FWRITE)
{
// Write mode
if (dir_index >= 0)
{
// File already exists, so delete existing versions
fat16_delete (file_data, name);
}
// Find a free cluster to point the file to
file_data->clusternum = fat16_find_free_cluster (
file_data->fat_data, 0);
// Only continue if there is enough room left
if (file_data->clusternum != 0)
{
// There is some room left, add directory
dir_index = fat16_get_free_dir_entry (file_data);
file_data->file_dir_entry = dir_index;
// Only continue if entry was valid
if (dir_index >= 0)
{
valid = 1;
file_data->fmode = FWRITE;
// Clear initial filesize of written data
file_data->filesize = 0;
// Save some basic directory information
file_data->dir_data [dir_index].attribute =
ATTB_ARCHIVE;
file_data->dir_data [dir_index].createtimems = 0;
file_data->dir_data [dir_index].createtime = 0;
file_data->dir_data [dir_index].createdate = 0;
file_data->dir_data [dir_index].createtimems = 0;
file_data->dir_data [dir_index].accessdate = 0;
file_data->dir_data [dir_index].clusterhi = 0;
file_data->dir_data [dir_index].updatetime =
DEFAULT_CR_TIME;
file_data->dir_data [dir_index].updatedate =
DEFAULT_CR_DATE;
file_data->dir_data [dir_index].filesize = 0;
// Normally, the reserved field should be set to 0x0,
// but some NT systems will not correctly recognize
// the file is not set to 0x18.
file_data->dir_data [dir_index].reserved1 = 0x18;
// Save starting cluster for this file
file_data->dir_data [dir_index].clusternum =
file_data->clusternum;
// Convert name to correct space padded format
fat16_name_break (name,
file_data->dir_data [dir_index].name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -