recvol.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "rar.hpp"
  2. #include "recvol3.cpp"
  3. #include "recvol5.cpp"
  4. bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent)
  5. {
  6. Archive Arc(Cmd);
  7. if (!Arc.Open(Name))
  8. {
  9. if (!Silent)
  10. ErrHandler.OpenErrorMsg(Name);
  11. return false;
  12. }
  13. RARFORMAT Fmt=RARFMT15;
  14. if (Arc.IsArchive(true))
  15. Fmt=Arc.Format;
  16. else
  17. {
  18. byte Sign[REV5_SIGN_SIZE];
  19. Arc.Seek(0,SEEK_SET);
  20. if (Arc.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0)
  21. Fmt=RARFMT50;
  22. }
  23. Arc.Close();
  24. // We define RecVol as local variable for proper stack unwinding when
  25. // handling exceptions. So it can close and delete files on Cancel.
  26. if (Fmt==RARFMT15)
  27. {
  28. RecVolumes3 RecVol(Cmd,false);
  29. return RecVol.Restore(Cmd,Name,Silent);
  30. }
  31. else
  32. {
  33. RecVolumes5 RecVol(Cmd,false);
  34. return RecVol.Restore(Cmd,Name,Silent);
  35. }
  36. }
  37. void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name)
  38. {
  39. wchar RevName[NM];
  40. *RevName=0;
  41. if (Arc!=NULL)
  42. {
  43. // We received .rar or .exe volume as a parameter, trying to find
  44. // the matching .rev file number 1.
  45. bool NewNumbering=Arc->NewNumbering;
  46. wchar ArcName[NM];
  47. wcsncpyz(ArcName,Name,ASIZE(ArcName));
  48. wchar *VolNumStart=VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),NewNumbering);
  49. wchar RecVolMask[NM];
  50. wcsncpyz(RecVolMask,ArcName,ASIZE(RecVolMask));
  51. size_t BaseNamePartLength=VolNumStart-ArcName;
  52. wcsncpyz(RecVolMask+BaseNamePartLength,L"*.rev",ASIZE(RecVolMask)-BaseNamePartLength);
  53. FindFile Find;
  54. Find.SetMask(RecVolMask);
  55. FindData RecData;
  56. while (Find.Next(&RecData))
  57. {
  58. wchar *Num=GetVolNumPart(RecData.Name);
  59. if (*Num!='1') // Name must have "0...01" numeric part.
  60. continue;
  61. bool FirstVol=true;
  62. while (--Num>=RecData.Name && IsDigit(*Num))
  63. if (*Num!='0')
  64. {
  65. FirstVol=false;
  66. break;
  67. }
  68. if (FirstVol)
  69. {
  70. wcsncpyz(RevName,RecData.Name,ASIZE(RevName));
  71. Name=RevName;
  72. break;
  73. }
  74. }
  75. if (*RevName==0) // First .rev file not found.
  76. return;
  77. }
  78. File RevFile;
  79. if (!RevFile.Open(Name))
  80. {
  81. ErrHandler.OpenErrorMsg(Name); // It also sets RARX_OPEN.
  82. return;
  83. }
  84. mprintf(L"\n");
  85. byte Sign[REV5_SIGN_SIZE];
  86. bool Rev5=RevFile.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0;
  87. RevFile.Close();
  88. if (Rev5)
  89. {
  90. RecVolumes5 RecVol(Cmd,true);
  91. RecVol.Test(Cmd,Name);
  92. }
  93. else
  94. {
  95. RecVolumes3 RecVol(Cmd,true);
  96. RecVol.Test(Cmd,Name);
  97. }
  98. }