1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** FileX Component                                                       */
16 /**                                                                       */
17 /**   Media                                                               */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define FX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "fx_api.h"
28 #include "fx_media.h"
29 #include "fx_utility.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _fx_media_check_lost_cluster_check                  PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    William E. Lamie, Microsoft Corporation                             */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function examines all clusters to see if there are any unused  */
45 /*    clusters that are also unavailable. If specified, this routine will */
46 /*    also mark the cluster as available.                                 */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    media_ptr                             Pointer to a previously       */
51 /*                                            opened media                */
52 /*    logical_fat                           Pointer to the logical FAT    */
53 /*                                            bit map                     */
54 /*    total_clusters                        Total number of clusters      */
55 /*    error_correction_option               Option for correcting lost    */
56 /*                                            cluster errors              */
57 /*                                                                        */
58 /*  OUTPUT                                                                */
59 /*                                                                        */
60 /*    error                                 Error code                    */
61 /*                                                                        */
62 /*  CALLS                                                                 */
63 /*                                                                        */
64 /*    _fx_utility_FAT_entry_read            Read a FAT entry              */
65 /*    _fx_utility_FAT_entry_write           Write a FAT entry             */
66 /*                                                                        */
67 /*  CALLED BY                                                             */
68 /*                                                                        */
69 /*    _fx_check_media                       Check media function          */
70 /*                                                                        */
71 /*  RELEASE HISTORY                                                       */
72 /*                                                                        */
73 /*    DATE              NAME                      DESCRIPTION             */
74 /*                                                                        */
75 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
76 /*  09-30-2020     William E. Lamie         Modified comment(s),          */
77 /*                                            resulting in version 6.1    */
78 /*                                                                        */
79 /**************************************************************************/
_fx_media_check_lost_cluster_check(FX_MEDIA * media_ptr,UCHAR * logical_fat,ULONG total_clusters,ULONG error_correction_option)80 ULONG  _fx_media_check_lost_cluster_check(FX_MEDIA *media_ptr, UCHAR *logical_fat, ULONG total_clusters, ULONG error_correction_option)
81 {
82 
83 ULONG cluster, next_cluster = 0;
84 ULONG fat_last;
85 ULONG error;
86 UINT  status;
87 
88 
89     /* Calculate the FAT reserved and last sector values.  */
90     if (media_ptr -> fx_media_32_bit_FAT)
91     {
92         fat_last =      FX_LAST_CLUSTER_1_32;
93     }
94     else
95     {
96         fat_last =      FX_LAST_CLUSTER_1;
97     }
98 
99     /* Initialize the error.  */
100     error =  0;
101 
102     /* Loop through all the clusters to see if any clusters NOT in the logical sector FAT have
103        a non zero value.  */
104     for (cluster = FX_FAT_ENTRY_START; cluster < total_clusters; cluster++)
105     {
106 
107         /* Determine if this cluster is in the logical FAT.  */
108         if (logical_fat[cluster >> 3] & (1 << (cluster & 7)))
109         {
110 
111             /* Yes, the cluster is in use by a file or sub-directory.  Just continue the loop.  */
112             continue;
113         }
114 
115         /* Otherwise, the cluster is not in use.  */
116 
117         /* Read the contents of what should be a free cluster.  */
118         status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster);
119 
120         /* Check for a good status.  */
121         if (status)
122         {
123 
124             /* Set the error code.  */
125             error = error | FX_IO_ERROR;
126 
127             /* Return error code.  */
128             return(error);
129         }
130 
131         /* Determine if the contents of the cluster is valid.  */
132         if (((next_cluster > (ULONG)FX_FREE_CLUSTER) && (next_cluster < media_ptr -> fx_media_fat_reserved)) ||
133             (next_cluster >= fat_last))
134         {
135 
136             /* Lost cluster is present.  */
137 
138             /* Set the error code status.  */
139             error =  FX_LOST_CLUSTER_ERROR;
140 
141             /* Determine if the lost cluster should be recovered.  */
142             if (error_correction_option & FX_LOST_CLUSTER_ERROR)
143             {
144 
145                 /* Make the cluster available again.  */
146                 status =  _fx_utility_FAT_entry_write(media_ptr, cluster, FX_FREE_CLUSTER);
147 
148                 /* Check for a good status.  */
149                 if (status)
150                 {
151 
152                     /* Increment the available clusters.  */
153                     media_ptr -> fx_media_available_clusters++;
154 
155                     /* Set the error code.  */
156                     error =  error | FX_IO_ERROR;
157 
158                     /* Return error code.  */
159                     return(error);
160                 }
161             }
162         }
163     }
164 
165     /* Return error code.  */
166     return(error);
167 }
168 
169