⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
    
    if (FAT_32 == g_FATParms.FATType)
    {
        SERPRINT( "INFO: The dump of Root directory for FAT-32 is not done yet!\n" );
    }
    else
    {
        SERPRINT( "DumpRootDir: FAT-12/FAT16\n" );
        SERPRINT( "Entry  DirName       Cluster      Filesize    \n" );
         //        0x0001 12345678.123  0x0000:0000  0x000000001 
         
        for (sector = g_FATParms.RootDirLBA; 
             (sector < (g_FATParms.RootDirLBA + g_FATParms.SectorsPerFAT)) && !bEndOfDir;
             sector++)
        {
            if (FALSE == ReadSectors( g_FATParms.DriveId, sector, 1, g_pReadBuffStart ) )
            {
                SERPRINT( "ERROR: Couldn't read non-FAT-32 root dir for dump!\r\n" );
                return;
            }
            
            pDirEntry = (DIRENTRY *) g_pReadBuffStart;
            for (i = 0; i < numEntriesPerSector; ++i, pDirEntry++)
            {
                // Since Long filename entries have all 4 lower bits set, we must test for it first...
                if ((pDirEntry->FATTr & 0x0F) != FAT_ATTR_LONG_NAME)
                {
                    memcpy( fName, (UCHAR *)pDirEntry->FileName, (sizeof( fName ) - 1) );
                    SERPRINT( "0x%04lX %11.11s  0x%X:%X  0x%08lX\n", 
                               ((sector - g_FATParms.RootDirLBA) * numEntriesPerSector) + i + 1, 
                               fName, pDirEntry->FirstClusterHigh, 
                               pDirEntry->FirstClusterLow, 
                               pDirEntry->FileSize );
                }
                if (pDirEntry->FileName[0] == 0x00)
                {
                    // According to Microsoft documentation, there are
                    // no other entries after this one to look at...
                    // So, should I trust the documentation???  I don't know!
                    bEndOfDir = TRUE;
                }
            }
        }
    }
    return;
}

#endif  // ( DUMP_ROOT_DIR )

#if defined( DUMP_FAT_TABLE )

void DumpFATTable( void )
{
    unsigned int Cluster;
    unsigned int numClusters;

    BOOL         bDumpFATTable = FALSE;
        
    USHORT       uShort1, uShort2;
        
    ULONG        byteOffset;
    ULONG        numFATSectors2Read =
                    MIN( g_FATParms.SectorsPerFAT, 
                        (READ_BUFFER_LENGTH_MAX / g_FATParms.BytesPerSect) );
    ULONG        clusterValue = 0;

    if ( !bDumpFATTable )
    {
        SERPRINT( "\r\nFAT Table dump is currently disabled\r\n" );
        return;
    }
    
    // Dump the entire FAT table to SERPRINT...
    SERPRINT("\r\nFAT table dump: FAT starts at LBA(0x%04lX) Size(0x%04lX)\r\n", g_FATParms.FATLBA, g_FATParms.SectorsPerFAT );
    SERPRINT("\r\n");

    if (FALSE == ReadSectors( g_FATParms.DriveId, g_FATParms.FATLBA, 
                              numFATSectors2Read, g_pReadBuffStart ) )
    {
        SERPRINT( "ERROR: Couldn't read FAT table for dump!\r\n" );
        return;
    }
    
    switch( g_FATParms.FATType )
    {
      case FAT_12:
        // each cluster takes 12 bits...
        numClusters = 
            MIN( g_FATParms.CountOfClusters, 
                 ((numFATSectors2Read * g_FATParms.BytesPerSect * 3) / 2 ) );
        break;
      case FAT_32:
        // each cluster takes 32 bits...
        numClusters = 
            MIN( g_FATParms.CountOfClusters, 
                 (numFATSectors2Read  * g_FATParms.BytesPerSect)/ sizeof( ULONG ) );
        numClusters = 0x18B0; // too many clusters otherwise!!!
        break;
      case FAT_16:
      default:
        // each cluster takes 16 bits...
        numClusters = 
            MIN( g_FATParms.CountOfClusters, 
                (numFATSectors2Read * g_FATParms.BytesPerSect)/ sizeof( USHORT ) );
        break;
    }
    SERPRINT( "\r\nCluster      Value\r\n" );
                 //0x00000000   0x00000000
    // The first cluster is 2...
    for (Cluster = 2; Cluster < (numClusters + 1); ++Cluster)
    {
        switch(g_FATParms.FATType)
        {
          case FAT_12:
            // each cluster takes 12 bits...
            // Cluster: 2   3    4   5    6   7    8   9    A   B    C   D   
            //          22 23 33 44 45 55 66 67 77 88 89 99 AA AB BB CC CD DD
            // Cluster: E   F    10  11   12  13   14  15   16  17   18  19
            //          EE EF FF 00 01 11 22 23 33 44 45 55 66 67 77 88 89 99
            // Cluster: 1A  1B   1C  1D
            //          AA AB BB CC CD DD
            byteOffset = (Cluster * 3)/2;
            // Get the bytes to be processed...
            uShort1 = *((PUCHAR) (g_pReadBuffStart + byteOffset));
            uShort2 = *((PUCHAR) (g_pReadBuffStart + byteOffset + 1));
            // determine if the cluster is odd or even...
            if (Cluster & 0x01)
            {
                // how odd, an odd cluster number!
                uShort1 = (uShort1 >> 4);
                uShort2 = (uShort2 << 4);
                clusterValue = uShort1 | uShort2;
            }
            else
            {
                // must be an even cluster, uShort1 does not change...
                uShort2 = (uShort2 & 0x0F);
                uShort2 = (uShort2 << 8);
                clusterValue = uShort1 | uShort2;
            }
            break;
          case FAT_32:
            byteOffset = Cluster * sizeof( ULONG );
            clusterValue = *((PULONG) (g_pReadBuffStart + byteOffset));
            break;
          case FAT_16:
          default:
            byteOffset = Cluster * sizeof( USHORT );
            clusterValue = *((PUSHORT) (g_pReadBuffStart + byteOffset));
            break;
        }
        SERPRINT( "0x%08X   0x%08lX\r\n", Cluster, clusterValue );
    }
    SERPRINT( "\r\nEnd of FAT table dump\n" );
}

