GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 88 / 0 / 88
Functions: 100.0% 1 / 0 / 1
Branches: 100.0% 66 / 0 / 66

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