GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_unicode_directory_create.c Lines: 43 43 100.0 %
Date: 2026-03-06 18:49:02 Branches: 24 24 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
/**   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_directory.h"
31
#include "fx_utility.h"
32
#ifdef FX_ENABLE_FAULT_TOLERANT
33
#include "fx_fault_tolerant.h"
34
#endif /* FX_ENABLE_FAULT_TOLERANT */
35
36
37
/**************************************************************************/
38
/*                                                                        */
39
/*  FUNCTION                                               RELEASE        */
40
/*                                                                        */
41
/*    _fx_unicode_directory_create                        PORTABLE C      */
42
/*                                                           6.1          */
43
/*  AUTHOR                                                                */
44
/*                                                                        */
45
/*    William E. Lamie, Microsoft Corporation                             */
46
/*                                                                        */
47
/*  DESCRIPTION                                                           */
48
/*                                                                        */
49
/*    This function creates the specified unicode directory.              */
50
/*                                                                        */
51
/*  INPUT                                                                 */
52
/*                                                                        */
53
/*    media_ptr                             Pointer to media              */
54
/*    source_unicode_name                   Pointer to source unicode name*/
55
/*    source_unicode_length                 Unicode name length           */
56
/*    short_name                            Designated short name         */
57
/*                                                                        */
58
/*  OUTPUT                                                                */
59
/*                                                                        */
60
/*    Completion Status                                                   */
61
/*                                                                        */
62
/*  CALLS                                                                 */
63
/*                                                                        */
64
/*    _fx_directory_search                  Search directory              */
65
/*    _fx_unicode_directory_entry_change    Change unicode file name      */
66
/*    _fx_unicode_directory_search          Search for unicode name       */
67
/*    _fx_directory_create                  Create a directory            */
68
/*    _fx_fault_tolerant_transaction_start  Start fault tolerant          */
69
/*                                            transaction                 */
70
/*    _fx_fault_tolerant_transaction_end    End fault tolerant transaction*/
71
/*    _fx_fault_tolerant_recover            Recover FAT chain             */
72
/*    _fx_fault_tolerant_reset_log_file     Reset the log file            */
73
/*                                                                        */
74
/*  CALLED BY                                                             */
75
/*                                                                        */
76
/*    Application Code                                                    */
77
/*                                                                        */
78
/**************************************************************************/
79
350
UINT  _fx_unicode_directory_create(FX_MEDIA *media_ptr, UCHAR *source_unicode_name, ULONG source_unicode_length, CHAR *short_name)
80
{
81
82
FX_DIR_ENTRY dir_entry;
83
UINT         i, status;
84
ULONG        temp_length;
85
UCHAR        destination_shortname[13];
86
87
88
    /* Setup pointer to media name buffer.  */
89
350
    dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
90
91
    /* Clear the short name string.  */
92
350
    dir_entry.fx_dir_entry_short_name[0] =  FX_NULL;
93
94
    /* Set destination shortname to null.  */
95
350
    destination_shortname[0] =  FX_NULL;
96
97
    /* Clear the return short name.  */
98
350
    short_name[0] =  FX_NULL;
99
100
    /* Check the media to make sure it is open.  */
101
350
    if (media_ptr -> fx_media_id != FX_MEDIA_ID)
102
    {
103
104
        /* Return the media not opened error.  */
105
1
        return(FX_MEDIA_NOT_OPEN);
106
    }
107
108
109
    /* If trace is enabled, insert this event into the trace buffer.  */
110
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_UNICODE_DIRECTORY_CREATE, media_ptr, source_unicode_name, source_unicode_length, short_name, FX_TRACE_DIRECTORY_EVENTS, 0, 0)
111
112
    /* Protect media.  */
113
349
    FX_PROTECT
114
115
#ifdef FX_ENABLE_FAULT_TOLERANT
116
    /* Start transaction. */
117
    _fx_fault_tolerant_transaction_start(media_ptr);
118
#endif /* FX_ENABLE_FAULT_TOLERANT */
119
120
    /* Check for write protect at the media level (set by driver).  */
121
349
    if (media_ptr -> fx_media_driver_write_protect)
122
    {
123
#ifdef FX_ENABLE_FAULT_TOLERANT
124
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
125
#endif /* FX_ENABLE_FAULT_TOLERANT */
126
127
        /* Release media protection.  */
128
1
        FX_UNPROTECT
129
130
        /* Return write protect error.  */
131
1
        return(FX_WRITE_PROTECT);
132
    }
133
134
    /* Setup temporary length.  */
135
348
    temp_length =  source_unicode_length;
136
137
    /* Determine if the destination directory is already present.  */
138
348
    status =  _fx_unicode_directory_search(media_ptr, &dir_entry, destination_shortname, sizeof(destination_shortname), source_unicode_name, &temp_length, 0);
