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

📄 sdfat.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 4 页
字号:
}

BOOL FATIsArchive(PFILEINFO pFileInfo){
    return (pFileInfo->FileAttribute&DIRENTRY_ARCHIVE) != 0;
}

BOOL FATEndOfFile(PFILEINFO pFileInfo){
    return pFileInfo->CurrentPostion >= pFileInfo->FileLength;
}

DWORD FATGetFileSize(PFILEINFO pFileInfo){
    return pFileInfo->FileLength;
}

DWORD FATGetFilePos(PFILEINFO pFileInfo){
    return pFileInfo->CurrentPostion;
}

BOOL FATSetFilePos(PFILEINFO pFileInfo, DWORD dwPos){
    PPARTITION pPartition;
    // parameter check
    if(pFileInfo->PartitionNumber >= PartitionNumber){
        return FAT_ERROR;
    }
    // adjust dwPos, if need
    if(dwPos > pFileInfo->FileLength){
        dwPos = pFileInfo->FileLength;
    }
    // start seeking...
    pPartition = &Partition[pFileInfo->PartitionNumber];
    if(pFileInfo->StartingCluster == FAT_ROOTCLUSTER){ // handle root specially
        // root area is continuous, simply assign new position
        pFileInfo->CurrentPostion = dwPos;
    }
    else{ // not root...
        DWORD dwStartCluster, dwClusterNumber;
        if(dwPos < pFileInfo->CurrentPostion){ // prev
            dwStartCluster  = pFileInfo->StartingCluster;
            dwClusterNumber = dwPos/pPartition->LengthPerCluster;
        }
        else{ // next
            dwStartCluster  = pFileInfo->CurrentCluster;
            dwClusterNumber = dwPos/pPartition->LengthPerCluster-
                pFileInfo->CurrentPostion/pPartition->LengthPerCluster;
        }
        // one time pass one cluster
        while(dwClusterNumber--){
            // go to next cluster
            dwStartCluster = GetFATEntry(pFileInfo->PartitionNumber, dwStartCluster);
            // verify it
            if(!IsAllocFATEntry(pFileInfo->PartitionNumber, dwStartCluster) && dwPos<pFileInfo->FileLength){
                return FAT_ERROR; // invalid cluster
            }
        }
        // update state
        pFileInfo->CurrentPostion = dwPos;
        pFileInfo->CurrentCluster = dwStartCluster;
    }
    return TRUE;
}

DWORD FATReadFile(PFILEINFO pFileInfo, PVOID pBuffer, DWORD dwLength){
    DWORD dwSavedLength;
    PPARTITION pPartition;
    // parameter check
    if(pFileInfo->PartitionNumber >= PartitionNumber){
        return FAT_ERROR;
    }
    if(pFileInfo->CurrentPostion >= pFileInfo->FileLength){ // end of file
        return 0; // no more data to read
    }
    // adjust dwLength, if need
    if(pFileInfo->CurrentPostion+dwLength > pFileInfo->FileLength){
        dwLength = pFileInfo->FileLength-pFileInfo->CurrentPostion;
    }
    // save length for later use
    dwSavedLength = dwLength;
    // start reading...
    pPartition = &Partition[pFileInfo->PartitionNumber];
    if(pFileInfo->StartingCluster == FAT_ROOTCLUSTER){ // handle root specially
        // root area is continuous, just need read one time
        DWORD dwReadBytes = FATReadPartition(pFileInfo->PartitionNumber,
            pBuffer, dwLength, pPartition->StartingRootEntry+pFileInfo->CurrentPostion);
        // error check
        if(dwReadBytes == FAT_ERROR){
            return FAT_ERROR;
        }
        // update state info
        (PBYTE)pBuffer += dwReadBytes;
        dwLength -= dwReadBytes;
        pFileInfo->CurrentPostion += dwReadBytes;
    }
    else{ // not root...
        FILEINFO fnFileInfo = *pFileInfo; // make copy for error tolerance
        while(dwLength){ // not end
            // offset from current cluster
            DWORD dwOffset = fnFileInfo.CurrentPostion%pPartition->LengthPerCluster;
            // maximum bytes we can read at one time
            DWORD dwReadBytes = pPartition->LengthPerCluster-dwOffset;
            // adjust dwReadBytes, if need
            if(dwReadBytes > dwLength){
                dwReadBytes = dwLength;
            }
            // read one cluster
            dwReadBytes = FATReadPartition(fnFileInfo.PartitionNumber, pBuffer, dwReadBytes, pPartition->StartingCluster+
                pPartition->LengthPerCluster*(fnFileInfo.CurrentCluster-FAT_STARTCLUSTER)+dwOffset);
            // error check
            if(dwReadBytes == FAT_ERROR){
                return FAT_ERROR;
            }
            // update state info
            (PBYTE)pBuffer += dwReadBytes;
            dwLength -= dwReadBytes;
            fnFileInfo.CurrentPostion += dwReadBytes;
            if(fnFileInfo.CurrentPostion%pPartition->LengthPerCluster == 0){ // end of cluster
                // go to next cluster
                fnFileInfo.CurrentCluster = GetFATEntry(fnFileInfo.PartitionNumber, fnFileInfo.CurrentCluster);
                //  verify it
                if(!IsAllocFATEntry(fnFileInfo.PartitionNumber, fnFileInfo.CurrentCluster) &&
                   fnFileInfo.CurrentPostion<fnFileInfo.FileLength){ // not end of file){
                    return FAT_ERROR; // invalid cluster
                }
            }
        }
        *pFileInfo = fnFileInfo; // everything is ok, copy back
    }
    return dwSavedLength-dwLength;
}

