@@ -708,18 +708,18 @@ static uint8_t ucAssumeFATType = 0;
708
708
* The end-of-chain value in the FAT table may also help to determine the
709
709
* correct FAT-type:
710
710
*
711
- * endOfChain = bits 4-32 at beginning of table
712
- * FAT-12: endOfChain == 0x0FF8
713
- * FAT-16: endOfChain == 0xFFF8
714
- * FAT-32: endOfChain == 0x0FFFFFF8
711
+ * ulFirstCluster = the first 32-bit of the FAT.
712
+ * FAT-12: endOfChain == 0x00000FF8 - 12 bits
713
+ * FAT-16: endOfChain == 0x0000FFF8 - 16 bits
714
+ * FAT-32: endOfChain == 0x0FFFFFF8 - 32 bits
715
715
*/
716
716
717
717
static FF_Error_t prvDetermineFatType ( FF_IOManager_t * pxIOManager )
718
718
{
719
719
FF_Partition_t * pxPartition ;
720
720
FF_Buffer_t * pxBuffer ;
721
- /* final cluster sentinel value */
722
- uint32_t ulEndOfChain = 0ul ;
721
+ /* The first 32-bits of the FAT. */
722
+ uint32_t ulFirstCluster = 0U ;
723
723
FF_Error_t xError = FF_ERR_NONE ;
724
724
725
725
pxPartition = & ( pxIOManager -> xPartition );
@@ -754,7 +754,8 @@ static FF_Error_t prvDetermineFatType( FF_IOManager_t * pxIOManager )
754
754
}
755
755
else
756
756
{
757
- ulEndOfChain = FF_getLong ( pxBuffer -> pucBuffer , 0x0000 ) & 0xFFFFFFF8ul ;
757
+ /* Read the first 4 bytes at offset 0. */
758
+ ulFirstCluster = FF_getLong ( pxBuffer -> pucBuffer , 0U );
758
759
xError = FF_ReleaseBuffer ( pxIOManager , pxBuffer );
759
760
}
760
761
}
@@ -767,13 +768,23 @@ static FF_Error_t prvDetermineFatType( FF_IOManager_t * pxIOManager )
767
768
/* FAT12 */
768
769
pxPartition -> ucType = FF_T_FAT12 ;
769
770
#if ( ffconfigFAT_CHECK != 0 )
770
- if ( ulEndOfChain != 0x0FF8 )
771
+ /* Keep bits 4..11 */
772
+
773
+ /* MS-DOS/PC DOS 3.3 and higher treats a value of 0xFF0 on FAT12.
774
+ * See https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system
775
+ */
776
+ ulFirstCluster &= 0xFF0U ;
777
+
778
+ if ( ulFirstCluster != 0xFF0U )
771
779
{
772
780
xError = FF_createERR ( FF_ERR_IOMAN_NOT_FAT_FORMATTED , FF_DETERMINEFATTYPE );
781
+ FF_PRINTF ( "FAT_CHECK: FAT12 Partition has unexpected FAT data %04lX\n" ,
782
+ ulFirstCluster );
773
783
}
774
784
else
775
785
#endif /* ffconfigFAT_CHECK */
776
786
{
787
+ /* FAT12 entry OK. */
777
788
xError = FF_ERR_NONE ;
778
789
}
779
790
}
@@ -785,39 +796,52 @@ static FF_Error_t prvDetermineFatType( FF_IOManager_t * pxIOManager )
785
796
/* FAT 16 */
786
797
pxPartition -> ucType = FF_T_FAT16 ;
787
798
#if ( ffconfigFAT_CHECK != 0 )
799
+ {
800
+ /* Keep bits 4..15 */
801
+ ulFirstCluster &= 0xFFF8U ;
802
+
803
+ if ( ulFirstCluster == 0xFFF8U )
788
804
{
789
- if ( ulEndOfChain == 0xFFF8 )
805
+ /* FAT16 entry OK. */
806
+ xError = FF_ERR_NONE ;
807
+ }
808
+ else
809
+ {
810
+ if ( ( ulFirstCluster & 0xFF8U ) == 0xFF8U )
790
811
{
791
- xError = FF_ERR_NONE ;
812
+ FF_PRINTF ( "FAT_CHECK: FAT16 Part at %lu is probably a FAT12\n" , pxIOManager -> xPartition . ulFATBeginLBA ) ;
792
813
}
793
814
else
794
815
{
795
- if ( ulEndOfChain == 0x0FF8 )
796
- {
797
- FF_PRINTF ( "Part at %lu is probably a FAT12\n" , pxIOManager -> xPartition .ulFATBeginLBA );
798
- }
799
- else
800
- {
801
- FF_PRINTF ( "Partition at %lu has strange FAT data %08lX\n" ,
802
- pxIOManager -> xPartition .ulFATBeginLBA , ulEndOfChain );
803
- }
804
-
805
- xError = FF_createERR ( FF_ERR_IOMAN_INVALID_FORMAT , FF_DETERMINEFATTYPE );
816
+ FF_PRINTF ( "FAT_CHECK: FAT16 Partition has unexpected FAT data %08lX\n" ,
817
+ ulFirstCluster );
806
818
}
819
+
820
+ xError = FF_createERR ( FF_ERR_IOMAN_INVALID_FORMAT , FF_DETERMINEFATTYPE );
807
821
}
822
+ }
808
823
#endif /* ffconfigFAT_CHECK */
809
824
}
810
825
else
811
826
{
812
827
/* FAT 32! */
813
828
pxPartition -> ucType = FF_T_FAT32 ;
814
829
#if ( ffconfigFAT_CHECK != 0 )
815
- if ( ulEndOfChain != 0x0FFFFFF8 )
830
+ /* Keep bits 4..27 */
831
+ ulFirstCluster &= 0x0FFFFFF8UL ;
832
+
833
+ if ( ulFirstCluster != 0x0FFFFFF8UL )
816
834
{
817
- xError = FF_createERR ( FF_ERR_IOMAN_NOT_FAT_FORMATTED , FF_DETERMINEFATTYPE );
835
+ FF_PRINTF ( "FAT_CHECK: FAT32 Partition at %lu has unexpected FAT data %08lX\n" ,
836
+ pxIOManager -> xPartition .ulFATBeginLBA , ulFirstCluster );
837
+ xError = FF_ERR_IOMAN_NOT_FAT_FORMATTED ;
818
838
}
839
+ else
819
840
#endif /* ffconfigFAT_CHECK */
820
- xError = FF_ERR_NONE ;
841
+ {
842
+ /* FAT32 entry OK. */
843
+ xError = FF_ERR_NONE ;
844
+ }
821
845
}
822
846
}
823
847
0 commit comments