// ======================================================= void CExt2Part::readSuperBlock() { BEGIN; CExt2Super sb; int nRes; // init memset(&m_info, 0, sizeof(CInfoExt2Header)); // 0. go to the beginning of the super block nRes = fseek(m_fDeviceFile, 1024, SEEK_SET); if (nRes == -1) goto error_readSuperBlock; // 1. read and print important informations nRes = fread(&sb, sizeof(sb), 1, m_fDeviceFile); if (nRes != 1) goto error_readSuperBlock; // check partition has an ext2 file system if (sb.s_magic != Le16ToCpu(EXT2_SUPER_MAGIC)) goto error_readSuperBlock; // read and print important informations m_info.dwBlockSize = (EXT2_MIN_BLOCK_SIZE << Le32ToCpu(sb.s_log_block_size)); //sb.s_blocksize; //EXT2_BLOCK_SIZE(m_fs->super); showDebug(1, "blksize=%lu\n", m_info.dwBlockSize); m_info.dwFirstBlock = Le32ToCpu(sb.s_first_data_block); showDebug(1, "first=%lu\n", m_info.dwFirstBlock); m_info.dwTotalBlocksCount = Le32ToCpu(sb.s_blocks_count); showDebug(1, "total blocks=%lu\n", m_info.dwTotalBlocksCount); m_info.dwBlocksPerGroup = Le32ToCpu(sb.s_blocks_per_group); showDebug(1, "BlocksPerGroup=%lu\n", m_info.dwBlocksPerGroup); m_info.dwGroupsCount = (m_info.dwTotalBlocksCount - m_info.dwFirstBlock + m_info.dwBlocksPerGroup - 1) / Le32ToCpu(sb.s_blocks_per_group); showDebug(1, "groups=%lu\n", m_info.dwGroupsCount); m_info.dwLogicalBlocksPerExt2Block = m_info.dwBlockSize / LOGICAL_EXT2_BLKSIZE; showDebug(1, "m_info.dwLogicalBlocksPerExt2Block=%lu\n",m_info.dwLogicalBlocksPerExt2Block); showDebug(1, "logperblok=%lu\n", m_info.dwLogicalBlocksPerExt2Block); m_info.dwDescPerBlock = m_info.dwBlockSize / sizeof(CExt2GroupDesc); m_info.dwDescBlocks = (m_info.dwGroupsCount + m_info.dwDescPerBlock - 1) / m_info.dwDescPerBlock; //debugWin("m_info.dwDescBlocks=%lu",(DWORD)m_info.dwDescBlocks); // virtual blocks used in the abstract CFSBase m_header.qwBlocksCount = m_info.dwTotalBlocksCount * m_info.dwLogicalBlocksPerExt2Block; m_header.qwBlockSize = LOGICAL_EXT2_BLKSIZE; m_header.qwBitmapSize = ((m_header.qwBlocksCount+7) / 8)+16; m_header.qwUsedBlocks = (m_info.dwTotalBlocksCount - Le32ToCpu(sb.s_free_blocks_count)) * m_info.dwLogicalBlocksPerExt2Block; //debugWin("freeblks=%lu", sb.s_free_blocks_count); strncpy(m_header.szLabel, sb.s_volume_name, 64); // features m_info.dwFeatureCompat = Le32ToCpu(sb.s_feature_compat); m_info.dwFeatureIncompat = Le32ToCpu(sb.s_feature_incompat); m_info.dwFeatureRoCompat = Le32ToCpu(sb.s_feature_ro_compat); // misc infos m_info.dwRevLevel = Le32ToCpu(sb.s_rev_level); // Revision level memcpy(m_info.cUuid, sb.s_uuid, 16); // 128-bit uuid for volume //success_readSuperBlock: setSuperBlockInfos(true, true, m_header.qwUsedBlocks*m_header.qwBlockSize, ((QWORD)Le32ToCpu(sb.s_free_blocks_count)) * ((QWORD)m_info.dwBlockSize)); showDebug(1, "end success\n"); RETURN; error_readSuperBlock: g_interface -> ErrorReadingSuperblock(errno); THROW(ERR_WRONG_FS); }
// Load partition information from storage device. bool PartitionLoad(FS_CONTEXT* FsContext, uint8_t DriverId) { uint32_t RootDirSectors; uint32_t BootSecNum = 0; uint32_t FatSize; uint32_t TotalSectors; uint8_t IndexPtb; uint8_t SectorSizeMul; uint32_t temp2; uint8_t ExtBootEntry = 0; uint16_t BPBRsvSectCnt; uint8_t LogicDriverId = 1; uint8_t LoopFlag = 0; #ifdef FUNC_USB_EN if(FsContext->gFsInfo.DevID == DEV_ID_USB) { SectorSizeMul = (HostStorGetBlockSize() / SECTOR_SIZE); } else #endif { SectorSizeMul = 1; } // FS_DBG("SectorSizeMul: %d\n", (uint16_t)SectorSizeMul); while(1) { LoopFlag = 0; //read MBR //if(!ReadBlock(BootSecNum, (uint8_t*)(FsContext->FAT_BUFFER), 1)) if(RES_OK != disk_read(FsContext->gFsInfo.DevID, (uint8_t*)(FsContext->FAT_BUFFER), BootSecNum, 1)) { FS_DBG("ReadBlock() error!\n"); return FALSE; } FsContext->gFsInfo.CurrFATSecNum = BootSecNum; #ifndef CANCEL_COMMON_SIGNATURE_JUDGMENT if(*(uint16_t*)((FsContext->FAT_BUFFER) + SIGNATURE_OFFSET) != COMMON_SIGNATURE) //if 0x55aa { return FALSE; } #endif for(IndexPtb = 0; IndexPtb < 4; IndexPtb++) { PARTITION* pPart = &((PARTITION*)((FsContext->FAT_BUFFER) + PARTITION_OFFSET))[IndexPtb]; if((pPart->PartitionType == 0x05) //Extended partition && ((ExtBootEntry == 0) || (IndexPtb >= ExtBootEntry))) { BootSecNum += Le32ToCpu(pPart->FirstSectorNum); ExtBootEntry = IndexPtb + 1; // FS_DBG("Extended partition bootSecNum:%ld\n", (uint32_t)BootSecNum); LoopFlag = 1; break; } //check the partition type and get the boot sector num if(pPart->PartitionType == 0x04 || pPart->PartitionType == 0x06 || pPart->PartitionType == 0x0B || pPart->PartitionType == 0x0C || pPart->PartitionType == 0x01 || pPart->PartitionType == 0x0E) { if(DriverId <= 1 || LogicDriverId == DriverId) { BootSecNum += Le32ToCpu(pPart->FirstSectorNum); break; } LogicDriverId++; } } if(LoopFlag) { continue; } if((IndexPtb == 4) && ((ExtBootEntry > 0) && (ExtBootEntry < 4))) { //if extended parttion failed,try again. BootSecNum = 0; continue;//增加对第一分区为无效扩展分区设备的支持 } break; } if((DriverId > 1) && (LogicDriverId != DriverId)) { return FALSE; } //read DBR //if(!ReadBlock((BootSecNum * SectorSizeMul), (uint8_t*)(FsContext->FAT_BUFFER), 1)) if(RES_OK != disk_read(FsContext->gFsInfo.DevID, (uint8_t*)(FsContext->FAT_BUFFER), (BootSecNum * SectorSizeMul), 1)) { return FALSE; } FsContext->gFsInfo.CurrFATSecNum = (BootSecNum * SectorSizeMul); #ifndef CANCEL_COMMON_SIGNATURE_JUDGMENT if(*(uint16_t*)((FsContext->FAT_BUFFER) + SIGNATURE_OFFSET) != COMMON_SIGNATURE) //if 0x55aa { return FALSE; } #endif #define pzero_sector ((BOOT_SECTOR*)((FsContext->FAT_BUFFER))) //updata device information FsContext->gFsInfo.ClusterSize = pzero_sector->BPB_SecPerClus; //get first sector of FAT BPBRsvSectCnt = Le16ToCpu(pzero_sector->BPB_RsvdSecCnt); FsContext->gFsInfo.FatStart = BPBRsvSectCnt + BootSecNum; //get sectors of boot dir if(pzero_sector->BPB_RootEntCnt != 0) { RootDirSectors = (Le16ToCpu(pzero_sector->BPB_RootEntCnt) * 32 + SECTOR_SIZE - 1) / SECTOR_SIZE; } else { RootDirSectors = 0; } //get FAT size if(pzero_sector->BPB_FATSz16 != 0) { FatSize = Le16ToCpu(pzero_sector->BPB_FATSz16); } else { FatSize = Le32ToCpu(pzero_sector->BPB_FATSz32); } //get total cluster if(pzero_sector->BPB_TotSec16 != 0) { TotalSectors = Le16ToCpu(pzero_sector->BPB_TotSec16); } else { TotalSectors = Le32ToCpu(pzero_sector->BPB_TotSec32); } temp2 = (TotalSectors - (BPBRsvSectCnt + FatSize * pzero_sector->BPB_NumFATs + RootDirSectors)) / FsContext->gFsInfo.ClusterSize; // FS_DBG("temp2:%ld\n", (uint32_t)temp2); if(temp2 < 4085) { FS_DBG("FAT12\n"); FsContext->gFsInfo.IsCpatFS = FALSE; //FAT12 return TRUE; } else if(temp2 < 65525) { FS_DBG("FAT16\n"); FsContext->gFsInfo.FAT32 = 0; //FAT16 FsContext->gFsInfo.IsCpatFS = TRUE; } else { //FAT32设备BPB_RootEntCnt/BPB_TotSec16/BPB_FATSz16数值必须为零 if(memcmp((uint8_t*)((FsContext->FAT_BUFFER) + 0x36), "FAT16\0\0\0", 8) == 0) { //客户有一个U盘(USB启动盘),根据计算得出的簇数目应该为FAT32,实际为FAT16系统,为支持这一类设备,需要做此处理 FS_DBG("FAT16\n"); FsContext->gFsInfo.FAT32 = 0; } else { FS_DBG("FAT32\n"); FsContext->gFsInfo.FAT32 = 1; //FAT32 } FsContext->gFsInfo.IsCpatFS = TRUE; } FsContext->gFsInfo.DataStart = FsContext->gFsInfo.FatStart + (FatSize * pzero_sector->BPB_NumFATs) + RootDirSectors; //the first sector of data // get max cluster number in this drive. //FsContext->gFsInfo.MaxCluster = ((TotalSectors - FsContext->gFsInfo.DataStart) / FsContext->gFsInfo.ClusterSize) + 2; FsContext->gFsInfo.MaxCluster = temp2 + 2; //get the data start and boot dir start if(FsContext->gFsInfo.FAT32) { FsContext->gFsInfo.RootStart = FsContext->gFsInfo.DataStart + (Le32ToCpu(pzero_sector->BPB_RootClus) - 2) * FsContext->gFsInfo.ClusterSize; } else { FsContext->gFsInfo.RootStart = FsContext->gFsInfo.FatStart + FatSize * pzero_sector->BPB_NumFATs; //FAT16 the first sector of root dir } FsContext->gFsInfo.ClusterSize *= SectorSizeMul; // RootDirSectors *= SectorSizeMul; FsContext->gFsInfo.FatStart *= SectorSizeMul; FsContext->gFsInfo.DataStart *= SectorSizeMul; FsContext->gFsInfo.MaxSector = (BootSecNum + TotalSectors) * SectorSizeMul; FsContext->gFsInfo.RootStart *= SectorSizeMul; // FS_DBG("*************UDisk virtual params******************\n"); // FS_DBG("ClusterSize:%ld\n", (uint32_t)FsContext->gFsInfo.ClusterSize); // FS_DBG("RootDirSectors:%ld\n", (uint32_t)RootDirSectors); // FS_DBG("FatStart:%ld\n", (uint32_t)FsContext->gFsInfo.FatStart); // FS_DBG("RootStart:%ld\n", (uint32_t)FsContext->gFsInfo.RootStart); // FS_DBG("DataStart:%ld\n", (uint32_t)FsContext->gFsInfo.DataStart); // FS_DBG("MaxCluster:%ld\n", (uint32_t)FsContext->gFsInfo.MaxCluster); // FS_DBG("*****************************************************\n\n"); return TRUE; }