PartitionEntry* FileSystem::readPartitionEntry(unsigned char *partitionBuffer, int partitionNumber, int sectorOffset) { int type = (int) partitionBuffer[4] & 0xFF; if (type != SWAP_PARTITION && type != UNUSED_PARTITION && type != EXT2_PARTITION && type != EXTENDED_PARTITION) { return NULL; } PartitionEntry *entry = new PartitionEntry; entry->partitionNumber = partitionNumber; entry->type = type; if (type == EXTENDED_PARTITION) { entry->startSector = extBootRecordOffset + getValueFromBytes(partitionBuffer, 8, 4); } else { entry->startSector = sectorOffset + getValueFromBytes(partitionBuffer, 8, 4); } entry->length = getValueFromBytes(partitionBuffer, 12, 4); entry->next = NULL; return entry; }
bool TwicCommands::getTagData(std::shared_ptr<TwicLocation> location, void* data, size_t datalen, void* datatag, size_t& datataglen) { bool ret = false; bool processed = false; unsigned char* ucdata = reinterpret_cast<unsigned char*>(data); size_t pos = 0; while (pos < datalen && !processed) { unsigned char currentTag = ucdata[pos++]; size_t encodedlength = getMinimumBytesRepresentation(getMaximumTagLength(location->dataObject, location->tag)); size_t currentTagLength = getValueFromBytes(&ucdata[pos], encodedlength); pos += encodedlength; if (currentTag == location->tag) { processed = true; if (datatag != NULL) { if (datataglen >= currentTagLength) { memcpy(datatag, &ucdata[pos], datataglen); ret = true; } } else { datataglen = currentTagLength; } pos += currentTagLength; } } return ret; }
int FileSystem::getIndirectDataBlockQt(PartitionEntry *partition, unsigned int blockNumber, unsigned int indirectionLevel) { int count = 0, i = 0; unsigned char buf[blockSize]; unsigned int sector = getBlockSector(partition, blockNumber); readSectors(sector, 2, buf); for (i = 0; i < 1024; i += 4) { if (indirectionLevel == 3 || indirectionLevel == 2) count += getIndirectDataBlockQt(partition, getValueFromBytes(buf, i, 4), indirectionLevel - 1); else if (indirectionLevel == 1) count += checkBlockBitmap(partition, getValueFromBytes(buf, i, 4)); } return count; }
size_t TwicCommands::getDataObjectLength(int64_t dataObject, bool withObjectLength) { size_t maxlen = getMaximumDataObjectLength(dataObject); size_t length = 0; size_t encodedlength = getMinimumBytesRepresentation(maxlen); if (encodedlength > 0) { size_t datalength = encodedlength + 1; std::vector<unsigned char> data; try { data = getTWICData(dataObject); if (data.size()) { length = getValueFromBytes(&data[1], datalength - 1); } } catch (std::exception&) { return 0; } } if (withObjectLength) { length += 1 + encodedlength; } return length; }
void FileSystem::readSuperblock(PartitionEntry *partition) { readSectors(partition->startSector, 6, superblockBuffer); super_block.s_magic = getValueFromBytes(superblockBuffer, 1080, 2); super_block.s_inodes_count = getValueFromBytes(superblockBuffer, 1024, 4); super_block.s_blocks_count = getValueFromBytes(superblockBuffer, 1024 + 4, 4); super_block.s_r_blocks_count = getValueFromBytes(superblockBuffer, 1024 + 8, 4); super_block.s_free_blocks_count = getValueFromBytes(superblockBuffer, 1024 + 12, 4); super_block.s_free_inodes_count = getValueFromBytes(superblockBuffer, 1024 + 16, 4); super_block.s_blocks_per_group = getValueFromBytes(superblockBuffer, 1024 + 32, 4); super_block.s_inodes_per_group = getValueFromBytes(superblockBuffer, 1024 + 40, 4); super_block.s_log_block_size = getValueFromBytes(superblockBuffer, 1024 + 24, 4); super_block.s_inode_size = getValueFromBytes(superblockBuffer, 1024 + 88, 2); }
InodeData FileSystem::readInode(PartitionEntry *partition, unsigned int inodeNumber) { InodeData inode; unsigned char buf[blockSize]; int i; int inodeOffset = getInodeStartingByte(inodeNumber); int inodeSector = getBlockSector(partition, inodeOffset / blockSize); int temp = inodeOffset - ((inodeSector - partition->startSector) * SECTOR_SIZE_BYTES); readSectors(inodeSector, (blockSize / SECTOR_SIZE_BYTES), buf); //First data block inode.inodeNumber = inodeNumber; inode.fileType = getValueFromBytes(buf, temp + 0, 2); inode.fileLength = getValueFromBytes(buf, temp + 4, 4); inode.hardLinksQt = getValueFromBytes(buf, temp + 26, 2); inode.dataBlocksQt = getValueFromBytes(buf, temp + 28, 4); for (i = 0; i < 15; i++) { inode.dataBlocksPointers[i] = getValueFromBytes(buf, temp + 40 + (i * 4), 4); } return inode; }
int FileSystem::checkBlockBitmap(PartitionEntry *partition, unsigned int blockNumber) { if (blockNumber == 0) return 0; unsigned char blockBitmap[blockSize]; unsigned int groupIndex = (blockNumber - 1) / super_block.s_blocks_per_group; unsigned int blockOffset = (blockNumber - 1) % super_block.s_blocks_per_group; unsigned int blockBitmapSector = getBlockSector( partition, getValueFromBytes(superblockBuffer, 1024 + blockSize + (groupIndex * 32) + 0, 4)); readSectors(blockBitmapSector, (blockSize / SECTOR_SIZE_BYTES), blockBitmap); unsigned int byte = blockOffset / 8; unsigned int offset = (blockOffset % 8); return !(!(blockBitmap[byte] & (1 << offset))); }
unsigned int FileSystem::readIndirectDataBlocks(PartitionEntry *partition, unsigned int inode, unsigned int parentInode, unsigned int blockNumber, unsigned int indirectionLevel, int passNumber, int performCheck, int fileType) { unsigned int i = 0; int retValue = -1; unsigned char buf[blockSize]; unsigned int sector = getBlockSector(partition, blockNumber); readSectors(sector, (blockSize / SECTOR_SIZE_BYTES), buf); for (i = 0; i < blockSize; i += 4) { unsigned int block = getValueFromBytes(buf, i, 4); if (block != 0 && (indirectionLevel == 3 || indirectionLevel == 2)) { if (passNumber == 4) blockMap[block] = 1; retValue = readIndirectDataBlocks(partition, inode, parentInode, block, indirectionLevel - 1, passNumber, performCheck, fileType); } else if (indirectionLevel == 1 && block != 0) { if (fileType != 1) retValue = parseFilesystem(partition, block, passNumber, inode, parentInode, performCheck); if (passNumber == 4) { blockMap[block] = 1; continue; } if (retValue != -1 && !performCheck) return retValue; } if (retValue != -1 && !performCheck) return retValue; } return -1; }
unsigned int FileSystem::getInodeTableBlockNumber(unsigned int inodeNumber) { unsigned int groupIndex = (inodeNumber - 1) / super_block.s_inodes_per_group; return getValueFromBytes(superblockBuffer, 1024 + blockSize + (groupIndex * 32) + 8, 4); }