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

📄 sdfat.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 4 页
字号:
            InitFileInfo(pFileInfo, dwPartNo, Partition[dwPartNo].StartingRootEntry, 0, DIRENTRY_SUBDIR);
        }
        else{
            InitFileInfo(pFileInfo, dwPartNo, FAT_ROOTCLUSTER, Partition[dwPartNo].RootEntryLength, DIRENTRY_SUBDIR);
        }
        return TRUE;
    }
    else{
        return FALSE;
    }
}

static BOOL FindNextDirEntry(PFILEINFO pFileInfo, PCSTR* ppCurItem){
    DIRENTRY drEntry;
    // search...
    while(1){
        // read one DIRENTRY 
        if(!GetDirEntryEx(pFileInfo, &drEntry)){
            break; // fail, exit loop
        }
        if(drEntry.FileName[0] == DIRENTRY_NEVERUSED){
            break; // no used entry, exit
        }
        // compare filename, if match update ppCurItem to next
        if(CompareFileName(drEntry.FileName, ppCurItem)){
            // update pFileInfo to new entry
            InitFileInfo(pFileInfo, pFileInfo->PartitionNumber,
                drEntry.StartingCluster, drEntry.FileLength, drEntry.Attribute);
            return TRUE;
        }
    }
    return FALSE;
}


// help routine for initialization
static DWORD GetDefaultSectorSize(){
    return DEFAULT_SECTOR_SIZE;
}

static BOOL InitPartition(BOOL fBootable, DWORD dwFileSystem, DWORD dwStart, DWORD dwLength){
    DWORD dwFileType;
    DWORD dwFATSectors, dwTotalSectors;
    DWORD dwRootStart, dwRootSectors, dwRootLength;
    DWORD dwDataStart, dwDataSectors, dwDataClusters;
    UINT8 buf[DEFAULT_SECTOR_SIZE];
    PRAWPARTITION pPart = (PRAWPARTITION)buf;
    // we just support 26 partition
    if(PartitionNumber >= MAX_PARTITION){
        return FALSE;
    }
    // read first sector
    if(FATReadDisk(pPart, sizeof(*pPart), dwStart) != sizeof(*pPart)){
        return FALSE;
    }

    // check field
    if(pPart->SectorSize == 0){
        return FALSE;
    }
    if(pPart->SectorPerCluster == 0){
        return FALSE;
    }
    if(pPart->ReservedSector == 0){
        return FALSE;
    }
    if(pPart->NumberOfFAT == 0){
        return FALSE;
    }
    if(pPart->NumberOfRootEntry==0 && pPart->FAT32.RootEntryCluster==0){
        return FALSE;
    }
    if(pPart->TotalSector != 0){
        if(pPart->TotalSector2 != 0){
            return FALSE;
        }
    }
    else if(pPart->TotalSector2 == 0){
        return FALSE;
    }
    if(pPart->SectorPerFAT==0 && pPart->FAT32.SectorPerFAT==0){
        return FALSE;
    }
    if(pPart->EFDCSignature!=RAWPARTITION_EFDCSIGNATURE &&
       pPart->FAT32.EFDCSignature!=RAWPARTITION_EFDCSIGNATURE){
        return FALSE;
    }
    if(pPart->Signature != RAWPARTITION_SIGNATURE){
        return FALSE;
    }
    // determine FAT type
    if(pPart->SectorPerFAT){
        dwFATSectors = pPart->NumberOfFAT*pPart->SectorPerFAT;
    }
    else{
        dwFATSectors = pPart->NumberOfFAT*pPart->FAT32.SectorPerFAT;
    }
    if(pPart->TotalSector){
        dwTotalSectors = pPart->TotalSector;
    }
    else{
        dwTotalSectors = pPart->TotalSector2;
    }
    dwRootStart    = pPart->SectorSize*(pPart->ReservedSector+dwFATSectors);
    dwRootLength   = 32*pPart->NumberOfRootEntry;
    dwRootSectors  = (dwRootLength+pPart->SectorSize-1)/pPart->SectorSize;
    dwDataStart    = dwRootStart+pPart->SectorSize*dwRootSectors;
    dwDataSectors  = dwTotalSectors-pPart->ReservedSector-dwFATSectors-dwRootSectors;
    dwDataClusters = dwDataSectors/pPart->SectorPerCluster;
    if(dwDataClusters < 4085){
        dwFileType = PART_FAT12;
    }
    else if(dwDataClusters < 65525){
        dwFileType = PART_FAT16;
    }
    else{
        dwFileType = PART_FAT32;
        dwRootStart = pPart->FAT32.RootEntryCluster;
    }
    // check consistent
    if(dwFileSystem != dwFileType){
        if(dwFileSystem != PART_UNKNOWN){
            return FALSE;
        }
    }
    // validated FAT, update global state
    Partition[PartitionNumber].Bootable          = fBootable;
    Partition[PartitionNumber].FileSystem        = dwFileType;
    Partition[PartitionNumber].StartingPartition = dwStart;
    Partition[PartitionNumber].PartitionLength   = dwLength;
    Partition[PartitionNumber].StartingFATEntry  = pPart->SectorSize*pPart->ReservedSector;
    Partition[PartitionNumber].FATEntryNumber    = dwDataClusters+2; // +2 for format identifier
    Partition[PartitionNumber].StartingRootEntry = dwRootStart;
    Partition[PartitionNumber].RootEntryLength   = dwRootLength;
    Partition[PartitionNumber].StartingCluster   = dwDataStart;
    Partition[PartitionNumber].LengthPerCluster  = pPart->SectorSize*pPart->SectorPerCluster;
    memcpy(&RawPartition[PartitionNumber++], pPart, sizeof(*pPart));
    return TRUE;
}

