1 |
|
|
/**************************************************************************/ |
2 |
|
|
/* */ |
3 |
|
|
/* Copyright (c) Microsoft Corporation. All rights reserved. */ |
4 |
|
|
/* */ |
5 |
|
|
/* This software is licensed under the Microsoft Software License */ |
6 |
|
|
/* Terms for Microsoft Azure RTOS. Full text of the license can be */ |
7 |
|
|
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ |
8 |
|
|
/* and in the root directory of this software. */ |
9 |
|
|
/* */ |
10 |
|
|
/**************************************************************************/ |
11 |
|
|
|
12 |
|
|
|
13 |
|
|
/**************************************************************************/ |
14 |
|
|
/**************************************************************************/ |
15 |
|
|
/** */ |
16 |
|
|
/** FileX Component */ |
17 |
|
|
/** */ |
18 |
|
|
/** Media */ |
19 |
|
|
/** */ |
20 |
|
|
/**************************************************************************/ |
21 |
|
|
/**************************************************************************/ |
22 |
|
|
|
23 |
|
|
#define FX_SOURCE_CODE |
24 |
|
|
|
25 |
|
|
|
26 |
|
|
/* Include necessary system files. */ |
27 |
|
|
|
28 |
|
|
#include "fx_api.h" |
29 |
|
|
#include "fx_media.h" |
30 |
|
|
#include "fx_utility.h" |
31 |
|
|
|
32 |
|
|
|
33 |
|
|
/**************************************************************************/ |
34 |
|
|
/* */ |
35 |
|
|
/* FUNCTION RELEASE */ |
36 |
|
|
/* */ |
37 |
|
|
/* _fx_media_check_lost_cluster_check PORTABLE C */ |
38 |
|
|
/* 6.1 */ |
39 |
|
|
/* AUTHOR */ |
40 |
|
|
/* */ |
41 |
|
|
/* William E. Lamie, Microsoft Corporation */ |
42 |
|
|
/* */ |
43 |
|
|
/* DESCRIPTION */ |
44 |
|
|
/* */ |
45 |
|
|
/* This function examines all clusters to see if there are any unused */ |
46 |
|
|
/* clusters that are also unavailable. If specified, this routine will */ |
47 |
|
|
/* also mark the cluster as available. */ |
48 |
|
|
/* */ |
49 |
|
|
/* INPUT */ |
50 |
|
|
/* */ |
51 |
|
|
/* media_ptr Pointer to a previously */ |
52 |
|
|
/* opened media */ |
53 |
|
|
/* logical_fat Pointer to the logical FAT */ |
54 |
|
|
/* bit map */ |
55 |
|
|
/* total_clusters Total number of clusters */ |
56 |
|
|
/* error_correction_option Option for correcting lost */ |
57 |
|
|
/* cluster errors */ |
58 |
|
|
/* */ |
59 |
|
|
/* OUTPUT */ |
60 |
|
|
/* */ |
61 |
|
|
/* error Error code */ |
62 |
|
|
/* */ |
63 |
|
|
/* CALLS */ |
64 |
|
|
/* */ |
65 |
|
|
/* _fx_utility_FAT_entry_read Read a FAT entry */ |
66 |
|
|
/* _fx_utility_FAT_entry_write Write a FAT entry */ |
67 |
|
|
/* */ |
68 |
|
|
/* CALLED BY */ |
69 |
|
|
/* */ |
70 |
|
|
/* _fx_check_media Check media function */ |
71 |
|
|
/* */ |
72 |
|
|
/* RELEASE HISTORY */ |
73 |
|
|
/* */ |
74 |
|
|
/* DATE NAME DESCRIPTION */ |
75 |
|
|
/* */ |
76 |
|
|
/* 05-19-2020 William E. Lamie Initial Version 6.0 */ |
77 |
|
|
/* 09-30-2020 William E. Lamie Modified comment(s), */ |
78 |
|
|
/* resulting in version 6.1 */ |
79 |
|
|
/* */ |
80 |
|
|
/**************************************************************************/ |
81 |
|
23 |
ULONG _fx_media_check_lost_cluster_check(FX_MEDIA *media_ptr, UCHAR *logical_fat, ULONG total_clusters, ULONG error_correction_option) |
82 |
|
|
{ |
83 |
|
|
|
84 |
|
23 |
ULONG cluster, next_cluster = 0; |
85 |
|
|
ULONG fat_last; |
86 |
|
|
ULONG error; |
87 |
|
|
UINT status; |
88 |
|
|
|
89 |
|
|
|
90 |
|
|
/* Calculate the FAT reserved and last sector values. */ |
91 |
✓✓ |
23 |
if (media_ptr -> fx_media_32_bit_FAT) |
92 |
|
|
{ |
93 |
|
3 |
fat_last = FX_LAST_CLUSTER_1_32; |
94 |
|
|
} |
95 |
|
|
else |
96 |
|
|
{ |
97 |
|
20 |
fat_last = FX_LAST_CLUSTER_1; |
98 |
|
|
} |
99 |
|
|
|
100 |
|
|
/* Initialize the error. */ |
101 |
|
23 |
error = 0; |
102 |
|
|
|
103 |
|
|
/* Loop through all the clusters to see if any clusters NOT in the logical sector FAT have |
104 |
|
|
a non zero value. */ |
105 |
✓✓ |
248207 |
for (cluster = FX_FAT_ENTRY_START; cluster < total_clusters; cluster++) |
106 |
|
|
{ |
107 |
|
|
|
108 |
|
|
/* Determine if this cluster is in the logical FAT. */ |
109 |
✓✓ |
248187 |
if (logical_fat[cluster >> 3] & (1 << (cluster & 7))) |
110 |
|
|
{ |
111 |
|
|
|
112 |
|
|
/* Yes, the cluster is in use by a file or sub-directory. Just continue the loop. */ |
113 |
|
5925 |
continue; |
114 |
|
|
} |
115 |
|
|
|
116 |
|
|
/* Otherwise, the cluster is not in use. */ |
117 |
|
|
|
118 |
|
|
/* Read the contents of what should be a free cluster. */ |
119 |
|
242262 |
status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster); |
120 |
|
|
|
121 |
|
|
/* Check for a good status. */ |
122 |
✓✓ |
242262 |
if (status) |
123 |
|
|
{ |
124 |
|
|
|
125 |
|
|
/* Set the error code. */ |
126 |
|
2 |
error = error | FX_IO_ERROR; |
127 |
|
|
|
128 |
|
|
/* Return error code. */ |
129 |
|
2 |
return(error); |
130 |
|
|
} |
131 |
|
|
|
132 |
|
|
/* Determine if the contents of the cluster is valid. */ |
133 |
✓✓✓✓
|
242260 |
if (((next_cluster > (ULONG)FX_FREE_CLUSTER) && (next_cluster < media_ptr -> fx_media_fat_reserved)) || |
134 |
✓✓ |
236299 |
(next_cluster >= fat_last)) |
135 |
|
|
{ |
136 |
|
|
|
137 |
|
|
/* Lost cluster is present. */ |
138 |
|
|
|
139 |
|
|
/* Set the error code status. */ |
140 |
|
5967 |
error = FX_LOST_CLUSTER_ERROR; |
141 |
|
|
|
142 |
|
|
/* Determine if the lost cluster should be recovered. */ |
143 |
✓✓ |
5967 |
if (error_correction_option & FX_LOST_CLUSTER_ERROR) |
144 |
|
|
{ |
145 |
|
|
|
146 |
|
|
/* Make the cluster available again. */ |
147 |
|
5942 |
status = _fx_utility_FAT_entry_write(media_ptr, cluster, FX_FREE_CLUSTER); |
148 |
|
|
|
149 |
|
|
/* Check for a good status. */ |
150 |
✓✓ |
5942 |
if (status) |
151 |
|
|
{ |
152 |
|
|
|
153 |
|
|
/* Increment the available clusters. */ |
154 |
|
1 |
media_ptr -> fx_media_available_clusters++; |
155 |
|
|
|
156 |
|
|
/* Set the error code. */ |
157 |
|
1 |
error = error | FX_IO_ERROR; |
158 |
|
|
|
159 |
|
|
/* Return error code. */ |
160 |
|
1 |
return(error); |
161 |
|
|
} |
162 |
|
|
} |
163 |
|
|
} |
164 |
|
|
} |
165 |
|
|
|
166 |
|
|
/* Return error code. */ |
167 |
|
20 |
return(error); |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
#ifdef FX_ENABLE_EXFAT |
171 |
|
|
/**************************************************************************/ |
172 |
|
|
/* */ |
173 |
|
|
/* FUNCTION RELEASE */ |
174 |
|
|
/* */ |
175 |
|
|
/* _fx_media_check_exFAT_lost_cluster_check PORTABLE C */ |
176 |
|
|
/* 6.1 */ |
177 |
|
|
/* AUTHOR */ |
178 |
|
|
/* */ |
179 |
|
|
/* William E. Lamie, Microsoft Corporation */ |
180 |
|
|
/* */ |
181 |
|
|
/* DESCRIPTION */ |
182 |
|
|
/* */ |
183 |
|
|
/* This function examines all clusters in exFAT to see if there are */ |
184 |
|
|
/* any unused clusters that are also unavailable. */ |
185 |
|
|
/* */ |
186 |
|
|
/* INPUT */ |
187 |
|
|
/* */ |
188 |
|
|
/* media_ptr Pointer to a previously */ |
189 |
|
|
/* opened media */ |
190 |
|
|
/* logical_fat Pointer to the logical FAT */ |
191 |
|
|
/* bit map */ |
192 |
|
|
/* total_clusters Total number of clusters */ |
193 |
|
|
/* error_correction_option Option for correcting lost */ |
194 |
|
|
/* cluster errors */ |
195 |
|
|
/* */ |
196 |
|
|
/* OUTPUT */ |
197 |
|
|
/* */ |
198 |
|
|
/* error Error code */ |
199 |
|
|
/* */ |
200 |
|
|
/* CALLS */ |
201 |
|
|
/* */ |
202 |
|
|
/* _fx_utility_exFAT_bitmap_flush Flush dirty bitmap clusters */ |
203 |
|
|
/* _fx_utility_exFAT_bitmap_cache_update Cache bitmap clusters */ |
204 |
|
|
/* */ |
205 |
|
|
/* CALLED BY */ |
206 |
|
|
/* */ |
207 |
|
|
/* _fx_check_media Check media function */ |
208 |
|
|
/* */ |
209 |
|
|
/* RELEASE HISTORY */ |
210 |
|
|
/* */ |
211 |
|
|
/* DATE NAME DESCRIPTION */ |
212 |
|
|
/* */ |
213 |
|
|
/* 05-19-2020 William E. Lamie Initial Version 6.0 */ |
214 |
|
|
/* 09-30-2020 William E. Lamie Modified comment(s), */ |
215 |
|
|
/* resulting in version 6.1 */ |
216 |
|
|
/* */ |
217 |
|
|
/**************************************************************************/ |
218 |
|
|
ULONG _fx_media_check_exFAT_lost_cluster_check(FX_MEDIA *media_ptr, UCHAR *logical_fat, ULONG total_clusters, ULONG error_correction_option) |
219 |
|
|
{ |
220 |
|
|
ULONG cluster = FX_FAT_ENTRY_START; |
221 |
|
|
ULONG cached_bitmap_bytes = media_ptr -> fx_media_exfat_bitmap_cache_size_in_sectors * media_ptr -> fx_media_bytes_per_sector; |
222 |
|
|
ULONG cached_bitmap_bits = cached_bitmap_bytes << 3; |
223 |
|
|
ULONG offset = 0; |
224 |
|
|
UINT status, i; |
225 |
|
|
|
226 |
|
|
/* This parameter has not been supported yet. */ |
227 |
|
|
FX_PARAMETER_NOT_USED(error_correction_option); |
228 |
|
|
|
229 |
|
|
/* Flush Allocation Bitmap Table first. */ |
230 |
|
|
status = _fx_utility_exFAT_bitmap_flush(media_ptr); |
231 |
|
|
|
232 |
|
|
if (FX_SUCCESS != status) |
233 |
|
|
{ |
234 |
|
|
return(status); |
235 |
|
|
} |
236 |
|
|
|
237 |
|
|
while (total_clusters) |
238 |
|
|
{ |
239 |
|
|
|
240 |
|
|
/* Read Allocation Bitmap Table from disk. */ |
241 |
|
|
status = _fx_utility_exFAT_bitmap_cache_update(media_ptr, cluster); |
242 |
|
|
|
243 |
|
|
if (FX_SUCCESS != status) |
244 |
|
|
{ |
245 |
|
|
return(status); |
246 |
|
|
} |
247 |
|
|
|
248 |
|
|
if (total_clusters >= cached_bitmap_bits) |
249 |
|
|
{ |
250 |
|
|
total_clusters -= cached_bitmap_bits; |
251 |
|
|
|
252 |
|
|
/* Compare cached bitmap with logical_fat. */ |
253 |
|
|
for (i = 0; i < media_ptr -> fx_media_bytes_per_sector; i++) |
254 |
|
|
{ |
255 |
|
|
if (logical_fat[offset + i] != ((UCHAR *)(media_ptr -> fx_media_exfat_bitmap_cache))[i]) |
256 |
|
|
{ |
257 |
|
|
return(FX_LOST_CLUSTER_ERROR); |
258 |
|
|
} |
259 |
|
|
|
260 |
|
|
offset += cached_bitmap_bytes; |
261 |
|
|
cluster += cached_bitmap_bits; |
262 |
|
|
} |
263 |
|
|
} |
264 |
|
|
else |
265 |
|
|
{ |
266 |
|
|
|
267 |
|
|
/* Compare cached bitmap with logical_fat. */ |
268 |
|
|
for (i = 0; i < ((total_clusters + 7) >> 3); i++) |
269 |
|
|
{ |
270 |
|
|
if (logical_fat[offset + i] != ((UCHAR *)(media_ptr -> fx_media_exfat_bitmap_cache))[i]) |
271 |
|
|
{ |
272 |
|
|
return(FX_LOST_CLUSTER_ERROR); |
273 |
|
|
} |
274 |
|
|
} |
275 |
|
|
|
276 |
|
|
total_clusters = 0; |
277 |
|
|
} |
278 |
|
|
} |
279 |
|
|
|
280 |
|
|
return(FX_SUCCESS); |
281 |
|
|
} |
282 |
|
|
#endif /* FX_ENABLE_EXFAT */ |