示例#1
0
            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);
                    }
                }
            }
示例#2
0
            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);
            }