00001 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and 00002 // repair tool). See https://parchive.sourceforge.net for details of PAR 2.0. 00003 // 00004 // Copyright (c) 2003 Peter Brian Clements 00005 // 00006 // par2cmdline is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // par2cmdline is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 #ifndef __PAR2FILEFORMAT_H__ 00021 #define __PAR2FILEFORMAT_H__ 00022 00023 // This file defines the format of a PAR2 file. 00024 00025 // PAR2 files consist of one or more "packets" that contain information 00026 // that is required to be able to verify and repair damaged data files. 00027 00028 // All packets start with a short "header" which contains information 00029 // used to describe what sort of data is stored in the rest of the packet 00030 // and also to allow that data to be verified. 00031 00032 // This file details the format for the following packet types described 00033 // in the PAR 2.0 specification: 00034 00035 // Main Packet struct MAINPACKET 00036 // File Description Packet struct FILEDESCRIPTIONPACKET 00037 // Input File Slice Checksum Packet struct FILEVERIFICATIONPACKET 00038 // Recovery Slice Packet struct RECOVERYBLOCKPACKET 00039 // Creator Packet struct CREATORPACKET 00040 00041 00042 #ifdef WIN32 00043 #pragma pack(push, 1) 00044 #define PACKED 00045 #else 00046 #define PACKED __attribute__ ((packed)) 00047 #endif 00048 00049 #ifdef _MSC_VER 00050 #pragma warning(disable:4200) 00051 #endif 00052 00053 // All numeric fields in the file format are in LITTLE ENDIAN format. 00054 00055 // The types leu32 and leu64 are defined in letype.h 00056 00057 // Two simple types used in the packet header. 00058 struct MAGIC {u8 magic[8];} PACKED; 00059 struct PACKETTYPE {u8 type[16];} PACKED; 00060 00061 // Every packet starts with a packet header. 00062 struct PACKET_HEADER 00063 { 00064 // Header 00065 MAGIC magic; // = {'P', 'A', 'R', '2', '\0', 'P', 'K', 'T'} 00066 leu64 length; // Length of entire packet including header 00067 MD5Hash hash; // Hash of entire packet excepting the first 3 fields 00068 MD5Hash setid; // Normally computed as the Hash of body of "Main Packet" 00069 PACKETTYPE type; // Used to specify the meaning of the rest of the packet 00070 } PACKED; 00071 00072 // The file verification packet is used to determine whether or not any 00073 // parts of a damaged file are useable. 00074 // It contains a FileId used to pair it with a corresponding file description 00075 // packet, followed by an array of hash and crc values. The number of entries in 00076 // the array can be determined from the packet_length. 00077 struct FILEVERIFICATIONENTRY 00078 { 00079 MD5Hash hash; 00080 leu32 crc; 00081 } PACKED; 00082 struct FILEVERIFICATIONPACKET 00083 { 00084 PACKET_HEADER header; 00085 // Body 00086 MD5Hash fileid; // MD5hash of file_hash_16k, file_length, file_name 00087 FILEVERIFICATIONENTRY entries[]; 00088 } PACKED; 00089 00090 // The file description packet is used to record the name of the file, 00091 // its size, and the Hash of both the whole file and the first 16k of 00092 // the file. 00093 // If the name of the file is an exact multiple of 4 characters in length 00094 // then it may not have a NULL termination. If the name of the file is not 00095 // an exact multiple of 4, then it will be padded with 0 bytes at the 00096 // end to make it up to a multiple of 4. 00097 struct FILEDESCRIPTIONPACKET 00098 { 00099 PACKET_HEADER header; 00100 // Body 00101 MD5Hash fileid; // MD5hash of [hash16k, length, name] 00102 MD5Hash hashfull; // MD5 Hash of the whole file 00103 MD5Hash hash16k; // MD5 Hash of the first 16k of the file 00104 leu64 length; // Length of the file 00105 u8 name[]; // Name of the file, padded with 1 to 3 zero bytes to reach 00106 // a multiple of 4 bytes. 00107 // Actual length can be determined from overall packet 00108 // length and then working backwards to find the first non 00109 // zero character. 00110 00111 //u8* name(void) {return (u8*)&this[1];} 00112 //const u8* name(void) const {return (const u8*)&this[1];} 00113 } PACKED; 00114 00115 // The main packet is used to tie together the other packets in a recovery file. 00116 // It specifies the block size used to virtually slice the source files, a count 00117 // of the number of source files, and an array of Hash values used to specify 00118 // in what order the source files are processed. 00119 // Each entry in the fileid array corresponds with the fileid value 00120 // in a file description packet and a file verification packet. 00121 // The fileid array may contain more entries than the count of the number 00122 // of recoverable files. The extra entries correspond to files that were not 00123 // used during the creation of the recovery files and which may not therefore 00124 // be repaired if they are found to be damaged. 00125 struct MAINPACKET 00126 { 00127 PACKET_HEADER header; 00128 // Body 00129 leu64 blocksize; 00130 leu32 recoverablefilecount; 00131 MD5Hash fileid[0]; 00132 //MD5Hash* fileid(void) {return (MD5Hash*)&this[1];} 00133 //const MD5Hash* fileid(void) const {return (const MD5Hash*)&this[1];} 00134 } PACKED; 00135 00136 // The creator packet is used to identify which program created a particular 00137 // recovery file. It is not required for verification or recovery of damaged 00138 // files. 00139 struct CREATORPACKET 00140 { 00141 PACKET_HEADER header; 00142 // Body 00143 u8 client[]; 00144 //u8* client(void) {return (u8*)&this[1];} 00145 } PACKED; 00146 00147 // The recovery block packet contains a single block of recovery data along 00148 // with the exponent value used during the computation of that block. 00149 struct RECOVERYBLOCKPACKET 00150 { 00151 PACKET_HEADER header; 00152 // Body 00153 leu32 exponent; 00154 // unsigned long data[]; 00155 // unsigned long* data(void) {return (unsigned long*)&this[1];} 00156 } PACKED; 00157 00158 #ifdef _MSC_VER 00159 #pragma warning(default:4200) 00160 #endif 00161 00162 #ifdef WIN32 00163 #pragma pack(pop) 00164 #endif 00165 #undef PACKED 00166 00167 00168 // Operators for comparing the MAGIC and PACKETTYPE values 00169 00170 inline bool operator == (const MAGIC &left, const MAGIC &right) 00171 { 00172 return (0==memcmp(&left, &right, sizeof(left))); 00173 } 00174 00175 inline bool operator != (const MAGIC &left, const MAGIC &right) 00176 { 00177 return !operator==(left, right); 00178 } 00179 00180 inline bool operator == (const PACKETTYPE &left, const PACKETTYPE &right) 00181 { 00182 return (0==memcmp(&left, &right, sizeof(left))); 00183 } 00184 00185 inline bool operator != (const PACKETTYPE &left, const PACKETTYPE &right) 00186 { 00187 return !operator==(left, right); 00188 } 00189 00190 extern MAGIC packet_magic; 00191 00192 extern PACKETTYPE fileverificationpacket_type; 00193 extern PACKETTYPE filedescriptionpacket_type; 00194 extern PACKETTYPE mainpacket_type; 00195 extern PACKETTYPE recoveryblockpacket_type; 00196 extern PACKETTYPE creatorpacket_type; 00197 00198 00199 #endif //__PAR2FILEFORMAT_H__