コード例 #1
0
ファイル: CHDLocalCheck.cs プロジェクト: artifexor/RVWorld
        private hdErr read_block_into_cache(hard_disk_info info, int block)
        {
            bool checkCrc = true;
            mapentry mapEntry = info.map[block];
            switch (mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_TYPE_MASK)
            {
                case mapFlags.MAP_ENTRY_TYPE_COMPRESSED:
                    {

                        if (mapEntry.BlockCache != null)
                        {
                            Buffer.BlockCopy(mapEntry.BlockCache, 0, cache, 0, (int)info.blocksize);
                            //already checked CRC for this block when the cache was made
                            checkCrc = false;
                            break;
                        }

                        info.file.Seek((long)info.map[block].offset, SeekOrigin.Begin);

                        switch (info.compression)
                        {
                            case HDCOMPRESSION_ZLIB:
                            case HDCOMPRESSION_ZLIB_PLUS:
                                {
                                    using (var st = new System.IO.Compression.DeflateStream(info.file, System.IO.Compression.CompressionMode.Decompress, true))
                                    {
                                        int bytes = st.Read(cache, 0, (int)info.blocksize);
                                        if (bytes != (int)info.blocksize)
                                            return hdErr.HDERR_READ_ERROR;

                                        if (mapEntry.UseCount > 0)
                                        {
                                            mapEntry.BlockCache = new byte[bytes];
                                            Buffer.BlockCopy(cache, 0, mapEntry.BlockCache, 0, bytes);
                                        }

                                    }
                                    break;
                                }
                            default:
                                {
                                    Console.WriteLine("Unknown compression");
                                    return hdErr.HDERR_DECOMPRESSION_ERROR;

                                }
                        }
                        break;
                    }

                case mapFlags.MAP_ENTRY_TYPE_UNCOMPRESSED:
                    {
                        info.file.Seek((long)info.map[block].offset, SeekOrigin.Begin);
                        int bytes = info.file.Read(cache, 0, (int)info.blocksize);

                        if (bytes != (int)info.blocksize)
                            return hdErr.HDERR_READ_ERROR;
                        break;
                    }

                case mapFlags.MAP_ENTRY_TYPE_MINI:
                    {
                        byte[] tmp = BitConverter.GetBytes(info.map[block].offset);
                        for (int i = 0; i < 8; i++)
                        {
                            cache[i] = tmp[7 - i];
                        }

                        for (int i = 8; i < info.blocksize; i++)
                        {
                            cache[i] = cache[i - 8];
                        }

                        break;
                    }

                case mapFlags.MAP_ENTRY_TYPE_SELF_HUNK:
                    {
                        hdErr ret = read_block_into_cache(info, (int)mapEntry.offset);
                        if (ret != hdErr.HDERR_NONE)
                            return ret;
                        // check CRC in the read_block_into_cache call
                        checkCrc = false;
                        break;
                    }
                default:
                    return hdErr.HDERR_DECOMPRESSION_ERROR;

            }

            if (checkCrc && (mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
            {
                if (!CRC.VerifyDigest(mapEntry.crc, cache, 0, info.blocksize))
                    return hdErr.HDERR_DECOMPRESSION_ERROR;
            }
            return hdErr.HDERR_NONE;
        }
コード例 #2
0
ファイル: CHDLocalCheck.cs プロジェクト: artifexor/RVWorld
        private static hdErr read_sector_map(hard_disk_info info)
        {
            info.map = new mapentry[info.totalblocks];

            info.file.Seek(info.length, SeekOrigin.Begin);

            using (BinaryReader br = new BinaryReader(info.file, Encoding.UTF8, true))
            {
                if (info.version <= 2)
                {
                    for (int i = 0; i < info.totalblocks; i++)
                    {
                        UInt64 tmpu = br.ReadUInt64BE();

                        mapentry me = new mapentry()
                        {
                            offset = (tmpu << 20) >> 20,
                            crc = 0,
                            length = (tmpu >> 44),
                            UseCount = 0
                        };
                        me.flags = mapFlags.MAP_ENTRY_FLAG_NO_CRC | ((me.length == info.blocksize)
                                       ? mapFlags.MAP_ENTRY_TYPE_UNCOMPRESSED
                                       : mapFlags.MAP_ENTRY_TYPE_COMPRESSED);
                        info.map[i] = me;
                    }
                    Dictionary<ulong, int> selfhunkMap = new Dictionary<ulong, int>();
                    for (int i = 0; i < info.totalblocks; i++)
                    {
                        if (selfhunkMap.TryGetValue(info.map[i].offset, out int index))
                        {
                            info.map[i].offset = (ulong)index;
                            info.map[i].flags = mapFlags.MAP_ENTRY_FLAG_NO_CRC | mapFlags.MAP_ENTRY_TYPE_SELF_HUNK;
                        }
                        else
                            selfhunkMap.Add(info.map[i].offset, i);
                    }
                }
                else
                {
                    for (int i = 0; i < info.totalblocks; i++)
                    {
                        mapentry me = new mapentry()
                        {
                            offset = br.ReadUInt64BE(),
                            crc = br.ReadUInt32BE(),
                            length = br.ReadUInt16BE(),
                            flags = (mapFlags)br.ReadUInt16BE(),
                            UseCount = 0
                        };
                        info.map[i] = me;
                    }
                }

                for (int i = 0; i < info.totalblocks; i++)
                {
                    if ((info.map[i].flags & mapFlags.MAP_ENTRY_FLAG_TYPE_MASK) == mapFlags.MAP_ENTRY_TYPE_SELF_HUNK)
                    {
                        info.map[info.map[i].offset].UseCount += 1;
                    }
                }
            }

            return hdErr.HDERR_NONE;
        }
コード例 #3
0
        public hdErr read_block_into_cache(int block, byte[] cache, ref byte[] crc)
        {
            crc = null;
            mapentry mapEntry = _hd.map[block];

            switch (mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_TYPE_MASK)
            {
            case mapFlags.MAP_ENTRY_TYPE_COMPRESSED:
            {
                if (mapEntry.BlockCache != null)
                {
                    Buffer.BlockCopy(mapEntry.BlockCache, 0, cache, 0, (int)_hd.blocksize);
                    //already checked CRC for this block when the cache was made
                    break;
                }

                _hd.file.Seek((long)_hd.map[block].offset, SeekOrigin.Begin);

                switch (_hd.compression)
                {
                case HDCOMPRESSION_ZLIB:
                case HDCOMPRESSION_ZLIB_PLUS:
                {
                    using (var st = new System.IO.Compression.DeflateStream(_hd.file, System.IO.Compression.CompressionMode.Decompress, true))
                    {
                        int bytes = st.Read(cache, 0, (int)_hd.blocksize);
                        if (bytes != (int)_hd.blocksize)
                        {
                            return(hdErr.HDERR_READ_ERROR);
                        }

                        if (mapEntry.UseCount > 0)
                        {
                            mapEntry.BlockCache = new byte[bytes];
                            Buffer.BlockCopy(cache, 0, mapEntry.BlockCache, 0, bytes);
                        }
                    }

                    if ((mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
                    {
                        _crc = BitConverter.GetBytes(mapEntry.crc);
                    }
                    break;
                }

                default:
                {
                    Console.WriteLine("Unknown compression");
                    return(hdErr.HDERR_DECOMPRESSION_ERROR);
                }
                }
                break;
            }

            case mapFlags.MAP_ENTRY_TYPE_UNCOMPRESSED:
            {
                _hd.file.Seek((long)_hd.map[block].offset, SeekOrigin.Begin);
                int bytes = _hd.file.Read(cache, 0, (int)_hd.blocksize);

                if (bytes != (int)_hd.blocksize)
                {
                    return(hdErr.HDERR_READ_ERROR);
                }
                if ((mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
                {
                    _crc = BitConverter.GetBytes(mapEntry.crc);
                }
                break;
            }

            case mapFlags.MAP_ENTRY_TYPE_MINI:
            {
                byte[] tmp = BitConverter.GetBytes(_hd.map[block].offset);
                for (int i = 0; i < 8; i++)
                {
                    cache[i] = tmp[7 - i];
                }

                for (int i = 8; i < _hd.blocksize; i++)
                {
                    cache[i] = cache[i - 8];
                }
                if ((mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
                {
                    _crc = BitConverter.GetBytes(mapEntry.crc);
                }
                break;
            }

            case mapFlags.MAP_ENTRY_TYPE_SELF_HUNK:
            {
                hdErr ret = read_block_into_cache((int)mapEntry.offset, cache, ref crc);
                if (ret != hdErr.HDERR_NONE)
                {
                    return(ret);
                }
                break;
            }

            default:
                return(hdErr.HDERR_DECOMPRESSION_ERROR);
            }
            return(hdErr.HDERR_NONE);
        }