GCC Code Coverage Report


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

fx_media_volume_set.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_set PORTABLE C */
40 /* 6.1 */
41 /* AUTHOR */
42 /* */
43 /* William E. Lamie, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* This function sets the volume name to the name supplied by the */
48 /* caller. */
49 /* */
50 /* INPUT */
51 /* */
52 /* media_ptr Media control block pointer */
53 /* volume_name New volume name */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* return status */
58 /* */
59 /* CALLS */
60 /* */
61 /* _fx_directory_entry_read Read a directory entry */
62 /* _fx_utility_logical_sector_read Read directory sector */
63 /* _fx_utility_logical_sector_write Write directory sector */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* Application Code */
68 /* */
69 /**************************************************************************/
70 9253 UINT _fx_media_volume_set(FX_MEDIA *media_ptr, CHAR *volume_name)
71 {
72
73 ULONG i, j;
74 FX_DIR_ENTRY dir_entry, dir_entry1;
75 UINT status, offset;
76 UCHAR *work_ptr;
77 CHAR alpha;
78
79
80 /* Check the media to make sure it is open. */
81
2/2
✓ Branch 2 → 3 taken 9009 times.
✓ Branch 2 → 4 taken 244 times.
9253 if (media_ptr -> fx_media_id != FX_MEDIA_ID)
82 {
83
84 /* Return the media not opened error. */
85 9009 return(FX_MEDIA_NOT_OPEN);
86 }
87
88 244 dir_entry.fx_dir_entry_log_sector = 0;
89 244 dir_entry.fx_dir_entry_byte_offset = 0;
90
91 /* If trace is enabled, insert this event into the trace buffer. */
92 FX_TRACE_IN_LINE_INSERT(FX_TRACE_MEDIA_VOLUME_SET, media_ptr, volume_name, 0, 0, FX_TRACE_MEDIA_EVENTS, 0, 0)
93
94 /* Protect against other threads accessing the media. */
95 136 FX_PROTECT
96
97
98 /* First, check for an invalid volume name. */
99
4/4
✓ Branch 4 → 5 taken 4 times.
✓ Branch 4 → 6 taken 104 times.
✓ Branch 5 → 6 taken 6 times.
✓ Branch 5 → 7 taken 130 times.
244 if (volume_name[0] == 0)
100 {
101
102 /* Yes, volume name is invalid. Return an error. */
103 10 return(FX_INVALID_NAME);
104 }
105
106 /* Read the logical directory sector 0 - we just do this to get a memory_buffer pointer */
107 234 status = _fx_utility_logical_sector_read(media_ptr, ((ULONG64) 0),
108 234 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
109
110 /* Check the read status. */
111
4/4
✓ Branch 7 → 8 taken 4 times.
✓ Branch 7 → 9 taken 100 times.
✓ Branch 8 → 9 taken 5 times.
✓ Branch 8 → 11 taken 125 times.
234 if (status != FX_SUCCESS)
112 {
113
114 /* Release media protection. */
115 5 FX_UNPROTECT
116
117 /* Return the error status. */
118 9 return(status);
119 }
120
121 #ifndef FX_MEDIA_STATISTICS_DISABLE
122
123 /* Increment the number of driver read boot sector requests. */
124 225 media_ptr -> fx_media_driver_boot_read_requests++;
125 #endif
126
127 /* Build a driver request to read the boot record. */
128 225 media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_READ;
129 225 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
130 225 media_ptr -> fx_media_driver_buffer = media_ptr -> fx_media_memory_buffer;
131 225 media_ptr -> fx_media_driver_sectors = 1;
132 225 media_ptr -> fx_media_driver_sector_type = FX_BOOT_SECTOR;
133
134 /* If trace is enabled, insert this event into the trace buffer. */
135 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)
136
137 /* Invoke the driver to read the boot sector. */
138 225 (media_ptr -> fx_media_driver_entry) (media_ptr);
139
140 /* Determine if the request is successful. */
141
4/4
✓ Branch 10 → 11 taken 4 times.
✓ Branch 10 → 12 taken 96 times.
✓ Branch 12 → 13 taken 5 times.
✓ Branch 12 → 15 taken 120 times.
225 if (media_ptr -> fx_media_driver_status)
142 {
143
144 /* Release media protection. */
145 5 FX_UNPROTECT
146
147 /* An error occurred in the driver. */
148 9 return(media_ptr -> fx_media_driver_status);
149 }
150
151 /* Calculate the offset based on the FAT present. */
152
4/4
✓ Branch 12 → 13 taken 20 times.
✓ Branch 12 → 14 taken 76 times.
✓ Branch 15 → 16 taken 25 times.
✓ Branch 15 → 17 taken 95 times.
216 if (media_ptr -> fx_media_32_bit_FAT)
153 {
154
155 /* FAT32 is present. */
156 45 offset = FX_VOLUME_LABEL_32;
157 }
158 else
159 {
160
161 /* FAT12/16 is present. */
162 171 offset = FX_VOLUME_LABEL;
163 }
164
165 /* Loop to store the volume name. */
166
4/4
✓ Branch 22 → 16 taken 588 times.
✓ Branch 22 → 23 taken 88 times.
✓ Branch 25 → 19 taken 735 times.
✓ Branch 25 → 26 taken 110 times.
1521 for (i = 0; volume_name[i]; i++)
167 {
168
169 /* Have we reached the end? */
170
4/4
✓ Branch 16 → 17 taken 8 times.
✓ Branch 16 → 18 taken 580 times.
✓ Branch 19 → 20 taken 10 times.
✓ Branch 19 → 21 taken 725 times.
1323 if (i == 11)
171 {
172
173 18 break;
174 }
175
176 /* Pickup volume name byte. */
177 1305 alpha = volume_name[i];
178
179 /* Determine if alpha needs to be converted to upper case. */
180
8/8
✓ Branch 18 → 19 taken 104 times.
✓ Branch 18 → 21 taken 476 times.
✓ Branch 19 → 20 taken 100 times.
✓ Branch 19 → 21 taken 4 times.
✓ Branch 21 → 22 taken 130 times.
✓ Branch 21 → 24 taken 595 times.
✓ Branch 22 → 23 taken 125 times.
✓ Branch 22 → 24 taken 5 times.
1305 if ((alpha >= 'a') && (alpha <= 'z'))
181 {
182
183 /* Convert alpha to upper case. */
184 225 alpha = (CHAR)((INT)alpha - 0x20);
185 }
186
187 /* Store a byte of the volume name. */
188 1305 media_ptr -> fx_media_memory_buffer[offset + i] = (UCHAR)alpha;
189 }
190
191 /* Now pad with spaces. */
192
4/4
✓ Branch 25 → 24 taken 476 times.
✓ Branch 25 → 26 taken 96 times.
✓ Branch 28 → 27 taken 595 times.
✓ Branch 28 → 29 taken 120 times.
1287 for (; i < 11; i++)
193 {
194
195 /* Append space character to volume name. */
196 1071 media_ptr -> fx_media_memory_buffer[offset + i] = 0x20;
197 }
198
199 #ifndef FX_MEDIA_STATISTICS_DISABLE
200
201 /* Increment the number of driver write boot sector requests. */
202 216 media_ptr -> fx_media_driver_boot_write_requests++;
203 #endif
204
205 /* Write the boot sector with the new volume name. */
206 216 media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_WRITE;
207 216 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
208 216 media_ptr -> fx_media_driver_buffer = media_ptr -> fx_media_memory_buffer;
209 216 media_ptr -> fx_media_driver_sectors = 1;
210 216 media_ptr -> fx_media_driver_sector_type = FX_BOOT_SECTOR;
211
212 /* Set the system write flag since we are writing the boot sector. */
213 216 media_ptr -> fx_media_driver_system_write = FX_TRUE;
214
215 /* If trace is enabled, insert this event into the trace buffer. */
216 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_BOOT_WRITE, media_ptr, media_ptr -> fx_media_memory_buffer, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
217
218 /* Invoke the driver to write the boot sector. */
219 216 (media_ptr -> fx_media_driver_entry) (media_ptr);
220
221 /* Clear the system write flag. */
222 216 media_ptr -> fx_media_driver_system_write = FX_FALSE;
223
224 /* Determine if the request is successful. */
225
4/4
✓ Branch 27 → 28 taken 4 times.
✓ Branch 27 → 29 taken 92 times.
✓ Branch 30 → 31 taken 5 times.
✓ Branch 30 → 33 taken 115 times.
216 if (media_ptr -> fx_media_driver_status)
226 {
227
228 /* Release media protection. */
229 5 FX_UNPROTECT
230
231 /* An error occurred in the driver. */
232 9 return(media_ptr -> fx_media_driver_status);
233 }
234
235 /* Setup pointer to media name buffer. */
236 207 dir_entry1.fx_dir_entry_name = media_ptr -> fx_media_name_buffer;
237
238 /* Clear the short name string. */
239 207 dir_entry1.fx_dir_entry_short_name[0] = 0;
240
241 /* Now we need to find the copy of the volume name in the root directory. */
242 207 i = 0;
243 207 j = media_ptr -> fx_media_root_directory_entries + 1;
244 do
245 {
246
247 /* Read an entry from the root directory. */
248 1404 status = _fx_directory_entry_read(media_ptr, FX_NULL, &i, &dir_entry1);
249
250 /* Check for error status. */
251
4/4
✓ Branch 31 → 32 taken 4 times.
✓ Branch 31 → 33 taken 620 times.
✓ Branch 35 → 36 taken 5 times.
✓ Branch 35 → 38 taken 775 times.
1404 if (status != FX_SUCCESS)
252 {
253
254 /* Release media protection. */
255 5 FX_UNPROTECT
256
257 /* Return to caller. */
258 9 return(status);
259 }
260
261 /* Determine if this is an empty entry. */
262
8/8
✓ Branch 33 → 34 taken 36 times.
✓ Branch 33 → 38 taken 584 times.
✓ Branch 34 → 35 taken 24 times.
✓ Branch 34 → 38 taken 12 times.
✓ Branch 38 → 39 taken 45 times.
✓ Branch 38 → 43 taken 730 times.
✓ Branch 39 → 40 taken 30 times.
✓ Branch 39 → 43 taken 15 times.
1395 if ((dir_entry1.fx_dir_entry_name[0] == (CHAR)FX_DIR_ENTRY_FREE) && (dir_entry1.fx_dir_entry_short_name[0] == 0))
263 {
264
265 /* Yes, this is free entry. Is it the first? */
266
4/4
✓ Branch 35 → 36 taken 20 times.
✓ Branch 35 → 37 taken 4 times.
✓ Branch 40 → 41 taken 25 times.
✓ Branch 40 → 42 taken 5 times.
54 if (i < j)
267 {
268
269 /* Yes, first free entry - remember it. */
270 45 dir_entry = dir_entry1;
271 45 j = i;
272 }
273 }
274 /* Determine if the directory entries are exhausted. */
275
4/4
✓ Branch 38 → 39 taken 40 times.
✓ Branch 38 → 42 taken 556 times.
✓ Branch 43 → 44 taken 50 times.
✓ Branch 43 → 47 taken 695 times.
1341 else if (dir_entry1.fx_dir_entry_name[0] == FX_DIR_ENTRY_DONE)
276 {
277
278 /* Yes, this we are at the end of the directory. Have there
279 been any other free entries? */
280
4/4
✓ Branch 39 → 40 taken 32 times.
✓ Branch 39 → 41 taken 8 times.
✓ Branch 44 → 45 taken 40 times.
✓ Branch 44 → 46 taken 10 times.
90 if (i < j)
281 {
282
283 /* No, we need to remember this as the free entry. */
284 72 dir_entry = dir_entry1;
285 72 j = i;
286 }
287 90 break;
288 }
289 /* Check for a volume name. */
290
4/4
✓ Branch 42 → 43 taken 36 times.
✓ Branch 42 → 44 taken 520 times.
✓ Branch 47 → 48 taken 45 times.
✓ Branch 47 → 49 taken 650 times.
1251 else if (dir_entry1.fx_dir_entry_attributes & FX_VOLUME)
291 {
292
293 /* Yes, we have found a previously set volume name - use this entry. */
294 81 dir_entry = dir_entry1;
295 81 j = i;
296 81 break;
297 }
298
299 /* Move to next directory entry. */
300 1224 i++;
301
4/4
✓ Branch 44 → 45 taken 532 times.
✓ Branch 44 → 46 taken 12 times.
✓ Branch 49 → 50 taken 665 times.
✓ Branch 49 → 51 taken 15 times.
1224 } while (i < media_ptr -> fx_media_root_directory_entries);
302
303 /* Determine if a volume entry was not found and there are no more empty slots. */
304
4/4
✓ Branch 46 → 47 taken 12 times.
✓ Branch 46 → 49 taken 76 times.
✓ Branch 51 → 52 taken 15 times.
✓ Branch 51 → 55 taken 95 times.
198 if (i == media_ptr -> fx_media_root_directory_entries)
305 {
306
307 /* Determine if there was a free or previous volume name. */
308
4/4
✓ Branch 47 → 48 taken 4 times.
✓ Branch 47 → 49 taken 8 times.
✓ Branch 52 → 53 taken 5 times.
✓ Branch 52 → 55 taken 10 times.
27 if (j == (media_ptr -> fx_media_root_directory_entries + 1))
309 {
310
311 /* No, nothing was available in the root directory. */
312
313 /* Release media protection. */
314 5 FX_UNPROTECT
315
316 /* No, existing volume name or space in the root directly was found, return an error. */
317 9 return(FX_MEDIA_INVALID);
318 }
319 }
320
321 /* Now set the volume name and attribute. */
322
323 /* Read the logical directory sector. */
324 189 status = _fx_utility_logical_sector_read(media_ptr, (ULONG64) dir_entry.fx_dir_entry_log_sector,
325 189 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_BOOT_SECTOR);
326
327 /* Check the status of reading the directory entry. */
328
4/4
✓ Branch 50 → 51 taken 4 times.
✓ Branch 50 → 52 taken 80 times.
✓ Branch 56 → 57 taken 5 times.
✓ Branch 56 → 59 taken 100 times.
189 if (status != FX_SUCCESS)
329 {
330
331 /* Release media protection. */
332 5 FX_UNPROTECT
333
334 /* Return the error status. */
335 9 return(status);
336 }
337
338 /* Calculate pointer into directory buffer. */
339 180 work_ptr = media_ptr -> fx_media_memory_buffer +
340 180 (UINT)dir_entry.fx_dir_entry_byte_offset;
341
342 /* Copy the volume name into the directory entry. */
343
4/4
✓ Branch 59 → 53 taken 532 times.
✓ Branch 59 → 60 taken 72 times.
✓ Branch 66 → 60 taken 665 times.
✓ Branch 66 → 67 taken 90 times.
1359 for (i = 0; volume_name[i]; i++)
344 {
345
346 /* Have we reached the end? */
347
4/4
✓ Branch 53 → 54 taken 8 times.
✓ Branch 53 → 55 taken 524 times.
✓ Branch 60 → 61 taken 10 times.
✓ Branch 60 → 62 taken 655 times.
1197 if (i == 11)
348 {
349
350 18 break;
351 }
352
353 /* Pickup volume name byte. */
354 1179 alpha = volume_name[i];
355
356 /* Determine if alpha needs to be converted to upper case. */
357
8/8
✓ Branch 55 → 56 taken 104 times.
✓ Branch 55 → 58 taken 420 times.
✓ Branch 56 → 57 taken 100 times.
✓ Branch 56 → 58 taken 4 times.
✓ Branch 62 → 63 taken 130 times.
✓ Branch 62 → 65 taken 525 times.
✓ Branch 63 → 64 taken 125 times.
✓ Branch 63 → 65 taken 5 times.
1179 if ((alpha >= 'a') && (alpha <= 'z'))
358 {
359
360 /* Convert alpha to upper case. */
361 225 alpha = (CHAR)((INT)alpha - 0x20);
362 }
363
364 /* Store volume name. */
365 1179 work_ptr[i] = (UCHAR)alpha;
366 }
367
368 /* Pad with space characters. */
369
4/4
✓ Branch 62 → 61 taken 356 times.
✓ Branch 62 → 63 taken 80 times.
✓ Branch 69 → 68 taken 445 times.
✓ Branch 69 → 70 taken 100 times.
981 for (; i < 11; i++)
370 {
371 801 work_ptr[i] = 0x20;
372 }
373
374 /* Set the appropriate attributes. */
375 180 work_ptr[11] = FX_VOLUME | FX_ARCHIVE;
376
377 /* Set the other parts of the volume entry. */
378
379 /* Clear the hi word of cluster. */
380 180 work_ptr[20] = 0;
381 180 work_ptr[21] = 0;
382
383 /* Clear the low word of cluster. */
384 180 work_ptr[26] = 0;
385 180 work_ptr[27] = 0;
386
387 /* Clear the file size. */
388 180 work_ptr[28] = 0;
389 180 work_ptr[29] = 0;
390 180 work_ptr[30] = 0;
391 180 work_ptr[31] = 0;
392
393 /* Write the directory sector to the media. */
394 180 status = _fx_utility_logical_sector_write(media_ptr, (ULONG64) dir_entry.fx_dir_entry_log_sector,
395 180 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
396
397 /* Release media protection. */
398 100 FX_UNPROTECT
399
400 /* Return the status. */
401 180 return(status);
402 }
403
404