Exemplo n.º 1
0
bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent)
{
  Archive Arc(Cmd);
  if (!Arc.Open(Name))
  {
    if (!Silent)
      ErrHandler.OpenErrorMsg(Name);
    return false;
  }

  RARFORMAT Fmt=RARFMT15;
  if (Arc.IsArchive(true))
    Fmt=Arc.Format;
  else
  {
    byte Sign[REV5_SIGN_SIZE];
    Arc.Seek(0,SEEK_SET);
    if (Arc.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0)
      Fmt=RARFMT50;
  }
  Arc.Close();

  // We define RecVol as local variable for proper stack unwinding when
  // handling exceptions. So it can close and delete files on Cancel.
  if (Fmt==RARFMT15)
  {
    RecVolumes3 RecVol(false);
    return RecVol.Restore(Cmd,Name,Silent);
  }
  else
  {
    RecVolumes5 RecVol(false);
    return RecVol.Restore(Cmd,Name,Silent);
  }
}
Exemplo n.º 2
0
void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name)
{
  wchar RevName[NM];
  *RevName=0;
  if (Arc!=NULL)
  {
    // We received .rar or .exe volume as a parameter, trying to find
    // the matching .rev file number 1.
    bool NewNumbering=Arc->NewNumbering;

    wchar ArcName[NM];
    wcsncpyz(ArcName,Name,ASIZE(ArcName));

    wchar *VolNumStart=VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),NewNumbering);
    wchar RecVolMask[NM];
    wcsncpyz(RecVolMask,ArcName,ASIZE(RecVolMask));
    size_t BaseNamePartLength=VolNumStart-ArcName;
    wcsncpyz(RecVolMask+BaseNamePartLength,L"*.rev",ASIZE(RecVolMask)-BaseNamePartLength);

    FindFile Find;
    Find.SetMask(RecVolMask);
    FindData RecData;

    while (Find.Next(&RecData))
    {
      wchar *Num=GetVolNumPart(RecData.Name);
      if (*Num!='1') // Name must have "0...01" numeric part.
        continue;
      bool FirstVol=true;
      while (--Num>=RecData.Name && IsDigit(*Num))
        if (*Num!='0')
        {
          FirstVol=false;
          break;
        }
      if (FirstVol)
      {
        wcsncpyz(RevName,RecData.Name,ASIZE(RevName));
        Name=RevName;
        break;
      }
    }
    if (*RevName==0) // First .rev file not found.
      return;
  }
  
  File RevFile;
  if (!RevFile.Open(Name))
  {
    ErrHandler.OpenErrorMsg(Name); // It also sets RARX_OPEN.
    return;
  }
#ifndef GUI
  mprintf(L"\n");
#endif
  byte Sign[REV5_SIGN_SIZE];
  bool Rev5=RevFile.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0;
  RevFile.Close();
  if (Rev5)
  {
    RecVolumes5 RecVol(true);
    RecVol.Test(Cmd,Name);
  }
  else
  {
    RecVolumes3 RecVol(true);
    RecVol.Test(Cmd,Name);
  }
}
Exemplo n.º 3
0
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command)
{
	RAROptions *Cmd=Arc.GetRAROptions();

	int HeaderType=Arc.GetHeaderType();
	FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd;
	bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) &&
		(hd->Flags & LHD_SPLIT_AFTER)!=0;

	if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 &&
		hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC)
	{
		Log(Arc.m_sParfileName, Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName);
	}

	Int64 PosBeforeClose=Arc.Tell();
	Arc.Close();

	char NextName[NM];
	strcpy(NextName,Arc.FileName);
	NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);

#if !defined(SFX_MODULE) && !defined(RARDLL)
	bool RecoveryDone=false;
