34
38
Cmd->ArcNames.Rewind();
35
39
while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
41
if (Cmd->ManualPassword)
42
Cmd->Password.Clean(); // Clean user entered password before processing next archive.
39
SecPassword PrevCmdPassword;
40
PrevCmdPassword=Cmd->Password;
42
EXTRACT_ARC_CODE Code=ExtractArchive(Cmd);
44
// Restore Cmd->Password, which could be changed in IsArchive() call
45
// for next header encrypted archive.
46
Cmd->Password=PrevCmdPassword;
45
EXTRACT_ARC_CODE Code=ExtractArchive();
48
46
if (Code!=EXTRACT_ARC_REPEAT)
52
50
DataIO.ProcessedArcSize+=FD.Size;
53
// Clean user entered password. Not really required, just for extra safety.
54
if (Cmd->ManualPassword)
55
Cmd->Password.Clean();
55
57
if (TotalFileCount==0 && Cmd->Command[0]!='I' &&
56
58
ErrHandler.GetErrorCode()!=RARX_BADPWD) // Not in case of wrong archive password.
58
60
if (!PasswordCancelled)
60
mprintf(St(MExtrNoFiles));
61
uiMsg(UIERROR_NOFILESTOEXTRACT,ArcName);
62
62
ErrHandler.SetErrorCode(RARX_NOFILES);
126
121
if (Arc.Volume && !Arc.FirstVolume)
128
123
wchar FirstVolName[NM];
129
VolNameToFirstName(ArcName,FirstVolName,Arc.NewNumbering);
124
VolNameToFirstName(ArcName,FirstVolName,ASIZE(FirstVolName),Arc.NewNumbering);
131
126
// If several volume names from same volume set are specified
132
127
// and current volume is not first in set and first volume is present
162
157
DataIO.TotalArcSize+=VolumeSetSize;
165
ExtractArchiveInit(Cmd,Arc);
160
ExtractArchiveInit(Arc);
167
162
if (*Cmd->Command=='T' || *Cmd->Command=='I')
172
166
if (*Cmd->Command=='I')
173
169
Cmd->DisablePercentage=true;
176
mprintf(St(MExtrTest),ArcName);
178
mprintf(St(MExtracting),ArcName);
173
uiStartArchiveExtract(!Cmd->Test,ArcName);
181
175
Arc.ViewComment();
189
183
bool Repeat=false;
190
if (!ExtractCurrentFile(Cmd,Arc,Size,Repeat))
184
if (!ExtractCurrentFile(Arc,Size,Repeat))
193
187
// If we started extraction from not first volume and need to
213
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,bool &Repeat)
207
bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
215
209
wchar Command=Cmd->Command[0];
216
210
if (HeaderSize==0)
216
// Supposing we unpack an old RAR volume without end of archive record
217
// and last file is not split between volumes.
222
218
if (!MergeArchive(Arc,&DataIO,false,Command))
224
220
ErrHandler.SetErrorCode(RARX_WARNING);
263
259
int MatchType=MATCH_WILDSUBPATH;
265
261
bool EqualNames=false;
266
int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType);
267
bool ExactMatch=MatchNumber!=0;
262
wchar MatchedArg[NM];
263
int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType,MatchedArg,ASIZE(MatchedArg));
264
bool MatchFound=MatchNumber!=0;
268
265
#ifndef SFX_MODULE
269
266
if (Cmd->ExclPath==EXCL_BASEPATH)
274
Cmd->FileArgs.Rewind();
275
if (Cmd->FileArgs.GetString(Cmd->ArcPath,ASIZE(Cmd->ArcPath),MatchNumber-1))
276
*PointToName(Cmd->ArcPath)=0;
268
wcsncpyz(Cmd->ArcPath,MatchedArg,ASIZE(Cmd->ArcPath));
269
*PointToName(Cmd->ArcPath)=0;
270
if (IsWildcard(Cmd->ArcPath)) // Cannot correctly process path*\* masks here.
280
if (ExactMatch && !EqualNames)
274
if (MatchFound && !EqualNames)
281
275
AllMatchesExact=false;
283
277
Arc.ConvertAttributes();
288
282
wchar CurVolName[NM];
289
283
wcsncpyz(CurVolName,ArcName,ASIZE(CurVolName));
290
VolNameToFirstName(ArcName,ArcName,Arc.NewNumbering);
284
VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),Arc.NewNumbering);
292
286
if (wcsicomp(ArcName,CurVolName)!=0 && FileExist(ArcName))
320
313
if (Cmd->VersionControl!=1 && !EqualNames)
322
315
if (Cmd->VersionControl==0)
324
317
int Version=ParseVersionFileName(ArcFileName,false);
325
318
if (Cmd->VersionControl-1==Version)
326
319
ParseVersionFileName(ArcFileName,true);
332
325
if (!Arc.IsArcDir() && Cmd->VersionControl>1)
335
328
DataIO.UnpVolume=Arc.FileHead.SplitAfter;
336
329
DataIO.NextVolumeMissing=false;
341
334
bool SkipSolid=false;
343
336
#ifndef SFX_MODULE
344
if (FirstFile && (ExactMatch || Arc.Solid) && Arc.FileHead.SplitBefore)
337
if (FirstFile && (MatchFound || Arc.Solid) && Arc.FileHead.SplitBefore)
348
Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName);
341
uiMsg(UIERROR_NEEDPREVVOL,Arc.FileName,ArcFileName);
350
343
Cmd->DllError=ERAR_BAD_DATA;
352
345
ErrHandler.SetErrorCode(RARX_OPEN);
360
if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
353
if (MatchFound || (SkipSolid=Arc.Solid)!=0)
355
// First common call of uiStartFileExtract. It is done before overwrite
356
// prompts, so if SkipSolid state is changed below, we'll need to make
357
// additional uiStartFileExtract calls with updated parameters.
358
if (!uiStartFileExtract(ArcFileName,!Cmd->Test,Cmd->Test && Command!='I',SkipSolid))
363
ExtrPrepareName(Cmd,Arc,ArcFileName,DestFileName,ASIZE(DestFileName));
361
ExtrPrepareName(Arc,ArcFileName,DestFileName,ASIZE(DestFileName));
365
363
// DestFileName can be set empty in case of excessive -ap switch.
366
364
ExtrFile=!SkipSolid && *DestFileName!=0 && !Arc.FileHead.SplitBefore;
390
388
if (Arc.FileHead.Encrypted)
393
if (!ExtrDllGetPassword(Cmd))
391
if (!ExtrDllGetPassword())
396
if (!ExtrGetPassword(Cmd,Arc,ArcFileName))
394
if (!ExtrGetPassword(Arc,ArcFileName))
398
396
PasswordCancelled=true;
402
400
// Skip only the current encrypted file if empty password is entered.
403
if (!Password.IsSet())
401
if (!Cmd->Password.IsSet())
405
403
ErrHandler.SetErrorCode(RARX_WARNING);
414
412
if (*Cmd->DllDestName!=0)
416
413
wcsncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
418
// Do we need this code?
419
// if (Cmd->DllOpMode!=RAR_EXTRACT)
424
416
if (!CheckUnpVer(Arc,ArcFileName))
427
ErrHandler.SetErrorCode(RARX_WARNING);
419
ErrHandler.SetErrorCode(RARX_FATAL);
429
421
Cmd->DllError=ERAR_UNKNOWN_FORMAT;
440
432
// Overwrite prompt for symbolic and hard links.
441
433
bool UserReject=false;
442
434
if (FileExist(DestFileName) && !UserReject)
443
FileCreate(Cmd,NULL,DestFileName,ASIZE(DestFileName),Cmd->Overwrite,&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime);
435
FileCreate(Cmd,NULL,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime);
451
443
if (!ExtrFile || Command=='P' || Command=='I' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
453
445
TotalFileCount++;
454
ExtrCreateDir(Cmd,Arc,ArcFileName);
446
ExtrCreateDir(Arc,ArcFileName);
458
450
if (ExtrFile) // Create files and file copies (FSREDIR_FILECOPY).
459
ExtrFile=ExtrCreateFile(Cmd,Arc,CurFile);
451
ExtrFile=ExtrCreateFile(Arc,CurFile);
461
453
if (!ExtrFile && Arc.Solid)
458
// We changed SkipSolid, so we need to call uiStartFileExtract
459
// with "Skip" parameter to change the operation status
460
// from "extracting" to "skipping". For example, it can be necessary
461
// if user answered "No" to overwrite prompt when unpacking
463
if (!uiStartFileExtract(ArcFileName,false,false,true))
473
472
if (!TestMode && Command!='P' && CurFile.IsDevice())
475
Log(Arc.FileName,St(MInvalidName),DestFileName);
474
uiMsg(UIERROR_INVALIDNAME,Arc.FileName,DestFileName);
476
475
ErrHandler.WriteError(Arc.FileName,DestFileName);
478
477
TotalFileCount++;
505
SecPassword FilePassword=Password;
504
SecPassword FilePassword=Cmd->Password;
506
505
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
507
506
ConvertDosPassword(Arc,FilePassword);
520
519
memcmp(Arc.FileHead.PswCheck,PswCheck,SIZE_PSWCHECK)!=0 &&
521
520
!Arc.BrokenHeader)
523
Log(Arc.FileName,St(MWrongPassword));
522
uiMsg(UIERROR_BADPSW,Arc.FileName);
524
523
ErrHandler.SetErrorCode(RARX_BADPWD);
525
524
WrongPassword=true;
532
531
DataIO.SetFiles(&Arc,&CurFile);
533
532
DataIO.SetTestMode(TestMode);
534
533
DataIO.SetSkipUnpCRC(SkipSolid);
535
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
536
if (!TestMode && !WrongPassword && !Arc.BrokenHeader &&
537
Arc.FileHead.UnpSize>0xffffffff && (Fat32 || !NotFat32))
539
if (!Fat32) // Not detected yet.
540
NotFat32=!(Fat32=IsFAT(Cmd->ExtrPath));
542
uiMsg(UIMSG_FAT32SIZE); // Inform user about FAT32 size limit.
535
546
if (!TestMode && !WrongPassword && !Arc.BrokenHeader &&
536
547
(Arc.FileHead.PackSize<<11)>Arc.FileHead.UnpSize &&
537
548
(Arc.FileHead.UnpSize<100000000 || Arc.FileLength()>Arc.FileHead.PackSize))
542
553
bool FileCreateMode=!TestMode && !SkipSolid && Command!='P';
543
554
bool ShowChecksum=true; // Display checksum verification result.
556
bool LinkSuccess=true; // Assume success for test mode.
547
559
FILE_SYSTEM_REDIRECT Type=Arc.FileHead.RedirType;
549
bool LinkSuccess=true; // Assume success for test mode.
550
561
if (Type==FSREDIR_HARDLINK || Type==FSREDIR_FILECOPY)
552
563
wchar NameExisting[NM];
553
ExtrPrepareName(Cmd,Arc,Arc.FileHead.RedirName,NameExisting,ASIZE(NameExisting));
564
ExtrPrepareName(Arc,Arc.FileHead.RedirName,NameExisting,ASIZE(NameExisting));
554
565
if (FileCreateMode && *NameExisting!=0) // *NameExisting can be 0 in case of excessive -ap switch.
555
566
if (Type==FSREDIR_HARDLINK)
556
567
LinkSuccess=ExtractHardlink(DestFileName,NameExisting,ASIZE(NameExisting));
588
597
UnstoreFile(DataIO,Arc.FileHead.UnpSize);
601
// malloc and new do not report memory allocation errors
602
// in Android, so if free memory is set, check it here
603
// trying to prevent crash.
604
if (Cmd->FreeMem!=0 && Cmd->FreeMem < Arc.FileHead.WinSize)
605
throw std::bad_alloc();
591
607
Unp->Init(Arc.FileHead.WinSize,Arc.FileHead.Solid);
592
608
Unp->SetDestSize(Arc.FileHead.UnpSize);
593
609
#ifndef SFX_MODULE
601
617
Arc.SeekToNext();
603
bool ValidCRC=DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL);
619
// We check for "split after" flag to detect partially extracted files
620
// from incomplete volume sets. For them file header contains packed
621
// data hash, which must not be compared against unpacked data hash
622
// to prevent accidental match. Moreover, for -m0 volumes packed data
623
// hash would match truncated unpacked data hash and lead to fake "OK"
624
// in incomplete volume set.
625
bool ValidCRC=!Arc.FileHead.SplitAfter && DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL);
605
627
// We set AnySolidDataUnpackedWell to true if we found at least one
606
628
// valid non-zero solid file in preceding solid stream. If it is true
615
637
bool BrokenFile=false;
617
639
// Checksum is not calculated in skip solid mode for performance reason.
640
if (!SkipSolid && ShowChecksum)
620
642
if (!WrongPassword && ValidCRC)
623
if (Command!='P' && Command!='I' && ShowChecksum)
645
if (Command!='P' && Command!='I')
624
646
mprintf(L"%s%s ",Cmd->DisablePercentage ? L" ":L"\b\b\b\b\b ",
625
647
Arc.FileHead.FileHash.Type==HASH_NONE ? L" ?":St(MOk));
630
652
if (!WrongPassword)
631
653
if (Arc.FileHead.Encrypted && (!Arc.FileHead.UsePswCheck ||
632
654
Arc.BrokenHeader) && !AnySolidDataUnpackedWell)
634
Log(Arc.FileName,St(MEncrBadCRC),ArcFileName);
655
uiMsg(UIERROR_CHECKSUMENC,Arc.FileName,ArcFileName);
638
Log(Arc.FileName,St(MCRCFailed),ArcFileName);
657
uiMsg(UIERROR_CHECKSUM,Arc.FileName,ArcFileName);
641
659
ErrHandler.SetErrorCode(RARX_CRC);
643
661
// If we already have ERAR_EOPEN as result of missing volume,
644
662
// we should not replace it with less precise ERAR_BAD_DATA.
645
663
if (Cmd->DllError!=ERAR_EOPEN)
646
Cmd->DllError=ERAR_BAD_DATA;
664
Cmd->DllError=WrongPassword ? ERAR_BAD_PASSWORD : ERAR_BAD_DATA;
655
673
if (!TestMode && !WrongPassword && (Command=='X' || Command=='E') &&
656
(!LinkEntry || Arc.FileHead.RedirType==FSREDIR_FILECOPY) &&
674
(!LinkEntry || Arc.FileHead.RedirType==FSREDIR_FILECOPY && LinkSuccess) &&
657
675
(!BrokenFile || Cmd->KeepBroken))
659
677
// We could preallocate more space that really written to broken file.
684
702
CurFile.SetCloseFileTime(
685
703
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
686
704
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
687
if (!Cmd->IgnoreGeneralAttr)
688
SetFileAttr(CurFile.FileName,Arc.FileHead.FileAttr);
705
if (!Cmd->IgnoreGeneralAttr && !SetFileAttr(CurFile.FileName,Arc.FileHead.FileAttr))
706
uiMsg(UIERROR_FILEATTR,Arc.FileName,CurFile.FileName);
689
708
PrevExtracted=true;
695
714
if (DataIO.NextVolumeMissing)
707
726
void CmdExtract::UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize)
709
Array<byte> Buffer(0x100000);
728
// 512 KB and larger buffer reported to reduce performance on old XP
729
// computers with WDC WD2000JD HDD. According to test made by user
730
// 256 KB buffer is optimal.
731
Array<byte> Buffer(0x40000);
712
734
uint Code=DataIO.UnpRead(&Buffer[0],Buffer.Size());
723
745
bool CmdExtract::ExtractFileCopy(File &New,wchar *ArcName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
726
UnixSlashToDos(NameExisting,NameExisting,NameExistingSize);
728
DosSlashToUnix(NameExisting,NameExisting,NameExistingSize);
747
SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.
731
if (!Existing.Open(NameExisting))
750
if (!Existing.WOpen(NameExisting))
733
ErrHandler.OpenErrorMsg(ArcName,NameExisting);
734
Log(ArcName,St(MCopyError),NameExisting,NameNew);
735
Log(ArcName,St(MCopyErrorHint));
752
uiMsg(UIERROR_FILECOPY,ArcName,NameExisting,NameNew);
753
uiMsg(UIERROR_FILECOPYHINT,ArcName);
755
Cmd->DllError=ERAR_EREFERENCE;
756
void CmdExtract::ExtrPrepareName(CommandData *Cmd,Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize)
777
void CmdExtract::ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize)
758
779
wcsncpyz(DestName,Cmd->ExtrPath,DestSize);
769
790
if (Cmd->AppendArcNameToPath)
771
792
wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize);
772
SetExt(DestName,NULL);
793
SetExt(DestName,NULL,DestSize);
773
794
AddEndSlash(DestName,DestSize);
845
866
Cmd->Password.Set(PasswordW);
846
867
cleandata(PasswordW,sizeof(PasswordW));
868
Cmd->ManualPassword=true;
848
870
if (!Cmd->Password.IsSet())
851
Password=Cmd->Password;
858
bool CmdExtract::ExtrGetPassword(CommandData *Cmd,Archive &Arc,const wchar *ArcFileName)
879
bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
860
if (!Password.IsSet())
881
if (!Cmd->Password.IsSet())
862
if (!GetPassword(PASSWORD_FILE,ArcFileName,&Password))
883
if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password) || !Cmd->Password.IsSet())
885
// Suppress "test is ok" message in GUI if user entered
886
// an empty password or cancelled a password prompt.
887
uiMsg(UIERROR_INCERRCOUNT);
891
Cmd->ManualPassword=true;
867
893
#if !defined(GUI) && !defined(SILENT)
869
895
if (!PasswordAll && !Arc.FileHead.Solid)
871
897
eprintf(St(MUseCurPsw),ArcFileName);
872
switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll)))
898
switch(Cmd->AllYes ? 1 : Ask(St(MYesNoAll)))
875
901
ErrHandler.Exit(RARX_USERBREAK);
877
if (!GetPassword(PASSWORD_FILE,ArcFileName,&Password))
903
if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password))
896
922
// We need the password in OEM encoding if file was encrypted by
897
923
// native RAR/DOS (not extender based). Let's make the conversion.
898
924
wchar PlainPsw[MAXPASSWORD];
899
Password.Get(PlainPsw,ASIZE(PlainPsw));
925
Cmd->Password.Get(PlainPsw,ASIZE(PlainPsw));
900
926
char PswA[MAXPASSWORD];
901
927
CharToOemBuffW(PlainPsw,PswA,ASIZE(PswA));
902
928
PswA[ASIZE(PswA)-1]=0;
930
956
// File with name same as this directory exists. Propose user
931
957
// to overwrite it.
933
FileCreate(Cmd,NULL,DestFileName,ASIZE(DestFileName),Cmd->Overwrite,&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime);
959
FileCreate(Cmd,NULL,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime);
938
964
CreatePath(DestFileName,true);
939
965
MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
966
if (MDCode!=MKDIR_SUCCESS)
968
wchar OrigName[ASIZE(DestFileName)];
969
wcsncpyz(OrigName,DestFileName,ASIZE(OrigName));
970
MakeNameUsable(DestFileName,true);
971
CreatePath(DestFileName,true);
972
MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
974
if (MDCode==MKDIR_SUCCESS)
975
uiMsg(UIERROR_RENAMING,Arc.FileName,OrigName,DestFileName);
942
980
if (MDCode==MKDIR_SUCCESS)
959
Log(Arc.FileName,St(MExtrErrMkDir),DestFileName);
960
ErrHandler.CheckLongPathErrMsg(DestFileName);
997
uiMsg(UIERROR_DIRCREATE,Arc.FileName,DestFileName);
961
998
ErrHandler.SysErrMsg();
963
1000
Cmd->DllError=ERAR_ECREATE;
982
bool CmdExtract::ExtrCreateFile(CommandData *Cmd,Archive &Arc,File &CurFile)
1019
bool CmdExtract::ExtrCreateFile(Archive &Arc,File &CurFile)
984
1021
bool Success=true;
985
1022
wchar Command=Cmd->Command[0];
992
1029
bool UserReject;
993
1030
// Specify "write only" mode to avoid OpenIndiana NAS problems
994
1031
// with SetFileTime and read+write files.
995
if (!FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),Cmd->Overwrite,&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
1032
if (!FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
998
1035
if (!UserReject)
1000
1037
ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
1001
ErrHandler.SetErrorCode(RARX_CREATE);
1003
1039
Cmd->DllError=ERAR_ECREATE;
1005
1041
if (!IsNameUsable(DestFileName))
1007
Log(Arc.FileName,St(MCorrectingName));
1043
uiMsg(UIMSG_CORRECTINGNAME,Arc.FileName);
1008
1045
wchar OrigName[ASIZE(DestFileName)];
1009
1046
wcsncpyz(OrigName,DestFileName,ASIZE(OrigName));
1011
1048
MakeNameUsable(DestFileName,true);
1013
1050
CreatePath(DestFileName,true);
1014
if (FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),Cmd->Overwrite,&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
1051
if (FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
1016
1053
#ifndef SFX_MODULE
1017
Log(Arc.FileName,St(MRenaming),OrigName,DestFileName);
1054
uiMsg(UIERROR_RENAMING,Arc.FileName,OrigName,DestFileName);
1052
Log(Arc.FileName,St(MUnknownMeth),ArcFileName);
1054
// Log(Arc.FileName,St(MVerRequired),Arc.FileHead.UnpVer/10,Arc.FileHead.UnpVer%10);
1055
Log(Arc.FileName,St(MNewerRAR));
1088
ErrHandler.UnknownMethodMsg(Arc.FileName,ArcFileName);
1089
uiMsg(UIERROR_NEWERRAR,Arc.FileName);
1059
1091
return !WrongVer;