GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_unicode_directory_entry_change.c Lines: 74 74 100.0 %
Date: 2024-01-10 21:53:23 Branches: 40 40 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_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
/*  RELEASE HISTORY                                                       */
73
/*                                                                        */
74
/*    DATE              NAME                      DESCRIPTION             */
75
/*                                                                        */
76
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
77
/*  09-30-2020     William E. Lamie         Modified comment(s),          */
78
/*                                            resulting in version 6.1    */
79
/*                                                                        */
80
/**************************************************************************/
81
371
UINT  _fx_unicode_directory_entry_change(FX_MEDIA *media_ptr, FX_DIR_ENTRY *entry_ptr, UCHAR *unicode_name, ULONG unicode_name_length)
82
{
83
84
UCHAR *work_ptr, *sector_base_ptr;
85
UINT   status;
86
UINT   i, j, k, u, card, lfn_entries;
87
UCHAR  eof_marker;
88
ULONG  logical_sector, relative_sector;
89
ULONG  byte_offset;
90
ULONG  cluster, next_cluster;
91
92
#ifdef FX_ENABLE_FAULT_TOLERANT
93
UCHAR *changed_ptr;
94
UINT   changed_size;
95
ULONG  changed_offset;
96
#endif /* FX_ENABLE_FAULT_TOLERANT */
97
98
99
#ifndef FX_MEDIA_STATISTICS_DISABLE
100
101
    /* Increment the number of directory entry write requests.  */
102
371
    media_ptr -> fx_media_directory_entry_writes++;
103
#endif
104
105
    /* Pickup the byte offset of the entry.  */
106
371
    byte_offset = entry_ptr -> fx_dir_entry_byte_offset;
107
108
    /* Pickup the logical sector of the entry.  */
109
371
    logical_sector = (ULONG)entry_ptr -> fx_dir_entry_log_sector;
110
111
    /* Figure out where what cluster we are in.  */
112
371
    if (logical_sector >= (ULONG)(media_ptr -> fx_media_data_sector_start))
113
    {
114
115
        /* Calculate the cluster that this logical sector is in.  */
116
260
        cluster =  (logical_sector - media_ptr -> fx_media_data_sector_start) / (media_ptr -> fx_media_sectors_per_cluster) + FX_FAT_ENTRY_START;
117
118
        /* Calculate the relative cluster.  */
119
260
        relative_sector =  logical_sector -  (((ULONG)media_ptr -> fx_media_data_sector_start) +
120
260
                                              (((ULONG)cluster - FX_FAT_ENTRY_START) *
121
260
                                               ((ULONG)media_ptr -> fx_media_sectors_per_cluster)));
122
    }
123
    else
124
    {
125
126
        /* Clear the cluster and the relative sector.  */
127
111
        cluster =  0;
128
111
        relative_sector =  0;
129
    }
130
131
    /* Read the logical directory sector.  */
132
371
    status =  _fx_utility_logical_sector_read(media_ptr, (ULONG64) entry_ptr -> fx_dir_entry_log_sector,
133
371
                                              media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
134
135
    /* Determine if an error occurred.  */
136
371
    if (status != FX_SUCCESS)
137
    {
138
139
        /* Return the error status.  */
140
4
        return(status);
141
    }
142
143
    /* Setup a pointer into the buffer.  */
144
367
    sector_base_ptr = (UCHAR *)media_ptr -> fx_media_memory_buffer;
145
367
    work_ptr =  sector_base_ptr + (UINT)entry_ptr -> fx_dir_entry_byte_offset;
146
147
    /* Initialize the unicode index.  */
148
367
    u =  0;
149
150
#ifdef FX_ENABLE_FAULT_TOLERANT
151
    /* Initialize data for fault tolerant. */
152
    changed_ptr = work_ptr;
153
    changed_size = 0;
154
    changed_offset = entry_ptr -> fx_dir_entry_byte_offset;
155
#endif /* FX_ENABLE_FAULT_TOLERANT */
156
157
    /* Check for a valid long name.  */
158
367
    if ((0x40 & (*work_ptr)))
159
    {
160
161
        /* Get the lower 5 bit containing the cardinality.  */
162
366
        card = (*work_ptr & (UCHAR)0x1f);
163
366
        lfn_entries =  card;
164
165
        /* Loop through the file name.  */
166
847
        for (j = 0; j < lfn_entries; j++)
167
        {
168
169
            /* Clear the eof marker.  */
170
486
            eof_marker =  0;
171
172
            /* Loop through file name fields.  */
173
8262
            for (i = 1, k = (26 * (card - 1)) & 0xFFFFFFFF; i < FX_DIR_ENTRY_SIZE; i += 2)
174
            {
175
176
                /* Process relative to specific fields.  */
177

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

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