GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_directory_create.c Lines: 144 144 100.0 %
Date: 2026-03-06 18:49:02 Branches: 64 64 100.0 %

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
22143
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
22143
    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
22143
    i =  0;
117
22143
    work_ptr =  (CHAR *)directory_name;
118

128139
    while (*work_ptr && (i < FX_MAX_LONG_NAME_LEN))
119
    {
120
121
        /* Determine if the character designates a new path.  */
122

105996
        if ((*work_ptr == '\\') || (*work_ptr == '/'))
123
        {
124
            /* Yes, reset the name size.  */
125
779
            i =  0;
126
        }
127
        /* Check for leading spaces.  */
128

105217
        else if ((*work_ptr != ' ') || (i != 0))
129
        {
130
131
            /* No leading spaces, increment the name size.  */
132
105151
            i++;
133
        }
134
135
        /* Move to the next character.  */
136
105996
        work_ptr++;
137
    }
138
139
    /* Determine if the supplied name is valid.  */
140

22143
    if ((i == 0) || (i >= FX_MAX_LONG_NAME_LEN))
141
    {
142
143
        /* Return an invalid name value.  */
144
2
        return(FX_INVALID_NAME);
145
    }
146
147
    /* Setup pointer to media name buffer.  */
148
22141
    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
22141
    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
22141
    dir_entry.fx_dir_entry_short_name[0] =  0;
155
156
    /* Clear the search short name string.  */
157
22141
    search_directory.fx_dir_entry_short_name[0] =  0;
158
159
    /* Check the media to make sure it is open.  */
160
22141
    if (media_ptr -> fx_media_id != FX_MEDIA_ID)
161
    {
162
163
        /* Return the media not opened error.  */
164
1
        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
22140
    FX_PROTECT
172
173
    /* Check for write protect at the media level (set by driver).  */
174
22140
    if (media_ptr -> fx_media_driver_write_protect)
175
    {
176
177
        /* Release media protection.  */
178
1
        FX_UNPROTECT
179
180
        /* Return write protect error.  */
181
1
        return(FX_WRITE_PROTECT);
182
    }
183
184
    /* Make sure there is at least one cluster remaining for the new file.  */
185
22139
    if (!media_ptr -> fx_media_available_clusters)
186
    {
187
188
        /* Release media protection.  */
189
1
        FX_UNPROTECT
190
191
        /* Return a no-space error.  */
192
1
        return(FX_NO_MORE_SPACE);
193
    }
194
195
    /* Search the system for the supplied directory name.  */
196
22138
    status =  _fx_directory_search(media_ptr, directory_name, &dir_entry, &search_directory, &work_ptr);
197
198
    /* Determine if the search was successful.  */
199
22138
    if (status == FX_SUCCESS)
200
    {
201
202
        /* Release media protection.  */
203
2287
        FX_UNPROTECT
204
205
        /* Directory found - Return the error code.  */
206
2287
        return(FX_ALREADY_CREATED);
207
    }
208
209
    /* Determine if there is anything left after the name.  */
210
19851
    if (_fx_directory_name_extract(work_ptr, &dir_entry.fx_dir_entry_name[0]))
211
    {
212
213
        /* Release media protection.  */
214
1
        FX_UNPROTECT
215
216
        /* Extra information after the file name, return an invalid name
217
           error.  */
218
1
        return(FX_INVALID_PATH);
219
    }
220
221
222
#ifdef FX_ENABLE_FAULT_TOLERANT
223
    /* Start transaction. */
224
    _fx_fault_tolerant_transaction_start(media_ptr);
225
#endif /* FX_ENABLE_FAULT_TOLERANT */
226
227
    /* Find a free slot for the new directory.  */
228
19850
    status =  _fx_directory_free_search(media_ptr, &search_directory, &dir_entry);
229
230
    /* Determine if the search was successful.  */
231
19850
    if (status != FX_SUCCESS)
232
    {
233
234
#ifdef FX_ENABLE_FAULT_TOLERANT
235
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
236
#endif /* FX_ENABLE_FAULT_TOLERANT */
237
238
        /* Release media protection.  */
239
86
        FX_UNPROTECT
240
241
        /* Return the error code.  */
242
86
        return(status);
243
    }
244
245
    /* Now allocate a cluster for our new sub-directory entry.  */
246
247
19764
    FAT_index    =      media_ptr -> fx_media_cluster_search_start;
248
19764
    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
19766
        if (!total_clusters)
256
        {
257
258
#ifdef FX_ENABLE_FAULT_TOLERANT
259
            FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
260
#endif /* FX_ENABLE_FAULT_TOLERANT */
261
262
            /* Release media protection.  */
263
1
            FX_UNPROTECT
264
265
            /* Something is wrong with the media - the desired clusters were
266
               not found in the FAT table.  */
267
1
            return(FX_NO_MORE_SPACE);
268
        }
269
270
        /* Read FAT entry.  */
271
19765
        status =  _fx_utility_FAT_entry_read(media_ptr, FAT_index, &FAT_value);
272
273
        /* Check for a bad status.  */
274
19765
        if (status != FX_SUCCESS)
275
        {
276
277
#ifdef FX_ENABLE_FAULT_TOLERANT
278
            FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
279
#endif /* FX_ENABLE_FAULT_TOLERANT */
280
281
            /* Release media protection.  */
282
1
            FX_UNPROTECT
283
284
            /* Return the bad status.  */
285
1
            return(status);
286
        }
287
288
        /* Decrement the total cluster count.  */
289
19764
        total_clusters--;
290
291
        /* Determine if the FAT entry is free.  */
292
19764
        if (FAT_value == FX_FREE_CLUSTER)
293
        {
294
295
            /* Move cluster search pointer forward.  */
296
19762
            media_ptr -> fx_media_cluster_search_start =  FAT_index + 1;
297
298
            /* Determine if this needs to be wrapped.  */
299
19762
            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
1
                media_ptr -> fx_media_cluster_search_start =  FX_FAT_ENTRY_START;
304
            }
305
306
            /* Break this loop.  */
307
19762
            break;
308
        }