#endif
	bool FailedOpen=false,OldSchemeTested=false;

	while (!Arc.Open(NextName))
	{
		if (!OldSchemeTested)
		{
			char AltNextName[NM];
			strcpy(AltNextName,Arc.FileName);
			NextVolumeName(AltNextName,true);
			OldSchemeTested=true;
			if (Arc.Open(AltNextName))
			{
				strcpy(NextName,AltNextName);
				break;
			}
		}
#ifdef RARDLL
		if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL ||
			Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1)
		{
			Cmd->DllError=ERAR_EOPEN;
			FailedOpen=true;
			break;
		}
		if (Cmd->ChangeVolProc!=NULL)
		{
#ifdef _WIN_32
			_EBX=_ESP;
#endif
			int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK);
#ifdef _WIN_32
			_ESP=_EBX;
#endif
			if (RetCode==0)
			{
				Cmd->DllError=ERAR_EOPEN;
				FailedOpen=true;
				break;
			}
		}
#else

#if !defined(SFX_MODULE) && !defined(_WIN_CE)
		if (!RecoveryDone)
		{
			RecVolumes RecVol(Arc.m_pvRarFiles, Arc.m_sParfileName);
			RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true);
			RecoveryDone=true;
			continue;
		}
#endif

#ifndef GUI
		if (!Cmd->VolumePause && !IsRemovable(NextName))
		{
			Log(Arc.m_sParfileName,Arc.FileName,St(MAbsNextVol),NextName);
			FailedOpen=true;
			break;
		}
#endif
#ifndef SILENT
		if (Cmd->AllYes || !AskNextVol(Arc.m_pvRarFiles, Arc.m_sParfileName, NextName))
#endif
		{
			FailedOpen=true;
			break;
		}
#endif
	}
	if (FailedOpen)
	{
		Arc.Open(Arc.FileName,Arc.FileNameW);
		Arc.Seek(PosBeforeClose,SEEK_SET);
		return(false);
	}
	Arc.CheckArc(true);
#ifdef RARDLL
	if (Cmd->Callback!=NULL &&
		Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_NOTIFY)==-1)
		return(false);
	if (Cmd->ChangeVolProc!=NULL)
	{
#ifdef _WIN_32
		_EBX=_ESP;
#endif
		int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_NOTIFY);
#ifdef _WIN_32
		_ESP=_EBX;
#endif
		if (RetCode==0)
			return(false);
	}
#endif

	if (Command=='T' || Command=='X' || Command=='E')
		mprintf(Arc.m_sParfileName,St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName);
	if (SplitHeader)
		Arc.SearchBlock(HeaderType);
	else
		Arc.ReadHeader();
	if (Arc.GetHeaderType()==FILE_HEAD)
	{
		Arc.ConvertAttributes();
		Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET);
	}
#ifndef GUI
	if (ShowFileName)
	{
		ostringstream strm;
		int lProgress = (DataIO->CurUnpRead * 1000) / Arc.NewLhd.FullUnpSize;
        //strm.str(""); strm << "Extracting: " << lProgress/10 << '.' << lProgress%10 << "%";
		//(new CMessageString(strm.str().c_str()))->PostAsWParam(g_hwndMain, WM_PARNRAR_PROGRESS, lProgress);
		strm.str(""); strm << lProgress/10 << '.' << lProgress%10;
		CPnrMessage::SendParProgress(Arc.m_sParfileName, strm.str().c_str());
		//mprintf(m_sParfileName,St(MExtrPoints),IntNameToExt(Arc.ArcName));
		//if (!Cmd->DisablePercentage)
			//mprintf(m_sParfileName,"     ");
	}
#endif
	if (DataIO!=NULL)
	{
		if (HeaderType==ENDARC_HEAD)
			DataIO->UnpVolume=false;
		else
		{
			DataIO->UnpVolume=(hd->Flags & LHD_SPLIT_AFTER);
			DataIO->SetPackedSizeToRead(hd->FullPackSize);
		}
		DataIO->PackedCRC=0xffffffff;
		//    DataIO->SetFiles(&Arc,NULL);
	}
	return(true);
}