protected void ProcessBlock(Byte[] block) { if (block[0] != 0x0a || block[1] != 0xf3) { throw new Exception("Missing extent tree header!"); } UInt32 entry_count; UInt32 max_entry_count; UInt32 depth; Utils.LoadLE16(out entry_count, block, 2); Utils.LoadLE16(out max_entry_count, block, 4); Utils.LoadLE16(out depth, block, 6); if (depth == 0) { UInt32 extent_id; UInt32 extent_length; Int64 start_block; Int64 temp; for (uint i = 0; i < entry_count; i++) { Utils.LoadLE32(out extent_id, block, 12 + i * 12); Utils.LoadLE16(out extent_length, block, 12 + i * 12 + 4); Utils.LoadLE16To64(out temp, block, 12 + i * 12 + 6); Utils.LoadLE32To64(out start_block, block, 12 + i * 12 + 8); start_block += temp * 0x100000000; extents.AddLast(new Extent(extent_id, start_block, extent_length)); if (current_extent == null) { current_extent = extents.First; } } } else { UInt32 id; Int64 next_node; Int64 temp; for (uint i = 0; i < entry_count; i++) { Utils.LoadLE32(out id, block, 12 + i * 12); Utils.LoadLE32To64(out next_node, block, 12 + i * 12 + 4); Utils.LoadLE16To64(out temp, block, 12 + i * 12 + 8); next_node += temp * 0x100000000; Byte[] child_block = new Byte[filesystem.BlockSize]; filesystem.ReadBlock(child_block, next_node); ProcessBlock(child_block); } } }
public bool ReadNextBlock(Byte[] block) { if (direct_position < 12) { if (direct_block[direct_position] == 0) { return(false); } filesystem.ReadBlock(block, direct_block[direct_position++]); return(true); } else { if (direct_block[direct_position] == 0 || direct_position > 14) { return(false); } while (indirect_level < direct_position - 11) { if (indirect_level == 0) { indirect_position.AddLast(0); Byte[] ptr_block = new Byte[filesystem.BlockSize]; filesystem.ReadBlock(ptr_block, direct_block[direct_position]); indirect_block.AddLast(ptr_block); current_indirect_block = indirect_block.Last; current_indirect_position = indirect_position.Last; indirect_level++; } else { UInt32 intermediate_block_id; Utils.LoadLE32(out intermediate_block_id, current_indirect_block.Value, current_indirect_position.Value); if (intermediate_block_id == 0) { return(false); } indirect_position.AddLast(0); Byte[] ptr_block = new Byte[filesystem.BlockSize]; filesystem.ReadBlock(ptr_block, intermediate_block_id); indirect_block.AddLast(ptr_block); current_indirect_block = indirect_block.Last; current_indirect_position = indirect_position.Last; indirect_level++; } } UInt32 final_block_id; Utils.LoadLE32(out final_block_id, current_indirect_block.Value, current_indirect_position.Value); if (final_block_id == 0) { return(false); } filesystem.ReadBlock(block, final_block_id); while (indirect_level > 0 && current_indirect_position.Value + 4 >= filesystem.BlockSize) { current_indirect_position = current_indirect_position.Previous; current_indirect_block = current_indirect_block.Previous; indirect_position.RemoveLast(); indirect_block.RemoveLast(); indirect_level--; } if (indirect_level == 0) { direct_position++; } else { current_indirect_position.Value += 4; } } return(true); }