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