Merge pull request #4324 from FernetMenta/wasapi
[vuplus_xbmc] / lib / UnrarXLib / rdwrfn.cpp
1 #include "rar.hpp"
2 #include "URL.h"
3 #include "dialogs/GUIDialogProgress.h"
4
5 ComprDataIO::ComprDataIO()
6 {
7   Init();
8 }
9
10
11 void ComprDataIO::Init()
12 {
13   UnpackFromMemory=false;
14   UnpackToMemory=false;
15   UnpackToMemorySize=-1;
16   UnpPackedSize=0;
17   ShowProgress=true;
18   TestMode=false;
19   SkipUnpCRC=true;
20   PackVolume=false;
21   UnpVolume=false;
22   NextVolumeMissing=false;
23   SrcFile=NULL;
24   DestFile=NULL;
25   UnpWrSize=0;
26   Command=NULL;
27   Encryption=0;
28   Decryption=0;
29   TotalPackRead=0;
30   CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=CurUnpStart=0;
31   PackFileCRC=UnpFileCRC=PackedCRC=0xffffffff;
32   LastPercent=-1;
33   SubHead=NULL;
34   SubHeadPos=NULL;
35   CurrentCommand=0;
36   ProcessedArcSize=TotalArcSize=0;
37   bQuit = false;
38   m_pDlgProgress = NULL;
39  }
40
41 int ComprDataIO::UnpRead(byte *Addr,uint Count)
42 {
43   int RetCode=0,TotalRead=0;
44   byte *ReadAddr;
45   ReadAddr=Addr;
46   while (Count > 0)
47   {
48     Archive *SrcArc=(Archive *)SrcFile;
49
50     uint ReadSize=(Count>UnpPackedSize) ? int64to32(UnpPackedSize):Count;
51     if (UnpackFromMemory)
52     {
53       memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize);
54       RetCode=UnpackFromMemorySize;
55       UnpackFromMemorySize=0;
56     }
57     else
58     {
59       bool bRead = true;
60       if (!SrcFile->IsOpened())
61       {
62         NextVolumeMissing = true;
63         return(-1);
64       }
65       if (UnpackToMemory)
66         if (hSeek->WaitMSec(1)) // we are seeking
67         {
68           if (m_iSeekTo > CurUnpStart+SrcArc->NewLhd.FullPackSize) // need to seek outside this block
69           {
70             TotalRead += (int)(SrcArc->NextBlockPos-SrcFile->Tell());
71             CurUnpRead=CurUnpStart+SrcArc->NewLhd.FullPackSize;
72             UnpPackedSize=0;
73             RetCode = 0;
74             bRead = false;
75           }
76           else
77           {
78             Int64 iStartOfFile = SrcArc->NextBlockPos-SrcArc->NewLhd.FullPackSize;
79             m_iStartOfBuffer = CurUnpStart;
80             Int64 iSeekTo=m_iSeekTo-CurUnpStart<MAXWINMEMSIZE/2?iStartOfFile:iStartOfFile+m_iSeekTo-CurUnpStart-MAXWINMEMSIZE/2;
81             if (iSeekTo == iStartOfFile) // front
82             {
83               if (CurUnpStart+MAXWINMEMSIZE>SrcArc->NewLhd.FullUnpSize)
84               {
85                 m_iSeekTo=iStartOfFile;
86                 UnpPackedSize = SrcArc->NewLhd.FullPackSize;
87               }
88               else 
89               {
90                 m_iSeekTo=MAXWINMEMSIZE-(m_iSeekTo-CurUnpStart);
91                 UnpPackedSize = SrcArc->NewLhd.FullPackSize - (m_iStartOfBuffer - CurUnpStart);
92               }
93             }
94             else
95             {
96               m_iStartOfBuffer = m_iSeekTo-MAXWINMEMSIZE/2; // front
97               if (m_iSeekTo+MAXWINMEMSIZE/2>SrcArc->NewLhd.FullUnpSize)
98               {
99                 iSeekTo = iStartOfFile+SrcArc->NewLhd.FullPackSize-MAXWINMEMSIZE;
100                 m_iStartOfBuffer = CurUnpStart+SrcArc->NewLhd.FullPackSize-MAXWINMEMSIZE;
101                 m_iSeekTo = MAXWINMEMSIZE-(m_iSeekTo-m_iStartOfBuffer);
102                 UnpPackedSize = MAXWINMEMSIZE;
103               }
104               else 
105               {
106                 m_iSeekTo=MAXWINMEMSIZE/2;
107                 UnpPackedSize = SrcArc->NewLhd.FullPackSize - (m_iStartOfBuffer - CurUnpStart);
108               }  
109             }
110
111             SrcFile->Seek(iSeekTo,SEEK_SET);
112             TotalRead = 0;
113             CurUnpRead = CurUnpStart + iSeekTo - iStartOfFile;
114             CurUnpWrite = SrcFile->Tell() - iStartOfFile + CurUnpStart;
115             
116             hSeek->Reset();
117             hSeekDone->Set();
118           }
119         }
120       if (bRead)
121       {
122         ReadSize=(Count>UnpPackedSize) ? int64to32(UnpPackedSize):Count;
123         RetCode=SrcFile->Read(ReadAddr,ReadSize);
124         FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->NewLhd;
125         if (hd->Flags & LHD_SPLIT_AFTER)
126         {
127           PackedCRC=CRC(PackedCRC,ReadAddr,ReadSize);
128         }
129       }
130     }
131     CurUnpRead+=RetCode;
132     ReadAddr+=RetCode;
133     TotalRead+=RetCode;
134     Count-=RetCode;
135     UnpPackedSize-=RetCode;
136     if (UnpPackedSize == 0 && UnpVolume)
137     {
138 #ifndef NOVOLUME
139       if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
140 #endif
141       {
142         NextVolumeMissing=true;
143         return(-1);
144       }
145       CurUnpStart = CurUnpRead;
146       if (m_pDlgProgress)
147       {
148         CURL url(SrcArc->FileName);
149         m_pDlgProgress->SetLine(0,url.GetWithoutUserDetails()); // update currently extracted rar file
150         m_pDlgProgress->Progress();
151       }
152     }
153     else
154       break;
155   }
156   Archive *SrcArc=(Archive *)SrcFile;
157   if (SrcArc!=NULL)
158     ShowUnpRead(SrcArc->CurBlockPos+CurUnpRead,UnpArcSize);
159   if (RetCode!=-1)
160   {
161     RetCode=TotalRead;
162 #ifndef NOCRYPT
163     if (Decryption)
164     {
165 #ifndef SFX_MODULE
166       if (Decryption<20)
167         Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE);
168       else if (Decryption==20)
169         for (int I=0;I<RetCode;I+=16)
170           Decrypt.DecryptBlock20(&Addr[I]);
171       else
172 #endif
173       {
174         int CryptSize=(RetCode & 0xf)==0 ? RetCode:((RetCode & ~0xf)+16);
175         Decrypt.DecryptBlock(Addr,CryptSize);
176       }
177     }
178 #endif
179   }
180   Wait();
181   return(RetCode);
182 }
183
184 void ComprDataIO::UnpWrite(byte *Addr,uint Count)
185 {
186 #ifdef RARDLL
187   RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
188   if (Cmd->DllOpMode!=RAR_SKIP)
189   {
190     if (Cmd->Callback!=NULL &&
191         Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LONG)Addr,Count)==-1)
192       ErrHandler.Exit(USER_BREAK);
193     if (Cmd->ProcessDataProc!=NULL)
194     {
195 #ifdef _WIN_32
196       _EBX=_ESP;
197 #endif
198       int RetCode=Cmd->ProcessDataProc(Addr,Count);
199 #ifdef _WIN_32
200       _ESP=_EBX;
201 #endif
202       if (RetCode==0)
203         ErrHandler.Exit(USER_BREAK);
204     }
205   }
206 #endif
207   UnpWrAddr=Addr;
208   UnpWrSize=Count;
209   if (UnpackToMemory)
210   {
211     while(UnpackToMemorySize < (int)Count)
212     {
213       hBufferEmpty->Set();
214       while(! hBufferFilled->WaitMSec(1)) 
215         if (hQuit->WaitMSec(1))
216           return;
217     }
218     
219     if (! hSeek->WaitMSec(1)) // we are seeking
220     {
221       memcpy(UnpackToMemoryAddr,Addr,Count);
222       UnpackToMemoryAddr+=Count;
223       UnpackToMemorySize-=Count;
224     }
225     else
226       return;
227   }
228   else
229     if (!TestMode)
230       DestFile->Write(Addr,Count);
231   
232   CurUnpWrite+=Count;
233   if (!SkipUnpCRC)
234   {
235 #ifndef SFX_MODULE
236     if (((Archive *)SrcFile)->OldFormat)
237       UnpFileCRC=OldCRC((ushort)UnpFileCRC,Addr,Count);
238     else
239 #endif
240       UnpFileCRC=CRC(UnpFileCRC,Addr,Count);
241   }
242   ShowUnpWrite();
243   Wait();
244   if (m_pDlgProgress)
245   {
246     m_pDlgProgress->ShowProgressBar(true);
247     m_pDlgProgress->SetPercentage(int(float(CurUnpWrite)/float(((Archive*)SrcFile)->NewLhd.FullUnpSize)*100));
248     m_pDlgProgress->Progress();
249     if (m_pDlgProgress->IsCanceled()) 
250       bQuit = true;
251   }
252 }
253
254
255
256
257
258
259 void ComprDataIO::ShowUnpRead(Int64 ArcPos,Int64 ArcSize)
260 {
261   if (ShowProgress && SrcFile!=NULL)
262   {
263     Archive *SrcArc=(Archive *)SrcFile;
264     RAROptions *Cmd=SrcArc->GetRAROptions();
265     if (TotalArcSize!=0)
266       ArcSize=TotalArcSize;
267     ArcPos+=ProcessedArcSize;
268     if (!SrcArc->Volume)
269     {
270       int CurPercent=ToPercent(ArcPos,ArcSize);
271       if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
272       {
273         mprintf("\b\b\b\b%3d%%",CurPercent);
274         LastPercent=CurPercent;
275       }
276     }
277   }
278 }
279
280
281 void ComprDataIO::ShowUnpWrite()
282 {
283 }
284
285
286
287
288
289
290
291
292 void ComprDataIO::SetFiles(File *SrcFile,File *DestFile)
293 {
294   if (SrcFile!=NULL)
295     ComprDataIO::SrcFile=SrcFile;
296   if (DestFile!=NULL)
297     ComprDataIO::DestFile=DestFile;
298   LastPercent=-1;
299 }
300
301
302 void ComprDataIO::GetUnpackedData(byte **Data,uint *Size)
303 {
304   *Data=UnpWrAddr;
305   *Size=UnpWrSize;
306 }
307
308
309 void ComprDataIO::SetEncryption(int Method,char *Password,byte *Salt,bool Encrypt)
310 {
311   if (Encrypt)
312   {
313     Encryption=*Password ? Method:0;
314 #ifndef NOCRYPT
315     Crypt.SetCryptKeys(Password,Salt,Encrypt);
316 #endif
317   }
318   else
319   {
320     Decryption=*Password ? Method:0;
321 #ifndef NOCRYPT
322     Decrypt.SetCryptKeys(Password,Salt,Encrypt,Method<29);
323 #endif
324   }
325 }
326
327
328 #ifndef SFX_MODULE
329 void ComprDataIO::SetAV15Encryption()
330 {
331   Decryption=15;
332   Decrypt.SetAV15Encryption();
333 }
334 #endif
335
336
337 #ifndef SFX_MODULE
338 void ComprDataIO::SetCmt13Encryption()
339 {
340   Decryption=13;
341   Decrypt.SetCmt13Encryption();
342 }
343 #endif
344
345
346
347
348 void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size)
349 {
350   UnpackToMemory=true;
351   UnpackToMemoryAddr=Addr;
352   UnpackToMemorySize=Size;
353 }