fx_unicode_directory_entry_change.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 | /** Unicode */ | ||
| 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_unicode.h" | ||
| 30 | #include "fx_utility.h" | ||
| 31 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 32 | #include "fx_fault_tolerant.h" | ||
| 33 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 34 | |||
| 35 | |||
| 36 | /**************************************************************************/ | ||
| 37 | /* */ | ||
| 38 | /* FUNCTION RELEASE */ | ||
| 39 | /* */ | ||
| 40 | /* _fx_unicode_directory_entry_change PORTABLE C */ | ||
| 41 | /* 6.1 */ | ||
| 42 | /* AUTHOR */ | ||
| 43 | /* */ | ||
| 44 | /* William E. Lamie, Microsoft Corporation */ | ||
| 45 | /* */ | ||
| 46 | /* DESCRIPTION */ | ||
| 47 | /* */ | ||
| 48 | /* This function changes the unicode name of a directory entry. */ | ||
| 49 | /* */ | ||
| 50 | /* INPUT */ | ||
| 51 | /* */ | ||
| 52 | /* media_ptr Pointer to media */ | ||
| 53 | /* entry_ptr Directory entry */ | ||
| 54 | /* unicode_name Destination unicode name */ | ||
| 55 | /* unicode_name_length Unicode name size */ | ||
| 56 | /* */ | ||
| 57 | /* OUTPUT */ | ||
| 58 | /* */ | ||
| 59 | /* Completion Status */ | ||
| 60 | /* */ | ||
| 61 | /* CALLS */ | ||
| 62 | /* */ | ||
| 63 | /* _fx_utility_FAT_entry_read Read a FAT entry */ | ||
| 64 | /* _fx_utility_logical_sector_read Read a logical sector */ | ||
| 65 | /* _fx_utility_logical_sector_write Write a logical sector */ | ||
| 66 | /* _fx_fault_tolerant_add_dir_log Add directory redo log */ | ||
| 67 | /* */ | ||
| 68 | /* CALLED BY */ | ||
| 69 | /* */ | ||
| 70 | /* Unicode Utilities */ | ||
| 71 | /* */ | ||
| 72 | /**************************************************************************/ | ||
| 73 | 4692 | UINT _fx_unicode_directory_entry_change(FX_MEDIA *media_ptr, FX_DIR_ENTRY *entry_ptr, UCHAR *unicode_name, ULONG unicode_name_length) | |
| 74 | { | ||
| 75 | |||
| 76 | UCHAR *work_ptr, *sector_base_ptr; | ||
| 77 | UINT status; | ||
| 78 | UINT i, j, k, u, card, lfn_entries; | ||
| 79 | UCHAR eof_marker; | ||
| 80 | ULONG logical_sector, relative_sector; | ||
| 81 | ULONG byte_offset; | ||
| 82 | ULONG cluster, next_cluster; | ||
| 83 | |||
| 84 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 85 | UCHAR *changed_ptr; | ||
| 86 | UINT changed_size; | ||
| 87 | ULONG changed_offset; | ||
| 88 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 89 | |||
| 90 | |||
| 91 | #ifndef FX_MEDIA_STATISTICS_DISABLE | ||
| 92 | |||
| 93 | /* Increment the number of directory entry write requests. */ | ||
| 94 | 4692 | media_ptr -> fx_media_directory_entry_writes++; | |
| 95 | #endif | ||
| 96 | |||
| 97 | /* Pickup the byte offset of the entry. */ | ||
| 98 | 4692 | byte_offset = entry_ptr -> fx_dir_entry_byte_offset; | |
| 99 | |||
| 100 | /* Pickup the logical sector of the entry. */ | ||
| 101 | 4692 | logical_sector = (ULONG)entry_ptr -> fx_dir_entry_log_sector; | |
| 102 | |||
| 103 | /* Figure out where what cluster we are in. */ | ||
| 104 |
2/2✓ Branch 2 → 3 taken 3398 times.
✓ Branch 2 → 4 taken 1294 times.
|
4692 | if (logical_sector >= (ULONG)(media_ptr -> fx_media_data_sector_start)) |
| 105 | { | ||
| 106 | |||
| 107 | /* Calculate the cluster that this logical sector is in. */ | ||
| 108 | 3398 | cluster = (logical_sector - media_ptr -> fx_media_data_sector_start) / (media_ptr -> fx_media_sectors_per_cluster) + FX_FAT_ENTRY_START; | |
| 109 | |||
| 110 | /* Calculate the relative cluster. */ | ||
| 111 | 3398 | relative_sector = logical_sector - (((ULONG)media_ptr -> fx_media_data_sector_start) + | |
| 112 | 3398 | (((ULONG)cluster - FX_FAT_ENTRY_START) * | |
| 113 | 3398 | ((ULONG)media_ptr -> fx_media_sectors_per_cluster))); | |
| 114 | } | ||
| 115 | else | ||
| 116 | { | ||
| 117 | |||
| 118 | /* Clear the cluster and the relative sector. */ | ||
| 119 | 1294 | cluster = 0; | |
| 120 | 1294 | relative_sector = 0; | |
| 121 | } | ||
| 122 | |||
| 123 | /* Read the logical directory sector. */ | ||
| 124 | 4692 | status = _fx_utility_logical_sector_read(media_ptr, (ULONG64) entry_ptr -> fx_dir_entry_log_sector, | |
| 125 | 4692 | media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR); | |
| 126 | |||
| 127 | /* Determine if an error occurred. */ | ||
| 128 |
2/2✓ Branch 6 → 7 taken 34 times.
✓ Branch 6 → 8 taken 4658 times.
|
4692 | if (status != FX_SUCCESS) |
| 129 | { | ||
| 130 | |||
| 131 | /* Return the error status. */ | ||
| 132 | 34 | return(status); | |
| 133 | } | ||
| 134 | |||
| 135 | /* Setup a pointer into the buffer. */ | ||
| 136 | 4658 | sector_base_ptr = (UCHAR *)media_ptr -> fx_media_memory_buffer; | |
| 137 | 4658 | work_ptr = sector_base_ptr + (UINT)entry_ptr -> fx_dir_entry_byte_offset; | |
| 138 | |||
| 139 | /* Initialize the unicode index. */ | ||
| 140 | 4658 | u = 0; | |
| 141 | |||
| 142 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 143 | /* Initialize data for fault tolerant. */ | ||
| 144 | 2836 | changed_ptr = work_ptr; | |
| 145 | 2836 | changed_size = 0; | |
| 146 | 2836 | changed_offset = entry_ptr -> fx_dir_entry_byte_offset; | |
| 147 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 148 | |||
| 149 | /* Check for a valid long name. */ | ||
| 150 |
3/3✓ Branch 8 → 9 taken 4649 times.
✓ Branch 8 → 45 taken 5 times.
✓ Branch 8 → 49 taken 4 times.
|
4658 | if ((0x40 & (*work_ptr))) |
| 151 | { | ||
| 152 | |||
| 153 | /* Get the lower 5 bit containing the cardinality. */ | ||
| 154 | 4649 | card = (*work_ptr & (UCHAR)0x1f); | |
| 155 | 4649 | lfn_entries = card; | |
| 156 | |||
| 157 | /* Loop through the file name. */ | ||
| 158 |
4/4✓ Branch 44 → 10 taken 2405 times.
✓ Branch 44 → 45 taken 1792 times.
✓ Branch 48 → 10 taken 3634 times.
✓ Branch 48 → 49 taken 2810 times.
|
10641 | for (j = 0; j < lfn_entries; j++) |
| 159 | { | ||
| 160 | |||
| 161 | /* Clear the eof marker. */ | ||
| 162 | 6039 | eof_marker = 0; | |
| 163 | |||
| 164 | /* Loop through file name fields. */ | ||
| 165 |
2/2✓ Branch 24 → 11 taken 96624 times.
✓ Branch 24 → 25 taken 6039 times.
|
102663 | for (i = 1, k = (26 * (card - 1)) & 0xFFFFFFFF; i < FX_DIR_ENTRY_SIZE; i += 2) |
| 166 | { | ||
| 167 | |||
| 168 | /* Process relative to specific fields. */ | ||
| 169 |
4/4✓ Branch 11 → 12 taken 90585 times.
✓ Branch 11 → 13 taken 6039 times.
✓ Branch 12 → 13 taken 6039 times.
✓ Branch 12 → 14 taken 84546 times.
|
96624 | if ((i == 11) || (i == 26)) |
| 170 | { | ||
| 171 | 12078 | continue; | |
| 172 | } | ||
| 173 | |||
| 174 |
2/2✓ Branch 14 → 15 taken 6039 times.
✓ Branch 14 → 16 taken 78507 times.
|
84546 | if (i == 13) |
| 175 | { | ||
| 176 | 6039 | i = 12; | |
| 177 | 6039 | continue; | |
| 178 | } | ||
| 179 | |||
| 180 | /* Determine if the EOF marker is present. */ | ||
| 181 |
2/2✓ Branch 16 → 17 taken 42552 times.
✓ Branch 16 → 18 taken 35955 times.
|
78507 | if (eof_marker) |
| 182 | { | ||
| 183 | |||
| 184 | 42552 | work_ptr[i] = eof_marker; | |
| 185 | 42552 | work_ptr[i + 1] = eof_marker; | |
| 186 | } | ||
| 187 |
2/2✓ Branch 18 → 19 taken 30172 times.
✓ Branch 18 → 20 taken 5783 times.
|
35955 | else if (k < (unicode_name_length * 2)) |
| 188 | { | ||
| 189 | |||
| 190 | 30172 | work_ptr[i] = unicode_name[k]; | |
| 191 | 30172 | work_ptr[i + 1] = unicode_name[k + 1]; | |
| 192 | 30172 | u = u + 2; | |
| 193 | } | ||
| 194 |
2/2✓ Branch 20 → 21 taken 4613 times.
✓ Branch 20 → 22 taken 1170 times.
|
5783 | else if (k == (unicode_name_length * 2)) |
| 195 | { | ||
| 196 | |||
| 197 | 4613 | work_ptr[i] = 0; | |
| 198 | 4613 | work_ptr[i + 1] = 0; | |
| 199 | |||
| 200 | /* end of name, pad with 0xff. */ | ||
| 201 | 4613 | eof_marker = (UCHAR)0xff; | |
| 202 | } | ||
| 203 | |||
| 204 | 78507 | k = k + 2; | |
| 205 | } | ||
| 206 | |||
| 207 | /* Decrement the card. */ | ||
| 208 | 6039 | card--; | |
| 209 | |||
| 210 | /* Setup pointers for the name write. */ | ||
| 211 | 6039 | work_ptr += FX_DIR_ENTRY_SIZE; | |
| 212 | 6039 | byte_offset += FX_DIR_ENTRY_SIZE; | |
| 213 | |||
| 214 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 215 | /* Update changed_size. */ | ||
| 216 | 3634 | changed_size += FX_DIR_ENTRY_SIZE; | |
| 217 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 218 | |||
| 219 | /* Determine if the write is within the current sector. */ | ||
| 220 |
3/3✓ Branch 25 → 26 taken 795 times.
✓ Branch 25 → 43 taken 1988 times.
✓ Branch 25 → 47 taken 3256 times.
|
6039 | if (byte_offset >= media_ptr -> fx_media_bytes_per_sector) |
| 221 | { | ||
| 222 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 223 |
2/2✓ Branch 26 → 27 taken 46 times.
✓ Branch 26 → 28 taken 332 times.
|
378 | if (media_ptr -> fx_media_fault_tolerant_enabled) |
| 224 | { | ||
| 225 | |||
| 226 | /* Redirect this request to log file. */ | ||
| 227 | 46 | status = _fx_fault_tolerant_add_dir_log(media_ptr, (ULONG64) logical_sector, changed_offset, changed_ptr, changed_size); | |
| 228 | } | ||
| 229 | else | ||
| 230 | { | ||
| 231 | |||
| 232 | /* Write the current sector out. */ | ||
| 233 | 332 | status = _fx_utility_logical_sector_write(media_ptr, (ULONG64) logical_sector, | |
| 234 | sector_base_ptr, ((ULONG) 1), FX_DIRECTORY_SECTOR); | ||
| 235 | } | ||
| 236 | |||
| 237 | |||
| 238 | /* Determine if an error occurred. */ | ||
| 239 |
2/2✓ Branch 29 → 30 taken 4 times.
✓ Branch 29 → 31 taken 374 times.
|
378 | if (status != FX_SUCCESS) |
| 240 | { | ||
| 241 | |||
| 242 | /* Return the error status. */ | ||
| 243 | 4 | return(status); | |
| 244 | } | ||
| 245 | #else /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 246 | |||
| 247 | /* Write the current sector out. */ | ||
| 248 | /* Note: Since the sector is in the cache after a sector read, therefore _fx_utility_logical_sector_write | ||
| 249 | always returns success when FX_ENABLE_FAULT_TOLERANT is not defined. In other words, the checking | ||
| 250 | on the return value is needed only when FX_ENABLE_FAULT_TOLERANT is defined. */ | ||
| 251 | 417 | _fx_utility_logical_sector_write(media_ptr, (ULONG64) logical_sector, | |
| 252 | sector_base_ptr, ((ULONG) 1), FX_DIRECTORY_SECTOR); | ||
| 253 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 254 | |||
| 255 | /* Determine if we are in the root directory. */ | ||
| 256 |
4/4✓ Branch 27 → 28 taken 339 times.
✓ Branch 27 → 37 taken 78 times.
✓ Branch 31 → 32 taken 308 times.
✓ Branch 31 → 41 taken 66 times.
|
791 | if (logical_sector >= (ULONG)(media_ptr -> fx_media_data_sector_start)) |
| 257 | { | ||
| 258 | |||
| 259 | /* Determine the next sector of the directory entry. */ | ||
| 260 |
4/4✓ Branch 28 → 29 taken 73 times.
✓ Branch 28 → 30 taken 266 times.
✓ Branch 32 → 33 taken 96 times.
✓ Branch 32 → 34 taken 212 times.
|
647 | if (relative_sector < (media_ptr -> fx_media_sectors_per_cluster - 1)) |
| 261 | { | ||
| 262 | |||
| 263 | /* More sectors in this cluster. */ | ||
| 264 | |||
| 265 | /* Simply increment the logical sector. */ | ||
| 266 | 169 | logical_sector++; | |
| 267 | |||
| 268 | /* Increment the relative sector. */ | ||
| 269 | 169 | relative_sector++; | |
| 270 | } | ||
| 271 | else | ||
| 272 | { | ||
| 273 | |||
| 274 | /* We need to move to the next cluster. */ | ||
| 275 | |||
| 276 | /* Pickup the next cluster. */ | ||
| 277 | 478 | status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster); | |
| 278 | |||
| 279 | /* Check for I/O error. */ | ||
| 280 |
4/4✓ Branch 31 → 32 taken 5 times.
✓ Branch 31 → 33 taken 261 times.
✓ Branch 35 → 36 taken 4 times.
✓ Branch 35 → 37 taken 208 times.
|
478 | if (status != FX_SUCCESS) |
| 281 | { | ||
| 282 | |||
| 283 | /* Return error code. */ | ||
| 284 | 9 | return(status); | |
| 285 | } | ||
| 286 | |||
| 287 | /* Copy next cluster to the current cluster. */ | ||
| 288 | 469 | cluster = next_cluster; | |
| 289 | |||
| 290 | /* Check the value of the new cluster - it must be a valid cluster number | ||
| 291 | or something is really wrong! */ | ||
| 292 |
8/8✓ Branch 33 → 34 taken 256 times.
✓ Branch 33 → 35 taken 5 times.
✓ Branch 34 → 35 taken 5 times.
✓ Branch 34 → 36 taken 251 times.
✓ Branch 37 → 38 taken 204 times.
✓ Branch 37 → 39 taken 4 times.
✓ Branch 38 → 39 taken 4 times.
✓ Branch 38 → 40 taken 200 times.
|
469 | if ((cluster < FX_FAT_ENTRY_START) || (cluster > media_ptr -> fx_media_fat_reserved)) |
| 293 | { | ||
| 294 | |||
| 295 | /* Send error message back to caller. */ | ||
| 296 | 18 | return(FX_FILE_CORRUPT); | |
| 297 | } | ||
| 298 | |||
| 299 | /* Setup the relative sector (this is zero for subsequent cluster. */ | ||
| 300 | 451 | relative_sector = 0; | |
| 301 | |||
| 302 | /* Calculate the next logical sector. */ | ||
| 303 | 451 | logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) + | |
| 304 | 451 | (((ULONG)cluster - FX_FAT_ENTRY_START) * | |
| 305 | 451 | ((ULONG)media_ptr -> fx_media_sectors_per_cluster)); | |
| 306 | } | ||
| 307 | } | ||
| 308 | else | ||
| 309 | { | ||
| 310 | |||
| 311 | /* Increment the logical sector. */ | ||
| 312 | 144 | logical_sector++; | |
| 313 | |||
| 314 | /* Determine if the logical sector is valid. */ | ||
| 315 |
4/4✓ Branch 37 → 38 taken 5 times.
✓ Branch 37 → 39 taken 73 times.
✓ Branch 41 → 42 taken 4 times.
✓ Branch 41 → 43 taken 62 times.
|
144 | if (logical_sector >= (ULONG)(media_ptr -> fx_media_data_sector_start)) |
| 316 | { | ||
| 317 | |||
| 318 | /* We have exceeded the root directory. */ | ||
| 319 | |||
| 320 | /* Send error message back to caller. */ | ||
| 321 | 9 | return(FX_FILE_CORRUPT); | |
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | /* Read the next logical sector. */ | ||
| 326 | 755 | status = _fx_utility_logical_sector_read(media_ptr, (ULONG64) logical_sector, | |
| 327 | 755 | media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR); | |
| 328 | |||
| 329 | /* Determine if an error occurred. */ | ||
| 330 |
4/4✓ Branch 40 → 41 taken 5 times.
✓ Branch 40 → 42 taken 392 times.
✓ Branch 44 → 45 taken 2 times.
✓ Branch 44 → 46 taken 356 times.
|
755 | if (status != FX_SUCCESS) |
| 331 | { | ||
| 332 | |||
| 333 | /* Return the error status. */ | ||
| 334 | 7 | return(status); | |
| 335 | } | ||
| 336 | |||
| 337 | /* Move to the next sector buffer. */ | ||
| 338 | 748 | sector_base_ptr = media_ptr -> fx_media_memory_buffer; | |
| 339 | |||
| 340 | /* Setup new buffer pointers. */ | ||
| 341 | 748 | byte_offset = 0; | |
| 342 | 748 | work_ptr = sector_base_ptr; | |
| 343 | |||
| 344 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 345 | /* Initialize data for fault tolerant. */ | ||
| 346 | 356 | changed_ptr = work_ptr; | |
| 347 | 356 | changed_size = 0; | |
| 348 | 356 | changed_offset = 0; | |
| 349 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 350 | } | ||
| 351 | } | ||
| 352 | } | ||
| 353 | |||
| 354 | /* Check for an error! */ | ||
| 355 |
4/4✓ Branch 45 → 46 taken 5 times.
✓ Branch 45 → 47 taken 1792 times.
✓ Branch 49 → 50 taken 4 times.
✓ Branch 49 → 51 taken 2810 times.
|
4611 | if (u != (unicode_name_length * 2)) |
| 356 | { | ||
| 357 | |||
| 358 | /* Return an error! */ | ||
| 359 | 9 | return(FX_FILE_CORRUPT); | |
| 360 | } | ||
| 361 | |||
| 362 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 363 |
2/2✓ Branch 51 → 52 taken 1364 times.
✓ Branch 51 → 53 taken 1446 times.
|
2810 | if (media_ptr -> fx_media_fault_tolerant_enabled) |
| 364 | { | ||
| 365 | |||
| 366 | /* Redirect this request to log file. */ | ||
| 367 | 1364 | status = _fx_fault_tolerant_add_dir_log(media_ptr, (ULONG64) logical_sector, changed_offset, changed_ptr, changed_size); | |
| 368 | } | ||
| 369 | else | ||
| 370 | { | ||
| 371 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 372 | |||
| 373 | /* Write the directory sector to the media. */ | ||
| 374 | 3238 | status = _fx_utility_logical_sector_write(media_ptr, (ULONG64) logical_sector, | |
| 375 | sector_base_ptr, ((ULONG) 1), FX_DIRECTORY_SECTOR); | ||
| 376 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 377 | } | ||
| 378 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 379 | |||
| 380 | 4602 | return(status); | |
| 381 | } | ||
| 382 | |||
| 383 |