DWORD FATReadFileEx(PFILEINFO pFileInfo, PVOID pBuffer, DWORD dwLength, DWORD dwPos){
    return FATSetFilePos(pFileInfo, dwPos)?FATReadFile(pFileInfo, pBuffer, dwLength):FAT_ERROR;
}

// dump function for testing only
VOID DumpMasterBootRecord(){
    DWORD dwMBRNo, dwPartNo;
    // dumping...
    for(dwMBRNo = 0; dwMBRNo < MasterBootRecordNumber; ++dwMBRNo){
        OALLog(L"Signature:%04X\r\n", MasterBootRecord[dwMBRNo].Signature);
        //        123 1234 1234 12345 123456  1234 12345 123456 123456 123456789012 1234567890123
        OALLog(L"|No.|Boot|Head/Track/Sector--Head/Track/Sector|System|Start Sector|Sector Number|\r\n");
        for(dwPartNo = 0; dwPartNo < PARTITION_NUMBER; ++dwPartNo){
            OALLog(L"|%3d|  %02X|%4u/%5u/%6u  %4u/%5u/%6u|    %02X|%12u|%13u|\r\n",
                   dwPartNo,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].BootIndicator,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].StartingHead,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].StartingCylinder,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].StartingSector,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].EndingHead,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].EndingCylinder,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].EndingSector,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].SystemId,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].RelativeSector,
                   MasterBootRecord[dwMBRNo].Partition[dwPartNo].TotalSector
                );
        }
    }
}

