GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 108 / 0 / 108
Functions: 100.0% 3 / 0 / 3
Branches: 81.4% 96 / 0 / 118

fx_partition_offset_calculate.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 /** Application Utility */
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_utility.h"
30
31
32 /* Define internal data structures. */
33
34 typedef struct FX_MEDIA_PARTITION_STRUCT
35 {
36 ULONG fx_media_part_start;
37 ULONG fx_media_part_size;
38 } FX_MEDIA_PARTITION;
39
40 /* Define internal partition constants. */
41
42 #ifndef FX_MAX_PARTITION_COUNT
43 #define FX_MAX_PARTITION_COUNT 16
44 #endif /* FX_MAX_PARTITION_COUNT */
45
46 #define FX_PARTITION_TABLE_OFFSET 446
47 #define FX_PARTITION_ENTRY_SIZE 16
48 #define FX_PARTITION_TYPE_OFFSET 4
49 #define FX_PARTITION_LBA_OFFSET 8
50 #define FX_PARTITION_SECTORS_OFFSET 12
51
52 #define FX_PARTITION_TYPE_FREE 0x00
53 #define FX_PARTITION_TYPE_EXTENDED 0x05
54 #define FX_PARTITION_TYPE_EXTENDED_LBA 0x0F
55
56
57 /* Define function prototypes for the partition table parsing application
58 utility. */
59
60 UINT _fx_partition_offset_calculate(void *partition_sector, UINT partition,
61 ULONG *partition_start, ULONG *partition_size);
62 UINT _fx_utility_partition_get(FX_MEDIA_PARTITION *partition_table,
63 UINT *count, ULONG sector, UCHAR *sector_buffer);
64 UINT _fx_partition_offset_calculate_extended(FX_MEDIA *media_ptr, void *partition_sector, UINT partition,
65 ULONG *partition_start, ULONG *partition_size);
66
67 /**************************************************************************/
68 /* */
69 /* FUNCTION RELEASE */
70 /* */
71 /* _fx_partition_offset_calculate PORTABLE C */
72 /* 6.1.6 */
73 /* AUTHOR */
74 /* */
75 /* William E. Lamie, Microsoft Corporation */
76 /* */
77 /* DESCRIPTION */
78 /* */
79 /* This function calculates the sector offset to the specified */
80 /* partition. The buffer containing the partition table is also */
81 /* supplied to this function. If the buffer supplied is a boot */
82 /* record (which could be the case in non-partition systems), this */
83 /* function returns an offset of zero, the total sectors, and a */
84 /* successful status indicating that the buffer supplied is the boot */
85 /* record. Otherwise, if a partition is found, this function returns */
86 /* the sector offset to its boot record along with a successful */
87 /* status. If the specified partition is not found or the buffer is */
88 /* not a partition table or boot record, this function returns an */
89 /* error. */
90 /* */
91 /* Note: Empty partitions have a FX_SUCCESS return code, however their */
92 /* starting sector is FX_NULL and the size returned is 0. */
93 /* */
94 /* INPUT */
95 /* */
96 /* partition_sector Pointer to buffer containing */
97 /* either the partition table */
98 /* or the boot sector */
99 /* partition Desired partition */
100 /* partition_start Return partition start */
101 /* partition_size Return partition size */
102 /* */
103 /* OUTPUT */
104 /* */
105 /* return status */
106 /* */
107 /* CALLS */
108 /* */
109 /* _fx_utility_partition_get Actual partition parsing */
110 /* routine */
111 /* */
112 /* CALLED BY */
113 /* */
114 /* Application Driver */
115 /* */
116 /**************************************************************************/
117 252 UINT _fx_partition_offset_calculate(void *partition_sector, UINT partition,
118 ULONG *partition_start, ULONG *partition_size)
119 {
120
121 FX_MEDIA_PARTITION partition_table[4];
122 UINT count;
123 ULONG64 total_sectors;
124 UCHAR *partition_sector_ptr;
125
126
127 /* Setup working pointer and initialize count. */
128 252 partition_sector_ptr = partition_sector;
129 252 count = 0;
130
131 /* Check for a real boot sector instead of a partition table. */
132
6/6
✓ Branch 2 → 3 taken 117 times.
✓ Branch 2 → 5 taken 135 times.
✓ Branch 3 → 4 taken 63 times.
✓ Branch 3 → 25 taken 54 times.
✓ Branch 4 → 5 taken 54 times.
✓ Branch 4 → 25 taken 9 times.
252 if ((partition_sector_ptr[0] == 0xe9) || ((partition_sector_ptr[0] == 0xeb) && (partition_sector_ptr[2] == 0x90)))
133 {
134
135 /* Yes, a real boot sector could be present. */
136
137 /* See if there are good values for sectors per FAT. */
138
12/12
✓ Branch 5 → 6 taken 63 times.
✓ Branch 5 → 11 taken 126 times.
✓ Branch 6 → 7 taken 54 times.
✓ Branch 6 → 11 taken 9 times.
✓ Branch 7 → 8 taken 36 times.
✓ Branch 7 → 11 taken 18 times.
✓ Branch 8 → 9 taken 27 times.
✓ Branch 8 → 11 taken 9 times.
✓ Branch 9 → 10 taken 18 times.
✓ Branch 9 → 11 taken 9 times.
✓ Branch 10 → 11 taken 9 times.
✓ Branch 10 → 25 taken 9 times.
189 if (partition_sector_ptr[0x16] || partition_sector_ptr[0x17] || partition_sector_ptr[0x24] || partition_sector_ptr[0x25] || partition_sector_ptr[0x26] || partition_sector_ptr[0x27])
139 {
140
141 /* There are values for sectors per FAT. */
142
143 /* Determine if there is a total sector count. */
144 180 total_sectors = 0;
145
146
4/4
✓ Branch 11 → 12 taken 90 times.
✓ Branch 11 → 13 taken 90 times.
✓ Branch 12 → 13 taken 27 times.
✓ Branch 12 → 14 taken 63 times.
180 if (partition_sector_ptr[0x13] || partition_sector_ptr[0x14])
147 {
148
149 /* Calculate the total sectors, FAT12/16. */
150 117 total_sectors = (((ULONG) partition_sector_ptr[0x14]) << 8) | ((ULONG) partition_sector_ptr[0x13]);
151 }
152
8/8
✓ Branch 14 → 15 taken 45 times.
✓ Branch 14 → 18 taken 18 times.
✓ Branch 15 → 16 taken 36 times.
✓ Branch 15 → 18 taken 9 times.
✓ Branch 16 → 17 taken 27 times.
✓ Branch 16 → 18 taken 9 times.
✓ Branch 17 → 18 taken 18 times.
✓ Branch 17 → 19 taken 9 times.
63 else if (partition_sector_ptr[0x20] || partition_sector_ptr[0x21] || partition_sector_ptr[0x22] || partition_sector_ptr[0x23])
153 {
154
155 /* Calculate the total sectors, FAT32. */
156 54 total_sectors = (((ULONG) partition_sector_ptr[0x23]) << 24) |
157 54 (((ULONG) partition_sector_ptr[0x22]) << 16) |
158 54 (((ULONG) partition_sector_ptr[0x21]) << 8) |
159 54 ((ULONG) partition_sector_ptr[0x20]);
160 }
161
162 /* Determine if there is a total sector count. */
163
2/2
✓ Branch 19 → 20 taken 171 times.
✓ Branch 19 → 25 taken 9 times.
180 if (total_sectors)
164 {
165
166
2/2
✓ Branch 20 → 21 taken 162 times.
✓ Branch 20 → 22 taken 9 times.
171 if (partition_start != FX_NULL)
167 {
168 /* Return an offset of 0, size of boot record, and a successful status. */
169 162 *partition_start = 0;
170 }
171
172 /* Determine if the total sectors is required. */
173
2/2
✓ Branch 22 → 23 taken 162 times.
✓ Branch 22 → 24 taken 9 times.
171 if (partition_size != FX_NULL)
174 {
175
176 /* Return the total sectors. */
177 162 *partition_size = (ULONG)(total_sectors & 0xFFFFFFFF);
178 }
179
180 /* Return success! */
181 171 return(FX_SUCCESS);
182 }
183 }
184 }
185
186 /* Check signature to make sure the buffer is valid. */
187
4/4
✓ Branch 25 → 26 taken 72 times.
✓ Branch 25 → 27 taken 9 times.
✓ Branch 26 → 27 taken 9 times.
✓ Branch 26 → 28 taken 63 times.
81 if ((partition_sector_ptr[510] != 0x55) || (partition_sector_ptr[511] != 0xAA))
188 {
189
190 /* Invalid, return an error. */
191 18 return(FX_NOT_FOUND);
192 }
193
194 /* Not bootable, look for specific partition. */
195 63 _fx_utility_partition_get(partition_table, &count, 0, partition_sector_ptr);
196
197 /* Determine if return value is valid. */
198
2/2
✓ Branch 29 → 30 taken 45 times.
✓ Branch 29 → 31 taken 18 times.
63 if (partition >= count)
199 {
200
201 /* No, return an error. */
202 45 return(FX_NOT_FOUND);
203 }
204
205 /* Return the partition starting sector, if non-NULL. */
206
2/2
✓ Branch 31 → 32 taken 9 times.
✓ Branch 31 → 33 taken 9 times.
18 if (partition_start != FX_NULL)
207 {
208 9 *partition_start = partition_table[partition].fx_media_part_start;
209 }
210
211 /* Return the partition size, if non-NULL. */
212
2/2
✓ Branch 33 → 34 taken 9 times.
✓ Branch 33 → 35 taken 9 times.
18 if (partition_size != FX_NULL)
213 {
214 9 *partition_size = partition_table[partition].fx_media_part_size;
215 }
216
217 /* Return successful completion. */
218 18 return(FX_SUCCESS);
219 }
220
221
222 /**************************************************************************/
223 /* */
224 /* FUNCTION RELEASE */
225 /* */
226 /* _fx_utility_partition_get PORTABLE C */
227 /* 6.1.6 */
228 /* AUTHOR */
229 /* */
230 /* William E. Lamie, Microsoft Corporation */
231 /* */
232 /* DESCRIPTION */
233 /* */
234 /* This function parses the partition sector and completes the */
235 /* supplied partition entry structure. */
236 /* */
237 /* INPUT */
238 /* */
239 /* partition_table Pointer to partition table */
240 /* count Number of partitions found */
241 /* sector Base sector */
242 /* sector_buffer Buffer containing partition */
243 /* table */
244 /* */
245 /* OUTPUT */
246 /* */
247 /* return status */
248 /* */
249 /* CALLS */
250 /* */
251 /* None */
252 /* */
253 /* CALLED BY */
254 /* */
255 /* _fx_partition_offset_calculate Calculate partition offset */
256 /* */
257 /**************************************************************************/
258 63 UINT _fx_utility_partition_get(FX_MEDIA_PARTITION *partition_table,
259 UINT *count, ULONG sector, UCHAR *sector_buffer)
260 {
261
262 UINT i;
263 ULONG base_sector, value;
264
265 /* This parameter has not been supported yet. */
266 FX_PARAMETER_NOT_USED(sector);
267
268 /* Initialize base sector. */
269 63 base_sector = 0;
270
271
2/2
✓ Branch 7 → 3 taken 252 times.
✓ Branch 7 → 8 taken 63 times.
315 for(i = 446; i <= 494; i+=16)
272 {
273
2/2
✓ Branch 3 → 4 taken 189 times.
✓ Branch 3 → 5 taken 63 times.
252 if (sector_buffer[i + 4] == 0) /* no partition entry here */
274 {
275
276 189 partition_table[*count].fx_media_part_start = 0;
277 189 partition_table[*count].fx_media_part_size = 0;
278 }
279 else
280 {
281
282 63 value = (ULONG) sector_buffer[i + 8]; /* little endian start value */
283 63 value = (((ULONG) sector_buffer[i + 9]) << 8) | value;
284 63 value = (((ULONG) sector_buffer[i + 10]) << 16) | value;
285 63 value = (((ULONG) sector_buffer[i + 11]) << 24) | value;
286 63 partition_table[*count].fx_media_part_start = value + base_sector;
287
288 63 value = (ULONG) sector_buffer[i + 12]; /* little endian size value */
289 63 value = (((ULONG) sector_buffer[i + 13]) << 8) | value;
290 63 value = (((ULONG) sector_buffer[i + 14]) << 16) | value;
291 63 value = (((ULONG) sector_buffer[i + 15]) << 24) | value;
292 63 partition_table[*count].fx_media_part_size = value;
293 }
294
295 252 (*count)++;
296 }
297
298 /* Return success. */
299 63 return(FX_SUCCESS);
300 }
301
302 /**************************************************************************/
303 /* */
304 /* FUNCTION RELEASE */
305 /* */
306 /* _fx_partition_offset_calculate_extended PORTABLE C */
307 /* 6.2.0 */
308 /* AUTHOR */
309 /* */
310 /* Xiuwen Cai, Microsoft Corporation */
311 /* */
312 /* DESCRIPTION */
313 /* */
314 /* This function calculates the sector offset to the specified */
315 /* partition. The buffer containing the partition table is also */
316 /* supplied to this function. If the buffer supplied is a boot */
317 /* record (which could be the case in non-partition systems), this */
318 /* function returns an offset of zero, the total sectors, and a */
319 /* successful status indicating that the buffer supplied is the boot */
320 /* record. Otherwise, if a partition is found, this function returns */
321 /* the sector offset to its boot record along with a successful */
322 /* status. If the specified partition is not found or the buffer is */
323 /* not a partition table or boot record, this function returns an */
324 /* error. */
325 /* */
326 /* Note: Empty partitions have a FX_NOT_FOUND return code. */
327 /* Use partition index 0 to 3 for primary partition and index 4 to */
328 /* FX_MAX_PARTITION_COUNT for extended partition. */
329 /* */
330 /* INPUT */
331 /* */
332 /* media_ptr Media control block pointer */
333 /* partition_sector Pointer to buffer containing */
334 /* either the partition table */
335 /* or the boot sector */
336 /* partition Desired partition */
337 /* partition_start Return partition start */
338 /* partition_size Return partition size */
339 /* */
340 /* OUTPUT */
341 /* */
342 /* return status */
343 /* */
344 /* CALLS */
345 /* */
346 /* _fx_utility_16_unsigned_read Read a USHORT from memory */
347 /* _fx_utility_32_unsigned_read Read a ULONG from memory */
348 /* _fx_utility_64_unsigned_read Read a ULONG64 from memory */
349 /* Media driver */
350 /* */
351 /* CALLED BY */
352 /* */
353 /* Application Driver */
354 /* */
355 /**************************************************************************/
356 126 UINT _fx_partition_offset_calculate_extended(FX_MEDIA *media_ptr, void *partition_sector, UINT partition,
357 ULONG *partition_start, ULONG *partition_size)
358 {
359
360 ULONG64 total_sectors;
361 UCHAR *partition_sector_ptr;
362 UCHAR partition_type;
363 UINT i;
364 ULONG base_sector;
365 ULONG base_sector_extended;
366
367
368 /* Setup working pointer. */
369 126 partition_sector_ptr = partition_sector;
370
371 /* Check for a real boot sector instead of a partition table. */
372
4/6
✓ Branch 2 → 3 taken 126 times.
✗ Branch 2 → 5 not taken.
✓ Branch 3 → 4 taken 18 times.
✓ Branch 3 → 21 taken 108 times.
✓ Branch 4 → 5 taken 18 times.
✗ Branch 4 → 21 not taken.
126 if ((partition_sector_ptr[0] == 0xe9) || ((partition_sector_ptr[0] == 0xeb) && (partition_sector_ptr[2] == 0x90)))
373 {
374
375 /* Yes, a real boot sector could be present. */
376
377 /* See if there are good values for sectors per FAT. */
378
1/12
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 11 taken 18 times.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 11 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 11 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 11 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 11 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 21 not taken.
18 if (partition_sector_ptr[0x16] || partition_sector_ptr[0x17] || partition_sector_ptr[0x24] || partition_sector_ptr[0x25] || partition_sector_ptr[0x26] || partition_sector_ptr[0x27])
379 {
380
381 /* There are values for sectors per FAT. */
382
383 /* Get the total sectors, FAT12/16. */
384 18 total_sectors = _fx_utility_16_unsigned_read(&partition_sector_ptr[FX_SECTORS]);
385
386
2/2
✓ Branch 12 → 13 taken 9 times.
✓ Branch 12 → 15 taken 9 times.
18 if (total_sectors == 0)
387 {
388
389 /* Get the total sectors, FAT32. */
390 9 total_sectors = _fx_utility_32_unsigned_read(&partition_sector_ptr[FX_HUGE_SECTORS]);
391 }
392
393 /* Determine if there is a total sector count. */
394
1/2
✓ Branch 15 → 16 taken 18 times.
✗ Branch 15 → 21 not taken.
18 if (total_sectors)
395 {
396
397
2/2
✓ Branch 16 → 17 taken 9 times.
✓ Branch 16 → 18 taken 9 times.
18 if (partition_start != FX_NULL)
398 {
399 /* Return an offset of 0, size of boot record, and a successful status. */
400 9 *partition_start = 0;
401 }
402
403 /* Determine if the total sectors is required. */
404
1/2
✓ Branch 18 → 19 taken 18 times.
✗ Branch 18 → 20 not taken.
18 if (partition_size != FX_NULL)
405 {
406
407 /* Return the total sectors. */
408 18 *partition_size = (ULONG)(total_sectors & 0xFFFFFFFF);
409 }
410
411 /* Return success! */
412 18 return(FX_SUCCESS);
413 }
414 }
415 }
416
417 /* Check signature to make sure the buffer is valid. */
418
3/4
✓ Branch 21 → 22 taken 99 times.
✓ Branch 21 → 23 taken 9 times.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 99 times.
108 if ((partition_sector_ptr[510] != FX_SIG_BYTE_1) || (partition_sector_ptr[511] != FX_SIG_BYTE_2))
419 {
420
421 /* Invalid, return an error. */
422 9 return(FX_NOT_FOUND);
423 }
424
425 /* Not bootable, look for specific partition. */
426
427 /* Check if primary partitions are addressed. */
428
2/2
✓ Branch 24 → 25 taken 27 times.
✓ Branch 24 → 34 taken 72 times.
99 if (partition < 4)
429 {
430
431 /* Get partition type. */
432 27 partition_type = partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + partition * FX_PARTITION_ENTRY_SIZE + FX_PARTITION_TYPE_OFFSET];
433
434 /* Check if there is a vaild partition. */
435
2/2
✓ Branch 25 → 26 taken 18 times.
✓ Branch 25 → 33 taken 9 times.
27 if (partition_type != FX_PARTITION_TYPE_FREE)
436 {
437
438 /* Return the partition starting sector, if non-NULL. */
439
2/2
✓ Branch 26 → 27 taken 9 times.
✓ Branch 26 → 29 taken 9 times.
18 if (partition_start != FX_NULL)
440 {
441 9 *partition_start = _fx_utility_32_unsigned_read(&partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + partition * FX_PARTITION_ENTRY_SIZE + FX_PARTITION_LBA_OFFSET]);
442 }
443
444 /* Return the partition size, if non-NULL. */
445
2/2
✓ Branch 29 → 30 taken 9 times.
✓ Branch 29 → 32 taken 9 times.
18 if (partition_size != FX_NULL)
446 {
447 9 *partition_size = _fx_utility_32_unsigned_read(&partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + partition * FX_PARTITION_ENTRY_SIZE + FX_PARTITION_SECTORS_OFFSET]);
448 }
449
450 /* Return success! */
451 18 return(FX_SUCCESS);
452 }
453 else
454 {
455
456 /* Not partition here. */
457 9 return(FX_NOT_FOUND);
458 }
459 }
460
461 /* Check for invalid parameter. */
462
2/2
✓ Branch 34 → 35 taken 9 times.
✓ Branch 34 → 36 taken 63 times.
72 if (partition > FX_MAX_PARTITION_COUNT)
463 {
464
465 /* Return error. */
466 9 return(FX_NOT_FOUND);
467 }
468
469 63 base_sector = 0;
470
471 /* Loop to find the extended partition table. */
472
2/2
✓ Branch 42 → 37 taken 90 times.
✓ Branch 42 → 43 taken 9 times.
99 for(i = FX_PARTITION_TABLE_OFFSET; i <= FX_PARTITION_TABLE_OFFSET + 3 * FX_PARTITION_ENTRY_SIZE; i += FX_PARTITION_ENTRY_SIZE)
473 {
474
475 /* Get partition type. */
476 90 partition_type = partition_sector_ptr[i + FX_PARTITION_TYPE_OFFSET];
477
3/4
✓ Branch 37 → 38 taken 36 times.
✓ Branch 37 → 39 taken 54 times.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 41 taken 36 times.
90 if (partition_type == FX_PARTITION_TYPE_EXTENDED || partition_type == FX_PARTITION_TYPE_EXTENDED_LBA)
478 {
479 54 base_sector = _fx_utility_32_unsigned_read(&partition_sector_ptr[i + FX_PARTITION_LBA_OFFSET]);
480 54 break;
481 }
482 }
483
484
2/2
✓ Branch 43 → 44 taken 9 times.
✓ Branch 43 → 45 taken 54 times.
63 if (base_sector == 0)
485 {
486
487 /* No extended partition. */
488 9 return(FX_NOT_FOUND);
489 }
490
491 54 base_sector_extended = base_sector;
492
493
1/2
✓ Branch 66 → 46 taken 63 times.
✗ Branch 66 → 67 not taken.
63 for (i = 4; i <= partition; i++)
494 {
495
496 /* Read the partition sector from the device. Build the read sector
497 command. */
498 63 media_ptr -> fx_media_driver_request = FX_DRIVER_READ;
499 63 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
500 63 media_ptr -> fx_media_driver_buffer = partition_sector_ptr;
501 63 media_ptr -> fx_media_driver_logical_sector = base_sector;
502 63 media_ptr -> fx_media_driver_sectors = 1;
503 63 media_ptr -> fx_media_driver_sector_type = FX_UNKNOWN_SECTOR;
504 63 media_ptr -> fx_media_hidden_sectors = 0;
505
506 /* Invoke the driver to read the sector. */
507 63 (media_ptr -> fx_media_driver_entry) (media_ptr);
508
509 /* Determine if the sector was read correctly. */
510
2/2
✓ Branch 47 → 48 taken 9 times.
✓ Branch 47 → 49 taken 54 times.
63 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
511 {
512
513 /* Return error. */
514 9 return(FX_IO_ERROR);
515 }
516
517 /* Check signature to make sure the sector is valid. */
518
3/4
✓ Branch 49 → 50 taken 45 times.
✓ Branch 49 → 51 taken 9 times.
✗ Branch 50 → 51 not taken.
✓ Branch 50 → 52 taken 45 times.
54 if ((partition_sector_ptr[510] != FX_SIG_BYTE_1) || (partition_sector_ptr[511] != FX_SIG_BYTE_2))
519 {
520
521 /* Invalid, return an error. */
522 9 return(FX_NOT_FOUND);
523 }
524
525 /* Determine if this is the desired partition. */
526
2/2
✓ Branch 52 → 53 taken 27 times.
✓ Branch 52 → 62 taken 18 times.
45 if (i == partition)
527 {
528
529 /* Get partition type. */
530 27 partition_type = partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + FX_PARTITION_TYPE_OFFSET];
531
2/2
✓ Branch 53 → 54 taken 18 times.
✓ Branch 53 → 61 taken 9 times.
27 if (partition_type != FX_PARTITION_TYPE_FREE)
532 {
533
534 /* Return the partition starting sector, if non-NULL. */
535
1/2
✓ Branch 54 → 55 taken 18 times.
✗ Branch 54 → 57 not taken.
18 if (partition_start != FX_NULL)
536 {
537 18 *partition_start = _fx_utility_32_unsigned_read(&partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + FX_PARTITION_LBA_OFFSET]) + base_sector;
538 }
539
540 /* Return the partition size, if non-NULL. */
541
1/2
✓ Branch 57 → 58 taken 18 times.
✗ Branch 57 → 60 not taken.
18 if (partition_size != FX_NULL)
542 {
543 18 *partition_size = _fx_utility_32_unsigned_read(&partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + FX_PARTITION_SECTORS_OFFSET]);
544 }
545
546 /* Return success! */
547 18 return(FX_SUCCESS);
548 }
549 else
550 {
551 /* Not partition here. */
552 9 return(FX_NOT_FOUND);
553 }
554 }
555 else
556 {
557
558 /* Get partition type. */
559 18 partition_type = partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + FX_PARTITION_ENTRY_SIZE + FX_PARTITION_TYPE_OFFSET];
560
3/4
✓ Branch 62 → 63 taken 9 times.
✓ Branch 62 → 64 taken 9 times.
✗ Branch 63 → 64 not taken.
✓ Branch 63 → 67 taken 9 times.
18 if (partition_type == FX_PARTITION_TYPE_EXTENDED || partition_type == FX_PARTITION_TYPE_EXTENDED_LBA)
561 {
562
563 /* Update sector number for next partition table. */
564 9 base_sector = _fx_utility_32_unsigned_read(&partition_sector_ptr[FX_PARTITION_TABLE_OFFSET + FX_PARTITION_ENTRY_SIZE + FX_PARTITION_LBA_OFFSET]) + base_sector_extended;
565 }
566 else
567 {
568 /* No valid partition, get out of the loop. */
569 break;
570 }
571 }
572
573 }
574
575 /* Return error. */
576 9 return(FX_NOT_FOUND);
577 }
578