Exemplo n.º 1
0
// =======================================================
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);
}
Exemplo n.º 2
0
// =======================================================
void CExt2Part::readBitmap(COptions *options) // FULLY WORKING
{
  BEGIN;
 
  DWORD i, j;
  CExt2GroupDesc *desc;
  int nRes;
  DWORD dwBlocksInThisGroup;
  DWORD dwBootBlocks;
  char *cTempBitmap;
  DWORD dwBit, dwByte;
  DWORD dwExt2DataBlock;
  char *cPtr;
  int group = 0;

  // debug
  DWORD dwUsed;
  DWORD dwFree;

  dwBootBlocks = m_info.dwFirstBlock / m_info.dwLogicalBlocksPerExt2Block;
  //debugWin("dwBootBlocks=%lu and m_info.dwLogicalBlocksPerExt2Block=%lu",dwBootBlocks,m_info.dwLogicalBlocksPerExt2Block);

  cTempBitmap = new char[((m_info.dwTotalBlocksCount+7)/8)+4096];
  if (!cTempBitmap)
  {  
     showDebug(1, "CExt2Part::readBitmap(): Error 001\n");  
     goto error_readBitmap;
  }

  // init bitmap size
  nRes = m_bitmap.init(m_header.qwBitmapSize);
  showDebug(1, "m_bitmap.init(m_header.qwBitmapSize = %lu)\n", m_header.qwBitmapSize);
  if (nRes == -1)
  { 
     showDebug(1, "CExt2Part::readBitmap(): Error 002\n");  
     goto error_readBitmap;
  }

  // load group descriptors
  desc = new CExt2GroupDesc[m_info.dwGroupsCount+m_info.dwDescPerBlock];
  showDebug(1, "dwGroupsCount = %lu, m_info.dwDescPerBlock = %lu\n",m_info.dwGroupsCount, m_info.dwDescPerBlock);
  if (!desc)
  { 
     showDebug(1, "CExt2Part::readBitmap(): Error 003\n");  
     goto error_readBitmap;
  }

  // for each descriptor BLOCK (not group descriptor!)
  showDebug(1, "readData m_info.dwBlockSize = %lu\n", m_info.dwBlockSize);
  for (cPtr=(char*)desc, i=0; i < m_info.dwDescBlocks; i++,cPtr+=m_info.dwBlockSize)
    {
      nRes = readData(cPtr, ((QWORD)m_info.dwBlockSize) * ((QWORD)(m_info.dwFirstBlock+1+i)), m_info.dwBlockSize);
      if (nRes == -1)
      { 
	 showDebug(1, "CExt2Part::readBitmap(): Error 004\n");  
	 goto error_readBitmap;
      }
    }

  dwUsed=0;
  dwFree=0;
  showDebug(1, "m_info.dwBlocksPerGroup = %lu\n", m_info.dwBlocksPerGroup);  
  for (i = 0; i < m_info.dwGroupsCount; i++) 
    {
      if (m_info.dwFirstBlock+((i+1)*m_info.dwBlocksPerGroup) > m_info.dwTotalBlocksCount)
	dwBlocksInThisGroup = (m_info.dwTotalBlocksCount-m_info.dwFirstBlock) - (i*m_info.dwBlocksPerGroup);
      else
	dwBlocksInThisGroup = m_info.dwBlocksPerGroup;

      if (Le32ToCpu(desc[i].bg_block_bitmap))
	{
	  // -- read the bitmap block
	   errno = 0;
	  nRes = readData(cTempBitmap+(i*(m_info.dwBlocksPerGroup/8)), ((QWORD)m_info.dwBlockSize) * 
			  ((QWORD)Le32ToCpu(desc[i].bg_block_bitmap)), (m_info.dwBlocksPerGroup/8));
	  if (nRes == -1)
	  {
	     showDebug(1, "CExt2Part::readBitmap(): Error 005\n");  
	     showDebug(1, "CExt2Part::readBitmap(): err=%d=%d\n", errno, strerror(errno));  
	     goto error_readBitmap;
	  }
	}
      else
	{
	  memset(cTempBitmap+(i*(m_info.dwBlocksPerGroup/8)), 0, (m_info.dwBlocksPerGroup/8));
	}
    }

  // convert bitmap to little endian
  DWORD *dwPtr;
  DWORD dwLen;
  dwLen = sizeof(cTempBitmap) / sizeof(DWORD);
  dwPtr = (DWORD *)cTempBitmap;
  for (i=0; i < dwLen; i++, dwPtr++)
    *dwPtr = CpuToLe32(*dwPtr);

  // bitmap is full of 0 at init, then we just have to
  // write 1 for used blocks

  // the boot block of 1024 bytes = used
  for (i=0; i < dwBootBlocks; i++)
    m_bitmap.setBit(i, true);

  dwUsed=0; dwFree=0;
  for (i=dwBootBlocks, dwExt2DataBlock=0; dwExt2DataBlock < ( m_info.dwTotalBlocksCount- m_info.dwFirstBlock); dwExt2DataBlock++)
    {	
      dwBit = dwExt2DataBlock % 8;
      dwByte = (dwExt2DataBlock - dwBit) / 8;
      group = (dwExt2DataBlock/m_info.dwBlocksPerGroup);
       
      if ((cTempBitmap[dwByte] & (1 << dwBit)) != 0)
	{
	  for (j=0; j <  m_info.dwLogicalBlocksPerExt2Block; j++, i++)
	    m_bitmap.setBit(i, true);
	      showDebug(3, "m_bitmap.setBit(%1u, true), g = %i\n", (i/4), group);
	  dwUsed++;
	}
      else
	{
	  for (j=0; j <  m_info.dwLogicalBlocksPerExt2Block; j++, i++)
	    m_bitmap.setBit(i, false);
	      showDebug(3, "m_bitmap.setBit(%1u, false), g = %i\n", (i/4), group);
	  dwFree++; 
	}
    }

  showDebug(1,"used=%lu\nfree=%lu\ntotal=%lu\n",dwUsed,dwFree,dwUsed+dwFree);
  calculateSpaceFromBitmap();

  //success_readBitmap:
  delete []cTempBitmap;
  showDebug(1, "end success\n");  
  RETURN; // auccess

 error_readBitmap:
  delete []cTempBitmap;
  showDebug(1, "end error\n");  
  g_interface->msgBoxError(i18n("There was an error while reading the bitmap"));
  THROW(ERR_READ_BITMAP);
}
// 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;
}