GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_unicode_directory_entry_change.c Lines: 74 74 100.0 %
Date: 2026-03-06 18:49:02 Branches: 40 40 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_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_entry_change                  PORTABLE C      */
41
/*                                                           6.1          */
42
/*  AUTHOR                                                                */
43
/*                                                                        */
44
/*    William E. Lamie, Microsoft Corporation                             */
45
/*                                                                        */
46
/*  DESCRIPTION                                                           */
47
/*                                                                        */
48
/*    This function changes the unicode name of a directory entry.        */
49
/*                                                                        */
50
/*  INPUT                                                                 */
51
/*                                                                        */
52
/*    media_ptr                             Pointer to media              */
53
/*    entry_ptr                             Directory entry               */
54
/*    unicode_name                          Destination unicode name      */
55
/*    unicode_name_length                   Unicode name size             */
56
/*                                                                        */
57
/*  OUTPUT                                                                */
58
/*                                                                        */
59
/*    Completion Status                                                   */
60
/*                                                                        */
61
/*  CALLS                                                                 */
62
/*                                                                        */
63
/*    _fx_utility_FAT_entry_read            Read a FAT entry              */
64
/*    _fx_utility_logical_sector_read       Read a logical sector         */
65
/*    _fx_utility_logical_sector_write      Write a logical sector        */
66
/*    _fx_fault_tolerant_add_dir_log        Add directory redo log        */
67
/*                                                                        */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    Unicode Utilities                                                   */
71
/*                                                                        */
72
/**************************************************************************/
73
371
UINT  _fx_unicode_directory_entry_change(FX_MEDIA *media_ptr, FX_DIR_ENTRY *entry_ptr, UCHAR *unicode_name, ULONG unicode_name_length)
74
{
75
76
UCHAR *work_ptr, *sector_base_ptr;
77
UINT   status;
78
UINT   i, j, k, u, card, lfn_entries;
79
UCHAR  eof_marker;
80
ULONG  logical_sector, relative_sector;
81
ULONG  byte_offset;
82
ULONG  cluster, next_cluster;
83
84
#ifdef FX_ENABLE_FAULT_TOLERANT
85
UCHAR *changed_ptr;
86
UINT   changed_size;
87
ULONG  changed_offset;
88
#endif /* FX_ENABLE_FAULT_TOLERANT */
89
90
91
#ifndef FX_MEDIA_STATISTICS_DISABLE
92
93
    /* Increment the number of directory entry write requests.  */
94
371
    media_ptr -> fx_media_directory_entry_writes++;
95
#endif
96
97
    /* Pickup the byte offset of the entry.  */
98
371
    byte_offset = entry_ptr -> fx_dir_entry_byte_offset;
99
100
    /* Pickup the logical sector of the entry.  */
101
371
    logical_sector = (ULONG)entry_ptr -> fx_dir_entry_log_sector;
102
103
    /* Figure out where what cluster we are in.  */
104
371
    if (logical_sector >= (ULONG)(media_ptr -> fx_media_data_sector_start))
105
    {
106
107
        /* Calculate the cluster that this logical sector is in.  */
108
260
        cluster =  (logical_sector - media_ptr -> fx_media_data_sector_start) / (media_ptr -> fx_media_sectors_per_cluster) + FX_FAT_ENTRY_START;
109
110
        /* Calculate the relative cluster.  */
111
260
        relative_sector =  logical_sector -  (((ULONG)media_ptr -> fx_media_data_sector_start) +
112
260
                                              (((ULONG)cluster - FX_FAT_ENTRY_START) *
113
260
                                               ((ULONG)media_ptr -> fx_media_sectors_per_cluster)));
114
    }
115
    else
116
    {
117
118
        /* Clear the cluster and the relative sector.  */
119
111
        cluster =  0;
120
111
        relative_sector =  0;
121
    }
122
123
    /* Read the logical directory sector.  */
124
371
    status =  _fx_utility_logical_sector_read(media_ptr, (ULONG64) entry_ptr -> fx_dir_entry_log_sector,
125
371
                                              media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
126
127
    /* Determine if an error occurred.  */
128
371
    if (status != FX_SUCCESS)
129
    {
130
131
        /* Return the error status.  */
132
4
        return(status);
133
    }
134
135
    /* Setup a pointer into the buffer.  */
136
367
    sector_base_ptr = (UCHAR *)media_ptr -> fx_media_memory_buffer;
137
367
    work_ptr =  sector_base_ptr + (UINT)entry_ptr -> fx_dir_entry_byte_offset;
138
139
    /* Initialize the unicode index.  */
140
367
    u =  0;
141
142
#ifdef FX_ENABLE_FAULT_TOLERANT
143
    /* Initialize data for fault tolerant. */
144
    changed_ptr = work_ptr;
145
    changed_size = 0;
146
    changed_offset = entry_ptr -> fx_dir_entry_byte_offset;
147
#endif /* FX_ENABLE_FAULT_TOLERANT */
148
149
    /* Check for a valid long name.  */
150
367
    if ((0x40 & (*work_ptr)))
151
    {
152
153
        /* Get the lower 5 bit containing the cardinality.  */
154
366
        card = (*work_ptr & (UCHAR)0x1f);
155
366
        lfn_entries =  card;
156
157
        /* Loop through the file name.  */
158
847
        for (j = 0; j < lfn_entries; j++)
159
        {
160
161
            /* Clear the eof marker.  */
162
486
            eof_marker =  0;
163
164
            /* Loop through file name fields.  */
165
8262
            for (i = 1, k = (26 * (card - 1)) & 0xFFFFFFFF; i < FX_DIR_ENTRY_SIZE; i += 2)
166
            {
167
168
                /* Process relative to specific fields.  */
169

7776
                if ((i == 11) || (i == 26))
170
                {
171
972
                    continue;
172
                }
173
174
6804
                if (i == 13)
175
                {
176
486
                    i = 12;
177
486
                    continue;
178
                }
179
180
                /* Determine if the EOF marker is present.  */
181
6318
                if (eof_marker)
182
                {
183
184
3368
                    work_ptr[i] = eof_marker;
185
3368
                    work_ptr[i + 1] = eof_marker;
186
                }
187
2950
                else if (k < (unicode_name_length * 2))
188
                {
189
190
2458
                    work_ptr[i] = unicode_name[k];
191
2458
                    work_ptr[i + 1] = unicode_name[k + 1];
192
2458
                    u =  u + 2;
193
                }
194
492
                else if (k == (unicode_name_length * 2))
195
                {
196
197
362
                    work_ptr[i] = 0;
198
362
                    work_ptr[i + 1] =  0;
199
200
                    /* end of name, pad with 0xff.  */
201
362
                    eof_marker =  (UCHAR)0xff;
202
                }
203
204
6318
                k =  k + 2;
205
            }
206
207
            /* Decrement the card.  */
208
486
            card--;
209
210
            /* Setup pointers for the name write.  */
211
486
            work_ptr += FX_DIR_ENTRY_SIZE;
212
486
            byte_offset += FX_DIR_ENTRY_SIZE;
213
214
#ifdef FX_ENABLE_FAULT_TOLERANT
215
            /* Update changed_size. */
216
            changed_size += FX_DIR_ENTRY_SIZE;
217
#endif /* FX_ENABLE_FAULT_TOLERANT */
218
219
            /* Determine if the write is within the current sector.   */
220
486
            if (byte_offset >= media_ptr -> fx_media_bytes_per_sector)
221
            {
222
#ifdef FX_ENABLE_FAULT_TOLERANT
223
                if (media_ptr -> fx_media_fault_tolerant_enabled)
224
                {
225
226
                    /* Redirect this request to log file. */
227
                    status = _fx_fault_tolerant_add_dir_log(media_ptr, (ULONG64) logical_sector, changed_offset, changed_ptr, changed_size);
228
                }
229
                else
230
                {
231
232
                    /* Write the current sector out.  */
233
                    status =  _fx_utility_logical_sector_write(media_ptr, (ULONG64) logical_sector,
234
                                                               sector_base_ptr, ((ULONG) 1), FX_DIRECTORY_SECTOR);
235
                }
236
237
238
                /* Determine if an error occurred.  */
239
                if (status != FX_SUCCESS)
240
                {
241
242
                    /* Return the error status.  */
243
                    return(status);
244
                }
245
#else /* FX_ENABLE_FAULT_TOLERANT */
246
247
                /* Write the current sector out.  */
248
                /* Note: Since the sector is in the cache after a sector read, therefore _fx_utility_logical_sector_write
249
                   always returns success when FX_ENABLE_FAULT_TOLERANT is not defined.  In other words, the checking
250
                   on the return value is needed only when FX_ENABLE_FAULT_TOLERANT is defined. */
251
85
                _fx_utility_logical_sector_write(media_ptr, (ULONG64) logical_sector,
252
                                                 sector_base_ptr, ((ULONG) 1), FX_DIRECTORY_SECTOR);
253
#endif /* FX_ENABLE_FAULT_TOLERANT */
254
255
                /* Determine if we are in the root directory.  */
256
85
                if (logical_sector >= (ULONG)(media_ptr -> fx_media_data_sector_start))
257
                {
258
259
                    /* Determine the next sector of the directory entry.  */
260
69
                    if (relative_sector < (media_ptr -> fx_media_sectors_per_cluster - 1))
261
                    {
262
263
                        /* More sectors in this cluster.  */
264
265
                        /* Simply increment the logical sector.  */
266
15
                        logical_sector++;
267
268
                        /* Increment the relative sector.  */
269
15
                        relative_sector++;
270
                    }
271
                    else
272
                    {
273
274
                        /* We need to move to the next cluster.  */
275
276
                        /* Pickup the next cluster.  */
277
54
                        status =  _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster);
278
279
                        /* Check for I/O error.  */
280
54
                        if (status != FX_SUCCESS)
281
                        {
282
283
                            /* Return error code.  */
284
1
                            return(status);
285
                        }
286
287
                        /* Copy next cluster to the current cluster.  */
288
53
                        cluster =  next_cluster;
289
290
                        /* Check the value of the new cluster - it must be a valid cluster number
291
                           or something is really wrong!  */
292

53
                        if ((cluster < FX_FAT_ENTRY_START) || (cluster > media_ptr -> fx_media_fat_reserved))
293
                        {
294
295
                            /* Send error message back to caller.  */
296
2
                            return(FX_FILE_CORRUPT);
297
                        }
298
299
                        /* Setup the relative sector (this is zero for subsequent cluster.  */
300
51
                        relative_sector =  0;
301
302
                        /* Calculate the next logical sector.  */
303
51
                        logical_sector =   ((ULONG)media_ptr -> fx_media_data_sector_start) +
304
51
                            (((ULONG)cluster - FX_FAT_ENTRY_START) *
305
51
                             ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
306
                    }
307
                }
308
                else
309
                {
310
311
                    /* Increment the logical sector.  */
312
16
                    logical_sector++;
313
314
                    /* Determine if the logical sector is valid.  */
315
16
                    if (logical_sector >= (ULONG)(media_ptr -> fx_media_data_sector_start))
316
                    {
317
318
                        /* We have exceeded the root directory.  */
319
320
                        /* Send error message back to caller.  */
321
1
                        return(FX_FILE_CORRUPT);
322
                    }
323
                }
324
325
                /* Read the next logical sector.  */
326
81
                status =  _fx_utility_logical_sector_read(media_ptr, (ULONG64) logical_sector,
327
81
                                                          media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
328
329
                /* Determine if an error occurred.  */
330
81
                if (status != FX_SUCCESS)
331
                {
332
333
                    /* Return the error status.  */
334
1
                    return(status);
335
                }
336
337
                /* Move to the next sector buffer.  */
338
80
                sector_base_ptr = media_ptr -> fx_media_memory_buffer;
339
340
                /* Setup new buffer pointers.  */
341
80
                byte_offset =  0;
342
80
                work_ptr = sector_base_ptr;
343
344
#ifdef FX_ENABLE_FAULT_TOLERANT
345
                /* Initialize data for fault tolerant. */
346
                changed_ptr = work_ptr;
347
                changed_size = 0;
348
                changed_offset = 0;
349
#endif /* FX_ENABLE_FAULT_TOLERANT */
350
            }
351
        }
352
    }
353
354
    /* Check for an error!  */
355
362
    if (u != (unicode_name_length * 2))
356
    {
357
358
        /* Return an error!  */
359
1
        return(FX_FILE_CORRUPT);
360
    }
361
362
#ifdef FX_ENABLE_FAULT_TOLERANT
363
    if (media_ptr -> fx_media_fault_tolerant_enabled)
364
    {
365
366
        /* Redirect this request to log file. */
367
        status = _fx_fault_tolerant_add_dir_log(media_ptr, (ULONG64) logical_sector, changed_offset, changed_ptr, changed_size);
368
    }
369
    else
370
    {
371
#endif /* FX_ENABLE_FAULT_TOLERANT */
372
373
        /* Write the directory sector to the media.  */
374
361
        status =  _fx_utility_logical_sector_write(media_ptr, (ULONG64) logical_sector,
375
                                                   sector_base_ptr, ((ULONG) 1), FX_DIRECTORY_SECTOR);
376
#ifdef FX_ENABLE_FAULT_TOLERANT
377
    }
378
#endif /* FX_ENABLE_FAULT_TOLERANT */
379
380
361
    return(status);
381
}
382