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 |