FX_FS.C
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:14k
- /**************************************************************************/
- /* */
- /* Copyright (c) 1996-2002 by Express Logic Inc. */
- /* */
- /* This software is copyrighted by and is the sole property of Express */
- /* Logic, Inc. All rights, title, ownership, or other interests */
- /* in the software remain the property of Express Logic, Inc. This */
- /* software may only be used in accordance with the corresponding */
- /* license agreement. Any unauthorized use, duplication, transmission, */
- /* distribution, or disclosure of this software is expressly forbidden. */
- /* */
- /* This Copyright notice may not be removed or modified without prior */
- /* written consent of Express Logic, Inc. */
- /* */
- /* Express Logic, Inc. reserves the right to modify this software */
- /* without notice. */
- /* */
- /* Express Logic, Inc. info@expresslogic.com */
- /* 11423 West Bernardo Court http://www.expresslogic.com */
- /* San Diego, CA 92127 */
- /* */
- /**************************************************************************/
- /**************************************************************************/
- /**************************************************************************/
- /** */
- /** FileX Component */
- /** */
- /** File (FIL) */
- /** */
- /**************************************************************************/
- /**************************************************************************/
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef ENABLE_FILEX
- #ifdef _DEBUG
- #undef IFTRACE
- #define IFTRACE if (gTraceFileSys)
- #include "DebugDbgMain.h"
- #endif //_DEBUG
- #define FX_SOURCE_CODE
- /* Include necessary system files. */
- #include "PlaycoreFileSysFileXfx_api.h"
- #include "PlaycoreFileSysFileXfx_sys.h"
- #include "PlaycoreFileSysFileXfx_dir.h"
- #include "PlaycoreFileSysFileXfx_fil.h"
- #include "PlaycoreFileSysFileXfx_uti.h"
- /**************************************************************************/
- /* */
- /* FUNCTION RELEASE */
- /* */
- /* _fx_file_seek PORTABLE C */
- /* 3.0 */
- /* AUTHOR */
- /* */
- /* William E. Lamie, Express Logic, Inc. */
- /* */
- /* DESCRIPTION */
- /* */
- /* This function positions the internal file pointers to the specified */
- /* byte offset such that the next read or write operation will be */
- /* performed there. If the byte offset is greater than the size, the */
- /* file pointers will be positioned to the end of the file. */
- /* */
- /* INPUT */
- /* */
- /* file_ptr File control block pointer */
- /* byte_offset Byte offset into the file */
- /* */
- /* OUTPUT */
- /* */
- /* return status */
- /* */
- /* CALLS */
- /* */
- /* _fx_utility_FAT_entry_read Read a FAT entry */
- /* */
- /* CALLED BY */
- /* */
- /* Application Code */
- /* */
- /* RELEASE HISTORY */
- /* */
- /* DATE NAME DESCRIPTION */
- /* */
- /* 01-01-1999 William E. Lamie Initial Version 1.0 */
- /* 04-19-1999 William E. Lamie Added logic to seek to the */
- /* end of a file whose size */
- /* is evenly divisible by */
- /* the media's cluster size, */
- /* resulting in version 1.0a. */
- /* 03-01-2000 William E. Lamie Modified comment(s), */
- /* resulting in version 1.0b. */
- /* 01-28-2001 William E. Lamie Modified comment(s), */
- /* resulting in version 2.0. */
- /* 03-01-2002 Mohammad N. Minhaz Modified comment(s), */
- /* changed to 32 bit variables,*/
- /* fixed possible infinite loop*/
- /* caused by a corrupt FAT, */
- /* and added logic to determine*/
- /* consecutive clusters, */
- /* resulting in version 3.0. */
- /* */
- /**************************************************************************/
- UINT _fx_file_seek(FX_FILE *file_ptr, ULONG byte_offset)
- {
- UINT status;
- ULONG cluster;
- ULONG contents;
- ULONG bytes_per_cluster;
- ULONG last_cluster;
- ULONG cluster_count;
- ULONG bytes_remaining;
- FX_MEDIA *media_ptr;
- ULONG fat_reserved;
- /* First, determine if the file is still open. */
- if (file_ptr -> fx_file_id != FX_FILE_ID)
- {
- /* Return the file not open error status. */
- return(FX_NOT_OPEN);
- }
- /* Setup pointer to associated media control block. */
- media_ptr = file_ptr -> fx_file_media_ptr;
- /* Determine the type of FAT and setup variables accordingly. */
- if (media_ptr -> fx_media_32_bit_FAT) fat_reserved = FX_RESERVED_1_32;
- else fat_reserved = FX_RESERVED_1;
- /* Protect against other threads accessing the media. */
- FX_PROTECT
- /* Calculate the number of bytes per cluster. */
- bytes_per_cluster = ((ULONG) media_ptr -> fx_media_bytes_per_sector) *
- ((ULONG) media_ptr -> fx_media_sectors_per_cluster);
- /* See if we need to adjust the byte offset. */
- if (byte_offset > file_ptr -> fx_file_current_file_size)
- {
- /* Adjust the byte offset down to the file size. */
- byte_offset = file_ptr -> fx_file_current_file_size;
- }
- /* check if the desired position within the leading consecutive clusters */
- if (byte_offset >= file_ptr -> fx_file_consecutive_cluster * bytes_per_cluster)
- {
- /* At this point, we are ready to walk list of clusters to setup the
- seek position of this file. */
- /* check if byte_offset is greater than where we were left off earlier */
- if (file_ptr -> fx_file_current_relative_cluster * bytes_per_cluster < byte_offset)
- {
- cluster = file_ptr -> fx_file_current_physical_cluster;
- bytes_remaining = byte_offset -
- file_ptr -> fx_file_current_relative_cluster * bytes_per_cluster;
- cluster_count = file_ptr -> fx_file_current_relative_cluster;
- last_cluster = 0;
- }
- else
- {
- cluster = file_ptr -> fx_file_first_physical_cluster +
- (file_ptr -> fx_file_consecutive_cluster - 1);
- bytes_remaining = byte_offset -
- (file_ptr -> fx_file_consecutive_cluster - 1)* bytes_per_cluster;
- last_cluster = 0;
- cluster_count = (file_ptr -> fx_file_consecutive_cluster - 1);
- }
- /* Follow the link of FAT entries. */
- while ((cluster >= FX_FAT_ENTRY_START) && (cluster < fat_reserved))
- {
- /* Increment the number of clusters. */
- cluster_count++;
- /* Read the current cluster entry from the FAT. */
- status = _fx_utility_FAT_entry_read(media_ptr, cluster, &contents);
- /* Check the return value. */
- if (status != FX_SUCCESS)
- {
- /* Release media protection. */
- FX_UNPROTECT
- /* Return the error status. */
- return(status);
- }
- /* Save the last valid cluster. */
- last_cluster = cluster;
- /* Setup for the next cluster. */
- cluster = contents;
- /* Determine if this is the last written cluster. */
- if (bytes_remaining > bytes_per_cluster)
- {
- /* Still more seeking, just decrement the working byte offset. */
- bytes_remaining = bytes_remaining - bytes_per_cluster;
- }
- else
- {
- /* Remember this cluster number. */
- file_ptr -> fx_file_current_physical_cluster = last_cluster;
- /* Remember the relative cluster. */
- file_ptr -> fx_file_current_relative_cluster = cluster_count-1;
- /* If the remaining bytes exactly fits the cluster size, check for
- a possible adjustment to the next cluster. */
- if ((bytes_remaining == bytes_per_cluster) &&
- (cluster >= FX_FAT_ENTRY_START) && (cluster < fat_reserved))
- {
- /* We need to position to next allocated cluster. */
- file_ptr -> fx_file_current_physical_cluster = cluster;
- file_ptr -> fx_file_current_relative_cluster++;
- /* Clear the remaining bytes. */
- bytes_remaining = 0;
- }
- /* This is the cluster that contains the seek position. */
- break;
- }
- }
- }
- else
- {
- /* we should directly access the desired cluster */
- file_ptr -> fx_file_current_relative_cluster = byte_offset/bytes_per_cluster;
- file_ptr -> fx_file_current_physical_cluster =
- file_ptr -> fx_file_first_physical_cluster + file_ptr -> fx_file_current_relative_cluster;
- bytes_remaining = byte_offset % bytes_per_cluster;
- }
- /* Determine if the remaining bytes fit exactly into the cluster size. */
- if (bytes_remaining == bytes_per_cluster)
- {
- /* Position to the end of the cluster. */
- file_ptr -> fx_file_current_logical_sector = ((ULONG) media_ptr -> fx_media_data_sector_start) +
- (((ULONG) file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) *
- ((ULONG) media_ptr -> fx_media_sectors_per_cluster)) +
- ((bytes_remaining-1) / (ULONG) media_ptr -> fx_media_bytes_per_sector);
- file_ptr -> fx_file_current_relative_sector = (UINT) (((bytes_remaining-1) / (ULONG) media_ptr -> fx_media_bytes_per_sector));
- file_ptr -> fx_file_current_file_offset = byte_offset;
- file_ptr -> fx_file_current_logical_offset = media_ptr -> fx_media_bytes_per_sector;
- }
- else
- {
- /* Position the pointers to the new offset. */
- file_ptr -> fx_file_current_logical_sector = ((ULONG) media_ptr -> fx_media_data_sector_start) +
- (((ULONG) file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) *
- ((ULONG) media_ptr -> fx_media_sectors_per_cluster)) +
- (bytes_remaining / (ULONG) media_ptr -> fx_media_bytes_per_sector);
- file_ptr -> fx_file_current_relative_sector = (UINT) ((bytes_remaining / (ULONG) media_ptr -> fx_media_bytes_per_sector));
- file_ptr -> fx_file_current_file_offset = byte_offset;
- file_ptr -> fx_file_current_logical_offset = bytes_remaining % ((ULONG) media_ptr -> fx_media_bytes_per_sector);
- }
-
- /* Release media protection. */
- FX_UNPROTECT
- /* Seek is complete, return successful status. */
- return(FX_SUCCESS);
- }
- #endif