GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_media_volume_get_extended.c Lines: 65 65 100.0 %
Date: 2024-01-10 21:53:23 Branches: 38 38 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
/**   Media                                                               */
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_system.h"
30
#include "fx_directory.h"
31
#include "fx_media.h"
32
#include "fx_utility.h"
33
#ifdef FX_ENABLE_EXFAT
34
#include "fx_directory_exFAT.h"
35
#endif /* FX_ENABLE_EXFAT */
36
37
38
/**************************************************************************/
39
/*                                                                        */
40
/*  FUNCTION                                               RELEASE        */
41
/*                                                                        */
42
/*    _fx_media_volume_get_extended                       PORTABLE C      */
43
/*                                                           6.1.11       */
44
/*  AUTHOR                                                                */
45
/*                                                                        */
46
/*    William E. Lamie, Microsoft Corporation                             */
47
/*                                                                        */
48
/*  DESCRIPTION                                                           */
49
/*                                                                        */
50
/*    This function reads the volume name stored in the media's boot      */
51
/*    record or root directory.                                           */
52
/*                                                                        */
53
/*  INPUT                                                                 */
54
/*                                                                        */
55
/*    media_ptr                             Media control block pointer   */
56
/*    volume_name                           Pointer to destination for    */
57
/*                                            the volume name (maximum    */
58
/*                                            11 characters + NULL)       */
59
/*    volume_name_buffer_length             Buffer length for volume_name */
60
/*    volume_source                         Source of volume              */
61
/*                                                                        */
62
/*  OUTPUT                                                                */
63
/*                                                                        */
64
/*    return status                                                       */
65
/*                                                                        */
66
/*  CALLS                                                                 */
67
/*                                                                        */
68
/*    _fx_utility_logical_sector_read       Read directory sector         */
69
/*    _fx_directory_entry_read              Directory entry read          */
70
/*                                                                        */
71
/*  CALLED BY                                                             */
72
/*                                                                        */
73
/*    Application Code                                                    */
74
/*                                                                        */
75
/*  RELEASE HISTORY                                                       */
76
/*                                                                        */
77
/*    DATE              NAME                      DESCRIPTION             */
78
/*                                                                        */
79
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
80
/*  09-30-2020     William E. Lamie         Modified comment(s),          */
81
/*                                            resulting in version 6.1    */
82
/*  04-25-2022     Bhupendra Naphade        Modified comment(s), and      */
83
/*                                            updated check for           */
84
/*                                            volume name,                */
85
/*                                            resulting in version 6.1.11 */
86
/*                                                                        */
87
/**************************************************************************/
88
1023
UINT  _fx_media_volume_get_extended(FX_MEDIA *media_ptr, CHAR *volume_name, UINT volume_name_buffer_length, UINT volume_source)
89
{
90
91
UINT         status, offset;
92
ULONG        i;
93
INT          j;
94
95
#ifdef FX_ENABLE_EXFAT
96
ULONG        character_count;
97
#endif /* FX_ENABLE_EXFAT */
98
FX_DIR_ENTRY dir_entry;
99
100
101
    /* Clear the volume name.  */
102
1023
    volume_name[0] =  FX_NULL;
103
104
    /* Check the media to make sure it is open.  */
105
1023
    if (media_ptr -> fx_media_id != FX_MEDIA_ID)
106
    {
107
108
        /* Return the media not opened error.  */
109
1001
        return(FX_MEDIA_NOT_OPEN);
110
    }
111
112
    /* If trace is enabled, insert this event into the trace buffer.  */
113
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_VOLUME_GET, media_ptr, volume_name, volume_source, 0, FX_TRACE_MEDIA_EVENTS, 0, 0)
114
115
    /* Protect against other threads accessing the media.  */
116
22
    FX_PROTECT
117
118
#ifdef FX_ENABLE_EXFAT
119
    if (media_ptr -> fx_media_FAT_type == FX_exFAT)
120
    {
121
        volume_source = FX_DIRECTORY_SECTOR;
122
    }
123
#endif /* FX_ENABLE_EXFAT */
124
125
    /* Ensure the volume name is NULL initially.  */
126
22
    volume_name[0] =  FX_NULL;
127
128
22
    if (volume_source == FX_DIRECTORY_SECTOR)
