Select one of the symbols to view example projects that use it.
 
Outline
...
...
...
...
#define FX_SOURCE_CODE
#include "fx_api.h"
#include "fx_system.h"
#include "fx_directory.h"
#include "fx_file.h"
#include "fx_utility.h"
...
...
_fx_file_extended_seek(FX_FILE *, ULONG64)
Files
loading...
CodeScopeSTM32 Libraries and Samplesfilexcommon/src/fx_file_extended_seek.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/**************************************************************************/ /* */ /* Copyright (c) Microsoft Corporation. All rights reserved. */ /* */ /* This software is licensed under the Microsoft Software License */ /* Terms for Microsoft Azure RTOS. Full text of the license can be */ /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ /* and in the root directory of this software. */ /* */... /**************************************************************************/ ... /**************************************************************************/ /**************************************************************************/ /** */ /** FileX Component */ /** */ /** File */ /** */... /**************************************************************************/ /**************************************************************************/ #define FX_SOURCE_CODE /* Include necessary system files. */ #include "fx_api.h" #include "fx_system.h" #include "fx_directory.h" #include "fx_file.h" #include "fx_utility.h" 5 includes ... /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _fx_file_extended_seek PORTABLE C */ /* 6.1.7 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ /* This function positions the internal file pointers to the specified */ /* byte offset such that the next read or write operation will be */ /* performed there. If the byte offset is greater than the size, the */ /* file pointers will be positioned to the end of the file. */ /* */ /* INPUT */ /* */ /* file_ptr File control block pointer */ /* byte_offset Byte offset into the file */ /* */ /* OUTPUT */ /* */ /* return status */ /* */ /* CALLS */ /* */ /* _fx_utility_FAT_entry_read Read a FAT entry */ /* */ /* CALLED BY */ /* */ /* Application Code */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ /* 05-19-2020 William E. Lamie Initial Version 6.0 */ /* 09-30-2020 William E. Lamie Modified comment(s), */ /* resulting in version 6.1 */ /* 06-02-2021 Bhupendra Naphade Modified comment(s), fixed */ /* relative cluster logic, */ /* resulting in version 6.1.7 */ /* */... /**************************************************************************/ UINT _fx_file_extended_seek(FX_FILE *file_ptr, ULONG64 byte_offset) { UINT status; ULONG cluster; ULONG contents = 0; ULONG bytes_per_cluster; ULONG last_cluster; ULONG cluster_count; ULONG64 bytes_remaining; FX_MEDIA *media_ptr; /* First, determine if the file is still open. */ if (file_ptr -> fx_file_id != FX_FILE_ID) { /* Return the file not open error status. */ return(FX_NOT_OPEN); }if (file_ptr -> fx_file_id != FX_FILE_ID) { ... } #ifndef FX_MEDIA_STATISTICS_DISABLE /* Setup pointer to media structure. */ media_ptr = file_ptr -> fx_file_media_ptr; /* Increment the number of times this service has been called. */ media_ptr -> fx_media_file_seeks++;/* ... */ #endif /* Setup pointer to associated media control block. */ media_ptr = file_ptr -> fx_file_media_ptr; /* If trace is enabled, insert this event into the trace buffer. */ FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_SEEK, file_ptr, byte_offset, file_ptr -> fx_file_current_file_offset, 0, FX_TRACE_FILE_EVENTS, 0, 0) /* Protect against other threads accessing the media. */ FX_PROTECT /* Check if we actually have to do anything. */ if (byte_offset == file_ptr -> fx_file_current_file_offset) { /* Release media protection. */ FX_UNPROTECT /* Seek is complete, return successful status. */ return(FX_SUCCESS); }if (byte_offset == file_ptr -> fx_file_current_file_offset) { ... } /* Calculate the number of bytes per cluster. */ bytes_per_cluster = ((ULONG)media_ptr -> fx_media_bytes_per_sector) * ((ULONG)media_ptr -> fx_media_sectors_per_cluster); /* Check for invalid value. */ if (bytes_per_cluster == 0) { /* Release media protection. */ FX_UNPROTECT /* Invalid media, return error. */ return(FX_MEDIA_INVALID); }if (bytes_per_cluster == 0) { ... } /* See if we need to adjust the byte offset. */ if (byte_offset > file_ptr -> fx_file_current_file_size) { /* Adjust the byte offset down to the file size. */ byte_offset = file_ptr -> fx_file_current_file_size; }if (byte_offset > file_ptr -> fx_file_current_file_size) { ... } /* Check if the desired position within the leading consecutive clusters. */ if (byte_offset >= (ULONG64)file_ptr -> fx_file_consecutive_cluster * (ULONG64)bytes_per_cluster) { #ifdef FX_ENABLE_EXFAT if (file_ptr -> fx_file_dir_entry.fx_dir_entry_dont_use_fat & 1) { if (byte_offset == (ULONG64)file_ptr -> fx_file_consecutive_cluster * (ULONG64)bytes_per_cluster) { /* If the file bytes exactly fits the cluster size */ bytes_remaining = bytes_per_cluster; file_ptr -> fx_file_current_relative_cluster = (ULONG)(byte_offset / bytes_per_cluster - 1); file_ptr -> fx_file_current_physical_cluster = file_ptr -> fx_file_first_physical_cluster + file_ptr -> fx_file_current_relative_cluster; }if (byte_offset == (ULONG64)file_ptr -> fx_file_consecutive_cluster * (ULONG64)bytes_per_cluster) { ... } else { /* We shouldn't be here if don't using FAT! */ FX_UNPROTECT return(FX_FILE_CORRUPT); }else { ... } }if (file_ptr -> fx_file_dir_entry.fx_dir_entry_dont_use_fat & 1) { ... } else { #endif /* FX_ENABLE_EXFAT */ /* At this point, we are ready to walk list of clusters to setup the seek position of this file. *//* ... */ /* check if byte_offset is greater than where we were left off earlier */ if ((ULONG64)file_ptr -> fx_file_current_relative_cluster * (ULONG64)bytes_per_cluster < byte_offset) { cluster = file_ptr -> fx_file_current_physical_cluster; bytes_remaining = byte_offset - file_ptr -> fx_file_current_relative_cluster * bytes_per_cluster; cluster_count = file_ptr -> fx_file_current_relative_cluster; }if ((ULONG64)file_ptr -> fx_file_current_relative_cluster * (ULONG64)bytes_per_cluster < byte_offset) { ... } else { cluster = file_ptr -> fx_file_first_physical_cluster + (file_ptr -> fx_file_consecutive_cluster - 1); bytes_remaining = byte_offset - (file_ptr -> fx_file_consecutive_cluster - 1) * bytes_per_cluster; cluster_count = (file_ptr -> fx_file_consecutive_cluster - 1); }else { ... } /* Follow the link of FAT entries. */ while ((cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved)) { /* Increment the number of clusters. */ cluster_count++; /* Read the current cluster entry from the FAT. */ status = _fx_utility_FAT_entry_read(media_ptr, cluster, &contents); /* Check the return value. */ if (status != FX_SUCCESS) { /* Release media protection. */ FX_UNPROTECT /* Return the error status. */ return(status); }if (status != FX_SUCCESS) { ... } /* Save the last valid cluster. */ last_cluster = cluster; /* Setup for the next cluster. */ cluster = contents; /* Determine if this is the last written cluster. */ if (bytes_remaining > bytes_per_cluster) { /* Still more seeking, just decrement the working byte offset. */ bytes_remaining = bytes_remaining - bytes_per_cluster; }if (bytes_remaining > bytes_per_cluster) { ... } else { /* Remember this cluster number. */ file_ptr -> fx_file_current_physical_cluster = last_cluster; /* Remember the relative cluster. */ file_ptr -> fx_file_current_relative_cluster = cluster_count - 1; /* If the remaining bytes exactly fits the cluster size, check for a possible adjustment to the next cluster. *//* ... */ if ((bytes_remaining == bytes_per_cluster) && (cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved)) { /* We need to position to next allocated cluster. */ file_ptr -> fx_file_current_physical_cluster = cluster; file_ptr -> fx_file_current_relative_cluster++; /* Clear the remaining bytes. */ bytes_remaining = 0; }if ((bytes_remaining == bytes_per_cluster) && (cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved)) { ... } /* This is the cluster that contains the seek position. */ break; }else { ... } }while ((cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved)) { ... } /* Check for errors in traversal of the FAT chain. */ if (byte_offset > (((ULONG64) bytes_per_cluster) * ((ULONG64) cluster_count))) { /* Release media protection. */ FX_UNPROTECT /* This is an error that suggests a corrupt file. */ return(FX_FILE_CORRUPT); }if (byte_offset > (((ULONG64) bytes_per_cluster) * ((ULONG64) cluster_count))) { ... } #ifdef FX_ENABLE_EXFAT }else { ... } #endif /* FX_ENABLE_EXFAT */ }if (byte_offset >= (ULONG64)file_ptr -> fx_file_consecutive_cluster * (ULONG64)bytes_per_cluster) { ... } else { /* we should directly access the desired cluster */ file_ptr -> fx_file_current_relative_cluster = (ULONG)(byte_offset / bytes_per_cluster); file_ptr -> fx_file_current_physical_cluster = file_ptr -> fx_file_first_physical_cluster + file_ptr -> fx_file_current_relative_cluster; bytes_remaining = byte_offset % bytes_per_cluster; }else { ... } /* Determine if the remaining bytes fit exactly into the cluster size. */ if (bytes_remaining == bytes_per_cluster) { /* Position to the end of the cluster. */ file_ptr -> fx_file_current_logical_sector = (ULONG)(((ULONG)media_ptr -> fx_media_data_sector_start) + (((ULONG64)file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) * ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + ((bytes_remaining - 1) / (ULONG)media_ptr -> fx_media_bytes_per_sector)); file_ptr -> fx_file_current_relative_sector = (UINT)(((bytes_remaining - 1) / (ULONG)media_ptr -> fx_media_bytes_per_sector)); file_ptr -> fx_file_current_file_offset = byte_offset; file_ptr -> fx_file_current_logical_offset = media_ptr -> fx_media_bytes_per_sector; }if (bytes_remaining == bytes_per_cluster) { ... } else { /* Position the pointers to the new offset. */ file_ptr -> fx_file_current_logical_sector = (ULONG)(((ULONG)media_ptr -> fx_media_data_sector_start) + (((ULONG64)file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START) * ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + (bytes_remaining / (ULONG)media_ptr -> fx_media_bytes_per_sector)); file_ptr -> fx_file_current_relative_sector = (UINT)((bytes_remaining / (ULONG)media_ptr -> fx_media_bytes_per_sector)); file_ptr -> fx_file_current_file_offset = byte_offset; file_ptr -> fx_file_current_logical_offset = (ULONG)(bytes_remaining % ((ULONG)media_ptr -> fx_media_bytes_per_sector)); }else { ... } /* Release media protection. */ FX_UNPROTECT /* Seek is complete, return successful status. */ return(FX_SUCCESS); }{ ... }