fx_media_check.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /*************************************************************************** | ||
| 2 | * Copyright (c) 2024 Microsoft Corporation | ||
| 3 | * Copyright (c) 2026-present Eclipse ThreadX contributors | ||
| 4 | * | ||
| 5 | * This program and the accompanying materials are made available under the | ||
| 6 | * terms of the MIT License which is available at | ||
| 7 | * https://opensource.org/licenses/MIT. | ||
| 8 | * | ||
| 9 | * SPDX-License-Identifier: MIT | ||
| 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_system.h" | ||
| 30 | #include "fx_directory.h" | ||
| 31 | #include "fx_media.h" | ||
| 32 | #include "fx_utility.h" | ||
| 33 | |||
| 34 | |||
| 35 | /* Define parameters for FileX media check utility. */ | ||
| 36 | |||
| 37 | #ifndef FX_MAX_DIRECTORY_NESTING | ||
| 38 | #define FX_MAX_DIRECTORY_NESTING 20 | ||
| 39 | #endif | ||
| 40 | |||
| 41 | |||
| 42 | /* Define data structures local to the FileX media check utility. */ | ||
| 43 | |||
| 44 | typedef struct CURRENT_DIRECTORY_ENTRY_STRUCT | ||
| 45 | { | ||
| 46 | ULONG current_directory_entry; | ||
| 47 | ULONG current_total_entries; | ||
| 48 | ULONG current_start_cluster; | ||
| 49 | } CURRENT_DIRECTORY_ENTRY; | ||
| 50 | |||
| 51 | |||
| 52 | /**************************************************************************/ | ||
| 53 | /* */ | ||
| 54 | /* FUNCTION RELEASE */ | ||
| 55 | /* */ | ||
| 56 | /* _fx_media_check PORTABLE C */ | ||
| 57 | /* 6.1 */ | ||
| 58 | /* AUTHOR */ | ||
| 59 | /* */ | ||
| 60 | /* William E. Lamie, Microsoft Corporation */ | ||
| 61 | /* */ | ||
| 62 | /* DESCRIPTION */ | ||
| 63 | /* */ | ||
| 64 | /* This function checks the specified media for basic structural */ | ||
| 65 | /* errors, including cross linking, invalid FAT chains, and lost */ | ||
| 66 | /* clusters. The function also provides the capability to correct */ | ||
| 67 | /* errors. */ | ||
| 68 | /* */ | ||
| 69 | /* The algorithm is to follow all sub-directories immediately and */ | ||
| 70 | /* check their contents. The maximum depth of sub-directories is */ | ||
| 71 | /* determined by the constant FX_MAX_DIRECTORY_NESTING. */ | ||
| 72 | /* By default, this is set at 20. Basically, the FAT chain of every */ | ||
| 73 | /* file and sub-directory is traversed. If valid, clusters are marked */ | ||
| 74 | /* in a logical FAT bit map to signal they are already in-use. The */ | ||
| 75 | /* algorithm should detect any broken or cross linked FAT condition. */ | ||
| 76 | /* */ | ||
| 77 | /* As for memory usage, the scratch memory supplied to the media check */ | ||
| 78 | /* function is used to hold several directory entries, a data */ | ||
| 79 | /* structure to "stack" the current directory entry position before */ | ||
| 80 | /* diving into the sub-directory, and finally the logical FAT bit map. */ | ||
| 81 | /* The basic data structures take from 512-1024 bytes and the logical */ | ||
| 82 | /* FAT bit map requires as many bits as there are clusters in your */ | ||
| 83 | /* device. For example, a device with 8000 clusters would require */ | ||
| 84 | /* 1000 bytes to represent. */ | ||
| 85 | /* */ | ||
| 86 | /* On the performance end of things, the traversal is reasonably fast */ | ||
| 87 | /* and is basically linear with the number of files and their sizes. */ | ||
| 88 | /* The lost cluster checking at the end of media check is a bit more */ | ||
| 89 | /* performance comprehensive. It basically checks that each unused */ | ||
| 90 | /* cluster is actually marked as free. You might decide to bypass this */ | ||
| 91 | /* step if no other errors are found... or there might be ways to */ | ||
| 92 | /* optimize the search by reading whole FAT sectors. You probably just */ | ||
| 93 | /* need to see how it behaves in your system. */ | ||
| 94 | /* */ | ||
| 95 | /* INPUT */ | ||
| 96 | /* */ | ||
| 97 | /* media_ptr Pointer to a previously */ | ||
| 98 | /* opened media */ | ||
| 99 | /* scratch_memory_ptr Pointer to memory area for */ | ||
| 100 | /* media check to use (as */ | ||
| 101 | /* mentioned above) */ | ||
| 102 | /* scratch_memory_size Size of the scratch memory */ | ||
| 103 | /* error_correction_option Specifies which - if any - */ | ||
| 104 | /* errors are corrected by */ | ||
| 105 | /* the media check function. */ | ||
| 106 | /* Setting the following bit */ | ||
| 107 | /* causes that error to be */ | ||
| 108 | /* corrected: */ | ||
| 109 | /* */ | ||
| 110 | /* 0x01 -> Fix FAT Chain Errors*/ | ||
| 111 | /* 0x02 -> Fix Directory Entry */ | ||
| 112 | /* Errors */ | ||
| 113 | /* 0x04 -> Fix Lost Clusters */ | ||
| 114 | /* */ | ||
| 115 | /* errors_detected Specifies the destination */ | ||
| 116 | /* ULONG to place the error */ | ||
| 117 | /* report from media check. */ | ||
| 118 | /* This has a similar bit map */ | ||
| 119 | /* as before: */ | ||
| 120 | /* */ | ||
| 121 | /* 0x01 -> FAT Chain Error(s) */ | ||
| 122 | /* 0x02 -> Directory Entry */ | ||
| 123 | /* Error(s) */ | ||
| 124 | /* 0x04 -> Lost Cluster(s) */ | ||
| 125 | /* */ | ||
| 126 | /* OUTPUT */ | ||
| 127 | /* */ | ||
| 128 | /* FX_SUCCESS Media check performed its */ | ||
| 129 | /* operation successfully. */ | ||
| 130 | /* This does not mean that */ | ||
| 131 | /* there were no errors. The */ | ||
| 132 | /* errors_detected variable */ | ||
| 133 | /* needs to be examined. */ | ||
| 134 | /* FX_MEDIA_NOT_OPEN The media was not open. */ | ||
| 135 | /* FX_NOT_ENOUGH_MEMORY The scratch memory was not */ | ||
| 136 | /* large enough or the nesting */ | ||
| 137 | /* depth was greater than the */ | ||
| 138 | /* maximum specified. */ | ||
| 139 | /* FX_IO_ERROR I/O Error reading/writing to */ | ||
| 140 | /* the media. */ | ||
| 141 | /* FX_ERROR_NOT_FIXED Fundamental problem with */ | ||
| 142 | /* media that couldn't be fixed*/ | ||
| 143 | /* */ | ||
| 144 | /* CALLS */ | ||
| 145 | /* */ | ||
| 146 | /* _fx_media_cache_invalidate Invalidate the cache */ | ||
| 147 | /* _fx_media_check_FAT_chain_check Walk the supplied FAT chain */ | ||
| 148 | /* _fx_media_check_lost_cluster_check Check for lost clusters */ | ||
| 149 | /* _fx_directory_entry_read Directory entry read */ | ||
| 150 | /* _fx_directory_entry_write Directory entry write */ | ||
| 151 | /* _fx_media_flush Flush changes to the media */ | ||
| 152 | /* _fx_utility_FAT_entry_write Write value to FAT entry */ | ||
| 153 | /* */ | ||
| 154 | /* CALLED BY */ | ||
| 155 | /* */ | ||
| 156 | /* Application Code */ | ||
| 157 | /* */ | ||
| 158 | /**************************************************************************/ | ||
| 159 | 18360 | UINT _fx_media_check(FX_MEDIA *media_ptr, UCHAR *scratch_memory_ptr, ULONG scratch_memory_size, ULONG error_correction_option, ULONG *errors_detected) | |
| 160 | { | ||
| 161 | |||
| 162 | CURRENT_DIRECTORY_ENTRY *current_directory; | ||
| 163 | ULONG total_entries, last_cluster, valid_clusters; | ||
| 164 | ULONG bytes_per_cluster, i, current_errors; | ||
| 165 | UINT status, long_name_size; | ||
| 166 | UINT current_directory_index; | ||
| 167 | UCHAR *logical_fat, *working_ptr; | ||
| 168 | ALIGN_TYPE address_mask; | ||
| 169 | FX_DIR_ENTRY *temp_dir_ptr, *source_dir_ptr, *dir_entry_ptr; | ||
| 170 | |||
| 171 | #ifdef TX_ENABLE_EVENT_TRACE | ||
| 172 | TX_TRACE_BUFFER_ENTRY *trace_event; | ||
| 173 | ULONG trace_timestamp; | ||
| 174 | #endif | ||
| 175 | |||
| 176 | |||
| 177 | /* Check the media to make sure it is open. */ | ||
| 178 |
2/2✓ Branch 2 → 3 taken 9 times.
✓ Branch 2 → 4 taken 18351 times.
|
18360 | if (media_ptr -> fx_media_id != FX_MEDIA_ID) |
| 179 | { | ||
| 180 | |||
| 181 | /* Return the media not opened error. */ | ||
| 182 | 9 | return(FX_MEDIA_NOT_OPEN); | |
| 183 | } | ||
| 184 | |||
| 185 | /* If trace is enabled, insert this event into the trace buffer. */ | ||
| 186 | FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_CHECK, media_ptr, scratch_memory_ptr, scratch_memory_size, 0, FX_TRACE_MEDIA_EVENTS, &trace_event, &trace_timestamp) | ||
| 187 | |||
| 188 | /* Protect against other threads accessing the media. */ | ||
| 189 | 10193 | FX_PROTECT | |
| 190 | |||
| 191 | /* Determine if there are any opened files. */ | ||
| 192 |
4/4✓ Branch 4 → 5 taken 4 times.
✓ Branch 4 → 6 taken 8154 times.
✓ Branch 5 → 6 taken 5 times.
✓ Branch 5 → 8 taken 10188 times.
|
18351 | if (media_ptr -> fx_media_opened_file_count) |
| 193 | { | ||
| 194 | |||
| 195 | /* There are opened files... this is an error! */ | ||
| 196 | |||
| 197 | /* Release protection. */ | ||
| 198 | 5 | FX_UNPROTECT | |
| 199 | |||
| 200 | /* Return an error. */ | ||
| 201 | 9 | return(FX_ACCESS_ERROR); | |
| 202 | } | ||
| 203 | |||
| 204 | /* Invalidate the cache. */ | ||
| 205 | 18342 | _fx_media_cache_invalidate(media_ptr); | |
| 206 | |||
| 207 | /* Initialize the reported error flag. */ | ||
| 208 | 18342 | *errors_detected = 0; | |
| 209 | |||
| 210 | /* Calculate the long name size, rounded up to something that is evenly divisible by 4. */ | ||
| 211 | 18342 | long_name_size = (((FX_MAX_LONG_NAME_LEN + 3) >> 2) << 2); | |
| 212 | |||
| 213 | /* Calculate the number of bytes per cluster. */ | ||
| 214 | 18342 | bytes_per_cluster = media_ptr -> fx_media_sectors_per_cluster * media_ptr -> fx_media_bytes_per_sector; | |
| 215 | |||
| 216 | /* Setup address mask. */ | ||
| 217 | 18342 | address_mask = sizeof(ULONG) - 1; | |
| 218 | 18342 | address_mask = ~address_mask; | |
| 219 | |||
| 220 | /* Setup working pointer. */ | ||
| 221 | 18342 | working_ptr = scratch_memory_ptr + (sizeof(ULONG) - 1); | |
| 222 | 18342 | working_ptr = (UCHAR *)(((ALIGN_TYPE)working_ptr) & address_mask); | |
| 223 | |||
| 224 | /* Memory is set aside for two FX_DIR_ENTRY structures */ | ||
| 225 | 18342 | dir_entry_ptr = (FX_DIR_ENTRY *)working_ptr; | |
| 226 | |||
| 227 | /* Adjust the scratch memory pointer forward. */ | ||
| 228 | 18342 | working_ptr = &working_ptr[sizeof(FX_DIR_ENTRY)]; | |
| 229 | |||
| 230 | /* Setup the name buffer for the first directory entry. */ | ||
| 231 | 18342 | dir_entry_ptr -> fx_dir_entry_name = (CHAR *)working_ptr; | |
| 232 | |||
| 233 | /* Adjust the scratch memory pointer forward. */ | ||
| 234 | 18342 | working_ptr = working_ptr + long_name_size + (sizeof(ULONG) - 1); | |
| 235 | 18342 | working_ptr = (UCHAR *)(((ALIGN_TYPE)working_ptr) & address_mask); | |
| 236 | |||
| 237 | /* Setup the source directory entry. */ | ||
| 238 | 18342 | source_dir_ptr = (FX_DIR_ENTRY *)working_ptr; | |
| 239 | |||
| 240 | /* Adjust the scratch memory pointer forward. */ | ||
| 241 | 18342 | working_ptr = &working_ptr[sizeof(FX_DIR_ENTRY)]; | |
| 242 | |||
| 243 | /* Setup the name buffer for the source directory entry. */ | ||
| 244 | 18342 | source_dir_ptr -> fx_dir_entry_name = (CHAR *)working_ptr; | |
| 245 | |||
| 246 | /* Adjust the scratch memory pointer forward. */ | ||
| 247 | 18342 | working_ptr = working_ptr + long_name_size + (sizeof(ULONG) - 1); | |
| 248 | 18342 | working_ptr = (UCHAR *)(((ALIGN_TYPE)working_ptr) & address_mask); | |
| 249 | |||
| 250 | /* Setup the current directory stack memory. */ | ||
| 251 | 18342 | current_directory = (CURRENT_DIRECTORY_ENTRY *)working_ptr; | |
| 252 | |||
| 253 | /* Allocate space for the size of the directory entry stack. This basically | ||
| 254 | defines the maximum level of sub-directories supported. */ | ||
| 255 | 18342 | working_ptr = &working_ptr[(FX_MAX_DIRECTORY_NESTING * sizeof(CURRENT_DIRECTORY_ENTRY))]; | |
| 256 | |||
| 257 | /* Setup the initial current directory entry. */ | ||
| 258 | 18342 | current_directory_index = 0; | |
| 259 | |||
| 260 | /* Adjust the size to account for the header information. */ | ||
| 261 |
4/4✓ Branch 7 → 8 taken 8 times.
✓ Branch 7 → 9 taken 8146 times.
✓ Branch 9 → 10 taken 10 times.
✓ Branch 9 → 12 taken 10178 times.
|
18342 | if (scratch_memory_size < (ULONG)((working_ptr - scratch_memory_ptr))) |
| 262 | { | ||
| 263 | |||
| 264 | /* Release media protection. */ | ||
| 265 | 10 | FX_UNPROTECT | |
| 266 | |||
| 267 | /* Return the not enough memory error. */ | ||
| 268 | 18 | return(FX_NOT_ENOUGH_MEMORY); | |
| 269 | } | ||
| 270 | |||
| 271 | /* Adjust the scratch memory size. */ | ||
| 272 | 18324 | scratch_memory_size = scratch_memory_size - (ULONG)(working_ptr - scratch_memory_ptr); | |
| 273 | |||
| 274 | /* Memory is set aside for logical FAT - one bit per cluster */ | ||
| 275 | 18324 | logical_fat = (UCHAR *)working_ptr; | |
| 276 | |||
| 277 | /* Determine if there is enough memory. */ | ||
| 278 |
4/4✓ Branch 9 → 10 taken 4004 times.
✓ Branch 9 → 11 taken 4142 times.
✓ Branch 12 → 13 taken 5005 times.
✓ Branch 12 → 15 taken 5173 times.
|
18324 | if (scratch_memory_size < ((media_ptr -> fx_media_total_clusters >> 3) + 1)) |
| 279 | { | ||
| 280 | |||
| 281 | /* Release media protection. */ | ||
| 282 | 5005 | FX_UNPROTECT | |
| 283 | |||
| 284 | /* Return the not enough memory error. */ | ||
| 285 | 9009 | return(FX_NOT_ENOUGH_MEMORY); | |
| 286 | } | ||
| 287 | |||
| 288 | /* Initialize the logical FAT table. */ | ||
| 289 |
4/4✓ Branch 13 → 12 taken 3464584 times.
✓ Branch 13 → 14 taken 4142 times.
✓ Branch 17 → 16 taken 4295986 times.
✓ Branch 17 → 18 taken 5173 times.
|
7769885 | for (i = 0; i < ((media_ptr -> fx_media_total_clusters >> 3) + 1); i++) |
| 290 | { | ||
| 291 | /* Clear the logical FAT entry, which actually represents eight clusters. */ | ||
| 292 | 7760570 | logical_fat[i] = 0; | |
| 293 | } | ||
| 294 | |||
| 295 | |||
| 296 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 297 |
4/4✓ Branch 14 → 15 taken 18 times.
✓ Branch 14 → 18 taken 2062 times.
✓ Branch 18 → 19 taken 18 times.
✓ Branch 18 → 22 taken 2062 times.
|
4160 | if (media_ptr -> fx_media_fault_tolerant_enabled) |
| 298 | { | ||
| 299 | ULONG cluster, cluster_number; | ||
| 300 | |||
| 301 | /* Mark the cluster used by fault tolerant as valid. */ | ||
| 302 | 36 | for (cluster = media_ptr -> fx_media_fault_tolerant_start_cluster; | |
| 303 |
4/4✓ Branch 17 → 16 taken 100 times.
✓ Branch 17 → 18 taken 18 times.
✓ Branch 21 → 20 taken 100 times.
✓ Branch 21 → 22 taken 18 times.
|
236 | cluster < media_ptr -> fx_media_fault_tolerant_start_cluster + media_ptr -> fx_media_fault_tolerant_clusters; |
| 304 | 200 | cluster++) | |
| 305 | { | ||
| 306 | |||
| 307 | 200 | cluster_number = cluster; | |
| 308 | |||
| 309 | |||
| 310 | 200 | logical_fat[cluster_number >> 3] = (UCHAR)(logical_fat[cluster_number >> 3] | (1 << (cluster_number & 7))); | |
| 311 | } | ||
| 312 | } | ||
| 313 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 314 | |||
| 315 | /* If FAT32 is present, determine if the root directory is coherent. */ | ||
| 316 |
7/7✓ Branch 14 → 15 taken 20 times.
✓ Branch 14 → 26 taken 2042 times.
✓ Branch 18 → 19 taken 66 times.
✓ Branch 18 → 30 taken 2044 times.
✓ Branch 18 → 33 taken 3063 times.
✓ Branch 22 → 23 taken 36 times.
✓ Branch 22 → 37 taken 2044 times.
|
9315 | if (media_ptr -> fx_media_32_bit_FAT) |
| 317 | { | ||
| 318 | |||
| 319 | /* A 32-bit FAT is present. We need to walk the clusters of the root directory to determine if | ||
| 320 | it is intact. */ | ||
| 321 | 122 | current_errors = _fx_media_check_FAT_chain_check(media_ptr, media_ptr -> fx_media_root_cluster_32, | |
| 322 | &last_cluster, &valid_clusters, logical_fat); | ||
| 323 | |||
| 324 | /* Make them part of the errors reported to the caller. */ | ||
| 325 | 122 | *errors_detected = *errors_detected | current_errors; | |
| 326 | |||
| 327 | /* Update the trace event with the errors detected. */ | ||
| 328 | FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_MEDIA_CHECK, 0, 0, 0, *errors_detected) | ||
| 329 | |||
| 330 | /* Determine if the I/O error is set. */ | ||
| 331 |
7/7✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 18 taken 18 times.
✓ Branch 20 → 21 taken 5 times.
✓ Branch 20 → 22 taken 34 times.
✓ Branch 20 → 23 taken 27 times.
✓ Branch 24 → 25 taken 2 times.
✓ Branch 24 → 27 taken 34 times.
|
122 | if (current_errors & FX_IO_ERROR) |
| 332 | { | ||
| 333 | |||
| 334 | /* Release media protection. */ | ||
| 335 | 5 | FX_UNPROTECT | |
| 336 | |||
| 337 | /* File I/O Error. */ | ||
| 338 | 9 | return(FX_IO_ERROR); | |
| 339 | } | ||
| 340 | |||
| 341 | /* Check the status. */ | ||
| 342 |
8/8✓ Branch 18 → 19 taken 10 times.
✓ Branch 18 → 26 taken 8 times.
✓ Branch 22 → 23 taken 10 times.
✓ Branch 22 → 30 taken 24 times.
✓ Branch 23 → 24 taken 15 times.
✓ Branch 23 → 33 taken 12 times.
✓ Branch 27 → 28 taken 10 times.
✓ Branch 27 → 37 taken 24 times.
|
113 | if (*errors_detected) |
| 343 | { | ||
| 344 | |||
| 345 | /* Determine if we can fix the FAT32 root directory error. */ | ||
| 346 |
15/15✓ Branch 19 → 20 taken 8 times.
✓ Branch 19 → 25 taken 2 times.
✓ Branch 20 → 21 taken 4 times.
✓ Branch 20 → 25 taken 4 times.
✓ Branch 23 → 24 taken 8 times.
✓ Branch 23 → 29 taken 2 times.
✓ Branch 24 → 25 taken 16 times.
✓ Branch 24 → 29 taken 4 times.
✓ Branch 24 → 31 taken 3 times.
✓ Branch 25 → 26 taken 6 times.
✓ Branch 25 → 31 taken 6 times.
✓ Branch 28 → 29 taken 8 times.
✓ Branch 28 → 35 taken 2 times.
✓ Branch 29 → 30 taken 4 times.
✓ Branch 29 → 35 taken 4 times.
|
45 | if ((valid_clusters) && (error_correction_option & FX_FAT_CHAIN_ERROR)) |
| 347 | { | ||
| 348 | |||
| 349 | /* Make the chain end at the last cluster. */ | ||
| 350 | 18 | status = _fx_utility_FAT_entry_write(media_ptr, last_cluster, media_ptr -> fx_media_fat_last); | |
| 351 | |||
| 352 | /* Determine if the write was successful. */ | ||
| 353 |
8/8✓ Branch 22 → 23 taken 2 times.
✓ Branch 22 → 24 taken 2 times.
✓ Branch 26 → 27 taken 2 times.
✓ Branch 26 → 28 taken 2 times.
✓ Branch 27 → 28 taken 3 times.
✓ Branch 27 → 30 taken 3 times.
✓ Branch 31 → 32 taken 2 times.
✓ Branch 31 → 34 taken 2 times.
|
18 | if (status) |
| 354 | { | ||
| 355 | |||
| 356 | /* Release media protection. */ | ||
| 357 | 5 | FX_UNPROTECT | |
| 358 | |||
| 359 | /* Return the error code. */ | ||
| 360 | 9 | return(status); | |
| 361 | } | ||
| 362 | |||
| 363 | /* Adjust the total entries in the root directory. */ | ||
| 364 | 9 | media_ptr -> fx_media_root_directory_entries = (valid_clusters * bytes_per_cluster) / FX_DIR_ENTRY_SIZE; | |
| 365 | } | ||
| 366 | else | ||
| 367 | { | ||
| 368 | |||
| 369 | /* Release media protection. */ | ||
| 370 | 15 | FX_UNPROTECT | |
| 371 | |||
| 372 | /* Return an error. */ | ||
| 373 | 27 | return(FX_ERROR_NOT_FIXED); | |
| 374 | } | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | /* Pickup total entries in the root directory. */ | ||
| 379 | 9270 | total_entries = media_ptr -> fx_media_root_directory_entries; | |
| 380 | |||
| 381 | /* Set temp directory pointer to NULL. */ | ||
| 382 | 9270 | temp_dir_ptr = FX_NULL; | |
| 383 | |||
| 384 | /* Put the root directory information in the entry stack */ | ||
| 385 | 9270 | current_directory[current_directory_index].current_total_entries = total_entries; | |
| 386 | 9270 | current_directory[current_directory_index].current_start_cluster = media_ptr -> fx_media_fat_last; | |
| 387 | 9270 | current_directory[current_directory_index].current_directory_entry = 0; | |
| 388 | |||
| 389 | /* Now we shall do the checking in depth first manner. */ | ||
| 390 | do | ||
| 391 | { | ||
| 392 | |||
| 393 | /* Pickup the directory index. */ | ||
| 394 | 11402 | i = current_directory[current_directory_index].current_directory_entry; | |
| 395 | |||
| 396 | /* Loop to process remaining directory entries. */ | ||
| 397 |
8/8✓ Branch 68 → 28 taken 28874 times.
✓ Branch 68 → 69 taken 10 times.
✓ Branch 72 → 32 taken 28834 times.
✓ Branch 72 → 73 taken 10 times.
✓ Branch 81 → 35 taken 44032 times.
✓ Branch 81 → 82 taken 15 times.
✓ Branch 85 → 39 taken 28834 times.
✓ Branch 85 → 86 taken 10 times.
|
130619 | while (i < current_directory[current_directory_index].current_total_entries) |
| 398 | { | ||
| 399 | |||
| 400 | /* Read a directory entry. */ | ||
| 401 | 130574 | status = _fx_directory_entry_read(media_ptr, temp_dir_ptr, &i, dir_entry_ptr); | |
| 402 | |||
| 403 | /* Determine if the read was successful. */ | ||
| 404 |
8/8✓ Branch 29 → 30 taken 1438 times.
✓ Branch 29 → 31 taken 27436 times.
✓ Branch 33 → 34 taken 1415 times.
✓ Branch 33 → 35 taken 27419 times.
✓ Branch 36 → 37 taken 2165 times.
✓ Branch 36 → 39 taken 41867 times.
✓ Branch 40 → 41 taken 1415 times.
✓ Branch 40 → 43 taken 27419 times.
|
130574 | if (status) |
| 405 | { | ||
| 406 | |||
| 407 | /* Release media protection. */ | ||
| 408 | 3580 | FX_UNPROTECT | |
| 409 | |||
| 410 | /* Return the error code. */ | ||
| 411 | 6433 | return(status); | |
| 412 | } | ||
| 413 | |||
| 414 | /* Check for the last entry. */ | ||
| 415 |
8/8✓ Branch 31 → 32 taken 504 times.
✓ Branch 31 → 33 taken 26932 times.
✓ Branch 35 → 36 taken 522 times.
✓ Branch 35 → 37 taken 26897 times.
✓ Branch 39 → 40 taken 782 times.
✓ Branch 39 → 41 taken 41085 times.
✓ Branch 43 → 44 taken 522 times.
✓ Branch 43 → 45 taken 26897 times.
|
124141 | if (dir_entry_ptr -> fx_dir_entry_name[0] == (CHAR)FX_DIR_ENTRY_DONE) |
| 416 | { | ||
| 417 | |||
| 418 | /* Last entry in this directory - no need to check further. */ | ||
| 419 | 2330 | break; | |
| 420 | } | ||
| 421 | |||
| 422 | /* Is the entry free? */ | ||
| 423 |
16/16✓ Branch 33 → 34 taken 10 times.
✓ Branch 33 → 36 taken 26922 times.
✓ Branch 34 → 35 taken 2 times.
✓ Branch 34 → 36 taken 8 times.
✓ Branch 37 → 38 taken 10 times.
✓ Branch 37 → 40 taken 26887 times.
✓ Branch 38 → 39 taken 2 times.
✓ Branch 38 → 40 taken 8 times.
✓ Branch 41 → 42 taken 15 times.
✓ Branch 41 → 44 taken 41070 times.
✓ Branch 42 → 43 taken 3 times.
✓ Branch 42 → 44 taken 12 times.
✓ Branch 45 → 46 taken 10 times.
✓ Branch 45 → 48 taken 26887 times.
✓ Branch 46 → 47 taken 2 times.
✓ Branch 46 → 48 taken 8 times.
|
121811 | if ((dir_entry_ptr -> fx_dir_entry_name[0] == (CHAR)FX_DIR_ENTRY_FREE) && (dir_entry_ptr -> fx_dir_entry_short_name[0] == 0)) |
| 424 | { | ||
| 425 | |||
| 426 | /* A deleted entry */ | ||
| 427 | 9 | i++; | |
| 428 | 9 | continue; | |
| 429 | } | ||
| 430 | |||
| 431 | |||
| 432 | /* Look for any cross links or errors in the FAT chain of current directory entry. */ | ||
| 433 | 121802 | current_errors = _fx_media_check_FAT_chain_check(media_ptr, dir_entry_ptr -> fx_dir_entry_cluster, | |
| 434 | &last_cluster, &valid_clusters, logical_fat); | ||
| 435 | |||
| 436 | /* Make them part of the errors reported to the caller. */ | ||
| 437 | 121802 | *errors_detected = *errors_detected | current_errors; | |
| 438 | |||
| 439 | /* Update the trace event with the errors detected. */ | ||
| 440 | FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_MEDIA_CHECK, 0, 0, 0, *errors_detected) | ||
| 441 | |||
| 442 | /* Determine if the I/O error is set. */ | ||
| 443 |
8/8✓ Branch 37 → 38 taken 454 times.
✓ Branch 37 → 39 taken 26476 times.
✓ Branch 41 → 42 taken 426 times.
✓ Branch 41 → 43 taken 26469 times.
✓ Branch 45 → 46 taken 703 times.
✓ Branch 45 → 48 taken 40379 times.
✓ Branch 49 → 50 taken 426 times.
✓ Branch 49 → 52 taken 26469 times.
|
121802 | if (current_errors & FX_IO_ERROR) |
| 444 | { | ||
| 445 | |||
| 446 | /* Release media protection. */ | ||
| 447 | 1129 | FX_UNPROTECT | |
| 448 | |||
| 449 | /* File I/O Error. */ | ||
| 450 | 2009 | return(FX_IO_ERROR); | |
| 451 | } | ||
| 452 | |||
| 453 | /* Check for errors. */ | ||
| 454 |
8/8✓ Branch 39 → 40 taken 24686 times.
✓ Branch 39 → 45 taken 1790 times.
✓ Branch 43 → 44 taken 24663 times.
✓ Branch 43 → 49 taken 1806 times.
✓ Branch 48 → 49 taken 37694 times.
✓ Branch 48 → 55 taken 2685 times.
✓ Branch 52 → 53 taken 24663 times.
✓ Branch 52 → 59 taken 1806 times.
|
119793 | if (*errors_detected) |
| 455 | { | ||
| 456 | |||
| 457 | /* Determine if we can fix the FAT chain. */ | ||
| 458 |
8/8✓ Branch 40 → 41 taken 10190 times.
✓ Branch 40 → 45 taken 14496 times.
✓ Branch 44 → 45 taken 10167 times.
✓ Branch 44 → 49 taken 14496 times.
✓ Branch 49 → 50 taken 15950 times.
✓ Branch 49 → 55 taken 21744 times.
✓ Branch 53 → 54 taken 10167 times.
✓ Branch 53 → 59 taken 14496 times.
|
111706 | if (error_correction_option & FX_FAT_CHAIN_ERROR) |
| 459 | { | ||
| 460 | |||
| 461 | /* Determine if there is a valid cluster to write the EOF to. */ | ||
| 462 |
8/8✓ Branch 41 → 42 taken 978 times.
✓ Branch 41 → 45 taken 9212 times.
✓ Branch 45 → 46 taken 978 times.
✓ Branch 45 → 49 taken 9189 times.
✓ Branch 50 → 51 taken 1517 times.
✓ Branch 50 → 55 taken 14433 times.
✓ Branch 54 → 55 taken 978 times.
✓ Branch 54 → 59 taken 9189 times.
|
46474 | if (valid_clusters) |
| 463 | { | ||
| 464 | |||
| 465 | /* Write EOF in the last FAT entry. */ | ||
| 466 | 4451 | status = _fx_utility_FAT_entry_write(media_ptr, last_cluster, media_ptr -> fx_media_fat_last); | |
| 467 | |||
| 468 | /* Determine if the write was successful. */ | ||
| 469 |
8/8✓ Branch 43 → 44 taken 2 times.
✓ Branch 43 → 45 taken 976 times.
✓ Branch 47 → 48 taken 2 times.
✓ Branch 47 → 49 taken 976 times.
✓ Branch 52 → 53 taken 3 times.
✓ Branch 52 → 55 taken 1514 times.
✓ Branch 56 → 57 taken 2 times.
✓ Branch 56 → 59 taken 976 times.
|
4451 | if (status) |
| 470 | { | ||
| 471 | |||
| 472 | /* Release media protection. */ | ||
| 473 | 5 | FX_UNPROTECT | |
| 474 | |||
| 475 | /* Return the error code. */ | ||
| 476 | 9 | return(status); | |
| 477 | } | ||
| 478 | } | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | /* Determine if we need to update the size of the directory entry. */ | ||
| 483 |
8/8✓ Branch 45 → 46 taken 3068 times.
✓ Branch 45 → 53 taken 23406 times.
✓ Branch 49 → 50 taken 3068 times.
✓ Branch 49 → 57 taken 23399 times.
✓ Branch 55 → 56 taken 4614 times.
✓ Branch 55 → 64 taken 35762 times.
✓ Branch 59 → 60 taken 3068 times.
✓ Branch 59 → 68 taken 23399 times.
|
119784 | if (dir_entry_ptr -> fx_dir_entry_file_size > (valid_clusters * bytes_per_cluster)) |
| 484 | { | ||
| 485 | |||
| 486 | /* Yes, update the directory entry's size. */ | ||
| 487 | 13818 | dir_entry_ptr -> fx_dir_entry_file_size = valid_clusters * bytes_per_cluster; | |
| 488 | |||
| 489 | /* Determine if the new file size is zero. */ | ||
| 490 |
8/8✓ Branch 46 → 47 taken 1622 times.
✓ Branch 46 → 49 taken 1446 times.
✓ Branch 50 → 51 taken 1622 times.
✓ Branch 50 → 53 taken 1446 times.
✓ Branch 56 → 57 taken 2433 times.
✓ Branch 56 → 59 taken 2181 times.
✓ Branch 60 → 61 taken 1622 times.
✓ Branch 60 → 63 taken 1446 times.
|
13818 | if (dir_entry_ptr -> fx_dir_entry_file_size == 0) |
| 491 | { | ||
| 492 | |||
| 493 | /* Consider this a directory error. */ | ||
| 494 | 7299 | *errors_detected = *errors_detected | FX_DIRECTORY_ERROR; | |
| 495 | |||
| 496 | /* Update the trace event with the errors detected. */ | ||
| 497 | FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_MEDIA_CHECK, 0, 0, 0, *errors_detected) | ||
| 498 | |||
| 499 | /* Clear the starting cluster number of this directory entry. */ | ||
| 500 | 7299 | dir_entry_ptr -> fx_dir_entry_cluster = 0; | |
| 501 | |||
| 502 | /* If directory fixing is required, delete this directory entry as well. */ | ||
| 503 |
8/8✓ Branch 47 → 48 taken 820 times.
✓ Branch 47 → 49 taken 802 times.
✓ Branch 51 → 52 taken 820 times.
✓ Branch 51 → 53 taken 802 times.
✓ Branch 57 → 58 taken 1230 times.
✓ Branch 57 → 59 taken 1203 times.
✓ Branch 61 → 62 taken 820 times.
✓ Branch 61 → 63 taken 802 times.
|
7299 | if (error_correction_option & FX_DIRECTORY_ERROR) |
| 504 | { | ||
| 505 | |||
| 506 | /* Mark the entry as deleted. */ | ||
| 507 | 3690 | dir_entry_ptr -> fx_dir_entry_name[0] = (CHAR)FX_DIR_ENTRY_FREE; | |
| 508 | 3690 | dir_entry_ptr -> fx_dir_entry_short_name[0] = (CHAR)FX_DIR_ENTRY_FREE; | |
| 509 | } | ||
| 510 | } | ||
| 511 | |||
| 512 | /* Only update the directory if the FAT chain was actually updated. */ | ||
| 513 |
8/8✓ Branch 49 → 50 taken 1506 times.
✓ Branch 49 → 53 taken 1562 times.
✓ Branch 53 → 54 taken 1506 times.
✓ Branch 53 → 57 taken 1562 times.
✓ Branch 59 → 60 taken 2271 times.
✓ Branch 59 → 64 taken 2343 times.
✓ Branch 63 → 64 taken 1506 times.
✓ Branch 63 → 68 taken 1562 times.
|
13818 | if (error_correction_option & FX_FAT_CHAIN_ERROR) |
| 514 | { | ||
| 515 | |||
| 516 | /* Update the directory entry. */ | ||
| 517 | 6789 | status = _fx_directory_entry_write(media_ptr, dir_entry_ptr); | |
| 518 | |||
| 519 | /* Determine if the write was successful. */ | ||
| 520 |
8/8✓ Branch 51 → 52 taken 108 times.
✓ Branch 51 → 53 taken 1398 times.
✓ Branch 55 → 56 taken 159 times.
✓ Branch 55 → 57 taken 1347 times.
✓ Branch 61 → 62 taken 132 times.
✓ Branch 61 → 64 taken 2139 times.
✓ Branch 65 → 66 taken 159 times.
✓ Branch 65 → 68 taken 1347 times.
|
6789 | if (status) |
| 521 | { | ||
| 522 | |||
| 523 | /* Release media protection. */ | ||
| 524 | 291 | FX_UNPROTECT | |
| 525 | |||
| 526 | /* Return the error code. */ | ||
| 527 | 558 | return(status); | |
| 528 | } | ||
| 529 | } | ||
| 530 | } | ||
| 531 | |||
| 532 | /* Determine if the entry is a sub-directory. */ | ||
| 533 |
8/8✓ Branch 53 → 54 taken 922 times.
✓ Branch 53 → 60 taken 25444 times.
✓ Branch 57 → 58 taken 922 times.
✓ Branch 57 → 64 taken 25386 times.
✓ Branch 64 → 65 taken 1421 times.
✓ Branch 64 → 72 taken 38823 times.
✓ Branch 68 → 69 taken 922 times.
✓ Branch 68 → 76 taken 25386 times.
|
119226 | if ((dir_entry_ptr -> fx_dir_entry_attributes & FX_DIRECTORY) |
| 534 |
8/8✓ Branch 54 → 55 taken 6 times.
✓ Branch 54 → 60 taken 916 times.
✓ Branch 58 → 59 taken 6 times.
✓ Branch 58 → 64 taken 916 times.
✓ Branch 65 → 66 taken 9 times.
✓ Branch 65 → 72 taken 1412 times.
✓ Branch 69 → 70 taken 6 times.
✓ Branch 69 → 76 taken 916 times.
|
4187 | && (valid_clusters == 0)) |
| 535 | { | ||
| 536 | |||
| 537 | /* Consider this a directory error. */ | ||
| 538 | 27 | *errors_detected = *errors_detected | FX_DIRECTORY_ERROR; | |
| 539 | |||
| 540 | /* Update the trace event with the errors detected. */ | ||
| 541 | FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_MEDIA_CHECK, 0, 0, 0, *errors_detected) | ||
| 542 | |||
| 543 | /* Determine if we can fix the error. */ | ||
| 544 |
8/8✓ Branch 55 → 56 taken 4 times.
✓ Branch 55 → 60 taken 2 times.
✓ Branch 59 → 60 taken 4 times.
✓ Branch 59 → 64 taken 2 times.
✓ Branch 66 → 67 taken 6 times.
✓ Branch 66 → 72 taken 3 times.
✓ Branch 70 → 71 taken 4 times.
✓ Branch 70 → 76 taken 2 times.
|
27 | if (error_correction_option & FX_DIRECTORY_ERROR) |
| 545 | { | ||
| 546 | |||
| 547 | /* Yes, make the directory entry free. */ | ||
| 548 | 18 | dir_entry_ptr -> fx_dir_entry_name[0] = (CHAR)FX_DIR_ENTRY_FREE; | |
| 549 | 18 | dir_entry_ptr -> fx_dir_entry_short_name[0] = (CHAR)FX_DIR_ENTRY_FREE; | |
| 550 | |||
| 551 | /* Delete the sub-directory entry. */ | ||
| 552 | 18 | status = _fx_directory_entry_write(media_ptr, dir_entry_ptr); | |
| 553 | |||
| 554 | /* Determine if the write was successful. */ | ||
| 555 |
8/8✓ Branch 57 → 58 taken 2 times.
✓ Branch 57 → 59 taken 2 times.
✓ Branch 61 → 62 taken 2 times.
✓ Branch 61 → 63 taken 2 times.
✓ Branch 68 → 69 taken 3 times.
✓ Branch 68 → 71 taken 3 times.
✓ Branch 72 → 73 taken 2 times.
✓ Branch 72 → 75 taken 2 times.
|
18 | if (status) |
| 556 | { | ||
| 557 | |||
| 558 | /* Release media protection. */ | ||
| 559 | 5 | FX_UNPROTECT | |
| 560 | |||
| 561 | /* Return the error code. */ | ||
| 562 | 9 | return(status); | |
| 563 | } | ||
| 564 | |||
| 565 | /* Move to next entry. */ | ||
| 566 | 9 | i++; | |
| 567 | 9 | continue; | |
| 568 | } | ||
| 569 | } | ||
| 570 | |||
| 571 | /* Determine if the entry is a directory. */ | ||
| 572 |
8/8✓ Branch 60 → 61 taken 918 times.
✓ Branch 60 → 64 taken 25444 times.
✓ Branch 64 → 65 taken 918 times.
✓ Branch 64 → 68 taken 25386 times.
✓ Branch 72 → 73 taken 1415 times.
✓ Branch 72 → 77 taken 38823 times.
✓ Branch 76 → 77 taken 918 times.
✓ Branch 76 → 81 taken 25386 times.
|
119208 | if (dir_entry_ptr -> fx_dir_entry_attributes & FX_DIRECTORY) |
| 573 | { | ||
| 574 | |||
| 575 | /* Current entry is a directory. The algorithm is designed to follow all | ||
| 576 | sub-directories immediately, i.e., a depth first search. */ | ||
| 577 | |||
| 578 | /* First, save the next entry position. */ | ||
| 579 | 4169 | current_directory[current_directory_index].current_directory_entry = i + 1; | |
| 580 | |||
| 581 | /* Push the current directory entry on the stack. */ | ||
| 582 | 4169 | current_directory_index++; | |
| 583 | |||
| 584 | /* Check for current directory stack overflow. */ | ||
| 585 |
8/8✓ Branch 61 → 62 taken 2 times.
✓ Branch 61 → 63 taken 916 times.
✓ Branch 65 → 66 taken 2 times.
✓ Branch 65 → 67 taken 916 times.
✓ Branch 73 → 74 taken 3 times.
✓ Branch 73 → 76 taken 1412 times.
✓ Branch 77 → 78 taken 2 times.
✓ Branch 77 → 80 taken 916 times.
|
4169 | if (current_directory_index >= FX_MAX_DIRECTORY_NESTING) |
| 586 | { | ||
| 587 | |||
| 588 | /* Release media protection. */ | ||
| 589 | 5 | FX_UNPROTECT | |
| 590 | |||
| 591 | /* Current directory stack overflow. Return error. */ | ||
| 592 | 9 | return(FX_NOT_ENOUGH_MEMORY); | |
| 593 | } | ||
| 594 | |||
| 595 | /* Otherwise, setup the new directory entry. */ | ||
| 596 | 4160 | current_directory[current_directory_index].current_total_entries = (valid_clusters * bytes_per_cluster) / FX_DIR_ENTRY_SIZE; | |
| 597 | 4160 | current_directory[current_directory_index].current_start_cluster = dir_entry_ptr -> fx_dir_entry_cluster; | |
| 598 | 4160 | current_directory[current_directory_index].current_directory_entry = 2; | |
| 599 | |||
| 600 | /* Setup new source directory. */ | ||
| 601 | 4160 | source_dir_ptr -> fx_dir_entry_cluster = dir_entry_ptr -> fx_dir_entry_cluster; | |
| 602 | 4160 | source_dir_ptr -> fx_dir_entry_file_size = current_directory[current_directory_index].current_total_entries; | |
| 603 | 4160 | source_dir_ptr -> fx_dir_entry_last_search_cluster = 0; | |
| 604 | 4160 | temp_dir_ptr = source_dir_ptr; | |
| 605 | |||
| 606 | /* Skip the first two entries of sub-directories. */ | ||
| 607 | 4160 | i = 2; | |
| 608 | |||
| 609 | } | ||
| 610 | else | ||
| 611 | { | ||
| 612 | |||
| 613 | /* Regular file entry. */ | ||
| 614 | |||
| 615 | /* Check for an invalid file size. */ | ||
| 616 |
8/8✓ Branch 64 → 65 taken 2 times.
✓ Branch 64 → 66 taken 25442 times.
✓ Branch 68 → 69 taken 2 times.
✓ Branch 68 → 70 taken 25384 times.
✓ Branch 77 → 78 taken 3 times.
✓ Branch 77 → 79 taken 38820 times.
✓ Branch 81 → 82 taken 2 times.
✓ Branch 81 → 83 taken 25384 times.
|
115039 | if (((valid_clusters * bytes_per_cluster) - dir_entry_ptr -> fx_dir_entry_file_size) > bytes_per_cluster) |
| 617 | { | ||
| 618 | |||
| 619 | /* There are more clusters allocated than needed for the file's size. Indicate that this error | ||
| 620 | is present. */ | ||
| 621 | 9 | *errors_detected = *errors_detected | FX_FILE_SIZE_ERROR; | |
| 622 | |||
| 623 | /* Update the trace event with the errors detected. */ | ||
| 624 | FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_MEDIA_CHECK, 0, 0, 0, *errors_detected) | ||
| 625 | |||
| 626 | /* For now, don't shorten the cluster chain. */ | ||
| 627 | } | ||
| 628 | |||
| 629 | /* Look into the next entry in the current directory. */ | ||
| 630 | 115039 | i++; | |
| 631 | } | ||
| 632 | } | ||
| 633 | |||
| 634 | /* Once we get here, we have exhausted the current directory and need to return to the previous | ||
| 635 | directory. */ | ||
| 636 | |||
| 637 | /* Check for being at the root directory. */ | ||
| 638 |
8/8✓ Branch 69 → 70 taken 46 times.
✓ Branch 69 → 71 taken 468 times.
✓ Branch 73 → 74 taken 64 times.
✓ Branch 73 → 75 taken 468 times.
✓ Branch 82 → 83 taken 69 times.
✓ Branch 82 → 84 taken 728 times.
✓ Branch 86 → 87 taken 64 times.
✓ Branch 86 → 88 taken 468 times.
|
2375 | if (current_directory_index == 0) |
| 639 | { | ||
| 640 | |||
| 641 | /* Yes, we have now exhausted searching the root directory so we are done! */ | ||
| 642 | 243 | break; | |
| 643 | } | ||
| 644 | |||
| 645 | /* Backup to the place we left off in the previous directory. */ | ||
| 646 | 2132 | current_directory_index--; | |
| 647 | |||
| 648 | /* Determine if we are now back at the root directory. */ | ||
| 649 |
8/8✓ Branch 71 → 72 taken 464 times.
✓ Branch 71 → 73 taken 4 times.
✓ Branch 75 → 76 taken 464 times.
✓ Branch 75 → 77 taken 4 times.
✓ Branch 84 → 85 taken 722 times.
✓ Branch 84 → 86 taken 6 times.
✓ Branch 88 → 89 taken 464 times.
✓ Branch 88 → 90 taken 4 times.
|
2132 | if (current_directory[current_directory_index].current_start_cluster == media_ptr -> fx_media_fat_last) |
| 650 | { | ||
| 651 | |||
| 652 | /* The search directory should be NULL since it is the root directory. */ | ||
| 653 | 2114 | temp_dir_ptr = FX_NULL; | |
| 654 | } | ||
| 655 | else | ||
| 656 | { | ||
| 657 | |||
| 658 | /* Otherwise, we are returning to a sub-directory. Setup the search directory | ||
| 659 | appropriately. */ | ||
| 660 | 18 | source_dir_ptr -> fx_dir_entry_cluster = current_directory[current_directory_index].current_start_cluster; | |
| 661 | 18 | source_dir_ptr -> fx_dir_entry_file_size = current_directory[current_directory_index].current_total_entries; | |
| 662 | 18 | source_dir_ptr -> fx_dir_entry_last_search_cluster = 0; | |
| 663 | 18 | temp_dir_ptr = source_dir_ptr; | |
| 664 | } | ||
| 665 | } while (1); | ||
| 666 | |||
| 667 | |||
| 668 | /* At this point, all the files and sub-directories have been examined. We now need to check for | ||
| 669 | lost clusters in the logical FAT. A lost cluster is basically anything that is not reported in | ||
| 670 | the logical FAT that has a non-zero value in the real FAT. */ | ||
| 671 | 243 | current_errors = _fx_media_check_lost_cluster_check(media_ptr, logical_fat, media_ptr -> fx_media_total_clusters, error_correction_option); | |
| 672 | |||
| 673 | /* Incorporate the error returned by the lost FAT check. */ | ||
| 674 | 243 | *errors_detected = *errors_detected | current_errors; | |
| 675 | |||
| 676 | /* Update the trace event with the errors detected. */ | ||
| 677 | FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_MEDIA_CHECK, 0, 0, 0, *errors_detected) | ||
| 678 | |||
| 679 | /* Determine if the I/O error is set. */ | ||
| 680 |
8/8✓ Branch 76 → 77 taken 6 times.
✓ Branch 76 → 78 taken 40 times.
✓ Branch 80 → 81 taken 6 times.
✓ Branch 80 → 82 taken 58 times.
✓ Branch 89 → 90 taken 9 times.
✓ Branch 89 → 92 taken 60 times.
✓ Branch 93 → 94 taken 6 times.
✓ Branch 93 → 96 taken 58 times.
|
243 | if (current_errors & FX_IO_ERROR) |
| 681 | { | ||
| 682 | |||
| 683 | /* Release media protection. */ | ||
| 684 | 15 | FX_UNPROTECT | |
| 685 | |||
| 686 | /* File I/O Error. */ | ||
| 687 | 27 | return(FX_IO_ERROR); | |
| 688 | } | ||
| 689 | |||
| 690 | /* Determine if there was any error and update was selected. */ | ||
| 691 |
16/16✓ Branch 78 → 79 taken 30 times.
✓ Branch 78 → 81 taken 10 times.
✓ Branch 79 → 80 taken 24 times.
✓ Branch 79 → 81 taken 6 times.
✓ Branch 82 → 83 taken 30 times.
✓ Branch 82 → 85 taken 28 times.
✓ Branch 83 → 84 taken 24 times.
✓ Branch 83 → 85 taken 6 times.
✓ Branch 92 → 93 taken 48 times.
✓ Branch 92 → 95 taken 12 times.
✓ Branch 93 → 94 taken 36 times.
✓ Branch 93 → 95 taken 12 times.
✓ Branch 96 → 97 taken 32 times.
✓ Branch 96 → 99 taken 26 times.
✓ Branch 97 → 98 taken 24 times.
✓ Branch 97 → 99 taken 8 times.
|
216 | if ((*errors_detected) && (error_correction_option)) |
| 692 | { | ||
| 693 | |||
| 694 | /* Flush any unwritten items to the media. */ | ||
| 695 | 108 | _fx_media_flush(media_ptr); | |
| 696 | } | ||
| 697 | |||
| 698 | /* Release media protection. */ | ||
| 699 | 118 | FX_UNPROTECT | |
| 700 | |||
| 701 | /* At this point, we have completed the diagnostic of the media, return success! */ | ||
| 702 | 216 | return(FX_SUCCESS); | |
| 703 | } | ||
| 704 | |||
| 705 |