GCC Code Coverage Report


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

fx_directory_entry_read.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 /** Directory */
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_utility.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _fx_directory_entry_read PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function reads the supplied directory entry from the supplied */
47 /* source directory. If the supplied directory entry is NULL, then */
48 /* the root directory is assumed. */
49 /* */
50 /* INPUT */
51 /* */
52 /* media_ptr Media control block pointer */
53 /* source_dir Source directory entry */
54 /* entry_ptr Directory entry number */
55 /* destination_ptr Pointer to destination for */
56 /* the directory entry */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* return status */
61 /* *entry_ptr should point to the 8:3 entry if it is a long name */
62 /* */
63 /* CALLS */
64 /* */
65 /* _fx_utility_FAT_entry_read Read a FAT entry */
66 /* _fx_utility_logical_sector_read Read directory sector */
67 /* _fx_utility_16_unsigned_read Read a UINT from memory */
68 /* _fx_utility_32_unsigned_read Read a ULONG from memory */
69 /* */
70 /* CALLED BY */
71 /* */
72 /* FileX System Functions */
73 /* */
74 /**************************************************************************/
75 83086316 UINT _fx_directory_entry_read(FX_MEDIA *media_ptr, FX_DIR_ENTRY *source_dir,
76 ULONG *entry_ptr, FX_DIR_ENTRY *destination_ptr)
77 {
78
79 UINT i, j, card, dotflag, get_short_name;
80 UINT number_of_lfns;
81 UINT status;
82 83086316 ULONG cluster, next_cluster = 0;
83 UINT relative_cluster;
84 UINT relative_sector;
85 ULONG logical_sector;
86 ULONG byte_offset;
87 ULONG bytes_per_cluster;
88 UCHAR *read_ptr;
89 CHAR *short_name_ptr;
90 83086316 ULONG entry = *entry_ptr;
91
92
93 #ifndef FX_MEDIA_STATISTICS_DISABLE
94
95 /* Increment the number of directory entry read requests. */
96 83086316 media_ptr -> fx_media_directory_entry_reads++;
97 #endif
98
99 /* Extended port-specific processing macro, which is by default defined to white space. */
100
4/4
✓ Branch 2 → 3 taken 90 times.
✓ Branch 2 → 5 taken 83086226 times.
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 5 taken 81 times.
83086316 FX_DIRECTORY_ENTRY_READ_EXTENSION
101
102 /* If trace is enabled, insert this event into the trace buffer. */
103 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_DIR_ENTRY_READ, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
104
105 /* Calculate the byte offset of this directory entry. */
106 83086307 byte_offset = entry * FX_DIR_ENTRY_SIZE;
107
108 /* Determine if a sub-directory or FAT32 root directory is specified. */
109
4/4
✓ Branch 5 → 6 taken 81526105 times.
✓ Branch 5 → 7 taken 1560202 times.
✓ Branch 6 → 7 taken 70644880 times.
✓ Branch 6 → 31 taken 10881225 times.
83086307 if ((source_dir) || (media_ptr -> fx_media_32_bit_FAT))
110 {
111
112 /* Yes, a sub-directory is present. */
113
114 /* Calculate the number of bytes per cluster. */
115 72205082 bytes_per_cluster = ((ULONG)media_ptr -> fx_media_bytes_per_sector) *
116 72205082 ((ULONG)media_ptr -> fx_media_sectors_per_cluster);
117
118 /* Check for invalid value. */
119
2/2
✓ Branch 7 → 8 taken 27 times.
✓ Branch 7 → 9 taken 72205055 times.
72205082 if (bytes_per_cluster == 0)
120 {
121
122 /* Invalid media, return error. */
123 27 return(FX_MEDIA_INVALID);
124 }
125
126 /* Now determine the relative cluster in the sub-directory file. */
127 72205055 relative_cluster = (UINT)(byte_offset / bytes_per_cluster);
128
129 /* Calculate the byte offset within the cluster. */
130 72205055 byte_offset = byte_offset % bytes_per_cluster;
131
132 /* Now figure out the relative sector within the cluster. */
133 72205055 relative_sector = (UINT)(byte_offset / ((ULONG)media_ptr -> fx_media_bytes_per_sector));
134
135 /* Read the directory sector into the internal memory buffer. */
136
137 /* Determine if there is a sub-directory. */
138
2/2
✓ Branch 9 → 10 taken 1560193 times.
✓ Branch 9 → 17 taken 70644862 times.
72205055 if (source_dir)
139 {
140
141 /* Determine if this source directory has valid information from the previous call. */
142
2/2
✓ Branch 10 → 11 taken 1265166 times.
✓ Branch 10 → 15 taken 295027 times.
1560193 if ((source_dir -> fx_dir_entry_last_search_cluster) &&
143
2/2
✓ Branch 11 → 12 taken 1265157 times.
✓ Branch 11 → 15 taken 9 times.
1265166 (source_dir -> fx_dir_entry_last_search_relative_cluster <= relative_cluster) &&
144
2/2
✓ Branch 12 → 13 taken 1265148 times.
✓ Branch 12 → 15 taken 9 times.
1265157 (source_dir -> fx_dir_entry_last_search_log_sector == source_dir -> fx_dir_entry_log_sector) &&
145
2/2
✓ Branch 13 → 14 taken 1265139 times.
✓ Branch 13 → 15 taken 9 times.
1265148 (source_dir -> fx_dir_entry_last_search_byte_offset == source_dir -> fx_dir_entry_byte_offset))
146 {
147
148 /* Use the previous information to start the search. */
149 1265139 cluster = source_dir -> fx_dir_entry_last_search_cluster;
150
151 /* Setup the relative cluster index to the saved relative cluster. */
152 1265139 i = source_dir -> fx_dir_entry_last_search_relative_cluster;
153
154 /* Clear the search cluster. It will be updated prior to successful return. */
155 1265139 source_dir -> fx_dir_entry_last_search_cluster = 0;
156 }
157 else
158 {
159
160 /* Nothing from the previous directory read, just setup the starting cluster to the
161 beginning of the sub-directory. */
162 295054 cluster = source_dir -> fx_dir_entry_cluster;
163
164 /* Setup the relative cluster index to zero. */
165 295054 i = 0;
166 }
167 }
168 else
169 {
170
171 /* No, setup the starting cluster to the FAT32 root cluster. */
172 70644862 cluster = media_ptr -> fx_media_root_cluster_32;
173
174 /* Setup the relative cluster index to zero. */
175 70644862 i = 0;
176 }
177
178 /* Loop to position to the appropriate cluster. */
179
2/2
✓ Branch 26 → 19 taken 18326622 times.
✓ Branch 26 → 27 taken 72205028 times.
90531650 while (i < relative_cluster)
180 {
181
182 /* Check the value of the new cluster - it must be a valid cluster number
183 or something is really wrong! */
184
4/4
✓ Branch 19 → 20 taken 18326613 times.
✓ Branch 19 → 21 taken 9 times.
✓ Branch 20 → 21 taken 9 times.
✓ Branch 20 → 22 taken 18326604 times.
18326622 if ((cluster < FX_FAT_ENTRY_START) || (cluster >= media_ptr -> fx_media_fat_reserved))
185 {
186
187 /* Send error message back to caller. */
188 18 return(FX_FILE_CORRUPT);
189 }
190
191 /* Read the next cluster. */
192 18326604 status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster);
193
194 /* There is a potential for loop, but hardly anything can be done */
195
196 /* Check for I/O error. */
197
2/2
✓ Branch 23 → 24 taken 9 times.
✓ Branch 23 → 25 taken 18326595 times.
18326604 if (status != FX_SUCCESS)
198 {
199
200 /* Return error code. */
201 9 return(status);
202 }
203
204 /* Setup the actual cluster. */
205 18326595 cluster = next_cluster;
206
207 /* Increment the relative cluster number. */
208 18326595 i++;
209 }
210
211 /* At this point, the directory data sector needs to be read. */
212 72205028 logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
213 72205028 (((ULONG)cluster - FX_FAT_ENTRY_START) *
214 72205028 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) +
215 relative_sector;
216
217 /* Read the logical directory sector. */
218 72205028 status = _fx_utility_logical_sector_read(media_ptr, (ULONG64) logical_sector,
219 72205028 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
220
221 /* Determine if an error occurred. */
222
2/2
✓ Branch 28 → 29 taken 1895 times.
✓ Branch 28 → 30 taken 72203133 times.
72205028 if (status != FX_SUCCESS)
223 {
224
225 /* Return error code. */
226 1895 return(status);
227 }
228
229 /* Calculate the byte offset within this sector. */
230 72203133 byte_offset = byte_offset % media_ptr -> fx_media_bytes_per_sector;
231 }
232 else
233 {
234
235 /* Read the entry from the root directory. */
236
237 /* Determine which sector the requested root directory entry is in. */
238 10881225 logical_sector = (byte_offset / media_ptr -> fx_media_bytes_per_sector) +
239 10881225 (ULONG)media_ptr -> fx_media_root_sector_start;
240
241 /* Read the logical directory sector. */
242 10881225 status = _fx_utility_logical_sector_read(media_ptr, (ULONG64) logical_sector,
243 10881225 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
244
245 /* Determine if an error occurred. */
246
2/2
✓ Branch 32 → 33 taken 4667 times.
✓ Branch 32 → 34 taken 10876558 times.
10881225 if (status != FX_SUCCESS)
247 {
248
249 /* Return error code. */
250 4667 return(status);
251 }
252
253 /* Set the cluster and relative variables (not used in this case) to avoid any compiler
254 warnings. */
255 10876558 relative_cluster = relative_sector = cluster = 0;
256
257 /* Now calculate the byte offset into this sector. */
258 10876558 byte_offset = byte_offset -
259 10876558 ((logical_sector - (ULONG)media_ptr -> fx_media_root_sector_start) *
260 10876558 media_ptr -> fx_media_bytes_per_sector);
261 }
262
263 /* Setup a pointer into the buffer. */
264 83079691 read_ptr = (UCHAR *)media_ptr -> fx_media_memory_buffer + (UINT)byte_offset;
265
266 /* Save the logical sector and byte offset in the returned directory entry. */
267 83079691 destination_ptr -> fx_dir_entry_log_sector = logical_sector;
268 83079691 destination_ptr -> fx_dir_entry_byte_offset = byte_offset;
269
270 /* Clear the short file name information. */
271 83079691 destination_ptr -> fx_dir_entry_long_name_shorted = 0;
272 83079691 destination_ptr -> fx_dir_entry_short_name[0] = 0;
273
274 /* Setup short name pointer. */
275 83079691 short_name_ptr = destination_ptr -> fx_dir_entry_name;
276
277 /* Check if long file name exists. */
278 83079691 get_short_name = 0;
279
4/4
✓ Branch 35 → 36 taken 622731 times.
✓ Branch 35 → 86 taken 82456960 times.
✓ Branch 36 → 37 taken 611335 times.
✓ Branch 36 → 86 taken 11396 times.
83079691 if ((*(read_ptr + 11) == (UCHAR)FX_LONG_NAME) && (*read_ptr != (UCHAR)FX_DIR_ENTRY_FREE))
280 {
281
282 /* Collate the long name. */
283
284 /* Pickup the file name length. */
285 611335 i = (((UINT)(*read_ptr & (UCHAR)0x1f) - 1) * FX_LONG_NAME_ENTRY_LEN) & 0xFFFFFFFF;
286
287 /* Save the number of LFN entries. */
288 611335 number_of_lfns = (UINT)(*read_ptr & (UCHAR)0x1f);
289
290 /* Check the file name size. */
291
2/2
✓ Branch 37 → 38 taken 303 times.
✓ Branch 37 → 39 taken 611032 times.
611335 if (i >= (FX_MAX_LONG_NAME_LEN - 1))
292 {
293
294 /* Name is too big, shorten it. */
295 303 get_short_name = 1;
296 303 destination_ptr -> fx_dir_entry_long_name_shorted = (UINT)(*read_ptr & (UCHAR)0x1f);
297 }
298 else
299 {
300
301 /* Size of name is fine, save pointer to short file name. */
302 611032 short_name_ptr = destination_ptr -> fx_dir_entry_short_name;
303
304 /* Loop to make sure the long file name is NULL terminated. */
305 611032 j = i + FX_LONG_NAME_ENTRY_LEN + 1;
306 do
307 {
308 /* Place a NULL in the long name. */
309 8542323 destination_ptr -> fx_dir_entry_name[i] = 0;
310
311 /* Position to the next entry. */
312 8542323 i++;
313
4/4
✓ Branch 40 → 41 taken 7933716 times.
✓ Branch 40 → 43 taken 608607 times.
✓ Branch 41 → 42 taken 7931291 times.
✓ Branch 41 → 43 taken 2425 times.
8542323 } while ((i < j) && (i < FX_MAX_LONG_NAME_LEN));
314 }
315
316 /* Loop to pickup the rest of the name. */
317 do
318 {
319
320 /* Get the lower 5 bit containing the cardinality. */
321 824363 card = (UINT)(*read_ptr & (UCHAR)0x1f) - 1;
322
323 /* For simplicity no checksum or cardinality checking is done */
324
2/2
✓ Branch 44 → 45 taken 810420 times.
✓ Branch 44 → 63 taken 13943 times.
824363 if (get_short_name == 0)
325 {
326
327 /* Loop to pickup name. */
328
2/2
✓ Branch 62 → 46 taken 12965250 times.
✓ Branch 62 → 63 taken 810138 times.
13775388 for (i = 1, j = 0; i < FX_DIR_ENTRY_SIZE; i += 2)
329 {
330
331
4/4
✓ Branch 46 → 47 taken 12154836 times.
✓ Branch 46 → 48 taken 810414 times.
✓ Branch 47 → 48 taken 810138 times.
✓ Branch 47 → 49 taken 11344698 times.
12965250 if ((i == 11) || (i == 26))
332 {
333 1620552 continue;
334 }
335
336 /* i = 12, 27 is not generated due to +=2 */
337
2/2
✓ Branch 49 → 50 taken 810414 times.
✓ Branch 49 → 51 taken 10534284 times.
11344698 if (i == 13)
338 {
339 810414 i = 12;
340 810414 continue; /* this time next unicode is byte offset 14*/
341 }
342
343 /* Determine if there is an actual unicode character present. */
344
2/2
✓ Branch 51 → 52 taken 5437700 times.
✓ Branch 51 → 55 taken 5096584 times.
10534284 if (read_ptr[i + 1])
345 {
346
347 /* Extended byte is non-zero, make sure both bytes of the unicode entry are not
348 all ones, since this is a normal case. */
349
4/4
✓ Branch 52 → 53 taken 5392684 times.
✓ Branch 52 → 54 taken 45016 times.
✓ Branch 53 → 54 taken 81 times.
✓ Branch 53 → 55 taken 5392603 times.
5437700 if ((read_ptr[i + 1] != (UCHAR)0xFF) || (read_ptr[i] != (UCHAR)0xFF))
350 {
351
352 /* Name is an actual unicode name, shorten it. */
353 45097 get_short_name = 1;
354
355 /* Save the number of directory entries the LFN has. This will be
356 used later when updating the 8.3 portion of the LFN. */
357 45097 destination_ptr -> fx_dir_entry_long_name_shorted = number_of_lfns;
358
359 /* Setup short name pointer. */
360 45097 short_name_ptr = destination_ptr -> fx_dir_entry_name;
361 }
362 }
363
364 /* Determine if the character is NULL. */
365
4/4
✓ Branch 55 → 56 taken 9922002 times.
✓ Branch 55 → 57 taken 612282 times.
✓ Branch 56 → 57 taken 5392711 times.
✓ Branch 56 → 58 taken 4529291 times.
10534284 if ((read_ptr[i] == FX_NULL) || (read_ptr[i] == (UCHAR)0xFF))
366 {
367 6004993 continue;
368 }
369
370 /* Determine if the name is too big. */
371
2/2
✓ Branch 58 → 59 taken 282 times.
✓ Branch 58 → 60 taken 4529009 times.
4529291 if ((card * 13 + j) >= (FX_MAX_LONG_NAME_LEN - 1))
372 {
373
374 /* Name is actually too big, shorten it. */
375 282 get_short_name = 1;
376
377 /* Save the number of directory entries the LFN has. This will be
378 used later when updating the 8.3 portion of the LFN. */
379 282 destination_ptr -> fx_dir_entry_long_name_shorted = number_of_lfns;
380
381 /* Also reposition the short name pointer. */
382 282 short_name_ptr = destination_ptr -> fx_dir_entry_name;
383
384 282 break;
385 }
386
387 /* Each entry contains 13 unicode and first byte ASCII, second byte is extended. */
388 4529009 destination_ptr -> fx_dir_entry_name[13 * card + j] = (CHAR)read_ptr[i];
389
390 4529009 j++;
391 }
392 }
393
394 /* Determine if a new sector needs to be read. */
395
2/2
✓ Branch 63 → 64 taken 139072 times.
✓ Branch 63 → 82 taken 685291 times.
824363 if (byte_offset + FX_DIR_ENTRY_SIZE >= media_ptr -> fx_media_bytes_per_sector)
396 {
397
398 /* Determine if a sub-directory or FAT32 root directory is specified. */
399
4/4
✓ Branch 64 → 65 taken 73350 times.
✓ Branch 64 → 66 taken 65722 times.
✓ Branch 65 → 66 taken 31457 times.
✓ Branch 65 → 76 taken 41893 times.
139072 if ((source_dir) || (media_ptr -> fx_media_32_bit_FAT))
400 {
401
402 /* Determine the next sector of the directory entry. */
403
2/2
✓ Branch 66 → 67 taken 38914 times.
✓ Branch 66 → 68 taken 58265 times.
97179 if (relative_sector < (media_ptr -> fx_media_sectors_per_cluster - 1))
404 {
405
406 /* More sectors in this cluster. */
407
408 /* Simply increment the logical sector. */
409 38914 logical_sector++;
410
411 /* Increment the relative sector. */
412 38914 relative_sector++;
413 }
414 else
415 {
416
417 /* We need to move to the next cluster. */
418
419 /* Pickup the next cluster. */
420 58265 status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster);
421
422 /* Check for I/O error. */
423
2/2
✓ Branch 69 → 70 taken 9 times.
✓ Branch 69 → 71 taken 58256 times.
58265 if (status != FX_SUCCESS)
424 {
425
426 /* Return error code. */
427 9 return(status);
428 }
429
430 /* Copy next cluster to the current cluster. */
431 58256 cluster = next_cluster;
432
433 /* Check the value of the new cluster - it must be a valid cluster number
434 or something is really wrong! */
435
4/4
✓ Branch 71 → 72 taken 58247 times.
✓ Branch 71 → 73 taken 9 times.
✓ Branch 72 → 73 taken 24 times.
✓ Branch 72 → 74 taken 58223 times.
58256 if ((cluster < FX_FAT_ENTRY_START) || (cluster >= media_ptr -> fx_media_fat_reserved))
436 {
437
438 /* Send error message back to caller. */
439 33 return(FX_FILE_CORRUPT);
440 }
441
442 /* Now increment the relative cluster. */
443 58223 relative_cluster++;
444
445 /* Setup the relative sector (this is zero for subsequent cluster. */
446 58223 relative_sector = 0;
447
448 /* Calculate the next logical sector. */
449 58223 logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
450 58223 (((ULONG)cluster - FX_FAT_ENTRY_START) *
451 58223 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
452 }
453 }
454 else
455 {
456
457 /* Non-FAT 32 root directory. */
458
459 /* Advance to the next sector. */
460 41893 logical_sector++;
461
462 /* Determine if the logical sector is valid. */
463
2/2
✓ Branch 76 → 77 taken 41 times.
✓ Branch 76 → 78 taken 41852 times.
41893 if (logical_sector >= (ULONG)(media_ptr -> fx_media_root_sector_start + media_ptr -> fx_media_root_sectors))
464 {
465
466 /* Trying to read past root directory - send error message back to caller. */
467 41 return(FX_FILE_CORRUPT);
468 }
469 }
470
471 /* Read the new sector. */
472 138989 status = _fx_utility_logical_sector_read(media_ptr, (ULONG64) logical_sector,
473 138989 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DIRECTORY_SECTOR);
474
475 /* Check I/O status. */
476
2/2
✓ Branch 79 → 80 taken 12 times.
✓ Branch 79 → 81 taken 138977 times.
138989 if (status != FX_SUCCESS)
477 {
478 12 return(status);
479 }
480
481 /* Set the byte offset to 0 for new sector. */
482 138977 byte_offset = 0;
483 }
484 else
485 {
486
487 /* Calculate the new byte offset. */
488 685291 byte_offset += FX_DIR_ENTRY_SIZE;
489 }
490
491 /* Calculate the next read pointer. */
492 824268 read_ptr = (UCHAR *)media_ptr -> fx_media_memory_buffer + (UINT) byte_offset;
493
494 /* Move to the next entry. */
495 824268 entry++;
496
2/2
✓ Branch 83 → 84 taken 213028 times.
✓ Branch 83 → 85 taken 611240 times.
824268 } while (card > 0);
497
498 /* Set flag indicating long file name is present. */
499 611240 destination_ptr -> fx_dir_entry_long_name_present = 1;
500 }
501 else
502 {
503 /* No long file name is present. */
504 82468356 get_short_name = 1;
505 }
506
507 /* Determine if we need to clear the long name flag. */
508
2/2
✓ Branch 87 → 88 taken 82506288 times.
✓ Branch 87 → 89 taken 573308 times.
83079596 if (get_short_name == 1)
509 {
510
511 /* Clear the long name flag. */
512 82506288 destination_ptr -> fx_dir_entry_long_name_present = 0;
513 }
514
515 /* Pickup the short file name. */
516 83079596 short_name_ptr[0] = 0;
517 83079596 dotflag = 0;
518
2/2
✓ Branch 105 → 90 taken 900936490 times.
✓ Branch 105 → 106 taken 81783385 times.
982719875 for (i = 0, j = 0; i < (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE); i++)
519 {
520
521 /* Check for a NULL. */
522
2/2
✓ Branch 90 → 91 taken 1296211 times.
✓ Branch 90 → 92 taken 899640279 times.
900936490 if ((CHAR)read_ptr[i] == 0)
523 {
524 1296211 break;
525 }
526
527 /* Check for a dot. This happens for the first two directory entries, no
528 extra dot is needed. */
529
2/2
✓ Branch 92 → 93 taken 461222 times.
✓ Branch 92 → 94 taken 899179057 times.
899640279 if ((CHAR)read_ptr[i] == '.')
530 {
531 461222 dotflag = 2;
532 }
533
534 /* Check for a space. */
535
2/2
✓ Branch 94 → 95 taken 219866215 times.
✓ Branch 94 → 98 taken 679774064 times.
899640279 if ((CHAR)read_ptr[i] == ' ')
536 {
537 /* Put a dot if a character comes after space. */
538
2/2
✓ Branch 95 → 96 taken 81472579 times.
✓ Branch 95 → 97 taken 138393636 times.
219866215 if (dotflag == 0)
539 {
540 81472579 dotflag = 1;
541 }
542 219866215 continue;
543 }
544
545 /* Check for the main short file name size. */
546
2/2
✓ Branch 98 → 99 taken 79184625 times.
✓ Branch 98 → 101 taken 600589439 times.
679774064 if (i == FX_DIR_NAME_SIZE)
547 {
548 /* Check to see if we need to insert a dot. */
549
2/2
✓ Branch 99 → 100 taken 3311 times.
✓ Branch 99 → 101 taken 79181314 times.
79184625 if (dotflag == 0)
550 {
551 3311 dotflag = 1;
552 }
553 }
554
555 /* Check to see if we need to add a dot. */
556
2/2
✓ Branch 101 → 102 taken 79184904 times.
✓ Branch 101 → 103 taken 600589160 times.
679774064 if (dotflag == 1)
557 {
558 /* Add dot to short file name. */
559 79184904 short_name_ptr[j++] = '.';
560 79184904 dotflag = 2; /* no more dot for spaces */
561 }
562
563 /* Copy a character. */
564 679774064 short_name_ptr[j] = (CHAR)read_ptr[i];
565
566 /* Increment size. */
567 679774064 j++;
568 }
569
570 /* Determine if a long file name is present and its associated short file
571 name is actually free. */
572
4/4
✓ Branch 106 → 107 taken 573308 times.
✓ Branch 106 → 109 taken 82506288 times.
✓ Branch 107 → 108 taken 153 times.
✓ Branch 107 → 109 taken 573155 times.
83079596 if ((destination_ptr -> fx_dir_entry_long_name_present) && (((UCHAR)short_name_ptr[0]) == (UCHAR)FX_DIR_ENTRY_FREE))
573 {
574
575 /* Yes, the short file name is really free even though long file name entries directly precede it.
576 In this case, simply place the free directory marker at the front of the long file name. */
577 153 destination_ptr -> fx_dir_entry_name[0] = (CHAR)FX_DIR_ENTRY_FREE;
578 153 short_name_ptr[0] = (CHAR)0;
579 }
580
581 /* Determine if the short name pointer is NULL while the read pointer is
582 non-NULL. */
583
4/4
✓ Branch 109 → 110 taken 1285004 times.
✓ Branch 109 → 114 taken 81794592 times.
✓ Branch 110 → 111 taken 54 times.
✓ Branch 110 → 114 taken 1284950 times.
83079596 if ((short_name_ptr[0] == 0) && (read_ptr[0] == ' '))
584 {
585
586 /* This condition can occur with an all blank volume name. Simply
587 copy the volume name to the short name in this case. */
588
2/2
✓ Branch 113 → 112 taken 594 times.
✓ Branch 113 → 114 taken 54 times.
648 for (j = 0; j < (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE); j++)
589 {
590
591 /* Copy a byte of the volume name. */
592 594 short_name_ptr[j] = (CHAR)read_ptr[j];
593 }
594 }
595
596 /* Set end of string to null. */
597 83079596 short_name_ptr[j] = 0;
598
599 /* Load up the destination directory entry. */
600 83079596 read_ptr += (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE);
601
602 /* Copy the attribute into the destination. */
603 83079596 destination_ptr -> fx_dir_entry_attributes = *read_ptr++;
604
605 /* Pickup the reserved byte. */
606 83079596 destination_ptr -> fx_dir_entry_reserved = *read_ptr++;
607
608 /* Check for an undocumented NT file name feature for optimizing the storage
609 of all lower case file names that otherwise are valid 8.3 file names. The
610 following reserved bit definitions are present:
611
612 BIT3 - set if 8.3 is all in lower case and no extended filename.
613 BIT4 - set for file, clear for directory entry if no extended filename.
614
615 This is true for all NT systems. Prior to NT follows MSDOS FAT documentation and
616 is set to 0x00, all bits cleared. Therefore if BIT3 is set force lowercase. */
617
4/4
✓ Branch 114 → 115 taken 82506288 times.
✓ Branch 114 → 123 taken 573308 times.
✓ Branch 115 → 116 taken 504 times.
✓ Branch 115 → 123 taken 82505784 times.
83079596 if ((get_short_name) && (destination_ptr -> fx_dir_entry_reserved & 0x08))
618 {
619
620 /* Microsoft undocumented NT file name feature... convert short name to lower
621 case. */
622
4/4
✓ Branch 121 → 122 taken 4644 times.
✓ Branch 121 → 123 taken 216 times.
✓ Branch 122 → 117 taken 4356 times.
✓ Branch 122 → 123 taken 288 times.
4860 for (j = 0; j <= (FX_DIR_NAME_SIZE + FX_DIR_EXT_SIZE) && (short_name_ptr[j] != 0x00); j++)
623 {
624
625 /* Determine if an upper case character is present. */
626
4/4
✓ Branch 117 → 118 taken 3906 times.
✓ Branch 117 → 120 taken 450 times.
✓ Branch 118 → 119 taken 2232 times.
✓ Branch 118 → 120 taken 1674 times.
4356 if ((short_name_ptr[j] >= 'A') && (short_name_ptr[j] <= 'Z'))
627 {
628
629 /* Yes, an upper case character is present. Force it to lower case. */
630 2232 short_name_ptr[j] = (CHAR)(short_name_ptr[j] + 32);
631 }
632 }
633 }
634
635 /* Pickup the created time in milliseconds. */
636 83079596 destination_ptr -> fx_dir_entry_created_time_ms = *read_ptr++;
637
638 /* Pickup the created time. */
639 83079596 destination_ptr -> fx_dir_entry_created_time = _fx_utility_16_unsigned_read(read_ptr);
640 83079596 read_ptr = read_ptr + 2; /* Always 2 bytes */
641
642 /* Pickup the created date. */
643 83079596 destination_ptr -> fx_dir_entry_created_date = _fx_utility_16_unsigned_read(read_ptr);
644 83079596 read_ptr = read_ptr + 2; /* Always 2 bytes */
645
646 /* Pickup the last accessed date. */
647 83079596 destination_ptr -> fx_dir_entry_last_accessed_date = _fx_utility_16_unsigned_read(read_ptr);
648 83079596 read_ptr = read_ptr + 2; /* Always 2 bytes */
649
650 /* read the upper 2 bytes of starting cluster - required only for 32 bit FAT */
651
2/2
✓ Branch 126 → 127 taken 71353152 times.
✓ Branch 126 → 129 taken 11726444 times.
83079596 if (media_ptr -> fx_media_32_bit_FAT)
652 {
653
654 /* FAT32 only. */
655 71353152 destination_ptr -> fx_dir_entry_cluster = _fx_utility_16_unsigned_read(read_ptr);
656 71353152 destination_ptr -> fx_dir_entry_cluster <<= 16;
657 }
658 else
659 {
660 /* Not required for non FAT32. */
661 11726444 destination_ptr -> fx_dir_entry_cluster = 0;
662 }
663
664 /* Advance the read pointer. */
665 83079596 read_ptr = read_ptr + 2; /* Always 2 bytes */
666
667 /* Copy the time into the destination. */
668 83079596 destination_ptr -> fx_dir_entry_time = _fx_utility_16_unsigned_read(read_ptr);
669 83079596 read_ptr = read_ptr + 2; /* Always 2 bytes */
670
671 /* Copy the date into the destination. */
672 83079596 destination_ptr -> fx_dir_entry_date = _fx_utility_16_unsigned_read(read_ptr);
673 83079596 read_ptr = read_ptr + 2; /* Always 2 bytes */
674
675 /* Copy the starting cluster into the destination. */
676 83079596 destination_ptr -> fx_dir_entry_cluster += _fx_utility_16_unsigned_read(read_ptr);
677 83079596 read_ptr = read_ptr + 2; /* Always 2 bytes */
678
679 /* Copy the file size into the destination. */
680 83079596 destination_ptr -> fx_dir_entry_file_size = _fx_utility_32_unsigned_read(read_ptr);
681
682 /* Clear the destination search specific fields. */
683 83079596 destination_ptr -> fx_dir_entry_last_search_cluster = 0;
684 83079596 destination_ptr -> fx_dir_entry_last_search_relative_cluster = 0;
685 83079596 destination_ptr -> fx_dir_entry_last_search_log_sector = 0;
686 83079596 destination_ptr -> fx_dir_entry_last_search_byte_offset = 0;
687
688 /* Remember the entry number. */
689 83079596 destination_ptr -> fx_dir_entry_number = entry;
690
691 /* Return entry number. */
692 83079596 *entry_ptr = entry;
693
694 /* Determine if we should remember the last cluster and relative cluster. */
695
2/2
✓ Branch 134 → 135 taken 1558247 times.
✓ Branch 134 → 136 taken 81521349 times.
83079596 if (source_dir)
696 {
697
698 /* Yes, remember the last cluster and relative cluster for a subsequent call
699 to read a directory entry. */
700 1558247 source_dir -> fx_dir_entry_last_search_cluster = cluster;
701 1558247 source_dir -> fx_dir_entry_last_search_relative_cluster = relative_cluster;
702
703 /* Also remember several other items that are unique to the directory... just to verify that the
704 search information can be used. */
705 1558247 source_dir -> fx_dir_entry_last_search_log_sector = source_dir -> fx_dir_entry_log_sector;
706 1558247 source_dir -> fx_dir_entry_last_search_byte_offset = source_dir -> fx_dir_entry_byte_offset;
707 }
708
709 /* Return success to the caller. */
710 83079596 return(FX_SUCCESS);
711 }
712
713
714
715