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)  

extract.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
4{
6
7 *ArcName=0;
8
10
12 Unp=new Unpack(&DataIO);
13#ifdef RAR_SMP
14 Unp->SetThreads(Cmd->Threads);
15#endif
16}
17
18
20{
21 delete Unp;
22}
23
24
26{
27#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
28 Fat32=NotFat32=false;
29#endif
32
33 FindData FD;
37
40 {
42 Cmd->Password.Clean(); // Clean user entered password before processing next archive.
43
44 ReconstructDone=false; // Must be reset here, not in ExtractArchiveInit().
45 UseExactVolName=false; // Must be reset here, not in ExtractArchiveInit().
46 while (true)
47 {
49 if (Code!=EXTRACT_ARC_REPEAT)
50 break;
51 }
53 }
54
55 // Clean user entered password. Not really required, just for extra safety.
58
59 if (TotalFileCount==0 && Cmd->Command[0]!='I' &&
60 ErrHandler.GetErrorCode()!=RARX_BADPWD) // Not in case of wrong archive password.
61 {
64
65 // Other error codes may explain a reason of "no files extracted" clearer,
66 // so set it only if no other errors found (wrong mask set by user).
69 }
70 else
71 if (!Cmd->DisableDone)
72 if (Cmd->Command[0]=='I')
74 else
77 else
79}
80
81
83{
85
86 FileCount=0;
88#ifndef SFX_MODULE
89 FirstFile=true;
90#endif
91
93
94 DataIO.UnpVolume=false;
95
96 PrevProcessed=false;
97 AllMatchesExact=true;
99
101}
102
103
105{
106 Archive Arc(Cmd);
107 if (*Cmd->UseStdin!=0)
108 {
110#ifdef USE_QOPEN
111 Arc.SetProhibitQOpen(true);
112#endif
113 }
114 else
115 {
116#if defined(_WIN_ALL) && !defined(SFX_MODULE) // WinRAR GUI code also resets the cache.
117 if (*Cmd->Command=='T' || Cmd->Test)
118 ResetFileCache(ArcName); // Reset the file cache when testing an archive.
119#endif
120 if (!Arc.WOpen(ArcName))
121 return EXTRACT_ARC_NEXT;
122 }
123
124 if (!Arc.IsArchive(true))
125 {
126#if !defined(SFX_MODULE) && !defined(RARDLL)
127 if (CmpExt(ArcName,L"rev"))
128 {
129 wchar FirstVolName[NM];
130 VolNameToFirstName(ArcName,FirstVolName,ASIZE(FirstVolName),true);
131
132 // If several volume names from same volume set are specified
133 // and current volume is not first in set and first volume is present
134 // and specified too, let's skip the current volume.
135 if (wcsicomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) &&
136 Cmd->ArcNames.Search(FirstVolName,false))
137 return EXTRACT_ARC_NEXT;
139 TotalFileCount++; // Suppress "No files to extract" message.
140 return EXTRACT_ARC_NEXT;
141 }
142#endif
143
145
146#ifndef SFX_MODULE
147 if (CmpExt(ArcName,L"rar"))
148#endif
150 return EXTRACT_ARC_NEXT;
151 }
152
153 if (Arc.FailedHeaderDecryption) // Bad archive password.
154 return EXTRACT_ARC_NEXT;
155
156#ifndef SFX_MODULE
157 if (Arc.Volume && !Arc.FirstVolume && !UseExactVolName)
158 {
159 wchar FirstVolName[NM];
160 VolNameToFirstName(ArcName,FirstVolName,ASIZE(FirstVolName),Arc.NewNumbering);
161
162 // If several volume names from same volume set are specified
163 // and current volume is not first in set and first volume is present
164 // and specified too, let's skip the current volume.
165 if (wcsicomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) &&
166 Cmd->ArcNames.Search(FirstVolName,false))
167 return EXTRACT_ARC_NEXT;
168 }
169#endif
170
171 int64 VolumeSetSize=0; // Total size of volumes after the current volume.
172
173 if (Arc.Volume)
174 {
175#ifndef SFX_MODULE
176 // Try to speed up extraction for independent solid volumes by starting
177 // extraction from non-first volume if we can.
179 {
180 UseExactVolName=true;
181 return EXTRACT_ARC_REPEAT;
182 }
183#endif
184
185 // Calculate the total size of all accessible volumes.
186 // This size is necessary to display the correct total progress indicator.
187
188 wchar NextName[NM];
189 wcsncpyz(NextName,Arc.FileName,ASIZE(NextName));
190
191 while (true)
192 {
193 // First volume is already added to DataIO.TotalArcSize
194 // in initial TotalArcSize calculation in DoExtract.
195 // So we skip it and start from second volume.
196 NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering);
197 FindData FD;
198 if (FindFile::FastFind(NextName,&FD))
199 VolumeSetSize+=FD.Size;
200 else
201 break;
202 }
203 DataIO.TotalArcSize+=VolumeSetSize;
204 }
205
207
208 if (*Cmd->Command=='T' || *Cmd->Command=='I')
209 Cmd->Test=true;
210
211
212 if (*Cmd->Command=='I')
213 {
215 }
216 else
218
219 Arc.ViewComment();
220
221
222 while (1)
223 {
224 size_t Size=Arc.ReadHeader();
225
226
227 bool Repeat=false;
228 if (!ExtractCurrentFile(Arc,Size,Repeat))
229 if (Repeat)
230 {
231 // If we started extraction from not first volume and need to
232 // restart it from first, we must set DataIO.TotalArcSize to size
233 // of new first volume to display the total progress correctly.
234 FindData NewArc;
235 if (FindFile::FastFind(ArcName,&NewArc))
236 DataIO.TotalArcSize=NewArc.Size;
237 return EXTRACT_ARC_REPEAT;
238 }
239 else
240 break;
241 }
242
243
244#if !defined(SFX_MODULE) && !defined(RARDLL)
245 if (Cmd->Test && Arc.Volume)
247#endif
248
249 return EXTRACT_ARC_NEXT;
250}
251
252
253bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
254{
255 wchar Command=Cmd->Command[0];
256 if (HeaderSize==0)
257 if (DataIO.UnpVolume)
258 {
259#ifdef NOVOLUME
260 return false;
261#else
262 // Supposing we unpack an old RAR volume without the end of archive
263 // record and last file is not split between volumes.
264 if (!MergeArchive(Arc,&DataIO,false,Command))
265 {
267 return false;
268 }
269#endif
270 }
271 else
272 return false;
273
274 HEADER_TYPE HeaderType=Arc.GetHeaderType();
275 if (HeaderType!=HEAD_FILE)
276 {
277#ifndef SFX_MODULE
278 if (Arc.Format==RARFMT15 && HeaderType==HEAD3_OLDSERVICE && PrevProcessed)
280#endif
281 if (HeaderType==HEAD_SERVICE && PrevProcessed)
283 if (HeaderType==HEAD_ENDARC)
284 if (Arc.EndArcHead.NextVolume)
285 {
286#ifdef NOVOLUME
287 return false;
288#else
289 if (!MergeArchive(Arc,&DataIO,false,Command))
290 {
292 return false;
293 }
294 Arc.Seek(Arc.CurBlockPos,SEEK_SET);
295 return true;
296#endif
297 }
298 else
299 return false;
300 Arc.SeekToNext();
301 return true;
302 }
303 PrevProcessed=false;
304
305 // We can get negative sizes in corrupt archive and it is unacceptable
306 // for size comparisons in ComprDataIO::UnpRead, where we cast sizes
307 // to size_t and can exceed another read or available size. We could fix it
308 // when reading an archive. But we prefer to do it here, because this
309 // function is called directly in unrar.dll, so we fix bad parameters
310 // passed to dll. Also we want to see real negative sizes in the listing
311 // of corrupt archive. To prevent uninitialized data access perform
312 // these checks after rejecting zero length and non-file headers above.
313 if (Arc.FileHead.PackSize<0)
314 Arc.FileHead.PackSize=0;
315 if (Arc.FileHead.UnpSize<0)
316 Arc.FileHead.UnpSize=0;
317
319 return false;
320
321 int MatchType=MATCH_WILDSUBPATH;
322
323 bool EqualNames=false;
324 wchar MatchedArg[NM];
325 int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType,0,MatchedArg,ASIZE(MatchedArg));
326 bool MatchFound=MatchNumber!=0;
327#ifndef SFX_MODULE
329 {
330 wcsncpyz(Cmd->ArcPath,MatchedArg,ASIZE(Cmd->ArcPath));
332 if (IsWildcard(Cmd->ArcPath)) // Cannot correctly process path*\* masks here.
333 *Cmd->ArcPath=0;
334 }
335#endif
336 if (MatchFound && !EqualNames)
337 AllMatchesExact=false;
338
339 Arc.ConvertAttributes();
340
341#if !defined(SFX_MODULE) && !defined(RARDLL)
343 {
344 wchar CurVolName[NM];
345 wcsncpyz(CurVolName,ArcName,ASIZE(CurVolName));
347
348 if (wcsicomp(ArcName,CurVolName)!=0 && FileExist(ArcName))
349 {
350 wcsncpyz(Cmd->ArcName,ArcName,ASIZE(ArcName)); // For GUI "Delete archive after extraction".
351 // If first volume name does not match the current name and if such
352 // volume name really exists, let's unpack from this first volume.
353 Repeat=true;
354 return false;
355 }
356#ifndef RARDLL
357 if (!ReconstructDone)
358 {
359 ReconstructDone=true;
360 if (RecVolumesRestore(Cmd,Arc.FileName,true))
361 {
362 Repeat=true;
363 return false;
364 }
365 }
366#endif
367 wcsncpyz(ArcName,CurVolName,ASIZE(ArcName));
368 }
369#endif
370
371 wchar ArcFileName[NM];
372 ConvertPath(Arc.FileHead.FileName,ArcFileName,ASIZE(ArcFileName));
373
374 if (Arc.FileHead.Version)
375 {
376 if (Cmd->VersionControl!=1 && !EqualNames)
377 {
378 if (Cmd->VersionControl==0)
379 MatchFound=false;
380 int Version=ParseVersionFileName(ArcFileName,false);
381 if (Cmd->VersionControl-1==Version)
382 ParseVersionFileName(ArcFileName,true);
383 else
384 MatchFound=false;
385 }
386 }
387 else
388 if (!Arc.IsArcDir() && Cmd->VersionControl>1)
389 MatchFound=false;
390
393
394 Arc.Seek(Arc.NextBlockPos-Arc.FileHead.PackSize,SEEK_SET);
395
396 bool ExtrFile=false;
397 bool SkipSolid=false;
398
399#ifndef SFX_MODULE
400 if (FirstFile && (MatchFound || Arc.Solid) && Arc.FileHead.SplitBefore)
401 {
402 if (MatchFound)
403 {
404 uiMsg(UIERROR_NEEDPREVVOL,Arc.FileName,ArcFileName);
405#ifdef RARDLL
406 Cmd->DllError=ERAR_BAD_DATA;
407#endif
409 }
410 MatchFound=false;
411 }
412
413 FirstFile=false;
414#endif
415
417 if (Arc.Solid)
418 return false; // Abort the entire extraction for solid archive.
419 else
420 MatchFound=false; // Skip only the current file for non-solid archive.
421
422 if (MatchFound || (SkipSolid=Arc.Solid)!=0)
423 {
424 // First common call of uiStartFileExtract. It is done before overwrite
425 // prompts, so if SkipSolid state is changed below, we'll need to make
426 // additional uiStartFileExtract calls with updated parameters.
427 if (!uiStartFileExtract(ArcFileName,!Cmd->Test,Cmd->Test && Command!='I',SkipSolid))
428 return false;
429
431
432 // DestFileName can be set empty in case of excessive -ap switch.
433 ExtrFile=!SkipSolid && *DestFileName!=0 && !Arc.FileHead.SplitBefore;
434
435 if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X'))
436 {
437 FindData FD;
439 {
440 if (FD.mtime >= Arc.FileHead.mtime)
441 {
442 // If directory already exists and its modification time is newer
443 // than start of extraction, it is likely it was created
444 // when creating a path to one of already extracted items.
445 // In such case we'll better update its time even if archived
446 // directory is older.
447
448 if (!FD.IsDir || FD.mtime<StartTime)
449 ExtrFile=false;
450 }
451 }
452 else
453 if (Cmd->FreshFiles)
454 ExtrFile=false;
455 }
456
457 if (!CheckUnpVer(Arc,ArcFileName))
458 {
460#ifdef RARDLL
461 Cmd->DllError=ERAR_UNKNOWN_FORMAT;
462#endif
463 Arc.SeekToNext();
464 return !Arc.Solid; // Can try extracting next file only in non-solid archive.
465 }
466
467 while (true) // Repeat the password prompt for wrong and empty passwords.
468 {
469 if (Arc.FileHead.Encrypted)
470 {
471 // Stop archive extracting if user cancelled a password prompt.
472#ifdef RARDLL
473 if (!ExtrDllGetPassword())
474 {
475 Cmd->DllError=ERAR_MISSING_PASSWORD;
476 return false;
477 }
478#else
479 if (!ExtrGetPassword(Arc,ArcFileName))
480 {
482 return false;
483 }
484#endif
485 }
486
487 // Set a password before creating the file, so we can skip creating
488 // in case of wrong password.
489 SecPassword FilePassword=Cmd->Password;
490#if defined(_WIN_ALL) && !defined(SFX_MODULE)
491 ConvertDosPassword(Arc,FilePassword);
492#endif
493
494 byte PswCheck[SIZE_PSWCHECK];
495 DataIO.SetEncryption(false,Arc.FileHead.CryptMethod,&FilePassword,
496 Arc.FileHead.SaltSet ? Arc.FileHead.Salt:NULL,
498 Arc.FileHead.HashKey,PswCheck);
499
500 // If header is damaged, we cannot rely on password check value,
501 // because it can be damaged too.
502 if (Arc.FileHead.Encrypted && Arc.FileHead.UsePswCheck &&
503 memcmp(Arc.FileHead.PswCheck,PswCheck,SIZE_PSWCHECK)!=0 &&
504 !Arc.BrokenHeader)
505 {
506 if (GlobalPassword) // For -p<pwd> or Ctrl+P to avoid the infinite loop.
507 {
508 // This message is used by Android GUI to reset cached passwords.
509 // Update appropriate code if changed.
510 uiMsg(UIERROR_BADPSW,Arc.FileName,ArcFileName);
511 }
512 else // For passwords entered manually.
513 {
514 // This message is used by Android GUI and Windows GUI and SFX to
515 // reset cached passwords. Update appropriate code if changed.
516 uiMsg(UIWAIT_BADPSW,Arc.FileName,ArcFileName);
517 Cmd->Password.Clean();
518
519 // Avoid new requests for unrar.dll to prevent the infinite loop
520 // if app always returns the same password.
521#ifndef RARDLL
522 continue; // Request a password again.
523#endif
524 }
525#ifdef RARDLL
526 // If we already have ERAR_EOPEN as result of missing volume,
527 // we should not replace it with less precise ERAR_BAD_PASSWORD.
528 if (Cmd->DllError!=ERAR_EOPEN)
529 Cmd->DllError=ERAR_BAD_PASSWORD;
530#endif
532 ExtrFile=false;
533 }
534 break;
535 }
536
537#ifdef RARDLL
538 if (*Cmd->DllDestName!=0)
540#endif
541
542 File CurFile;
543
544 bool LinkEntry=Arc.FileHead.RedirType!=FSREDIR_NONE;
545 if (LinkEntry && Arc.FileHead.RedirType!=FSREDIR_FILECOPY)
546 {
547 if (ExtrFile && Command!='P' && !Cmd->Test)
548 {
549 // Overwrite prompt for symbolic and hard links.
550 bool UserReject=false;
551 if (FileExist(DestFileName) && !UserReject)
553 if (UserReject)
554 ExtrFile=false;
555 }
556 }
557 else
558 if (Arc.IsArcDir())
559 {
560 if (!ExtrFile || Command=='P' || Command=='I' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
561 return true;
563 ExtrCreateDir(Arc,ArcFileName);
564 // It is important to not increment MatchedArgs here, so we extract
565 // dir with its entire contents and not dir record only even if
566 // dir record precedes files.
567 return true;
568 }
569 else
570 if (ExtrFile) // Create files and file copies (FSREDIR_FILECOPY).
571 ExtrFile=ExtrCreateFile(Arc,CurFile);
572
573 if (!ExtrFile && Arc.Solid)
574 {
575 SkipSolid=true;
576 ExtrFile=true;
577
578 // We changed SkipSolid, so we need to call uiStartFileExtract
579 // with "Skip" parameter to change the operation status
580 // from "extracting" to "skipping". For example, it can be necessary
581 // if user answered "No" to overwrite prompt when unpacking
582 // a solid archive.
583 if (!uiStartFileExtract(ArcFileName,false,false,true))
584 return false;
585 }
586 if (ExtrFile)
587 {
588 // Set it in test mode, so we also test subheaders such as NTFS streams
589 // after tested file.
590 if (Cmd->Test)
591 PrevProcessed=true;
592
593 bool TestMode=Cmd->Test || SkipSolid; // Unpack to memory, not to disk.
594
595 if (!SkipSolid)
596 {
597 if (!TestMode && Command!='P' && CurFile.IsDevice())
598 {
601 }
603 }
604 FileCount++;
605 if (Command!='I' && !Cmd->DisableNames)
606 if (SkipSolid)
607 mprintf(St(MExtrSkipFile),ArcFileName);
608 else
609 switch(Cmd->Test ? 'T':Command) // "Test" can be also enabled by -t switch.
610 {
611 case 'T':
612 mprintf(St(MExtrTestFile),ArcFileName);
613 break;
614#ifndef SFX_MODULE
615 case 'P':
616 mprintf(St(MExtrPrinting),ArcFileName);
617 break;
618#endif
619 case 'X':
620 case 'E':
622 break;
623 }
625 mprintf(L" ");
626 if (Cmd->DisableNames)
627 uiEolAfterMsg(); // Avoid erasing preceding messages by percentage indicator in -idn mode.
628
634 DataIO.SetFiles(&Arc,&CurFile);
635 DataIO.SetTestMode(TestMode);
636 DataIO.SetSkipUnpCRC(SkipSolid);
637
638#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
639 if (!TestMode && !Arc.BrokenHeader &&
640 Arc.FileHead.UnpSize>0xffffffff && (Fat32 || !NotFat32))
641 {
642 if (!Fat32) // Not detected yet.
643 NotFat32=!(Fat32=IsFAT(Cmd->ExtrPath));
644 if (Fat32)
645 uiMsg(UIMSG_FAT32SIZE); // Inform user about FAT32 size limit.
646 }
647#endif
648
649 uint64 Preallocated=0;
650 if (!TestMode && !Arc.BrokenHeader && Arc.FileHead.UnpSize>1000000 &&
651 Arc.FileHead.PackSize*1024>Arc.FileHead.UnpSize && Arc.IsSeekable() &&
652 (Arc.FileHead.UnpSize<100000000 || Arc.FileLength()>Arc.FileHead.PackSize))
653 {
654 CurFile.Prealloc(Arc.FileHead.UnpSize);
655 Preallocated=Arc.FileHead.UnpSize;
656 }
657 CurFile.SetAllowDelete(!Cmd->KeepBroken);
658
659 bool FileCreateMode=!TestMode && !SkipSolid && Command!='P';
660 bool ShowChecksum=true; // Display checksum verification result.
661
662 bool LinkSuccess=true; // Assume success for test mode.
663 if (LinkEntry)
664 {
666
667 if (Type==FSREDIR_HARDLINK || Type==FSREDIR_FILECOPY)
668 {
669 wchar RedirName[NM];
670 ConvertPath(Arc.FileHead.RedirName,RedirName,ASIZE(RedirName));
671
672 wchar NameExisting[NM];
673 ExtrPrepareName(Arc,RedirName,NameExisting,ASIZE(NameExisting));
674 if (FileCreateMode && *NameExisting!=0) // *NameExisting can be 0 in case of excessive -ap switch.
675 if (Type==FSREDIR_HARDLINK)
676 LinkSuccess=ExtractHardlink(Cmd,DestFileName,NameExisting,ASIZE(NameExisting));
677 else
678 LinkSuccess=ExtractFileCopy(CurFile,Arc.FileName,DestFileName,NameExisting,ASIZE(NameExisting));
679 }
680 else
681 if (Type==FSREDIR_UNIXSYMLINK || Type==FSREDIR_WINSYMLINK || Type==FSREDIR_JUNCTION)
682 {
683 if (FileCreateMode)
684 LinkSuccess=ExtractSymlink(Cmd,DataIO,Arc,DestFileName);
685 }
686 else
687 {
689 LinkSuccess=false;
690 }
691
692 if (!LinkSuccess || Arc.Format==RARFMT15 && !FileCreateMode)
693 {
694 // RAR 5.x links have a valid data checksum even in case of
695 // failure, because they do not store any data.
696 // We do not want to display "OK" in this case.
697 // For 4.x symlinks we verify the checksum only when extracting,
698 // but not when testing an archive.
699 ShowChecksum=false;
700 }
701 PrevProcessed=FileCreateMode && LinkSuccess;
702 }
703 else
704 if (!Arc.FileHead.SplitBefore)
705 if (Arc.FileHead.Method==0)
707 else
708 {
711#ifndef SFX_MODULE
712 if (Arc.Format!=RARFMT50 && Arc.FileHead.UnpVer<=15)
713 Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
714 else
715#endif
717 }
718
719 Arc.SeekToNext();
720
721 // We check for "split after" flag to detect partially extracted files
722 // from incomplete volume sets. For them file header contains packed
723 // data hash, which must not be compared against unpacked data hash
724 // to prevent accidental match. Moreover, for -m0 volumes packed data
725 // hash would match truncated unpacked data hash and lead to fake "OK"
726 // in incomplete volume set.
727 bool ValidCRC=!Arc.FileHead.SplitAfter && DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL);
728
729 // We set AnySolidDataUnpackedWell to true if we found at least one
730 // valid non-zero solid file in preceding solid stream. If it is true
731 // and if current encrypted file is broken, we do not need to hint
732 // about a wrong password and can report CRC error only.
733 if (!Arc.FileHead.Solid)
734 AnySolidDataUnpackedWell=false; // Reset the flag, because non-solid file is found.
735 else
736 if (Arc.FileHead.Method!=0 && Arc.FileHead.UnpSize>0 && ValidCRC)
738
739 bool BrokenFile=false;
740
741 // Checksum is not calculated in skip solid mode for performance reason.
742 if (!SkipSolid && ShowChecksum)
743 {
744 if (ValidCRC)
745 {
746 if (Command!='P' && Command!='I' && !Cmd->DisableNames)
747 mprintf(L"%s%s ",Cmd->DisablePercentage ? L" ":L"\b\b\b\b\b ",
748 Arc.FileHead.FileHash.Type==HASH_NONE ? L" ?":St(MOk));
749 }
750 else
751 {
752 if (Arc.FileHead.Encrypted && (!Arc.FileHead.UsePswCheck ||
754 uiMsg(UIERROR_CHECKSUMENC,Arc.FileName,ArcFileName);
755 else
756 uiMsg(UIERROR_CHECKSUM,Arc.FileName,ArcFileName);
757 BrokenFile=true;
759#ifdef RARDLL
760 // If we already have ERAR_EOPEN as result of missing volume
761 // or ERAR_BAD_PASSWORD for RAR5 wrong password,
762 // we should not replace it with less precise ERAR_BAD_DATA.
763 if (Cmd->DllError!=ERAR_EOPEN && Cmd->DllError!=ERAR_BAD_PASSWORD)
764 Cmd->DllError=ERAR_BAD_DATA;
765#endif
766 }
767 }
768 else
769 {
770 // We check SkipSolid to remove percent for skipped solid files only.
771 // We must not apply these \b to links with ShowChecksum==false
772 // and their possible error messages.
773 if (SkipSolid)
774 mprintf(L"\b\b\b\b\b ");
775 }
776
777 // If we successfully unpacked a hard link, we wish to set its file
778 // attributes. Hard link shares file metadata with link target,
779 // so we do not need to set link time or owner. But when we overwrite
780 // an existing link, we can call PrepareToDelete(), which affects
781 // link target attributes as well. So we set link attributes to restore
782 // both target and link attributes if PrepareToDelete() changed them.
783 bool SetAttrOnly=LinkEntry && Arc.FileHead.RedirType==FSREDIR_HARDLINK && LinkSuccess;
784
785 if (!TestMode && (Command=='X' || Command=='E') &&
786 (!LinkEntry || SetAttrOnly || Arc.FileHead.RedirType==FSREDIR_FILECOPY && LinkSuccess) &&
787 (!BrokenFile || Cmd->KeepBroken))
788 {
789 // Below we use DestFileName instead of CurFile.FileName,
790 // so we can set file attributes also for hard links, which do not
791 // have the open CurFile. These strings are the same for other items.
792
793 if (!SetAttrOnly)
794 {
795 // We could preallocate more space that really written to broken file
796 // or file with crafted header.
797 if (Preallocated>0 && (BrokenFile || DataIO.CurUnpWrite!=Preallocated))
798 CurFile.Truncate();
799
800
801 CurFile.SetOpenFileTime(
802 Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
803 Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.FileHead.ctime,
804 Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
805 CurFile.Close();
806
808
809 CurFile.SetCloseFileTime(
810 Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
811 Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
812 }
813
814#if defined(_WIN_ALL) && !defined(SFX_MODULE)
815 if (Cmd->SetCompressedAttr &&
816 (Arc.FileHead.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0)
817 SetFileCompression(DestFileName,true);
818 if (Cmd->ClearArc)
819 Arc.FileHead.FileAttr&=~FILE_ATTRIBUTE_ARCHIVE;
820#endif
822 {
824 // Android cannot set file attributes and while UIERROR_FILEATTR
825 // above is handled by Android RAR silently, this call would cause
826 // "Operation not permitted" message for every unpacked file.
828 }
829
830 PrevProcessed=true;
831 }
832 }
833 }
834 // It is important to increment it for files, but not dirs. So we extract
835 // dir with its entire contents, not just dir record only even if dir
836 // record precedes files.
837 if (MatchFound)
838 MatchedArgs++;
840 return false;
841 if (!ExtrFile)
842 if (!Arc.Solid)
843 Arc.SeekToNext();
844 else
845 if (!SkipSolid)
846 return false;
847 return true;
848}
849
850
852{
854 while (true)
855 {
856 int ReadSize=DataIO.UnpRead(&Buffer[0],Buffer.Size());
857 if (ReadSize<=0)
858 break;
859 int WriteSize=ReadSize<DestUnpSize ? ReadSize:(int)DestUnpSize;
860 if (WriteSize>0)
861 {
862 DataIO.UnpWrite(&Buffer[0],WriteSize);
863 DestUnpSize-=WriteSize;
864 }
865 }
866}
867
868
869bool CmdExtract::ExtractFileCopy(File &New,wchar *ArcName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
870{
871 SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.
872
873 File Existing;
874 if (!Existing.WOpen(NameExisting))
875 {
876 uiMsg(UIERROR_FILECOPY,ArcName,NameExisting,NameNew);
878#ifdef RARDLL
879 Cmd->DllError=ERAR_EREFERENCE;
880#endif
881 return false;
882 }
883
884 Array<char> Buffer(0x100000);
885 int64 CopySize=0;
886
887 while (true)
888 {
889 Wait();
890 int ReadSize=Existing.Read(&Buffer[0],Buffer.Size());
891 if (ReadSize==0)
892 break;
893 New.Write(&Buffer[0],ReadSize);
894 CopySize+=ReadSize;
895 }
896
897 return true;
898}
899
900
901void CmdExtract::ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize)
902{
903 wcsncpyz(DestName,Cmd->ExtrPath,DestSize);
904
905 if (*Cmd->ExtrPath!=0)
906 {
907 wchar LastChar=*PointToLastChar(Cmd->ExtrPath);
908 // We need IsPathDiv check here to correctly handle Unix forward slash
909 // in the end of destination path in Windows: rar x arc dest/
910 // so we call IsPathDiv first instead of just calling AddEndSlash,
911 // which checks for only one type of path separator.
912 // IsDriveDiv is needed for current drive dir: rar x arc d:
913 if (!IsPathDiv(LastChar) && !IsDriveDiv(LastChar))
914 {
915 // Destination path can be without trailing slash if it come from GUI shell.
916 AddEndSlash(DestName,DestSize);
917 }
918 }
919
920#ifndef SFX_MODULE
922 {
923 switch(Cmd->AppendArcNameToPath)
924 {
925 case APPENDARCNAME_DESTPATH: // To subdir of destination path.
926 wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize);
927 SetExt(DestName,NULL,DestSize);
928 break;
929 case APPENDARCNAME_OWNSUBDIR: // To subdir of archive own dir.
930 wcsncpyz(DestName,Arc.FirstVolumeName,DestSize);
931 SetExt(DestName,NULL,DestSize);
932 break;
933 case APPENDARCNAME_OWNDIR: // To archive own dir.
934 wcsncpyz(DestName,Arc.FirstVolumeName,DestSize);
935 RemoveNameFromPath(DestName);
936 break;
937 }
938 AddEndSlash(DestName,DestSize);
939 }
940#endif
941
942#ifndef SFX_MODULE
943 wchar *ArcPath=*Cmd->ExclArcPath!=0 ? Cmd->ExclArcPath:Cmd->ArcPath;
944 size_t ArcPathLength=wcslen(ArcPath);
945 if (ArcPathLength>0)
946 {
947 size_t NameLength=wcslen(ArcFileName);
948 if (NameLength>=ArcPathLength && wcsnicompc(ArcPath,ArcFileName,ArcPathLength)==0 &&
949 (IsPathDiv(ArcPath[ArcPathLength-1]) ||
950 IsPathDiv(ArcFileName[ArcPathLength]) || ArcFileName[ArcPathLength]==0))
951 {
952 ArcFileName+=Min(ArcPathLength,NameLength);
953 while (IsPathDiv(*ArcFileName))
954 ArcFileName++;
955 if (*ArcFileName==0) // Excessive -ap switch.
956 {
957 *DestName=0;
958 return;
959 }
960 }
961 }
962#endif
963
964 wchar Command=Cmd->Command[0];
965 // Use -ep3 only in systems, where disk letters are exist, not in Unix.
966 bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':');
967
968 // We do not use any user specified destination paths when extracting
969 // absolute paths in -ep3 mode.
970 if (AbsPaths)
971 *DestName=0;
972
973 if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
974 wcsncatz(DestName,PointToName(ArcFileName),DestSize);
975 else
976 wcsncatz(DestName,ArcFileName,DestSize);
977
978#ifdef _WIN_ALL
979 // Must do after Cmd->ArcPath processing above, so file name and arc path
980 // trailing spaces are in sync.
981 if (!Cmd->AllowIncompatNames)
982 MakeNameCompatible(DestName,DestSize);
983#endif
984
985 wchar DiskLetter=toupperw(DestName[0]);
986
987 if (AbsPaths)
988 {
989 if (DestName[1]=='_' && IsPathDiv(DestName[2]) &&
990 DiskLetter>='A' && DiskLetter<='Z')
991 DestName[1]=':';
992 else
993 if (DestName[0]=='_' && DestName[1]=='_')
994 {
995 // Convert __server\share to \\server\share.
996 DestName[0]=CPATHDIVIDER;
997 DestName[1]=CPATHDIVIDER;
998 }
999 }
1000}
1001
1002
1003#ifdef RARDLL
1004bool CmdExtract::ExtrDllGetPassword()
1005{
1006 if (!Cmd->Password.IsSet())
1007 {
1008 if (Cmd->Callback!=NULL)
1009 {
1010 wchar PasswordW[MAXPASSWORD];
1011 *PasswordW=0;
1012 if (Cmd->Callback(UCM_NEEDPASSWORDW,Cmd->UserData,(LPARAM)PasswordW,ASIZE(PasswordW))==-1)
1013 *PasswordW=0;
1014 if (*PasswordW==0)
1015 {
1016 char PasswordA[MAXPASSWORD];
1017 *PasswordA=0;
1018 if (Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)PasswordA,ASIZE(PasswordA))==-1)
1019 *PasswordA=0;
1020 GetWideName(PasswordA,NULL,PasswordW,ASIZE(PasswordW));
1021 cleandata(PasswordA,sizeof(PasswordA));
1022 }
1023 Cmd->Password.Set(PasswordW);
1024 cleandata(PasswordW,sizeof(PasswordW));
1025 Cmd->ManualPassword=true;
1026 }
1027 if (!Cmd->Password.IsSet())
1028 return false;
1029 }
1030 return true;
1031}
1032#endif
1033
1034
1035#ifndef RARDLL
1036bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
1037{
1038 if (!Cmd->Password.IsSet())
1039 {
1040 if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password)/* || !Cmd->Password.IsSet()*/)
1041 {
1042 // Suppress "test is ok" message if user cancelled the password prompt.
1044 return false;
1045 }
1046 Cmd->ManualPassword=true;
1047 }
1048#if !defined(SILENT)
1049 else
1050 if (!GlobalPassword && !Arc.FileHead.Solid)
1051 {
1052 eprintf(St(MUseCurPsw),ArcFileName);
1053 switch(Cmd->AllYes ? 1 : Ask(St(MYesNoAll)))
1054 {
1055 case -1:
1057 case 2:
1058 if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password))
1059 return false;
1060 break;
1061 case 3:
1062 GlobalPassword=true;
1063 break;
1064 }
1065 }
1066#endif
1067 return true;
1068}
1069#endif
1070
1071
1072#if defined(_WIN_ALL) && !defined(SFX_MODULE)
1073void CmdExtract::ConvertDosPassword(Archive &Arc,SecPassword &DestPwd)
1074{
1075 if (Arc.Format==RARFMT15 && Arc.FileHead.HostOS==HOST_MSDOS)
1076 {
1077 // We need the password in OEM encoding if file was encrypted by
1078 // native RAR/DOS (not extender based). Let's make the conversion.
1079 wchar PlainPsw[MAXPASSWORD];
1080 Cmd->Password.Get(PlainPsw,ASIZE(PlainPsw));
1081 char PswA[MAXPASSWORD];
1082 CharToOemBuffW(PlainPsw,PswA,ASIZE(PswA));
1083 PswA[ASIZE(PswA)-1]=0;
1084 CharToWide(PswA,PlainPsw,ASIZE(PlainPsw));
1085 DestPwd.Set(PlainPsw);
1086 cleandata(PlainPsw,sizeof(PlainPsw));
1087 cleandata(PswA,sizeof(PswA));
1088 }
1089}
1090#endif
1091
1092
1093void CmdExtract::ExtrCreateDir(Archive &Arc,const wchar *ArcFileName)
1094{
1095 if (Cmd->Test)
1096 {
1097 if (!Cmd->DisableNames)
1098 {
1099 mprintf(St(MExtrTestFile),ArcFileName);
1100 mprintf(L" %s",St(MOk));
1101 }
1102 return;
1103 }
1104
1106 bool DirExist=false;
1107 if (MDCode!=MKDIR_SUCCESS)
1108 {
1109 DirExist=FileExist(DestFileName);
1110 if (DirExist && !IsDir(GetFileAttr(DestFileName)))
1111 {
1112 // File with name same as this directory exists. Propose user
1113 // to overwrite it.
1114 bool UserReject;
1116 DirExist=false;
1117 }
1118 if (!DirExist)
1119 {
1122 if (MDCode!=MKDIR_SUCCESS && !IsNameUsable(DestFileName))
1123 {
1125 wchar OrigName[ASIZE(DestFileName)];
1126 wcsncpyz(OrigName,DestFileName,ASIZE(OrigName));
1128#ifndef SFX_MODULE
1130#endif
1132 if (!DirExist)
1133 {
1136 }
1137 }
1138 }
1139 }
1140 if (MDCode==MKDIR_SUCCESS)
1141 {
1142 if (!Cmd->DisableNames)
1143 {
1145 mprintf(L" %s",St(MOk));
1146 }
1147 PrevProcessed=true;
1148 }
1149 else
1150 if (DirExist)
1151 {
1152 if (!Cmd->IgnoreGeneralAttr)
1154 PrevProcessed=true;
1155 }
1156 else
1157 {
1160#ifdef RARDLL
1161 Cmd->DllError=ERAR_ECREATE;
1162#endif
1164 }
1165 if (PrevProcessed)
1166 {
1167#if defined(_WIN_ALL) && !defined(SFX_MODULE)
1168 if (Cmd->SetCompressedAttr &&
1169 (Arc.FileHead.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()!=WNT_NONE)
1170 SetFileCompression(DestFileName,true);
1171#endif
1174 Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
1175 Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.FileHead.ctime,
1176 Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
1177 }
1178}
1179
1180
1182{
1183 bool Success=true;
1184 wchar Command=Cmd->Command[0];
1185#if !defined(SFX_MODULE)
1186 if (Command=='P')
1188#endif
1189 if ((Command=='E' || Command=='X') && !Cmd->Test)
1190 {
1191 bool UserReject;
1192 // Specify "write only" mode to avoid OpenIndiana NAS problems
1193 // with SetFileTime and read+write files.
1194 if (!FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
1195 {
1196 Success=false;
1197 if (!UserReject)
1198 {
1202
1203#ifdef RARDLL
1204 Cmd->DllError=ERAR_ECREATE;
1205#endif
1207 {
1209
1210 wchar OrigName[ASIZE(DestFileName)];
1211 wcsncpyz(OrigName,DestFileName,ASIZE(OrigName));
1212
1214
1216 if (FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
1217 {
1218#ifndef SFX_MODULE
1220#endif
1221 Success=true;
1222 }
1223 else
1225 }
1226 }
1227 }
1228 }
1229 return Success;
1230}
1231
1232
1233bool CmdExtract::CheckUnpVer(Archive &Arc,const wchar *ArcFileName)
1234{
1235 bool WrongVer;
1236 if (Arc.Format==RARFMT50) // Both SFX and RAR can unpack RAR 5.0 archives.
1237 WrongVer=Arc.FileHead.UnpVer>VER_UNPACK5;
1238 else
1239 {
1240#ifdef SFX_MODULE // SFX can unpack only RAR 2.9 archives.
1241 WrongVer=Arc.FileHead.UnpVer!=VER_UNPACK;
1242#else // All formats since 1.3 for RAR.
1243 WrongVer=Arc.FileHead.UnpVer<13 || Arc.FileHead.UnpVer>VER_UNPACK;
1244#endif
1245 }
1246
1247 // We can unpack stored files regardless of compression version field.
1248 if (Arc.FileHead.Method==0)
1249 WrongVer=false;
1250
1251 if (WrongVer)
1252 {
1253 ErrHandler.UnknownMethodMsg(Arc.FileName,ArcFileName);
1255 }
1256 return !WrongVer;
1257}
1258
1259
1260#ifndef SFX_MODULE
1261// To speed up solid volumes extraction, try to find a non-first start volume,
1262// which still allows to unpack all files. It is possible for independent
1263// solid volumes with solid statistics reset in the beginning.
1264bool CmdExtract::DetectStartVolume(const wchar *VolName,bool NewNumbering)
1265{
1266 wchar *ArgName=Cmd->FileArgs.GetString();
1267 Cmd->FileArgs.Rewind();
1268 if (ArgName!=NULL && (wcscmp(ArgName,L"*")==0 || wcscmp(ArgName,L"*.*")==0))
1269 return false; // No need to check further for * and *.* masks.
1270
1271 wchar StartName[NM];
1272 *StartName=0;
1273
1274 // Start search from first volume if all volumes preceding current are available.
1275 wchar NextName[NM];
1276 GetFirstVolIfFullSet(VolName,NewNumbering,NextName,ASIZE(NextName));
1277
1278 bool Matched=false;
1279 while (!Matched)
1280 {
1281 Archive Arc(Cmd);
1282 if (!Arc.Open(NextName) || !Arc.IsArchive(false) || !Arc.Volume)
1283 break;
1284
1285 bool OpenNext=false;
1286 while (Arc.ReadHeader()>0)
1287 {
1288 Wait();
1289
1290 HEADER_TYPE HeaderType=Arc.GetHeaderType();
1291 if (HeaderType==HEAD_ENDARC)
1292 {
1293 OpenNext|=Arc.EndArcHead.NextVolume; // Allow open next volume.
1294 break;
1295 }
1296 if (HeaderType==HEAD_FILE)
1297 {
1298 if (!Arc.FileHead.SplitBefore)
1299 {
1300 if (!Arc.FileHead.Solid) // Can start extraction from here.
1301 wcsncpyz(StartName,NextName,ASIZE(StartName));
1302
1303 if (Cmd->IsProcessFile(Arc.FileHead,NULL,MATCH_WILDSUBPATH,0,NULL,0)!=0)
1304 {
1305 Matched=true; // First matched file found, must stop further scan.
1306 break;
1307 }
1308 }
1309 if (Arc.FileHead.SplitAfter)
1310 {
1311 OpenNext=true; // Allow open next volume.
1312 break;
1313 }
1314 }
1315 Arc.SeekToNext();
1316 }
1317 Arc.Close();
1318
1319 if (!OpenNext)
1320 break;
1321
1322 NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering);
1323 }
1324 bool NewStartFound=wcscmp(VolName,StartName)!=0;
1325 if (NewStartFound) // Found a new volume to start extraction.
1326 wcsncpyz(ArcName,StartName,ASIZE(ArcName));
1327
1328 return NewStartFound;
1329}
1330#endif
1331
1332
1333#ifndef SFX_MODULE
1334// Return the first volume name if all volumes preceding the specified
1335// are available. Otherwise return the specified volume name.
1336void CmdExtract::GetFirstVolIfFullSet(const wchar *SrcName,bool NewNumbering,wchar *DestName,size_t DestSize)
1337{
1338 wchar FirstVolName[NM];
1339 VolNameToFirstName(SrcName,FirstVolName,ASIZE(FirstVolName),NewNumbering);
1340 wchar NextName[NM];
1341 wcsncpyz(NextName,FirstVolName,ASIZE(NextName));
1342 wchar ResultName[NM];
1343 wcsncpyz(ResultName,SrcName,ASIZE(ResultName));
1344 while (true)
1345 {
1346 if (wcscmp(SrcName,NextName)==0)
1347 {
1348 wcsncpyz(ResultName,FirstVolName,DestSize);
1349 break;
1350 }
1351 if (!FileExist(NextName))
1352 break;
1353 NextVolumeName(NextName,ASIZE(NextName),!NewNumbering);
1354 }
1355 wcsncpyz(DestName,ResultName,DestSize);
1356}
1357
1358#endif
@ RARFMT50
Definition: archive.hpp:13
@ RARFMT15
Definition: archive.hpp:13
ErrorHandler ErrHandler
wchar FirstVolumeName[NM]
Definition: archive.hpp:144
size_t ReadHeader()
Definition: arcread.cpp:3
bool BrokenHeader
Definition: archive.hpp:128
bool FirstVolume
Definition: archive.hpp:123
bool FailedHeaderDecryption
Definition: archive.hpp:129
HEADER_TYPE GetHeaderType()
Definition: archive.hpp:85
bool IsArchive(bool EnableBroken)
Definition: archive.cpp:126
EndArcHeader EndArcHead
Definition: archive.hpp:105
void SeekToNext()
Definition: archive.cpp:276
bool Solid
Definition: archive.hpp:118
FileHeader FileHead
Definition: archive.hpp:104
void ViewComment()
Definition: arccmt.cpp:169
RARFORMAT Format
Definition: archive.hpp:117
bool IsArcDir()
Definition: arcread.cpp:1299
int64 NextBlockPos
Definition: archive.hpp:115
void ConvertAttributes()
Definition: arcread.cpp:1305
int64 CurBlockPos
Definition: archive.hpp:114
bool NewNumbering
Definition: archive.hpp:124
bool Volume
Definition: archive.hpp:119
size_t Size()
Definition: array.hpp:94
bool ExtractFileCopy(File &New, wchar *ArcName, wchar *NameNew, wchar *NameExisting, size_t NameExistingSize)
Definition: extract.cpp:869
bool FirstFile
Definition: extract.hpp:38
bool ExtrCreateFile(Archive &Arc, File &CurFile)
Definition: extract.cpp:1181
bool ReconstructDone
Definition: extract.hpp:40
bool PrevProcessed
Definition: extract.hpp:52
bool GlobalPassword
Definition: extract.hpp:51
EXTRACT_ARC_CODE ExtractArchive()
Definition: extract.cpp:104
bool ExtractCurrentFile(Archive &Arc, size_t HeaderSize, bool &Repeat)
Definition: extract.cpp:253
~CmdExtract()
Definition: extract.cpp:19
bool DetectStartVolume(const wchar *VolName, bool NewNumbering)
Definition: extract.cpp:1264
static void UnstoreFile(ComprDataIO &DataIO, int64 DestUnpSize)
Definition: extract.cpp:851
void GetFirstVolIfFullSet(const wchar *SrcName, bool NewNumbering, wchar *DestName, size_t DestSize)
Definition: extract.cpp:1336
CommandData * Cmd
Definition: extract.hpp:30
unsigned long MatchedArgs
Definition: extract.hpp:37
wchar ArcName[NM]
Definition: extract.hpp:49
ComprDataIO DataIO
Definition: extract.hpp:32
Unpack * Unp
Definition: extract.hpp:33
void ExtrCreateDir(Archive &Arc, const wchar *ArcFileName)
Definition: extract.cpp:1093
bool CheckUnpVer(Archive &Arc, const wchar *ArcFileName)
Definition: extract.cpp:1233
wchar DestFileName[NM]
Definition: extract.hpp:53
void ExtrPrepareName(Archive &Arc, const wchar *ArcFileName, wchar *DestName, size_t DestSize)
Definition: extract.cpp:901
bool UseExactVolName
Definition: extract.hpp:41
bool PasswordCancelled
Definition: extract.hpp:54
void ExtractArchiveInit(Archive &Arc)
Definition: extract.cpp:82
RarTime StartTime
Definition: extract.hpp:28
void DoExtract()
Definition: extract.cpp:25
bool AllMatchesExact
Definition: extract.hpp:39
unsigned long TotalFileCount
Definition: extract.hpp:34
bool ExtrGetPassword(Archive &Arc, const wchar *ArcFileName)
Definition: extract.cpp:1036
CmdExtract(CommandData *Cmd)
Definition: extract.cpp:3
bool AnySolidDataUnpackedWell
Definition: extract.hpp:47
unsigned long FileCount
Definition: extract.hpp:36
StringList ArcNames
Definition: cmddata.hpp:66
wchar Command[NM+16]
Definition: cmddata.hpp:59
StringList FileArgs
Definition: cmddata.hpp:63
bool GetArcName(wchar *Name, int MaxSize)
Definition: cmddata.cpp:1012
int IsProcessFile(FileHeader &FileHead, bool *ExactMatch, int MatchType, bool Flags, wchar *MatchedArg, uint MatchedArgSize)
Definition: cmdfilter.cpp:279
wchar ArcName[NM]
Definition: cmddata.hpp:61
bool NextVolumeMissing
Definition: rdwrfn.hpp:84
int64 LastArcSize
Definition: rdwrfn.hpp:93
int64 CurUnpWrite
Definition: rdwrfn.hpp:85
void UnpWrite(byte *Addr, size_t Count)
Definition: rdwrfn.cpp:154
void SetCurrentCommand(wchar Cmd)
Definition: rdwrfn.hpp:78
int64 ProcessedArcSize
Definition: rdwrfn.hpp:90
int64 TotalArcSize
Definition: rdwrfn.hpp:95
DataHash UnpHash
Definition: rdwrfn.hpp:99
void SetSkipUnpCRC(bool Skip)
Definition: rdwrfn.hpp:68
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
void AdjustTotalArcSize(Archive *Arc)
Definition: rdwrfn.cpp:296
void SetPackedSizeToRead(int64 Size)
Definition: rdwrfn.hpp:66
bool UnpVolume
Definition: rdwrfn.hpp:83
void SetFiles(File *SrcFile, File *DestFile)
Definition: rdwrfn.cpp:232
void SetTestMode(bool Mode)
Definition: rdwrfn.hpp:67
int64 CurUnpRead
Definition: rdwrfn.hpp:85
DataHash PackedDataHash
Definition: rdwrfn.hpp:97
void Init(HASH_TYPE Type, uint MaxThreads)
Definition: hash.cpp:67
bool Cmp(HashValue *CmpValue, byte *Key)
Definition: hash.cpp:128
void SetErrorCode(RAR_EXIT Code)
Definition: errhnd.cpp:243
void SysErrMsg()
Definition: errhnd.cpp:368
void UnknownMethodMsg(const wchar *ArcName, const wchar *FileName)
Definition: errhnd.cpp:229
uint GetErrorCount()
Definition: errhnd.hpp:59
RAR_EXIT GetErrorCode()
Definition: errhnd.hpp:58
void CreateErrorMsg(const wchar *FileName)
Definition: errhnd.cpp:179
void WriteError(const wchar *ArcName, const wchar *FileName)
Definition: errhnd.cpp:91
void Exit(RAR_EXIT ExitCode)
Definition: errhnd.cpp:236
Definition: file.hpp:57
virtual void Seek(int64 Offset, int Method)
Definition: file.cpp:514
bool Truncate()
Definition: file.cpp:640
void SetHandleType(FILE_HANDLETYPE Type)
Definition: file.hpp:124
static size_t CopyBufferSize()
Definition: file.hpp:148
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
void SetCloseFileTime(RarTime *ftm, RarTime *fta=NULL)
Definition: file.cpp:687
bool IsDevice()
Definition: file.cpp:760
virtual bool Open(const wchar *Name, uint Mode=FMF_READ)
Definition: file.cpp:48
void SetOpenFileTime(RarTime *ftm, RarTime *ftc=NULL, RarTime *fta=NULL)
Definition: file.cpp:663
void Prealloc(int64 Size)
Definition: file.cpp:606
wchar FileName[NM]
Definition: file.hpp:88
void SetAllowDelete(bool Allow)
Definition: file.hpp:134
virtual bool Close()
Definition: file.cpp:241
bool WOpen(const wchar *Name)
Definition: file.cpp:167
static bool FastFind(const wchar *FindMask, FindData *fd, bool GetSymLink=false)
Definition: find.cpp:108
bool SetCompressedAttr
Definition: options.hpp:180
bool FreshFiles
Definition: options.hpp:145
bool IgnoreGeneralAttr
Definition: options.hpp:181
APPENDARCNAME_MODE AppendArcNameToPath
Definition: options.hpp:194
bool DisableNames
Definition: options.hpp:138
bool UpdateFiles
Definition: options.hpp:146
bool ManualPassword
Definition: options.hpp:125
RECURSE_MODE Recurse
Definition: options.hpp:148
bool AllYes
Definition: options.hpp:152
bool KeepBroken
Definition: options.hpp:163
wchar ExtrPath[NM]
Definition: options.hpp:112
SecPassword Password
Definition: options.hpp:121
wchar UseStdin[NM]
Definition: options.hpp:204
EXTTIME_MODE xmtime
Definition: options.hpp:196
wchar ExclArcPath[NM]
Definition: options.hpp:120
EXTTIME_MODE xatime
Definition: options.hpp:198
PATH_EXCL_MODE ExclPath
Definition: options.hpp:147
bool SkipEncrypted
Definition: options.hpp:123
bool ClearArc
Definition: options.hpp:142
bool DisableDone
Definition: options.hpp:137
bool DisablePercentage
Definition: options.hpp:135
uint VersionControl
Definition: options.hpp:193
bool Test
Definition: options.hpp:189
uint Threads
Definition: options.hpp:206
wchar ArcPath[NM]
Definition: options.hpp:119
EXTTIME_MODE xctime
Definition: options.hpp:197
void SetCurrentTime()
Definition: timefn.cpp:305
void Set(const wchar *Psw)
void Clean()
Definition: secpassword.cpp:70
bool IsSet()
Definition: secpassword.hpp:22
void Get(wchar *Psw, size_t MaxSize)
bool GetString(wchar *Str, size_t MaxLength)
Definition: strlist.cpp:49
bool Search(const wchar *Str, bool CaseSensitive)
Definition: strlist.cpp:110
void Rewind()
Definition: strlist.cpp:103
size_t ItemsCount()
Definition: strlist.hpp:24
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
void eprintf(const wchar *fmt,...)
Definition: consio.cpp:135
int Ask(const wchar *AskStr)
Definition: consio.cpp:325
void mprintf(const wchar *fmt,...)
Definition: consio.cpp:118
#define SIZE_PSWCHECK
Definition: crypt.hpp:12
#define ERAR_UNKNOWN_FORMAT
Definition: dll.hpp:11
#define ERAR_BAD_DATA
Definition: dll.hpp:9
#define ERAR_ECREATE
Definition: dll.hpp:13
@ UCM_NEEDPASSWORDW
Definition: dll.hpp:160
@ UCM_NEEDPASSWORD
Definition: dll.hpp:159
#define ERAR_EREFERENCE
Definition: dll.hpp:20
#define ERAR_BAD_PASSWORD
Definition: dll.hpp:21
#define ERAR_MISSING_PASSWORD
Definition: dll.hpp:19
#define ERAR_EOPEN
Definition: dll.hpp:12
@ RARX_USERBREAK
Definition: errhnd.hpp:19
@ RARX_OPEN
Definition: errhnd.hpp:12
@ RARX_BADPWD
Definition: errhnd.hpp:17
@ RARX_CRC
Definition: errhnd.hpp:9
@ RARX_FATAL
Definition: errhnd.hpp:8
@ RARX_CREATE
Definition: errhnd.hpp:15
@ RARX_NOFILES
Definition: errhnd.hpp:16
@ RARX_SUCCESS
Definition: errhnd.hpp:6
@ RARX_WARNING
Definition: errhnd.hpp:7
bool ExtractSymlink(CommandData *Cmd, ComprDataIO &DataIO, Archive &Arc, const wchar *LinkName)
Definition: extinfo.cpp:163
void SetExtraInfo(CommandData *Cmd, Archive &Arc, wchar *Name)
Definition: extinfo.cpp:49
void SetExtraInfo20(CommandData *Cmd, Archive &Arc, wchar *Name)
Definition: extinfo.cpp:22
void SetFileHeaderExtra(CommandData *Cmd, Archive &Arc, wchar *Name)
Definition: extinfo.cpp:66
bool ExtractHardlink(CommandData *Cmd, wchar *NameNew, wchar *NameExisting, size_t NameExistingSize)
Definition: hardlinks.cpp:1
EXTRACT_ARC_CODE
Definition: extract.hpp:4
@ EXTRACT_ARC_NEXT
Definition: extract.hpp:4
@ EXTRACT_ARC_REPEAT
Definition: extract.hpp:4
bool FileCreate(RAROptions *Cmd, File *NewFile, wchar *Name, size_t MaxNameSize, bool *UserReject, int64 FileSize, RarTime *FileTime, bool WriteOnly)
Definition: filcreat.cpp:6
@ FILE_HANDLESTD
Definition: file.hpp:19
uint GetFileAttr(const wchar *Name)
Definition: filefn.cpp:280
bool CreatePath(const wchar *Path, bool SkipLastName, bool Silent)
Definition: filefn.cpp:41
void SetDirTime(const wchar *Name, RarTime *ftm, RarTime *ftc, RarTime *fta)
Definition: filefn.cpp:89
bool IsDir(uint Attr)
Definition: filefn.cpp:218
MKDIR_CODE MakeDir(const wchar *Name, bool SetAttr, uint Attr)
Definition: filefn.cpp:3
bool SetFileAttr(const wchar *Name, uint Attr)
Definition: filefn.cpp:302
bool FileExist(const wchar *Name)
Definition: filefn.cpp:190
MKDIR_CODE
Definition: filefn.hpp:4
@ MKDIR_SUCCESS
Definition: filefn.hpp:4
@ HASH_NONE
Definition: hash.hpp:4
#define VER_UNPACK
Definition: headers.hpp:19
FILE_SYSTEM_REDIRECT
Definition: headers.hpp:108
@ FSREDIR_FILECOPY
Definition: headers.hpp:110
@ FSREDIR_HARDLINK
Definition: headers.hpp:110
@ FSREDIR_WINSYMLINK
Definition: headers.hpp:109
@ FSREDIR_NONE
Definition: headers.hpp:109
@ FSREDIR_UNIXSYMLINK
Definition: headers.hpp:109
@ FSREDIR_JUNCTION
Definition: headers.hpp:109
HEADER_TYPE
Definition: headers.hpp:74
@ HEAD_FILE
Definition: headers.hpp:76
@ HEAD3_OLDSERVICE
Definition: headers.hpp:81
@ HEAD_SERVICE
Definition: headers.hpp:76
@ HEAD_ENDARC
Definition: headers.hpp:77
@ HOST_MSDOS
Definition: headers.hpp:97
#define VER_UNPACK5
Definition: headers.hpp:20
DWORD WinNT()
Definition: isnt.cpp:3
@ WNT_NONE
Definition: isnt.hpp:5
#define MDone
Definition: loclang.hpp:184
#define MExtrTotalErr
Definition: loclang.hpp:224
#define MCreatDir
Definition: loclang.hpp:214
#define MExtrTestFile
Definition: loclang.hpp:216
#define MExtrPrinting
Definition: loclang.hpp:220
#define MYesNoAll
Definition: loclang.hpp:2
#define MExtrSkipFile
Definition: loclang.hpp:215
#define MOk
Definition: loclang.hpp:183
#define MExtrFile
Definition: loclang.hpp:217
#define MNotRAR
Definition: loclang.hpp:176
#define MExtrAllOk
Definition: loclang.hpp:223
#define MUseCurPsw
Definition: loclang.hpp:213
@ MATCH_WILDSUBPATH
Definition: match.hpp:29
@ EXTTIME_NONE
Definition: options.hpp:24
@ EXCL_ABSPATH
Definition: options.hpp:15
@ EXCL_SKIPWHOLEPATH
Definition: options.hpp:12
@ EXCL_BASEPATH
Definition: options.hpp:13
@ APPENDARCNAME_DESTPATH
Definition: options.hpp:64
@ APPENDARCNAME_OWNDIR
Definition: options.hpp:65
@ APPENDARCNAME_NONE
Definition: options.hpp:64
@ APPENDARCNAME_OWNSUBDIR
Definition: options.hpp:64
void SetExt(wchar *Name, const wchar *NewExt, size_t MaxSize)
Definition: pathfn.cpp:74
bool IsWildcard(const wchar *Str)
Definition: pathfn.cpp:121
void MakeNameUsable(char *Name, bool Extended)
Definition: pathfn.cpp:440
wchar * VolNameToFirstName(const wchar *VolName, wchar *FirstName, size_t MaxSize, bool NewNumbering)
Definition: pathfn.cpp:632
wchar * PointToName(const wchar *Path)
Definition: pathfn.cpp:3
wchar * GetWideName(const char *Name, const wchar *NameW, wchar *DestW, size_t DestSize)
Definition: pathfn.cpp:903
bool IsNameUsable(const wchar *Name)
Definition: pathfn.cpp:423
bool IsPathDiv(int Ch)
Definition: pathfn.cpp:134
void NextVolumeName(wchar *ArcName, uint MaxLength, bool OldNumbering)
Definition: pathfn.cpp:359
int ParseVersionFileName(wchar *Name, bool Truncate)
Definition: pathfn.cpp:616
void RemoveNameFromPath(wchar *Path)
Definition: pathfn.cpp:208
wchar * ConvertPath(const wchar *SrcPath, wchar *DestPath, size_t DestSize)
Definition: pathfn.cpp:19
wchar * PointToLastChar(const wchar *Path)
Definition: pathfn.cpp:12
bool CmpExt(const wchar *Name, const wchar *Ext)
Definition: pathfn.cpp:114
void AddEndSlash(wchar *Path, size_t MaxLength)
Definition: pathfn.cpp:170
bool IsDriveDiv(int Ch)
Definition: pathfn.cpp:144
void SlashToNative(const char *SrcName, char *DestName, size_t MaxLength)
Definition: pathfn.hpp:40
#define Min(x, y)
Definition: rardefs.hpp:4
#define MAXPASSWORD
Definition: rardefs.hpp:14
#define ASIZE(x)
Definition: rardefs.hpp:10
wchar_t wchar
Definition: rartypes.hpp:13
int64_t int64
Definition: rartypes.hpp:12
uint64_t uint64
Definition: rartypes.hpp:11
bool RecVolumesRestore(RAROptions *Cmd, const wchar *Name, bool Silent)
Definition: recvol.cpp:8
void RecVolumesTest(RAROptions *Cmd, Archive *Arc, const wchar *Name)
Definition: recvol.cpp:45
const wchar * St(MSGID StringId)
Definition: resource.cpp:8
void cleandata(void *data, size_t size)
Definition: secpassword.cpp:80
void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:275
int wcsnicompc(const wchar *s1, const wchar *s2, size_t n)
Definition: strfn.cpp:252
void wcsncatz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:300
bool NextVolume
Definition: headers.hpp:273
RarTime atime
Definition: headers.hpp:190
HashValue FileHash
Definition: headers.hpp:196
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
byte Method
Definition: headers.hpp:179
bool Encrypted
Definition: headers.hpp:205
uint UnpVer
Definition: headers.hpp:178
byte Salt[SIZE_SALT50]
Definition: headers.hpp:208
bool UsePswCheck
Definition: headers.hpp:210
bool SaltSet
Definition: headers.hpp:207
wchar RedirName[NM]
Definition: headers.hpp:239
bool Version
Definition: headers.hpp:225
RarTime mtime
Definition: headers.hpp:188
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
Definition: find.hpp:9
RarTime mtime
Definition: find.hpp:15
uint64 Size
Definition: find.hpp:11
bool IsDir
Definition: find.hpp:13
HASH_TYPE Type
Definition: hash.hpp:12
void Wait()
Definition: system.cpp:80
@ UIPASSWORD_FILE
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
void uiEolAfterMsg()
Definition: uiconsole.cpp:472
bool uiStartFileExtract(const wchar *FileName, bool Extract, bool Test, bool Skip)
Definition: uiconsole.cpp:66
@ UIERROR_NEWERRAR
Definition: ui.hpp:21
@ UIERROR_FILECOPY
Definition: ui.hpp:15
@ UIERROR_FILECOPYHINT
Definition: ui.hpp:15
@ UIERROR_DIRCREATE
Definition: ui.hpp:16
@ UIERROR_FILEATTR
Definition: ui.hpp:15
@ UIERROR_UNKNOWNEXTRA
Definition: ui.hpp:33
@ UIERROR_CHECKSUM
Definition: ui.hpp:11
@ UIERROR_BADPSW
Definition: ui.hpp:12
@ UIMSG_CORRECTINGNAME
Definition: ui.hpp:49
@ UIMSG_FAT32SIZE
Definition: ui.hpp:51
@ UIWAIT_BADPSW
Definition: ui.hpp:55
@ UIERROR_CHECKSUMENC
Definition: ui.hpp:11
@ UIERROR_NEEDPREVVOL
Definition: ui.hpp:33
@ UIERROR_NOFILESTOEXTRACT
Definition: ui.hpp:32
@ UIERROR_INVALIDNAME
Definition: ui.hpp:29
@ UIERROR_RENAMING
Definition: ui.hpp:21
@ UIERROR_DIRNAMEEXISTS
Definition: ui.hpp:42
@ UIERROR_INCERRCOUNT
Definition: ui.hpp:10
void uiStartArchiveExtract(bool Extract, const wchar *ArcName)
Definition: uiconsole.cpp:60
int wcsicomp(const wchar *s1, const wchar *s2)
Definition: unicode.cpp:425
bool CharToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:85
int toupperw(int ch)
Definition: unicode.cpp:523
bool MergeArchive(Archive &Arc, ComprDataIO *DataIO, bool ShowFileName, wchar Command)
Definition: volume.cpp:10