GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_unicode_file_rename.c Lines: 62 62 100.0 %
Date: 2024-01-10 21:53:23 Branches: 46 46 100.0 %

Line Branch Exec Source
1
/**************************************************************************/
2
/*                                                                        */
3
/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4
/*                                                                        */
5
/*       This software is licensed under the Microsoft Software License   */
6
/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7
/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8
/*       and in the root directory of this software.                      */
9
/*                                                                        */
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_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_unicode_file_rename                             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 file.  If found, */
51
/*    the rename request is valid and the directory entry will be changed */
52
/*    to the new file name.  Otherwise, if the file is not found, the     */
53
/*    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                    New unicode name length       */
62
/*    new_short_name                        Designated new short name     */
63
/*                                                                        */
64
/*  OUTPUT                                                                */
65
/*                                                                        */
66
/*    Completion Status                                                   */
67
/*                                                                        */
68
/*  CALLS                                                                 */
69
/*                                                                        */
70
/*    _fx_unicode_short_name_get            Get short name of unicode name*/
71
/*    _fx_directory_search                  Search directory              */
72
/*    _fx_unicode_directory_entry_change    Change unicode file name      */
73
/*    _fx_unicode_directory_search          Search for unicode name       */
74
/*    _fx_file_rename                       Rename for ASCII file name    */
75
/*    _fx_fault_tolerant_transaction_start  Start fault tolerant          */
76
/*                                            transaction                 */
77
/*    _fx_fault_tolerant_transaction_end    End fault tolerant transaction*/
78
/*                                                                        */
79
/*  CALLED BY                                                             */
80
/*                                                                        */
81
/*    Application Code                                                    */
82
/*                                                                        */
83
/*  RELEASE HISTORY                                                       */
84
/*                                                                        */
85
/*    DATE              NAME                      DESCRIPTION             */
86
/*                                                                        */
87
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
88
/*  09-30-2020     William E. Lamie         Modified comment(s),          */
89
/*                                            resulting in version 6.1    */
90
/*                                                                        */
91
/**************************************************************************/
92
44
UINT _fx_unicode_file_rename(FX_MEDIA *media_ptr, UCHAR *old_unicode_name, ULONG old_unicode_length,
93
                             UCHAR *new_unicode_name, ULONG new_unicode_length, CHAR *new_short_name)
94
{
95
ULONG        i;
96
UINT         status;
97
CHAR         alpha, beta;
98
CHAR         old_shortname[13];
99
CHAR         new_shortname[13];
100
FX_DIR_ENTRY dir_entry;
101
102
103
    /* Clear the return short name.  */
104
44
    new_short_name[0] =  FX_NULL;
105
106
    /* Set shortname to null.  */
107
44
    old_shortname[0] =  FX_NULL;
108
44
    new_shortname[0] =  FX_NULL;
109
110
    /* Check the media to make sure it is open.  */
111
44
    if (media_ptr -> fx_media_id != FX_MEDIA_ID)
112
    {
113
114
        /* Return the media not opened error.  */
115
3
        return(FX_MEDIA_NOT_OPEN);
116
    }
117
118
#ifdef FX_ENABLE_EXFAT
119
    /* Check if media format is exFAT.  */
120
    if (media_ptr -> fx_media_FAT_type == FX_exFAT)
121
    {
122
123
        /* Return the not implemented error.  */
124
        return(FX_NOT_IMPLEMENTED);
125
    }
126
#endif
127
128
    /* Get shortname of old unicode name. */
129
41
    status = _fx_unicode_short_name_get(media_ptr, old_unicode_name, old_unicode_length, old_shortname);
130
131
    /* Determine if the result was successful.  */
132
41
    if (status != FX_SUCCESS)
133
    {
134
135
        /* Return the error code.  */
136
4
        return(status);
137
    }
138
139
    /* Protect media.  */
140
37
    FX_PROTECT
141
142
    /* Setup pointer to media name buffer.  */
143
37
    dir_entry.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
144
145
    /* Clear the short name string.  */
146
37
    dir_entry.fx_dir_entry_short_name[0] =  FX_NULL;
147
148
    /* Search the target directory for the same file name.  */
149
37
    status = _fx_unicode_directory_search(media_ptr, &dir_entry, (UCHAR *)new_shortname, sizeof(new_shortname),
150
                                          new_unicode_name, &new_unicode_length, 0);
151
152
    /* Determine if the name already exists.  */
153
37
    if (status == FX_SUCCESS)
154
    {
155
156
21
        if (old_unicode_length == new_unicode_length)
157
        {
158
159
            /* Determine if the new name simply has an ASCII case change. If so, simply let the processing
160
               continue.  */
161
18
            i =  0;
162
            do
163
            {
164
165
                /* Pickup an old name and new name character and convert to upper case if necessary.  */
166
40
                alpha = (CHAR)old_unicode_name[i << 1];
167

40
                if ((alpha >= 'a') && (alpha <= 'z') && (old_unicode_name[(i << 1) + 1] == 0))
168
                {
169
170
                    /* Lower case, convert to upper case!  */
171
18
                    alpha =  (CHAR)((INT)alpha - 0x20);
172
                }
173
40
                beta =   (CHAR)new_unicode_name[i << 1];
174

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