309
        else
310
        {
311
312
            /* FAT entry is not free... Advance the FAT index.  */
313
2
            FAT_index++;
314
315
            /* Determine if we need to wrap the FAT index around.  */
316
2
            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
1
                FAT_index =  FX_FAT_ENTRY_START;
321
            }
322
        }
323
    } while (FX_TRUE);
324
325
    /* Decrease the number of available clusters for the media.  */
326
19762
    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
19762
    _fx_directory_name_extract(work_ptr, &dir_entry.fx_dir_entry_name[0]);
336
337
    /* Lockout interrupts for time/date access.  */
338
19762
    FX_DISABLE_INTS
339
340
    /* Set time and date stamps.  */
341
19762
    dir_entry.fx_dir_entry_time =  _fx_system_time;
342
19762
    dir_entry.fx_dir_entry_date =  _fx_system_date;
343
344
    /* Restore interrupts.  */
345
19762
    FX_RESTORE_INTS
346
347
    /* Set the attributes for the file.  */
348
19762
    dir_entry.fx_dir_entry_attributes =  FX_DIRECTORY;
349
350
351
    /* Set file size to 0. */
352
19762
    dir_entry.fx_dir_entry_file_size =  0;
353
354
355
    /* Set the cluster to EOF.  */
356
19762
    dir_entry.fx_dir_entry_cluster =    FAT_index;
357
358
    /* Is there a leading dot?  */
359
19762
    if (dir_entry.fx_dir_entry_name[0] == '.')
