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

📄 fat.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
            // SERPRINT("INFO: %d: File name '%s' File size = 0x%x Attrib(0x%X)  %x\r\n", j, pDirEntry->FileName, pDirEntry->FileSize, pDirEntry->FATTr , pDirEntry);
            result = pDirEntry;
            break;
        }
    }
    //SERPRINT( "INFO: Entries checked(%d): files(%d), dirs(%d), longFnames(%d)\r\n", (lfCnt + dirCnt + fileCnt), fileCnt, dirCnt, lfCnt );
    return( result );
}


PDIRENTRY SearchFAT12And16ForFile( 
    PCHAR   pFileName
)
{
    PDIRENTRY result = NULL;
    USHORT    i = 0;
    ULONG     DirLBA = 0;
    UCHAR     Sector[SECTOR_SIZE];
    USHORT    numEntriesInSector = g_FATParms.BytesPerSect / sizeof( DIRENTRY );
    
    //
    // Look for the filename in directory list.
    //
    for ( i = 0, DirLBA = g_FATParms.RootDirLBA; 
         (result == NULL) && (i < g_FATParms.NumRootEntries + 1); 
         DirLBA++, i += numEntriesInSector )
    {
        memset( &Sector[0], 0, SECTOR_SIZE );

        //SERPRINT("INFO: Reading root directory sector (LBA=0x%x)...\r\n", DirLBA);

        //
        // Read a sector from the root directory.
        //
        if (!ReadSectors( g_FATParms.DriveId, DirLBA, 1, (PUCHAR) Sector ))
        {
            SERPRINT("ERROR: Couldn't read root directory sector (LBA=0x%x).\r\n", DirLBA);
            return(0);
        }
//        EdbgDumpHexBuf((PUCHAR) Sector, SECTOR_SIZE);

        result = SearchBufferForFile( pFileName, &Sector[0], 1 );
    } 

    return( result );
}


PDIRENTRY SearchFAT32ForFile( 
    PCHAR   pFileName
)
{
    PDIRENTRY result = NULL;
    ULONG     Cluster = g_FATParms.RootDirCluster;    // Where the Root starts
    
    do
    {
        // Read the cluster...
        if (!ReadSectors( g_FATParms.DriveId, Cluster2LBA( Cluster ), 
                          g_FATParms.SectsPerClust, (PUCHAR) READ_BUFFER_START ) )
        {
            SERPRINT( "OpenFile ERROR: Couldn't read root directory's cluster %ld(LBA: 0x%04lx)\r\n", 
                      Cluster, Cluster2LBA( Cluster ) );
            return( result );
        }
//        EdbgDumpHexBuf((PUCHAR) READ_BUFFER_START, SECTOR_SIZE);
        
        //
        // Try to find the specified file in the root directory...
        //
        result = SearchBufferForFile( pFileName, (PUCHAR) READ_BUFFER_START, 
                                      g_FATParms.SectsPerClust );
        if ( result != NULL )
        {
            // the file has been found...
            break;
        }
        
        // Root directory in FAT-32 is the same as any other directory...
        // so, get the next cluster...
        Cluster = GetNextCluster( Cluster );
    } while ( TRUE == IsDataCluster( Cluster) );
    
    return( result );
}