139
140
    /* Determine if the search was successful.  */
141
348
    if (status == FX_SUCCESS)
142
    {
143
#ifdef FX_ENABLE_FAULT_TOLERANT
144
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
145
#endif /* FX_ENABLE_FAULT_TOLERANT */
146
147
        /* Release media protection.  */
148
9
        FX_UNPROTECT
149
150
        /* Return the error code.  */
151
9
        return(FX_ALREADY_CREATED);
152
    }
153
154
    /* Okay, at this point we need to create a new long directory name that has enough space for the
155
       eventual unicode directory name.  */
156
157
    /* Copy the characters from the unicode directory name and make sure they are
158
       within the ASCII range.  */
159
339
    _fx_unicode_temp_long_file_name[0] =  'z';
160
2263
    for (i = 1; i < source_unicode_length; i++)
161
    {
162
163
        /* Build temporary long file name.  */
164
1924
        _fx_unicode_temp_long_file_name[i] =  (UCHAR)((INT)'0' + (i % 9));
165
    }
166
339
    _fx_unicode_temp_long_file_name[i] =  FX_NULL;
167
168
    /* Loop to try different temp long file names... if necessary.  */
169
    do
170
    {
171
172
        /* Create a new directory with the temp long file name.  */
173
2611
        status =  _fx_directory_create(media_ptr, (CHAR *)_fx_unicode_temp_long_file_name);
174
175
        /* Determine if there was an error.  */
176
2611
        if (status == FX_ALREADY_CREATED)
177
        {
178
179
            /* Adjust the name slightly and try again!  */
180
2283
            _fx_unicode_temp_long_file_name[0]--;
181
182
            /* Determine if it is outside the lower case boundary.  */
183
2283
            if (_fx_unicode_temp_long_file_name[0] < 0x61)
184
            {
185
11
                break;
186
            }
187
        }
188
2600
    } while (status == FX_ALREADY_CREATED);
189
190
    /* Determine if there was an error.  */
191
339
    if (status)
192
    {
193
#ifdef FX_ENABLE_FAULT_TOLERANT
194
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
195
#endif /* FX_ENABLE_FAULT_TOLERANT */
196
197
        /* Release media protection.  */
198
95
        FX_UNPROTECT
199
200
        /* Return error.  */
201
95
        return(status);
202
    }
203
204
    /* Setup pointer to media name buffer.  */
205
244
    dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
206
207
    /* Clear the short name string.  */
208
244
    dir_entry.fx_dir_entry_short_name[0] =  0;
209
210
    /* Search the system for the supplied file name.  */
211
244
    status =  _fx_directory_search(media_ptr, (CHAR *)_fx_unicode_temp_long_file_name, &dir_entry, FX_NULL, FX_NULL);
212
213
    /* Determine if the search was successful.  */
214
244
    if (status != FX_SUCCESS)
215
    {
216
#ifdef FX_ENABLE_FAULT_TOLERANT
217
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
218
#endif /* FX_ENABLE_FAULT_TOLERANT */
219
220
        /* Release media protection.  */
221
5
        FX_UNPROTECT
222
223
        /* Return the error status.  */
224
5
        return(status);
225
    }
226
227
    /* We can now change the temporary long file name with the destination unicode name.  */
228
239
    status =  _fx_unicode_directory_entry_change(media_ptr, &dir_entry,  source_unicode_name, source_unicode_length);
229
230
    /* Was this successful?  */
231
239
    if (status == FX_SUCCESS)
232
    {
233
234
        /* Yes, copy the short file name to the destination.  */
235
        /* The new short name only have 8 characters, since we didn't include a dot in temp_long_file_name. */
236
1473
        for (i = 0; i < FX_DIR_NAME_SIZE; i++)
237
        {
238
239
            /* Copy a character.  */
240
1373
            short_name[i] =  dir_entry.fx_dir_entry_short_name[i];
241
242
            /* Are we done?  */
243
1373
            if (short_name[i] == FX_NULL)
244
            {
245
137
                break;
246
            }
247
        }
248
    }
249
250
#ifdef FX_ENABLE_FAULT_TOLERANT
251
    /* Check for a bad status.  */
252
    if (status != FX_SUCCESS)
253
    {
254
255
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
256
257
        /* Release media protection.  */
258
        FX_UNPROTECT
259
260
        /* Return the bad status.  */
261
        return(status);
262
    }
263
264
    /* End transaction. */
265
    status = _fx_fault_tolerant_transaction_end(media_ptr);
266
#endif /* FX_ENABLE_FAULT_TOLERANT */
267
268
    /* Release the protection.  */
269
239
    FX_UNPROTECT
270
271
    /* Return completion status.  */
272
239
    return(status);
273
}
274