GCC Code Coverage Report


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

fx_file_open.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 /** File */
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_file.h"
32 #include "fx_utility.h"
33
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* _fx_file_open PORTABLE C */
40 /* 6.1 */
41 /* AUTHOR */
42 /* */
43 /* William E. Lamie, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* This function first attempts to find the specified file. If found, */
48 /* the open request is validated and the file is opened. During the */
49 /* opening process, all of the FAT entries for this file are examined */
50 /* for their integrity. */
51 /* */
52 /* INPUT */
53 /* */
54 /* media_ptr Media control block pointer */
55 /* file_ptr File control block pointer */
56 /* file_name Name pointer */
57 /* open_type Type of open requested */
58 /* */
59 /* OUTPUT */
60 /* */
61 /* return status */
62 /* */
63 /* CALLS */
64 /* */
65 /* _fx_directory_search Search for the file name in */
66 /* the directory structure */
67 /* _fx_utility_FAT_entry_read Read a FAT entry */
68 /* */
69 /* CALLED BY */
70 /* */
71 /* Application Code */
72 /* */
73 /**************************************************************************/
74 6972280 UINT _fx_file_open(FX_MEDIA *media_ptr, FX_FILE *file_ptr, CHAR *file_name, UINT open_type)
75 {
76
77 UINT status;
78 #ifndef FX_DISABLE_CONSECUTIVE_DETECT
79 UINT leading_consecutive;
80 #endif /* FX_DISABLE_CONSECUTIVE_DETECT */
81 ULONG cluster;
82 6972280 ULONG contents = 0;
83 ULONG open_count;
84 FX_FILE *tail_ptr;
85 FX_FILE *search_ptr;
86 ULONG bytes_per_cluster;
87 UINT last_cluster;
88 ULONG cluster_count;
89 ULONG64 bytes_available;
90 ULONG64 bytes_remaining;
91 ULONG fat_last;
92 #ifndef FX_DISABLE_FAST_OPEN
93 UINT fast_open;
94 #endif /* FX_DISABLE_FAST_OPEN */
95 UCHAR not_a_file_attr;
96
97
98 /* Check the media to make sure it is open. */
99
2/2
✓ Branch 2 → 3 taken 691 times.
✓ Branch 2 → 4 taken 6971589 times.
6972280 if (media_ptr -> fx_media_id != FX_MEDIA_ID)
100 {
101
102 /* Return the media not opened error. */
103 691 return(FX_MEDIA_NOT_OPEN);
104 }
105
106 #ifndef FX_MEDIA_STATISTICS_DISABLE
107
108 /* Increment the number of times this service has been called. */
109 6971589 media_ptr -> fx_media_file_opens++;
110 #endif
111
112 /* Clear the notify function. */
113 6971589 file_ptr -> fx_file_write_notify = FX_NULL;
114
115 /* Determine the type of FAT and setup variables accordingly. */
116
2/2
✓ Branch 4 → 5 taken 6830664 times.
✓ Branch 4 → 6 taken 140925 times.
6971589 if (media_ptr -> fx_media_32_bit_FAT)
117 {
118 6830664 fat_last = FX_LAST_CLUSTER_1_32;
119 6830664 not_a_file_attr = FX_DIRECTORY | FX_VOLUME;
120 }
121 else
122 {
123 140925 fat_last = FX_LAST_CLUSTER_1;
124 140925 not_a_file_attr = FX_DIRECTORY | FX_VOLUME;
125 }
126
127 #ifndef FX_DISABLE_FAST_OPEN
128 /* Determine if a fast open is selected. */
129
2/2
✓ Branch 7 → 8 taken 18 times.
✓ Branch 7 → 9 taken 6971571 times.
6971589 if (open_type == FX_OPEN_FOR_READ_FAST)
130 {
131
132 /* Yes, convert the open type to a standard read. */
133 18 open_type = FX_OPEN_FOR_READ;
134
135 /* Set the open fast flag. */
136 18 fast_open = FX_TRUE;
137 }
138 else
139 {
140
141 /* A fast open is not selected, set the flag to false. */
142 6971571 fast_open = FX_FALSE;
143 }
144 #endif /* FX_DISABLE_FAST_OPEN */
145
146 /* If trace is enabled, register this object. */
147 FX_TRACE_OBJECT_REGISTER(FX_TRACE_OBJECT_TYPE_FILE, file_ptr, file_name, 0, 0)
148
149 /* If trace is enabled, insert this event into the trace buffer. */
150 FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_OPEN, media_ptr, file_ptr, file_name, open_type, FX_TRACE_FILE_EVENTS, 0, 0)
151
152 /* Protect against other threads accessing the media. */
153 6895829 FX_PROTECT
154
155 /* Setup file name pointer. */
156 6971588 file_ptr -> fx_file_dir_entry.fx_dir_entry_name = file_ptr -> fx_file_name_buffer;
157 6971588 file_ptr -> fx_file_dir_entry.fx_dir_entry_short_name[0] = 0;
158
159 /* Search the system for the supplied file name. */
160 6971588 status = _fx_directory_search(media_ptr, file_name, &(file_ptr -> fx_file_dir_entry), FX_NULL, FX_NULL);
161
162 /* Determine if the search was successful. */
163
4/4
✓ Branch 11 → 12 taken 50 times.
✓ Branch 11 → 13 taken 75710 times.
✓ Branch 12 → 13 taken 123 times.
✓ Branch 12 → 15 taken 6895705 times.
6971588 if (status != FX_SUCCESS)
164 {
165
166 /* Release media protection. */
167 123 FX_UNPROTECT
168
169 /* Return the error code. */
170 173 return(status);
171 }
172
173 /* Check to make sure the found entry is a file. */
174
4/4
✓ Branch 13 → 14 taken 4 times.
✓ Branch 13 → 15 taken 75706 times.
✓ Branch 15 → 16 taken 5 times.
✓ Branch 15 → 18 taken 6895700 times.
6971415 if (file_ptr -> fx_file_dir_entry.fx_dir_entry_attributes & not_a_file_attr)
175 {
176
177 /* Release media protection. */
178 5 FX_UNPROTECT
179
180 /* Return the not a file error code. */
181 9 return(FX_NOT_A_FILE);
182 }
183
184 #ifdef FX_SINGLE_OPEN_LEGACY
185 /* Check to make sure the access is okay. */
186 if (open_type == FX_OPEN_FOR_READ)
187 {
188
189 /* Check the list of open files for others open for writing. */
190 open_count = media_ptr -> fx_media_opened_file_count;
191 search_ptr = media_ptr -> fx_media_opened_file_list;
192 while (open_count)
193 {
194
195 /* Look at each opened file to see if the same file is opened
196 for writing. */
197 if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector ==
198 file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) &&
199 (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset ==
200 file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset) &&
201 (search_ptr -> fx_file_open_mode))
202 {
203
204 /* Release media protection. */
205 FX_UNPROTECT
206
207 /* The file has been opened for writing by a previous call. */
208 return(FX_ACCESS_ERROR);
209 }
210
211 /* Adjust the pointer and decrement the search count. */
212 search_ptr = search_ptr -> fx_file_opened_next;
213 open_count--;
214 }
215 }
216 else
217 #else
218
4/4
✓ Branch 15 → 16 taken 71612 times.
✓ Branch 15 → 27 taken 4094 times.
✓ Branch 18 → 19 taken 3489345 times.
✓ Branch 18 → 33 taken 3406355 times.
6971406 if (open_type == FX_OPEN_FOR_WRITE)
219 #endif
220 {
221
222 /* A open for write request is present, check the file attributes
223 and the list of open files for any other open instance of
224 this file. */
225
4/4
✓ Branch 16 → 17 taken 4 times.
✓ Branch 16 → 18 taken 71608 times.
✓ Branch 19 → 20 taken 5 times.
✓ Branch 19 → 22 taken 3489340 times.
3560957 if (media_ptr -> fx_media_driver_write_protect)
226 {
227
228 /* Release media protection. */
229 5 FX_UNPROTECT
230
231 /* Return write protect error. */
232 9 return(FX_WRITE_PROTECT);
233 }
234
235
4/4
✓ Branch 18 → 19 taken 4 times.
✓ Branch 18 → 20 taken 71604 times.
✓ Branch 22 → 23 taken 5 times.
✓ Branch 22 → 25 taken 3489335 times.
3560948 if (file_ptr -> fx_file_dir_entry.fx_dir_entry_attributes & (UCHAR)(FX_READ_ONLY))
236 {
237
238 /* Release media protection. */
239 5 FX_UNPROTECT
240
241 /* Return the not a file error code. */
242 9 return(FX_ACCESS_ERROR);
243 }
244
245 /* Also search the opened files to see if this file is currently
246 opened. */
247 3560939 open_count = media_ptr -> fx_media_opened_file_count;
248 3560939 search_ptr = media_ptr -> fx_media_opened_file_list;
249
4/4
✓ Branch 26 → 21 taken 268236 times.
✓ Branch 26 → 27 taken 71600 times.
✓ Branch 32 → 26 taken 335295 times.
✓ Branch 32 → 33 taken 3489330 times.
4164461 while (open_count)
250 {
251
252 /* Look at each opened file to see if the same file is already opened. */
253 #ifdef FX_SINGLE_OPEN_LEGACY
254 if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector ==
255 file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) &&
256 (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset ==
257 file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset))
258 #else
259 /* Look at each opened file to see if the same file is already opened
260 for writing. */
261 603531 if ((search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector ==
262
4/4
✓ Branch 21 → 22 taken 264248 times.
✓ Branch 21 → 25 taken 3988 times.
✓ Branch 26 → 27 taken 330310 times.
✓ Branch 26 → 31 taken 4985 times.
603531 file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) &&
263 594558 (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset ==
264
4/4
✓ Branch 22 → 23 taken 28 times.
✓ Branch 22 → 25 taken 264220 times.
✓ Branch 27 → 28 taken 35 times.
✓ Branch 27 → 31 taken 330275 times.
594558 file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset) &&
265
4/4
✓ Branch 23 → 24 taken 4 times.
✓ Branch 23 → 25 taken 24 times.
✓ Branch 28 → 29 taken 5 times.
✓ Branch 28 → 31 taken 30 times.
63 (search_ptr -> fx_file_open_mode == FX_OPEN_FOR_WRITE))
266 #endif
267 {
268
269 /* Release media protection. */
270 5 FX_UNPROTECT
271
272 /* The file is currently open. */
273 9 return(FX_ACCESS_ERROR);
274 }
275
276 /* Adjust the pointer and decrement the search count. */
277 603522 search_ptr = search_ptr -> fx_file_opened_next;
278 603522 open_count--;
279 }
280 }
281
282 /* At this point, we are ready to walk list of clusters to setup the
283 initial condition of this file as well as to verify its integrity. */
284 6971379 cluster = file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster;
285 6971379 bytes_remaining = file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size;
286 6971379 bytes_per_cluster = ((ULONG)media_ptr -> fx_media_bytes_per_sector) *
287 6971379 ((ULONG)media_ptr -> fx_media_sectors_per_cluster);
288 6971379 file_ptr -> fx_file_current_physical_cluster = 0;
289
290 /* Check for invalid value. */
291
4/4
✓ Branch 27 → 28 taken 4 times.
✓ Branch 27 → 29 taken 75690 times.
✓ Branch 33 → 34 taken 5 times.
✓ Branch 33 → 36 taken 6895680 times.
6971379 if (bytes_per_cluster == 0)
292 {
293
294 /* Release media protection. */
295 5 FX_UNPROTECT
296
297 /* Invalid media, return error. */
298 9 return(FX_MEDIA_INVALID);
299 }
300
301 6971370 last_cluster = 0;
302 6971370 cluster_count = 0;
303
304 #ifndef FX_DISABLE_CONSECUTIVE_DETECT
305 6971370 leading_consecutive = 1;
306 #endif /* FX_DISABLE_CONSECUTIVE_DETECT */
307 6971370 file_ptr -> fx_file_consecutive_cluster = 1;
308 #ifndef FX_DISABLE_FAST_OPEN
309
310 /* Determine if the file is being open for reading with the fast option. */
311
4/4
✓ Branch 29 → 30 taken 8 times.
✓ Branch 29 → 31 taken 75682 times.
✓ Branch 36 → 37 taken 10 times.
✓ Branch 36 → 38 taken 6895670 times.
6971370 if (fast_open)
312 {
313
314 /* Calculate the bytes available. */
315 18 bytes_available = ((bytes_remaining + bytes_per_cluster - 1) / bytes_per_cluster) * bytes_per_cluster;
316
317 }
318 else
319 #endif /* FX_DISABLE_FAST_OPEN */
320 {
321
322 /* Follow the link of FAT entries. */
323
8/8
✓ Branch 50 → 51 taken 1978938 times.
✓ Branch 50 → 52 taken 26295 times.
✓ Branch 51 → 32 taken 1929563 times.
✓ Branch 51 → 52 taken 49375 times.
✓ Branch 59 → 60 taken 67622434 times.
✓ Branch 59 → 61 taken 32891 times.
✓ Branch 60 → 39 taken 60759670 times.
✓ Branch 60 → 61 taken 6862764 times.
69660558 while ((cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved))
324 {
325
326 /* Increment the number of clusters. */
327 62689233 cluster_count++;
328
329 /* Read the current cluster entry from the FAT. */
330 62689233 status = _fx_utility_FAT_entry_read(media_ptr, cluster, &contents);
331
332 /* Check the return value. */
333
4/4
✓ Branch 33 → 34 taken 4 times.
✓ Branch 33 → 35 taken 1929559 times.
✓ Branch 40 → 41 taken 5 times.
✓ Branch 40 → 43 taken 60759665 times.
62689233 if (status != FX_SUCCESS)
334 {
335
336 /* Release media protection. */
337 5 FX_UNPROTECT
338
339 /* Return the error status. */
340 9 return(status);
341 }
342
343 /* Determine if the cluster is invalid (points to itself) or the count exceeds the total number of clusters. */
344
8/8
✓ Branch 35 → 36 taken 1929555 times.
✓ Branch 35 → 37 taken 4 times.
✓ Branch 36 → 37 taken 4 times.
✓ Branch 36 → 38 taken 1929551 times.
✓ Branch 43 → 44 taken 60759660 times.
✓ Branch 43 → 45 taken 5 times.
✓ Branch 44 → 45 taken 5 times.
✓ Branch 44 → 47 taken 60759655 times.
62689224 if ((cluster == contents) || (cluster_count > media_ptr -> fx_media_total_clusters))
345 {
346
347 /* Release media protection. */
348 10 FX_UNPROTECT
349
350 /* Return the bad status. */
351 18 return(FX_FAT_READ_ERROR);
352 }
353
354 #ifndef FX_DISABLE_CONSECUTIVE_DETECT
355
356 /* Check if present and next clusters are consecutive */
357
4/4
✓ Branch 38 → 39 taken 1858688 times.
✓ Branch 38 → 41 taken 70863 times.
✓ Branch 47 → 48 taken 53869741 times.
✓ Branch 47 → 50 taken 6889914 times.
62689206 if (cluster + 1 == contents)
358 {
359
360 /* Determine if clusters are consecutive so far. */
361
4/4
✓ Branch 39 → 40 taken 1858588 times.
✓ Branch 39 → 42 taken 100 times.
✓ Branch 48 → 49 taken 53866127 times.
✓ Branch 48 → 51 taken 3614 times.
55728429 if (leading_consecutive)
362 {
363
364 /* Yes, increment the number of leading consecutive clusters. */
365 55724715 file_ptr -> fx_file_consecutive_cluster++;
366 }
367 }
368 else
369 {
370
371 /* The clusters are no longer consecutive, clear the consecutive flag. */
372 6960777 leading_consecutive = 0;
373 }
374 #endif /* FX_DISABLE_CONSECUTIVE_DETECT */
375
376 /* Save the last valid cluster. */
377 62689206 last_cluster = cluster;
378
379 /* Setup for the next cluster. */
380 62689206 cluster = contents;
381
382 /* Determine if this is the last written cluster. We need to remember this
383 for open for writing. */
384
4/4
✓ Branch 42 → 43 taken 1880156 times.
✓ Branch 42 → 44 taken 49395 times.
✓ Branch 51 → 52 taken 53896868 times.
✓ Branch 51 → 53 taken 6862787 times.
62689206 if (bytes_remaining > bytes_per_cluster)
385 {
386
387 /* Still more written clusters, just decrement the counter. */
388 55777024 bytes_remaining = bytes_remaining - bytes_per_cluster;
389 }
390
4/4
✓ Branch 44 → 45 taken 49375 times.
✓ Branch 44 → 49 taken 20 times.
✓ Branch 53 → 54 taken 6862765 times.
✓ Branch 53 → 58 taken 22 times.
6912182 else if (!file_ptr -> fx_file_current_physical_cluster)
391 {
392
393 /* Remember this cluster number. */
394 6912140 file_ptr -> fx_file_current_physical_cluster = last_cluster;
395
396 /* Remember the relative cluster. */
397 6912140 file_ptr -> fx_file_current_relative_cluster = cluster_count - 1;
398
399 /* If the remaining bytes exactly fits the cluster size, check for
400 a possible adjustment to the next cluster. */
401
8/8
✓ Branch 45 → 46 taken 4218 times.
✓ Branch 45 → 49 taken 45157 times.
✓ Branch 46 → 47 taken 4214 times.
✓ Branch 46 → 49 taken 4 times.
✓ Branch 54 → 55 taken 3605972 times.
✓ Branch 54 → 58 taken 3256793 times.
✓ Branch 55 → 56 taken 3605967 times.
✓ Branch 55 → 58 taken 5 times.
6912140 if ((bytes_remaining == bytes_per_cluster) &&
402
4/4
✓ Branch 47 → 48 taken 4 times.
✓ Branch 47 → 49 taken 4210 times.
✓ Branch 56 → 57 taken 5 times.
✓ Branch 56 → 58 taken 3605962 times.
3610181 (cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved))
403 {
404
405 /* We need to position to next allocated cluster. */
406 9 file_ptr -> fx_file_current_physical_cluster = cluster;
407 9 file_ptr -> fx_file_current_relative_cluster++;
408
409 /* Clear the remaining bytes. */
410 9 bytes_remaining = 0;
411 }
412 }
413 }
414
415 /* Determine if the number of clusters is large enough to support the
416 specified file size. */
417 6971325 bytes_available = ((ULONG64)media_ptr -> fx_media_bytes_per_sector) *
418 6971325 ((ULONG64)media_ptr -> fx_media_sectors_per_cluster) *
419 6971325 ((ULONG64)cluster_count);
420
421 /* Check the bytes available in the cluster chain against the directory entry file size. */
422
8/8
✓ Branch 52 → 53 taken 75656 times.
✓ Branch 52 → 55 taken 14 times.
✓ Branch 53 → 54 taken 49375 times.
✓ Branch 53 → 56 taken 26281 times.
✓ Branch 61 → 62 taken 6895639 times.
✓ Branch 61 → 64 taken 16 times.
✓ Branch 62 → 63 taken 6862765 times.
✓ Branch 62 → 66 taken 32874 times.
6971325 if ((bytes_available < file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size) ||
423
4/4
✓ Branch 54 → 55 taken 6 times.
✓ Branch 54 → 56 taken 49369 times.
✓ Branch 63 → 64 taken 8 times.
✓ Branch 63 → 66 taken 6862757 times.
6912140 ((cluster_count) && (contents < fat_last)))
424 {
425 /* File is corrupt, release media protection. */
426 24 FX_UNPROTECT
427
428 /* Return a corrupt file error status. */
429 44 return(FX_FILE_CORRUPT);
430 }
431 }
432
433 /* The file is okay, populate the file control block and complete the
434 file open process. */
435 6971299 file_ptr -> fx_file_id = FX_FILE_ID;
436 6971299 file_ptr -> fx_file_name = file_ptr -> fx_file_name_buffer;
437 6971299 file_ptr -> fx_file_media_ptr = media_ptr;
438 6971299 file_ptr -> fx_file_open_mode = open_type;
439 6971299 file_ptr -> fx_file_modified = FX_FALSE;
440 6971299 file_ptr -> fx_file_total_clusters = cluster_count;
441 6971299 file_ptr -> fx_file_first_physical_cluster = file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster;
442 6971299 file_ptr -> fx_file_last_physical_cluster = last_cluster;
443 6971299 file_ptr -> fx_file_current_file_size = file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size;
444 6971299 file_ptr -> fx_file_current_available_size = bytes_available;
445 6971299 file_ptr -> fx_file_disable_burst_cache = FX_FALSE;
446
447 /* Set the current settings based on how the file was opened. */
448
4/4
✓ Branch 56 → 57 taken 4094 times.
✓ Branch 56 → 58 taken 71564 times.
✓ Branch 66 → 67 taken 3406355 times.
✓ Branch 66 → 68 taken 3489286 times.
6971299 if (open_type == FX_OPEN_FOR_READ)
449 {
450
451 /* Position the pointers to the beginning of the file. */
452 3410449 file_ptr -> fx_file_current_physical_cluster = file_ptr -> fx_file_first_physical_cluster;
453 3410449 file_ptr -> fx_file_current_relative_cluster = 0;
454 3410449 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
455 3410449 (((ULONG64)(file_ptr -> fx_file_first_physical_cluster - FX_FAT_ENTRY_START)) *
456 3410449 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
457 3410449 file_ptr -> fx_file_current_relative_sector = 0;
458 3410449 file_ptr -> fx_file_current_logical_offset = 0;
459 3410449 file_ptr -> fx_file_current_file_offset = 0;
460 }
461 else
462 {
463
464 /* Open for writing - position the pointers to the end of the file. */
465
466 /* Determine if the remaining bytes fit exactly into the cluster size. */
467
4/4
✓ Branch 58 → 59 taken 202 times.
✓ Branch 58 → 60 taken 71362 times.
✓ Branch 68 → 69 taken 1800442 times.
✓ Branch 68 → 70 taken 1688844 times.
3560850 if (bytes_remaining == bytes_per_cluster)
468 {
469
470 /* Position to the end of the cluster. */
471 1800644 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
472 1800644 (((ULONG64)file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) *
473 1800644 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) +
474 1800644 ((ULONG)(((bytes_remaining - 1) / (ULONG)media_ptr -> fx_media_bytes_per_sector)));
475 1800644 file_ptr -> fx_file_current_relative_sector = (ULONG)(((bytes_remaining - 1) / (ULONG)media_ptr -> fx_media_bytes_per_sector));
476 1800644 file_ptr -> fx_file_current_file_offset = file_ptr -> fx_file_current_file_size;
477 1800644 file_ptr -> fx_file_current_logical_offset = media_ptr -> fx_media_bytes_per_sector;
478 }
479 else
480 {
481
482 /* Position file parameters at end of last cluster allocation. */
483 1760206 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
484 1760206 (((ULONG64)file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) *
485 1760206 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) +
486 1760206 ((ULONG)((bytes_remaining / (ULONG)media_ptr -> fx_media_bytes_per_sector)));
487 1760206 file_ptr -> fx_file_current_relative_sector = (ULONG)((bytes_remaining / (ULONG)media_ptr -> fx_media_bytes_per_sector));
488 1760206 file_ptr -> fx_file_current_file_offset = file_ptr -> fx_file_current_file_size;
489 1760206 file_ptr -> fx_file_current_logical_offset = (ULONG)bytes_remaining % ((ULONG)media_ptr -> fx_media_bytes_per_sector);
490 }
491 }
492
493 #ifdef FX_ENABLE_FAULT_TOLERANT
494 /* By default, the whole file is used. */
495 6879889 file_ptr -> fx_file_maximum_size_used = file_ptr -> fx_file_current_file_size;
496 #endif /* FX_ENABLE_FAULT_TOLERANT */
497
498 /* Place newly opened file on the list of open files for
499 this media. First, check for an empty list. */
500
4/4
✓ Branch 61 → 62 taken 44372 times.
✓ Branch 61 → 63 taken 31286 times.
✓ Branch 71 → 72 taken 55465 times.
✓ Branch 71 → 73 taken 6840176 times.
6971299 if (media_ptr -> fx_media_opened_file_list)
501 {
502
503 /* Pickup tail pointer. */
504 99837 tail_ptr = (media_ptr -> fx_media_opened_file_list) -> fx_file_opened_previous;
505
506 /* Place the new file in the list. */
507 99837 (media_ptr -> fx_media_opened_file_list) -> fx_file_opened_previous = file_ptr;
508 99837 tail_ptr -> fx_file_opened_next = file_ptr;
509
510 /* Setup this file's opened links. */
511 99837 file_ptr -> fx_file_opened_previous = tail_ptr;
512 99837 file_ptr -> fx_file_opened_next = media_ptr -> fx_media_opened_file_list;
513 }
514 else
515 {
516
517 /* The opened media list is empty. Add the media to empty list. */
518 6871462 media_ptr -> fx_media_opened_file_list = file_ptr;
519 6871462 file_ptr -> fx_file_opened_next = file_ptr;
520 6871462 file_ptr -> fx_file_opened_previous = file_ptr;
521 }
522
523 /* Increment the opened file counter. */
524 6971299 media_ptr -> fx_media_opened_file_count++;
525
526 /* Release media protection. */
527 6895641 FX_UNPROTECT
528
529 /* Open is complete, return successful status. */
530 6971295 return(FX_SUCCESS);
531 }
532
533