//
// Open filename specified and return the size.
//
ULONG OpenFile(PCHAR pFileName)
{
    USHORT i = 0;
    USHORT j = 0;
    BOOL bFound = FALSE;
#if defined( NDEF_DWF_USE_NEW_DIR_READ )        
    ULONG DirLBA = 0;
#if !defined( NDEF_DWF_USE_OLD_READ )       
    UCHAR Sector[SECTOR_SIZE];
#else   // ( NDEF_DWF_USE_OLD_READ )        
    CHAR Sector[SECTOR_SIZE];
#endif  // ( NDEF_DWF_USE_OLD_READ )        
#endif  // ( NDEF_DWF_USE_NEW_DIR_READ )        
    PDIRENTRY pDirEntry = NULL;
    CHAR FileName[11] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};

    SERPRINT("OpenFile %s\r\n", pFileName);
    // 
    // Check caller's parameters.
    //
    if (pFileName == NULL)
        return(0);

    //
    // Convert the filename to the form stored on disk.
    //
    for (i = 0 ; i < 8 && *(pFileName + i) != '\0' && *(pFileName + i) != '.' ; i++)
    {
        FileName[i] = TO_UPPER(*(pFileName + i));
    }
    
    if (*(pFileName + i) == '.')
    {
        i++;
        for (j=0 ; i < 12 && *(pFileName + i) != '\0' ; i++, j++)
            FileName[8 + j] = TO_UPPER(*(pFileName + i));
    }

#if !defined( NDEF_DWF_USE_NEW_DIR_READ )       

    bFound = FALSE;
    if (g_FATParms.FATType != FAT_32)
    {
        SERPRINT("Searching FAT (fat12 or fat16).... \r\n");
        pDirEntry = SearchFAT12And16ForFile( FileName );
    }
    else
    {
        SERPRINT("Searching FAT (fat32).... \"%s\" \r\n", FileName);
        pDirEntry = SearchFAT32ForFile( FileName );
    }
    bFound = (pDirEntry != NULL);

    SERPRINT("Found FAT Entry %x pDirEntry %x\r\n", bFound, pDirEntry);
#else   // ( NDEF_DWF_USE_NEW_DIR_READ )        

    //
    // Look for the filename in directory list.
    //
    for (bFound = FALSE, i = 0, DirLBA = g_FATParms.RootDirLBA ; !bFound && i < g_FATParms.NumRootEntries ; DirLBA++)
    {
        memset(&Sector[0], 0, SECTOR_SIZE);

        // SERPRINT("INFO: Reading root directory sector (LBA=0x%x)...\r\n", DirLBA);

        //
        // Read a sector from the root directory.
        //
#if defined( NDEF_DWF_USE_OLD_READ )        
        if (0 != read_sector( DirLBA, Sector ) )
        {
            SERPRINT("ERROR: Couldn't read root directory sector (LBA=0x%x).\r\n", DirLBA);
            return(0);
        }
#else   // ( NDEF_DWF_USE_OLD_READ )        
        if (!ReadSectors(g_FATParms.DriveId, DirLBA, 1, (PUCHAR) Sector))
        {
            SERPRINT("ERROR: Couldn't read root directory sector (LBA=0x%x).\r\n", DirLBA);
            return(0);
        }
//        EdbgDumpHexBuf((PUCHAR)&Sector[0],SECTOR_SIZE);

#endif  // ( NDEF_DWF_USE_OLD_READ )        

        //
        // Try to find the specified file in the root directory...
        //
        for (pDirEntry = (PDIRENTRY)Sector, j = 0 ; j < (g_FATParms.BytesPerSect / sizeof(DIRENTRY)) && i < g_FATParms.NumRootEntries ; j++, i++, pDirEntry++)
        {
            // SERPRINT("INFO: %d: File name '%s' File size = 0x%x\r\n", j, pDirEntry->FileName, pDirEntry->FileSize);

            if (!memcmp(FileName, (void *)pDirEntry->FileName, 11))
            {
                //
                // Found it.
                //
                bFound = TRUE;
                break;
            }
        }
    } 
