fx_directory_create.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 | /** Directory */ | ||
| 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 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 34 | #include "fx_fault_tolerant.h" | ||
| 35 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 36 | |||
| 37 | |||
| 38 | /**************************************************************************/ | ||
| 39 | /* */ | ||
| 40 | /* FUNCTION RELEASE */ | ||
| 41 | /* */ | ||
| 42 | /* _fx_directory_create PORTABLE C */ | ||
| 43 | /* 6.1 */ | ||
| 44 | /* AUTHOR */ | ||
| 45 | /* */ | ||
| 46 | /* William E. Lamie, Microsoft Corporation */ | ||
| 47 | /* */ | ||
| 48 | /* DESCRIPTION */ | ||
| 49 | /* */ | ||
| 50 | /* This function first attempts to find the specified directory. */ | ||
| 51 | /* If found, the create request is invalid and an error is returned */ | ||
| 52 | /* to the caller. After the file name verification is made, a search */ | ||
| 53 | /* for a free directory entry will be made. If nothing is available, */ | ||
| 54 | /* an error will be returned to the caller. Otherwise, if all is */ | ||
| 55 | /* okay, an empty directory will be created. */ | ||
| 56 | /* */ | ||
| 57 | /* INPUT */ | ||
| 58 | /* */ | ||
| 59 | /* media_ptr Media control block pointer */ | ||
| 60 | /* directory_name Directory name */ | ||
| 61 | /* */ | ||
| 62 | /* OUTPUT */ | ||
| 63 | /* */ | ||
| 64 | /* return status */ | ||
| 65 | /* */ | ||
| 66 | /* CALLS */ | ||
| 67 | /* */ | ||
| 68 | /* _fx_directory_entry_write Write the new directory entry */ | ||
| 69 | /* _fx_directory_name_extract Pickup next part of name */ | ||
| 70 | /* _fx_directory_search Search for the file name in */ | ||
| 71 | /* the directory structure */ | ||
| 72 | /* _fx_directory_free_search Search for a free directory */ | ||
| 73 | /* entry */ | ||
| 74 | /* _fx_utility_FAT_flush Flush written FAT entries */ | ||
| 75 | /* _fx_utility_FAT_entry_read Read a FAT entry */ | ||
| 76 | /* _fx_utility_FAT_entry_write Write a FAT entry */ | ||
| 77 | /* _fx_utility_logical_sector_flush Flush the written log sector */ | ||
| 78 | /* _fx_utility_logical_sector_read Read logical sector */ | ||
| 79 | /* _fx_fault_tolerant_transaction_start Start fault tolerant */ | ||
| 80 | /* transaction */ | ||
| 81 | /* _fx_fault_tolerant_transaction_end End fault tolerant transaction*/ | ||
| 82 | /* _fx_fault_tolerant_recover Recover FAT chain */ | ||
| 83 | /* _fx_fault_tolerant_reset_log_file Reset the log file */ | ||
| 84 | /* */ | ||
| 85 | /* CALLED BY */ | ||
| 86 | /* */ | ||
| 87 | /* Application Code */ | ||
| 88 | /* */ | ||
| 89 | /**************************************************************************/ | ||
| 90 | 205999 | UINT _fx_directory_create(FX_MEDIA *media_ptr, CHAR *directory_name) | |
| 91 | { | ||
| 92 | |||
| 93 | UINT status; | ||
| 94 | ULONG FAT_index; | ||
| 95 | ULONG FAT_value; | ||
| 96 | UINT sectors; | ||
| 97 | ULONG total_clusters; | ||
| 98 | CHAR *work_ptr; | ||
| 99 | ULONG64 logical_sector; | ||
| 100 | ULONG i; | ||
| 101 | FX_DIR_ENTRY dir_entry; | ||
| 102 | FX_DIR_ENTRY sub_dir_entry; | ||
| 103 | FX_DIR_ENTRY search_directory; | ||
| 104 | |||
| 105 | FX_INT_SAVE_AREA | ||
| 106 | |||
| 107 | |||
| 108 | #ifndef FX_MEDIA_STATISTICS_DISABLE | ||
| 109 | |||
| 110 | /* Increment the number of times this service has been called. */ | ||
| 111 | 205999 | media_ptr -> fx_media_directory_creates++; | |
| 112 | #endif | ||
| 113 | |||
| 114 | /* Determine if the supplied name is less than the maximum supported name size. The | ||
| 115 | maximum name (FX_MAX_LONG_NAME_LEN) is defined in fx_api.h. */ | ||
| 116 | 205999 | i = 0; | |
| 117 | 205999 | work_ptr = (CHAR *)directory_name; | |
| 118 |
4/4✓ Branch 10 → 11 taken 999563 times.
✓ Branch 10 → 12 taken 205990 times.
✓ Branch 11 → 3 taken 999554 times.
✓ Branch 11 → 12 taken 9 times.
|
1205553 | while (*work_ptr && (i < FX_MAX_LONG_NAME_LEN)) |
| 119 | { | ||
| 120 | |||
| 121 | /* Determine if the character designates a new path. */ | ||
| 122 |
4/4✓ Branch 3 → 4 taken 997385 times.
✓ Branch 3 → 5 taken 2169 times.
✓ Branch 4 → 5 taken 9170 times.
✓ Branch 4 → 6 taken 988215 times.
|
999554 | if ((*work_ptr == '\\') || (*work_ptr == '/')) |
| 123 | { | ||
| 124 | /* Yes, reset the name size. */ | ||
| 125 | 11339 | i = 0; | |
| 126 | } | ||
| 127 | /* Check for leading spaces. */ | ||
| 128 |
4/4✓ Branch 6 → 7 taken 639 times.
✓ Branch 6 → 8 taken 987576 times.
✓ Branch 7 → 8 taken 45 times.
✓ Branch 7 → 9 taken 594 times.
|
988215 | else if ((*work_ptr != ' ') || (i != 0)) |
| 129 | { | ||
| 130 | |||
| 131 | /* No leading spaces, increment the name size. */ | ||
| 132 | 987621 | i++; | |
| 133 | } | ||
| 134 | |||
| 135 | /* Move to the next character. */ | ||
| 136 | 999554 | work_ptr++; | |
| 137 | } | ||
| 138 | |||
| 139 | /* Determine if the supplied name is valid. */ | ||
| 140 |
4/4✓ Branch 12 → 13 taken 205990 times.
✓ Branch 12 → 14 taken 9 times.
✓ Branch 13 → 14 taken 9 times.
✓ Branch 13 → 15 taken 205981 times.
|
205999 | if ((i == 0) || (i >= FX_MAX_LONG_NAME_LEN)) |
| 141 | { | ||
| 142 | |||
| 143 | /* Return an invalid name value. */ | ||
| 144 | 18 | return(FX_INVALID_NAME); | |
| 145 | } | ||
| 146 | |||
| 147 | /* Setup pointer to media name buffer. */ | ||
| 148 | 205981 | dir_entry.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN; | |
| 149 | |||
| 150 | /* Setup search directory pointer to another media name buffer. */ | ||
| 151 | 205981 | search_directory.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN * 2; | |
| 152 | |||
| 153 | /* Clear the short name string. */ | ||
| 154 | 205981 | dir_entry.fx_dir_entry_short_name[0] = 0; | |
| 155 | |||
| 156 | /* Clear the search short name string. */ | ||
| 157 | 205981 | search_directory.fx_dir_entry_short_name[0] = 0; | |
| 158 | |||
| 159 | /* Check the media to make sure it is open. */ | ||
| 160 |
2/2✓ Branch 15 → 16 taken 9 times.
✓ Branch 15 → 17 taken 205972 times.
|
205981 | if (media_ptr -> fx_media_id != FX_MEDIA_ID) |
| 161 | { | ||
| 162 | |||
| 163 | /* Return the media not opened error. */ | ||
| 164 | 9 | return(FX_MEDIA_NOT_OPEN); | |
| 165 | } | ||
| 166 | |||
| 167 | /* If trace is enabled, insert this event into the trace buffer. */ | ||
| 168 | FX_TRACE_IN_LINE_INSERT(FX_TRACE_DIRECTORY_CREATE, media_ptr, directory_name, 0, 0, FX_TRACE_DIRECTORY_EVENTS, 0, 0) | ||
| 169 | |||
| 170 | /* Protect against other threads accessing the media. */ | ||
| 171 | 114244 | FX_PROTECT | |
| 172 | |||
| 173 | /* Check for write protect at the media level (set by driver). */ | ||
| 174 |
4/4✓ Branch 17 → 18 taken 4 times.
✓ Branch 17 → 19 taken 91724 times.
✓ Branch 18 → 19 taken 5 times.
✓ Branch 18 → 21 taken 114239 times.
|
205972 | if (media_ptr -> fx_media_driver_write_protect) |
| 175 | { | ||
| 176 | |||
| 177 | /* Release media protection. */ | ||
| 178 | 5 | FX_UNPROTECT | |
| 179 | |||
| 180 | /* Return write protect error. */ | ||
| 181 | 9 | return(FX_WRITE_PROTECT); | |
| 182 | } | ||
| 183 | |||
| 184 | /* Make sure there is at least one cluster remaining for the new file. */ | ||
| 185 |
4/4✓ Branch 19 → 20 taken 4 times.
✓ Branch 19 → 21 taken 91720 times.
✓ Branch 21 → 22 taken 5 times.
✓ Branch 21 → 24 taken 114234 times.
|
205963 | if (!media_ptr -> fx_media_available_clusters) |
| 186 | { | ||
| 187 | |||
| 188 | /* Release media protection. */ | ||
| 189 | 5 | FX_UNPROTECT | |
| 190 | |||
| 191 | /* Return a no-space error. */ | ||
| 192 | 9 | return(FX_NO_MORE_SPACE); | |
| 193 | } | ||
| 194 | |||
| 195 | /* Search the system for the supplied directory name. */ | ||
| 196 | 205954 | status = _fx_directory_search(media_ptr, directory_name, &dir_entry, &search_directory, &work_ptr); | |
| 197 | |||
| 198 | /* Determine if the search was successful. */ | ||
| 199 |
4/4✓ Branch 22 → 23 taken 10901 times.
✓ Branch 22 → 24 taken 80819 times.
✓ Branch 25 → 26 taken 13188 times.
✓ Branch 25 → 28 taken 101046 times.
|
205954 | if (status == FX_SUCCESS) |
| 200 | { | ||
| 201 | |||
| 202 | /* Release media protection. */ | ||
| 203 | 13188 | FX_UNPROTECT | |
| 204 | |||
| 205 | /* Directory found - Return the error code. */ | ||
| 206 | 24089 | return(FX_ALREADY_CREATED); | |
| 207 | } | ||
| 208 | |||
| 209 | /* Determine if there is anything left after the name. */ | ||
| 210 |
4/4✓ Branch 25 → 26 taken 4 times.
✓ Branch 25 → 27 taken 80815 times.
✓ Branch 29 → 30 taken 5 times.
✓ Branch 29 → 32 taken 101041 times.
|
181865 | if (_fx_directory_name_extract(work_ptr, &dir_entry.fx_dir_entry_name[0])) |
| 211 | { | ||
| 212 | |||
| 213 | /* Release media protection. */ | ||
| 214 | 5 | FX_UNPROTECT | |
| 215 | |||
| 216 | /* Extra information after the file name, return an invalid name | ||
| 217 | error. */ | ||
| 218 | 9 | return(FX_INVALID_PATH); | |
| 219 | } | ||
| 220 | |||
| 221 | |||
| 222 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 223 | /* Start transaction. */ | ||
| 224 | 82800 | _fx_fault_tolerant_transaction_start(media_ptr); | |
| 225 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 226 | |||
| 227 | /* Find a free slot for the new directory. */ | ||
| 228 | 181856 | status = _fx_directory_free_search(media_ptr, &search_directory, &dir_entry); | |
| 229 | |||
| 230 | /* Determine if the search was successful. */ | ||
| 231 |
8/8✓ Branch 28 → 29 taken 169 times.
✓ Branch 28 → 30 taken 39340 times.
✓ Branch 29 → 30 taken 170 times.
✓ Branch 29 → 32 taken 41136 times.
✓ Branch 33 → 34 taken 257 times.
✓ Branch 33 → 36 taken 59290 times.
✓ Branch 34 → 35 taken 172 times.
✓ Branch 34 → 38 taken 41322 times.
|
181856 | if (status != FX_SUCCESS) |
| 232 | { | ||
| 233 | |||
| 234 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 235 | 342 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 236 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 237 | |||
| 238 | /* Release media protection. */ | ||
| 239 | 429 | FX_UNPROTECT | |
| 240 | |||
| 241 | /* Return the error code. */ | ||
| 242 | 768 | return(status); | |
| 243 | } | ||
| 244 | |||
| 245 | /* Now allocate a cluster for our new sub-directory entry. */ | ||
| 246 | |||
| 247 | 181088 | FAT_index = media_ptr -> fx_media_cluster_search_start; | |
| 248 | 181088 | total_clusters = media_ptr -> fx_media_total_clusters; | |
| 249 | |||
| 250 | /* Loop to find the first available cluster. */ | ||
| 251 | do | ||
| 252 | { | ||
| 253 | |||
| 254 | /* Make sure we don't go past the FAT table. */ | ||
| 255 |
8/8✓ Branch 31 → 32 taken 2 times.
✓ Branch 31 → 33 taken 39342 times.
✓ Branch 33 → 34 taken 2 times.
✓ Branch 33 → 36 taken 41375 times.
✓ Branch 37 → 38 taken 3 times.
✓ Branch 37 → 40 taken 59293 times.
✓ Branch 39 → 40 taken 2 times.
✓ Branch 39 → 43 taken 41561 times.
|
181580 | if (!total_clusters) |
| 256 | { | ||
| 257 | |||
| 258 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 259 | 4 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 260 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 261 | |||
| 262 | /* Release media protection. */ | ||
| 263 | 5 | FX_UNPROTECT | |
| 264 | |||
| 265 | /* Something is wrong with the media - the desired clusters were | ||
| 266 | not found in the FAT table. */ | ||
| 267 | 9 | return(FX_NO_MORE_SPACE); | |
| 268 | } | ||
| 269 | |||
| 270 | /* Read FAT entry. */ | ||
| 271 | 181571 | status = _fx_utility_FAT_entry_read(media_ptr, FAT_index, &FAT_value); | |
| 272 | |||
| 273 | /* Check for a bad status. */ | ||
| 274 |
8/8✓ Branch 34 → 35 taken 2 times.
✓ Branch 34 → 36 taken 39340 times.
✓ Branch 37 → 38 taken 3 times.
✓ Branch 37 → 40 taken 41372 times.
✓ Branch 41 → 42 taken 3 times.
✓ Branch 41 → 44 taken 59290 times.
✓ Branch 44 → 45 taken 3 times.
✓ Branch 44 → 48 taken 41558 times.
|
181571 | if (status != FX_SUCCESS) |
| 275 | { | ||
| 276 | |||
| 277 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 278 | 6 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 279 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 280 | |||
| 281 | /* Release media protection. */ | ||
| 282 | 6 | FX_UNPROTECT | |
| 283 | |||
| 284 | /* Return the bad status. */ | ||
| 285 | 11 | return(status); | |
| 286 | } | ||
| 287 | |||
| 288 | /* Decrement the total cluster count. */ | ||
| 289 | 181560 | total_clusters--; | |
| 290 | |||
| 291 | /* Determine if the FAT entry is free. */ | ||
| 292 |
8/8✓ Branch 36 → 37 taken 39336 times.
✓ Branch 36 → 40 taken 4 times.
✓ Branch 40 → 41 taken 41131 times.
✓ Branch 40 → 44 taken 241 times.
✓ Branch 44 → 45 taken 59284 times.
✓ Branch 44 → 48 taken 6 times.
✓ Branch 48 → 49 taken 41317 times.
✓ Branch 48 → 52 taken 241 times.
|
181560 | if (FAT_value == FX_FREE_CLUSTER) |
| 293 | { | ||
| 294 | |||
| 295 | /* Move cluster search pointer forward. */ | ||
| 296 | 181068 | media_ptr -> fx_media_cluster_search_start = FAT_index + 1; | |
| 297 | |||
| 298 | /* Determine if this needs to be wrapped. */ | ||
| 299 |
8/8✓ Branch 37 → 38 taken 2 times.
✓ Branch 37 → 39 taken 39334 times.
✓ Branch 41 → 42 taken 2 times.
✓ Branch 41 → 43 taken 41129 times.
✓ Branch 45 → 46 taken 3 times.
✓ Branch 45 → 47 taken 59281 times.
✓ Branch 49 → 50 taken 2 times.
✓ Branch 49 → 51 taken 41315 times.
|
181068 | if (media_ptr -> fx_media_cluster_search_start >= (media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START)) |
| 300 | { | ||
| 301 | |||
| 302 | /* Wrap the search to the beginning FAT entry. */ | ||
| 303 | 9 | media_ptr -> fx_media_cluster_search_start = FX_FAT_ENTRY_START; | |
| 304 | } | ||
| 305 | |||
| 306 | /* Break this loop. */ | ||
| 307 | 181068 | break; | |
| 308 | } | ||
| 309 | else | ||
| 310 | { | ||
| 311 | |||
| 312 | /* FAT entry is not free... Advance the FAT index. */ | ||
| 313 | 492 | FAT_index++; | |
| 314 | |||
| 315 | /* Determine if we need to wrap the FAT index around. */ | ||
| 316 |
8/8✓ Branch 40 → 41 taken 2 times.
✓ Branch 40 → 42 taken 2 times.
✓ Branch 44 → 45 taken 2 times.
✓ Branch 44 → 46 taken 239 times.
✓ Branch 48 → 49 taken 3 times.
✓ Branch 48 → 50 taken 3 times.
✓ Branch 52 → 53 taken 2 times.
✓ Branch 52 → 54 taken 239 times.
|
492 | if (FAT_index >= (media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START)) |
| 317 | { | ||
| 318 | |||
| 319 | /* Wrap the search to the beginning FAT entry. */ | ||
| 320 | 9 | FAT_index = FX_FAT_ENTRY_START; | |
| 321 | } | ||
| 322 | } | ||
| 323 | } while (FX_TRUE); | ||
| 324 | |||
| 325 | /* Decrease the number of available clusters for the media. */ | ||
| 326 | 181068 | media_ptr -> fx_media_available_clusters--; | |
| 327 | |||
| 328 | /* Defer the writing of the FAT entry until the directory's first sector | ||
| 329 | has been properly written. If a power loss occurs prior to writing | ||
| 330 | the FAT entry, it will not result in a lost cluster. */ | ||
| 331 | |||
| 332 | /* Populate the directory entry. */ | ||
| 333 | |||
| 334 | /* Isolate the file name. */ | ||
| 335 | 181068 | _fx_directory_name_extract(work_ptr, &dir_entry.fx_dir_entry_name[0]); | |
| 336 | |||
| 337 | /* Lockout interrupts for time/date access. */ | ||
| 338 | 100601 | FX_DISABLE_INTS | |
| 339 | |||
| 340 | /* Set time and date stamps. */ | ||
| 341 | 181068 | dir_entry.fx_dir_entry_time = _fx_system_time; | |
| 342 | 181068 | dir_entry.fx_dir_entry_date = _fx_system_date; | |
| 343 | |||
| 344 | /* Restore interrupts. */ | ||
| 345 | 100601 | FX_RESTORE_INTS | |
| 346 | |||
| 347 | /* Set the attributes for the file. */ | ||
| 348 | 181068 | dir_entry.fx_dir_entry_attributes = FX_DIRECTORY; | |
| 349 | |||
| 350 | |||
| 351 | /* Set file size to 0. */ | ||
| 352 | 181068 | dir_entry.fx_dir_entry_file_size = 0; | |
| 353 | |||
| 354 | |||
| 355 | /* Set the cluster to EOF. */ | ||
| 356 | 181068 | dir_entry.fx_dir_entry_cluster = FAT_index; | |
| 357 | |||
| 358 | /* Is there a leading dot? */ | ||
| 359 |
8/8✓ Branch 44 → 45 taken 4 times.
✓ Branch 44 → 46 taken 39332 times.
✓ Branch 48 → 49 taken 4 times.
✓ Branch 48 → 50 taken 41127 times.
✓ Branch 54 → 55 taken 6 times.
✓ Branch 54 → 56 taken 59278 times.
✓ Branch 58 → 59 taken 4 times.
✓ Branch 58 → 60 taken 41313 times.
|
181068 | if (dir_entry.fx_dir_entry_name[0] == '.') |
| 360 | { | ||
| 361 | |||
| 362 | /* Yes, toggle the hidden attribute bit. */ | ||
| 363 | 18 | dir_entry.fx_dir_entry_attributes |= FX_HIDDEN; | |
| 364 | } | ||
| 365 | |||
| 366 | /* In previous versions, the new directory was written here. It | ||
| 367 | is now at the bottom of the file - after the FAT and the initial | ||
| 368 | sub-directory is written out. This makes the directory create | ||
| 369 | more fault tolerant. */ | ||
| 370 | |||
| 371 | /* Calculate the first sector of the sub-directory file. */ | ||
| 372 | 181068 | logical_sector = ((ULONG) media_ptr -> fx_media_data_sector_start) + | |
| 373 | 181068 | (((ULONG64) FAT_index - FX_FAT_ENTRY_START) * | |
| 374 | 181068 | ((ULONG) media_ptr -> fx_media_sectors_per_cluster)); | |
| 375 | |||
| 376 | /* Pickup the number of sectors for the initial sub-directory cluster. */ | ||
| 377 | 181068 | sectors = media_ptr -> fx_media_sectors_per_cluster; | |
| 378 | |||
| 379 | /* Read the first logical sector associated with the allocated | ||
| 380 | cluster. */ | ||
| 381 | 181068 | status = _fx_utility_logical_sector_read(media_ptr, logical_sector, | |
| 382 | 181068 | media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR); | |
| 383 | |||
| 384 | /* Determine if an error occurred. */ | ||
| 385 |
8/8✓ Branch 47 → 48 taken 2 times.
✓ Branch 47 → 49 taken 39334 times.
✓ Branch 51 → 52 taken 2 times.
✓ Branch 51 → 54 taken 41129 times.
✓ Branch 57 → 58 taken 3 times.
✓ Branch 57 → 60 taken 59281 times.
✓ Branch 61 → 62 taken 2 times.
✓ Branch 61 → 65 taken 41315 times.
|
181068 | if (status != FX_SUCCESS) |
| 386 | { | ||
| 387 | |||
| 388 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 389 | 4 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 390 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 391 | |||
| 392 | /* Release media protection. */ | ||
| 393 | 5 | FX_UNPROTECT | |
| 394 | |||
| 395 | /* Return error code. */ | ||
| 396 | 9 | return(status); | |
| 397 | } | ||
| 398 | |||
| 399 | /* Clear the entire first sector of the new sub-directory cluster. */ | ||
| 400 | 181059 | work_ptr = (CHAR *)media_ptr -> fx_media_memory_buffer; | |
| 401 | 181059 | i = 0; | |
| 402 |
8/8✓ Branch 51 → 50 taken 1266752 times.
✓ Branch 51 → 52 taken 39334 times.
✓ Branch 56 → 55 taken 1409920 times.
✓ Branch 56 → 57 taken 41129 times.
✓ Branch 62 → 61 taken 1909088 times.
✓ Branch 62 → 63 taken 59281 times.
✓ Branch 67 → 66 taken 1415872 times.
✓ Branch 67 → 68 taken 41315 times.
|
6182691 | while (i < media_ptr -> fx_media_bytes_per_sector) |
| 403 | { | ||
| 404 | |||
| 405 | /* Clear 4 bytes. */ | ||
| 406 | 6001632 | *((ULONG *)work_ptr) = (ULONG)0; | |
| 407 | |||
| 408 | /* Increment pointer. */ | ||
| 409 | 6001632 | work_ptr = work_ptr + sizeof(ULONG); | |
| 410 | |||
| 411 | /* Increment counter. */ | ||
| 412 | 6001632 | i = i + (ULONG)sizeof(ULONG); | |
| 413 | } | ||
| 414 | |||
| 415 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 416 |
4/4✓ Branch 57 → 58 taken 1937 times.
✓ Branch 57 → 66 taken 39192 times.
✓ Branch 68 → 69 taken 1937 times.
✓ Branch 68 → 79 taken 39378 times.
|
82444 | if (media_ptr -> fx_media_fault_tolerant_enabled == FX_TRUE) |
| 417 | { | ||
| 418 | |||
| 419 | /* Write back. */ | ||
| 420 | 3874 | status = _fx_utility_logical_sector_write(media_ptr, logical_sector, | |
| 421 | 3874 | media_ptr -> fx_media_memory_buffer, (ULONG)1, FX_DIRECTORY_SECTOR); | |
| 422 | |||
| 423 | /* Determine if an error occurred. */ | ||
| 424 |
4/4✓ Branch 59 → 60 taken 2 times.
✓ Branch 59 → 62 taken 1935 times.
✓ Branch 70 → 71 taken 2 times.
✓ Branch 70 → 74 taken 1935 times.
|
3874 | if (status != FX_SUCCESS) |
| 425 | { | ||
| 426 | 4 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 427 | |||
| 428 | /* Release media protection. */ | ||
| 429 | 2 | FX_UNPROTECT | |
| 430 | |||
| 431 | /* Return error code. */ | ||
| 432 | 4 | return(status); | |
| 433 | } | ||
| 434 | |||
| 435 | /* Force flush the internal logical sector cache. */ | ||
| 436 | 3870 | status = _fx_utility_logical_sector_flush(media_ptr, logical_sector, sectors, FX_TRUE); | |
| 437 | |||
| 438 | /* Determine if the write was successful. */ | ||
| 439 |
4/4✓ Branch 63 → 64 taken 1 time.
✓ Branch 63 → 66 taken 1934 times.
✓ Branch 75 → 76 taken 1 time.
✓ Branch 75 → 79 taken 1934 times.
|
3870 | if (status != FX_SUCCESS) |
| 440 | { | ||
| 441 | 2 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 442 | |||
| 443 | /* Release media protection. */ | ||
| 444 | 1 | FX_UNPROTECT | |
| 445 | |||
| 446 | /* Return the error code. */ | ||
| 447 | 2 | return(status); | |
| 448 | } | ||
| 449 | } | ||
| 450 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 451 | |||
| 452 | /* Determine if there are more sectors to clear in the first cluster of the new | ||
| 453 | sub-directory. */ | ||
| 454 |
8/8✓ Branch 52 → 53 taken 289 times.
✓ Branch 52 → 62 taken 39045 times.
✓ Branch 63 → 64 taken 437 times.
✓ Branch 63 → 75 taken 58844 times.
✓ Branch 66 → 67 taken 2225 times.
✓ Branch 66 → 79 taken 38901 times.
✓ Branch 79 → 80 taken 2227 times.
✓ Branch 79 → 94 taken 39085 times.
|
181053 | if (sectors > 1) |
| 455 | { | ||
| 456 | |||
| 457 | /* Yes, invalidate all cached sectors that are contained in the newly allocated first | ||
| 458 | cluster of the directory. */ | ||
| 459 | |||
| 460 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 461 |
4/4✓ Branch 67 → 68 taken 291 times.
✓ Branch 67 → 72 taken 1934 times.
✓ Branch 80 → 81 taken 293 times.
✓ Branch 80 → 86 taken 1934 times.
|
4452 | if (media_ptr -> fx_media_fault_tolerant_enabled == FX_FALSE) |
| 462 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 463 | { | ||
| 464 | |||
| 465 | /* Flush the internal logical sector cache. */ | ||
| 466 | 1310 | status = _fx_utility_logical_sector_flush(media_ptr, logical_sector + 1, ((ULONG64)(sectors - 1)), FX_TRUE); | |
| 467 | |||
| 468 | /* Determine if the write was successful. */ | ||
| 469 |
8/8✓ Branch 54 → 55 taken 1 time.
✓ Branch 54 → 56 taken 288 times.
✓ Branch 65 → 66 taken 2 times.
✓ Branch 65 → 68 taken 435 times.
✓ Branch 69 → 70 taken 1 time.
✓ Branch 69 → 72 taken 290 times.
✓ Branch 82 → 83 taken 1 time.
✓ Branch 82 → 86 taken 292 times.
|
1310 | if (status != FX_SUCCESS) |
| 470 | { | ||
| 471 | |||
| 472 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 473 | 2 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 474 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 475 | |||
| 476 | /* Release media protection. */ | ||
| 477 | 3 | FX_UNPROTECT | |
| 478 | |||
| 479 | /* Return the error code. */ | ||
| 480 | 5 | return(status); | |
| 481 | } | ||
| 482 | } | ||
| 483 | |||
| 484 | /* Clear all additional sectors of new sub-directory. */ | ||
| 485 | 5173 | sectors--; | |
| 486 |
8/8✓ Branch 61 → 57 taken 1800 times.
✓ Branch 61 → 62 taken 286 times.
✓ Branch 74 → 69 taken 2703 times.
✓ Branch 74 → 75 taken 432 times.
✓ Branch 78 → 73 taken 14860 times.
✓ Branch 78 → 79 taken 2222 times.
✓ Branch 93 → 87 taken 14862 times.
✓ Branch 93 → 94 taken 2224 times.
|
39389 | while (sectors) |
| 487 | { | ||
| 488 | |||
| 489 | #ifndef FX_MEDIA_STATISTICS_DISABLE | ||
| 490 | |||
| 491 | /* Increment the number of driver write sector(s) requests. */ | ||
| 492 | 34225 | media_ptr -> fx_media_driver_write_requests++; | |
| 493 | #endif | ||
| 494 | |||
| 495 | /* Build Write request to the driver. */ | ||
| 496 | 34225 | media_ptr -> fx_media_driver_request = FX_DRIVER_WRITE; | |
| 497 | 34225 | media_ptr -> fx_media_driver_status = FX_IO_ERROR; | |
| 498 | 34225 | media_ptr -> fx_media_driver_buffer = media_ptr -> fx_media_memory_buffer; | |
| 499 | #ifdef FX_DRIVER_USE_64BIT_LBA | ||
| 500 | media_ptr -> fx_media_driver_logical_sector = logical_sector + ((ULONG)sectors); | ||
| 501 | #else | ||
| 502 | 34225 | media_ptr -> fx_media_driver_logical_sector = (ULONG)logical_sector + ((ULONG)sectors); | |
| 503 | #endif | ||
| 504 | 34225 | media_ptr -> fx_media_driver_sectors = 1; | |
| 505 | 34225 | media_ptr -> fx_media_driver_sector_type = FX_DIRECTORY_SECTOR; | |
| 506 | |||
| 507 | /* Set the system write flag since we are writing a directory sector. */ | ||
| 508 | 34225 | media_ptr -> fx_media_driver_system_write = FX_TRUE; | |
| 509 | |||
| 510 | /* If trace is enabled, insert this event into the trace buffer. */ | ||
| 511 | FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_WRITE, media_ptr, ((ULONG)logical_sector) + ((ULONG)sectors), 1, media_ptr -> fx_media_memory_buffer, FX_TRACE_INTERNAL_EVENTS, 0, 0) | ||
| 512 | |||
| 513 | /* Invoke the driver to write the sector. */ | ||
| 514 | 34225 | (media_ptr -> fx_media_driver_entry) (media_ptr); | |
| 515 | |||
| 516 | /* Clear the system write flag. */ | ||
| 517 | 34225 | media_ptr -> fx_media_driver_system_write = FX_FALSE; | |
| 518 | |||
| 519 | /* Determine if an error occurred. */ | ||
| 520 |
8/8✓ Branch 58 → 59 taken 2 times.
✓ Branch 58 → 60 taken 1798 times.
✓ Branch 70 → 71 taken 3 times.
✓ Branch 70 → 73 taken 2700 times.
✓ Branch 74 → 75 taken 2 times.
✓ Branch 74 → 77 taken 14858 times.
✓ Branch 88 → 89 taken 2 times.
✓ Branch 88 → 92 taken 14860 times.
|
34225 | if (media_ptr -> fx_media_driver_status != FX_SUCCESS) |
| 521 | { | ||
| 522 | |||
| 523 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 524 | 4 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 525 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 526 | |||
| 527 | /* Release media protection. */ | ||
| 528 | 5 | FX_UNPROTECT | |
| 529 | |||
| 530 | /* Return error code. */ | ||
| 531 | 9 | return(media_ptr -> fx_media_driver_status); | |
| 532 | } | ||
| 533 | |||
| 534 | /* Decrease the number of sectors to clear. */ | ||
| 535 | 34216 | sectors--; | |
| 536 | } | ||
| 537 | } | ||
| 538 | |||
| 539 | |||
| 540 | /* Now setup the first sector with the initial sub-directory information. */ | ||
| 541 | |||
| 542 | /* Copy the base directory entry to the sub-directory entry. */ | ||
| 543 | 181039 | sub_dir_entry = dir_entry; | |
| 544 | |||
| 545 | /* Setup pointer to media name buffer. */ | ||
| 546 | 181039 | sub_dir_entry.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + (FX_MAX_LONG_NAME_LEN * 3); | |
| 547 | |||
| 548 | /* Set the directory entry name to all blanks. */ | ||
| 549 | 181039 | work_ptr = &sub_dir_entry.fx_dir_entry_name[0]; | |
| 550 |
8/8✓ Branch 64 → 63 taken 432641 times.
✓ Branch 64 → 65 taken 39331 times.
✓ Branch 77 → 76 taken 652036 times.
✓ Branch 77 → 78 taken 59276 times.
✓ Branch 81 → 80 taken 452353 times.
✓ Branch 81 → 82 taken 41123 times.
✓ Branch 96 → 95 taken 454399 times.
✓ Branch 96 → 97 taken 41309 times.
|
2172468 | for (i = 0; i < (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE); i++) |
| 551 | { | ||
| 552 | 1991429 | *work_ptr++ = ' '; | |
| 553 | } | ||
| 554 | |||
| 555 | 181039 | sub_dir_entry.fx_dir_entry_long_name_present = 0; | |
| 556 | |||
| 557 | /* Now build the "." directory entry. */ | ||
| 558 | 181039 | sub_dir_entry.fx_dir_entry_name[0] = '.'; | |
| 559 | 181039 | sub_dir_entry.fx_dir_entry_name[1] = 0; | |
| 560 | 181039 | sub_dir_entry.fx_dir_entry_log_sector = logical_sector; | |
| 561 | 181039 | sub_dir_entry.fx_dir_entry_byte_offset = 0; | |
| 562 | |||
| 563 | /* Write the directory's first entry. */ | ||
| 564 | 181039 | status = _fx_directory_entry_write(media_ptr, &sub_dir_entry); | |
| 565 | |||
| 566 | /* Check for error condition. */ | ||
| 567 |
8/8✓ Branch 66 → 67 taken 2 times.
✓ Branch 66 → 68 taken 39329 times.
✓ Branch 79 → 80 taken 3 times.
✓ Branch 79 → 82 taken 59273 times.
✓ Branch 83 → 84 taken 2 times.
✓ Branch 83 → 86 taken 41121 times.
✓ Branch 98 → 99 taken 2 times.
✓ Branch 98 → 102 taken 41307 times.
|
181039 | if (status != FX_SUCCESS) |
| 568 | { | ||
| 569 | |||
| 570 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 571 | 4 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 572 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 573 | |||
| 574 | /* Release media protection. */ | ||
| 575 | 5 | FX_UNPROTECT | |
| 576 | |||
| 577 | /* Return error status. */ | ||
| 578 | 9 | return(status); | |
| 579 | } | ||
| 580 | |||
| 581 | /* Now build the ".." directory entry. */ | ||
| 582 | |||
| 583 | /* Determine if the search directory is the root. */ | ||
| 584 |
8/8✓ Branch 68 → 69 taken 752 times.
✓ Branch 68 → 73 taken 38577 times.
✓ Branch 82 → 83 taken 1362 times.
✓ Branch 82 → 87 taken 57911 times.
✓ Branch 86 → 87 taken 2209 times.
✓ Branch 86 → 91 taken 38912 times.
✓ Branch 102 → 103 taken 2347 times.
✓ Branch 102 → 107 taken 38960 times.
|
181030 | if (search_directory.fx_dir_entry_name[0]) |
| 585 | { | ||
| 586 | |||
| 587 | /* Previous directory is not the root directory. */ | ||
| 588 | |||
| 589 | /* Copy into the working directory entry. */ | ||
| 590 | 6670 | sub_dir_entry = search_directory; | |
| 591 | |||
| 592 | /* Copy the date and time from the actual sub-directory. */ | ||
| 593 | 6670 | sub_dir_entry.fx_dir_entry_time = dir_entry.fx_dir_entry_time; | |
| 594 | 6670 | sub_dir_entry.fx_dir_entry_date = dir_entry.fx_dir_entry_date; | |
| 595 | |||
| 596 | /* Adjust pointer to media name buffer. */ | ||
| 597 | 6670 | sub_dir_entry.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + (FX_MAX_LONG_NAME_LEN * 3); | |
| 598 | |||
| 599 | /* Change the name to ".." */ | ||
| 600 | 6670 | work_ptr = &sub_dir_entry.fx_dir_entry_name[0]; | |
| 601 |
8/8✓ Branch 71 → 70 taken 8272 times.
✓ Branch 71 → 72 taken 752 times.
✓ Branch 85 → 84 taken 14982 times.
✓ Branch 85 → 86 taken 1362 times.
✓ Branch 89 → 88 taken 24299 times.
✓ Branch 89 → 90 taken 2209 times.
✓ Branch 105 → 104 taken 25817 times.
✓ Branch 105 → 106 taken 2347 times.
|
80040 | for (i = 0; i < (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE); i++) |
| 602 | { | ||
| 603 | 73370 | *work_ptr++ = ' '; | |
| 604 | } | ||
| 605 | |||
| 606 | 6670 | sub_dir_entry.fx_dir_entry_name[0] = '.'; | |
| 607 | 6670 | sub_dir_entry.fx_dir_entry_name[1] = '.'; | |
| 608 | 6670 | sub_dir_entry.fx_dir_entry_name[2] = 0; | |
| 609 | |||
| 610 | 6670 | sub_dir_entry.fx_dir_entry_long_name_present = 0; | |
| 611 | |||
| 612 | /* Set file size to 0. */ | ||
| 613 | 6670 | sub_dir_entry.fx_dir_entry_file_size = 0; | |
| 614 | |||
| 615 | /* Change the logical sector for this entry. */ | ||
| 616 | 6670 | sub_dir_entry.fx_dir_entry_log_sector = logical_sector; | |
| 617 | } | ||
| 618 | else | ||
| 619 | { | ||
| 620 | |||
| 621 | /* Just modify the current directory since the parent | ||
| 622 | directory is the root. */ | ||
| 623 | 174360 | sub_dir_entry.fx_dir_entry_name[1] = '.'; | |
| 624 | 174360 | sub_dir_entry.fx_dir_entry_name[2] = 0; | |
| 625 | |||
| 626 | /* Clear the cluster to indicate the root directory. */ | ||
| 627 | 174360 | sub_dir_entry.fx_dir_entry_cluster = 0; | |
| 628 | } | ||
| 629 | |||
| 630 | /* Setup the byte offset. */ | ||
| 631 | 181030 | sub_dir_entry.fx_dir_entry_byte_offset = FX_DIR_ENTRY_SIZE; | |
| 632 | |||
| 633 | /* Write the directory's second entry. */ | ||
| 634 | 181030 | status = _fx_directory_entry_write(media_ptr, &sub_dir_entry); | |
| 635 | |||
| 636 | /* Check for error condition. */ | ||
| 637 |
8/8✓ Branch 75 → 76 taken 3 times.
✓ Branch 75 → 77 taken 39326 times.
✓ Branch 89 → 90 taken 4 times.
✓ Branch 89 → 92 taken 59269 times.
✓ Branch 93 → 94 taken 3 times.
✓ Branch 93 → 96 taken 41118 times.
✓ Branch 109 → 110 taken 3 times.
✓ Branch 109 → 113 taken 41304 times.
|
181030 | if (status != FX_SUCCESS) |
| 638 | { | ||
| 639 | |||
| 640 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 641 | 6 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 642 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 643 | |||
| 644 | /* Release media protection. */ | ||
| 645 | 7 | FX_UNPROTECT | |
| 646 | |||
| 647 | /* Return error status. */ | ||
| 648 | 13 | return(status); | |
| 649 | } | ||
| 650 | |||
| 651 | /* Write an EOF in the found FAT entry. */ | ||
| 652 | 181017 | status = _fx_utility_FAT_entry_write(media_ptr, FAT_index, media_ptr -> fx_media_fat_last); | |
| 653 | |||
| 654 | /* Check for a bad status. */ | ||
| 655 |
8/8✓ Branch 78 → 79 taken 2 times.
✓ Branch 78 → 80 taken 39324 times.
✓ Branch 93 → 94 taken 3 times.
✓ Branch 93 → 96 taken 59266 times.
✓ Branch 97 → 98 taken 2 times.
✓ Branch 97 → 100 taken 41116 times.
✓ Branch 114 → 115 taken 2 times.
✓ Branch 114 → 118 taken 41302 times.
|
181017 | if (status != FX_SUCCESS) |
| 656 | { | ||
| 657 | |||
| 658 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 659 | 4 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 660 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 661 | |||
| 662 | /* Release media protection. */ | ||
| 663 | 5 | FX_UNPROTECT | |
| 664 | |||
| 665 | /* Return the bad status. */ | ||
| 666 | 9 | return(status); | |
| 667 | } | ||
| 668 | |||
| 669 | |||
| 670 | #ifdef FX_FAULT_TOLERANT | ||
| 671 | |||
| 672 | /* Flush the cached individual FAT entries */ | ||
| 673 | 82418 | _fx_utility_FAT_flush(media_ptr); | |
| 674 | #endif | ||
| 675 | |||
| 676 | /* Now write out the new directory entry. */ | ||
| 677 | |||
| 678 | 181008 | status = _fx_directory_entry_write(media_ptr, &dir_entry); | |
| 679 | |||
| 680 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 681 | /* Check for a bad status. */ | ||
| 682 |
4/4✓ Branch 102 → 103 taken 2 times.
✓ Branch 102 → 105 taken 41114 times.
✓ Branch 120 → 121 taken 2 times.
✓ Branch 120 → 124 taken 41300 times.
|
82418 | if (status != FX_SUCCESS) |
| 683 | { | ||
| 684 | 4 | FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr); | |
| 685 | |||
| 686 | /* Release media protection. */ | ||
| 687 | 2 | FX_UNPROTECT | |
| 688 | |||
| 689 | /* Return the bad status. */ | ||
| 690 | 4 | return(status); | |
| 691 | } | ||
| 692 | |||
| 693 | /* End transaction. */ | ||
| 694 | 82414 | status = _fx_fault_tolerant_transaction_end(media_ptr); | |
| 695 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 696 | |||
| 697 | /* Release media protection. */ | ||
| 698 | 100536 | FX_UNPROTECT | |
| 699 | |||
| 700 | /* Directory create is complete, return status. */ | ||
| 701 | 180950 | return(status); | |
| 702 | } | ||
| 703 | |||
| 704 |