static BOOL InitMasterBootRecord(DWORD dwStart, DWORD dwLength){
    int i, j;
    BOOL fBootable;
    UINT8 buf[DEFAULT_SECTOR_SIZE];
    PARTITION_TABLE EmptyPart = {0}; // all zero
    PPARTITION_TABLE pPart1, pPart2;
    DWORD dwPartStart, dwPartLength;
    PMASTERBOOT_RECORD pMBR = (PMASTERBOOT_RECORD)buf;
    // we just support 26 MBR
    if(MasterBootRecordNumber >= MAX_PARTITION){
        return FALSE;
    }
    // read first sector
    if(FATReadDisk(pMBR, sizeof(*pMBR), dwStart) != sizeof(*pMBR)){
        return FALSE;
    }

    // check signature
    if(pMBR->Signature != MASTERBOOT_SIGNATURE){
        return FALSE;
    }
    // check partition table
    for(i = 0; i < PARTITION_NUMBER; ++i){
        pPart1 = &pMBR->Partition[i];
        // check empty partition
        if(pPart1->SystemId == PARTITION_EMPTY){
            if(memcmp(pPart1, &EmptyPart, sizeof(EmptyPart)) != 0){
                return FALSE; // empty partition should be all zero
            }
            continue; // skip follow check
        }
        // check boot indicator
        if(pPart1->BootIndicator!=PARTITION_NORMAL && pPart1->BootIndicator!=PARTITION_SYSTEM){
            return FALSE;
        }
        // check header(0-254)
        if(pPart1->StartingHead==0xFF || pPart1->EndingHead==0xFF){
            return FALSE;
        }
        // check sector(1-63)
        if(pPart1->StartingSector==0 || pPart1->EndingSector==0){
            return FALSE;
        }
        // check start&length
        dwPartStart = pPart1->RelativeSector*GetDefaultSectorSize();
        dwPartLength = pPart1->TotalSector*GetDefaultSectorSize();
        if(dwPartStart >= dwLength){
            return FALSE;
        }
        if(dwPartLength==0 || dwPartStart+dwPartLength>dwLength){
            return FALSE;
        }
        // check overlap
        for(j = i+1; j < PARTITION_NUMBER; ++j){
            pPart2 = &pMBR->Partition[j];
            // skip empty
            if(pPart2->SystemId == PARTITION_EMPTY){
                continue;
            }
            // check start point
            if(pPart2->RelativeSector>=pPart1->RelativeSector &&
               pPart2->RelativeSector<pPart1->RelativeSector+pPart1->TotalSector){
                return FALSE;
            }
            // check end point
            if(pPart2->RelativeSector+pPart2->TotalSector>pPart1->RelativeSector &&
               pPart2->RelativeSector+pPart2->TotalSector<=pPart1->RelativeSector+pPart1->TotalSector){
               return FALSE;
            }
        }
    }
    // validated MBR, copy it!
    memcpy(&MasterBootRecord[MasterBootRecordNumber++], pMBR, sizeof(*pMBR));
    // init individual partition 
    for(i = 0; i < PARTITION_NUMBER; ++i){
        pPart1 = &pMBR->Partition[i];
        fBootable = (pPart1->BootIndicator==PARTITION_SYSTEM);
        dwPartStart = dwStart + GetDefaultSectorSize()*pPart1->RelativeSector;
        dwPartLength = GetDefaultSectorSize()*pPart1->TotalSector;
        switch(pPart1->SystemId){
        case PARTITION_FAT12: // FAT12
            InitPartition(fBootable, PART_FAT12, dwPartStart, dwPartLength);
            break;
        case PARTITION_FAT16: // FAT16
        case PARTITION_FAT16B:
        case PARTITION_FAT16L:
            InitPartition(fBootable, PART_FAT16, dwPartStart, dwPartLength);
            break;
        case PARTITION_FAT32: // FAT32
        case PARTITION_FAT32L:
            InitPartition(fBootable, PART_FAT32, dwPartStart, dwPartLength);
            break;
        case PARTITION_EXT:   // Extend
        case PARTITION_EXTL:
            InitMasterBootRecord(dwPartStart, dwPartLength); // recursion!
            break;
        case PARTITION_EMPTY:
            break; // no action
        default:
            //InitPartition(PART_UNKNOWN, dwPartStart, dwPartLength); // try it?
            break;
        }
    }
    return TRUE;
}


