unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

rdwrfn.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
4{
5#ifndef RAR_NOCRYPT
8#endif
9
10 Init();
11}
12
13
15{
16 UnpackFromMemory=false;
17 UnpackToMemory=false;
20 ShowProgress=true;
21 TestMode=false;
22 SkipUnpCRC=false;
23 NoFileHeader=false;
24 PackVolume=false;
25 UnpVolume=false;
27 SrcFile=NULL;
28 DestFile=NULL;
29 UnpWrAddr=NULL;
30 UnpWrSize=0;
31 Command=NULL;
32 Encryption=false;
33 Decryption=false;
35 LastPercent=-1;
36 SubHead=NULL;
37 SubHeadPos=NULL;
42}
43
44
46{
47#ifndef RAR_NOCRYPT
48 delete Crypt;
49 delete Decrypt;
50#endif
51}
52
53
54
55
56int ComprDataIO::UnpRead(byte *Addr,size_t Count)
57{
58#ifndef RAR_NOCRYPT
59 // In case of encryption we need to align read size to encryption
60 // block size. We can do it by simple masking, because unpack read code
61 // always reads more than CRYPT_BLOCK_SIZE, so we do not risk to make it 0.
62 if (Decryption)
63 Count &= ~CRYPT_BLOCK_MASK;
64#endif
65
66 int ReadSize=0,TotalRead=0;
67 byte *ReadAddr;
68 ReadAddr=Addr;
69 while (Count > 0)
70 {
71 Archive *SrcArc=(Archive *)SrcFile;
72
74 {
76 ReadSize=(int)UnpackFromMemorySize;
78 }
79 else
80 {
81 size_t SizeToRead=((int64)Count>UnpPackedLeft) ? (size_t)UnpPackedLeft:Count;
82 if (SizeToRead > 0)
83 {
84 if (UnpVolume && Decryption && (int64)Count>UnpPackedLeft)
85 {
86 // We need aligned blocks for decryption and we want "Keep broken
87 // files" to work efficiently with missing encrypted volumes.
88 // So for last data block in volume we adjust the size to read to
89 // next equal or smaller block producing aligned total block size.
90 // So we'll ask for next volume only when processing few unaligned
91 // bytes left in the end, when most of data is already extracted.
92 size_t NewTotalRead = TotalRead + SizeToRead;
93 size_t Adjust = NewTotalRead - (NewTotalRead & ~CRYPT_BLOCK_MASK);
94 size_t NewSizeToRead = SizeToRead - Adjust;
95 if ((int)NewSizeToRead > 0)
96 SizeToRead = NewSizeToRead;
97 }
98
99 if (!SrcFile->IsOpened())
100 return -1;
101 ReadSize=SrcFile->Read(ReadAddr,SizeToRead);
102 FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->FileHead;
103 if (!NoFileHeader && hd->SplitAfter)
104 PackedDataHash.Update(ReadAddr,ReadSize);
105 }
106 }
107 CurUnpRead+=ReadSize;
108 TotalRead+=ReadSize;
109#ifndef NOVOLUME
110 // These variable are not used in NOVOLUME mode, so it is better
111 // to exclude commands below to avoid compiler warnings.
112 ReadAddr+=ReadSize;
113 Count-=ReadSize;
114#endif
115 UnpPackedLeft-=ReadSize;
116
117 // Do not ask for next volume if we read something from current volume.
118 // If next volume is missing, we need to process all data from current
119 // volume before aborting. It helps to recover all possible data
120 // in "Keep broken files" mode. But if we process encrypted data,
121 // we ask for next volume also if we have non-aligned encryption block.
122 // Since we adjust data size for decryption earlier above,
123 // it does not hurt "Keep broken files" mode efficiency.
124 if (UnpVolume && UnpPackedLeft == 0 &&
125 (ReadSize==0 || Decryption && (TotalRead & CRYPT_BLOCK_MASK) != 0) )
126 {
127#ifndef NOVOLUME
128 if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
129#endif
130 {
132 return -1;
133 }
134 }
135 else
136 break;
137 }
138 Archive *SrcArc=(Archive *)SrcFile;
139 if (SrcArc!=NULL)
141 if (ReadSize!=-1)
142 {
143 ReadSize=TotalRead;
144#ifndef RAR_NOCRYPT
145 if (Decryption)
146 Decrypt->DecryptBlock(Addr,ReadSize);
147#endif
148 }
149 Wait();
150 return ReadSize;
151}
152
153
154void ComprDataIO::UnpWrite(byte *Addr,size_t Count)
155{
156
157#ifdef RARDLL
158 RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
159 if (Cmd->DllOpMode!=RAR_SKIP)
160 {
161 if (Cmd->Callback!=NULL &&
162 Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LPARAM)Addr,Count)==-1)
164 if (Cmd->ProcessDataProc!=NULL)
165 {
166 int RetCode=Cmd->ProcessDataProc(Addr,(int)Count);
167 if (RetCode==0)
169 }
170 }
171#endif // RARDLL
172
173 UnpWrAddr=Addr;
174 UnpWrSize=Count;
175 if (UnpackToMemory)
176 {
177 if (Count <= UnpackToMemorySize)
178 {
179 memcpy(UnpackToMemoryAddr,Addr,Count);
180 UnpackToMemoryAddr+=Count;
181 UnpackToMemorySize-=Count;
182 }
183 }
184 else
185 if (!TestMode)
186 DestFile->Write(Addr,Count);
187 CurUnpWrite+=Count;
188 if (!SkipUnpCRC)
189 UnpHash.Update(Addr,Count);
190 ShowUnpWrite();
191 Wait();
192}
193
194
195
196
197
198
200{
201 if (ShowProgress && SrcFile!=NULL)
202 {
203 // Important when processing several archives or multivolume archive.
204 ArcPos+=ProcessedArcSize;
205
206 Archive *SrcArc=(Archive *)SrcFile;
207 RAROptions *Cmd=SrcArc->GetRAROptions();
208
209 int CurPercent=ToPercent(ArcPos,ArcSize);
210 if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
211 {
212 uiExtractProgress(CurUnpWrite,SrcArc->FileHead.UnpSize,ArcPos,ArcSize);
213 LastPercent=CurPercent;
214 }
215 }
216}
217
218
220{
221}
222
223
224
225
226
227
228
229
230
231
232void ComprDataIO::SetFiles(File *SrcFile,File *DestFile)
233{
234 if (SrcFile!=NULL)
236 if (DestFile!=NULL)
238 LastPercent=-1;
239}
240
241
242void ComprDataIO::GetUnpackedData(byte **Data,size_t *Size)
243{
244 *Data=UnpWrAddr;
245 *Size=UnpWrSize;
246}
247
248
250 SecPassword *Password,const byte *Salt,const byte *InitV,
251 uint Lg2Cnt,byte *HashKey,byte *PswCheck)
252{
253#ifndef RAR_NOCRYPT
254 if (Encrypt)
255 Encryption=Crypt->SetCryptKeys(true,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck);
256 else
257 Decryption=Decrypt->SetCryptKeys(false,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck);
258#endif
259}
260
261
262#if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
264{
265 Decryption=true;
267}
268#endif
269
270
271#if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
273{
274 Decryption=true;
276}
277#endif
278
279
280
281
283{
284 UnpackToMemory=true;
287}
288
289
290// Extraction progress is based on the position in archive and we adjust
291// the total archives size here, so trailing blocks do not prevent progress
292// reaching 100% at the end of extraction. Alternatively we could print "100%"
293// after completing the entire archive extraction, but then we would need
294// to take into account possible messages like the checksum error after
295// last file percent progress.
297{
298 // If we know a position of QO or RR blocks, use them to adjust the total
299 // packed size to beginning of these blocks. Earlier we already calculated
300 // the total size based on entire archive sizes. We also set LastArcSize
301 // to start of first trailing block, to add it later to ProcessedArcSize.
302 int64 ArcLength=Arc->IsSeekable() ? Arc->FileLength() : 0;
303 if (Arc->MainHead.QOpenOffset!=0) // QO is always preceding RR record.
305 else
306 if (Arc->MainHead.RROffset!=0)
308 else
309 {
310 // If neither QO nor RR are found, exclude the approximate size of
311 // end of archive block.
312 // We select EndBlock to be larger than typical 8 bytes HEAD_ENDARC,
313 // but to not exceed the smallest 22 bytes HEAD_FILE with 1 byte file
314 // name, so we do not have two files with 100% at the end of archive.
315 const uint EndBlock=23;
316
317 if (ArcLength>EndBlock)
318 LastArcSize=ArcLength-EndBlock;
319 }
320
321 TotalArcSize-=ArcLength-LastArcSize;
322}
ErrorHandler ErrHandler
FileHeader FileHead
Definition: archive.hpp:104
RAROptions * GetRAROptions()
Definition: archive.hpp:86
int64 NextBlockPos
Definition: archive.hpp:115
MainHeader MainHead
Definition: archive.hpp:102
bool NextVolumeMissing
Definition: rdwrfn.hpp:84
int64 LastArcSize
Definition: rdwrfn.hpp:93
int64 UnpPackedLeft
Definition: rdwrfn.hpp:33
bool Encryption
Definition: rdwrfn.hpp:101
int64 CurUnpWrite
Definition: rdwrfn.hpp:85
void SetCmt13Encryption()
Definition: rdwrfn.cpp:272
void UnpWrite(byte *Addr, size_t Count)
Definition: rdwrfn.cpp:154
bool SkipUnpCRC
Definition: rdwrfn.hpp:37
int64 UnpPackedSize
Definition: rdwrfn.hpp:32
byte * UnpWrAddr
Definition: rdwrfn.hpp:30
CmdAdd * Command
Definition: rdwrfn.hpp:43
int LastPercent
Definition: rdwrfn.hpp:54
int64 ProcessedArcSize
Definition: rdwrfn.hpp:90
int64 TotalArcSize
Definition: rdwrfn.hpp:95
bool PackVolume
Definition: rdwrfn.hpp:82
DataHash UnpHash
Definition: rdwrfn.hpp:99
File * SrcFile
Definition: rdwrfn.hpp:40
bool Decryption
Definition: rdwrfn.hpp:102
bool TestMode
Definition: rdwrfn.hpp:36
wchar CurrentCommand
Definition: rdwrfn.hpp:56
byte * UnpackToMemoryAddr
Definition: rdwrfn.hpp:27
void SetEncryption(bool Encrypt, CRYPT_METHOD Method, SecPassword *Password, const byte *Salt, const byte *InitV, uint Lg2Cnt, byte *HashKey, byte *PswCheck)
Definition: rdwrfn.cpp:249
int UnpRead(byte *Addr, size_t Count)
Definition: rdwrfn.cpp:56
size_t UnpackToMemorySize
Definition: rdwrfn.hpp:26
bool UnpackFromMemory
Definition: rdwrfn.hpp:21
void GetUnpackedData(byte **Data, size_t *Size)
Definition: rdwrfn.cpp:242
void AdjustTotalArcSize(Archive *Arc)
Definition: rdwrfn.cpp:296
CryptData * Decrypt
Definition: rdwrfn.hpp:50
int64 CurPackWrite
Definition: rdwrfn.hpp:85
void Init()
Definition: rdwrfn.cpp:14
bool UnpVolume
Definition: rdwrfn.hpp:83
byte * UnpackFromMemoryAddr
Definition: rdwrfn.hpp:23
void SetFiles(File *SrcFile, File *DestFile)
Definition: rdwrfn.cpp:232
bool UnpackToMemory
Definition: rdwrfn.hpp:25
CryptData * Crypt
Definition: rdwrfn.hpp:49
FileHeader * SubHead
Definition: rdwrfn.hpp:45
int64 * SubHeadPos
Definition: rdwrfn.hpp:46
void ShowUnpWrite()
Definition: rdwrfn.cpp:219
bool NoFileHeader
Definition: rdwrfn.hpp:38
ComprDataIO()
Definition: rdwrfn.cpp:3
int64 CurUnpRead
Definition: rdwrfn.hpp:85
size_t UnpackFromMemorySize
Definition: rdwrfn.hpp:22
DataHash PackedDataHash
Definition: rdwrfn.hpp:97
~ComprDataIO()
Definition: rdwrfn.cpp:45
int64 CurPackRead
Definition: rdwrfn.hpp:85
size_t UnpWrSize
Definition: rdwrfn.hpp:29
void SetAV15Encryption()
Definition: rdwrfn.cpp:263
bool ShowProgress
Definition: rdwrfn.hpp:35
void SetUnpackToMemory(byte *Addr, uint Size)
Definition: rdwrfn.cpp:282
void ShowUnpRead(int64 ArcPos, int64 ArcSize)
Definition: rdwrfn.cpp:199
File * DestFile
Definition: rdwrfn.hpp:41
bool SetCryptKeys(bool Encrypt, CRYPT_METHOD Method, SecPassword *Password, const byte *Salt, const byte *InitV, uint Lg2Cnt, byte *HashKey, byte *PswCheck)
Definition: crypt.cpp:55
void SetCmt13Encryption()
Definition: crypt1.cpp:44
void SetAV15Encryption()
Definition: crypt1.cpp:33
void DecryptBlock(byte *Buf, size_t Size)
Definition: crypt.cpp:31
void Update(const void *Data, size_t DataSize)
Definition: hash.cpp:84
void Exit(RAR_EXIT ExitCode)
Definition: errhnd.cpp:236
Definition: file.hpp:57
virtual bool IsOpened()
Definition: file.hpp:122
int64 FileLength()
Definition: file.cpp:750
bool Write(const void *Data, size_t Size)
Definition: file.cpp:298
virtual int Read(void *Data, size_t Size)
Definition: file.cpp:374
bool IsSeekable()
Definition: file.hpp:127
bool DisablePercentage
Definition: options.hpp:135
CRYPT_METHOD
Definition: crypt.hpp:5
#define CRYPT_BLOCK_MASK
Definition: crypt.hpp:16
#define RAR_SKIP
Definition: dll.hpp:27
@ UCM_PROCESSDATA
Definition: dll.hpp:159
@ RARX_USERBREAK
Definition: errhnd.hpp:19
int64_t int64
Definition: rartypes.hpp:12
unsigned int uint
Definition: rartypes.hpp:8
int ToPercent(int64 N1, int64 N2)
Definition: smallfn.cpp:3
int64 UnpSize
Definition: headers.hpp:193
bool SplitAfter
Definition: headers.hpp:201
uint64 RROffset
Definition: headers.hpp:169
uint64 QOpenOffset
Definition: headers.hpp:167
void Wait()
Definition: system.cpp:80
void uiExtractProgress(int64 CurFileSize, int64 TotalFileSize, int64 CurSize, int64 TotalSize)
Definition: uiconsole.cpp:72
bool MergeArchive(Archive &Arc, ComprDataIO *DataIO, bool ShowFileName, wchar Command)
Definition: volume.cpp:10