VOID DumpPartitionBootSector(DWORD dwPartNo){
    // parameter check
    if(dwPartNo >= PartitionNumber){
        KITLOutputDebugString("Partition Number beyond scope\r\n");
        return;
    }
    // dumping...
    OALLog(L"JumpCode            : %06X\r\n" , *((UINT32*)(RawPartition[dwPartNo].JumpCode))&0x00FFFFFF);
    OALLog(L"CreatorID           : %.8S\r\n" , RawPartition[dwPartNo].CreatorID);
    OALLog(L"SectorSize          : %u\r\n"   , RawPartition[dwPartNo].SectorSize);
    OALLog(L"SectorPerCluster    : %u\r\n"   , RawPartition[dwPartNo].SectorPerCluster);
    OALLog(L"ReservedSector      : %u\r\n"   , RawPartition[dwPartNo].ReservedSector);
    OALLog(L"NumberOfFAT         : %u\r\n"   , RawPartition[dwPartNo].NumberOfFAT);
    OALLog(L"NumberOfRootEntry   : %u\r\n"   , RawPartition[dwPartNo].NumberOfRootEntry);
    OALLog(L"TotalSector         : %u\r\n"   , RawPartition[dwPartNo].TotalSector);
    OALLog(L"MediumId            : %02X\r\n" , RawPartition[dwPartNo].MediumId);
    OALLog(L"SectorPerFAT        : %u\r\n"   , RawPartition[dwPartNo].SectorPerFAT);
    OALLog(L"SectorPerTrack      : %u\r\n"   , RawPartition[dwPartNo].SectorPerTrack);
    OALLog(L"NumberOfSide        : %u\r\n"   , RawPartition[dwPartNo].NumberOfSide);
    OALLog(L"NumberOfHiddenSector: %u\r\n"   , RawPartition[dwPartNo].NumberOfHiddenSector);
    OALLog(L"TotalSector2        : %u\r\n"   , RawPartition[dwPartNo].TotalSector2);
    if(Partition[dwPartNo].FileSystem == PART_FAT32){
        OALLog(L"SectorPerFAT2       : %u\r\n"   , RawPartition[dwPartNo].FAT32.SectorPerFAT);
        OALLog(L"ExtentFlag          : %04X\r\n" , RawPartition[dwPartNo].FAT32.ExtentFlag);
        OALLog(L"FileSystemVersion   : %04X\r\n" , RawPartition[dwPartNo].FAT32.FileSystemVersion);
        OALLog(L"RootEntryCluster    : %u\r\n"   , RawPartition[dwPartNo].FAT32.RootEntryCluster);
        OALLog(L"FileSystemInfomation: %u\r\n"   , RawPartition[dwPartNo].FAT32.FileSystemInfomation);
        OALLog(L"BackupBootSector    : %u\r\n"   , RawPartition[dwPartNo].FAT32.BackupBootSector);
        OALLog(L"PhysicalDiskNumber  : %02X\r\n" , RawPartition[dwPartNo].FAT32.PhysicalDiskNumber);
        OALLog(L"EFDCSignature       : %02X\r\n" , RawPartition[dwPartNo].FAT32.EFDCSignature);
        OALLog(L"VolumeSerialNumber  : %08X\r\n" , RawPartition[dwPartNo].FAT32.VolumeSerialNumber);
        OALLog(L"VolumeLabel         : %.11S\r\n", RawPartition[dwPartNo].FAT32.VolumeLabel);
        OALLog(L"FileSystemType      : %.8S\r\n" , RawPartition[dwPartNo].FAT32.FileSystemType);
    }
    else{ // FAT12/FAT16
        OALLog(L"PhysicalDiskNumber  : %02X\r\n" , RawPartition[dwPartNo].PhysicalDiskNumber);
        OALLog(L"EFDCSignature       : %02X\r\n" , RawPartition[dwPartNo].EFDCSignature);
        OALLog(L"VolumeSerialNumber  : %08X\r\n" , RawPartition[dwPartNo].VolumeSerialNumber);
        OALLog(L"VolumeLabel         : %.11S\r\n", RawPartition[dwPartNo].VolumeLabel);
        OALLog(L"FileSystemType      : %.8S\r\n" , RawPartition[dwPartNo].FileSystemType);
    }
    OALLog(L"Signature           : %04X\r\n" , RawPartition[dwPartNo].Signature);
}

VOID DumpFATTable(DWORD dwPartNo, DWORD dwStart, DWORD dwCount){
    DWORD dwBits, dwLine, dwLoop;
    // parameter check
    if(dwPartNo >= PartitionNumber){
        KITLOutputDebugString("Partition Number beyond scope\r\n");
        return;
    }
    if(dwStart >= Partition[dwPartNo].FATEntryNumber){
        KITLOutputDebugString("Start position beyond FAT entry number\r\n");
        return;
    }
    // adjust dwCount if need
    if(dwStart+dwCount > Partition[dwPartNo].FATEntryNumber){
        dwCount = Partition[dwPartNo].FATEntryNumber-dwStart;
    }
    // get FAT entry bit size
    dwBits = GetFATEntryBits(dwPartNo);
    dwLine = 32/GetFATEntryBytes(dwPartNo); // one line display 32 bytes 
    // begin dump
    for(dwLoop = 0; dwLoop < dwCount; ++dwLoop){
        if(dwLoop%dwLine == 0){
            OALLog(L"%04X   ", dwStart+dwLoop);
        }
        OALLog(L"%0*X ", dwBits/4, GetFATEntry(dwPartNo, dwStart+dwLoop));
        if(dwLoop%dwLine==dwLine-1 || dwLoop+1==dwCount){
            OALLog(L"\r\n");
        }
    }
}