360
    {
361
362
        /* Yes, toggle the hidden attribute bit.  */
363
2
        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
19762
    logical_sector =    ((ULONG) media_ptr -> fx_media_data_sector_start) +
373
19762
                         (((ULONG64) FAT_index - FX_FAT_ENTRY_START) *
374
19762
                         ((ULONG) media_ptr -> fx_media_sectors_per_cluster));
375
376
    /* Pickup the number of sectors for the initial sub-directory cluster.  */
377
19762
    sectors =  media_ptr -> fx_media_sectors_per_cluster;
378
379
    /* Read the first logical sector associated with the allocated
380
       cluster.  */
381
19762
    status =  _fx_utility_logical_sector_read(media_ptr, logical_sector,
382
19762
                                              media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
383
384
    /* Determine if an error occurred.  */
385
19762
    if (status != FX_SUCCESS)
386
    {
387
388
#ifdef FX_ENABLE_FAULT_TOLERANT
389
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
390
#endif /* FX_ENABLE_FAULT_TOLERANT */
391
392
        /* Release media protection.  */
393
1
        FX_UNPROTECT
394
395
        /* Return error code.  */
396
1
        return(status);
397
    }
398
399
    /* Clear the entire first sector of the new sub-directory cluster.  */
400
19761
    work_ptr =  (CHAR *)media_ptr -> fx_media_memory_buffer;
401
19761
    i =  0;
402
656145
    while (i < media_ptr -> fx_media_bytes_per_sector)
403
    {
404
405
        /* Clear 4 bytes.  */
406
636384
        *((ULONG *)work_ptr) =  (ULONG)0;
407
408
        /* Increment pointer.  */
409
636384
        work_ptr =  work_ptr + sizeof(ULONG);
410
411
        /* Increment counter.  */
412
636384
        i =  i + (ULONG)sizeof(ULONG);
413
    }
414
415
#ifdef FX_ENABLE_FAULT_TOLERANT
416
    if (media_ptr -> fx_media_fault_tolerant_enabled == FX_TRUE)
417
    {
418
419
        /* Write back. */
420
        status =  _fx_utility_logical_sector_write(media_ptr, logical_sector,
421
                                                   media_ptr -> fx_media_memory_buffer, (ULONG)1, FX_DIRECTORY_SECTOR);
422
423
        /* Determine if an error occurred.  */
424
        if (status != FX_SUCCESS)
425
        {
426
            FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
427
428
            /* Release media protection.  */
429
            FX_UNPROTECT
430
431
            /* Return error code.  */
432
            return(status);
433
        }
434
435
        /* Force flush the internal logical sector cache.  */
436
        status =  _fx_utility_logical_sector_flush(media_ptr, logical_sector, sectors, FX_TRUE);
437
438
        /* Determine if the write was successful.  */
439
        if (status != FX_SUCCESS)
440
        {
441
            FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
442
443
            /* Release media protection.  */
444
            FX_UNPROTECT
445
446
            /* Return the error code.  */
447
            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
19761
    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
        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
146
            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
146
            if (status != FX_SUCCESS)
470
            {
471
472
#ifdef FX_ENABLE_FAULT_TOLERANT
473
                FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
474
#endif /* FX_ENABLE_FAULT_TOLERANT */
475
476
                /* Release media protection.  */
477
1
                FX_UNPROTECT
478
479
                /* Return the error code.  */
480
1
                return(status);
481
            }
482
        }
483
484
        /* Clear all additional sectors of new sub-directory.  */
485
145
        sectors--;
486
1045
        while (sectors)
487
        {
488
489
#ifndef FX_MEDIA_STATISTICS_DISABLE
490
491
            /* Increment the number of driver write sector(s) requests.  */
492
901
            media_ptr -> fx_media_driver_write_requests++;
493
#endif
494
495
            /* Build Write request to the driver.  */
496
901
            media_ptr -> fx_media_driver_request =          FX_DRIVER_WRITE;
497
901
            media_ptr -> fx_media_driver_status =           FX_IO_ERROR;
498
901
            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
901
            media_ptr -> fx_media_driver_logical_sector =   (ULONG)logical_sector + ((ULONG)sectors);
503
#endif
504
901
            media_ptr -> fx_media_driver_sectors =          1;
505
901
            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
901
            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
901
                (media_ptr -> fx_media_driver_entry) (media_ptr);
515
516
            /* Clear the system write flag.  */
517
901
            media_ptr -> fx_media_driver_system_write =  FX_FALSE;
518
519
            /* Determine if an error occurred.  */
520
901
            if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
521
            {
522
523
#ifdef FX_ENABLE_FAULT_TOLERANT
524
                FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
525
#endif /* FX_ENABLE_FAULT_TOLERANT */
526
527
                /* Release media protection.  */
528
1
                FX_UNPROTECT
529
530
                /* Return error code.  */
531
1
                return(media_ptr -> fx_media_driver_status);
532
            }
533
534
            /* Decrease the number of sectors to clear.  */
535
900
            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
19759
    sub_dir_entry =  dir_entry;
544
545
    /* Setup pointer to media name buffer.  */
546
19759
    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
19759
    work_ptr =  &sub_dir_entry.fx_dir_entry_name[0];
550
237108
    for (i = 0; i < (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE); i++)
551
    {
552
217349
        *work_ptr++ = ' ';
553
    }
554
555
19759
    sub_dir_entry.fx_dir_entry_long_name_present = 0;
556
557
    /* Now build the "." directory entry.  */
558
19759
    sub_dir_entry.fx_dir_entry_name[0] =        '.';
559
19759
    sub_dir_entry.fx_dir_entry_name[1] =        0;
560
19759
    sub_dir_entry.fx_dir_entry_log_sector =     logical_sector;
561
19759
    sub_dir_entry.fx_dir_entry_byte_offset =    0;
562
563
    /* Write the directory's first entry.  */
564
19759
    status =  _fx_directory_entry_write(media_ptr, &sub_dir_entry);
565
566
    /* Check for error condition.  */
567
19759
    if (status != FX_SUCCESS)
568
    {
569
570
#ifdef FX_ENABLE_FAULT_TOLERANT
571
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
572
#endif /* FX_ENABLE_FAULT_TOLERANT */
573
574
        /* Release media protection.  */
575
1
        FX_UNPROTECT
576
577
        /* Return error status.  */
578
1
        return(status);
579
    }
580
581
    /* Now build the ".." directory entry.  */
582
583
    /* Determine if the search directory is the root.  */
584
19758
    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
454
        sub_dir_entry =  search_directory;
591
592
        /* Copy the date and time from the actual sub-directory.  */
593
454
        sub_dir_entry.fx_dir_entry_time =  dir_entry.fx_dir_entry_time;
594
454
        sub_dir_entry.fx_dir_entry_date =  dir_entry.fx_dir_entry_date;
595
596
        /* Adjust pointer to media name buffer.  */
597
454
        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
454
        work_ptr =  &sub_dir_entry.fx_dir_entry_name[0];
601
5448
        for (i = 0; i < (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE); i++)
602
        {
603
4994
            *work_ptr++ = ' ';
604
        }
605
606
454
        sub_dir_entry.fx_dir_entry_name[0] =  '.';
607
454
        sub_dir_entry.fx_dir_entry_name[1] =  '.';
608
454
        sub_dir_entry.fx_dir_entry_name[2] =   0;
609
610
454
        sub_dir_entry.fx_dir_entry_long_name_present = 0;
611
612
        /* Set file size to 0. */
613
454
        sub_dir_entry.fx_dir_entry_file_size =  0;
614
615
        /* Change the logical sector for this entry.  */
616
454
        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
19304
        sub_dir_entry.fx_dir_entry_name[1] =  '.';
624
19304
        sub_dir_entry.fx_dir_entry_name[2] =   0;
625
626
        /* Clear the cluster to indicate the root directory.  */
627
19304
        sub_dir_entry.fx_dir_entry_cluster =  0;
628
    }
629
630
    /* Setup the byte offset.  */
631
19758
    sub_dir_entry.fx_dir_entry_byte_offset =  FX_DIR_ENTRY_SIZE;
632
633
    /* Write the directory's second entry.  */
634
19758
    status =  _fx_directory_entry_write(media_ptr, &sub_dir_entry);
635
636
    /* Check for error condition.  */
637
19758
    if (status != FX_SUCCESS)
638
    {
639
640
#ifdef FX_ENABLE_FAULT_TOLERANT
641
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
642
#endif /* FX_ENABLE_FAULT_TOLERANT */
643
644
        /* Release media protection.  */
645
1
        FX_UNPROTECT
646
647
        /* Return error status.  */
648
1
        return(status);
649
    }
650
651
    /* Write an EOF in the found FAT entry.  */
652
19757
    status =  _fx_utility_FAT_entry_write(media_ptr, FAT_index, media_ptr -> fx_media_fat_last);
653
654
    /* Check for a bad status.  */
655
19757
    if (status != FX_SUCCESS)
656
    {
657
658
#ifdef FX_ENABLE_FAULT_TOLERANT
659
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
660
#endif /* FX_ENABLE_FAULT_TOLERANT */
661
662
        /* Release media protection.  */
663
1
        FX_UNPROTECT
664
665
        /* Return the bad status.  */
666
1
        return(status);
667
    }
668
669
670
#ifdef FX_FAULT_TOLERANT
671
672
    /* Flush the cached individual FAT entries */
673
    _fx_utility_FAT_flush(media_ptr);
674
#endif
675
676
    /* Now write out the new directory entry.  */
677
678
19756
    status = _fx_directory_entry_write(media_ptr, &dir_entry);
679
680
#ifdef FX_ENABLE_FAULT_TOLERANT
681
    /* Check for a bad status.  */
682
    if (status != FX_SUCCESS)
683
    {
684
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
685
686
        /* Release media protection.  */
687
        FX_UNPROTECT
688
689
        /* Return the bad status.  */
690
        return(status);
691
    }
692
693
    /* End transaction. */
694
    status = _fx_fault_tolerant_transaction_end(media_ptr);
695
#endif /* FX_ENABLE_FAULT_TOLERANT */
696
697
    /* Release media protection.  */
698
19756
    FX_UNPROTECT
699
700
    /* Directory create is complete, return status.  */
701
19756
    return(status);
702
}
703