rdwrfn.cpp 6.6 KB

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