#endif  // ( DUMP_FAT_TABLE )

//
// Initialize the FAT subsystem.
//
BOOL InitFAT(ULONG uFirstPartitionLBA)
{
    UCHAR bsect[SECTOR_SIZE];
    PBIOSPB pBPB = NULL;
    tOffset36_FAT16 *pFAT16Extension = NULL;
    tOffset36_FAT32 *pFAT32Extension = NULL;
    
    ULONG ReadBufferLen = 0;
    UCHAR FATType[9];
#if defined( NDEF_DWF_PARTIIONS )
    pPARTITION_ENTRY pPartition = NULL;
    int i;
#endif  // ( NDEF_DWF_PARTIIONS )
    
    // Locate and verify single active partition in MBR.

    memset (&bsect[0], 0, SECTOR_SIZE);
    if (FALSE == ReadSectors( g_FATParms.DriveId, uFirstPartitionLBA, 1, (PUCHAR) &bsect[0] ) )
    {
        SERPRINT( "ERROR: Couldn't read BOOT in FAT.\r\n" );
        return(-1);
    }
    // EdbgDumpHexBuf((PUCHAR)&bsect[0],SECTOR_SIZE);

    //
    // The BIOS parameter block is in the MBR just read, so point to that block...
    // 
    pBPB = (PBIOSPB)&bsect[0];

    // setup the extension ptrs for later use...
    pFAT16Extension = (tOffset36_FAT16 *)&pBPB->Offset36Extension[ 0 ];
    pFAT32Extension = (tOffset36_FAT32 *)&pBPB->Offset36Extension[ 0 ];
    
    //
    // Determine FAT type by determining the "count of cluster" on the volume.
    // 
    
    // First find the number of sectors in the root directory.  This will always
    // be zero for FAT32 volumes because pBPB->NumRootEntries will be zero!
    //
    g_FATParms.RootDirSectors = 
      ((pBPB->NumRootEntries * 32) + (pBPB->BytesPerSect - 1)) / pBPB->BytesPerSect + uFirstPartitionLBA;
    
    // Determine size of FAT tables...
    if ( pBPB->SectsPerFAT16 != 0 )
    {
        g_FATParms.SectorsPerFAT = pBPB->SectsPerFAT16;
    }
    else
    {
        // it is beginning to look a lot like FAT32!!!
        // but we are not done yet!
        g_FATParms.SectorsPerFAT = pFAT32Extension->SectsPerFAT32;
    }
    
    if ( pBPB->TotalSectors16 != 0 )
    {
        g_FATParms.TotalSectors = pBPB->TotalSectors16;
    }
    else
    {
        g_FATParms.TotalSectors = pBPB->TotalSectors32;
    }
    

    g_FATParms.NumFATs = pBPB->NumFATs;
    g_FATParms.ReservedSects = pBPB->RsvdSects;
    g_FATParms.NumHiddenSectors = pBPB->NumHiddenSectors;
    

    g_FATParms.DataRegionSectors = 
        g_FATParms.TotalSectors - 
          (g_FATParms.ReservedSects + (g_FATParms.NumFATs * g_FATParms.SectorsPerFAT) + 
           g_FATParms.RootDirSectors);
           
    // It is okay that the following calculation rounds down!
    g_FATParms.CountOfClusters = g_FATParms.DataRegionSectors / pBPB->SectsPerClust;
    
    if ( g_FATParms.CountOfClusters < 4085 )
    {
        g_FATParms.FATType = FAT_12;
    }
    else if ( g_FATParms.CountOfClusters < 65525 )
    {
        g_FATParms.FATType = FAT_16;
    }
    else
    {
        g_FATParms.FATType = FAT_32;
    }

    //
    // Get the FAT filesystem description.
    //
    if ( (g_FATParms.FATType == FAT_12) ||
         (g_FATParms.FATType == FAT_16) )
    {
        memcpy(FATType, (void *)pFAT16Extension->TypeFAT16, 8);
    }
    else
    {
        memcpy(FATType, (void *)pFAT32Extension->TypeFAT32, 8);
    }
    FATType[8] = '\0';
    
    //
    // Compute LBA for various disk regions.
    //

    // The start of the data region, the first sector of cluster 2 is...
    g_FATParms.DataStartLBA = g_FATParms.ReservedSects + 
                              (g_FATParms.NumFATs * g_FATParms.SectorsPerFAT) +
                              g_FATParms.RootDirSectors;
    
    g_FATParms.NumRootEntries = pBPB->NumRootEntries;
    g_FATParms.BytesPerSect = pBPB->BytesPerSect;

    if (g_FATParms.FATType == FAT_32)
    {
        g_FATParms.RootDirCluster = pFAT32Extension->RootFirstCluster;
        g_FATParms.RootDirLBA = Cluster2LBA( g_FATParms.RootDirCluster );
        g_FATParms.DriveId  = pFAT32Extension->DriveId32;
        // FAT LBA starts right after the reserved sectors
        g_FATParms.FATLBA = g_FATParms.ReservedSects + uFirstPartitionLBA;

    }
    else
    {
        // FAT-12/16 FAT root is not an allocated cluster!
        g_FATParms.RootDirCluster = 0;  
        // Since it is not an allocated cluster, then calculate the LBA 
        // here...
        g_FATParms.RootDirLBA = 
            g_FATParms.DataStartLBA - 
              ((sizeof(DIRENTRY) * g_FATParms.NumRootEntries) / g_FATParms.BytesPerSect);
        g_FATParms.DriveId  = pFAT16Extension->DriveId16;
        // FAT LBA starts right after the reserved sectors
        g_FATParms.FATLBA = g_FATParms.ReservedSects + uFirstPartitionLBA;
    }
    
    if ((sizeof(DIRENTRY) * g_FATParms.NumRootEntries) % g_FATParms.BytesPerSect)
    {
        --g_FATParms.RootDirLBA;
    }
    
    g_FATParms.SectsPerClust = pBPB->SectsPerClust;
    g_FATParms.NumHeads = (USHORT) pBPB->NumHeads;
    g_FATParms.SectsPerTrack = pBPB->SectsPerTrack;

    // Some BIOS/floppy combinations don't support multi-sector reads.
    // On a PC BIOS based system, a drive ID < 0x80 is a floppy disk.
    // We will not have that here!  So, set the ReadBufferLen to the
    // maximum rather than the number of bytes per sector!
    // ReadBufferLen = ((pBPB->DriveId < 0x80) ? g_FATParms.BytesPerSect : READ_BUFFER_LENGTH_MAX);
    ReadBufferLen = READ_BUFFER_LENGTH_MAX;

    //
    // Initialize the read buffer.
    //
    if (!InitReadBuffer(READ_BUFFER_START, ReadBufferLen))
    {
        SERPRINT("ERROR: Failed to initialize read buffer.\r\n");
        return(FALSE);
    }

#if defined( DUMP_FAT_INFO )
    SERPRINT("\r\nDrive Info:\r\n");
    SERPRINT(" - Drive ID ................... 0x%x\r\n", g_FATParms.DriveId);
    SERPRINT(" - Heads ...................... 0x%x\r\n", g_FATParms.NumHeads);
    SERPRINT(" - Number of Sectors Per Track  0x%x\r\n", g_FATParms.SectsPerTrack);
    SERPRINT(" - Sector Size ...............  0x%x\r\n\r\n", g_FATParms.BytesPerSect);

    SERPRINT("FAT Info:\r\n");
    SERPRINT(" - FAT Type ................... %s(%d)\r\n", FATType, g_FATParms.FATType );
    SERPRINT(" - Cluster Size ............... 0x%x\r\n", (g_FATParms.SectsPerClust * g_FATParms.BytesPerSect));
    SERPRINT(" - Number of FATs ............. 0x%x\r\n", g_FATParms.NumFATs);
    SERPRINT(" - Number of Sectors Per FAT .. 0x%x\r\n", g_FATParms.SectorsPerFAT);
    SERPRINT(" - Number of Hidden Sectors ... 0x%x\r\n", g_FATParms.NumHiddenSectors);
    SERPRINT(" - Number of Reserved Sectors . 0x%x\r\n\r\n", g_FATParms.ReservedSects);
    SERPRINT(" - Root dir location (LBA) .... 0x%x\r\n", g_FATParms.RootDirLBA);
    SERPRINT(" - FAT location (LBA) ......... 0x%x\r\n", g_FATParms.FATLBA);
    SERPRINT(" - Data location (LBA) ........ 0x%x\r\n\r\n", g_FATParms.DataStartLBA);
    
#if defined( DUMP_ROOT_DIR )
    DumpRootDir();
#endif  // (DUMP_ROOT_DIR )

#if defined( DUMP_FAT_TABLE )
    DumpFATTable();
#endif  // ( DUMP_FAT_TABLE )
    
#endif  // ( DUMP_FAT_INFO )

#if defined( NDEF_DWF_PARTIIONS )
    i = 0;
    pPartition = (pPARTITION_ENTRY) &bsect[ 446 ];
    while (i < 4)
    {
        SERPRINT(" - partion %2d: bootFlag(0x%X) type(0x%X) LBA(0x%08lX)\r\n",
                   i, pPartition->ucBootFlag, pPartition->ucPartitionType,
                   pPartition->startLBA );
        pPartition++;
        ++i;
    }
#endif  // ( NDEF_DWF_PARTIIONS )
    return(TRUE); 
}