129
    {
130
131
        /* Setup pointer to media name buffer.  */
132
13
        dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer;
133
134
        /* Clear the short name string.  */
135
13
        dir_entry.fx_dir_entry_short_name[0] =  0;
136
137
        /* Attempt to find the volume name in the root directory.  */
138
13
        i =  0;
139
        do
140
        {
141
142
            /* Read an entry from the root directory.  */
143
90
            status =  _fx_directory_entry_read(media_ptr, FX_NULL, &i, &dir_entry);
144
145
            /* Check for error status.  */
146
90
            if (status != FX_SUCCESS)
147
            {
148
149
                /* Release media protection.  */
150
1
                FX_UNPROTECT
151
152
                /* Return to caller.  */
153
1
                return(status);
154
            }
155
156
            /* Check for a volume name.  */
157
#ifdef FX_ENABLE_EXFAT
158
            if (((media_ptr -> fx_media_FAT_type == FX_exFAT) && ((dir_entry.fx_dir_entry_attributes & FX_VOLUME) || (dir_entry.fx_dir_entry_type == FX_EXFAT_DIR_ENTRY_TYPE_VOLUME_LABEL)))
159
                    || ((media_ptr -> fx_media_FAT_type != FX_exFAT) && (dir_entry.fx_dir_entry_attributes & FX_VOLUME) && ((UCHAR)dir_entry.fx_dir_entry_name[0] != (UCHAR)FX_DIR_ENTRY_FREE)))
160
#else
161

89
            if ((dir_entry.fx_dir_entry_attributes & FX_VOLUME) && ((UCHAR)dir_entry.fx_dir_entry_name[0] != (UCHAR)FX_DIR_ENTRY_FREE))
162
#endif /* FX_ENABLE_EXFAT */
163
            {
164
165
                /* Yes, we have found a previously set volume name.  */
166
9
                break;
167
            }
168
169
            /* Move to next directory entry.  */
170
80
            i++;
171
80
        } while (i < media_ptr -> fx_media_root_directory_entries);
172
173
        /* Determine if a volume entry has been found.  */
174
12
        if (i < media_ptr -> fx_media_root_directory_entries)
175
        {
176
177
            /* Read the logical directory sector.  */
178
9
            status =  _fx_utility_logical_sector_read(media_ptr, (ULONG64) dir_entry.fx_dir_entry_log_sector,
179
9
                                                      media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
180
181
            /* Determine if an error occurred.  */
182
9
            if (status != FX_SUCCESS)
183
            {
184
185
                /* Release media protection.  */
186
1
                FX_UNPROTECT
187
188
                /* Return error code.  */
189
1
                return(status);
190
            }
191
192
            /* Offset to volume label entry.  */
193
8
            offset = dir_entry.fx_dir_entry_byte_offset;
194
195
#ifdef FX_ENABLE_EXFAT
196
            if (media_ptr -> fx_media_FAT_type == FX_exFAT)
197
            {
198
199
                /* Read character count of volume label.  */
200
                character_count = media_ptr -> fx_media_memory_buffer[offset + FX_EXFAT_CHAR_COUNT];
201
202
                /* Check if the buffer is too short for the name.  */
203
                if (character_count >= volume_name_buffer_length)
204
                {
205
206
                    /* Buffer too short, return error.  */
207
                    status =  FX_BUFFER_ERROR;
208
209
                    /* Set character count to fit for the buffer.  */
210
                    character_count = volume_name_buffer_length - 1;
211
                }
212
213
                /* Move to volume label field.  */
214
                offset += FX_EXFAT_VOLUME_LABEL;
215
216
                for (i = 0; i < character_count; i++)
217
                {
218
219
                    /* Read one character of volume label.  */
220
                    volume_name[i] = (CHAR)_fx_utility_16_unsigned_read(&media_ptr -> fx_media_memory_buffer[offset]);
221
222
                    /* Move to next character.  */
223
                    offset += 2;
224
                }
225
226
                /* NULL terminate the volume name.  */
227
                volume_name[i] =  FX_NULL;
228
            }
229
            else
230
            {
231
#endif /* FX_ENABLE_EXFAT */
232
233
                /* Skip trailing space characters of volume name. */
234
63
                for (j = 10; j >= 0; j--)
235
                {
236
237
                    /* Check for space character.  */
238
61
                    if (media_ptr -> fx_media_memory_buffer[offset + (UINT)j] != (UCHAR)' ')
239
                    {
240
241
                        /* Last character found. */
242
6
                        break;
243
                    }
244
                }
245
246
                /* Check if the buffer is too short for the name.  */
247
8
                if (j >= (INT)volume_name_buffer_length - 1)
248
                {
249
250
                    /* Buffer too short, return error.  */
251
1
                    status =  FX_BUFFER_ERROR;
252
253
                    /* Set character count to fit for the buffer.  */
254
1
                    j = (INT)volume_name_buffer_length - 2;
255
                }
256
257
                /* NULL terminate the volume name.  */
258
8
                volume_name[j + 1] =  FX_NULL;
259
260
                /* Pickup the remaining characters of the volume name from the boot sector.  */
261
40
                for (; j >= 0; j--)
262
                {
263
264
                    /* Pickup byte of volume name.  */
265
32
                    volume_name[j] =  (CHAR)media_ptr -> fx_media_memory_buffer[offset + (UINT)j];
266
                }
267
#ifdef FX_ENABLE_EXFAT
268
            }
269
#endif /* FX_ENABLE_EXFAT */
270
271
            /* Release media protection.  */
272
8
            FX_UNPROTECT
273
274
            /* Return the completion status.  */
275
8
            return(status);
276
        }
277
    }
278
279
    /* Read volume name from boot record.  */
280
    /* Read the logical directory sector 0 - we just do this to get a memory_buffer pointer */
281
12
    status =  _fx_utility_logical_sector_read(media_ptr, ((ULONG64) 0),
282
12
                                              media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
283
284
    /* Check the return status.  */
285
12
    if (status != FX_SUCCESS)
286
    {
287
288
        /* Release media protection.  */
289
1
        FX_UNPROTECT
290
291
        /* Return the error status.  */
292
1
        return(status);
293
    }
294
295
#ifndef FX_MEDIA_STATISTICS_DISABLE
296
297
    /* Increment the number of driver read boot sector requests.  */
298
11
    media_ptr -> fx_media_driver_boot_read_requests++;
299
#endif
300
301
    /* Build the driver request to read the boot record.  */
302
11
    media_ptr -> fx_media_driver_request =      FX_DRIVER_BOOT_READ;
303
11
    media_ptr -> fx_media_driver_status =       FX_IO_ERROR;
304
11
    media_ptr -> fx_media_driver_buffer =       media_ptr -> fx_media_memory_buffer;
305
11
    media_ptr -> fx_media_driver_sectors =      1;
306
11
    media_ptr -> fx_media_driver_sector_type =  FX_BOOT_SECTOR;
307
308
    /* If trace is enabled, insert this event into the trace buffer.  */
309
    FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_BOOT_READ, media_ptr, media_ptr -> fx_media_memory_buffer, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
310
311
    /* Invoke the driver to read the boot sector.  */
312
11
    (media_ptr -> fx_media_driver_entry) (media_ptr);
313
314
    /* Determine if the request is successful.  */
315
11
    if (media_ptr -> fx_media_driver_status)
316
    {
317
318
        /* Release media protection.  */
319
1
        FX_UNPROTECT
320
321
        /* An error occurred in the driver.  */
322
1
        return(media_ptr -> fx_media_driver_status);
323
    }
324
325
    /* Calculate the offset to the volume name based on the type of FAT.  */
326
10
    if (media_ptr -> fx_media_32_bit_FAT)
327
    {
328
329
        /* FAT32 offset to volume name.  */
330
4
        offset =  FX_VOLUME_LABEL_32;
331
    }
332
    else
333
    {
334
335
        /* FAT12/16 offset to volume name.  */
336
6
        offset =  FX_VOLUME_LABEL;
337
    }
338
339
    /* Skip trailing space characters of volume name. */
340
52
    for (j = 10; j >= 0; j--)
341
    {
342
343
        /* Check for space character.  */
344
51
        if (media_ptr -> fx_media_memory_buffer[offset + (UINT)j] != (UCHAR)' ')
345
        {
346
347
            /* Last character found. */
348
9
            break;
349
        }
350
    }
351
352
    /* Check if the buffer is too short for the name.  */
353
10
    if (j >= (INT)volume_name_buffer_length - 1)
354
    {
355
356
        /* Buffer too short, return error.  */
357
1
        status =  FX_BUFFER_ERROR;
358
359
        /* Set character count to fit for the buffer.  */
360
1
        j = (INT)volume_name_buffer_length - 2;
361
    }
362
363
    /* NULL terminate the volume name.  */
364
10
    volume_name[j + 1] =  FX_NULL;
365
366
    /* Pickup the remaining characters of the volume name from the boot sector.  */
367
68
    for (; j >= 0; j--)
368
    {
369
370
        /* Pickup byte of volume name.  */
371
58
        volume_name[j] =  (CHAR)media_ptr -> fx_media_memory_buffer[offset + (UINT)j];
372
    }
373
374
    /* Release media protection.  */
375
10
    FX_UNPROTECT
376
377
    /* Return the completion status.  */
378
10
    return(status);
379
}
380