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); }
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'); }
// 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); }
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); } } }
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); }
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); }
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; } } }