Пример #1
0
        private PacketType GetPacketType(byte[] type)
        {
            if (ToolKit.SafeCompare(type, filedescriptionpacket_type))
            {
                return(PacketType.DescriptionPacket);
            }

            if (ToolKit.SafeCompare(type, creatorpacket_type))
            {
                return(PacketType.CreatorPacket);
            }

            if (ToolKit.SafeCompare(type, fileverificationpacket_type))
            {
                return(PacketType.VerificationPacket);
            }

            if (ToolKit.SafeCompare(type, mainpacket_type))
            {
                return(PacketType.MainPacket);
            }

            if (ToolKit.SafeCompare(type, recoveryblockpacket_type))
            {
                return(PacketType.RecoveryPacket);
            }

            if (ToolKit.SafeCompare(type, packet_magic))
            {
                return(PacketType.MagicPacket);
            }

            return(PacketType.Unknown);
        }
Пример #2
0
 static Par2FileReader()
 {
     packet_magic = ToolKit.InitByteArrayFromChars('P', 'A', 'R', '2', '\0', 'P', 'K', 'T');
     fileverificationpacket_type = ToolKit.InitByteArrayFromChars('P', 'A', 'R', ' ', '2', '.', '0', '\0', 'I', 'F', 'S', 'C', '\0', '\0', '\0', '\0');
     filedescriptionpacket_type  = ToolKit.InitByteArrayFromChars('P', 'A', 'R', ' ', '2', '.', '0', '\0', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c');
     mainpacket_type             = ToolKit.InitByteArrayFromChars('P', 'A', 'R', ' ', '2', '.', '0', '\0', 'M', 'a', 'i', 'n', '\0', '\0', '\0', '\0');
     recoveryblockpacket_type    = ToolKit.InitByteArrayFromChars('P', 'A', 'R', ' ', '2', '.', '0', '\0', 'R', 'e', 'c', 'v', 'S', 'l', 'i', 'c');
     creatorpacket_type          = ToolKit.InitByteArrayFromChars('P', 'A', 'R', ' ', '2', '.', '0', '\0', 'C', 'r', 'e', 'a', 't', 'o', 'r', '\0');
 }
Пример #3
0
        // Write some data to disk
        internal bool Write(ulong _offset, byte[] buffer, ulong start, uint length)
        {
            if (!IsFileHandleAccessible())
            {
                return(false);
            }

            if (offset != _offset)
            {
                hFile.Position = (long)_offset;

                if (hFile.Position != (long)_offset)
                {
                    return(false);
                }

                offset = _offset;
            }

            int write = (int)length;

            try
            {
                // Write the data
                hFile.Write(buffer, (int)start, write);
                hFile.Flush();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                return(false);
            }

            ToolKit.LogToFile(@"diskfile.log", string.Format("filename={0},offset={1},length={2}", filename, _offset, length));

            if (filename.Contains("EntLib50.chm.par2"))
            {
                ToolKit.LogArrayToFile <byte>("dump.log", buffer);
            }

            offset += length;

            if (filesize < offset)
            {
                filesize = offset;
            }

            return(true);
        }
Пример #4
0
        private void UpdateOrAddRecoverySet(Par2RecoverySet recoverySet)
        {
            lock (syncObject)
            {
                string setid = ToolKit.ToHex(recoverySet.MainPacket.header.setid);

                if (!setids.Keys.Contains(setid))
                {
                    setids.Add(setid, recoverySet);
                }
                else
                {
                    UpdateRecoverySet(setids[setid], recoverySet);
                }
            }
        }
Пример #5
0
        public void GetMagicPackets()
        {
            int readsize = (int)Math.Min((long)10485760, fileInfo.Length);

            byte[] bytes = ReadBytes(readsize);

            int index = 0;

            do
            {
                index = ToolKit.IndexOf(bytes, packet_magic, index);

                if (index < 0)
                {
                    break;
                }

                Console.WriteLine(index);

                index++;
            } while (index >= 0);
        }
Пример #6
0
        public Par2RecoverySet ReadRecoverySet()
        {
            //int readsize = (int)Math.Min((long)buffer_size, fileInfo.Length);

            int readsize = (int)fileInfo.Length;

            byte[] bytes = ReadBytes(readsize);

            int index = 0;

            int file_offset = 0;

            //while (BaseStream.Position < BaseStream.Length)
            {
                do
                {
                    index = ToolKit.IndexOf(bytes, packet_magic, index);

                    if (index < 0)
                    {
                        break;
                    }

                    PacketHeader header = PacketHeader.Create(bytes, index);

                    switch (GetPacketType(header.type))
                    {
                    case PacketType.CreatorPacket:
                        CreatorPacket createPacket = CreatorPacket.Create(header, bytes, index + header.GetSize());
                        par2RecoverySet.AddCreatorPacket(createPacket);
                        index += createPacket.GetSize() - header.GetSize();
                        break;

                    case PacketType.DescriptionPacket:
                        FileDescriptionPacket descPacket = FileDescriptionPacket.Create(header, bytes, index + header.GetSize());
                        par2RecoverySet.AddDescriptionPacket(descPacket);
                        index += descPacket.GetSize() - header.GetSize();
                        break;

                    case PacketType.MainPacket:
                        MainPacket mainPacket = MainPacket.Create(header, bytes, index + header.GetSize());
                        par2RecoverySet.AddMainPacket(mainPacket);
                        index += mainPacket.GetSize() - header.GetSize();
                        break;

                    case PacketType.RecoveryPacket:
                        RecoveryPacket recoveryPacket = RecoveryPacket.Create(header, bytes, index + header.GetSize(), fileInfo.FullName, file_offset);
                        par2RecoverySet.AddRecoveryPacket(recoveryPacket);
                        index += recoveryPacket.GetSize() - header.GetSize();
                        break;

                    case PacketType.VerificationPacket:
                        FileVerificationPacket verPacket = FileVerificationPacket.Create(header, bytes, index + header.GetSize());
                        par2RecoverySet.AddVerificationPacket(verPacket);
                        index += verPacket.GetSize() - header.GetSize();
                        break;

                    case PacketType.Unknown:
                        // Unknown packettype
                        break;
                    }
                } while (index >= 0);

                index = 0;

                readsize = (int)Math.Min((long)buffer_size, BaseStream.Length - BaseStream.Position);

                file_offset += bytes.Length;

                bytes = ReadBytes(readsize);
            }

            return(par2RecoverySet);
        }
Пример #7
0
        private static void CheckBuffer(byte[] buffer, DiskFile diskFile, string filename, int blocksize, Dictionary <uint, FileVerificationEntry> hashfull, ref MatchType matchType, int globalOffset)
        {
            uint partial_key = (uint)(Path.GetFileName(filename).GetHashCode());

            MD5 md5Hasher = MD5.Create();

            //FastCRC32.FastCRC32 crc32 = new FastCRC32.FastCRC32((ulong)blocksize);
            FastCRC32.FastCRC32 crc32 = FastCRC32.FastCRC32.GetCRC32Instance((ulong)blocksize);

            int offset = 0;

            byte inch  = 0;
            byte outch = 0;

            uint crc32Value = 0;

            crc32Value = crc32.CRCUpdateBlock(0xFFFFFFFF, (uint)blocksize, buffer, (uint)offset) ^ 0xFFFFFFFF;

            while (offset < (buffer.Length - blocksize))
            {
                uint key = crc32Value ^ partial_key;

                FileVerificationEntry entry = null;

                if (hashfull.ContainsKey(key))
                {
                    entry = hashfull[key];

                    byte[] blockhash = md5Hasher.ComputeHash(buffer, offset, blocksize);

                    if (ToolKit.ToHex(blockhash) == ToolKit.ToHex(entry.hash))
                    {
                        // We found a complete match, so go to next block !

                        //Console.WriteLine("block found at offset {0}, crc {1}", globalOffset + offset, entry.crc);
                        if (entry.datablock.diskfile == null)
                        {
                            lock (entry)
                            {
                                if (entry.datablock.diskfile == null)
                                {
                                    entry.SetBlock(diskFile, (int)(globalOffset + offset));
                                }
                            }
                        }

                        offset += blocksize;

                        crc32Value = crc32.CRCUpdateBlock(0xFFFFFFFF, (uint)(Math.Min(blocksize, buffer.Length - offset)), buffer, (uint)offset) ^ 0xFFFFFFFF;
                    }
                    else
                    {
                        if (offset + blocksize > buffer.Length)
                        {
                            return;
                        }

                        matchType = MatchType.PartialMatch;

                        inch  = buffer[offset + blocksize];
                        outch = buffer[offset];

                        crc32Value = crc32.windowMask ^ crc32.CRCSlideChar(crc32.windowMask ^ crc32Value, inch, outch);

                        ++offset;
                    }
                }
                else
                {
                    if (offset + blocksize > buffer.Length)
                    {
                        return;
                    }

                    matchType = MatchType.PartialMatch;

                    inch  = buffer[offset + blocksize];
                    outch = buffer[offset];

                    crc32Value = crc32.windowMask ^ crc32.CRCSlideChar(crc32.windowMask ^ crc32Value, inch, outch);

                    ++offset;
                }
            }
        }