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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20 #ifndef __PAR2REPAIRER_H__
21 #define __PAR2REPAIRER_H__
22 
23 class Par2Repairer
24 {
25 public:
26   Par2Repairer(void);
27   ~Par2Repairer(void);
28 
29   Result Process(const CommandLine &commandline, bool dorepair);
30 
31 protected:
32   // Steps in verifying and repairing files:
33 
34   // Load packets from the specified file
35   bool LoadPacketsFromFile(string filename);
36   // Finish loading a recovery packet
37   bool LoadRecoveryPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
38   // Finish loading a file description packet
39   bool LoadDescriptionPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
40   // Finish loading a file verification packet
41   bool LoadVerificationPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
42   // Finish loading the main packet
43   bool LoadMainPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
44   // Finish loading the creator packet
45   bool LoadCreatorPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
46 
47   // Load packets from other PAR2 files with names based on the original PAR2 file
48   bool LoadPacketsFromOtherFiles(string filename);
49 
50   // Load packets from any other PAR2 files whose names are given on the command line
51   bool LoadPacketsFromExtraFiles(const list<CommandLine::ExtraFile> &extrafiles);
52 
53   // Check that the packets are consistent and discard any that are not
54   bool CheckPacketConsistency(void);
55 
56   // Use the information in the main packet to get the source files
57   // into the correct order and determine their filenames
58   bool CreateSourceFileList(void);
59 
60   // Determine the total number of DataBlocks for the recoverable source files
61   // The allocate the DataBlocks and assign them to each source file
62   bool AllocateSourceBlocks(void);
63 
64   // Create a verification hash table for all files for which we have not
65   // found a complete version of the file and for which we have
66   // a verification packet
67   bool PrepareVerificationHashTable(void);
68 
69   // Compute the table for the sliding CRC computation
70   bool ComputeWindowTable(void);
71 
72   // Attempt to verify all of the source files
73   bool VerifySourceFiles(void);
74 
75   // Scan any extra files specified on the command line
76   bool VerifyExtraFiles(const list<CommandLine::ExtraFile> &extrafiles, const multimap<string,string> &extrafilenamemap);
77 
78   // Scan an extra file
79   bool VerifyExtraFile(const string &filename);
80 
81   // Attempt to match the data in the DiskFile with the source file
82   bool VerifyDataFile(DiskFile *diskfile, Par2RepairerSourceFile *sourcefile);
83 
84   // Perform a sliding window scan of the DiskFile looking for blocks of data that
85   // might belong to any of the source files (for which a verification packet was
86   // available). If a block of data might be from more than one source file, prefer
87   // the one specified by the "sourcefile" parameter. If the first data block
88   // found is for a different source file then "sourcefile" is changed accordingly.
89   bool ScanDataFile(DiskFile                *diskfile,   // [in]     The file being scanned
90                     Par2RepairerSourceFile* &sourcefile, // [in/out] The source file matched
91                     MatchType               &matchtype,  // [out]    The type of match
92                     MD5Hash                 &hashfull,   // [out]    The full hash of the file
93                     MD5Hash                 &hash16k,    // [out]    The hash of the first 16k
94                     u32                     &count);     // [out]    The number of blocks found
95 
96   // Find out how much data we have found
97   void UpdateVerificationResults(void);
98 
99   // Check the verification results and report the results
100   bool CheckVerificationResults(void);
101 
102 public:
103   string                    searchpath;              // Where to find files on disk
104 
105   bool                      firstpacket;             // Whether or not a valid packet has been found.
106   MD5Hash                   setid;                   // The SetId extracted from the first packet.
107 
108   map<u32, RecoveryPacket*> recoverypacketmap;       // One recovery packet for each exponent value.
109   MainPacket               *mainpacket;              // One copy of the main packet.
110   CreatorPacket            *creatorpacket;           // One copy of the creator packet.
111 
112   DiskFileMap               diskFileMap;
113 
114   map<MD5Hash,Par2RepairerSourceFile*> sourcefilemap;// Map from FileId to SourceFile
115   vector<Par2RepairerSourceFile*>      sourcefiles;  // The source files
116   vector<Par2RepairerSourceFile*>      verifylist;   // Those source files that are being repaired
117 
118   u64                       blocksize;               // The block size.
119   u64                       chunksize;               // How much of a block can be processed.
120   u32                       sourceblockcount;        // The total number of blocks
121   u32                       availableblockcount;     // How many undamaged blocks have been found
122   u32                       missingblockcount;       // How many blocks are missing
123 
124   bool                      blocksallocated;         // Whether or not the DataBlocks have been allocated
125   vector<DataBlock>         sourceblocks;            // The DataBlocks that will be read from disk
126   vector<DataBlock>         targetblocks;            // The DataBlocks that will be written to disk
127 
128   u32                       windowtable[256];        // Table for sliding CRCs
129   u32                       windowmask;              // Maks for sliding CRCs
130 
131   bool                            blockverifiable;         // Whether and files can be verified at the block level
132   VerificationHashTable           verificationhashtable;   // Hash table for block verification
133   list<Par2RepairerSourceFile*>   unverifiablesourcefiles; // Files that are not block verifiable
134 
135   u32                       completefilecount;       // How many files are fully verified
136   u32                       renamedfilecount;        // How many files are verified but have the wrong name
137   u32                       damagedfilecount;        // How many files exist but are damaged
138   u32                       missingfilecount;        // How many files are completely missing
139 
140   vector<DataBlock*>        inputblocks;             // Which DataBlocks will be read from disk
141   vector<DataBlock*>        copyblocks;              // Which DataBlocks will copied back to disk
142   vector<DataBlock*>        outputblocks;            // Which DataBlocks have to calculated using RS
143 
144   u64                       progress;                // How much data has been processed.
145   u64                       totaldata;               // Total amount of data to be processed.
146 };
147 
148 #endif // __PAR2REPAIRER_H__
149