"Fossies" - the Fresh Open Source Software Archive

Member "unrar/volume.cpp" (4 May 2022, 7734 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "volume.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 6.1.3_vs_6.1.4.

    1 #include "rar.hpp"
    2 
    3 #ifdef RARDLL
    4 static bool DllVolChange(RAROptions *Cmd,wchar *NextName,size_t NameSize);
    5 static bool DllVolNotify(RAROptions *Cmd,wchar *NextName);
    6 #endif
    7 
    8 
    9 
   10 bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,wchar Command)
   11 {
   12   RAROptions *Cmd=Arc.GetRAROptions();
   13 
   14   HEADER_TYPE HeaderType=Arc.GetHeaderType();
   15   FileHeader *hd=HeaderType==HEAD_SERVICE ? &Arc.SubHead:&Arc.FileHead;
   16   bool SplitHeader=(HeaderType==HEAD_FILE || HeaderType==HEAD_SERVICE) &&
   17                    hd->SplitAfter;
   18 
   19   if (DataIO!=NULL && SplitHeader)
   20   {
   21     bool PackedHashPresent=Arc.Format==RARFMT50 || 
   22          hd->UnpVer>=20 && hd->FileHash.CRC32!=0xffffffff;
   23     if (PackedHashPresent && 
   24         !DataIO->PackedDataHash.Cmp(&hd->FileHash,hd->UseHashKey ? hd->HashKey:NULL))
   25       uiMsg(UIERROR_CHECKSUMPACKED, Arc.FileName, hd->FileName);
   26   }
   27 
   28   bool PrevVolEncrypted=Arc.Encrypted;
   29 
   30   int64 PosBeforeClose=Arc.Tell();
   31 
   32   if (DataIO!=NULL)
   33     DataIO->ProcessedArcSize+=DataIO->LastArcSize;
   34 
   35 
   36   Arc.Close();
   37 
   38   wchar NextName[NM];
   39   wcsncpyz(NextName,Arc.FileName,ASIZE(NextName));
   40   NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering);
   41 
   42 #if !defined(SFX_MODULE) && !defined(RARDLL)
   43   bool RecoveryDone=false;
   44 #endif
   45   bool OldSchemeTested=false;
   46 
   47   bool FailedOpen=false; // No more next volume open attempts if true.
   48 #if !defined(SILENT)
   49   // In -vp mode we force the pause before next volume even if it is present
   50   // and even if we are on the hard disk. It is important when user does not
   51   // want to process partially downloaded volumes preliminary.
   52   // 2022.01.11: In WinRAR 6.10 beta versions we tried to ignore VolumePause
   53   // if we could open the next volume with FMF_OPENEXCLUSIVE. But another
   54   // developer asked us to return the previous behavior and always prompt
   55   // for confirmation. They want to control when unrar continues, because
   56   // the next file might not be fully decoded yet. They write chunks of data
   57   // and then close the file again until the next chunk comes in.
   58 
   59   if (Cmd->VolumePause && !uiAskNextVolume(NextName,ASIZE(NextName)))
   60     FailedOpen=true;
   61 #endif
   62 
   63   uint OpenMode = Cmd->OpenShared ? FMF_OPENSHARED : 0;
   64 
   65   if (!FailedOpen)
   66     while (!Arc.Open(NextName,OpenMode))
   67     {
   68       // We need to open a new volume which size was not calculated
   69       // in total size before, so we cannot calculate the total progress
   70       // anymore. Let's reset the total size to zero and stop 
   71       // the total progress.
   72       if (DataIO!=NULL)
   73         DataIO->TotalArcSize=0;
   74 
   75       if (!OldSchemeTested)
   76       {
   77         // Checking for new style volumes renamed by user to old style
   78         // name format. Some users did it for unknown reason.
   79         wchar AltNextName[NM];
   80         wcsncpyz(AltNextName,Arc.FileName,ASIZE(AltNextName));
   81         NextVolumeName(AltNextName,ASIZE(AltNextName),true);
   82         OldSchemeTested=true;
   83         if (Arc.Open(AltNextName,OpenMode))
   84         {
   85           wcsncpyz(NextName,AltNextName,ASIZE(NextName));
   86           break;
   87         }
   88       }
   89 #ifdef RARDLL
   90       if (!DllVolChange(Cmd,NextName,ASIZE(NextName)))
   91       {
   92         FailedOpen=true;
   93         break;
   94       }
   95 #else // !RARDLL
   96 
   97 #ifndef SFX_MODULE
   98       if (!RecoveryDone)
   99       {
  100         RecVolumesRestore(Cmd,Arc.FileName,true);
  101         RecoveryDone=true;
  102         continue;
  103       }
  104 #endif
  105 
  106       if (!Cmd->VolumePause && !IsRemovable(NextName))
  107       {
  108         FailedOpen=true;
  109         break;
  110       }
  111 #ifndef SILENT
  112       if (Cmd->AllYes || !uiAskNextVolume(NextName,ASIZE(NextName)))
  113 #endif
  114       {
  115         FailedOpen=true;
  116         break;
  117       }
  118 
  119 #endif // RARDLL
  120     }
  121   
  122   if (FailedOpen)
  123   {
  124     uiMsg(UIERROR_MISSINGVOL,NextName);
  125     Arc.Open(Arc.FileName,OpenMode);
  126     Arc.Seek(PosBeforeClose,SEEK_SET);
  127     return false;
  128   }
  129 
  130   if (Command=='T' || Command=='X' || Command=='E')
  131     mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName);
  132 
  133 
  134   Arc.CheckArc(true);
  135 #ifdef RARDLL
  136   if (!DllVolNotify(Cmd,NextName))
  137     return false;
  138 #endif
  139 
  140   if (Arc.Encrypted!=PrevVolEncrypted)
  141   {
  142     // There is no legitimate reason for encrypted header state to be
  143     // changed in the middle of volume sequence. So we abort here to prevent
  144     // replacing an encrypted header volume to unencrypted and adding
  145     // unexpected files by third party to encrypted extraction.
  146     uiMsg(UIERROR_BADARCHIVE,Arc.FileName);
  147     ErrHandler.Exit(RARX_FATAL);
  148   }
  149 
  150   if (SplitHeader)
  151     Arc.SearchBlock(HeaderType);
  152   else
  153     Arc.ReadHeader();
  154   if (Arc.GetHeaderType()==HEAD_FILE)
  155   {
  156     Arc.ConvertAttributes();
  157     Arc.Seek(Arc.NextBlockPos-Arc.FileHead.PackSize,SEEK_SET);
  158   }
  159   if (ShowFileName && !Cmd->DisableNames)
  160   {
  161     mprintf(St(MExtrPoints),Arc.FileHead.FileName);
  162     if (!Cmd->DisablePercentage)
  163       mprintf(L"     ");
  164   }
  165   if (DataIO!=NULL)
  166   {
  167     if (HeaderType==HEAD_ENDARC)
  168       DataIO->UnpVolume=false;
  169     else
  170     {
  171       DataIO->UnpVolume=hd->SplitAfter;
  172       DataIO->SetPackedSizeToRead(hd->PackSize);
  173     }
  174 
  175     DataIO->AdjustTotalArcSize(&Arc);
  176       
  177     // Reset the size of packed data read from current volume. It is used
  178     // to display the total progress and preceding volumes are already
  179     // compensated with ProcessedArcSize, so we need to reset this variable.
  180     DataIO->CurUnpRead=0;
  181 
  182     DataIO->PackedDataHash.Init(hd->FileHash.Type,Cmd->Threads);
  183   }
  184   return true;
  185 }
  186 
  187 
  188 
  189 
  190 
  191 
  192 #ifdef RARDLL
  193 bool DllVolChange(RAROptions *Cmd,wchar *NextName,size_t NameSize)
  194 {
  195   bool DllVolChanged=false,DllVolAborted=false;
  196 
  197   if (Cmd->Callback!=NULL)
  198   {
  199     wchar OrgNextName[NM];
  200     wcsncpyz(OrgNextName,NextName,ASIZE(OrgNextName));
  201     if (Cmd->Callback(UCM_CHANGEVOLUMEW,Cmd->UserData,(LPARAM)NextName,RAR_VOL_ASK)==-1)
  202       DllVolAborted=true;
  203     else
  204       if (wcscmp(OrgNextName,NextName)!=0)
  205         DllVolChanged=true;
  206       else
  207       {
  208         char NextNameA[NM],OrgNextNameA[NM];
  209         WideToChar(NextName,NextNameA,ASIZE(NextNameA));
  210         strncpyz(OrgNextNameA,NextNameA,ASIZE(OrgNextNameA));
  211         if (Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LPARAM)NextNameA,RAR_VOL_ASK)==-1)
  212           DllVolAborted=true;
  213         else
  214           if (strcmp(OrgNextNameA,NextNameA)!=0)
  215           {
  216             // We can damage some Unicode characters by U->A->U conversion,
  217             // so set Unicode name only if we see that ANSI name is changed.
  218             CharToWide(NextNameA,NextName,NameSize);
  219             DllVolChanged=true;
  220           }
  221       }
  222   }
  223   if (!DllVolChanged && Cmd->ChangeVolProc!=NULL)
  224   {
  225     char NextNameA[NM];
  226     WideToChar(NextName,NextNameA,ASIZE(NextNameA));
  227     int RetCode=Cmd->ChangeVolProc(NextNameA,RAR_VOL_ASK);
  228     if (RetCode==0)
  229       DllVolAborted=true;
  230     else
  231       CharToWide(NextNameA,NextName,NameSize);
  232   }
  233 
  234   // We quit only on 'abort' condition, but not on 'name not changed'.
  235   // It is legitimate for program to return the same name when waiting
  236   // for currently non-existent volume.
  237   // Also we quit to prevent an infinite loop if no callback is defined.
  238   if (DllVolAborted || Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL)
  239   {
  240     Cmd->DllError=ERAR_EOPEN;
  241     return false;
  242   }
  243   return true;
  244 }
  245 #endif
  246 
  247 
  248 #ifdef RARDLL
  249 bool DllVolNotify(RAROptions *Cmd,wchar *NextName)
  250 {
  251   char NextNameA[NM];
  252   WideToChar(NextName,NextNameA,ASIZE(NextNameA));
  253   if (Cmd->Callback!=NULL)
  254   {
  255     if (Cmd->Callback(UCM_CHANGEVOLUMEW,Cmd->UserData,(LPARAM)NextName,RAR_VOL_NOTIFY)==-1)
  256       return false;
  257     if (Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LPARAM)NextNameA,RAR_VOL_NOTIFY)==-1)
  258       return false;
  259   }
  260   if (Cmd->ChangeVolProc!=NULL)
  261   {
  262     int RetCode=Cmd->ChangeVolProc(NextNameA,RAR_VOL_NOTIFY);
  263     if (RetCode==0)
  264       return false;
  265   }
  266   return true;
  267 }
  268 #endif