GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_unicode_directory_rename.c Lines: 63 63 100.0 %
Date: 2026-03-06 18:49:02 Branches: 46 46 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_rename                        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
/*    This function first attempts to find the specified directory.       */
51
/*    If found, the unicode rename request is valid and the directory     */
52
/*    will be changed to the new unicode name. Otherwise, if the directory*/
53
/*    is not found, the appropriate error code is returned to the caller. */
54
/*                                                                        */
55
/*  INPUT                                                                 */
56
/*                                                                        */
57
/*    media_ptr                             Pointer to media              */
58
/*    old_unicode_name                      Pointer to old unicode name   */
59
/*    old_unicode_length                    Old unicode name length       */
60
/*    new_unicode_name                      Pointer to new unicode name   */
61
/*    new_unicode_length                    Old unicode name length       */
62
/*    new_short_name                        Pointer to new short name     */
63
/*                                                                        */
64
/*  OUTPUT                                                                */
65
/*                                                                        */
66
/*    Completion Status                                                   */
67
/*                                                                        */
68
/*  CALLS                                                                 */
69
/*                                                                        */
70
/*    _fx_unicode_short_name_get            Get the directory short name  */
71
/*    _fx_unicode_directory_search          Search for unicode name       */
72
/*    _fx_unicode_directory_entry_change    Change unicode file name      */
73
/*    _fx_directory_rename                  Rename the directory          */
74
/*    _fx_directory_search                  Search directory              */
75
/*                                                                        */
76
/*  CALLED BY                                                             */
77
/*                                                                        */
78
/*    Application Code                                                    */
79
/*                                                                        */
80
/**************************************************************************/
81
51
UINT  _fx_unicode_directory_rename(FX_MEDIA *media_ptr, UCHAR *old_unicode_name, ULONG old_unicode_length,
82
                                   UCHAR *new_unicode_name, ULONG new_unicode_length, CHAR *new_short_name)
