// ======================================================= 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); }
// ======================================================= void CAfsPart::readSuperBlock() { BEGIN; QWORD qwFreeBlocks; CAfsSuper sb; int nRes; // init memset(&m_info, 0, sizeof(CInfoAfsHeader)); // 0. go to the beginning of the super block nRes = readData(&sb, AFS_SUPERBLOCK_OFFSET, sizeof(sb)); if (nRes == -1) goto error_readSuperBlock; if (CpuToLe32(sb.as_nMagic1) != SUPER_BLOCK_MAGIC1) goto error_readSuperBlock; if (CpuToLe32(sb.as_nMagic2) != SUPER_BLOCK_MAGIC2) goto error_readSuperBlock; // take infos from superblock m_info.dwByteOrder = sb.as_nByteOrder; m_info.dwBlockShift = sb.as_nBlockShift; m_info.dwBlockPerGroup = sb.as_nBlockPerGroup; m_info.dwAllocGrpShift = sb.as_nAllocGrpShift; m_info.dwAllocGroupCount = sb.as_nAllocGroupCount; m_info.dwFlags = sb.as_nFlags; m_info.dwBootLoaderSize = sb.as_nBootLoaderSize; // virtual blocks used in the abstract CFSBase m_header.qwBlocksCount = (DWORD)sb.as_nNumBlocks; showDebug(1, "qwBlocksCount=%llu\n", m_header.qwBlocksCount); m_header.qwBlockSize = (DWORD)sb.as_nBlockSize; showDebug(1, "qwBlockSize=%llu\n", m_header.qwBlockSize); m_header.qwBitmapSize = ((m_header.qwBlocksCount+7)/ 8)+1024; m_header.qwUsedBlocks = sb.as_nUsedBlocks; showDebug(1, "qwUsedBlocks%llu\n", m_header.qwUsedBlocks); // get bitmap position /*DWORD a, b, c; a = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize - 1) / m_header.qwBlockSize; b = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize) / m_header.qwBlockSize; c = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize + 1) / m_header.qwBlockSize; showDebug(1, "a=%lu\n", a); showDebug(1, "b=%lu\n", b); showDebug(1, "c=%lu\n", c); */ m_info.qwBitmapStart = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize - 1) / m_header.qwBlockSize; qwFreeBlocks = m_header.qwBlocksCount-m_header.qwUsedBlocks; setSuperBlockInfos(false, false, m_header.qwUsedBlocks*m_header.qwBlockSize, qwFreeBlocks * m_header.qwBlockSize); showDebug(1, "end success\n"); RETURN; error_readSuperBlock: g_interface -> ErrorReadingSuperblock(errno); THROW(ERR_WRONG_FS); }