📄 fat_layer.c
字号:
* file_seek
* Purpose: This function is used to reposition the read pointer in the
* file.
* Supported operations:
*
* API:
* -- file_handle = pointer to a valid file handle
* -- int index = offset from initial start of file in BYTES
*
* -- int whence = other info about how to seek
*/
BOOL file_seek(FILE_HNDL_PTR file_handle, LONG index, LONG whence){
LONG cluster_index=0;
LONG sector_index=0;
LONG byte_index=0;
LONG bytes_per_cluster;
int remainder;
#if FAT_DEBUG
if(DEBUG_FILE_SEEK){
printf("\nfile_handle: %x, ", file_handle);
printf("index: %x,", index);
printf("whence: %x\n", whence);
}
#endif
bytes_per_cluster = file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust *
file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec;
if(whence == ABSOLUTE_SEEK){
file_handle->byte_index = index;
}else if (whence == RELATIVE_SEEK){
file_handle->byte_index += index;
file_handle->curr_sector_offset += index;
}
if(file_handle->byte_index >= file_handle->dir_entry->dir_file_size){
return FALSE;
}
#if FAT_DEBUG
if(DEBUG_FILE_SEEK){
printf("Cluster: %x, Sector: %x, Byte:%x\n", file_handle->curr_cluster,
file_handle->curr_sector_index,
file_handle->curr_sector_offset);
}
#endif
if(whence == RELATIVE_SEEK){
if(file_handle->curr_sector_offset >= file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec){
file_handle->curr_sector_index += (file_handle->curr_sector_offset / file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec);
file_handle->curr_sector_offset %= file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec;
}
if(file_handle->curr_sector_index >= file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust){
cluster_index += (file_handle->curr_sector_index / file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust);
file_handle->curr_sector_index %= file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust;
}
}
if(whence == ABSOLUTE_SEEK){
file_handle->curr_cluster = (file_handle->dir_entry->dir_clust_hi << sizeof(LONG) |
file_handle->dir_entry->dir_clust_low);
}
while(cluster_index > 0){
file_handle->vol_ptr->fat_op=FAT_GET;
file_handle->vol_ptr->fat_num=file_handle->curr_cluster;
doFatTableOp(file_handle->vol_ptr);
/* finding the cluster number depends on the FAT type */
if (file_handle->vol_ptr->fat_type == FAT12){
if (file_handle->vol_ptr->fat_num & 0x0001)
file_handle->curr_cluster = (file_handle->vol_ptr->fat_data) >> 4;
else
file_handle->curr_cluster = (file_handle->vol_ptr->fat_data) & 0x0FFF;
}else
file_handle->curr_cluster = file_handle->vol_ptr->fat_data;
cluster_index-=1;
}
#if FAT_DEBUG
if(DEBUG_FILE_SEEK){
printf("Cluster: %x, Sector: %x, Byte:%x\n", file_handle->curr_cluster,
file_handle->curr_sector_index,
file_handle->curr_sector_offset);
}
#endif
return TRUE;
}
/*
* fileOp
* Purpose: This function is called to perform an operation on a file's
* data area.
* Supported operations:
* -- read : reads a sectors worth of data to the disk
* -- write : writes a sectors worth of data to the disk
*
* API:
* -- file_handle->file_op = FILE_READ | FILE_WRITE
* -- file_handle->file_op_data1 = (LONG) number of bytes to read
* -- file_handle->file_op_data2 = (BYTE *) pointer to the receiving/sending buffer
*
* Returns:
*/
#define DEBUG_FILEOP FALSE
int fileOp(FILE_HNDL_PTR file_handle){
LONG num_bytes_to_process=0, fetch_this_num_bytes=0, bytes_left_in_sector=0;
LONG bytes_done=0, index=0;
/*
* To do:
* we could cache the last operation and location to determine the next cluster and
* sector to read/write
*/
/*
* process number of bytes to read.. let the ride begin
* run through the sectors in the cluster
*/
num_bytes_to_process = file_handle->file_op_data1;
if((file_handle->byte_index + num_bytes_to_process) >=
file_handle->dir_entry->dir_file_size){
num_bytes_to_process = file_handle->dir_entry->dir_file_size -
file_handle->byte_index;
}
bytes_done = num_bytes_to_process;
/*
* We can simply jump in and start reading, as all of the nasty computation
* regarding cluster, sector, and offet has been done by lseek
*/
#if FAT_DEBUG
if(DEBUG_FILEOP){
printf("fileOp-> file_op_data1 = %x, file_op_data2 = %x\n",
file_handle->file_op_data1,
file_handle->file_op_data2);
}
#endif
while(num_bytes_to_process > 0){
/* if the operation was a partial write, read in the sector, and then write it out. */
file_handle->cluster_op = CLUSTER_READ;
file_handle->cluster_op_data1 = file_handle->curr_cluster;
file_handle->cluster_op_data2 = file_handle->curr_sector_index;
/*
* To do:
* fix up reads and writes of sectors so that if a sector is in memory, it is
* not re-read.
*/
if(file_handle->cluster_op == CLUSTER_READ){
#if FAT_DEBUG
if(DEBUG_FILEOP){
printf("calling fileop-> curr_cluster: %x, curr_sector_index: %x\n",
file_handle->curr_cluster,
file_handle->curr_sector_index);
}
#endif
doClusterOp(file_handle);
/*
* How many bytes left in this sector...
* we can only fetch the number left in the sector... at max
*/
bytes_left_in_sector = file_handle->vol_ptr->fat_bytes_per_sec -
file_handle->curr_sector_offset;
if(num_bytes_to_process > bytes_left_in_sector){
fetch_this_num_bytes = bytes_left_in_sector;
num_bytes_to_process -= bytes_left_in_sector;
}else{
fetch_this_num_bytes = num_bytes_to_process;
num_bytes_to_process=0;
}
/* Stop thrashing the index */
memcpy(file_handle->file_op_data2 + index,
file_handle->fat_file_buf + file_handle->curr_sector_offset,
fetch_this_num_bytes);
index+=fetch_this_num_bytes;
}else if(file_handle->file_op == CLUSTER_WRITE){
/*
* To do:
* fix file writes
*/
printf("ERROR: fileOp() - write not currently supported\n");
}
file_seek(file_handle, fetch_this_num_bytes, RELATIVE_SEEK);
}
file_handle->file_op_data1 = bytes_done;
return 0;
}
/*
* These are all the high level access functions
*/
BOOL kill_file_handle(FILE_HNDL_PTR file_handle){
/*
* To do:
* make this routine work
*/
printf("ERROR: kill_file_handle() not yet supported\n");
return FALSE;
}
BOOL close_file(FILE_HNDL_PTR file_handle){
/*
* To do:
* make this routine work
*/
printf("ERROR: close_file() not yet supported\n");
return FALSE;
}
LONG read_file(FILE_HNDL_PTR file_handle,
BYTE *buffer,
LONG size){
if(size > file_handle->dir_entry->dir_file_size){
//printf("error: read_file: char_number > dir_file_size\n");
// return FALSE;
size = file_handle->dir_entry->dir_file_size;
}
if(size >= (file_handle->dir_entry->dir_file_size-file_handle->byte_index))
size = file_handle->dir_entry->dir_file_size-file_handle->byte_index;
/*
* o.k., down to business... lets start readin'
* calculate number of clusters to dive into
* calculate the correct sector to get
* read/write the sector
*/
file_handle->file_op=FILE_READ;
file_handle->file_op_data1=size;
file_handle->file_op_data2=buffer;
fileOp(file_handle);
return(file_handle->file_op_data1);
};
//
// fileByIndexOp
//
// API:
// -- file_handle->file_op = GET_NUM_FILES
// -- file_handle->file_op_data1 = index
// -- file_handle->file_op_data2 = (BYTE *) name of entry to search for
//
// Returns:
// GET_NUM_FILES => file_handle->file_op_data1 = number of files in dir
// GET_FILE_BY_INDEX
// =>file_handle->file_ptr = the necessary info to read the file
// =>file_handle->file_op_data2 = the name of the file on the fat
//
#define DEBUG_FILECOUNT FALSE
int get_file_count(FILE_HNDL_PTR file_handle){
char /*file_name[11],*/ search_name[11];
LONG cluster_to_search;
int dir_entry_offset;
BYTE *dir_entry;
LONG sec_num=0, sectors_per_cluster=0;
LONG cluster_num;
int index=0;
BOOL done=FALSE;
//int char_count;
unsigned int fileCount = 0;
FAT_FILE_PTR tmp_dir_entry_ptr;
/*
* Non - Root directories that need to be searched
* We'll handle this later................
*/
if(0 ) {
/* op + cluster number */
file_handle->cluster_op = CLUSTER_READ;
file_handle->cluster_op_data1 = file_handle->curr_cluster;
sectors_per_cluster = file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust;
#if FAT_DEBUG
if(DEBUG_FILECOUNT){
}
#endif
/* Just in case you need to root around in the root directory. */
}else if((file_handle->file_op == GET_NUM_FILES)||
(file_handle->file_op == GET_FILE_BY_INDEX)){
file_handle->cluster_op = ROOT_READ;
sectors_per_cluster = file_handle->vol_ptr->root_sectors;
#if FAT_DEBUG
if(DEBUG_FILECOUNT){
printf("root_file_op\n");
printf("op: %x, spc: %x\n",
file_handle->cluster_op,
sectors_per_cluster);
}
#endif
}
/*
* Loop over all entries in the clusters for this directory
* Lookin' for the file...
*/
while(!done){
/*
* In the case of the root directory under FAT 16, we don't
* need to go beyond the size of our root directory in
* terms of sectors...
*/
done=TRUE;
for(sec_num=0;(sec_num < sectors_per_cluster);sec_num++){
file_handle->cluster_op_data2=sec_num;
doClusterOp(file_handle);
/* Read done, now iterate over entries in the sector */
for(dir_entry_offset=0;
dir_entry_offset < file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec;
dir_entry_offset += sizeof(FAT_FILE))
{
// file_handle->dir_entry = (FAT_FILE_PTR)(file_handle->fat_file_buf + dir_entry_offset);
tmp_dir_entry_ptr = (FAT_FILE_PTR)(file_handle->fat_file_buf + dir_entry_offset);
#if FAT_DEBUG
if(DEBUG_FILECOUNT)
{
printf("Entry: ");
debug_print((BYTE *)tmp_dir_entry_ptr->dir_name, 11);
printf("\n");
}
#endif
/* No more files in the directory... go home! */
if(tmp_dir_entry_ptr->dir_name[0] == 0x00)
{
file_handle->file_op_data1=fileCount;
if(file_handle->file_op == GET_FILE_BY_INDEX)
return FALSE;
else
return TRUE;
}
else
{
if(!(*(tmp_dir_entry_ptr->dir_attr) & (ATTR_READ_ONLY |
ATTR_HIDDEN |
ATTR_SYSTEM |
ATTR_VOLUME_ID)))
{
if(!(*(tmp_dir_entry_ptr->dir_attr) & ATTR_DIRECTORY)){
if(tmp_dir_entry_ptr->dir_name[0] != 0xE5)
fileCount++;
#if FAT_DEBUG
if(DEBUG_FILECOUNT)
printf("File Count: %d\n", fileCount);
#endif
}
}
if((file_handle->file_op == GET_FILE_BY_INDEX) &&
(fileCount == (file_handle->file_op_data1+1)))
{
memcpy((BYTE*)file_handle->dir_entry, (BYTE*)tmp_dir_entry_ptr, sizeof(FAT_FILE));
file_handle->curr_cluster=(file_handle->dir_entry->dir_clust_hi << sizeof(LONG) |
file_handle->dir_entry->dir_clust_low);
file_handle->curr_sector_index = 0;
file_handle->curr_sector_offset = 0;
file_handle->byte_index = 0;
#if FAT_DEBUG
if(DEBUG_FILECOUNT)
{
printf("Curr cluster: %x\n", file_handle->curr_cluster);
}
#endif
file_handle->file_op_data1=(fileCount-1);
return(TRUE);
}
}
}
}
return(FALSE);
}
return 0;
}
int FAT_GetNumFiles(FILE_HNDL_PTR file_handle){
file_handle->file_op = GET_NUM_FILES;
if(get_file_count(file_handle))
return(file_handle->file_op_data1);
else
return 0;
}
BOOL FAT_GetFileByIndex(FILE_HNDL_PTR file_handle, int index){
file_handle->file_op = GET_FILE_BY_INDEX;
file_handle->file_op_data1 = index;
if(get_file_count(file_handle))
return(TRUE);
else
return(FALSE);
}
void FAT_GetShortName(FILE_HNDL_PTR file_handle, char *buf){
memcpy((char*)buf, (char*)file_handle->dir_entry->dir_name, 11);
buf[11]=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -