1 #include "rar.hpp"
2 
ComprDataIO()3 ComprDataIO::ComprDataIO()
4 {
5   Init();
6 }
7 
8 
Init()9 void ComprDataIO::Init()
10 {
11   UnpackFromMemory=false;
12   UnpackToMemory=false;
13   UnpPackedSize=0;
14   ShowProgress=true;
15   TestMode=false;
16   SkipUnpCRC=false;
17   PackVolume=false;
18   UnpVolume=false;
19   NextVolumeMissing=false;
20   SrcFile=NULL;
21   DestFile=NULL;
22   UnpWrSize=0;
23   Command=NULL;
24   Encryption=0;
25   Decryption=0;
26   TotalPackRead=0;
27   CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=0;
28   PackFileCRC=UnpFileCRC=PackedCRC=0xffffffff;
29   LastPercent=-1;
30   SubHead=NULL;
31   SubHeadPos=NULL;
32   CurrentCommand=0;
33   ProcessedArcSize=TotalArcSize=0;
34 }
35 
36 
37 
38 
UnpRead(byte * Addr,size_t Count)39 int ComprDataIO::UnpRead(byte *Addr,size_t Count)
40 {
41   int RetCode=0,TotalRead=0;
42   byte *ReadAddr;
43   ReadAddr=Addr;
44   while (Count > 0)
45   {
46     Archive *SrcArc=(Archive *)SrcFile;
47 
48     size_t ReadSize=((int64)Count>UnpPackedSize) ? (size_t)UnpPackedSize:Count;
49     if (UnpackFromMemory)
50     {
51       memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize);
52       RetCode=(int)UnpackFromMemorySize;
53       UnpackFromMemorySize=0;
54     }
55     else
56     {
57       if (!SrcFile->IsOpened())
58         return(-1);
59       RetCode=SrcFile->Read(ReadAddr,ReadSize);
60       FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->NewLhd;
61       if (hd->Flags & LHD_SPLIT_AFTER)
62         PackedCRC=CRC(PackedCRC,ReadAddr,RetCode);
63     }
64     CurUnpRead+=RetCode;
65     TotalRead+=RetCode;
66 #ifndef NOVOLUME
67     // These variable are not used in NOVOLUME mode, so it is better
68     // to exclude commands below to avoid compiler warnings.
69     ReadAddr+=RetCode;
70     Count-=RetCode;
71 #endif
72     UnpPackedSize-=RetCode;
73     if (UnpPackedSize == 0 && UnpVolume)
74     {
75 #ifndef NOVOLUME
76       if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
77 #endif
78       {
79         NextVolumeMissing=true;
80         return(-1);
81       }
82     }
83     else
84       break;
85   }
86   Archive *SrcArc=(Archive *)SrcFile;
87   if (SrcArc!=NULL)
88     ShowUnpRead(SrcArc->CurBlockPos+CurUnpRead,UnpArcSize);
89   if (RetCode!=-1)
90   {
91     RetCode=TotalRead;
92 #ifndef RAR_NOCRYPT
93     if (Decryption)
94 #ifndef SFX_MODULE
95       if (Decryption<20)
96         Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE);
97       else
98         if (Decryption==20)
99           for (int I=0;I<RetCode;I+=16)
100             Decrypt.DecryptBlock20(&Addr[I]);
101         else
102 #endif
103         {
104           int CryptSize=(RetCode & 0xf)==0 ? RetCode:((RetCode & ~0xf)+16);
105           Decrypt.DecryptBlock(Addr,CryptSize);
106         }
107 #endif
108   }
109   Wait();
110   return(RetCode);
111 }
112 
113 
114 #if defined(RARDLL) && defined(_MSC_VER) && !defined(_WIN_64)
115 // Disable the run time stack check for unrar.dll, so we can manipulate
116 // with ProcessDataProc call type below. Run time check would intercept
117 // a wrong ESP before we restore it.
118 #pragma runtime_checks( "s", off )
119 #endif
120 
UnpWrite(byte * Addr,size_t Count)121 void ComprDataIO::UnpWrite(byte *Addr,size_t Count)
122 {
123 
124 #ifdef RARDLL
125   RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
126   if (Cmd->DllOpMode!=RAR_SKIP)
127   {
128     if (Cmd->Callback!=NULL &&
129         Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LPARAM)Addr,Count)==-1)
130       ErrHandler.Exit(USER_BREAK);
131     if (Cmd->ProcessDataProc!=NULL)
132     {
133       // Here we preserve ESP value. It is necessary for those developers,
134       // who still define ProcessDataProc callback as "C" type function,
135       // even though in year 2001 we announced in unrar.dll whatsnew.txt
136       // that it will be PASCAL type (for compatibility with Visual Basic).
137 #if defined(_MSC_VER)
138 #ifndef _WIN_64
139       __asm mov ebx,esp
140 #endif
141 #elif defined(_WIN_ALL) && defined(__BORLANDC__)
142       _EBX=_ESP;
143 #endif
144       int RetCode=Cmd->ProcessDataProc(Addr,(int)Count);
145 
146       // Restore ESP after ProcessDataProc with wrongly defined calling
147       // convention broken it.
148 #if defined(_MSC_VER)
149 #ifndef _WIN_64
150       __asm mov esp,ebx
151 #endif
152 #elif defined(_WIN_ALL) && defined(__BORLANDC__)
153       _ESP=_EBX;
154 #endif
155       if (RetCode==0)
156         ErrHandler.Exit(USER_BREAK);
157     }
158   }
159 #endif // RARDLL
160 
161   UnpWrAddr=Addr;
162   UnpWrSize=Count;
163   if (UnpackToMemory)
164   {
165     if (Count <= UnpackToMemorySize)
166     {
167       memcpy(UnpackToMemoryAddr,Addr,Count);
168       UnpackToMemoryAddr+=Count;
169       UnpackToMemorySize-=Count;
170     }
171   }
172   else
173     if (!TestMode)
174       DestFile->Write(Addr,Count);
175   CurUnpWrite+=Count;
176   if (!SkipUnpCRC)
177 #ifndef SFX_MODULE
178     if (((Archive *)SrcFile)->OldFormat)
179       UnpFileCRC=OldCRC((ushort)UnpFileCRC,Addr,Count);
180     else
181 #endif
182       UnpFileCRC=CRC(UnpFileCRC,Addr,Count);
183   ShowUnpWrite();
184   Wait();
185 }
186 
187 #if defined(RARDLL) && defined(_MSC_VER) && !defined(_WIN_64)
188 // Restore the run time stack check for unrar.dll.
189 #pragma runtime_checks( "s", restore )
190 #endif
191 
192 
193 
194 
195 
196 
ShowUnpRead(int64 ArcPos,int64 ArcSize)197 void ComprDataIO::ShowUnpRead(int64 ArcPos,int64 ArcSize)
198 {
199   if (ShowProgress && SrcFile!=NULL)
200   {
201     if (TotalArcSize!=0)
202     {
203       // important when processing several archives or multivolume archive
204       ArcSize=TotalArcSize;
205       ArcPos+=ProcessedArcSize;
206     }
207 
208     Archive *SrcArc=(Archive *)SrcFile;
209     RAROptions *Cmd=SrcArc->GetRAROptions();
210 
211     int CurPercent=ToPercent(ArcPos,ArcSize);
212     if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
213     {
214       mprintf("\b\b\b\b%3d%%",CurPercent);
215       LastPercent=CurPercent;
216     }
217   }
218 }
219 
220 
ShowUnpWrite()221 void ComprDataIO::ShowUnpWrite()
222 {
223 }
224 
225 
226 
227 
228 
229 
230 
231 
SetFiles(File * SrcFile,File * DestFile)232 void ComprDataIO::SetFiles(File *SrcFile,File *DestFile)
233 {
234   if (SrcFile!=NULL)
235     ComprDataIO::SrcFile=SrcFile;
236   if (DestFile!=NULL)
237     ComprDataIO::DestFile=DestFile;
238   LastPercent=-1;
239 }
240 
241 
GetUnpackedData(byte ** Data,size_t * Size)242 void ComprDataIO::GetUnpackedData(byte **Data,size_t *Size)
243 {
244   *Data=UnpWrAddr;
245   *Size=UnpWrSize;
246 }
247 
248 
SetEncryption(int Method,const wchar * Password,const byte * Salt,bool Encrypt,bool HandsOffHash)249 void ComprDataIO::SetEncryption(int Method,const wchar *Password,const byte *Salt,bool Encrypt,bool HandsOffHash)
250 {
251   if (Encrypt)
252   {
253     Encryption=*Password ? Method:0;
254 #ifndef RAR_NOCRYPT
255     Crypt.SetCryptKeys(Password,Salt,Encrypt,false,HandsOffHash);
256 #endif
257   }
258   else
259   {
260     Decryption=*Password ? Method:0;
261 #ifndef RAR_NOCRYPT
262     Decrypt.SetCryptKeys(Password,Salt,Encrypt,Method<29,HandsOffHash);
263 #endif
264   }
265 }
266 
267 
268 #if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
SetAV15Encryption()269 void ComprDataIO::SetAV15Encryption()
270 {
271   Decryption=15;
272   Decrypt.SetAV15Encryption();
273 }
274 #endif
275 
276 
277 #if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
SetCmt13Encryption()278 void ComprDataIO::SetCmt13Encryption()
279 {
280   Decryption=13;
281   Decrypt.SetCmt13Encryption();
282 }
283 #endif
284 
285 
286 
287 
SetUnpackToMemory(byte * Addr,uint Size)288 void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size)
289 {
290   UnpackToMemory=true;
291   UnpackToMemoryAddr=Addr;
292   UnpackToMemorySize=Size;
293 }
294 
295 
296