in ff_ioman.c [1055:1225]
FF_Error_t FF_PartitionSearch( FF_IOManager_t * pxIOManager,
FF_SPartFound_t * pPartsFound )
{
BaseType_t xPartNr;
FF_Buffer_t * pxBuffer;
uint8_t * ucDataBuffer;
BaseType_t isPBR = pdFALSE;
FF_Error_t xError = FF_ERR_NONE;
uint32_t prevTotalSectors = pxIOManager->xPartition.ulTotalSectors;
FF_Part_t pxPartitions[ 4 ];
memset( pPartsFound, '\0', sizeof( *pPartsFound ) );
do
{
pxBuffer = FF_GetBuffer( pxIOManager, 0, FF_MODE_READ );
if( pxBuffer == NULL )
{
xError = FF_ERR_DEVICE_DRIVER_FAILED | FF_PARTITIONSEARCH;
break;
}
/* Disable sector checking in FF_BlockRead
* Let user driver return an error is appropriate. */
pxIOManager->xPartition.ulTotalSectors = 0;
ucDataBuffer = pxBuffer->pucBuffer;
/* Check MBR (Master Boot Record) or
* PBR (Partition Boot Record) signature. */
if( ( FF_getChar( ucDataBuffer, FF_FAT_MBR_SIGNATURE ) != 0x55 ) ||
( FF_getChar( ucDataBuffer, FF_FAT_MBR_SIGNATURE + 1 ) != 0xAA ) )
{
/* No MBR, but is it a PBR ?
* Partition Boot Record */
if( ( FF_getChar( ucDataBuffer, 0 ) == 0xEB ) && /* PBR Byte 0 */
( FF_getChar( ucDataBuffer, 2 ) == 0x90 ) )
{
/* PBR Byte 2
* No MBR but PBR exist then there is only one partition
* Handle this later. */
isPBR = pdTRUE;
}
else
{
FF_PRINTF( "FF_PartitionSearch: [%02X,%02X] No signature (%02X %02X), no PBR neither\n",
FF_getChar( ucDataBuffer, 0 ),
FF_getChar( ucDataBuffer, 2 ),
FF_getChar( ucDataBuffer, FF_FAT_MBR_SIGNATURE ),
FF_getChar( ucDataBuffer, FF_FAT_MBR_SIGNATURE + 1 ) );
/* No MBR and no PBR then no partition found. */
xError = FF_ERR_IOMAN_INVALID_FORMAT | FF_PARTITIONSEARCH;
break;
}
}
/* Copy the 4 partition records into 'pxPartitions': */
FF_ReadParts( ucDataBuffer, pxPartitions );
for( xPartNr = 0; ( xPartNr < 4 ) && ( isPBR == pdFALSE ); xPartNr++ )
{
/* FF_PRINTF ("FF_Part[%d]: id %02X act %02X Start %6lu Len %6lu (sectors)\n", */
/* xPartNr, pxPartitions[ xPartNr ].ucPartitionID, */
/* pxPartitions[ xPartNr ].ucActive, */
/* pxPartitions[ xPartNr ].ulStartLBA, */
/* pxPartitions[ xPartNr ].ulSectorCount); */
if( prvIsExtendedPartition( pxPartitions[ xPartNr ].ucPartitionID ) != pdFALSE )
{
continue; /* Do this later */
}
/* The first sector must be a MBR, then check the partition entry in the MBR */
if( ( pxPartitions[ xPartNr ].ucActive != 0x80 ) &&
( pxPartitions[ xPartNr ].ucActive != 0x00 ) )
{
if( ( xPartNr == 0 ) &&
( FF_getShort( ucDataBuffer, FF_FAT_RESERVED_SECTORS ) != 0 ) &&
( FF_getChar( ucDataBuffer, FF_FAT_NUMBER_OF_FATS ) != 0 ) )
{
isPBR = pdTRUE;
}
else
{
xError = FF_ERR_IOMAN_INVALID_FORMAT | FF_PARTITIONSEARCH;
break;
}
}
else if( pxPartitions[ xPartNr ].ulSectorCount )
{
FF_Part_t * p = &pPartsFound->pxPartitions[ pPartsFound->iCount++ ];
*p = pxPartitions[ xPartNr ];
p->bIsExtended = 0;
if( pPartsFound->iCount >= ffconfigMAX_PARTITIONS )
{
break;
}
}
}
if( FF_isERR( xError ) || ( pPartsFound->iCount >= ffconfigMAX_PARTITIONS ) )
{
break;
}
for( xPartNr = 0; xPartNr < 4; xPartNr++ )
{
if( prvIsExtendedPartition( pxPartitions[ xPartNr ].ucPartitionID ) )
{
xError = FF_ParseExtended( pxIOManager, pxPartitions[ xPartNr ].ulStartLBA,
pxPartitions[ xPartNr ].ulSectorCount, pPartsFound );
if( ( FF_isERR( xError ) != pdFALSE ) || ( pPartsFound->iCount >= ffconfigMAX_PARTITIONS ) )
{
goto done;
}
}
}
if( pPartsFound->iCount == 0 )
{
FF_PRINTF( "FF_Part: no partitions, try as PBR\n" );
isPBR = pdTRUE;
}
if( isPBR )
{
uint8_t media = FF_getChar( ucDataBuffer, FF_FAT_MEDIA_TYPE );
FF_Part_t * p;
if( !prvIsValidMedia( media ) )
{
FF_PRINTF( "FF_Part: Looks like PBR but media %02X\n", media );
xError = FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION | FF_PARTITIONSEARCH;
goto done;
}
/* This looks like a PBR because it has a valid media type */
p = pPartsFound->pxPartitions;
p->ulStartLBA = 0; /* FF_FAT_PTBL_LBA */
p->ulSectorCount = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, FF_FAT_16_TOTAL_SECTORS );
if( p->ulSectorCount == 0ul )
{
p->ulSectorCount = FF_getLong( pxBuffer->pucBuffer, FF_FAT_32_TOTAL_SECTORS );
}
p->ucActive = 0x80; /* FF_FAT_PTBL_ACTIVE */
p->ucPartitionID = 0x0B; /* FF_FAT_PTBL_ID MSDOS data partition */
p->bIsExtended = 0;
pPartsFound->iCount = 1;
}
} while( pdFALSE );
done:
if( pxBuffer )
{
FF_Error_t xTempError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
if( FF_isERR( xError ) == pdFALSE )
{
xError = xTempError;
}
}
pxIOManager->xPartition.ulTotalSectors = prevTotalSectors;
return FF_isERR( xError ) ? xError : pPartsFound->iCount;
} /* FF_PartitionSearch() */