#endif  // ( NDEF_DWF_USE_NEW_DIR_READ )        

    if (!bFound)
    {
        SERPRINT("ERROR: Couldn't find file '%s'.\r\n", pFileName); 
        return(0);
    }
    else
    {
        SERPRINT("INFO: Found file '%s' (start cluster = 0x%X:%X size = 0x%x)\r\n", pFileName, pDirEntry->FirstClusterHigh, pDirEntry->FirstClusterLow, pDirEntry->FileSize); 
    }
   
    //
    // Save file parameters
    //
    g_FileInfo.FileSize            = pDirEntry->FileSize;
    g_FileInfo.FirstCluster        = (pDirEntry->FirstClusterHigh << 16);
    g_FileInfo.FirstCluster       += pDirEntry->FirstClusterLow;
    g_FileInfo.CurrentCluster      = g_FileInfo.FirstCluster;
    g_FileInfo.NumContigClusters   = 0;
    g_FileInfo.pCurReadBuffAddr    = g_pReadBuffStart;
    g_FileInfo.NumReadBuffBytes    = 0;
    g_FileInfo.pTotalReadByte      = 0;

    return(g_FileInfo.FileSize);
}


void CloseFile(void)
{
    memset(&g_FileInfo, 0, sizeof(g_FileInfo));

    return;
}


static BOOL InitReadBuffer(ULONG pStartAddress, ULONG Length)
{
    // Check arguments.
    //
    if (pStartAddress == 0)
        return(FALSE);

    // Determine how many clusters are in the read buffer.
    //
    Length /= (g_FATParms.BytesPerSect * g_FATParms.SectsPerClust);

    if (!Length)
    {
        SERPRINT("ERROR: Read buffer should be at least a cluster size in length.\r\n");
        return(FALSE);
    }

    // Store read buffer start and the adjusted length.
    //
    g_pReadBuffStart        = (UCHAR *)pStartAddress;
    g_ReadBuffLenInClusters = Length;

    return(TRUE);
}

CLUSTTYPE GetNextClusterGroup(ULONG StartCluster, PULONG pNumberClusters)
{
    ULONG CurrentCluster = 0;
    ULONG NextCluster = 0;

    *pNumberClusters = 0;

    // TODO - could be a bad cluster - check for it here.

    // Determine number of contiguous clusters.
    //
    NextCluster = StartCluster;
    do
    {
        CurrentCluster = NextCluster;
        *pNumberClusters = *pNumberClusters + 1;
        NextCluster = GetNextCluster(CurrentCluster);
        if (NextCluster != (CurrentCluster + 1))
        {
            break;
        }
    } while(IsDataCluster(NextCluster));

    // Why did we break out of the above loop?
    //
    if (IsEOFCluster(NextCluster))
        return(EOF_CLUSTER);
    if (IsBadCluster(NextCluster))
        return(BAD_CLUSTER);
    if (IsRsvdCluster(NextCluster))
        return(RSVD_CLUSTER);
    return(DATA_CLUSTER);
}