PDIRENTRY SearchBufferForFile( 
    PCHAR   pFileName, 
    PUCHAR  pBuffer, 
    USHORT  uiNumSectors
)
{
    PDIRENTRY result = NULL;
    PDIRENTRY pDirEntry = NULL;
    USHORT j = 0;
    int dirCnt = 0;
    int lfCnt = 0;
    int fileCnt = 0;  
    
    //
    // Try to find the specified file in the root directory...
    //
    for ( pDirEntry = (PDIRENTRY) pBuffer, j = 0; 
          j < (g_FATParms.BytesPerSect * uiNumSectors) / sizeof(DIRENTRY);
          j++, pDirEntry++ )
    {
        // Since Long filename entries have all 4 lower bits set, we must test for it first...
        if ((pDirEntry->FATTr & 0x0F) == FAT_ATTR_LONG_NAME)
        {
            lfCnt++;
            // SERPRINT( "INFO: Skipped Long Filename entry ('%s'), attrib(0x%X)\r\n", pDirEntry->FileName, pDirEntry->FATTr );
            continue;
        }
        if ((pDirEntry->FATTr & 0x10) == FAT_ATTR_DIRECTORY)
        {
            dirCnt++;
            // SERPRINT( "INFO: Skipped directory entry ('%s'), attrib(0x%X)\r\n", pDirEntry->FileName, pDirEntry->FATTr );
            continue;
        }
        
        fileCnt++;
        
        if (!memcmp(pFileName, (void *)pDirEntry->FileName, 11))
        {
            //
            // Found it, so get ready to return a ptr to it...
            //
            // SERPRINT("INFO: Found the file!!\r\n" );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -