FX_DER.C
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:20k
- /**************************************************************************/
- /* */
- /* 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 */
- /** */
- /** Directory (DIR) */
- /** */
- /**************************************************************************/
- /**************************************************************************/
- #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_uti.h"
- /**************************************************************************/
- /* */
- /* FUNCTION RELEASE */
- /* */
- /* _fx_directory_entry_read PORTABLE C */
- /* 3.0 */
- /* AUTHOR */
- /* */
- /* William E. Lamie, Express Logic, Inc. */
- /* */
- /* DESCRIPTION */
- /* */
- /* This function reads the supplied directory entry from the supplied */
- /* source directory. If the supplied directory entry is NULL, then */
- /* the root directory is assumed. */
- /* */
- /* INPUT */
- /* */
- /* media_ptr Media control block pointer */
- /* source_dir Source directory entry */
- /* entry_ptr Directory entry number */
- /* destination_ptr Pointer to destination for */
- /* the directory entry */
- /* */
- /* OUTPUT */
- /* */
- /* return status */
- /* *entry_ptr should point to the 8:3 entry if it is a long name */
- /* */
- /* CALLS */
- /* */
- /* _fx_utility_log_sector_read Read directory sector */
- /* _fx_utility_16_unsigned_read Read an UINT from memory */
- /* _fx_utility_32_unsigned_read Read an ULONG from memory */
- /* */
- /* CALLED BY */
- /* */
- /* FileX System Functions */
- /* */
- /* RELEASE HISTORY */
- /* */
- /* DATE NAME DESCRIPTION */
- /* */
- /* 01-01-1999 William E. Lamie Initial Version 1.0 */
- /* 04-19-1999 William E. Lamie Corrected reading directory */
- /* time and date entries, */
- /* 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) and */
- /* deleted old directory cache */
- /* invalidate code, resulting */
- /* in version 2.0. */
- /* 03-01-2002 Mohammad N. Minhaz Changed to 32 bit variables */
- /* In 32 bit root directory is */
- /* treated like subdirectory, */
- /* changed long representation */
- /* and added long name support */
- /* resulting in version 3.0. */
- /* */
- /**************************************************************************/
- UINT _fx_directory_entry_read(FX_MEDIA *media_ptr, FX_DIR_ENTRY *source_dir,
- ULONG *entry_ptr, FX_DIR_ENTRY *destination_ptr)
- {
- UINT i, j, card, dotflag, get_short_name;
- UINT status;
- ULONG cluster, next_cluster, next_logical_sector;
- UINT relative_cluster;
- UINT relative_sector;
- ULONG logical_sector;
- ULONG byte_offset;
- ULONG bytes_per_cluster;
- UCHAR_PTR read_ptr;
- ULONG fat_reserved;
- ULONG entry = *entry_ptr;
- /* Determine which FAT is present and setup variables accordingly. */
- if (media_ptr -> fx_media_32_bit_FAT) fat_reserved = FX_RESERVED_1_32;
- else fat_reserved = FX_RESERVED_1;
- /* Calculate the byte offset of this directory entry. */
- byte_offset = entry * FX_DIR_ENTRY_SIZE;
- /* Determine if a sub-directory is specified. */
- if ((source_dir) || (media_ptr -> fx_media_32_bit_FAT))
- {
- /* Yes, a sub-directory is present. */
- /* 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);
- /* Now determine the relative cluster in the sub-directory file. */
- relative_cluster = byte_offset/bytes_per_cluster;
- /* Calculate the byte offset within the cluster. */
- byte_offset %= bytes_per_cluster;
- /* Now figure out the relative sector within the cluster. */
- relative_sector = byte_offset/((ULONG) media_ptr -> fx_media_bytes_per_sector);
- /* Read the directory sector into the internal memory buffer. */
- /* Loop to position to the appropriate cluster. */
- if (source_dir)
- cluster = source_dir -> fx_dir_entry_cluster;
- else cluster = media_ptr ->fx_media_root_clus_32;
- for (i = 0; ; i++)
- {
- /* Check the value of the new cluster - it must be a valid cluster number
- or something is really wrong! */
- if ((cluster < FX_FAT_ENTRY_START) || (cluster > fat_reserved))
- {
- /* Send error message back to caller. */
- return(FX_FILE_CORRUPT);
- }
- /* Read the next cluster. */
- status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster);
- /* There is a potential for loop, but hardly anything can be done */
- /* Check for I/O error. */
- if (status != FX_SUCCESS)
- {
- /* Return error code. */
- return(status);
- }
- if (i < relative_cluster) cluster = next_cluster;
- else break;
- }
- /* At this point, the directory data sector needs to be read. */
- logical_sector = ((ULONG) media_ptr -> fx_media_data_sector_start) +
- (((ULONG) cluster - FX_FAT_ENTRY_START) *
- ((ULONG) media_ptr -> fx_media_sectors_per_cluster)) +
- relative_sector;
- /* determine if next sector is in next cluster or in next sector */
- if ((bytes_per_cluster - byte_offset) >= (ULONG) media_ptr -> fx_media_bytes_per_sector)
- next_logical_sector = logical_sector + 1;
- else
- if ((next_cluster >= FX_FAT_ENTRY_START) && (next_cluster <= fat_reserved))
- next_logical_sector = ((ULONG) media_ptr -> fx_media_data_sector_start) +
- (((ULONG) next_cluster - FX_FAT_ENTRY_START) * ((ULONG) media_ptr -> fx_media_sectors_per_cluster));
- else next_logical_sector = 0; /* no such sector possible */
- /* Read the logical directory sector. */
- status = _fx_utility_log_sector_read(media_ptr, (ULONG) logical_sector,
- media_ptr -> fx_media_memory_buffer, (ULONG) 1);
- /* Determine if an error occurred. */
- if (status != FX_SUCCESS)
- {
- /* Return error code. */
- return(status);
- }
- /* Calculate the byte offset within this sector. */
- byte_offset %= media_ptr -> fx_media_bytes_per_sector;
- }
- else
- {
- /* Read the entry from the root directory. */
- /* Determine which sector the requested root directory entry is in. */
- logical_sector = (byte_offset/media_ptr -> fx_media_bytes_per_sector) +
- (ULONG) media_ptr -> fx_media_root_sector_start;
- next_logical_sector = logical_sector + 1;
- if (next_logical_sector >= ((ULONG) media_ptr -> fx_media_root_sector_start + (ULONG) media_ptr -> fx_media_root_sectors))
- next_logical_sector = 0; /* no next logical sector possible */
- /* Read the logical directory sector. */
- status = _fx_utility_log_sector_read(media_ptr, (ULONG) logical_sector,
- media_ptr -> fx_media_memory_buffer, (ULONG) 1);
- /* Determine if an error occurred. */
- if (status != FX_SUCCESS)
- {
- /* Return error code. */
- return(status);
- }
- /* Now calculate the byte offset into this sector. */
- byte_offset -=
- ((logical_sector - (ULONG) media_ptr -> fx_media_root_sector_start) *
- media_ptr -> fx_media_bytes_per_sector);
- }
- /* Setup a pointer into the buffer. */
- read_ptr = (UCHAR_PTR) media_ptr -> fx_media_memory_buffer + (UINT) byte_offset;
- /* Save the logical sector and byte offset in the returned directory entry. */
- destination_ptr -> fx_dir_entry_log_sector = logical_sector;
- destination_ptr -> fx_dir_entry_byte_offset = byte_offset;
- /* check if long file name exists */
- get_short_name = 0;
- if ((*(read_ptr + 11) == FX_LONG_NAME) && (*read_ptr != FX_DIR_ENTRY_FREE)
- // && ( (i = (*read_ptr & 0x1f)*13) < FX_MAX_LONG_NAME_LEN )
- )
- {
- i = (*read_ptr & 0x1f)*13;
- if ( i >= FX_MAX_LONG_NAME_LEN)
- {
- // i = FX_MAX_LONG_NAME_LEN-1;
- get_short_name = 1;
- } else
- {
- destination_ptr -> fx_dir_entry_name[i] = 0; /* null termintated string */
- }
- do {
- card = (*read_ptr & 0x1f) - 1; /* get the lower 5 bit containing the cardinality */
- /* for simplicity no checksum or cardinality checking is done */
- if (get_short_name == 0)
- {
- for(i = 1, j = 0; i < FX_DIR_ENTRY_SIZE; i+=2)
- {
- if ((i == 11) || (i ==26)) continue;
- /* i = 12, 27 is not generated due to +=2 */
- if (i == 13)
- {
- i = 12;
- continue; /* this time next unicode is byte offset 14*/
- }
- /* each entry contains 13 unicode and first byte ascii, second byte is extended */
- #if 0
- if (((CHAR)read_ptr[i] >= 'a') && ((CHAR)read_ptr[i] <= 'z')) /* make upper */
- destination_ptr -> fx_dir_entry_name[13*card + j] = (CHAR)read_ptr[i] - 0x20;
- else
- #endif
- // <<< ZKR GL112003 : Check if the charater code is english-based unicode.
- // if not, we should substitute '*' for it.
- #if 1 //def S1_GUI
- if ( (read_ptr[i+1]<3) && (read_ptr[i+1]>=0) )
- destination_ptr -> fx_dir_entry_name[13*card + j] = (CHAR)read_ptr[i]; //
- else
- destination_ptr -> fx_dir_entry_name[13*card + j] = (CHAR)'*';
- #else // S1_GUI
- destination_ptr -> fx_dir_entry_name[13*card + j] = (CHAR)read_ptr[i];
- #endif
- // ZKR GL112003 >>>
- j++;
- // <<< ZKR GL112003 : Check null charater only if the charater code is english-based unicode.
- #if 1 //def S1_GUI
- if ( ((CHAR)read_ptr[i] == 0) && ((read_ptr[i+1]<3) && (read_ptr[i+1]>=0)) )
- #else // S1_GUI
- if ( (CHAR)read_ptr[i] == 0 )
- #endif // S1_GUI
- // ZKR GL112003 >>>
- break;
- }
- }
- if (byte_offset + FX_DIR_ENTRY_SIZE >= media_ptr -> fx_media_bytes_per_sector)
- {
- /* read new sector */
- if (next_logical_sector != 0)
- logical_sector = next_logical_sector;
- else
- return(FX_FILE_CORRUPT);
-
- status = _fx_utility_log_sector_read(media_ptr, (ULONG) logical_sector,
- media_ptr -> fx_media_memory_buffer, (ULONG) 1);
- if (status != FX_SUCCESS)
- return(status);
- byte_offset = 0;
- }
- else byte_offset += FX_DIR_ENTRY_SIZE;
- read_ptr = (UCHAR_PTR) media_ptr -> fx_media_memory_buffer + (UINT) byte_offset;
- entry++;
- } while (card > 0);
- destination_ptr -> fx_dir_long_name_present = 1;
- }
- else
- {
- get_short_name = 1;
- }
- if (get_short_name == 1)
- {
- destination_ptr -> fx_dir_long_name_present = 0;
- destination_ptr -> fx_dir_entry_name[0] = 0;
- dotflag = 0;
- for (i = 0, j = 0; i < (FX_DIR_NAME_SIZE+FX_DIR_EXT_SIZE); i++)
- {
- if ((CHAR) read_ptr[i] == 0)
- break;
- if ((CHAR) read_ptr[i] == '.')
- dotflag = 2; /* happen for the first two dir entries, no extra dot*/
- if ((CHAR) read_ptr[i] == ' ')
- {
- if (dotflag == 0) dotflag = 1; /* put a dot if a char comes aft space */
- continue;
- }
-
- if (i == FX_DIR_NAME_SIZE)
- if (dotflag == 0)
- dotflag = 1; /* not a space/null, no dot yet inserted */
- if (dotflag == 1)
- {
- destination_ptr -> fx_dir_entry_name[j++] = '.';
- dotflag = 2; /* no more dot for spaces */
- }
- #if 0
- if (((CHAR)read_ptr[i] >= 'a') && ((CHAR)read_ptr[i] <= 'z')) /* make upper */
- destination_ptr -> fx_dir_entry_name[j] = read_ptr[i] - 0x20;
- else
- #endif
- destination_ptr -> fx_dir_entry_name[j] = read_ptr[i];
- j++;
- }
- destination_ptr -> fx_dir_entry_name[j] = 0;
- }
- /* Load up the destination directory entry. */
- read_ptr += (FX_DIR_NAME_SIZE+FX_DIR_EXT_SIZE);
- /* Copy the attribute into the destination. */
- destination_ptr -> fx_dir_entry_attributes = *read_ptr++;
- /* Advance the read_ptr past the reserved bytes. */
- read_ptr += FX_DIR_RESERVED;
- /* read the upper 2 bytes of starting cluster - req. only for 32 bit FAT */
- if (media_ptr -> fx_media_32_bit_FAT)
- {
- destination_ptr -> fx_dir_entry_cluster = _fx_utility_16_unsigned_read(read_ptr);
- destination_ptr -> fx_dir_entry_cluster <<= 16;
- }
- else destination_ptr -> fx_dir_entry_cluster = 0;
- read_ptr += 2; /* Always 2 bytes */
- /* Copy the time into the destination. */
- destination_ptr -> fx_dir_entry_time = _fx_utility_16_unsigned_read(read_ptr);
- read_ptr += 2; /* Always 2 bytes */
- /* Copy the date into the destination. */
- destination_ptr -> fx_dir_entry_date = _fx_utility_16_unsigned_read(read_ptr);
- read_ptr += 2; /* Always 2 bytes */
- /* Copy the starting cluster into the destination. */
- destination_ptr -> fx_dir_entry_cluster += _fx_utility_16_unsigned_read(read_ptr);
- read_ptr += 2; /* Always 2 bytes */
- /* Copy the file size into the destination. */
- destination_ptr -> fx_dir_entry_file_size = _fx_utility_32_unsigned_read(read_ptr);
- *entry_ptr = entry;
- /* Return success to the caller. */
- return(FX_SUCCESS);
- }
- #endif