GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_unicode_directory_rename.c Lines: 63 63 100.0 %
Date: 2024-03-11 05:15:45 Branches: 46 46 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** FileX Component                                                       */
16
/**                                                                       */
17
/**   Unicode                                                             */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
#define FX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "fx_api.h"
28
#include "fx_unicode.h"
29
#include "fx_directory.h"
30
#include "fx_utility.h"
31
#ifdef FX_ENABLE_FAULT_TOLERANT
32
#include "fx_fault_tolerant.h"
33
#endif /* FX_ENABLE_FAULT_TOLERANT */
34
35
36
/**************************************************************************/
37
/*                                                                        */
38
/*  FUNCTION                                               RELEASE        */
39
/*                                                                        */
40
/*    _fx_unicode_directory_rename                        PORTABLE C      */
41
/*                                                           6.1          */
42
/*  AUTHOR                                                                */
43
/*                                                                        */
44
/*    William E. Lamie, Microsoft Corporation                             */
45
/*                                                                        */
46
/*  DESCRIPTION                                                           */
47
/*                                                                        */
48
/*    This function creates the specified unicode directory.              */
49
/*    This function first attempts to find the specified directory.       */
50
/*    If found, the unicode rename request is valid and the directory     */
51
/*    will be changed to the new unicode name. Otherwise, if the directory*/
52
/*    is not found, the appropriate error code is returned to the caller. */
53
/*                                                                        */
54
/*  INPUT                                                                 */
55
/*                                                                        */
56
/*    media_ptr                             Pointer to media              */
57
/*    old_unicode_name                      Pointer to old unicode name   */
58
/*    old_unicode_length                    Old unicode name length       */
59
/*    new_unicode_name                      Pointer to new unicode name   */
60
/*    new_unicode_length                    Old unicode name length       */
61
/*    new_short_name                        Pointer to new short name     */
62
/*                                                                        */
63
/*  OUTPUT                                                                */
64
/*                                                                        */
65
/*    Completion Status                                                   */
66
/*                                                                        */
67
/*  CALLS                                                                 */
68
/*                                                                        */
69
/*    _fx_unicode_short_name_get            Get the directory short name  */
70
/*    _fx_unicode_directory_search          Search for unicode name       */
71
/*    _fx_unicode_directory_entry_change    Change unicode file name      */
72
/*    _fx_directory_rename                  Rename the directory          */
73
/*    _fx_directory_search                  Search directory              */
74
/*                                                                        */
75
/*  CALLED BY                                                             */
76
/*                                                                        */
77
/*    Application Code                                                    */
78
/*                                                                        */
79
/*  RELEASE HISTORY                                                       */
80
/*                                                                        */
81
/*    DATE              NAME                      DESCRIPTION             */
82
/*                                                                        */
83
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
84
/*  09-30-2020     William E. Lamie         Modified comment(s),          */
85
/*                                            resulting in version 6.1    */
86
/*                                                                        */
87
/**************************************************************************/
88
51
UINT  _fx_unicode_directory_rename(FX_MEDIA *media_ptr, UCHAR *old_unicode_name, ULONG old_unicode_length,
89
                                   UCHAR *new_unicode_name, ULONG new_unicode_length, CHAR *new_short_name)
90
{
91
92
FX_DIR_ENTRY dir_entry;
93
UINT         i, status;
94
ULONG        temp_length;
95
CHAR         old_dir_short_name[13];
96
CHAR         new_dir_short_name[13];
97
UCHAR        alpha, beta;
98
99
100
    /* Clear the return short name.  */
101
51
    new_short_name[0] =  FX_NULL;
102
103
    /* Set shortname to null.  */
104
51
    old_dir_short_name[0] =  FX_NULL;
105
51
    new_dir_short_name[0] =  FX_NULL;
106
107
    /* Check the media to make sure it is open.  */
108
51
    if (media_ptr -> fx_media_id != FX_MEDIA_ID)
109
    {
110
111
        /* Return the media not opened error.  */
112
3
        return(FX_MEDIA_NOT_OPEN);
113
    }
114
115
116
    /* Get the old short name.  */
117
48
    status = _fx_unicode_short_name_get(media_ptr, old_unicode_name, old_unicode_length, &old_dir_short_name[0]);
118
119
    /* Determine if the search was successful.  */
120
48
    if (status != FX_SUCCESS)
121
    {
122
123
        /* Return the error code.  */
124
9
        return(status);
125
    }
126
127
    /* Protect media.  */
128
39
    FX_PROTECT
129
130
    /* Setup temporary length.  */
131
39
    temp_length =  new_unicode_length;
132
133
    /* Setup pointer to media name buffer.  */
134
39
    dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
135
136
    /* Clear the short name string.  */
137
39
    dir_entry.fx_dir_entry_short_name[0] =  FX_NULL;
138
139
    /* Determine if the new directory name is already present.  */
140
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);
141
142
    /* Determine if the search was successful.  */
143
39
    if (status == FX_SUCCESS)
144
    {
145
146
        /* Determine if the name length are equal.  */
147
21
        if (old_unicode_length == new_unicode_length)
148
        {
149
150
            /* Determine if the new name simply has a UNICODE case change. If so, simply let the processing
151
               continue.  */
152
18
            i =  0;
153
            do
154
            {
155
156
                /* Pickup an old name and new name character and convert to upper case if necessary.  */
157
40
                alpha =  old_unicode_name[i * 2];
158

40
                if ((alpha >= 'a') && (alpha <= 'z') && (old_unicode_name[i * 2 + 1] == 0))
159
                {
160
161
                    /* Lower case, convert to upper case!  */
162
18
                    alpha =  (UCHAR)((INT)alpha - 0x20);
163
                }
164
40
                beta =   new_unicode_name[i * 2];
165

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