1 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and 2 // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. 3 // 4 // Copyright (c) 2003 Peter Brian Clements 5 // 6 // par2cmdline is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2 of the License, or 9 // (at your option) any later version. 10 // 11 // par2cmdline is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 19 20 #ifndef __PAR2REPAIRER_H__ 21 #define __PAR2REPAIRER_H__ 22 23 #include <sigc++/sigc++.h> 24 #include "parheaders.h" 25 26 class Par2Repairer 27 { 28 public: 29 Par2Repairer(void); 30 ~Par2Repairer(void); 31 32 Result PreProcess(const CommandLine &commandline); 33 Result Process(const CommandLine &commandline, bool dorepair); 34 sigc::signal<void, std::string> sig_filename; 35 sigc::signal<void, double> sig_progress; 36 sigc::signal<void, ParHeaders*> sig_headers; 37 sigc::signal<void, std::string, int, int> sig_done; 38 39 // This method allows to determine whether libpar2 includes the patches 40 // ("libpar2-0.2-bugfixes.patch") submitted to libpar2 project. 41 // Use the method in configure scripts for detection. BugfixesPatchVersion2()42 void BugfixesPatchVersion2() { } 43 44 protected: 45 // Steps in verifying and repairing files: 46 47 // Load packets from the specified file 48 bool LoadPacketsFromFile(string filename); 49 // Finish loading a recovery packet 50 bool LoadRecoveryPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); 51 // Finish loading a file description packet 52 bool LoadDescriptionPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); 53 // Finish loading a file verification packet 54 bool LoadVerificationPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); 55 // Finish loading the main packet 56 bool LoadMainPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); 57 // Finish loading the creator packet 58 bool LoadCreatorPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); 59 60 // Load packets from other PAR2 files with names based on the original PAR2 file 61 bool LoadPacketsFromOtherFiles(string filename); 62 63 // Load packets from any other PAR2 files whose names are given on the command line 64 bool LoadPacketsFromExtraFiles(const list<CommandLine::ExtraFile> &extrafiles); 65 66 // Check that the packets are consistent and discard any that are not 67 bool CheckPacketConsistency(void); 68 69 // Use the information in the main packet to get the source files 70 // into the correct order and determine their filenames 71 bool CreateSourceFileList(void); 72 73 // Determine the total number of DataBlocks for the recoverable source files 74 // The allocate the DataBlocks and assign them to each source file 75 bool AllocateSourceBlocks(void); 76 77 // Create a verification hash table for all files for which we have not 78 // found a complete version of the file and for which we have 79 // a verification packet 80 bool PrepareVerificationHashTable(void); 81 82 // Compute the table for the sliding CRC computation 83 bool ComputeWindowTable(void); 84 85 // Attempt to verify all of the source files 86 bool VerifySourceFiles(void); 87 88 // Scan any extra files specified on the command line 89 bool VerifyExtraFiles(const list<CommandLine::ExtraFile> &extrafiles); 90 91 // Attempt to match the data in the DiskFile with the source file 92 bool VerifyDataFile(DiskFile *diskfile, Par2RepairerSourceFile *sourcefile); 93 94 // Perform a sliding window scan of the DiskFile looking for blocks of data that 95 // might belong to any of the source files (for which a verification packet was 96 // available). If a block of data might be from more than one source file, prefer 97 // the one specified by the "sourcefile" parameter. If the first data block 98 // found is for a different source file then "sourcefile" is changed accordingly. 99 bool ScanDataFile(DiskFile *diskfile, // [in] The file being scanned 100 Par2RepairerSourceFile* &sourcefile, // [in/out] The source file matched 101 MatchType &matchtype, // [out] The type of match 102 MD5Hash &hashfull, // [out] The full hash of the file 103 MD5Hash &hash16k, // [out] The hash of the first 16k 104 u32 &count); // [out] The number of blocks found 105 106 // Find out how much data we have found 107 void UpdateVerificationResults(void); 108 109 // Check the verification results and report the results 110 bool CheckVerificationResults(void); 111 112 // Rename any damaged or missnamed target files. 113 bool RenameTargetFiles(void); 114 115 // Work out which files are being repaired, create them, and allocate 116 // target DataBlocks to them, and remember them for later verification. 117 bool CreateTargetFiles(void); 118 119 // Work out which data blocks are available, which need to be copied 120 // directly to the output, and which need to be recreated, and compute 121 // the appropriate Reed Solomon matrix. 122 bool ComputeRSmatrix(void); 123 124 // Allocate memory buffers for reading and writing data to disk. 125 bool AllocateBuffers(size_t memorylimit); 126 127 // Read source data, process it through the RS matrix and write it to disk. 128 bool ProcessData(u64 blockoffset, size_t blocklength); 129 130 // Verify that all of the reconstructed target files are now correct 131 bool VerifyTargetFiles(void); 132 133 // Delete all of the partly reconstructed files 134 bool DeleteIncompleteTargetFiles(void); 135 136 protected: 137 ParHeaders* headers; // Headers 138 bool alreadyloaded; // Already loaded ? 139 CommandLine::NoiseLevel noiselevel; // OnScreen display 140 141 string searchpath; // Where to find files on disk 142 143 bool firstpacket; // Whether or not a valid packet has been found. 144 MD5Hash setid; // The SetId extracted from the first packet. 145 146 map<u32, RecoveryPacket*> recoverypacketmap; // One recovery packet for each exponent value. 147 MainPacket *mainpacket; // One copy of the main packet. 148 CreatorPacket *creatorpacket; // One copy of the creator packet. 149 150 DiskFileMap diskFileMap; 151 152 map<MD5Hash,Par2RepairerSourceFile*> sourcefilemap;// Map from FileId to SourceFile 153 vector<Par2RepairerSourceFile*> sourcefiles; // The source files 154 vector<Par2RepairerSourceFile*> verifylist; // Those source files that are being repaired 155 156 u64 blocksize; // The block size. 157 u64 chunksize; // How much of a block can be processed. 158 u32 sourceblockcount; // The total number of blocks 159 u32 availableblockcount; // How many undamaged blocks have been found 160 u32 missingblockcount; // How many blocks are missing 161 162 bool blocksallocated; // Whether or not the DataBlocks have been allocated 163 vector<DataBlock> sourceblocks; // The DataBlocks that will be read from disk 164 vector<DataBlock> targetblocks; // The DataBlocks that will be written to disk 165 166 u32 windowtable[256]; // Table for sliding CRCs 167 u32 windowmask; // Maks for sliding CRCs 168 169 bool blockverifiable; // Whether and files can be verified at the block level 170 VerificationHashTable verificationhashtable; // Hash table for block verification 171 list<Par2RepairerSourceFile*> unverifiablesourcefiles; // Files that are not block verifiable 172 173 u32 completefilecount; // How many files are fully verified 174 u32 renamedfilecount; // How many files are verified but have the wrong name 175 u32 damagedfilecount; // How many files exist but are damaged 176 u32 missingfilecount; // How many files are completely missing 177 178 vector<DataBlock*> inputblocks; // Which DataBlocks will be read from disk 179 vector<DataBlock*> copyblocks; // Which DataBlocks will copied back to disk 180 vector<DataBlock*> outputblocks; // Which DataBlocks have to calculated using RS 181 182 ReedSolomon<Galois16> rs; // The Reed Solomon matrix. 183 184 void *inputbuffer; // Buffer for reading DataBlocks (chunksize) 185 void *outputbuffer; // Buffer for writing DataBlocks (chunksize * missingblockcount) 186 187 u64 progress; // How much data has been processed. 188 u64 totaldata; // Total amount of data to be processed. 189 u64 totalsize; // Total data size 190 191 bool cancelled; // repair cancelled 192 }; 193 194 #endif // __PAR2REPAIRER_H__ 195