BOOL lReadFile(PUCHAR pAddress, ULONG Length)
{
    ULONG  ClustersToRead = 0;

    // Validate callers parameters.
    //
    if (!pAddress || Length == 0)
        return(FALSE);

//  SERPRINT("lReadFile address=%x  length = %x\r\n",pAddress,Length);

    // Make sure callers called InitReadBuffer before calling us.
    //
    if (!g_pReadBuffStart || g_ReadBuffLenInClusters == 0)
    {
        SERPRINT("ERROR: InitReadBuffer must be called before reading a file.\r\n");
        return(FALSE);
    }

    do
    {
        // Is there data in the read buffer?
        //
        if (g_FileInfo.NumReadBuffBytes)
        {
            if (Length <= g_FileInfo.NumReadBuffBytes)
            {
                // We can satisfy the read request with what's in the read buffer already.
                //
                memcpy(pAddress, g_FileInfo.pCurReadBuffAddr, Length);
                g_FileInfo.NumReadBuffBytes  -= Length;
                g_FileInfo.pCurReadBuffAddr  += Length;
                pAddress                     += Length;
                return(TRUE);
            }
            else
            {
                // Empty the read buffer before loading more.
                //
                memcpy(pAddress, g_FileInfo.pCurReadBuffAddr, g_FileInfo.NumReadBuffBytes);
                Length   -= g_FileInfo.NumReadBuffBytes;
                pAddress += g_FileInfo.NumReadBuffBytes;
            }
        }
    
        //
        // Load the entire read buffer with more data.
        //
    
        // Determine next grouping of clusters that are contiguous (on the storage device).
        if (g_FileInfo.NumContigClusters == 0)
        {
            // If the current cluster isn't the first cluster in the file, then the value is +1 from the last
            // cluster in the contiguous grouping.  Subtract one, follow the link and seek a new grouping.
            //
            if (g_FileInfo.CurrentCluster != g_FileInfo.FirstCluster)
            {
                --g_FileInfo.CurrentCluster;
                if (IsEOFCluster(g_FileInfo.CurrentCluster))
                {
                    SERPRINT("INFO: Reached EOF cluster in FAT file chain.\r\n");
                    return(FALSE);
                }
                g_FileInfo.CurrentCluster = GetNextCluster(g_FileInfo.CurrentCluster);
            }

            // Get the next contiguous grouping of cluster and return the type of the last cluster in the list.
            //
            switch(GetNextClusterGroup(g_FileInfo.CurrentCluster, &g_FileInfo.NumContigClusters))
            {
            case DATA_CLUSTER:
//              SERPRINT("INFO: 0x%x contiguous clusters starting with 0x%x.\r\n", g_FileInfo.NumContigClusters, g_FileInfo.CurrentCluster);
                break;
            case EOF_CLUSTER:
//              SERPRINT("INFO: 0x%x contiguous clusters starting with 0x%x (EOF terminator).\r\n", g_FileInfo.NumContigClusters, g_FileInfo.CurrentCluster);
                break;
            case RSVD_CLUSTER:
                SERPRINT("ERROR: Found reserved cluster in FAT file chain.\r\n");
                return(FALSE);
                break;
            case BAD_CLUSTER:
                SERPRINT("ERROR: Found bad cluster in FAT file chain.\r\n");
                return(FALSE);
                break;
            default:
                SERPRINT("ERROR: Unable to determine contiguous cluster grouping (start cluster = 0x%x).\r\n", g_FileInfo.CurrentCluster);
                return(FALSE); 
            }
        }
    
        // Determine the number of clusters we can read at this time.
        //
        ClustersToRead = MIN(g_ReadBuffLenInClusters, g_FileInfo.NumContigClusters);
    
        // Read data from storage.
        //
        if (!ReadSectors(g_FATParms.DriveId, Cluster2LBA(g_FileInfo.CurrentCluster), (USHORT)(ClustersToRead * g_FATParms.SectsPerClust), g_pReadBuffStart))
        {
            SERPRINT("ERROR: Failed to read data from storage (starting cluster = 0x%x  number of clusters = 0x%x).\r\n", g_FileInfo.CurrentCluster, ClustersToRead);
            return(FALSE);
        }
//        EdbgDumpHexBuf((PUCHAR)g_pReadBuffStart,512*2);
    
        // Update read management data.
        //
        g_FileInfo.NumContigClusters -= ClustersToRead;
        g_FileInfo.CurrentCluster    += ClustersToRead;
        g_FileInfo.pCurReadBuffAddr   = g_pReadBuffStart;
        g_FileInfo.NumReadBuffBytes   = (ClustersToRead * g_FATParms.SectsPerClust * g_FATParms.BytesPerSect);

        if(g_FileInfo.pTotalReadByte ==0)
            EdbgOutputDebugString("Reading Image File.");
        g_FileInfo.pTotalReadByte    += g_FileInfo.NumReadBuffBytes;
        if((g_FileInfo.pTotalReadByte & 0xfffff ) ==0)
            EdbgOutputDebugString(".");
        else if(g_FileInfo.pTotalReadByte >= g_FileInfo.FileSize)
            EdbgOutputDebugString("OK\r\n");
    }
    while (Length);

    return(TRUE);
}

⌨️ 快捷键说明

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