FX_FO.C
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:22k
源码类别:

DVD

开发平台:

Others

  1. /**************************************************************************/ 
  2. /*                                                                        */ 
  3. /*            Copyright (c) 1996-2002 by Express Logic Inc.               */ 
  4. /*                                                                        */ 
  5. /*  This software is copyrighted by and is the sole property of Express   */ 
  6. /*  Logic, Inc.  All rights, title, ownership, or other interests         */ 
  7. /*  in the software remain the property of Express Logic, Inc.  This      */ 
  8. /*  software may only be used in accordance with the corresponding        */ 
  9. /*  license agreement.  Any unauthorized use, duplication, transmission,  */ 
  10. /*  distribution, or disclosure of this software is expressly forbidden.  */ 
  11. /*                                                                        */
  12. /*  This Copyright notice may not be removed or modified without prior    */ 
  13. /*  written consent of Express Logic, Inc.                                */ 
  14. /*                                                                        */ 
  15. /*  Express Logic, Inc. reserves the right to modify this software        */ 
  16. /*  without notice.                                                       */ 
  17. /*                                                                        */ 
  18. /*  Express Logic, Inc.                     info@expresslogic.com         */
  19. /*  11423 West Bernardo Court               http://www.expresslogic.com   */
  20. /*  San Diego, CA  92127                                                  */
  21. /*                                                                        */
  22. /**************************************************************************/
  23. /**************************************************************************/
  24. /**************************************************************************/
  25. /**                                                                       */ 
  26. /** FileX Component                                                       */ 
  27. /**                                                                       */
  28. /**   File (FIL)                                                          */
  29. /**                                                                       */
  30. /**************************************************************************/
  31. /**************************************************************************/
  32. #include "Config.h" // Global Configuration - do not remove!
  33. #ifdef ENABLE_FILEX
  34. #ifdef _DEBUG
  35. #undef IFTRACE
  36. #define IFTRACE if (gTraceFileSys)
  37. #include "DebugDbgMain.h"
  38. #endif //_DEBUG
  39. #define FX_SOURCE_CODE
  40. /* Include necessary system files.  */
  41. #include "PlaycoreFileSysFileXfx_api.h"
  42. #include "PlaycoreFileSysFileXfx_sys.h"
  43. #include "PlaycoreFileSysFileXfx_dir.h"
  44. #include "PlaycoreFileSysFileXfx_fil.h"
  45. #include "PlaycoreFileSysFileXfx_uti.h"
  46. /**************************************************************************/ 
  47. /*                                                                        */ 
  48. /*  FUNCTION                                               RELEASE        */ 
  49. /*                                                                        */ 
  50. /*    _fx_file_open                                       PORTABLE C      */ 
  51. /*                                                           3.0          */ 
  52. /*  AUTHOR                                                                */ 
  53. /*                                                                        */ 
  54. /*    William E. Lamie, Express Logic, Inc.                               */ 
  55. /*                                                                        */ 
  56. /*  DESCRIPTION                                                           */ 
  57. /*                                                                        */ 
  58. /*    This function first attempts to find the specified file.  If found, */ 
  59. /*    the open request is validated and the file is opened.  During the   */ 
  60. /*    opening process, all of the FAT entries for this file are examined  */ 
  61. /*    for their integrity.                                                */ 
  62. /*                                                                        */ 
  63. /*  INPUT                                                                 */ 
  64. /*                                                                        */ 
  65. /*    media_ptr                             Media control block pointer   */ 
  66. /*    file_ptr                              File control block pointer    */ 
  67. /*    name_ptr                              Name pointer (8 chars + ext)  */ 
  68. /*    open_type                             Type of open requested        */ 
  69. /*                                                                        */ 
  70. /*  OUTPUT                                                                */ 
  71. /*                                                                        */ 
  72. /*    return status                                                       */ 
  73. /*                                                                        */ 
  74. /*  CALLS                                                                 */ 
  75. /*                                                                        */ 
  76. /*    _fx_directory_search                  Search for the file name in   */ 
  77. /*                                          the directory structure       */ 
  78. /*    _fx_utility_FAT_entry_read            Read a FAT entry              */ 
  79. /*                                                                        */ 
  80. /*  CALLED BY                                                             */ 
  81. /*                                                                        */ 
  82. /*    Application Code                                                    */ 
  83. /*                                                                        */ 
  84. /*  RELEASE HISTORY                                                       */ 
  85. /*                                                                        */ 
  86. /*    DATE              NAME                      DESCRIPTION             */ 
  87. /*                                                                        */ 
  88. /*  01-01-1999     William E. Lamie         Initial Version 1.0           */ 
  89. /*  04-19-1999     William E. Lamie         Added logic to setup a file   */ 
  90. /*                                            opened for writing whose    */ 
  91. /*                                            size is evenly divisible by */ 
  92. /*                                            the media's cluster size,   */ 
  93. /*                                            resulting in version 1.0a.  */ 
  94. /*  03-01-2000     William E. Lamie         Modified comment(s), and      */ 
  95. /*                                            added casting to remove     */ 
  96. /*                                            compiler warning message,   */ 
  97. /*                                            resulting in version 1.0b.  */ 
  98. /*  01-28-2001     William E. Lamie         Modified comment(s) and added */ 
  99. /*                                            logic to allow opening of   */ 
  100. /*                                            initially null open files,  */ 
  101. /*                                            resulting in version 2.0.   */ 
  102. /*  03-01-2002     Mohammad N. Minhaz       Modified comment(s),          */ 
  103. /*                                            changed to 32 bit variables,*/ 
  104. /*                                            fixed possible infinite loop*/ 
  105. /*                                            caused by a corrupted FAT,  */ 
  106. /*                                            determined consecutive      */ 
  107. /*                                            clusters, and added write   */ 
  108. /*                                            protect logic, resulting in */ 
  109. /*                                            version 3.0.                */ 
  110. /*                                                                        */ 
  111. /**************************************************************************/ 
  112. UINT  _fx_file_open(FX_MEDIA *media_ptr, FX_FILE *file_ptr, CHAR *file_name, UINT open_type)
  113. {
  114. UINT        status, leading_consecutive;
  115. ULONG       cluster;
  116. ULONG       contents;
  117. ULONG       open_count;
  118. FX_FILE    *tail_ptr;
  119. FX_FILE    *search_ptr;
  120. ULONG       bytes_per_cluster;
  121. ULONG       last_cluster;
  122. ULONG       cluster_count;
  123. ULONG       bytes_available;
  124. ULONG       bytes_remaining;
  125. ULONG       fat_reserved, fat_last;
  126.     /* Check the media to make sure it is open.  */
  127.     if (media_ptr -> fx_media_id != FX_MEDIA_ID)
  128.     {
  129.         /* Return the media not opened error.  */
  130.         return(FX_MEDIA_NOT_OPEN);
  131.     }
  132.     /* Determine the type of FAT and setup variables accordingly.  */
  133.     if (media_ptr -> fx_media_32_bit_FAT) fat_reserved = FX_RESERVED_1_32;
  134.     else fat_reserved = FX_RESERVED_1;
  135.     if (media_ptr -> fx_media_32_bit_FAT) fat_last = FX_LAST_CLUSTER_1_32;
  136.     else fat_last = FX_LAST_CLUSTER_1;
  137.     /* Protect against other threads accessing the media.  */
  138.     FX_PROTECT
  139.     /* Search the system for the supplied file name.  */
  140.     status =  _fx_directory_search(media_ptr, file_name, &(file_ptr -> fx_file_dir_entry), FX_NULL, FX_NULL);
  141.     /* Determine if the search was successful.  */
  142.     if (status != FX_SUCCESS)
  143.     {
  144.         /* Release media protection.  */
  145.         FX_UNPROTECT
  146.         /* Return the error code.  */
  147.         return(status);
  148.     }
  149.     /* Check to make sure the found entry is a file.  */
  150.     if (file_ptr -> fx_file_dir_entry.fx_dir_entry_attributes & (UCHAR) (FX_DIRECTORY | FX_VOLUME))
  151.     {
  152.         /* Release media protection.  */
  153.         FX_UNPROTECT
  154.         /* Return the not a file error code.  */
  155.         return(FX_NOT_A_FILE);
  156.     }
  157.     /* Check to make sure the access is okay.  */
  158.     if (open_type == FX_OPEN_FOR_READ)
  159.     {
  160. #if 0 //don't maintain any file list.
  161.         /* Check the list of open files for others open for writing.  */
  162.         open_count =  media_ptr -> fx_media_opened_file_count;
  163.         search_ptr =  media_ptr -> fx_media_opened_file_list;
  164.         while(open_count)
  165.         {
  166.             /* Look at each opened file to see if the same file is opened
  167.                for writing.  */
  168.             if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector ==
  169.                         file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) &&
  170.                 (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset ==
  171.                         file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset) &&
  172.                 (search_ptr -> fx_file_open_mode))
  173.             {
  174.                 /* Release media protection.  */
  175.                 FX_UNPROTECT
  176.                 /* The file has been opened for writing by a previous call.  */
  177.                 return(FX_ACCESS_ERROR);
  178.             }
  179.             /* Adjust the pointer and decrement the search count.  */
  180.             search_ptr =  search_ptr -> fx_file_opened_next;
  181.             open_count--;
  182.         }
  183. #endif
  184.   }
  185. #if 0 //don't maintain any file list.
  186.     else
  187.     {
  188.         /* A open for write request is present, check the file attributes
  189.            and the list of open files for any other open instance of 
  190.            this file.  */
  191.         if (media_ptr -> fx_media_driver_write_protect)
  192.         {
  193.             /* Release media protection.  */
  194.             FX_UNPROTECT
  195.             /* Return write protect error.  */
  196.             return(FX_WRITE_PROTECT);
  197.         }
  198.         if (file_ptr -> fx_file_dir_entry.fx_dir_entry_attributes & (UCHAR) (FX_READ_ONLY))
  199.         {
  200.             /* Release media protection.  */
  201.             FX_UNPROTECT
  202.             /* Return the not a file error code.  */
  203.             return(FX_ACCESS_ERROR);
  204.         }
  205.         /* Also search the opened files to see if this file is currently 
  206.            opened.  */
  207.         open_count =  media_ptr -> fx_media_opened_file_count;
  208.         search_ptr =  media_ptr -> fx_media_opened_file_list;
  209.         while(open_count)
  210.         {
  211.             /* Look at each opened file to see if the same file is opened
  212.                for writing.  */
  213.             if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector ==
  214.                         file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) &&
  215.                 (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset ==
  216.                         file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset))
  217.             {
  218.                 /* Release media protection.  */
  219.                 FX_UNPROTECT
  220.                 /* The file is currently open.  */
  221.                 return(FX_ACCESS_ERROR);
  222.             }
  223.             /* Adjust the pointer and decrement the search count.  */
  224.             search_ptr =  search_ptr -> fx_file_opened_next;
  225.             open_count--;
  226.         }
  227.     }
  228. #endif
  229.     /* At this point, we are ready to walk list of clusters to setup the
  230.        initial condition of this file as well as to verify its integrity.  */
  231.     cluster =           file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster;
  232.     bytes_remaining =   file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size;
  233.     bytes_per_cluster = ((ULONG) media_ptr -> fx_media_bytes_per_sector) *
  234.                                ((ULONG) media_ptr -> fx_media_sectors_per_cluster);
  235.     file_ptr -> fx_file_current_physical_cluster =  0;
  236.     last_cluster =      0;
  237.     cluster_count =     0;
  238.     leading_consecutive = 1;
  239.     file_ptr -> fx_file_consecutive_cluster = 1;
  240.     /* Follow the link of FAT entries.  */
  241.     while ((cluster >= FX_FAT_ENTRY_START) && (cluster < fat_reserved))
  242.     {
  243.         /* Increment the number of clusters.  */
  244.         cluster_count++;
  245.         /* Read the current cluster entry from the FAT.  */
  246.         status =  _fx_utility_FAT_entry_read(media_ptr, cluster, &contents);
  247.         /* Check the return value.  */
  248.         if (status != FX_SUCCESS)
  249.         {
  250.             /* Release media protection.  */
  251.             FX_UNPROTECT
  252.             /* Return the error status.  */
  253.             return(status);
  254.         }
  255.         if ((cluster == contents) || (cluster_count > media_ptr -> fx_media_total_clusters)) 
  256.         {
  257.             /* Release media protection.  */
  258.             FX_UNPROTECT
  259.             /* Return the bad status.  */
  260.             return(FX_FAT_READ_ERROR);
  261.         }
  262.         /* Check if present and next clusters are consecutive */
  263.         if (cluster + 1 == contents)
  264.         {
  265.             /* Save the number of leading consecutive clusters */
  266.             if (leading_consecutive)
  267.                 file_ptr -> fx_file_consecutive_cluster ++;
  268.         }
  269.         else 
  270.             leading_consecutive = 0;
  271.         /* Save the last valid cluster.  */
  272.         last_cluster =  cluster;
  273.         /* Setup for the next cluster.  */
  274.         cluster =  contents;
  275.         /* Determine if this is the last written cluster.  We need to remember this
  276.            for open for writing.  */
  277.         if (bytes_remaining > bytes_per_cluster)
  278.         {
  279.             /* Still more written clusters, just decrement the counter.  */
  280.             bytes_remaining =  bytes_remaining - bytes_per_cluster;
  281.         }
  282.         else if (!file_ptr -> fx_file_current_physical_cluster)
  283.         {
  284.             /* Remember this cluster number.  */
  285.             file_ptr -> fx_file_current_physical_cluster =  last_cluster;
  286.             /* Remember the relative cluster.  */
  287.             file_ptr -> fx_file_current_relative_cluster =  cluster_count-1;
  288.             /* If the remaining bytes exactly fits the cluster size, check for 
  289.                a possible adjustment to the next cluster.  */
  290.             if ((bytes_remaining == bytes_per_cluster) &&
  291.                 (cluster >= FX_FAT_ENTRY_START) && (cluster < fat_reserved))
  292.             {
  293.                 /* We need to position to next allocated cluster.  */
  294.                 file_ptr -> fx_file_current_physical_cluster =  cluster;
  295.                 file_ptr -> fx_file_current_relative_cluster++;
  296.                 /* Clear the remaining bytes.  */
  297.                 bytes_remaining =  0;
  298.             }
  299.         }
  300.     }        
  301.     /* Determine if the number of clusters is large enough to support the 
  302.        specified file size.  */
  303.     bytes_available =  ((ULONG) media_ptr -> fx_media_bytes_per_sector) *
  304.                        ((ULONG) media_ptr -> fx_media_sectors_per_cluster) *
  305.                        ((ULONG) cluster_count);
  306.     if ((bytes_available < file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size) ||
  307.         ((cluster_count) && (contents < fat_last)))
  308.     {
  309.         /* Release media protection.  */
  310.         FX_UNPROTECT
  311.         /* Return a corrupt file error status.  */
  312.         return(FX_FILE_CORRUPT);
  313.     }
  314.     /* The file is okay, populate the file control block and complete the
  315.        file open process.  */
  316.     file_ptr -> fx_file_id =                        FX_FILE_ID;
  317.     file_ptr -> fx_file_name =                      file_name;
  318.     file_ptr -> fx_file_media_ptr =                 media_ptr;
  319.     file_ptr -> fx_file_open_mode =                 (UCHAR) open_type;
  320.     file_ptr -> fx_file_modified =                  FX_FALSE;
  321.     file_ptr -> fx_file_total_clusters =            cluster_count;
  322.     file_ptr -> fx_file_first_physical_cluster =    file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster;
  323.     file_ptr -> fx_file_last_physical_cluster =     last_cluster;
  324.     file_ptr -> fx_file_current_file_size =         file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size;
  325.     file_ptr -> fx_file_current_available_size =    bytes_available;
  326.     /* Set the current settings based on how the file was opened.  */
  327.     if (open_type == FX_OPEN_FOR_READ)
  328.     {
  329.         /* Position the pointers to the beginning of the file.  */
  330.         file_ptr -> fx_file_current_physical_cluster =  file_ptr -> fx_file_first_physical_cluster;
  331.         file_ptr -> fx_file_current_relative_cluster =  0;
  332.         file_ptr -> fx_file_current_logical_sector =    ((ULONG) media_ptr -> fx_media_data_sector_start) +
  333.                                                         (((ULONG) (file_ptr -> fx_file_first_physical_cluster - FX_FAT_ENTRY_START)) *
  334.                                                         ((ULONG) media_ptr -> fx_media_sectors_per_cluster));
  335.         file_ptr -> fx_file_current_relative_sector =   0;
  336.         file_ptr -> fx_file_current_logical_offset =    0;
  337.         file_ptr -> fx_file_current_file_offset =       0;
  338.     }
  339.     else
  340.     {
  341.         /* Open for writing - position the pointers to the end of the file.  */
  342.         /* Determine if the remaining bytes fit exactly into the cluster size.  */
  343.         if (bytes_remaining == bytes_per_cluster)
  344.         {
  345.             /* Position to the end of the cluster.  */
  346.             file_ptr -> fx_file_current_logical_sector =    ((ULONG) media_ptr -> fx_media_data_sector_start) +
  347.                                                             (((ULONG) file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) *
  348.                                                             ((ULONG) media_ptr -> fx_media_sectors_per_cluster)) +
  349.                                                             ((bytes_remaining-1) / (ULONG) media_ptr -> fx_media_bytes_per_sector);
  350.             file_ptr -> fx_file_current_relative_sector =   (UINT) (((bytes_remaining-1) / (ULONG) media_ptr -> fx_media_bytes_per_sector));
  351.             file_ptr -> fx_file_current_file_offset =       file_ptr -> fx_file_current_file_size;
  352.             file_ptr -> fx_file_current_logical_offset =    media_ptr -> fx_media_bytes_per_sector;
  353.         }
  354.         else
  355.         {
  356.             /* Position file parameters at end of last cluster allocation.  */
  357.             file_ptr -> fx_file_current_logical_sector =    ((ULONG) media_ptr -> fx_media_data_sector_start) +
  358.                                                             (((ULONG) file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) *
  359.                                                             ((ULONG) media_ptr -> fx_media_sectors_per_cluster)) +
  360.                                                             (bytes_remaining / (ULONG) media_ptr -> fx_media_bytes_per_sector);
  361.             file_ptr -> fx_file_current_relative_sector =   (UINT) ((bytes_remaining / (ULONG) media_ptr -> fx_media_bytes_per_sector));
  362.             file_ptr -> fx_file_current_file_offset =       file_ptr -> fx_file_current_file_size;
  363.             file_ptr -> fx_file_current_logical_offset =    bytes_remaining % ((ULONG) media_ptr -> fx_media_bytes_per_sector);
  364.         }
  365.     }
  366. #if 0 //don't maintain any file list.
  367.     /* Place newly opened file on the list of open files for 
  368.        this media.  First, check for an empty list.  */
  369.     if (media_ptr -> fx_media_opened_file_list)
  370.     {
  371.         /* Pickup tail pointer.  */
  372.         tail_ptr =  (media_ptr -> fx_media_opened_file_list) -> fx_file_opened_previous;
  373.         /* Place the new file in the list.  */
  374.         (media_ptr -> fx_media_opened_file_list) -> fx_file_opened_previous =  file_ptr;
  375.         tail_ptr -> fx_file_opened_next =  file_ptr;
  376.         /* Setup this file's opened links.  */
  377.         file_ptr -> fx_file_opened_previous =  tail_ptr;
  378.         file_ptr -> fx_file_opened_next =      media_ptr -> fx_media_opened_file_list;
  379.     }
  380.     else
  381.     {
  382.         /* The opened media list is empty.  Add the media to empty list.  */
  383.         media_ptr -> fx_media_opened_file_list =   file_ptr;
  384.         file_ptr ->  fx_file_opened_next =         file_ptr;
  385.         file_ptr ->  fx_file_opened_previous =     file_ptr;
  386.     }
  387.     /* Increment the opened file counter.  */
  388.     media_ptr -> fx_media_opened_file_count++;
  389. #endif
  390.     /* Release media protection.  */
  391.     FX_UNPROTECT
  392.     /* Open is complete, return successful status.  */
  393.     return(FX_SUCCESS);
  394. }
  395. #endif