fx_file_open.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 | /** File */ | ||
| 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_file.h" | ||
| 32 | #include "fx_utility.h" | ||
| 33 | |||
| 34 | |||
| 35 | /**************************************************************************/ | ||
| 36 | /* */ | ||
| 37 | /* FUNCTION RELEASE */ | ||
| 38 | /* */ | ||
| 39 | /* _fx_file_open PORTABLE C */ | ||
| 40 | /* 6.1 */ | ||
| 41 | /* AUTHOR */ | ||
| 42 | /* */ | ||
| 43 | /* William E. Lamie, Microsoft Corporation */ | ||
| 44 | /* */ | ||
| 45 | /* DESCRIPTION */ | ||
| 46 | /* */ | ||
| 47 | /* This function first attempts to find the specified file. If found, */ | ||
| 48 | /* the open request is validated and the file is opened. During the */ | ||
| 49 | /* opening process, all of the FAT entries for this file are examined */ | ||
| 50 | /* for their integrity. */ | ||
| 51 | /* */ | ||
| 52 | /* INPUT */ | ||
| 53 | /* */ | ||
| 54 | /* media_ptr Media control block pointer */ | ||
| 55 | /* file_ptr File control block pointer */ | ||
| 56 | /* file_name Name pointer */ | ||
| 57 | /* open_type Type of open requested */ | ||
| 58 | /* */ | ||
| 59 | /* OUTPUT */ | ||
| 60 | /* */ | ||
| 61 | /* return status */ | ||
| 62 | /* */ | ||
| 63 | /* CALLS */ | ||
| 64 | /* */ | ||
| 65 | /* _fx_directory_search Search for the file name in */ | ||
| 66 | /* the directory structure */ | ||
| 67 | /* _fx_utility_FAT_entry_read Read a FAT entry */ | ||
| 68 | /* */ | ||
| 69 | /* CALLED BY */ | ||
| 70 | /* */ | ||
| 71 | /* Application Code */ | ||
| 72 | /* */ | ||
| 73 | /**************************************************************************/ | ||
| 74 | 6972280 | UINT _fx_file_open(FX_MEDIA *media_ptr, FX_FILE *file_ptr, CHAR *file_name, UINT open_type) | |
| 75 | { | ||
| 76 | |||
| 77 | UINT status; | ||
| 78 | #ifndef FX_DISABLE_CONSECUTIVE_DETECT | ||
| 79 | UINT leading_consecutive; | ||
| 80 | #endif /* FX_DISABLE_CONSECUTIVE_DETECT */ | ||
| 81 | ULONG cluster; | ||
| 82 | 6972280 | ULONG contents = 0; | |
| 83 | ULONG open_count; | ||
| 84 | FX_FILE *tail_ptr; | ||
| 85 | FX_FILE *search_ptr; | ||
| 86 | ULONG bytes_per_cluster; | ||
| 87 | UINT last_cluster; | ||
| 88 | ULONG cluster_count; | ||
| 89 | ULONG64 bytes_available; | ||
| 90 | ULONG64 bytes_remaining; | ||
| 91 | ULONG fat_last; | ||
| 92 | #ifndef FX_DISABLE_FAST_OPEN | ||
| 93 | UINT fast_open; | ||
| 94 | #endif /* FX_DISABLE_FAST_OPEN */ | ||
| 95 | UCHAR not_a_file_attr; | ||
| 96 | |||
| 97 | |||
| 98 | /* Check the media to make sure it is open. */ | ||
| 99 |
2/2✓ Branch 2 → 3 taken 691 times.
✓ Branch 2 → 4 taken 6971589 times.
|
6972280 | if (media_ptr -> fx_media_id != FX_MEDIA_ID) |
| 100 | { | ||
| 101 | |||
| 102 | /* Return the media not opened error. */ | ||
| 103 | 691 | return(FX_MEDIA_NOT_OPEN); | |
| 104 | } | ||
| 105 | |||
| 106 | #ifndef FX_MEDIA_STATISTICS_DISABLE | ||
| 107 | |||
| 108 | /* Increment the number of times this service has been called. */ | ||
| 109 | 6971589 | media_ptr -> fx_media_file_opens++; | |
| 110 | #endif | ||
| 111 | |||
| 112 | /* Clear the notify function. */ | ||
| 113 | 6971589 | file_ptr -> fx_file_write_notify = FX_NULL; | |
| 114 | |||
| 115 | /* Determine the type of FAT and setup variables accordingly. */ | ||
| 116 |
2/2✓ Branch 4 → 5 taken 6830664 times.
✓ Branch 4 → 6 taken 140925 times.
|
6971589 | if (media_ptr -> fx_media_32_bit_FAT) |
| 117 | { | ||
| 118 | 6830664 | fat_last = FX_LAST_CLUSTER_1_32; | |
| 119 | 6830664 | not_a_file_attr = FX_DIRECTORY | FX_VOLUME; | |
| 120 | } | ||
| 121 | else | ||
| 122 | { | ||
| 123 | 140925 | fat_last = FX_LAST_CLUSTER_1; | |
| 124 | 140925 | not_a_file_attr = FX_DIRECTORY | FX_VOLUME; | |
| 125 | } | ||
| 126 | |||
| 127 | #ifndef FX_DISABLE_FAST_OPEN | ||
| 128 | /* Determine if a fast open is selected. */ | ||
| 129 |
2/2✓ Branch 7 → 8 taken 18 times.
✓ Branch 7 → 9 taken 6971571 times.
|
6971589 | if (open_type == FX_OPEN_FOR_READ_FAST) |
| 130 | { | ||
| 131 | |||
| 132 | /* Yes, convert the open type to a standard read. */ | ||
| 133 | 18 | open_type = FX_OPEN_FOR_READ; | |
| 134 | |||
| 135 | /* Set the open fast flag. */ | ||
| 136 | 18 | fast_open = FX_TRUE; | |
| 137 | } | ||
| 138 | else | ||
| 139 | { | ||
| 140 | |||
| 141 | /* A fast open is not selected, set the flag to false. */ | ||
| 142 | 6971571 | fast_open = FX_FALSE; | |
| 143 | } | ||
| 144 | #endif /* FX_DISABLE_FAST_OPEN */ | ||
| 145 | |||
| 146 | /* If trace is enabled, register this object. */ | ||
| 147 | FX_TRACE_OBJECT_REGISTER(FX_TRACE_OBJECT_TYPE_FILE, file_ptr, file_name, 0, 0) | ||
| 148 | |||
| 149 | /* If trace is enabled, insert this event into the trace buffer. */ | ||
| 150 | FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_OPEN, media_ptr, file_ptr, file_name, open_type, FX_TRACE_FILE_EVENTS, 0, 0) | ||
| 151 | |||
| 152 | /* Protect against other threads accessing the media. */ | ||
| 153 | 6895829 | FX_PROTECT | |
| 154 | |||
| 155 | /* Setup file name pointer. */ | ||
| 156 | 6971588 | file_ptr -> fx_file_dir_entry.fx_dir_entry_name = file_ptr -> fx_file_name_buffer; | |
| 157 | 6971588 | file_ptr -> fx_file_dir_entry.fx_dir_entry_short_name[0] = 0; | |
| 158 | |||
| 159 | /* Search the system for the supplied file name. */ | ||
| 160 | 6971588 | status = _fx_directory_search(media_ptr, file_name, &(file_ptr -> fx_file_dir_entry), FX_NULL, FX_NULL); | |
| 161 | |||
| 162 | /* Determine if the search was successful. */ | ||
| 163 |
4/4✓ Branch 11 → 12 taken 50 times.
✓ Branch 11 → 13 taken 75710 times.
✓ Branch 12 → 13 taken 123 times.
✓ Branch 12 → 15 taken 6895705 times.
|
6971588 | if (status != FX_SUCCESS) |
| 164 | { | ||
| 165 | |||
| 166 | /* Release media protection. */ | ||
| 167 | 123 | FX_UNPROTECT | |
| 168 | |||
| 169 | /* Return the error code. */ | ||
| 170 | 173 | return(status); | |
| 171 | } | ||
| 172 | |||
| 173 | /* Check to make sure the found entry is a file. */ | ||
| 174 |
4/4✓ Branch 13 → 14 taken 4 times.
✓ Branch 13 → 15 taken 75706 times.
✓ Branch 15 → 16 taken 5 times.
✓ Branch 15 → 18 taken 6895700 times.
|
6971415 | if (file_ptr -> fx_file_dir_entry.fx_dir_entry_attributes & not_a_file_attr) |
| 175 | { | ||
| 176 | |||
| 177 | /* Release media protection. */ | ||
| 178 | 5 | FX_UNPROTECT | |
| 179 | |||
| 180 | /* Return the not a file error code. */ | ||
| 181 | 9 | return(FX_NOT_A_FILE); | |
| 182 | } | ||
| 183 | |||
| 184 | #ifdef FX_SINGLE_OPEN_LEGACY | ||
| 185 | /* Check to make sure the access is okay. */ | ||
| 186 | if (open_type == FX_OPEN_FOR_READ) | ||
| 187 | { | ||
| 188 | |||
| 189 | /* Check the list of open files for others open for writing. */ | ||
| 190 | open_count = media_ptr -> fx_media_opened_file_count; | ||
| 191 | search_ptr = media_ptr -> fx_media_opened_file_list; | ||
| 192 | while (open_count) | ||
| 193 | { | ||
| 194 | |||
| 195 | /* Look at each opened file to see if the same file is opened | ||
| 196 | for writing. */ | ||
| 197 | if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector == | ||
| 198 | file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) && | ||
| 199 | (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset == | ||
| 200 | file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset) && | ||
| 201 | (search_ptr -> fx_file_open_mode)) | ||
| 202 | { | ||
| 203 | |||
| 204 | /* Release media protection. */ | ||
| 205 | FX_UNPROTECT | ||
| 206 | |||
| 207 | /* The file has been opened for writing by a previous call. */ | ||
| 208 | return(FX_ACCESS_ERROR); | ||
| 209 | } | ||
| 210 | |||
| 211 | /* Adjust the pointer and decrement the search count. */ | ||
| 212 | search_ptr = search_ptr -> fx_file_opened_next; | ||
| 213 | open_count--; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | else | ||
| 217 | #else | ||
| 218 |
4/4✓ Branch 15 → 16 taken 71612 times.
✓ Branch 15 → 27 taken 4094 times.
✓ Branch 18 → 19 taken 3489345 times.
✓ Branch 18 → 33 taken 3406355 times.
|
6971406 | if (open_type == FX_OPEN_FOR_WRITE) |
| 219 | #endif | ||
| 220 | { | ||
| 221 | |||
| 222 | /* A open for write request is present, check the file attributes | ||
| 223 | and the list of open files for any other open instance of | ||
| 224 | this file. */ | ||
| 225 |
4/4✓ Branch 16 → 17 taken 4 times.
✓ Branch 16 → 18 taken 71608 times.
✓ Branch 19 → 20 taken 5 times.
✓ Branch 19 → 22 taken 3489340 times.
|
3560957 | if (media_ptr -> fx_media_driver_write_protect) |
| 226 | { | ||
| 227 | |||
| 228 | /* Release media protection. */ | ||
| 229 | 5 | FX_UNPROTECT | |
| 230 | |||
| 231 | /* Return write protect error. */ | ||
| 232 | 9 | return(FX_WRITE_PROTECT); | |
| 233 | } | ||
| 234 | |||
| 235 |
4/4✓ Branch 18 → 19 taken 4 times.
✓ Branch 18 → 20 taken 71604 times.
✓ Branch 22 → 23 taken 5 times.
✓ Branch 22 → 25 taken 3489335 times.
|
3560948 | if (file_ptr -> fx_file_dir_entry.fx_dir_entry_attributes & (UCHAR)(FX_READ_ONLY)) |
| 236 | { | ||
| 237 | |||
| 238 | /* Release media protection. */ | ||
| 239 | 5 | FX_UNPROTECT | |
| 240 | |||
| 241 | /* Return the not a file error code. */ | ||
| 242 | 9 | return(FX_ACCESS_ERROR); | |
| 243 | } | ||
| 244 | |||
| 245 | /* Also search the opened files to see if this file is currently | ||
| 246 | opened. */ | ||
| 247 | 3560939 | open_count = media_ptr -> fx_media_opened_file_count; | |
| 248 | 3560939 | search_ptr = media_ptr -> fx_media_opened_file_list; | |
| 249 |
4/4✓ Branch 26 → 21 taken 268236 times.
✓ Branch 26 → 27 taken 71600 times.
✓ Branch 32 → 26 taken 335295 times.
✓ Branch 32 → 33 taken 3489330 times.
|
4164461 | while (open_count) |
| 250 | { | ||
| 251 | |||
| 252 | /* Look at each opened file to see if the same file is already opened. */ | ||
| 253 | #ifdef FX_SINGLE_OPEN_LEGACY | ||
| 254 | if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector == | ||
| 255 | file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) && | ||
| 256 | (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset == | ||
| 257 | file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset)) | ||
| 258 | #else | ||
| 259 | /* Look at each opened file to see if the same file is already opened | ||
| 260 | for writing. */ | ||
| 261 | 603531 | if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector == | |
| 262 |
4/4✓ Branch 21 → 22 taken 264248 times.
✓ Branch 21 → 25 taken 3988 times.
✓ Branch 26 → 27 taken 330310 times.
✓ Branch 26 → 31 taken 4985 times.
|
603531 | file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) && |
| 263 | 594558 | (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset == | |
| 264 |
4/4✓ Branch 22 → 23 taken 28 times.
✓ Branch 22 → 25 taken 264220 times.
✓ Branch 27 → 28 taken 35 times.
✓ Branch 27 → 31 taken 330275 times.
|
594558 | file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset) && |
| 265 |
4/4✓ Branch 23 → 24 taken 4 times.
✓ Branch 23 → 25 taken 24 times.
✓ Branch 28 → 29 taken 5 times.
✓ Branch 28 → 31 taken 30 times.
|
63 | (search_ptr -> fx_file_open_mode == FX_OPEN_FOR_WRITE)) |
| 266 | #endif | ||
| 267 | { | ||
| 268 | |||
| 269 | /* Release media protection. */ | ||
| 270 | 5 | FX_UNPROTECT | |
| 271 | |||
| 272 | /* The file is currently open. */ | ||
| 273 | 9 | return(FX_ACCESS_ERROR); | |
| 274 | } | ||
| 275 | |||
| 276 | /* Adjust the pointer and decrement the search count. */ | ||
| 277 | 603522 | search_ptr = search_ptr -> fx_file_opened_next; | |
| 278 | 603522 | open_count--; | |
| 279 | } | ||
| 280 | } | ||
| 281 | |||
| 282 | /* At this point, we are ready to walk list of clusters to setup the | ||
| 283 | initial condition of this file as well as to verify its integrity. */ | ||
| 284 | 6971379 | cluster = file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster; | |
| 285 | 6971379 | bytes_remaining = file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size; | |
| 286 | 6971379 | bytes_per_cluster = ((ULONG)media_ptr -> fx_media_bytes_per_sector) * | |
| 287 | 6971379 | ((ULONG)media_ptr -> fx_media_sectors_per_cluster); | |
| 288 | 6971379 | file_ptr -> fx_file_current_physical_cluster = 0; | |
| 289 | |||
| 290 | /* Check for invalid value. */ | ||
| 291 |
4/4✓ Branch 27 → 28 taken 4 times.
✓ Branch 27 → 29 taken 75690 times.
✓ Branch 33 → 34 taken 5 times.
✓ Branch 33 → 36 taken 6895680 times.
|
6971379 | if (bytes_per_cluster == 0) |
| 292 | { | ||
| 293 | |||
| 294 | /* Release media protection. */ | ||
| 295 | 5 | FX_UNPROTECT | |
| 296 | |||
| 297 | /* Invalid media, return error. */ | ||
| 298 | 9 | return(FX_MEDIA_INVALID); | |
| 299 | } | ||
| 300 | |||
| 301 | 6971370 | last_cluster = 0; | |
| 302 | 6971370 | cluster_count = 0; | |
| 303 | |||
| 304 | #ifndef FX_DISABLE_CONSECUTIVE_DETECT | ||
| 305 | 6971370 | leading_consecutive = 1; | |
| 306 | #endif /* FX_DISABLE_CONSECUTIVE_DETECT */ | ||
| 307 | 6971370 | file_ptr -> fx_file_consecutive_cluster = 1; | |
| 308 | #ifndef FX_DISABLE_FAST_OPEN | ||
| 309 | |||
| 310 | /* Determine if the file is being open for reading with the fast option. */ | ||
| 311 |
4/4✓ Branch 29 → 30 taken 8 times.
✓ Branch 29 → 31 taken 75682 times.
✓ Branch 36 → 37 taken 10 times.
✓ Branch 36 → 38 taken 6895670 times.
|
6971370 | if (fast_open) |
| 312 | { | ||
| 313 | |||
| 314 | /* Calculate the bytes available. */ | ||
| 315 | 18 | bytes_available = ((bytes_remaining + bytes_per_cluster - 1) / bytes_per_cluster) * bytes_per_cluster; | |
| 316 | |||
| 317 | } | ||
| 318 | else | ||
| 319 | #endif /* FX_DISABLE_FAST_OPEN */ | ||
| 320 | { | ||
| 321 | |||
| 322 | /* Follow the link of FAT entries. */ | ||
| 323 |
8/8✓ Branch 50 → 51 taken 1978938 times.
✓ Branch 50 → 52 taken 26295 times.
✓ Branch 51 → 32 taken 1929563 times.
✓ Branch 51 → 52 taken 49375 times.
✓ Branch 59 → 60 taken 67622434 times.
✓ Branch 59 → 61 taken 32891 times.
✓ Branch 60 → 39 taken 60759670 times.
✓ Branch 60 → 61 taken 6862764 times.
|
69660558 | while ((cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved)) |
| 324 | { | ||
| 325 | |||
| 326 | /* Increment the number of clusters. */ | ||
| 327 | 62689233 | cluster_count++; | |
| 328 | |||
| 329 | /* Read the current cluster entry from the FAT. */ | ||
| 330 | 62689233 | status = _fx_utility_FAT_entry_read(media_ptr, cluster, &contents); | |
| 331 | |||
| 332 | /* Check the return value. */ | ||
| 333 |
4/4✓ Branch 33 → 34 taken 4 times.
✓ Branch 33 → 35 taken 1929559 times.
✓ Branch 40 → 41 taken 5 times.
✓ Branch 40 → 43 taken 60759665 times.
|
62689233 | if (status != FX_SUCCESS) |
| 334 | { | ||
| 335 | |||
| 336 | /* Release media protection. */ | ||
| 337 | 5 | FX_UNPROTECT | |
| 338 | |||
| 339 | /* Return the error status. */ | ||
| 340 | 9 | return(status); | |
| 341 | } | ||
| 342 | |||
| 343 | /* Determine if the cluster is invalid (points to itself) or the count exceeds the total number of clusters. */ | ||
| 344 |
8/8✓ Branch 35 → 36 taken 1929555 times.
✓ Branch 35 → 37 taken 4 times.
✓ Branch 36 → 37 taken 4 times.
✓ Branch 36 → 38 taken 1929551 times.
✓ Branch 43 → 44 taken 60759660 times.
✓ Branch 43 → 45 taken 5 times.
✓ Branch 44 → 45 taken 5 times.
✓ Branch 44 → 47 taken 60759655 times.
|
62689224 | if ((cluster == contents) || (cluster_count > media_ptr -> fx_media_total_clusters)) |
| 345 | { | ||
| 346 | |||
| 347 | /* Release media protection. */ | ||
| 348 | 10 | FX_UNPROTECT | |
| 349 | |||
| 350 | /* Return the bad status. */ | ||
| 351 | 18 | return(FX_FAT_READ_ERROR); | |
| 352 | } | ||
| 353 | |||
| 354 | #ifndef FX_DISABLE_CONSECUTIVE_DETECT | ||
| 355 | |||
| 356 | /* Check if present and next clusters are consecutive */ | ||
| 357 |
4/4✓ Branch 38 → 39 taken 1858688 times.
✓ Branch 38 → 41 taken 70863 times.
✓ Branch 47 → 48 taken 53869741 times.
✓ Branch 47 → 50 taken 6889914 times.
|
62689206 | if (cluster + 1 == contents) |
| 358 | { | ||
| 359 | |||
| 360 | /* Determine if clusters are consecutive so far. */ | ||
| 361 |
4/4✓ Branch 39 → 40 taken 1858588 times.
✓ Branch 39 → 42 taken 100 times.
✓ Branch 48 → 49 taken 53866127 times.
✓ Branch 48 → 51 taken 3614 times.
|
55728429 | if (leading_consecutive) |
| 362 | { | ||
| 363 | |||
| 364 | /* Yes, increment the number of leading consecutive clusters. */ | ||
| 365 | 55724715 | file_ptr -> fx_file_consecutive_cluster++; | |
| 366 | } | ||
| 367 | } | ||
| 368 | else | ||
| 369 | { | ||
| 370 | |||
| 371 | /* The clusters are no longer consecutive, clear the consecutive flag. */ | ||
| 372 | 6960777 | leading_consecutive = 0; | |
| 373 | } | ||
| 374 | #endif /* FX_DISABLE_CONSECUTIVE_DETECT */ | ||
| 375 | |||
| 376 | /* Save the last valid cluster. */ | ||
| 377 | 62689206 | last_cluster = cluster; | |
| 378 | |||
| 379 | /* Setup for the next cluster. */ | ||
| 380 | 62689206 | cluster = contents; | |
| 381 | |||
| 382 | /* Determine if this is the last written cluster. We need to remember this | ||
| 383 | for open for writing. */ | ||
| 384 |
4/4✓ Branch 42 → 43 taken 1880156 times.
✓ Branch 42 → 44 taken 49395 times.
✓ Branch 51 → 52 taken 53896868 times.
✓ Branch 51 → 53 taken 6862787 times.
|
62689206 | if (bytes_remaining > bytes_per_cluster) |
| 385 | { | ||
| 386 | |||
| 387 | /* Still more written clusters, just decrement the counter. */ | ||
| 388 | 55777024 | bytes_remaining = bytes_remaining - bytes_per_cluster; | |
| 389 | } | ||
| 390 |
4/4✓ Branch 44 → 45 taken 49375 times.
✓ Branch 44 → 49 taken 20 times.
✓ Branch 53 → 54 taken 6862765 times.
✓ Branch 53 → 58 taken 22 times.
|
6912182 | else if (!file_ptr -> fx_file_current_physical_cluster) |
| 391 | { | ||
| 392 | |||
| 393 | /* Remember this cluster number. */ | ||
| 394 | 6912140 | file_ptr -> fx_file_current_physical_cluster = last_cluster; | |
| 395 | |||
| 396 | /* Remember the relative cluster. */ | ||
| 397 | 6912140 | file_ptr -> fx_file_current_relative_cluster = cluster_count - 1; | |
| 398 | |||
| 399 | /* If the remaining bytes exactly fits the cluster size, check for | ||
| 400 | a possible adjustment to the next cluster. */ | ||
| 401 |
8/8✓ Branch 45 → 46 taken 4218 times.
✓ Branch 45 → 49 taken 45157 times.
✓ Branch 46 → 47 taken 4214 times.
✓ Branch 46 → 49 taken 4 times.
✓ Branch 54 → 55 taken 3605972 times.
✓ Branch 54 → 58 taken 3256793 times.
✓ Branch 55 → 56 taken 3605967 times.
✓ Branch 55 → 58 taken 5 times.
|
6912140 | if ((bytes_remaining == bytes_per_cluster) && |
| 402 |
4/4✓ Branch 47 → 48 taken 4 times.
✓ Branch 47 → 49 taken 4210 times.
✓ Branch 56 → 57 taken 5 times.
✓ Branch 56 → 58 taken 3605962 times.
|
3610181 | (cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved)) |
| 403 | { | ||
| 404 | |||
| 405 | /* We need to position to next allocated cluster. */ | ||
| 406 | 9 | file_ptr -> fx_file_current_physical_cluster = cluster; | |
| 407 | 9 | file_ptr -> fx_file_current_relative_cluster++; | |
| 408 | |||
| 409 | /* Clear the remaining bytes. */ | ||
| 410 | 9 | bytes_remaining = 0; | |
| 411 | } | ||
| 412 | } | ||
| 413 | } | ||
| 414 | |||
| 415 | /* Determine if the number of clusters is large enough to support the | ||
| 416 | specified file size. */ | ||
| 417 | 6971325 | bytes_available = ((ULONG64)media_ptr -> fx_media_bytes_per_sector) * | |
| 418 | 6971325 | ((ULONG64)media_ptr -> fx_media_sectors_per_cluster) * | |
| 419 | 6971325 | ((ULONG64)cluster_count); | |
| 420 | |||
| 421 | /* Check the bytes available in the cluster chain against the directory entry file size. */ | ||
| 422 |
8/8✓ Branch 52 → 53 taken 75656 times.
✓ Branch 52 → 55 taken 14 times.
✓ Branch 53 → 54 taken 49375 times.
✓ Branch 53 → 56 taken 26281 times.
✓ Branch 61 → 62 taken 6895639 times.
✓ Branch 61 → 64 taken 16 times.
✓ Branch 62 → 63 taken 6862765 times.
✓ Branch 62 → 66 taken 32874 times.
|
6971325 | if ((bytes_available < file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size) || |
| 423 |
4/4✓ Branch 54 → 55 taken 6 times.
✓ Branch 54 → 56 taken 49369 times.
✓ Branch 63 → 64 taken 8 times.
✓ Branch 63 → 66 taken 6862757 times.
|
6912140 | ((cluster_count) && (contents < fat_last))) |
| 424 | { | ||
| 425 | /* File is corrupt, release media protection. */ | ||
| 426 | 24 | FX_UNPROTECT | |
| 427 | |||
| 428 | /* Return a corrupt file error status. */ | ||
| 429 | 44 | return(FX_FILE_CORRUPT); | |
| 430 | } | ||
| 431 | } | ||
| 432 | |||
| 433 | /* The file is okay, populate the file control block and complete the | ||
| 434 | file open process. */ | ||
| 435 | 6971299 | file_ptr -> fx_file_id = FX_FILE_ID; | |
| 436 | 6971299 | file_ptr -> fx_file_name = file_ptr -> fx_file_name_buffer; | |
| 437 | 6971299 | file_ptr -> fx_file_media_ptr = media_ptr; | |
| 438 | 6971299 | file_ptr -> fx_file_open_mode = open_type; | |
| 439 | 6971299 | file_ptr -> fx_file_modified = FX_FALSE; | |
| 440 | 6971299 | file_ptr -> fx_file_total_clusters = cluster_count; | |
| 441 | 6971299 | file_ptr -> fx_file_first_physical_cluster = file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster; | |
| 442 | 6971299 | file_ptr -> fx_file_last_physical_cluster = last_cluster; | |
| 443 | 6971299 | file_ptr -> fx_file_current_file_size = file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size; | |
| 444 | 6971299 | file_ptr -> fx_file_current_available_size = bytes_available; | |
| 445 | 6971299 | file_ptr -> fx_file_disable_burst_cache = FX_FALSE; | |
| 446 | |||
| 447 | /* Set the current settings based on how the file was opened. */ | ||
| 448 |
4/4✓ Branch 56 → 57 taken 4094 times.
✓ Branch 56 → 58 taken 71564 times.
✓ Branch 66 → 67 taken 3406355 times.
✓ Branch 66 → 68 taken 3489286 times.
|
6971299 | if (open_type == FX_OPEN_FOR_READ) |
| 449 | { | ||
| 450 | |||
| 451 | /* Position the pointers to the beginning of the file. */ | ||
| 452 | 3410449 | file_ptr -> fx_file_current_physical_cluster = file_ptr -> fx_file_first_physical_cluster; | |
| 453 | 3410449 | file_ptr -> fx_file_current_relative_cluster = 0; | |
| 454 | 3410449 | file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) + | |
| 455 | 3410449 | (((ULONG64)(file_ptr -> fx_file_first_physical_cluster - FX_FAT_ENTRY_START)) * | |
| 456 | 3410449 | ((ULONG)media_ptr -> fx_media_sectors_per_cluster)); | |
| 457 | 3410449 | file_ptr -> fx_file_current_relative_sector = 0; | |
| 458 | 3410449 | file_ptr -> fx_file_current_logical_offset = 0; | |
| 459 | 3410449 | file_ptr -> fx_file_current_file_offset = 0; | |
| 460 | } | ||
| 461 | else | ||
| 462 | { | ||
| 463 | |||
| 464 | /* Open for writing - position the pointers to the end of the file. */ | ||
| 465 | |||
| 466 | /* Determine if the remaining bytes fit exactly into the cluster size. */ | ||
| 467 |
4/4✓ Branch 58 → 59 taken 202 times.
✓ Branch 58 → 60 taken 71362 times.
✓ Branch 68 → 69 taken 1800442 times.
✓ Branch 68 → 70 taken 1688844 times.
|
3560850 | if (bytes_remaining == bytes_per_cluster) |
| 468 | { | ||
| 469 | |||
| 470 | /* Position to the end of the cluster. */ | ||
| 471 | 1800644 | file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) + | |
| 472 | 1800644 | (((ULONG64)file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) * | |
| 473 | 1800644 | ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + | |
| 474 | 1800644 | ((ULONG)(((bytes_remaining - 1) / (ULONG)media_ptr -> fx_media_bytes_per_sector))); | |
| 475 | 1800644 | file_ptr -> fx_file_current_relative_sector = (ULONG)(((bytes_remaining - 1) / (ULONG)media_ptr -> fx_media_bytes_per_sector)); | |
| 476 | 1800644 | file_ptr -> fx_file_current_file_offset = file_ptr -> fx_file_current_file_size; | |
| 477 | 1800644 | file_ptr -> fx_file_current_logical_offset = media_ptr -> fx_media_bytes_per_sector; | |
| 478 | } | ||
| 479 | else | ||
| 480 | { | ||
| 481 | |||
| 482 | /* Position file parameters at end of last cluster allocation. */ | ||
| 483 | 1760206 | file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) + | |
| 484 | 1760206 | (((ULONG64)file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) * | |
| 485 | 1760206 | ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + | |
| 486 | 1760206 | ((ULONG)((bytes_remaining / (ULONG)media_ptr -> fx_media_bytes_per_sector))); | |
| 487 | 1760206 | file_ptr -> fx_file_current_relative_sector = (ULONG)((bytes_remaining / (ULONG)media_ptr -> fx_media_bytes_per_sector)); | |
| 488 | 1760206 | file_ptr -> fx_file_current_file_offset = file_ptr -> fx_file_current_file_size; | |
| 489 | 1760206 | file_ptr -> fx_file_current_logical_offset = (ULONG)bytes_remaining % ((ULONG)media_ptr -> fx_media_bytes_per_sector); | |
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 494 | /* By default, the whole file is used. */ | ||
| 495 | 6879889 | file_ptr -> fx_file_maximum_size_used = file_ptr -> fx_file_current_file_size; | |
| 496 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 497 | |||
| 498 | /* Place newly opened file on the list of open files for | ||
| 499 | this media. First, check for an empty list. */ | ||
| 500 |
4/4✓ Branch 61 → 62 taken 44372 times.
✓ Branch 61 → 63 taken 31286 times.
✓ Branch 71 → 72 taken 55465 times.
✓ Branch 71 → 73 taken 6840176 times.
|
6971299 | if (media_ptr -> fx_media_opened_file_list) |
| 501 | { | ||
| 502 | |||
| 503 | /* Pickup tail pointer. */ | ||
| 504 | 99837 | tail_ptr = (media_ptr -> fx_media_opened_file_list) -> fx_file_opened_previous; | |
| 505 | |||
| 506 | /* Place the new file in the list. */ | ||
| 507 | 99837 | (media_ptr -> fx_media_opened_file_list) -> fx_file_opened_previous = file_ptr; | |
| 508 | 99837 | tail_ptr -> fx_file_opened_next = file_ptr; | |
| 509 | |||
| 510 | /* Setup this file's opened links. */ | ||
| 511 | 99837 | file_ptr -> fx_file_opened_previous = tail_ptr; | |
| 512 | 99837 | file_ptr -> fx_file_opened_next = media_ptr -> fx_media_opened_file_list; | |
| 513 | } | ||
| 514 | else | ||
| 515 | { | ||
| 516 | |||
| 517 | /* The opened media list is empty. Add the media to empty list. */ | ||
| 518 | 6871462 | media_ptr -> fx_media_opened_file_list = file_ptr; | |
| 519 | 6871462 | file_ptr -> fx_file_opened_next = file_ptr; | |
| 520 | 6871462 | file_ptr -> fx_file_opened_previous = file_ptr; | |
| 521 | } | ||
| 522 | |||
| 523 | /* Increment the opened file counter. */ | ||
| 524 | 6971299 | media_ptr -> fx_media_opened_file_count++; | |
| 525 | |||
| 526 | /* Release media protection. */ | ||
| 527 | 6895641 | FX_UNPROTECT | |
| 528 | |||
| 529 | /* Open is complete, return successful status. */ | ||
| 530 | 6971295 | return(FX_SUCCESS); | |
| 531 | } | ||
| 532 | |||
| 533 |