83
{
84
85
FX_DIR_ENTRY dir_entry;
86
UINT         i, status;
87
ULONG        temp_length;
88
CHAR         old_dir_short_name[13];
89
CHAR         new_dir_short_name[13];
90
UCHAR        alpha, beta;
91
92
93
    /* Clear the return short name.  */
94
51
    new_short_name[0] =  FX_NULL;
95
96
    /* Set shortname to null.  */
97
51
    old_dir_short_name[0] =  FX_NULL;
98
51
    new_dir_short_name[0] =  FX_NULL;
99
100
    /* Check the media to make sure it is open.  */
101
51
    if (media_ptr -> fx_media_id != FX_MEDIA_ID)
102
    {
103
104
        /* Return the media not opened error.  */
105
3
        return(FX_MEDIA_NOT_OPEN);
106
    }
107
108
109
    /* Get the old short name.  */
110
48
    status = _fx_unicode_short_name_get(media_ptr, old_unicode_name, old_unicode_length, &old_dir_short_name[0]);
111
112
    /* Determine if the search was successful.  */
113
48
    if (status != FX_SUCCESS)
114
    {
115
116
        /* Return the error code.  */
117
9
        return(status);
118
    }
119
120
    /* Protect media.  */
121
39
    FX_PROTECT
122
123
    /* Setup temporary length.  */
124
39
    temp_length =  new_unicode_length;
125
126
    /* Setup pointer to media name buffer.  */
127
39
    dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
128
129
    /* Clear the short name string.  */
130
39
    dir_entry.fx_dir_entry_short_name[0] =  FX_NULL;
131
132
    /* Determine if the new directory name is already present.  */
133
39
    status =  _fx_unicode_directory_search(media_ptr, &dir_entry, (UCHAR *)new_dir_short_name, sizeof(new_dir_short_name), new_unicode_name, &temp_length, 0);
134
135
    /* Determine if the search was successful.  */
136
39
    if (status == FX_SUCCESS)
137
    {
138
139
        /* Determine if the name length are equal.  */
140
21
        if (old_unicode_length == new_unicode_length)
141
        {
142
143
            /* Determine if the new name simply has a UNICODE case change. If so, simply let the processing
144
               continue.  */
145
18
            i =  0;
146
            do
147
            {
148
149
                /* Pickup an old name and new name character and convert to upper case if necessary.  */
150
40
                alpha =  old_unicode_name[i * 2];
151

40
                if ((alpha >= 'a') && (alpha <= 'z') && (old_unicode_name[i * 2 + 1] == 0))
152
                {
153
154
                    /* Lower case, convert to upper case!  */
155
18
                    alpha =  (UCHAR)((INT)alpha - 0x20);
156
                }
157
40
                beta =   new_unicode_name[i * 2];
158

40
                if ((beta >= 'a') && (beta <= 'z') && (new_unicode_name[i * 2 + 1] == 0))
159
                {
160
161
                    /* Lower case, convert to upper case!  */
162
15
                    beta =  (UCHAR)((INT)beta - 0x20);
163
                }
164
165
                /* Now compare the characters.  */
166
40
                if (alpha != beta)
167
                {
168
169
                    /* Get out of this loop!  */
170
6
                    break;
171
                }
172
173
                /* Pickup the high bytes. */
174
34
                alpha = old_unicode_name[i * 2 + 1];
175
34
                beta =   new_unicode_name[i * 2 + 1];
176
177
                /* Now compare the byte.  */
178
34
                if ((alpha != beta))
179
                {
180
181
                    /* Get out of this loop!  */
182
3
                    break;
183
                }
184
185
                /* Move to next character.  */
186
31
                i++;
187
31
            } while (i < old_unicode_length);
188
        }
189
        else
190
        {
191
3
            alpha = 0;
192
3
            beta = 1;
193
        }
194
195
        /* Now determine if the names match.  */
196
21
        if (alpha != beta)
197
        {
198
199
            /* Yes, the directory name already exists in the target location.  */
200
201
            /* Release media protection.  */
202
12
            FX_UNPROTECT
203
204
            /* Return the error code.  */
205
12
            return(FX_ALREADY_CREATED);
206
         }
207
    }
208
209
#ifdef FX_ENABLE_FAULT_TOLERANT
210
    /* Start transaction. */
211
    _fx_fault_tolerant_transaction_start(media_ptr);
212
#endif /* FX_ENABLE_FAULT_TOLERANT */
213
214
    /* Okay, at this point we need to create a new long directory name that has enough space for the
215
       eventual unicode directory name.  */
216
217
    /* Copy the characters from the unicode directory name and make sure they are
218
       within the ASCII range.  */
219
27
    _fx_unicode_temp_long_file_name[0] =  'z';
220
145
    for (i = 1; i < new_unicode_length; i++)
221
    {
222
223
        /* Build temporary long file name.  */
224
118
        _fx_unicode_temp_long_file_name[i] =  (UCHAR)((UINT)'0' + (i % 9));
225
    }
226
27
    _fx_unicode_temp_long_file_name[i] =  FX_NULL;
227
228
    /* Loop to try different temp long file names... if necessary.  */
229
    do
230
    {
231
232
        /* Rename the directory name.  */
233
68
        status =  _fx_directory_rename(media_ptr, old_dir_short_name, (CHAR *)_fx_unicode_temp_long_file_name);
234
235
        /* Determine if there was an error.  */
236
68
        if (status == FX_ALREADY_CREATED)
237
        {
238
239
            /* Adjust the name slightly and try again!  */
240
42
            _fx_unicode_temp_long_file_name[0]--;
241
242
            /* Determine if it is outside the lower case boundary.  */
243
42
            if (_fx_unicode_temp_long_file_name[0] < 0x61)
244
            {
245
1
                break;
246
            }
247
        }
248
67
    } while (status == FX_ALREADY_CREATED);
249
250
    /* Determine if there was an error.  */
251
27
    if (status)
252
    {
253
254
#ifdef FX_ENABLE_FAULT_TOLERANT
255
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
256
#endif /* FX_ENABLE_FAULT_TOLERANT */
257
258
        /* Release media protection.  */
259
3
        FX_UNPROTECT
260
261
        /* Return error.  */
262
3
        return(status);
263
    }
264
265
    /* Setup pointer to media name buffer.  */
266
24
    dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
267
268
    /* Clear the short name string.  */
269
24
    dir_entry.fx_dir_entry_short_name[0] =  FX_NULL;
270
271
    /* Search the system for the supplied file name.  */
272
24
    status =  _fx_directory_search(media_ptr, (CHAR *)_fx_unicode_temp_long_file_name, &dir_entry, FX_NULL, FX_NULL);
273
274
    /* Determine if the search was successful.  */
275
24
    if (status != FX_SUCCESS)
276
    {
277
278
#ifdef FX_ENABLE_FAULT_TOLERANT
279
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
280
#endif /* FX_ENABLE_FAULT_TOLERANT */
281
282
        /* Release media protection.  */
283
1
        FX_UNPROTECT
284
285
        /* Return the error status.  */
286
1
        return(status);
287
    }
288
289
    /* We can now change the temporary long file name with the destination unicode name.  */
290
23
    status = _fx_unicode_directory_entry_change(media_ptr, &dir_entry, new_unicode_name, new_unicode_length);
291
292
    /* Determine if the rename was successful.  */
293
23
    if (status == FX_SUCCESS)
294
    {
295
296
        /* Yes, copy the short file name to the destination.  */
297
        /* The new short name only have 8 characters, since we didn't include a dot in temp_long_file_name. */
298
112
        for (i = 0; i < FX_DIR_NAME_SIZE; i++)
299
        {
300
301
            /* Copy a character.  */
302
109
            new_short_name[i] =  dir_entry.fx_dir_entry_short_name[i];
303
304
            /* Are we done?  */
305
109
            if (new_short_name[i] == FX_NULL)
306
            {
307
19
                break;
308
            }
309
        }
310
    }
311
312
#ifdef FX_ENABLE_FAULT_TOLERANT
313
    /* Check for a bad status.  */
314
    if (status != FX_SUCCESS)
315
    {
316
317
        FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
318
319
        /* Release media protection.  */
320
        FX_UNPROTECT
321
322
        /* Return the bad status.  */
323
        return(status);
324
    }
325
326
    /* End transaction. */
327
    status = _fx_fault_tolerant_transaction_end(media_ptr);
328
#endif /* FX_ENABLE_FAULT_TOLERANT */
329
330
    /* Release the protection.  */
331
23
    FX_UNPROTECT
332
333
    /* Return completion status.  */
334
23
    return(status);
335
}
336