GCC Code Coverage Report


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

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