VOID DumpDirectory(PCSTR pDirName, DWORD dwStart, DWORD dwCount){
    FILEINFO fnFileInfo;
    DIRENTRY drEntry;
    DWORD    dwEntries;

    // open dir&verify it
    if(!FATOpenFile(&fnFileInfo, pDirName)){
        KITLOutputDebugString("Can't open %S\r\n", pDirName);
        return;
    }
    // get dir entries
    dwEntries = GetDirEntryNumber(&fnFileInfo);
    // check&adjust parameter
    if(dwStart >= dwEntries){
        KITLOutputDebugString("Start position beyond directory entry number\r\n");
        return;
    }
    if(dwStart+dwCount > dwEntries){
        dwCount = dwEntries-dwStart;
    }
    //       123456789012345678901**12345678901234567**12345678**
    OALLog(L"Created                Modified           Accessed  "
    //       123*123*123*12345678**12345678*1234567890123
           L"Att Sum Ord Cluster   Length   FileName\r\n"
        );
    // process each directory entry
    while(dwCount--){
        // read item
        if(!GetDirEntry(&fnFileInfo, &drEntry, dwStart++)){
            KITLOutputDebugString("Fail to read %S\r\n", pDirName);
            break;
        }
        // output
        OALLog(L"%02u/%02u/%02u-%02u:%02u:%02u:%03u  %02u/%02u/%02u-%02u:%02u:%02u  "
               L"%02u/%02u/%02u  %02X  %02X  %02X  %08X  %-8u %-13S\r\n",
               drEntry.Created.wYear%100, drEntry.Created.wMonth, drEntry.Created.wDay,
               drEntry.Created.wHour, drEntry.Created.wMinute, drEntry.Created.wSecond,
               drEntry.Created.wMilliseconds,
               drEntry.Modified.wYear%100, drEntry.Modified.wMonth, drEntry.Modified.wDay,
               drEntry.Modified.wHour, drEntry.Modified.wMinute, drEntry.Modified.wSecond,
               drEntry.Accessed.wYear%100, drEntry.Accessed.wMonth, drEntry.Accessed.wDay,
               drEntry.Attribute, drEntry.CheckSum, drEntry.Ordinal,  
               drEntry.StartingCluster, drEntry.FileLength, drEntry.FileName
            );
    }
}

VOID DumpDirectoryEx(PCSTR pDirName){
    FILEINFO fnFileInfo;
    DIRENTRY drEntry;

    // open dir&verify it
    if(!FATOpenFile(&fnFileInfo, pDirName)){
        KITLOutputDebugString("Can't open %S\r\n", pDirName);
        return;
    }
    if(!FATIsDirectory(&fnFileInfo)){
        KITLOutputDebugString("%S isn't directory\r\n", pDirName);
        return;
    }
    //       12345678901234567**123*12345678**12345678*1...
    OALLog(L"Modified           Att Cluster   Length   FileName\r\n");
    // process each directory entry
    while(1){
        // read item
        if(!GetDirEntryEx(&fnFileInfo, &drEntry)){
            break;
        }
        if(drEntry.FileName[0] == DIRENTRY_NEVERUSED){
            break; // finish?
        }
        // output
        OALLog(L"%02u/%02u/%02u-%02u:%02u:%02u  %02X  %08X  %-8u %S\r\n",
               drEntry.Modified.wYear%100, drEntry.Modified.wMonth, drEntry.Modified.wDay,
               drEntry.Modified.wHour, drEntry.Modified.wMinute, drEntry.Modified.wSecond,
               drEntry.Attribute, drEntry.StartingCluster, drEntry.FileLength, drEntry.FileName
            );
    }
}

VOID DumpRootDirectoryEx(){
    FILEINFO fnFileInfo;
    DIRENTRY drEntry;
    DWORD dwPartNo = 0;

    // open dir&verify it
    if(Partition[dwPartNo].FileSystem == PART_FAT32){
        InitFileInfo(&fnFileInfo, dwPartNo, Partition[dwPartNo].StartingRootEntry, 0, DIRENTRY_SUBDIR);
    }
    else{
        InitFileInfo(&fnFileInfo, dwPartNo, FAT_ROOTCLUSTER, Partition[dwPartNo].RootEntryLength, DIRENTRY_SUBDIR);
    }

    if(!FATIsDirectory(&fnFileInfo)){
        KITLOutputDebugString("root isn't directory\r\n");
        return;
    }
    //       12345678901234567**123*12345678**12345678*1...
    OALLog(L"Modified           Att Cluster   Length   FileName\r\n");
    // process each directory entry
    while(1){
        // read item
        if(!GetDirEntryEx(&fnFileInfo, &drEntry)){
            break;
        }
        if(drEntry.FileName[0] == DIRENTRY_NEVERUSED){
            break; // finish?
        }
        // output
        OALLog(L"%02u/%02u/%02u-%02u:%02u:%02u  %02X  %08X  %-8u %S\r\n",
               drEntry.Modified.wYear%100, drEntry.Modified.wMonth, drEntry.Modified.wDay,
               drEntry.Modified.wHour, drEntry.Modified.wMinute, drEntry.Modified.wSecond,
               drEntry.Attribute, drEntry.StartingCluster, drEntry.FileLength, drEntry.FileName
            );
    }
}



⌨️ 快捷键说明

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