GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 65 / 0 / 65
Functions: 100.0% 1 / 0 / 1
Branches: 100.0% 74 / 0 / 74

fx_media_volume_get_extended.c
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 /** 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
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* _fx_media_volume_get_extended PORTABLE C */
40 /* 6.1.11 */
41 /* AUTHOR */
42 /* */
43 /* William E. Lamie, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* This function reads the volume name stored in the media's boot */
48 /* record or root directory. */
49 /* */
50 /* INPUT */
51 /* */
52 /* media_ptr Media control block pointer */
53 /* volume_name Pointer to destination for */
54 /* the volume name (maximum */
55 /* 11 characters + NULL) */
56 /* volume_name_buffer_length Buffer length for volume_name */
57 /* volume_source Source of volume */
58 /* */
59 /* OUTPUT */
60 /* */
61 /* return status */
62 /* */
63 /* CALLS */
64 /* */
65 /* _fx_utility_logical_sector_read Read directory sector */
66 /* _fx_directory_entry_read Directory entry read */
67 /* */
68 /* CALLED BY */
69 /* */
70 /* Application Code */
71 /* */
72 /**************************************************************************/
73 9207 UINT _fx_media_volume_get_extended(FX_MEDIA *media_ptr, CHAR *volume_name, UINT volume_name_buffer_length, UINT volume_source)
74 {
75
76 UINT status, offset;
77 ULONG i;
78 INT j;
79
80 FX_DIR_ENTRY dir_entry;
81
82
83 /* Clear the volume name. */
84 9207 volume_name[0] = FX_NULL;
85
86 /* Check the media to make sure it is open. */
87
2/2
✓ Branch 2 → 3 taken 9009 times.
✓ Branch 2 → 4 taken 198 times.
9207 if (media_ptr -> fx_media_id != FX_MEDIA_ID)
88 {
89
90 /* Return the media not opened error. */
91 9009 return(FX_MEDIA_NOT_OPEN);
92 }
93
94 /* If trace is enabled, insert this event into the trace buffer. */
95 FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_VOLUME_GET, media_ptr, volume_name, volume_source, 0, FX_TRACE_MEDIA_EVENTS, 0, 0)
96
97 /* Protect against other threads accessing the media. */
98 110 FX_PROTECT
99
100
101 /* Ensure the volume name is NULL initially. */
102 198 volume_name[0] = FX_NULL;
103
104
4/4
✓ Branch 4 → 5 taken 52 times.
✓ Branch 4 → 29 taken 36 times.
✓ Branch 5 → 6 taken 65 times.
✓ Branch 5 → 33 taken 45 times.
198 if (volume_source == FX_DIRECTORY_SECTOR)
105 {
106
107 /* Setup pointer to media name buffer. */
108 117 dir_entry.fx_dir_entry_name = media_ptr -> fx_media_name_buffer;
109
110 /* Clear the short name string. */
111 117 dir_entry.fx_dir_entry_short_name[0] = 0;
112
113 /* Attempt to find the volume name in the root directory. */
114 117 i = 0;
115 do
116 {
117
118 /* Read an entry from the root directory. */
119 810 status = _fx_directory_entry_read(media_ptr, FX_NULL, &i, &dir_entry);
120
121 /* Check for error status. */
122
4/4
✓ Branch 7 → 8 taken 4 times.
✓ Branch 7 → 9 taken 356 times.
✓ Branch 8 → 9 taken 5 times.
✓ Branch 8 → 11 taken 445 times.
810 if (status != FX_SUCCESS)
123 {
124
125 /* Release media protection. */
126 5 FX_UNPROTECT
127
128 /* Return to caller. */
129 9 return(status);
130 }
131
132 /* Check for a volume name. */
133
8/8
✓ Branch 9 → 10 taken 40 times.
✓ Branch 9 → 12 taken 316 times.
✓ Branch 10 → 11 taken 36 times.
✓ Branch 10 → 12 taken 4 times.
✓ Branch 11 → 12 taken 50 times.
✓ Branch 11 → 14 taken 395 times.
✓ Branch 12 → 13 taken 45 times.
✓ Branch 12 → 14 taken 5 times.
801 if ((dir_entry.fx_dir_entry_attributes & FX_VOLUME) && ((UCHAR)dir_entry.fx_dir_entry_name[0] != (UCHAR)FX_DIR_ENTRY_FREE))
134 {
135
136 /* Yes, we have found a previously set volume name. */
137 81 break;
138 }
139
140 /* Move to next directory entry. */
141 720 i++;
142
4/4
✓ Branch 12 → 13 taken 308 times.
✓ Branch 12 → 14 taken 12 times.
✓ Branch 14 → 15 taken 385 times.
✓ Branch 14 → 16 taken 15 times.
720 } while (i < media_ptr -> fx_media_root_directory_entries);
143
144 /* Determine if a volume entry has been found. */
145
4/4
✓ Branch 14 → 15 taken 36 times.
✓ Branch 14 → 29 taken 12 times.
✓ Branch 16 → 17 taken 45 times.
✓ Branch 16 → 33 taken 15 times.
108 if (i < media_ptr -> fx_media_root_directory_entries)
146 {
147
148 /* Read the logical directory sector. */
149 81 status = _fx_utility_logical_sector_read(media_ptr, (ULONG64) dir_entry.fx_dir_entry_log_sector,
150 81 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
151
152 /* Determine if an error occurred. */
153
4/4
✓ Branch 16 → 17 taken 4 times.
✓ Branch 16 → 18 taken 32 times.
✓ Branch 18 → 19 taken 5 times.
✓ Branch 18 → 21 taken 40 times.
81 if (status != FX_SUCCESS)
154 {
155
156 /* Release media protection. */
157 5 FX_UNPROTECT
158
159 /* Return error code. */
160 9 return(status);
161 }
162
163 /* Offset to volume label entry. */
164 72 offset = dir_entry.fx_dir_entry_byte_offset;
165
166
167 /* Skip trailing space characters of volume name. */
168
4/4
✓ Branch 22 → 19 taken 244 times.
✓ Branch 22 → 23 taken 8 times.
✓ Branch 25 → 22 taken 305 times.
✓ Branch 25 → 26 taken 10 times.
567 for (j = 10; j >= 0; j--)
169 {
170
171 /* Check for space character. */
172
4/4
✓ Branch 19 → 20 taken 24 times.
✓ Branch 19 → 21 taken 220 times.
✓ Branch 22 → 23 taken 30 times.
✓ Branch 22 → 24 taken 275 times.
549 if (media_ptr -> fx_media_memory_buffer[offset + (UINT)j] != (UCHAR)' ')
173 {
174
175 /* Last character found. */
176 54 break;
177 }
178 }
179
180 /* Check if the buffer is too short for the name. */
181
4/4
✓ Branch 23 → 24 taken 4 times.
✓ Branch 23 → 25 taken 28 times.
✓ Branch 26 → 27 taken 5 times.
✓ Branch 26 → 28 taken 35 times.
72 if (j >= (INT)volume_name_buffer_length - 1)
182 {
183
184 /* Buffer too short, return error. */
185 9 status = FX_BUFFER_ERROR;
186
187 /* Set character count to fit for the buffer. */
188 9 j = (INT)volume_name_buffer_length - 2;
189 }
190
191 /* NULL terminate the volume name. */
192 72 volume_name[j + 1] = FX_NULL;
193
194 /* Pickup the remaining characters of the volume name from the boot sector. */
195
4/4
✓ Branch 27 → 26 taken 128 times.
✓ Branch 27 → 28 taken 32 times.
✓ Branch 30 → 29 taken 160 times.
✓ Branch 30 → 31 taken 40 times.
360 for (; j >= 0; j--)
196 {
197
198 /* Pickup byte of volume name. */
199 288 volume_name[j] = (CHAR)media_ptr -> fx_media_memory_buffer[offset + (UINT)j];
200 }
201
202 /* Release media protection. */
203 40 FX_UNPROTECT
204
205 /* Return the completion status. */
206 72 return(status);
207 }
208 }
209
210 /* Read volume name from boot record. */
211 /* Read the logical directory sector 0 - we just do this to get a memory_buffer pointer */
212 108 status = _fx_utility_logical_sector_read(media_ptr, ((ULONG64) 0),
213 108 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
214
215 /* Check the return status. */
216
4/4
✓ Branch 30 → 31 taken 4 times.
✓ Branch 30 → 32 taken 44 times.
✓ Branch 34 → 35 taken 5 times.
✓ Branch 34 → 37 taken 55 times.
108 if (status != FX_SUCCESS)
217 {
218
219 /* Release media protection. */
220 5 FX_UNPROTECT
221
222 /* Return the error status. */
223 9 return(status);
224 }
225
226 #ifndef FX_MEDIA_STATISTICS_DISABLE
227
228 /* Increment the number of driver read boot sector requests. */
229 99 media_ptr -> fx_media_driver_boot_read_requests++;
230 #endif
231
232 /* Build the driver request to read the boot record. */
233 99 media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_READ;
234 99 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
235 99 media_ptr -> fx_media_driver_buffer = media_ptr -> fx_media_memory_buffer;
236 99 media_ptr -> fx_media_driver_sectors = 1;
237 99 media_ptr -> fx_media_driver_sector_type = FX_BOOT_SECTOR;
238
239 /* If trace is enabled, insert this event into the trace buffer. */
240 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)
241
242 /* Invoke the driver to read the boot sector. */
243 99 (media_ptr -> fx_media_driver_entry) (media_ptr);
244
245 /* Determine if the request is successful. */
246
4/4
✓ Branch 33 → 34 taken 4 times.
✓ Branch 33 → 35 taken 40 times.
✓ Branch 38 → 39 taken 5 times.
✓ Branch 38 → 41 taken 50 times.
99 if (media_ptr -> fx_media_driver_status)
247 {
248
249 /* Release media protection. */
250 5 FX_UNPROTECT
251
252 /* An error occurred in the driver. */
253 9 return(media_ptr -> fx_media_driver_status);
254 }
255
256 /* Calculate the offset to the volume name based on the type of FAT. */
257
4/4
✓ Branch 35 → 36 taken 16 times.
✓ Branch 35 → 37 taken 24 times.
✓ Branch 41 → 42 taken 20 times.
✓ Branch 41 → 43 taken 30 times.
90 if (media_ptr -> fx_media_32_bit_FAT)
258 {
259
260 /* FAT32 offset to volume name. */
261 36 offset = FX_VOLUME_LABEL_32;
262 }
263 else
264 {
265
266 /* FAT12/16 offset to volume name. */
267 54 offset = FX_VOLUME_LABEL;
268 }
269
270 /* Skip trailing space characters of volume name. */
271
4/4
✓ Branch 42 → 39 taken 204 times.
✓ Branch 42 → 43 taken 4 times.
✓ Branch 48 → 45 taken 255 times.
✓ Branch 48 → 49 taken 5 times.
468 for (j = 10; j >= 0; j--)
272 {
273
274 /* Check for space character. */
275
4/4
✓ Branch 39 → 40 taken 36 times.
✓ Branch 39 → 41 taken 168 times.
✓ Branch 45 → 46 taken 45 times.
✓ Branch 45 → 47 taken 210 times.
459 if (media_ptr -> fx_media_memory_buffer[offset + (UINT)j] != (UCHAR)' ')
276 {
277
278 /* Last character found. */
279 81 break;
280 }
281 }
282
283 /* Check if the buffer is too short for the name. */
284
4/4
✓ Branch 43 → 44 taken 4 times.
✓ Branch 43 → 45 taken 36 times.
✓ Branch 49 → 50 taken 5 times.
✓ Branch 49 → 51 taken 45 times.
90 if (j >= (INT)volume_name_buffer_length - 1)
285 {
286
287 /* Buffer too short, return error. */
288 9 status = FX_BUFFER_ERROR;
289
290 /* Set character count to fit for the buffer. */
291 9 j = (INT)volume_name_buffer_length - 2;
292 }
293
294 /* NULL terminate the volume name. */
295 90 volume_name[j + 1] = FX_NULL;
296
297 /* Pickup the remaining characters of the volume name from the boot sector. */
298
4/4
✓ Branch 47 → 46 taken 232 times.
✓ Branch 47 → 48 taken 40 times.
✓ Branch 53 → 52 taken 290 times.
✓ Branch 53 → 54 taken 50 times.
612 for (; j >= 0; j--)
299 {
300
301 /* Pickup byte of volume name. */
302 522 volume_name[j] = (CHAR)media_ptr -> fx_media_memory_buffer[offset + (UINT)j];
303 }
304
305 /* Release media protection. */
306 50 FX_UNPROTECT
307
308 /* Return the completion status. */
309 90 return(status);
310 }
311
312