📄 sma_fat16.c
字号:
// Also tag the present cluster as 'used' by linking
// to itself
file_data->fat_data->clusters [file_data->clusternum] =
file_data->clusternum;
}
}
}
}
return valid;
}
/***********************************************************************
*
* Function: fat16_read
*
* Purpose:
* Read data from a file.
*
* Processing:
* See function.
*
* Parameters:
* file_data : Pointer to a file data structure
* bytes_to_copy : Number of bytes to copy
* buffer_ptr : Pointer to buffer to copy
* bytes_copied : Pointer to where to return number of bytes copied
* eof : Pointer to end of file flag, set on eof
*
* Outputs:
* None
*
* Returns:
* '1' if the operation was successful, '0' otherwise.
*
* Notes:
* None
*
**********************************************************************/
INT_32 fat16_read (file_type *file_data, INT_32 bytes_to_copy,
void *buffer_ptr, INT_32 *bytes_copied, INT_32 *eof)
{
INT_32 index;
UNS_8 *buffer = (UNS_8 *) buffer_ptr;
INT_32 valid = 0;
// Set up initial values for function
*bytes_copied = 0;
*eof = 0;
// Only continue if the file is open for read operations
if (file_data->fmode == FREAD)
{
valid = 1;
index = 0;
// Copy out the specified number of bytes or until file end
while ((bytes_to_copy > 0) && (file_data->filesize > 0))
{
// Does a new cluster need to be read in?
if (file_data->buf_index >=
(INT_32) file_data->fat_data->cfat.cluster_size)
{
// Entire cluster buffer has been emptied, buffer a
// new cluster and reset index
file_data->buf_index = 0;
file_data->clusternum = fat16_get_next_cluster (
file_data->fat_data, file_data->clusternum);
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);
}
else
{
// Start reading data up to the filesize limit or the
// copy size, whichever comes first
while ((bytes_to_copy > 0) &&
(file_data->filesize > 0) &&
(file_data->buf_index <
file_data->fat_data->cfat.cluster_size))
{
buffer [index] =
file_data->data [file_data->buf_index];
// Update buffered index, filesize, and bytes copied
index++;
file_data->buf_index++;
file_data->filesize--;
bytes_to_copy--;
*bytes_copied = *bytes_copied + 1;
}
}
}
}
// If there were no errors, and total file was copied, set EOF flag
if ((valid == 1) && (file_data->filesize == 0))
{
*eof = 1;
}
return valid;
}
/***********************************************************************
*
* Function: fat16_write
*
* Purpose:
* Write data to a file.
*
* Processing:
* See function.
*
* Parameters:
* file_data : Pointer to a file data structure
* bytes_to_copy : Number of bytes to write
* buffer_ptr : Pointer to buffer to copy
*
* Outputs:
* None
*
* Returns:
* '1' if the operation was successful, '0' if the device is out of
* storage space.
*
* Notes:
* None
*
**********************************************************************/
INT_32 fat16_write (file_type *file_data, void *buffer_ptr,
INT_32 bytes_to_copy)
{
INT_32 index;
UNS_16 next_cluster, save_cluster;
UNS_8 *buffer = (UNS_8 *) buffer_ptr;
INT_32 valid = 0;
// Only continue if the file is open for write operations
if (file_data->fmode == FWRITE)
{
valid = 1;
index = 0;
// Continue copying until buffer is empty or an error occurs
while ((bytes_to_copy > 0) && (valid == 1))
{
// Is the data ready to write?
if (file_data->buf_index >=
file_data->fat_data->cfat.cluster_size)
{
// Buffer is the size of a cluster, write data
fat16_write_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);
// Clear buffer index
file_data->buf_index = 0;
// Get next free cluster number
next_cluster = fat16_find_free_cluster (
file_data->fat_data, file_data->clusternum);
// Is cluster valid (indicating the device is not full)?
if (next_cluster > 0)
{
// Cluster is good, setup link to cluster
file_data->fat_data->clusters [file_data->clusternum]
= next_cluster;
file_data->clusternum = next_cluster;
// Temporarily tag present cluster as 'pointing to
// itself' so the clear logic can clear it if needed
file_data->fat_data->clusters [next_cluster] =
next_cluster;
}
else
{
// No more free clusters, error
valid = 0;
// Since there is no more room, remove the file from
// the device completely (by clearing the directory
// entry and allocated FAT clusters)
file_data->dir_data [file_data->file_dir_entry].name [0] =
DIR_ERASED;
// Return the used clusters to 'free'
next_cluster =
file_data->dir_data [file_data->file_dir_entry].clusternum;
while (next_cluster != 0)
{
save_cluster = fat16_get_next_cluster (
file_data->fat_data, next_cluster);
file_data->fat_data->clusters [next_cluster] = 0;
next_cluster = save_cluster;
}
// The file descriptor is no longer valid
file_data->fmode = FINVALID;
}
}
else
{
// Keep moving data into the work buffer
file_data->data [file_data->buf_index] = buffer [index];
// update counters
index++;
file_data->buf_index++;
file_data->filesize++;
bytes_to_copy--;
}
}
}
return valid;
}
/***********************************************************************
*
* Function: fat16_close_file
*
* Purpose:
* Close a file that was open for reading or writing.
*
* Processing:
* See function.
*
* Parameters:
* file_data : Pointer to a file data structure
*
* Outputs:
* None
*
* Returns:
* Nothing
*
* Notes:
* None
*
**********************************************************************/
void fat16_close_file (file_type *file_data)
{
INT_32 i;
// If the last operation was a write operation, update the DIR
// structure
if (file_data->fmode == FWRITE)
{
// Fill the reset of the buffer with zeros, and write the
// buffer out to the device
for (i = file_data->buf_index;
i < file_data->fat_data->cfat.cluster_size; i++)
{
file_data->data [i] = 0;
}
// Write cluster to device
fat16_write_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);
// Set the present cluster to the last flasg in the list
file_data->fat_data->clusters [file_data->clusternum] =
CLUSTER_MAX;
// Update file size in directory structure
file_data->dir_data [file_data->file_dir_entry].filesize =
file_data->filesize;
// Set cached dir change and FAT cluster flags
file_data->dir_commit = 1;
file_data->fat_data->fat_commit = 1;
}
file_data->fmode = FINVALID;
}
/***********************************************************************
*
* Function: fat16_get_active_mbr
*
* Purpose:
* Returns an index to the first FAT partition.
*
* Processing:
* See function.
*
* Parameters:
* file_data : Pointer to a file data structure
* use_active_only : Flag that indicates that active partions are used
* support_no_mbr : Flag that allows MBR-less device support
*
* Outputs:
* None
*
* Returns:
* Nothing
*
* Notes:
* None
*
**********************************************************************/
INT_32 fat16_get_active_mbr (fat_device_type *fat_data,
INT_32 use_active_only, INT_32 support_no_mbr)
{
INT_32 i = 0, active = -2;
UNS_8 data [PTAB_SIZE + 512];
// Loop until first valid partition found or until all have been
// processed
while (active == -2)
{
if ((fat_data->part [i].partype == FAT16_LT32M) ||
(fat_data->part [i].partype == FAT16_EXDOS) ||
(fat_data->part [i].partype == FAT16_GT32M))
{
// Valid partition flag
if (use_active_only == 0)
{
active = i + 1;
}
else if ((fat_data->part [i].state & PART_ACTV) != 0)
{
active = i + 1;
}
}
else
{
i++;
if (i >= 4)
{
// No partition found
active = -1;
}
}
}
// If no partition is usable and support for mbr-less devices is
// needed, then read sector 0 again
if ((active == -1) && (support_no_mbr != 0))
{
fat16_set_no_mbr (fat_data);
// Read sector 1 and check the extended signature to see if it
// is valid
// fat16_read_sectors (fat_data, &data, 1, 1);
// Is extended signature valid?
// if (data [EXTENDED_SIG_IDX] == EXTENDED_SIG)
{
active = 1;
}
}
return active;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -