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)  

arcread.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
4{
5 // Once we failed to decrypt an encrypted block, there is no reason to
6 // attempt to do it further. We'll never be successful and only generate
7 // endless errors.
9 return 0;
10
12
13 // Other developers asked us to initialize it to suppress "may be used
14 // uninitialized" warning in code below in some compilers.
15 size_t ReadSize=0;
16
17 switch(Format)
18 {
19#ifndef SFX_MODULE
20 case RARFMT14:
21 ReadSize=ReadHeader14();
22 break;
23#endif
24 case RARFMT15:
25 ReadSize=ReadHeader15();
26 break;
27 case RARFMT50:
28 ReadSize=ReadHeader50();
29 break;
30 }
31
32 // It is important to check ReadSize>0 here, because it is normal
33 // for RAR2 and RAR3 archives without end of archive block to have
34 // NextBlockPos==CurBlockPos after the end of archive has reached.
35 if (ReadSize>0 && NextBlockPos<=CurBlockPos)
36 {
38 ReadSize=0;
39 }
40
41 if (ReadSize==0)
43
44 return ReadSize;
45}
46
47
49{
50 size_t Size,Count=0;
51 while ((Size=ReadHeader())!=0 &&
52 (HeaderType==HEAD_ENDARC || GetHeaderType()!=HEAD_ENDARC))
53 {
54 if ((++Count & 127)==0)
55 Wait();
56 if (GetHeaderType()==HeaderType)
57 return Size;
58 SeekToNext();
59 }
60 return 0;
61}
62
63
64size_t Archive::SearchSubBlock(const wchar *Type)
65{
66 size_t Size,Count=0;
67 while ((Size=ReadHeader())!=0 && GetHeaderType()!=HEAD_ENDARC)
68 {
69 if ((++Count & 127)==0)
70 Wait();
72 return Size;
73 SeekToNext();
74 }
75 return 0;
76}
77
78
80{
81 // If locator extra field is available for recovery record, let's utilize it.
83 {
84 uint64 CurPos=Tell();
85 Seek(MainHead.RROffset,SEEK_SET);
86 size_t Size=ReadHeader();
88 return Size;
89 Seek(CurPos,SEEK_SET);
90 }
91 // Otherwise scan the entire archive to find the recovery record.
93}
94
95
97{
98 int64 ArcSize=FileLength();
99
100 // If block positions are equal to file size, this is not an error.
101 // It can happen when we reached the end of older RAR 1.5 archive,
102 // which did not have the end of archive block.
103 if (CurBlockPos!=ArcSize || NextBlockPos!=ArcSize)
104 {
107 }
108}
109
110
112{
114 BrokenHeader=true;
116}
117
118
119void Archive::UnkEncVerMsg(const wchar *Name,const wchar *Info)
120{
123}
124
125
126// Return f in case of signed integer overflow or negative parameters
127// or v1+v2 otherwise. We use it for file offsets, which are signed
128// for compatibility with off_t in POSIX file functions and third party code.
129// Signed integer overflow is the undefined behavior according to
130// C++ standard and it causes fuzzers to complain.
132{
133 return v1>=0 && v2>=0 && v1<=MAX_INT64-v2 ? v1+v2 : f;
134}
135
136
138{
139 RawRead Raw(this);
140
142
143 if (Decrypt)
144 {
145#ifdef RAR_NOCRYPT // For rarext.dll and unrar_nocrypt.dll.
146 return 0;
147#else
149
150 byte Salt[SIZE_SALT30];
151 if (Read(Salt,SIZE_SALT30)!=SIZE_SALT30)
152 {
154 return 0;
155 }
156 HeadersCrypt.SetCryptKeys(false,CRYPT_RAR30,&Cmd->Password,Salt,NULL,0,NULL,NULL);
158#endif
159 }
160
162 if (Raw.Size()==0)
163 {
165 return 0;
166 }
167
168 ShortBlock.HeadCRC=Raw.Get2();
169
171
172 uint HeaderType=Raw.Get1();
173 ShortBlock.Flags=Raw.Get2();
176
179 {
181 return 0;
182 }
183
184 // For simpler further processing we map header types common
185 // for RAR 1.5 and 5.0 formats to RAR 5.0 values. It does not include
186 // header types specific for RAR 1.5 - 4.x only.
187 switch(ShortBlock.HeaderType)
188 {
193 }
195
197 {
198 // Old style (up to RAR 2.9) comment header embedded into main
199 // or file header. We must not read the entire ShortBlock.HeadSize here
200 // to not break the comment processing logic later.
202 }
203 else
205 {
206 // Old style (up to RAR 2.9) main archive comment embedded into
207 // the main archive header found. While we can read the entire
208 // ShortBlock.HeadSize here and remove this part of "if", it would be
209 // waste of memory, because we'll read and process this comment data
210 // in other function anyway and we do not need them here now.
212 }
213 else
215
217
218 switch(ShortBlock.HeaderType)
219 {
220 case HEAD_MAIN:
221 MainHead.Reset();
223 MainHead.HighPosAV=Raw.Get2();
224 MainHead.PosAV=Raw.Get4();
225
233
234 // Only for encrypted 3.0+ archives. 2.x archives did not have this
235 // flag, so for non-encrypted archives, we'll set it later based on
236 // file attributes.
238
240 break;
241 case HEAD_FILE:
242 case HEAD_SERVICE:
243 {
244 bool FileBlock=ShortBlock.HeaderType==HEAD_FILE;
245 FileHeader *hd=FileBlock ? &FileHead:&SubHead;
246 hd->Reset();
247
248 *(BaseBlock *)hd=ShortBlock;
249
250 hd->SplitBefore=(hd->Flags & LHD_SPLIT_BEFORE)!=0;
251 hd->SplitAfter=(hd->Flags & LHD_SPLIT_AFTER)!=0;
252 hd->Encrypted=(hd->Flags & LHD_PASSWORD)!=0;
253 hd->SaltSet=(hd->Flags & LHD_SALT)!=0;
254 hd->Solid=FileBlock && (hd->Flags & LHD_SOLID)!=0;
255 hd->SubBlock=!FileBlock && (hd->Flags & LHD_SOLID)!=0;
257 hd->WinSize=hd->Dir ? 0:0x10000<<((hd->Flags & LHD_WINDOWMASK)>>5);
258 hd->CommentInHeader=(hd->Flags & LHD_COMMENT)!=0;
259 hd->Version=(hd->Flags & LHD_VERSION)!=0;
260
261 hd->DataSize=Raw.Get4();
262 uint LowUnpSize=Raw.Get4();
263 hd->HostOS=Raw.Get1();
264
266 hd->FileHash.CRC32=Raw.Get4();
267
268 uint FileTime=Raw.Get4();
269 hd->UnpVer=Raw.Get1();
270
271 hd->Method=Raw.Get1()-0x30;
272 size_t NameSize=Raw.Get2();
273 hd->FileAttr=Raw.Get4();
274
275 // RAR15 did not use the special dictionary size to mark dirs.
276 if (hd->UnpVer<20 && (hd->FileAttr & 0x10)!=0)
277 hd->Dir=true;
278
280 if (hd->Encrypted)
281 switch(hd->UnpVer)
282 {
283 case 13: hd->CryptMethod=CRYPT_RAR13; break;
284 case 15: hd->CryptMethod=CRYPT_RAR15; break;
285 case 20:
286 case 26: hd->CryptMethod=CRYPT_RAR20; break;
287 default: hd->CryptMethod=CRYPT_RAR30; break;
288 }
289
291 if (hd->HostOS==HOST_UNIX || hd->HostOS==HOST_BEOS)
292 hd->HSType=HSYS_UNIX;
293 else
294 if (hd->HostOS<HOST_MAX)
296
298
299 // RAR 4.x Unix symlink.
300 if (hd->HostOS==HOST_UNIX && (hd->FileAttr & 0xF000)==0xA000)
301 {
303 *hd->RedirName=0;
304 }
305
306 hd->Inherited=!FileBlock && (hd->SubFlags & SUBHEAD_FLAGS_INHERITED)!=0;
307
308 hd->LargeFile=(hd->Flags & LHD_LARGE)!=0;
309
310 uint HighPackSize,HighUnpSize;
311 if (hd->LargeFile)
312 {
313 HighPackSize=Raw.Get4();
314 HighUnpSize=Raw.Get4();
315 hd->UnknownUnpSize=(LowUnpSize==0xffffffff && HighUnpSize==0xffffffff);
316 }
317 else
318 {
319 HighPackSize=HighUnpSize=0;
320 // UnpSize equal to 0xffffffff without LHD_LARGE flag indicates
321 // that we do not know the unpacked file size and must unpack it
322 // until we find the end of file marker in compressed data.
323 hd->UnknownUnpSize=(LowUnpSize==0xffffffff);
324 }
325 hd->PackSize=INT32TO64(HighPackSize,hd->DataSize);
326 hd->UnpSize=INT32TO64(HighUnpSize,LowUnpSize);
327 if (hd->UnknownUnpSize)
328 hd->UnpSize=INT64NDF;
329
330 char FileName[NM*4];
331 size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1);
332 Raw.GetB((byte *)FileName,ReadNameSize);
333 FileName[ReadNameSize]=0;
334
335 if (FileBlock)
336 {
337 *hd->FileName=0;
338 if ((hd->Flags & LHD_UNICODE)!=0)
339 {
340 EncodeFileName NameCoder;
341 size_t Length=strlen(FileName);
342 Length++;
343 if (ReadNameSize>Length)
344 NameCoder.Decode(FileName,ReadNameSize,(byte *)FileName+Length,
345 ReadNameSize-Length,hd->FileName,
346 ASIZE(hd->FileName));
347 }
348
349 if (*hd->FileName==0)
351
352#ifndef SFX_MODULE
354#endif
356 }
357 else
358 {
360
361 // Calculate the size of optional data.
362 int DataSize=int(hd->HeadSize-NameSize-SIZEOF_FILEHEAD3);
363 if ((hd->Flags & LHD_SALT)!=0)
364 DataSize-=SIZE_SALT30;
365
366 if (DataSize>0)
367 {
368 // Here we read optional additional fields for subheaders.
369 // They are stored after the file name and before salt.
370 hd->SubData.Alloc(DataSize);
371 Raw.GetB(&hd->SubData[0],DataSize);
372
373 }
374
375 if (hd->CmpName(SUBHEAD_TYPE_CMT))
376 MainComment=true;
377 }
378 if ((hd->Flags & LHD_SALT)!=0)
379 Raw.GetB(hd->Salt,SIZE_SALT30);
380 hd->mtime.SetDos(FileTime);
381 if ((hd->Flags & LHD_EXTTIME)!=0)
382 {
383 ushort Flags=Raw.Get2();
384 RarTime *tbl[4];
385 tbl[0]=&FileHead.mtime;
386 tbl[1]=&FileHead.ctime;
387 tbl[2]=&FileHead.atime;
388 tbl[3]=NULL; // Archive time is not used now.
389 for (int I=0;I<4;I++)
390 {
391 RarTime *CurTime=tbl[I];
392 uint rmode=Flags>>(3-I)*4;
393 if ((rmode & 8)==0 || CurTime==NULL)
394 continue;
395 if (I!=0)
396 {
397 uint DosTime=Raw.Get4();
398 CurTime->SetDos(DosTime);
399 }
400 RarLocalTime rlt;
401 CurTime->GetLocal(&rlt);
402 if (rmode & 4)
403 rlt.Second++;
404 rlt.Reminder=0;
405 uint count=rmode&3;
406 for (uint J=0;J<count;J++)
407 {
408 byte CurByte=Raw.Get1();
409 rlt.Reminder|=(((uint)CurByte)<<((J+3-count)*8));
410 }
411 // Convert from 100ns RAR precision to REMINDER_PRECISION.
413 CurTime->SetLocal(&rlt);
414 }
415 }
416 // Set to 0 in case of overflow, so end of ReadHeader cares about it.
418
419 bool CRCProcessedOnly=hd->CommentInHeader;
420 ushort HeaderCRC=Raw.GetCRC15(CRCProcessedOnly);
421 if (hd->HeadCRC!=HeaderCRC)
422 {
423 BrokenHeader=true;
425
426 // If we have a broken encrypted header, we do not need to display
427 // the error message here, because it will be displayed for such
428 // headers later in this function. Also such headers are unlikely
429 // to have anything sensible in file name field, so it is useless
430 // to display the file name.
431 if (!Decrypt)
433 }
434 }
435 break;
436 case HEAD_ENDARC:
446 break;
447#ifndef SFX_MODULE
448 case HEAD3_CMT:
450 CommHead.UnpSize=Raw.Get2();
451 CommHead.UnpVer=Raw.Get1();
452 CommHead.Method=Raw.Get1();
453 CommHead.CommCRC=Raw.Get2();
454 break;
455 case HEAD3_PROTECT:
461 Raw.GetB(ProtectHead.Mark,8);
463 break;
464 case HEAD3_OLDSERVICE: // RAR 2.9 and earlier.
469 SubBlockHead.Level=Raw.Get1();
470 switch(SubBlockHead.SubType)
471 {
472 case UO_HEAD:
484 break;
485 case NTACL_HEAD:
487 EAHead.UnpSize=Raw.Get4();
488 EAHead.UnpVer=Raw.Get1();
489 EAHead.Method=Raw.Get1();
490 EAHead.EACRC=Raw.Get4();
491 break;
492 case STREAM_HEAD:
494 StreamHead.UnpSize=Raw.Get4();
495 StreamHead.UnpVer=Raw.Get1();
496 StreamHead.Method=Raw.Get1();
503 break;
504 }
505 break;
506#endif
507 default:
509 NextBlockPos+=Raw.Get4();
510 break;
511 }
512
513 ushort HeaderCRC=Raw.GetCRC15(false);
514
515 // Old AV header does not have header CRC properly set.
518 {
519 bool Recovered=false;
521 {
522 // Last 7 bytes of recovered volume can contain zeroes, because
523 // REV files store its own information (volume number, etc.) here.
524 int64 Length=Tell();
525 Seek(Length-7,SEEK_SET);
526 Recovered=true;
527 for (int J=0;J<7;J++)
528 if (GetByte()!=0)
529 Recovered=false;
530 }
531 if (!Recovered)
532 {
533 BrokenHeader=true;
535
536 if (Decrypt)
537 {
540 return 0;
541 }
542 }
543 }
544
545 return Raw.Size();
546}
547
548
550{
551 RawRead Raw(this);
552
554
555 if (Decrypt)
556 {
557#if defined(RAR_NOCRYPT)
558 return 0;
559#else
560
561 if (Cmd->SkipEncrypted)
562 {
564 FailedHeaderDecryption=true; // Suppress error messages and quit quietly.
565 return 0;
566 }
567
568 byte HeadersInitV[SIZE_INITV];
569 if (Read(HeadersInitV,SIZE_INITV)!=SIZE_INITV)
570 {
572 return 0;
573 }
574
575 // We repeat the password request only for manually entered passwords
576 // and not for -p<pwd>. Wrong password can be intentionally provided
577 // in -p<pwd> to not stop batch processing for encrypted archives.
578 bool GlobalPassword=Cmd->Password.IsSet() || uiIsGlobalPasswordSet();
579
580 while (true) // Repeat the password prompt for wrong passwords.
581 {
583
584 byte PswCheck[SIZE_PSWCHECK];
586 // Verify password validity.
587 if (CryptHead.UsePswCheck && memcmp(PswCheck,CryptHead.PswCheck,SIZE_PSWCHECK)!=0)
588 {
589 if (GlobalPassword) // For -p<pwd> or Ctrl+P.
590 {
591 // This message is used by Android GUI to reset cached passwords.
592 // Update appropriate code if changed.
596 return 0;
597 }
598 else // For passwords entered manually.
599 {
600 // This message is used by Android GUI and Windows GUI and SFX to
601 // reset cached passwords. Update appropriate code if changed.
603 Cmd->Password.Clean();
604 }
605
606#ifdef RARDLL
607 // Avoid new requests for unrar.dll to prevent the infinite loop
608 // if app always returns the same password.
610 Cmd->DllError=ERAR_BAD_PASSWORD;
612#else
613 continue; // Request a password again.
614#endif
615 }
616 break;
617 }
618
620#endif
621 }
622
623 // Header size must not occupy more than 3 variable length integer bytes
624 // resulting in 2 MB maximum header size (MAX_HEADER_SIZE_RAR5),
625 // so here we read 4 byte CRC32 followed by 3 bytes or less of header size.
626 const size_t FirstReadSize=7; // Smallest possible block size.
627 if (Raw.Read(FirstReadSize)<FirstReadSize)
628 {
630 return 0;
631 }
632
634 ShortBlock.HeadCRC=Raw.Get4();
635 uint SizeBytes=Raw.GetVSize(4);
636 uint64 BlockSize=Raw.GetV();
637
638 if (BlockSize==0 || SizeBytes==0)
639 {
641 return 0;
642 }
643
644 int SizeToRead=int(BlockSize);
645 SizeToRead-=FirstReadSize-SizeBytes-4; // Adjust overread size bytes if any.
646 uint HeaderSize=4+SizeBytes+(uint)BlockSize;
647
648 if (SizeToRead<0 || HeaderSize<SIZEOF_SHORTBLOCKHEAD5)
649 {
651 return 0;
652 }
653
654 Raw.Read(SizeToRead);
655
656 if (Raw.Size()<HeaderSize)
657 {
659 return 0;
660 }
661
662 uint HeaderCRC=Raw.GetCRC50();
663
665 ShortBlock.Flags=(uint)Raw.GetV();
667 ShortBlock.HeadSize=HeaderSize;
668
670
671 bool BadCRC=(ShortBlock.HeadCRC!=HeaderCRC);
672 if (BadCRC)
673 {
674 BrokenHeaderMsg(); // Report, but attempt to process.
675
676 BrokenHeader=true;
678
679 if (Decrypt)
680 {
683 return 0;
684 }
685 }
686
687 uint64 ExtraSize=0;
688 if ((ShortBlock.Flags & HFL_EXTRA)!=0)
689 {
690 ExtraSize=Raw.GetV();
691 if (ExtraSize>=ShortBlock.HeadSize)
692 {
694 return 0;
695 }
696 }
697
698 uint64 DataSize=0;
699 if ((ShortBlock.Flags & HFL_DATA)!=0)
700 DataSize=Raw.GetV();
701
703 // Set to 0 in case of overflow, so end of ReadHeader cares about it.
705
706 switch(ShortBlock.HeaderType)
707 {
708 case HEAD_CRYPT:
709 {
711 uint CryptVersion=(uint)Raw.GetV();
712 if (CryptVersion>CRYPT_VERSION)
713 {
714 wchar Info[20];
715 swprintf(Info,ASIZE(Info),L"h%u",CryptVersion);
717 return 0;
718 }
719 uint EncFlags=(uint)Raw.GetV();
721 CryptHead.Lg2Count=Raw.Get1();
723 {
724 wchar Info[20];
725 swprintf(Info,ASIZE(Info),L"hc%u",CryptHead.Lg2Count);
727 return 0;
728 }
729
732 {
734
735 byte csum[SIZE_PSWCHECK_CSUM];
736 Raw.GetB(csum,SIZE_PSWCHECK_CSUM);
737
738 sha256_context ctx;
739 sha256_init(&ctx);
741
742 byte Digest[SHA256_DIGEST_SIZE];
743 sha256_done(&ctx, Digest);
744
745 CryptHead.UsePswCheck=memcmp(csum,Digest,SIZE_PSWCHECK_CSUM)==0;
746 }
747 Encrypted=true;
748 }
749 break;
750 case HEAD_MAIN:
751 {
752 MainHead.Reset();
754 uint ArcFlags=(uint)Raw.GetV();
755
756 Volume=(ArcFlags & MHFL_VOLUME)!=0;
757 Solid=(ArcFlags & MHFL_SOLID)!=0;
758 Locked=(ArcFlags & MHFL_LOCK)!=0;
759 Protected=(ArcFlags & MHFL_PROTECT)!=0;
760 Signed=false;
761 NewNumbering=true;
762
763 if ((ArcFlags & MHFL_VOLNUMBER)!=0)
764 VolNumber=(uint)Raw.GetV();
765 else
766 VolNumber=0;
768
769 if (ExtraSize!=0)
770 ProcessExtra50(&Raw,(size_t)ExtraSize,&MainHead);
771
772#ifdef USE_QOPEN
773 if (!ProhibitQOpen && MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
774 {
775 // We seek to QO block in the end of archive when processing
776 // QOpen.Load, so we need to preserve current block positions
777 // to not break normal archive processing by calling function.
778 int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
779 HEADER_TYPE SaveCurHeaderType=CurHeaderType;
780
781 QOpen.Init(this,false);
782 QOpen.Load(MainHead.QOpenOffset);
783
784 CurBlockPos=SaveCurBlockPos;
785 NextBlockPos=SaveNextBlockPos;
786 CurHeaderType=SaveCurHeaderType;
787 }
788#endif
789 }
790 break;
791 case HEAD_FILE:
792 case HEAD_SERVICE:
793 {
795 hd->Reset(); // Clear hash, time fields and other stuff like flags.
796 *(BaseBlock *)hd=ShortBlock;
797
798 bool FileBlock=ShortBlock.HeaderType==HEAD_FILE;
799
800 hd->LargeFile=true;
801
802 hd->PackSize=DataSize;
803 hd->FileFlags=(uint)Raw.GetV();
804 hd->UnpSize=Raw.GetV();
805
807 if (hd->UnknownUnpSize)
808 hd->UnpSize=INT64NDF;
809
810 hd->MaxSize=Max(hd->PackSize,hd->UnpSize);
811 hd->FileAttr=(uint)Raw.GetV();
812 if ((hd->FileFlags & FHFL_UTIME)!=0)
813 hd->mtime.SetUnix((time_t)Raw.Get4());
814
816 if ((hd->FileFlags & FHFL_CRC32)!=0)
817 {
819 hd->FileHash.CRC32=Raw.Get4();
820 }
821
823
824 uint CompInfo=(uint)Raw.GetV();
825 hd->Method=(CompInfo>>7) & 7;
826
827 // "+ 50" to not mix with old RAR format algorithms. For example,
828 // we may need to use the compression algorithm 15 in the future,
829 // but it was already used in RAR 1.5 and Unpack needs to distinguish
830 // them.
831 hd->UnpVer=(CompInfo & 0x3f) + 50;
832 if (hd->UnpVer!=50) // Only 5.0 compression is known now.
834
835 hd->HostOS=(byte)Raw.GetV();
836 size_t NameSize=(size_t)Raw.GetV();
838
840 if (hd->HostOS==HOST5_UNIX)
841 hd->HSType=HSYS_UNIX;
842 else
843 if (hd->HostOS==HOST5_WINDOWS)
845
846 hd->SplitBefore=(hd->Flags & HFL_SPLITBEFORE)!=0;
847 hd->SplitAfter=(hd->Flags & HFL_SPLITAFTER)!=0;
848 hd->SubBlock=(hd->Flags & HFL_CHILD)!=0;
849 hd->Solid=FileBlock && (CompInfo & FCI_SOLID)!=0;
850 hd->Dir=(hd->FileFlags & FHFL_DIRECTORY)!=0;
851 hd->WinSize=hd->Dir ? 0:size_t(0x20000)<<((CompInfo>>10)&0xf);
852
854
855 char FileName[NM*4];
856 size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1);
857 Raw.GetB((byte *)FileName,ReadNameSize);
858 FileName[ReadNameSize]=0;
859
861
862 // Should do it before converting names, because extra fields can
863 // affect name processing, like in case of NTFS streams.
864 if (ExtraSize!=0)
865 ProcessExtra50(&Raw,(size_t)ExtraSize,hd);
866
867 if (FileBlock)
868 {
869#ifndef SFX_MODULE
871#endif
873 }
874
875 if (!FileBlock && hd->CmpName(SUBHEAD_TYPE_CMT))
876 MainComment=true;
877
878#if 0
879 // For RAR5 format we read the user specified recovery percent here.
880 // It would be useful to do it for shell extension too, so we display
881 // the correct recovery record size in archive properties. But then
882 // we would need to include the entire recovery record processing
883 // code to shell extension, which is not done now.
884 if (!FileBlock && hd->CmpName(SUBHEAD_TYPE_RR) && hd->SubData.Size()>0)
885 {
886 // It is stored as a single byte up to RAR 6.02 and as vint since
887 // 6.10, where we extended the maximum RR size from 99% to 1000%.
888 RawRead RawPercent;
889 RawPercent.Read(&hd->SubData[0],hd->SubData.Size());
890 RecoveryPercent=(int)RawPercent.GetV();
891
892 RSBlockHeader Header;
893 GetRRInfo(this,&Header);
894 RecoverySize=Header.RecSectionSize*Header.RecCount;
895 }
896#endif
897
898 if (BadCRC) // Add the file name to broken header message displayed above.
900 }
901 break;
902 case HEAD_ENDARC:
903 {
905 uint ArcFlags=(uint)Raw.GetV();
906 EndArcHead.NextVolume=(ArcFlags & EHFL_NEXTVOLUME)!=0;
908 EndArcHead.DataCRC=false;
909 EndArcHead.RevSpace=false;
910 }
911 break;
912 }
913
914 return Raw.Size();
915}
916
917
918#if !defined(RAR_NOCRYPT)
920{
921 if (!Cmd->Password.IsSet())
922 {
923#ifdef RARDLL
924 if (Cmd->Callback!=NULL)
925 {
926 wchar PasswordW[MAXPASSWORD];
927 *PasswordW=0;
928 if (Cmd->Callback(UCM_NEEDPASSWORDW,Cmd->UserData,(LPARAM)PasswordW,ASIZE(PasswordW))==-1)
929 *PasswordW=0;
930 if (*PasswordW==0)
931 {
932 char PasswordA[MAXPASSWORD];
933 *PasswordA=0;
934 if (Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)PasswordA,ASIZE(PasswordA))==-1)
935 *PasswordA=0;
936 GetWideName(PasswordA,NULL,PasswordW,ASIZE(PasswordW));
937 cleandata(PasswordA,sizeof(PasswordA));
938 }
939 Cmd->Password.Set(PasswordW);
940 cleandata(PasswordW,sizeof(PasswordW));
941 }
942 if (!Cmd->Password.IsSet())
943 {
944 Close();
945 Cmd->DllError=ERAR_MISSING_PASSWORD;
947 }
948#else
950 {
951 Close();
952 uiMsg(UIERROR_INCERRCOUNT); // Prevent archive deleting if delete after extraction is on.
954 }
955#endif
956 Cmd->ManualPassword=true;
957 }
958}
959#endif
960
961
962void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
963{
964 // Read extra data from the end of block skipping any fields before it.
965 size_t ExtraStart=Raw->Size()-ExtraSize;
966 if (ExtraStart<Raw->GetPos())
967 return;
968 Raw->SetPos(ExtraStart);
969 while (Raw->DataLeft()>=2)
970 {
971 int64 FieldSize=Raw->GetV(); // Needs to be signed for check below and can be negative.
972 if (FieldSize<=0 || Raw->DataLeft()==0 || FieldSize>(int64)Raw->DataLeft())
973 break;
974 size_t NextPos=size_t(Raw->GetPos()+FieldSize);
975 uint64 FieldType=Raw->GetV();
976
977 FieldSize=int64(NextPos-Raw->GetPos()); // Field size without size and type fields.
978
979 if (FieldSize<0) // FieldType is longer than expected extra field size.
980 break;
981
982 if (bb->HeaderType==HEAD_MAIN)
983 {
984 MainHeader *hd=(MainHeader *)bb;
985 if (FieldType==MHEXTRA_LOCATOR)
986 {
987 hd->Locator=true;
988 uint Flags=(uint)Raw->GetV();
989 if ((Flags & MHEXTRA_LOCATOR_QLIST)!=0)
990 {
991 uint64 Offset=Raw->GetV();
992 if (Offset!=0) // 0 means that reserved space was not enough to write the offset.
993 hd->QOpenOffset=Offset+CurBlockPos;
994 }
995 if ((Flags & MHEXTRA_LOCATOR_RR)!=0)
996 {
997 uint64 Offset=Raw->GetV();
998 if (Offset!=0) // 0 means that reserved space was not enough to write the offset.
999 hd->RROffset=Offset+CurBlockPos;
1000 }
1001 }
1002 }
1003
1005 {
1006 FileHeader *hd=(FileHeader *)bb;
1007 switch(FieldType)
1008 {
1009 case FHEXTRA_CRYPT:
1010 {
1011 FileHeader *hd=(FileHeader *)bb;
1012 uint EncVersion=(uint)Raw->GetV();
1013 if (EncVersion>CRYPT_VERSION)
1014 {
1015 wchar Info[20];
1016 swprintf(Info,ASIZE(Info),L"x%u",EncVersion);
1017 UnkEncVerMsg(hd->FileName,Info);
1018 }
1019 else
1020 {
1021 uint Flags=(uint)Raw->GetV();
1022 hd->UsePswCheck=(Flags & FHEXTRA_CRYPT_PSWCHECK)!=0;
1023 hd->UseHashKey=(Flags & FHEXTRA_CRYPT_HASHMAC)!=0;
1024 hd->Lg2Count=Raw->Get1();
1026 {
1027 wchar Info[20];
1028 swprintf(Info,ASIZE(Info),L"xc%u",hd->Lg2Count);
1029 UnkEncVerMsg(hd->FileName,Info);
1030 }
1031 Raw->GetB(hd->Salt,SIZE_SALT50);
1032 Raw->GetB(hd->InitV,SIZE_INITV);
1033 if (hd->UsePswCheck)
1034 {
1035 Raw->GetB(hd->PswCheck,SIZE_PSWCHECK);
1036
1037 // It is important to know if password check data is valid.
1038 // If it is damaged and header CRC32 fails to detect it,
1039 // archiver would refuse to decompress a possibly valid file.
1040 // Since we want to be sure distinguishing a wrong password
1041 // or corrupt file data, we use 64-bit password check data
1042 // and to control its validity we use 32 bits of password
1043 // check data SHA-256 additionally to 32-bit header CRC32.
1044 byte csum[SIZE_PSWCHECK_CSUM];
1045 Raw->GetB(csum,SIZE_PSWCHECK_CSUM);
1046
1047 sha256_context ctx;
1048 sha256_init(&ctx);
1050
1051 byte Digest[SHA256_DIGEST_SIZE];
1052 sha256_done(&ctx, Digest);
1053
1054 hd->UsePswCheck=memcmp(csum,Digest,SIZE_PSWCHECK_CSUM)==0;
1055
1056 // RAR 5.21 and earlier set PswCheck field in service records to 0
1057 // even if UsePswCheck was present.
1058 if (bb->HeaderType==HEAD_SERVICE && memcmp(hd->PswCheck,"\0\0\0\0\0\0\0\0",SIZE_PSWCHECK)==0)
1059 hd->UsePswCheck=0;
1060 }
1061 hd->SaltSet=true;
1063 hd->Encrypted=true;
1064 }
1065 }
1066 break;
1067 case FHEXTRA_HASH:
1068 {
1069 FileHeader *hd=(FileHeader *)bb;
1070 uint Type=(uint)Raw->GetV();
1071 if (Type==FHEXTRA_HASH_BLAKE2)
1072 {
1075 }
1076 }
1077 break;
1078 case FHEXTRA_HTIME:
1079 if (FieldSize>=5)
1080 {
1081 byte Flags=(byte)Raw->GetV();
1082 bool UnixTime=(Flags & FHEXTRA_HTIME_UNIXTIME)!=0;
1083 if ((Flags & FHEXTRA_HTIME_MTIME)!=0)
1084 if (UnixTime)
1085 hd->mtime.SetUnix(Raw->Get4());
1086 else
1087 hd->mtime.SetWin(Raw->Get8());
1088 if ((Flags & FHEXTRA_HTIME_CTIME)!=0)
1089 if (UnixTime)
1090 hd->ctime.SetUnix(Raw->Get4());
1091 else
1092 hd->ctime.SetWin(Raw->Get8());
1093 if ((Flags & FHEXTRA_HTIME_ATIME)!=0)
1094 if (UnixTime)
1095 hd->atime.SetUnix((time_t)Raw->Get4());
1096 else
1097 hd->atime.SetWin(Raw->Get8());
1098 if (UnixTime && (Flags & FHEXTRA_HTIME_UNIX_NS)!=0) // Add nanoseconds.
1099 {
1100 uint ns;
1101 if ((Flags & FHEXTRA_HTIME_MTIME)!=0 && (ns=(Raw->Get4() & 0x3fffffff))<1000000000)
1102 hd->mtime.Adjust(ns);
1103 if ((Flags & FHEXTRA_HTIME_CTIME)!=0 && (ns=(Raw->Get4() & 0x3fffffff))<1000000000)
1104 hd->ctime.Adjust(ns);
1105 if ((Flags & FHEXTRA_HTIME_ATIME)!=0 && (ns=(Raw->Get4() & 0x3fffffff))<1000000000)
1106 hd->atime.Adjust(ns);
1107 }
1108 }
1109 break;
1110 case FHEXTRA_VERSION:
1111 if (FieldSize>=1)
1112 {
1113 Raw->GetV(); // Skip flags field.
1114 uint Version=(uint)Raw->GetV();
1115 if (Version!=0)
1116 {
1117 hd->Version=true;
1118
1119 wchar VerText[20];
1120 swprintf(VerText,ASIZE(VerText),L";%u",Version);
1121 wcsncatz(hd->FileName,VerText,ASIZE(hd->FileName));
1122 }
1123 }
1124 break;
1125 case FHEXTRA_REDIR:
1126 {
1128 uint Flags=(uint)Raw->GetV();
1129 hd->DirTarget=(Flags & FHEXTRA_REDIR_DIR)!=0;
1130 size_t NameSize=(size_t)Raw->GetV();
1131
1132 char UtfName[NM*4];
1133 *UtfName=0;
1134 if (NameSize<ASIZE(UtfName)-1)
1135 {
1136 Raw->GetB(UtfName,NameSize);
1137 UtfName[NameSize]=0;
1138 }
1139#ifdef _WIN_ALL
1140 UnixSlashToDos(UtfName,UtfName,ASIZE(UtfName));
1141#endif
1142 UtfToWide(UtfName,hd->RedirName,ASIZE(hd->RedirName));
1143 }
1144 break;
1145 case FHEXTRA_UOWNER:
1146 {
1147 uint Flags=(uint)Raw->GetV();
1148 hd->UnixOwnerNumeric=(Flags & FHEXTRA_UOWNER_NUMUID)!=0;
1149 hd->UnixGroupNumeric=(Flags & FHEXTRA_UOWNER_NUMGID)!=0;
1150 *hd->UnixOwnerName=*hd->UnixGroupName=0;
1151 if ((Flags & FHEXTRA_UOWNER_UNAME)!=0)
1152 {
1153 size_t Length=(size_t)Raw->GetV();
1154 Length=Min(Length,ASIZE(hd->UnixOwnerName)-1);
1155 Raw->GetB(hd->UnixOwnerName,Length);
1156 hd->UnixOwnerName[Length]=0;
1157 }
1158 if ((Flags & FHEXTRA_UOWNER_GNAME)!=0)
1159 {
1160 size_t Length=(size_t)Raw->GetV();
1161 Length=Min(Length,ASIZE(hd->UnixGroupName)-1);
1162 Raw->GetB(hd->UnixGroupName,Length);
1163 hd->UnixGroupName[Length]=0;
1164 }
1165#ifdef _UNIX
1166 if (hd->UnixOwnerNumeric)
1167 hd->UnixOwnerID=(uid_t)Raw->GetV();
1168 if (hd->UnixGroupNumeric)
1169 hd->UnixGroupID=(gid_t)Raw->GetV();
1170#else
1171 // Need these fields in Windows too for 'list' command,
1172 // but uid_t and gid_t are not defined.
1173 if (hd->UnixOwnerNumeric)
1174 hd->UnixOwnerID=(uint)Raw->GetV();
1175 if (hd->UnixGroupNumeric)
1176 hd->UnixGroupID=(uint)Raw->GetV();
1177#endif
1178 hd->UnixOwnerSet=true;
1179 }
1180 break;
1181 case FHEXTRA_SUBDATA:
1182 {
1183 // RAR 5.21 and earlier set FHEXTRA_SUBDATA size to 1 less than
1184 // required. It did not hurt extraction, because UnRAR 5.21
1185 // and earlier ignored this field and set FieldSize as data left
1186 // in entire extra area. But now we set the correct field size
1187 // and set FieldSize based on the actual extra record size,
1188 // so we need to adjust it for those older archives here.
1189 // FHEXTRA_SUBDATA in those archives always belongs to HEAD_SERVICE
1190 // and always is last in extra area. So since its size is by 1
1191 // less than needed, we always have 1 byte left in extra area,
1192 // which fact we use here to detect such archives.
1193 if (bb->HeaderType==HEAD_SERVICE && Raw->Size()-NextPos==1)
1194 FieldSize++;
1195
1196 // We cannot allocate too much memory here, because above
1197 // we check FieldSize againt Raw size and we control that Raw size
1198 // is sensible when reading headers.
1199 hd->SubData.Alloc((size_t)FieldSize);
1200 Raw->GetB(hd->SubData.Addr(0),(size_t)FieldSize);
1201 }
1202 break;
1203 }
1204 }
1205
1206 Raw->SetPos(NextPos);
1207 }
1208}
1209
1210
1211#ifndef SFX_MODULE
1213{
1214 RawRead Raw(this);
1216 {
1218 MainHead.Reset();
1219 byte Mark[4];
1220 Raw.GetB(Mark,4);
1221 uint HeadSize=Raw.Get2();
1222 if (HeadSize<7)
1223 return false;
1224 byte Flags=Raw.Get1();
1225 NextBlockPos=CurBlockPos+HeadSize;
1227
1228 Volume=(Flags & MHD_VOLUME)!=0;
1229 Solid=(Flags & MHD_SOLID)!=0;
1230 Locked=(Flags & MHD_LOCK)!=0;
1233 }
1234 else
1235 {
1237 FileHead.Reset();
1238
1240 FileHead.DataSize=Raw.Get4();
1241 FileHead.UnpSize=Raw.Get4();
1244 FileHead.HeadSize=Raw.Get2();
1245 if (FileHead.HeadSize<21)
1246 return false;
1247 uint FileTime=Raw.Get4();
1248 FileHead.FileAttr=Raw.Get1();
1250 FileHead.UnpVer=(Raw.Get1()==2) ? 13 : 10;
1251 size_t NameSize=Raw.Get1();
1252 FileHead.Method=Raw.Get1();
1253
1258
1260 FileHead.WinSize=0x10000;
1261 FileHead.Dir=(FileHead.FileAttr & 0x10)!=0;
1262
1265
1266 FileHead.mtime.SetDos(FileTime);
1267
1268 Raw.Read(NameSize);
1269
1270 char FileName[NM];
1271 size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1);
1272 Raw.GetB((byte *)FileName,ReadNameSize);
1273 FileName[ReadNameSize]=0;
1278
1279 if (Raw.Size()!=0)
1282 }
1283 return NextBlockPos>CurBlockPos ? Raw.Size() : 0;
1284}
1285#endif
1286
1287
1288#ifndef SFX_MODULE
1290{
1292 wcsupper(Name);
1294 wcslower(Name);
1295}
1296#endif
1297
1298
1300{
1301 return FileHead.Dir;
1302}
1303
1304
1306{
1307#if defined(_WIN_ALL) || defined(_EMX)
1309 FileHead.FileAttr=FileHead.Dir ? 0x10 : 0x20;
1310#endif
1311#ifdef _UNIX
1312 // umask defines which permission bits must not be set by default
1313 // when creating a file or directory. The typical default value
1314 // for the process umask is S_IWGRP | S_IWOTH (octal 022),
1315 // resulting in 0644 mode for new files.
1316 // Normally umask is applied automatically when creating a file,
1317 // but we set attributes with chmod later, so we need to calculate
1318 // resulting attributes here. We do it only for non-Unix archives.
1319 // We restore native Unix attributes as is, because it can be backup.
1320 static mode_t mask = (mode_t) -1;
1321
1322 if (mask == (mode_t) -1)
1323 {
1324 // umask call returns the current umask value. Argument (022) is not
1325 // really important here.
1326 mask = umask(022);
1327
1328 // Restore the original umask value, which was changed to 022 above.
1329 umask(mask);
1330 }
1331
1332 switch(FileHead.HSType)
1333 {
1334 case HSYS_WINDOWS:
1335 {
1336 // Mapping MSDOS, OS/2 and Windows file attributes to Unix.
1337
1338 if (FileHead.FileAttr & 0x10) // FILE_ATTRIBUTE_DIRECTORY
1339 {
1340 // For directories we use 0777 mask.
1341 FileHead.FileAttr=0777 & ~mask;
1342 }
1343 else
1344 if (FileHead.FileAttr & 1) // FILE_ATTRIBUTE_READONLY
1345 {
1346 // For read only files we use 0444 mask with 'w' bits turned off.
1347 FileHead.FileAttr=0444 & ~mask;
1348 }
1349 else
1350 {
1351 // umask does not set +x for regular files, so we use 0666
1352 // instead of 0777 as for directories.
1353 FileHead.FileAttr=0666 & ~mask;
1354 }
1355 }
1356 break;
1357 case HSYS_UNIX:
1358 break;
1359 default:
1360 if (FileHead.Dir)
1361 FileHead.FileAttr=0x41ff & ~mask;
1362 else
1363 FileHead.FileAttr=0x81b6 & ~mask;
1364 break;
1365 }
1366#endif
1367}
1368
1369
1371{
1372 if (hd->HSType==HSYS_UNKNOWN)
1373 if (hd->Dir)
1374 hd->FileAttr=0x10;
1375 else
1376 hd->FileAttr=0x20;
1377
1378#ifdef _WIN_ALL
1379 if (hd->HSType==HSYS_UNIX) // Convert Unix, OS X and Android decomposed chracters to Windows precomposed.
1380 ConvertToPrecomposed(hd->FileName,ASIZE(hd->FileName));
1381#endif
1382
1383 for (wchar *s=hd->FileName;*s!=0;s++)
1384 {
1385#ifdef _UNIX
1386 // Backslash is the invalid character for Windows file headers,
1387 // but it can present in Unix file names extracted in Unix.
1388 if (*s=='\\' && Format==RARFMT50 && hd->HSType==HSYS_WINDOWS)
1389 *s='_';
1390#endif
1391
1392#if defined(_WIN_ALL) || defined(_EMX)
1393 // RAR 5.0 archives do not use '\' as path separator, so if we see it,
1394 // it means that it is a part of Unix file name, which we cannot
1395 // extract in Windows.
1396 if (*s=='\\' && Format==RARFMT50)
1397 *s='_';
1398
1399 // ':' in file names is allowed in Unix, but not in Windows.
1400 // Even worse, file data will be written to NTFS stream on NTFS,
1401 // so automatic name correction on file create error in extraction
1402 // routine does not work. In Windows and DOS versions we better
1403 // replace ':' now.
1404 if (*s==':')
1405 *s='_';
1406#endif
1407
1408 // This code must be performed only after other path separator checks,
1409 // because it produces backslashes illegal for some of checks above.
1410 // Backslash is allowed in file names in Unix, but not in Windows.
1411 // Still, RAR 4.x uses backslashes as path separator even in Unix.
1412 // Forward slash is not allowed in both systems. In RAR 5.0 we use
1413 // the forward slash as universal path separator.
1414 if (*s=='/' || *s=='\\' && Format!=RARFMT50)
1415 *s=CPATHDIVIDER;
1416 }
1417}
1418
1419
1421{
1422 int64 StartPos=SFXSize+MarkHead.HeadSize;
1423 if (Format==RARFMT15)
1424 StartPos+=MainHead.HeadSize;
1425 else // RAR 5.0.
1427 return StartPos;
1428}
1429
1430
1431bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode)
1432{
1433 if (BrokenHeader)
1434 {
1437 return false;
1438 }
1440 {
1442 return false;
1443 }
1444
1446 return true;
1447
1448 SubDataIO.Init();
1450 Unpack.Init(SubHead.WinSize,false);
1451
1452 if (DestFile==NULL)
1453 {
1454 if (SubHead.UnpSize>0x1000000)
1455 {
1456 // So huge allocation must never happen in valid archives.
1458 return false;
1459 }
1460 if (UnpData==NULL)
1461 SubDataIO.SetTestMode(true);
1462 else
1463 {
1464 UnpData->Alloc((size_t)SubHead.UnpSize);
1466 }
1467 }
1468 if (SubHead.Encrypted)
1469 if (Cmd->Password.IsSet())
1473 else
1474 return false;
1478 SubDataIO.SetFiles(this,DestFile);
1479 SubDataIO.SetTestMode(TestMode);
1483 if (SubHead.Method==0)
1485 else
1487
1489 {
1492 if (UnpData!=NULL)
1493 UnpData->Reset();
1494 return false;
1495 }
1496 return true;
1497}
@ RARFMT50
Definition: archive.hpp:13
@ RARFMT15
Definition: archive.hpp:13
@ RARFMT14
Definition: archive.hpp:13
int64 SafeAdd(int64 v1, int64 v2, int64 f)
Definition: arcread.cpp:131
ErrorHandler ErrHandler
#define BLAKE2_DIGEST_SIZE
Definition: blake2s.hpp:5
ProtectHeader ProtectHead
Definition: archive.hpp:109
RAROptions * Cmd
Definition: archive.hpp:48
int64 GetStartPos()
Definition: arcread.cpp:1420
size_t ReadHeader()
Definition: arcread.cpp:3
bool Signed
Definition: archive.hpp:122
bool Encrypted
Definition: archive.hpp:126
EAHeader EAHead
Definition: archive.hpp:111
bool BrokenHeader
Definition: archive.hpp:128
bool FirstVolume
Definition: archive.hpp:123
bool FailedHeaderDecryption
Definition: archive.hpp:129
ComprDataIO SubDataIO
Definition: archive.hpp:46
HEADER_TYPE GetHeaderType()
Definition: archive.hpp:85
uint VolNumber
Definition: archive.hpp:137
bool Protected
Definition: archive.hpp:125
MarkHeader MarkHead
Definition: archive.hpp:101
void ConvertFileHeader(FileHeader *hd)
Definition: arcread.cpp:1370
EndArcHeader EndArcHead
Definition: archive.hpp:105
bool Locked
Definition: archive.hpp:121
void ConvertNameCase(wchar *Name)
Definition: arcread.cpp:1289
void UnkEncVerMsg(const wchar *Name, const wchar *Info)
Definition: arcread.cpp:119
void SeekToNext()
Definition: archive.cpp:276
bool Solid
Definition: archive.hpp:118
HEADER_TYPE CurHeaderType
Definition: archive.hpp:53
FileHeader FileHead
Definition: archive.hpp:104
bool MainComment
Definition: archive.hpp:120
size_t SearchRR()
Definition: arcread.cpp:79
RARFORMAT Format
Definition: archive.hpp:117
uint FullHeaderSize(size_t Size)
Definition: archive.cpp:287
size_t SearchSubBlock(const wchar *Type)
Definition: arcread.cpp:64
bool IsArcDir()
Definition: arcread.cpp:1299
int64 NextBlockPos
Definition: archive.hpp:115
void ConvertAttributes()
Definition: arcread.cpp:1305
size_t ReadHeader15()
Definition: arcread.cpp:137
size_t SFXSize
Definition: archive.hpp:127
FileHeader SubHead
Definition: archive.hpp:107
size_t ReadHeader50()
Definition: arcread.cpp:549
size_t SearchBlock(HEADER_TYPE HeaderType)
Definition: arcread.cpp:48
CryptData HeadersCrypt
Definition: archive.hpp:44
BaseBlock ShortBlock
Definition: archive.hpp:100
MainHeader MainHead
Definition: archive.hpp:102
SubBlockHeader SubBlockHead
Definition: archive.hpp:106
bool ReadSubData(Array< byte > *UnpData, File *DestFile, bool TestMode)
Definition: arcread.cpp:1431
StreamHeader StreamHead
Definition: archive.hpp:112
void UnexpEndArcMsg()
Definition: arcread.cpp:96
int64 CurBlockPos
Definition: archive.hpp:114
CommentHeader CommHead
Definition: archive.hpp:108
bool NewNumbering
Definition: archive.hpp:124
CryptHeader CryptHead
Definition: archive.hpp:103
void ProcessExtra50(RawRead *Raw, size_t ExtraSize, BaseBlock *bb)
Definition: arcread.cpp:962
size_t ReadHeader14()
Definition: arcread.cpp:1212
void RequestArcPassword()
Definition: arcread.cpp:919
void BrokenHeaderMsg()
Definition: arcread.cpp:111
bool Volume
Definition: archive.hpp:119
UnixOwnersHeader UOHead
Definition: archive.hpp:110
size_t Size()
Definition: array.hpp:94
void Reset()
Definition: array.hpp:148
void Alloc(size_t Items)
Definition: array.hpp:139
T * Addr(size_t Item)
Definition: array.hpp:30
static void UnstoreFile(ComprDataIO &DataIO, int64 DestUnpSize)
Definition: extract.cpp:851
DataHash UnpHash
Definition: rdwrfn.hpp:99
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
void SetPackedSizeToRead(int64 Size)
Definition: rdwrfn.hpp:66
void Init()
Definition: rdwrfn.cpp:14
bool UnpVolume
Definition: rdwrfn.hpp:83
void SetFiles(File *SrcFile, File *DestFile)
Definition: rdwrfn.cpp:232
void EnableShowProgress(bool Show)
Definition: rdwrfn.hpp:64
void SetTestMode(bool Mode)
Definition: rdwrfn.hpp:67
void SetSubHeader(FileHeader *hd, int64 *Pos)
Definition: rdwrfn.hpp:72
void SetUnpackToMemory(byte *Addr, uint Size)
Definition: rdwrfn.cpp:282
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 Init(HASH_TYPE Type, uint MaxThreads)
Definition: hash.cpp:67
bool Cmp(HashValue *CmpValue, byte *Key)
Definition: hash.cpp:128
void Decode(char *Name, size_t NameSize, byte *EncName, size_t EncSize, wchar *NameW, size_t MaxDecSize)
Definition: encname.cpp:14
void SetErrorCode(RAR_EXIT Code)
Definition: errhnd.cpp:243
void Exit(RAR_EXIT ExitCode)
Definition: errhnd.cpp:236
Definition: file.hpp:57
virtual void Seek(int64 Offset, int Method)
Definition: file.cpp:514
int64 FileLength()
Definition: file.cpp:750
virtual int Read(void *Data, size_t Size)
Definition: file.cpp:374
virtual int64 Tell()
Definition: file.cpp:576
byte GetByte()
Definition: file.cpp:626
wchar FileName[NM]
Definition: file.hpp:88
virtual bool Close()
Definition: file.cpp:241
bool ManualPassword
Definition: options.hpp:125
SecPassword Password
Definition: options.hpp:121
bool SkipEncrypted
Definition: options.hpp:123
int ConvertNames
Definition: options.hpp:156
void SetDos(uint DosTime)
Definition: timefn.cpp:211
void GetLocal(RarLocalTime *lt)
Definition: timefn.cpp:3
void SetWin(uint64 WinTime)
Definition: timefn.cpp:158
void SetUnix(time_t ut)
Definition: timefn.cpp:170
void Adjust(int64 ns)
Definition: timefn.cpp:322
static const uint REMINDER_PRECISION
Definition: timefn.hpp:29
void SetLocal(RarLocalTime *lt)
Definition: timefn.cpp:70
uint GetVSize(size_t Pos)
Definition: rawread.cpp:132
void SetPos(size_t Pos)
Definition: rawread.hpp:33
uint64 Get8()
Definition: rawread.cpp:108
uint GetCRC15(bool ProcessedOnly)
Definition: rawread.cpp:166
void SetCrypt(CryptData *Crypt)
Definition: rawread.hpp:36
uint64 GetV()
Definition: rawread.cpp:115
uint Get4()
Definition: rawread.cpp:95
size_t DataLeft()
Definition: rawread.hpp:31
size_t GetPos()
Definition: rawread.hpp:32
uint GetCRC50()
Definition: rawread.cpp:175
ushort Get2()
Definition: rawread.cpp:83
size_t Size()
Definition: rawread.hpp:29
byte Get1()
Definition: rawread.cpp:77
size_t GetB(void *Field, size_t Size)
Definition: rawread.cpp:141
size_t Read(size_t Size)
Definition: rawread.cpp:26
void Set(const wchar *Psw)
void Clean()
Definition: secpassword.cpp:70
bool IsSet()
Definition: secpassword.hpp:22
void Init(size_t WinSize, bool Solid)
Definition: unpack.cpp:73
void DoUnpack(uint Method, bool Solid)
Definition: unpack.cpp:149
void SetDestSize(int64 DestSize)
Definition: unpack.hpp:381
@ CRYPT_RAR13
Definition: crypt.hpp:6
@ CRYPT_RAR20
Definition: crypt.hpp:6
@ CRYPT_RAR15
Definition: crypt.hpp:6
@ CRYPT_RAR50
Definition: crypt.hpp:6
@ CRYPT_NONE
Definition: crypt.hpp:6
@ CRYPT_RAR30
Definition: crypt.hpp:6
#define SIZE_PSWCHECK
Definition: crypt.hpp:12
#define SIZE_PSWCHECK_CSUM
Definition: crypt.hpp:13
#define CRYPT_VERSION
Definition: crypt.hpp:20
#define SIZE_SALT50
Definition: crypt.hpp:9
#define SIZE_SALT30
Definition: crypt.hpp:10
#define SIZE_INITV
Definition: crypt.hpp:11
#define CRYPT5_KDF_LG2_COUNT_MAX
Definition: crypt.hpp:19
@ UCM_NEEDPASSWORDW
Definition: dll.hpp:160
@ UCM_NEEDPASSWORD
Definition: dll.hpp:159
#define ERAR_BAD_PASSWORD
Definition: dll.hpp:21
#define ERAR_MISSING_PASSWORD
Definition: dll.hpp:19
@ RARX_USERBREAK
Definition: errhnd.hpp:19
@ RARX_BADPWD
Definition: errhnd.hpp:17
@ RARX_CRC
Definition: errhnd.hpp:9
@ RARX_WARNING
Definition: errhnd.hpp:7
@ HASH_NONE
Definition: hash.hpp:4
@ HASH_RAR14
Definition: hash.hpp:4
@ HASH_CRC32
Definition: hash.hpp:4
@ HASH_BLAKE2
Definition: hash.hpp:4
#define MHFL_VOLUME
Definition: headers5.hpp:25
#define FHEXTRA_CRYPT_HASHMAC
Definition: headers5.hpp:89
#define FHEXTRA_HASH_BLAKE2
Definition: headers5.hpp:78
#define MHFL_VOLNUMBER
Definition: headers5.hpp:26
#define FHEXTRA_HASH
Definition: headers5.hpp:69
#define FHEXTRA_UOWNER
Definition: headers5.hpp:73
#define FHEXTRA_CRYPT_PSWCHECK
Definition: headers5.hpp:88
#define FHEXTRA_HTIME
Definition: headers5.hpp:70
#define CHFL_CRYPT_PSWCHECK
Definition: headers5.hpp:41
#define FHFL_UNPUNKNOWN
Definition: headers5.hpp:35
#define MHFL_LOCK
Definition: headers5.hpp:29
#define MHFL_SOLID
Definition: headers5.hpp:27
#define FHEXTRA_UOWNER_UNAME
Definition: headers5.hpp:95
#define HFL_INHERITED
Definition: headers5.hpp:22
#define FHEXTRA_VERSION
Definition: headers5.hpp:71
#define FHEXTRA_REDIR_DIR
Definition: headers5.hpp:92
#define FHFL_CRC32
Definition: headers5.hpp:34
#define FHEXTRA_UOWNER_GNAME
Definition: headers5.hpp:96
#define FHEXTRA_UOWNER_NUMUID
Definition: headers5.hpp:97
#define EHFL_NEXTVOLUME
Definition: headers5.hpp:38
#define FHEXTRA_CRYPT
Definition: headers5.hpp:68
#define FHEXTRA_HTIME_UNIXTIME
Definition: headers5.hpp:81
#define FHEXTRA_REDIR
Definition: headers5.hpp:72
#define FHEXTRA_UOWNER_NUMGID
Definition: headers5.hpp:98
#define SIZEOF_SHORTBLOCKHEAD5
Definition: headers5.hpp:5
#define FHEXTRA_HTIME_UNIX_NS
Definition: headers5.hpp:85
#define MHEXTRA_LOCATOR
Definition: headers5.hpp:61
#define HFL_DATA
Definition: headers5.hpp:12
#define HFL_CHILD
Definition: headers5.hpp:20
#define FHFL_UTIME
Definition: headers5.hpp:33
#define HFL_SKIPIFUNKNOWN
Definition: headers5.hpp:14
#define MHEXTRA_LOCATOR_RR
Definition: headers5.hpp:65
#define FCI_SOLID
Definition: headers5.hpp:51
#define HFL_EXTRA
Definition: headers5.hpp:10
#define MHEXTRA_LOCATOR_QLIST
Definition: headers5.hpp:64
#define HFL_SPLITAFTER
Definition: headers5.hpp:18
#define FHEXTRA_HTIME_MTIME
Definition: headers5.hpp:82
#define HFL_SPLITBEFORE
Definition: headers5.hpp:16
#define SIZEOF_MARKHEAD5
Definition: headers5.hpp:4
#define FHFL_DIRECTORY
Definition: headers5.hpp:32
#define MHFL_PROTECT
Definition: headers5.hpp:28
#define FHEXTRA_SUBDATA
Definition: headers5.hpp:74
#define FHEXTRA_HTIME_CTIME
Definition: headers5.hpp:83
#define FHEXTRA_HTIME_ATIME
Definition: headers5.hpp:84
#define EARC_REVSPACE
Definition: headers.hpp:71
#define LHD_LARGE
Definition: headers.hpp:60
#define MHD_COMMENT
Definition: headers.hpp:27
#define MHD_NEWNUMBERING
Definition: headers.hpp:32
#define MHD_VOLUME
Definition: headers.hpp:23
#define SIZEOF_FILEHEAD3
Definition: headers.hpp:8
#define SUBHEAD_TYPE_RR
Definition: headers.hpp:120
#define LHD_EXTTIME
Definition: headers.hpp:64
#define LHD_SPLIT_BEFORE
Definition: headers.hpp:38
#define SUBHEAD_FLAGS_INHERITED
Definition: headers.hpp:124
#define SIZEOF_COMMHEAD
Definition: headers.hpp:12
#define LHD_SALT
Definition: headers.hpp:62
#define MHD_FIRSTVOLUME
Definition: headers.hpp:36
@ HSYS_UNKNOWN
Definition: headers.hpp:103
@ HSYS_UNIX
Definition: headers.hpp:103
@ HSYS_WINDOWS
Definition: headers.hpp:103
#define VER_UNPACK
Definition: headers.hpp:19
#define MHD_PASSWORD
Definition: headers.hpp:35
@ STREAM_HEAD
Definition: headers.hpp:88
@ NTACL_HEAD
Definition: headers.hpp:88
@ UO_HEAD
Definition: headers.hpp:87
#define MHD_PROTECT
Definition: headers.hpp:34
#define LHD_COMMENT
Definition: headers.hpp:44
#define EARC_DATACRC
Definition: headers.hpp:70
#define SIZEOF_MAINHEAD3
Definition: headers.hpp:6
#define SIZEOF_MAINHEAD14
Definition: headers.hpp:5
#define MHD_SOLID
Definition: headers.hpp:30
FILE_SYSTEM_REDIRECT
Definition: headers.hpp:108
@ FSREDIR_NONE
Definition: headers.hpp:109
@ FSREDIR_UNIXSYMLINK
Definition: headers.hpp:109
#define EARC_VOLNUMBER
Definition: headers.hpp:72
#define SIZEOF_SHORTBLOCKHEAD
Definition: headers.hpp:9
#define MHD_LOCK
Definition: headers.hpp:29
#define MHD_PACK_COMMENT
Definition: headers.hpp:31
#define LHD_WINDOWMASK
Definition: headers.hpp:50
#define LHD_VERSION
Definition: headers.hpp:63
#define SIZEOF_FILEHEAD14
Definition: headers.hpp:7
#define EARC_NEXT_VOLUME
Definition: headers.hpp:69
#define LHD_UNICODE
Definition: headers.hpp:61
HEADER_TYPE
Definition: headers.hpp:74
@ HEAD3_FILE
Definition: headers.hpp:80
@ HEAD_FILE
Definition: headers.hpp:76
@ HEAD3_SERVICE
Definition: headers.hpp:82
@ HEAD_UNKNOWN
Definition: headers.hpp:77
@ HEAD_CRYPT
Definition: headers.hpp:77
@ HEAD3_OLDSERVICE
Definition: headers.hpp:81
@ HEAD3_MAIN
Definition: headers.hpp:80
@ HEAD3_SIGN
Definition: headers.hpp:81
@ HEAD_SERVICE
Definition: headers.hpp:76
@ HEAD_MAIN
Definition: headers.hpp:76
@ HEAD3_ENDARC
Definition: headers.hpp:82
@ HEAD3_CMT
Definition: headers.hpp:80
@ HEAD3_AV
Definition: headers.hpp:81
@ HEAD3_PROTECT
Definition: headers.hpp:81
@ HEAD_ENDARC
Definition: headers.hpp:77
#define LONG_BLOCK
Definition: headers.hpp:67
#define LHD_DIRECTORY
Definition: headers.hpp:58
#define LHD_SOLID
Definition: headers.hpp:47
#define SKIP_IF_UNKNOWN
Definition: headers.hpp:66
#define SIZEOF_MARKHEAD3
Definition: headers.hpp:4
#define LHD_SPLIT_AFTER
Definition: headers.hpp:39
#define LHD_PASSWORD
Definition: headers.hpp:40
@ HOST_MSDOS
Definition: headers.hpp:97
@ HOST_BEOS
Definition: headers.hpp:98
@ HOST5_UNIX
Definition: headers.hpp:94
@ HOST5_WINDOWS
Definition: headers.hpp:94
@ HOST_MAX
Definition: headers.hpp:98
@ HOST_UNIX
Definition: headers.hpp:97
#define SUBHEAD_TYPE_CMT
Definition: headers.hpp:114
#define VER_UNPACK5
Definition: headers.hpp:20
#define VER_UNKNOWN
Definition: headers.hpp:21
@ NAMES_LOWERCASE
Definition: options.hpp:27
@ NAMES_UPPERCASE
Definition: options.hpp:27
@ QOPEN_NONE
Definition: options.hpp:49
wchar * GetWideName(const char *Name, const wchar *NameW, wchar *DestW, size_t DestSize)
Definition: pathfn.cpp:903
void UnixSlashToDos(const char *SrcName, char *DestName, size_t MaxLength)
Definition: pathfn.cpp:491
#define Min(x, y)
Definition: rardefs.hpp:4
#define MAXPASSWORD
Definition: rardefs.hpp:14
#define Max(x, y)
Definition: rardefs.hpp:5
#define ASIZE(x)
Definition: rardefs.hpp:10
#define INT64NDF
Definition: rartypes.hpp:30
wchar_t wchar
Definition: rartypes.hpp:13
int64_t int64
Definition: rartypes.hpp:12
unsigned int uint
Definition: rartypes.hpp:8
uint16_t ushort
Definition: rartypes.hpp:7
uint8_t byte
Definition: rartypes.hpp:6
#define MAX_INT64
Definition: rartypes.hpp:22
uint64_t uint64
Definition: rartypes.hpp:11
#define INT32TO64(high, low)
Definition: rartypes.hpp:19
void cleandata(void *data, size_t size)
Definition: secpassword.cpp:80
void sha256_process(sha256_context *ctx, const void *Data, size_t Size)
Definition: sha256.cpp:90
void sha256_done(sha256_context *ctx, byte *Digest)
Definition: sha256.cpp:114
void sha256_init(sha256_context *ctx)
Definition: sha256.cpp:35
#define SHA256_DIGEST_SIZE
Definition: sha256.hpp:4
void IntToExt(const char *Src, char *Dest, size_t DestSize)
Definition: strfn.cpp:15
void wcsncatz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:300
void ArcCharToWide(const char *Src, wchar *Dest, size_t DestSize, ACTW_ENCODING Encoding)
Definition: strfn.cpp:33
@ ACTW_OEM
Definition: strfn.hpp:8
HEADER_TYPE HeaderType
Definition: headers.hpp:141
void Reset()
Definition: headers.hpp:147
uint HeadCRC
Definition: headers.hpp:140
uint HeadSize
Definition: headers.hpp:143
uint Flags
Definition: headers.hpp:142
bool SkipIfUnknown
Definition: headers.hpp:145
uint DataSize
Definition: headers.hpp:156
ushort UnpSize
Definition: headers.hpp:308
ushort CommCRC
Definition: headers.hpp:311
byte PswCheck[SIZE_PSWCHECK]
Definition: headers.hpp:293
byte Salt[SIZE_SALT50]
Definition: headers.hpp:292
uint Lg2Count
Definition: headers.hpp:291
bool UsePswCheck
Definition: headers.hpp:290
byte Method
Definition: headers.hpp:338
uint UnpSize
Definition: headers.hpp:336
uint EACRC
Definition: headers.hpp:339
byte UnpVer
Definition: headers.hpp:337
uint ArcDataCRC
Definition: headers.hpp:267
bool DataCRC
Definition: headers.hpp:274
bool NextVolume
Definition: headers.hpp:273
uint VolNumber
Definition: headers.hpp:269
bool RevSpace
Definition: headers.hpp:275
bool StoreVolNumber
Definition: headers.hpp:276
RarTime atime
Definition: headers.hpp:190
HashValue FileHash
Definition: headers.hpp:196
char UnixOwnerName[256]
Definition: headers.hpp:243
char UnixGroupName[256]
Definition: headers.hpp:243
uint UnixOwnerID
Definition: headers.hpp:248
CRYPT_METHOD CryptMethod
Definition: headers.hpp:206
int64 UnpSize
Definition: headers.hpp:193
bool Solid
Definition: headers.hpp:222
bool UseHashKey
Definition: headers.hpp:214
wchar FileName[NM]
Definition: headers.hpp:184
uint Lg2Count
Definition: headers.hpp:220
size_t WinSize
Definition: headers.hpp:226
byte HashKey[SHA256_DIGEST_SIZE]
Definition: headers.hpp:218
byte PswCheck[SIZE_PSWCHECK]
Definition: headers.hpp:211
int64 PackSize
Definition: headers.hpp:192
RarTime ctime
Definition: headers.hpp:189
bool LargeFile
Definition: headers.hpp:230
bool UnixGroupNumeric
Definition: headers.hpp:242
bool UnixOwnerSet
Definition: headers.hpp:242
bool SubBlock
Definition: headers.hpp:234
uint FileFlags
Definition: headers.hpp:198
bool UnknownUnpSize
Definition: headers.hpp:203
byte Method
Definition: headers.hpp:179
bool Encrypted
Definition: headers.hpp:205
uint UnpVer
Definition: headers.hpp:178
uint UnixGroupID
Definition: headers.hpp:249
bool Inherited
Definition: headers.hpp:227
bool DirTarget
Definition: headers.hpp:240
bool CommentInHeader
Definition: headers.hpp:224
bool Dir
Definition: headers.hpp:223
void Reset(size_t SubDataSize=0)
Definition: headers.cpp:3
bool CmpName(const wchar *Name)
Definition: headers.hpp:254
bool UnixOwnerNumeric
Definition: headers.hpp:242
byte Salt[SIZE_SALT50]
Definition: headers.hpp:208
uint SubFlags
Definition: headers.hpp:182
bool UsePswCheck
Definition: headers.hpp:210
bool SaltSet
Definition: headers.hpp:207
Array< byte > SubData
Definition: headers.hpp:186
wchar RedirName[NM]
Definition: headers.hpp:239
int64 MaxSize
Definition: headers.hpp:194
bool Version
Definition: headers.hpp:225
RarTime mtime
Definition: headers.hpp:188
HOST_SYSTEM_TYPE HSType
Definition: headers.hpp:236
byte HostOS
Definition: headers.hpp:177
FILE_SYSTEM_REDIRECT RedirType
Definition: headers.hpp:238
byte InitV[SIZE_INITV]
Definition: headers.hpp:209
bool SplitBefore
Definition: headers.hpp:200
bool SplitAfter
Definition: headers.hpp:201
uint FileAttr
Definition: headers.hpp:181
byte Digest[SHA256_DIGEST_SIZE]
Definition: hash.hpp:16
HASH_TYPE Type
Definition: hash.hpp:12
uint CRC32
Definition: hash.hpp:15
void Reset()
Definition: headers.cpp:50
bool Locator
Definition: headers.hpp:166
ushort HighPosAV
Definition: headers.hpp:162
bool PackComment
Definition: headers.hpp:165
uint PosAV
Definition: headers.hpp:163
uint64 RROffset
Definition: headers.hpp:169
uint64 QOpenOffset
Definition: headers.hpp:167
bool CommentInHeader
Definition: headers.hpp:164
uint HeadSize
Definition: headers.hpp:134
uint TotalBlocks
Definition: headers.hpp:319
ushort RecSectors
Definition: headers.hpp:318
byte Mark[8]
Definition: headers.hpp:320
uint Reminder
Definition: timefn.hpp:12
uint Second
Definition: timefn.hpp:11
uint StreamCRC
Definition: headers.hpp:348
char StreamName[260]
Definition: headers.hpp:350
uint UnpSize
Definition: headers.hpp:345
ushort StreamNameSize
Definition: headers.hpp:349
ushort SubType
Definition: headers.hpp:301
ushort GroupNameSize
Definition: headers.hpp:327
char GroupName[256]
Definition: headers.hpp:330
ushort OwnerNameSize
Definition: headers.hpp:326
char OwnerName[256]
Definition: headers.hpp:329
void Wait()
Definition: system.cpp:80
@ UIPASSWORD_ARCHIVE
Definition: ui.hpp:90
bool uiIsGlobalPasswordSet()
Definition: uiconsole.cpp:407
bool uiGetPassword(UIPASSWORD_TYPE Type, const wchar *FileName, SecPassword *Password)
Definition: uiconsole.cpp:398
void uiMsg(UIMESSAGE_CODE Code)
Definition: ui.hpp:148
@ UIERROR_SUBHEADERUNKNOWN
Definition: ui.hpp:19
@ UIERROR_HEADERBROKEN
Definition: ui.hpp:18
@ UIERROR_BADPSW
Definition: ui.hpp:12
@ UIERROR_UNKNOWNENCMETHOD
Definition: ui.hpp:21
@ UIMSG_SKIPENCARC
Definition: ui.hpp:52
@ UIWAIT_BADPSW
Definition: ui.hpp:55
@ UIERROR_UNEXPEOF
Definition: ui.hpp:28
@ UIERROR_SUBHEADERDATABROKEN
Definition: ui.hpp:20
@ UIERROR_CHECKSUMENC
Definition: ui.hpp:11
@ UIERROR_FHEADERBROKEN
Definition: ui.hpp:18
@ UIERROR_SUBHEADERBROKEN
Definition: ui.hpp:19
@ UIERROR_INCERRCOUNT
Definition: ui.hpp:10
wchar * wcslower(wchar *s)
Definition: unicode.cpp:490
bool CharToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:85
bool UtfToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:324
wchar * wcsupper(wchar *s)
Definition: unicode.cpp:506