// disk function
BOOL FATInitDisk(){
    // init hardware
    if(!SDInitializeHardware()){
        return FALSE;
    }
    // try to init MBR
    if(InitMasterBootRecord(0, FATGetDiskSize())){
        return TRUE;
    }
    // no MBR, try to init partition
    if(InitPartition(TRUE, PART_UNKNOWN, 0, FATGetDiskSize())){
        return TRUE;
    }
    // no FAT partition, fail!
    return FALSE;
}

DWORD FATGetDiskSize(){
    return 0xFFFFFFFF; // TODO: get from SD Card
}

DWORD FATReadDisk(PVOID pBuffer, DWORD dwLength, DWORD dwPos){
    // parameter check
    if(dwPos >= FATGetDiskSize()){
        return 0;
    }
    // adjust dwLength if need
    if(dwPos+dwLength > FATGetDiskSize()){
        dwLength = FATGetDiskSize()-dwPos;
    }
    return SDReadDataBlock(pBuffer, dwLength, dwPos)?dwLength:FAT_ERROR;
}


// partition function
DWORD FATGetPartitionNumber(){
    return PartitionNumber;
}

DWORD FATGetPartitionSize(DWORD dwPartNo){
    return dwPartNo<PartitionNumber?Partition[dwPartNo].PartitionLength:FAT_ERROR;
}

DWORD FATReadPartition(DWORD dwPartNo, PVOID pBuffer, DWORD dwLength, DWORD dwPos){
    // parameter check
    if(dwPartNo >= PartitionNumber){
        return FAT_ERROR;
    }
    if(dwPos >= Partition[dwPartNo].PartitionLength){
        return 0;
    }
    // adjust dwLength if need
    if(dwPos+dwLength > Partition[dwPartNo].PartitionLength){
        dwLength = Partition[dwPartNo].PartitionLength-dwPos;
    }
    return FATReadDisk(pBuffer, dwLength, Partition[dwPartNo].StartingPartition+dwPos);
}


// file function
BOOL FATOpenFile(PFILEINFO pFileInfo, PCSTR pFileName){
    FILEINFO fnFileInfo;
    // invalid pFileInfo
    ClearFileInfo(pFileInfo);
    // find root directory
    if(!FindRootDirEntry(&fnFileInfo, &pFileName)){
        return FALSE;
    }
    // find each directory and last file
    while(*pFileName){
        if(!FATIsDirectory(&fnFileInfo)){ // not directory
            return FALSE;
        }
        if(!FindNextDirEntry(&fnFileInfo, &pFileName)){
            return FALSE;
        }
    }
    // copy it
    memcpy(pFileInfo, &fnFileInfo, sizeof(*pFileInfo));
    return TRUE;
}

BOOL FATCloseFile(PFILEINFO pFileInfo){
    ClearFileInfo(pFileInfo);
    return TRUE;
}

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

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

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

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

BOOL FATIsDirectory(PFILEINFO pFileInfo){
    return (pFileInfo->FileAttribute&DIRENTRY_SUBDIR) != 0;

⌨️ 快捷键说明

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