Exemple #1
0
inline int strnicmpw_w2c(const wchar *s1,const wchar *s2,int n)
{
  wchar Wide1[NM*2],Wide2[NM*2];
  strncpyw(Wide1,s1,sizeof(Wide1)/sizeof(Wide1[0])-1);
  strncpyw(Wide2,s2,sizeof(Wide2)/sizeof(Wide2[0])-1);
  Wide1[Min(sizeof(Wide1)/sizeof(Wide1[0])-1,n)]=0;
  Wide2[Min(sizeof(Wide2)/sizeof(Wide2[0])-1,n)]=0;
  char Ansi1[NM*2],Ansi2[NM*2];
  WideToChar(Wide1,Ansi1,sizeof(Ansi1));
  WideToChar(Wide2,Ansi2,sizeof(Ansi2));
  return(stricomp(Ansi1,Ansi2));
}
Exemple #2
0
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath)
{
  const wchar *DestPtr=SrcPath;
  for (const wchar *s=DestPtr;*s!=0;s++)
    if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
      DestPtr=s+4;
  while (*DestPtr)
  {
    const wchar *s=DestPtr;
    if (s[0] && IsDriveDiv(s[1]))
      s+=2;
    if (s[0]=='\\' && s[1]=='\\')
    {
      const wchar *Slash=strchrw(s+2,'\\');
      if (Slash!=NULL && (Slash=strchrw(Slash+1,'\\'))!=NULL)
        s=Slash+1;
    }
    for (const wchar *t=s;*t!=0;t++)
      if (IsPathDiv(*t))
        s=t+1;
      else
        if (*t!='.')
          break;
    if (s==DestPtr)
      break;
    DestPtr=s;
  }
  if (DestPath!=NULL)
  {
    wchar TmpStr[NM];
    strncpyw(TmpStr,DestPtr,sizeof(TmpStr)/sizeof(TmpStr[0])-1);
    strcpyw(DestPath,TmpStr);
  }
  return((wchar *)DestPtr);
}
Exemple #3
0
void GetFilePath(const wchar *FullName,wchar *Path)
{
  const wchar *PathPtr=/*(*FullName && IsDriveDiv(FullName[1])) ? FullName+2:*/FullName;
  int PathLength=PointToName(FullName)-FullName;
  strncpyw(Path,PathPtr,PathLength);
  Path[PathLength]=0;
}
Exemple #4
0
// safe strncpyw: copies maxlen-1 max and always returns zero terminated dest
wchar* strncpyzw(wchar *dest, const wchar *src, size_t maxlen)
{
  if (maxlen>0)
  {
    strncpyw(dest,src,maxlen-1);
    dest[maxlen-1]=0;
  }
  return(dest);
}
Exemple #5
0
bool StringList::GetString(char *Str,wchar *StrW,int MaxLength)
{
  char *StrPtr;
  wchar *StrPtrW;
  if (Str==NULL || !GetString(&StrPtr,&StrPtrW))
    return(false);
  strncpy(Str,StrPtr,MaxLength);
  if (StrW!=NULL)
    strncpyw(StrW,NullToEmpty(StrPtrW),MaxLength);
  return(true);
}
Exemple #6
0
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
{
#ifdef _WIN_32
  uint DirAttr=0;
#else
  uint DirAttr=0777;
#endif
  int PosW=0;
  for (const char *s=Path;*s!=0 && PosW<NM;s=charnext(s),PosW++)
  {
    bool Wide=PathW!=NULL && *PathW!=0;
    if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER)
    {
      wchar *DirPtrW=NULL;
      if (Wide)
      {
        wchar DirNameW[NM];
        strncpyw(DirNameW,PathW,PosW);
        DirNameW[PosW]=0;
        DirPtrW=DirNameW;
      }
      char DirName[NM];
      strncpy(DirName,Path,s-Path);
      DirName[s-Path]=0;
      if (MakeDir(DirName,DirPtrW,DirAttr)==MKDIR_SUCCESS)
      {
#ifndef GUI
        mprintf(St(MCreatDir),DirName);
        mprintf(" %s",St(MOk));
#endif
      }
    }
  }
  if (!SkipLastName)
    MakeDir(Path,PathW,DirAttr);
}
Exemple #7
0
void CommandData::ParseArg(char *Arg,wchar *ArgW)
{
  if (IsSwitch(*Arg) && !NoMoreSwitches)
    if (Arg[1]=='-')
      NoMoreSwitches=true;
    else
      ProcessSwitch(&Arg[1]);
  else
    if (*Command==0)
    {
      strncpy(Command,Arg,sizeof(Command));
      if (ArgW!=NULL)
        strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0]));
      if (toupper(*Command)=='S')
      {
        const char *SFXName=Command[1] ? Command+1:DefSFXName;
        if (PointToName(SFXName)!=SFXName || FileExist(SFXName))
          strcpy(SFXModule,SFXName);
        else
          GetConfigName(SFXName,SFXModule,true);
      }
#ifndef GUI
      *Command=toupper(*Command);
      if (*Command!='I' && *Command!='S')
        strupper(Command);
#endif
    }
    else
      if (*ArcName==0)
      {
        strncpy(ArcName,Arg,sizeof(ArcName));
        if (ArgW!=NULL)
          strncpyw(ArcNameW,ArgW,sizeof(ArcNameW)/sizeof(ArcNameW[0]));
      }
      else
      {
        int Length=strlen(Arg);
        char EndChar=Arg[Length-1];
        char CmdChar=toupper(*Command);
        bool Add=strchr("AFUM",CmdChar)!=NULL;
        bool Extract=CmdChar=='X' || CmdChar=='E';
        if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add)
          strcpy(ExtrPath,Arg);
        else
          if ((Add || CmdChar=='T') && *Arg!='@')
            FileArgs->AddString(Arg);
          else
          {
            struct FindData FileData;
            bool Found=FindFile::FastFind(Arg,NULL,&FileData);
            if (!Found && *Arg=='@' && !IsWildcard(Arg))
            {
              ReadTextFile(Arg+1,FileArgs,false,true,true,true,true);
              FileLists=true;
            }
            else
              if (Found && FileData.IsDir && Extract && *ExtrPath==0)
              {
                strcpy(ExtrPath,Arg);
                AddEndSlash(ExtrPath);
              }
              else
                FileArgs->AddString(Arg);
          }
      }
}
Exemple #8
0
int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW)
{
  DataSet *Data=(DataSet *)hArcData;
  //try
  //{
    Data->Cmd.DllError=0;
    if (Data->OpenMode==RAR_OM_LIST || Data->OpenMode==RAR_OM_LIST_INCSPLIT ||
        Operation==RAR_SKIP && !Data->Arc.Solid)
    {
      if (Data->Arc.Volume &&
          Data->Arc.GetHeaderType()==FILE_HEAD &&
          (Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0)
        if (MergeArchive(Data->Arc,NULL,false,'L'))
        {
          Data->Extract.SignatureFound=false;
          Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
          return(0);
        }
        else
          return(ERAR_EOPEN);
      Data->Arc.SeekToNext();
    }
    else
    {
      Data->Cmd.DllOpMode=Operation;

      if (DestPath!=NULL || DestName!=NULL)
      {
#ifdef _WIN_32
        OemToChar(NullToEmpty(DestPath),Data->Cmd.ExtrPath);
#else
        strcpy(Data->Cmd.ExtrPath,NullToEmpty(DestPath));
#endif
        AddEndSlash(Data->Cmd.ExtrPath);
#ifdef _WIN_32
        OemToChar(NullToEmpty(DestName),Data->Cmd.DllDestName);
#else
        strcpy(Data->Cmd.DllDestName,NullToEmpty(DestName));
#endif
      }
      else
      {
        *Data->Cmd.ExtrPath=0;
        *Data->Cmd.DllDestName=0;
      }

      if (DestPathW!=NULL || DestNameW!=NULL)
      {
        strncpyw(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2);
        AddEndSlash(Data->Cmd.ExtrPathW);
        strncpyw(Data->Cmd.DllDestNameW,NullToEmpty(DestNameW),NM-1);

        if (*Data->Cmd.DllDestNameW!=0 && *Data->Cmd.DllDestName==0)
          WideToChar(Data->Cmd.DllDestNameW,Data->Cmd.DllDestName);
      }
      else
      {
        *Data->Cmd.ExtrPathW=0;
        *Data->Cmd.DllDestNameW=0;
      }

      strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T");
      Data->Cmd.Test=Operation!=RAR_EXTRACT;
      bool Repeat=false;
      Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);

      while (Data->Arc.ReadHeader()!=0 && Data->Arc.GetHeaderType()==NEWSUB_HEAD)
      {
        Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
        Data->Arc.SeekToNext();
      }
      Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
    }
  //}
  //catch (int ErrCode)
  //{
   // return(RarErrorToDll(ErrCode));
  //}
  return(Data->Cmd.DllError);
}
Exemple #9
0
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
{
  DataSet *Data=(DataSet *)hArcData;
  //try
  //{
    if ((Data->HeaderSize=(int)Data->Arc.SearchBlock(FILE_HEAD))<=0)
    {
      if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD &&
          (Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
        if (MergeArchive(Data->Arc,NULL,false,'L'))
        {
          Data->Extract.SignatureFound=false;
          Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
          return(RARReadHeaderEx(hArcData,D));
        }
        else
          return(ERAR_EOPEN);
      return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE);
    }
    if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
    {
      int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
      if (Code==0)
        return(RARReadHeaderEx(hArcData,D));
      else
        return(Code);
    }
    strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName));
    if (*Data->Arc.FileNameW)
      strncpyw(D->ArcNameW,Data->Arc.FileNameW,sizeof(D->ArcNameW));
    else
      CharToWide(Data->Arc.FileName,D->ArcNameW);
    strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName));
    if (*Data->Arc.NewLhd.FileNameW)
      strncpyw(D->FileNameW,Data->Arc.NewLhd.FileNameW,sizeof(D->FileNameW));
    else
    {
#ifdef _WIN_32
      char AnsiName[NM];
      OemToChar(Data->Arc.NewLhd.FileName,AnsiName);
      if (!CharToWide(AnsiName,D->FileNameW,ASIZE(D->FileNameW)))
        *D->FileNameW=0;
#else
      if (!CharToWide(Data->Arc.NewLhd.FileName,D->FileNameW,ASIZE(D->FileNameW)))
        *D->FileNameW=0;
#endif
    }
    D->Flags=Data->Arc.NewLhd.Flags;
    D->PackSize=Data->Arc.NewLhd.PackSize;
    D->PackSizeHigh=Data->Arc.NewLhd.HighPackSize;
    D->UnpSize=Data->Arc.NewLhd.UnpSize;
    D->UnpSizeHigh=Data->Arc.NewLhd.HighUnpSize;
    D->HostOS=Data->Arc.NewLhd.HostOS;
    D->FileCRC=Data->Arc.NewLhd.FileCRC;
    D->FileTime=Data->Arc.NewLhd.FileTime;
    D->UnpVer=Data->Arc.NewLhd.UnpVer;
    D->Method=Data->Arc.NewLhd.Method;
    D->FileAttr=Data->Arc.NewLhd.FileAttr;
    D->CmtSize=0;
    D->CmtState=0;
//  }
 // catch (int ErrCode)
  //{
  //  return(RarErrorToDll(ErrCode));
 // }
  return(0);
}
Exemple #10
0
void CommandData::ParseArg(char *Arg,wchar *ArgW)
{
  if (IsSwitch(*Arg) && !NoMoreSwitches)
    if (Arg[1]=='-')
      NoMoreSwitches=true;
    else
      ProcessSwitch(&Arg[1],(ArgW!=NULL && *ArgW!=0 ? &ArgW[1]:NULL));
  else
    if (*Command==0)
    {
      strncpyz(Command,Arg,ASIZE(Command));
      if (ArgW!=NULL)
        strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0]));
      if (etoupper(*Command)=='S')
      {
        const char *SFXName=Command[1] ? Command+1:DefSFXName;
        if (PointToName(SFXName)!=SFXName || FileExist(SFXName))
          strcpy(SFXModule,SFXName);
        else
          GetConfigName(SFXName,SFXModule,true);
      }
#ifndef GUI
      *Command=etoupper(*Command);
      if (*Command!='I' && *Command!='S')
        strupper(Command);
#endif
    }
    else
      if (*ArcName==0)
      {
        strncpyz(ArcName,Arg,ASIZE(ArcName));
        if (ArgW!=NULL)
          strncpyzw(ArcNameW,ArgW,ASIZE(ArcNameW));
      }
      else
      {
        size_t Length=strlen(Arg);
        char EndChar=Length==0 ? 0:Arg[Length-1];
        char CmdChar=etoupper(*Command);
        bool Add=strchr("AFUM",CmdChar)!=NULL;
        bool Extract=CmdChar=='X' || CmdChar=='E';
        if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add)
        {
          strncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
          if (ArgW!=NULL)
            strncpyzw(ExtrPathW,ArgW,ASIZE(ExtrPathW));
        }
        else
          if ((Add || CmdChar=='T') && *Arg!='@')
            FileArgs->AddString(Arg);
          else
          {
            struct FindData FileData;
            bool Found=FindFile::FastFind(Arg,NULL,&FileData);
            if (!Found && *Arg=='@' && !IsWildcard(Arg))
            {
              FileLists=true;

              RAR_CHARSET Charset=FilelistCharset;

#if defined(_WIN_32) && !defined(GUI)
              // for compatibility reasons we use OEM encoding
              // in Win32 console version by default

              if (Charset==RCH_DEFAULT)
                Charset=RCH_OEM;
#endif

              ReadTextFile(Arg+1,FileArgs,false,true,Charset,true,true,true);
            }
            else
              if (Found && FileData.IsDir && Extract && *ExtrPath==0)
              {
                strcpy(ExtrPath,Arg);
                AddEndSlash(ExtrPath);
              }
              else
                FileArgs->AddString(Arg);
          }
      }
}
Exemple #11
0
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
{
#ifdef _WIN_32
  uint DirAttr=0;
#else
  uint DirAttr=0777;
#endif
#ifdef UNICODE_SUPPORTED
  bool Wide=PathW!=NULL && *PathW!=0 && UnicodeEnabled();
#else
  bool Wide=false;
#endif
  bool IgnoreAscii=false;

  const char *s=Path;
  for (int PosW=0;;PosW++)
  {
    if (s==NULL || s-Path>=NM || *s==0)
      IgnoreAscii=true;
    if (Wide && (PosW>=NM || PathW[PosW]==0) || !Wide && IgnoreAscii)
      break;
    if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER)
    {
      wchar *DirPtrW=NULL,DirNameW[NM];
      if (Wide)
      {
        strncpyw(DirNameW,PathW,PosW);
        DirNameW[PosW]=0;
        DirPtrW=DirNameW;
      }
      char DirName[NM];
      if (IgnoreAscii)
        WideToChar(DirPtrW,DirName);
      else
      {
#ifndef DBCS_SUPPORTED
        if (*s!=CPATHDIVIDER)
          for (const char *n=s;*n!=0 && n-Path<NM;n++)
            if (*n==CPATHDIVIDER)
            {
              s=n;
              break;
            }
#endif
        strncpy(DirName,Path,s-Path);
        DirName[s-Path]=0;
      }
      if (MakeDir(DirName,DirPtrW,DirAttr)==MKDIR_SUCCESS)
      {
#ifndef GUI
        mprintf(St(MCreatDir),DirName);
        mprintf(" %s",St(MOk));
#endif
      }
    }
    if (!IgnoreAscii)
      s=charnext(s);
  }
  if (!SkipLastName)
    MakeDir(Path,PathW,DirAttr);
}
Exemple #12
0
int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW, string sParfileName)
{
	DataSet *Data=(DataSet *)hArcData;
	try
	{
		Data->Arc.m_sParfileName = sParfileName;

		if (Data->OpenMode==RAR_OM_LIST || Operation==RAR_SKIP && !Data->Arc.Solid)
		{
			if (/*Data->OpenMode==RAR_OM_LIST && */Data->Arc.Volume &&
				Data->Arc.GetHeaderType()==FILE_HEAD &&
				(Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0)
				if (MergeArchive(Data->Arc,NULL,false,'L'))
				{
					Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
					return(0);
				}
				else
					return(ERAR_EOPEN);
			Data->Arc.SeekToNext();
		}
		else
		{
			if (DestPath!=NULL || DestName!=NULL)
			{
				OemToChar(NullToEmpty(DestPath),Data->Cmd.ExtrPath);
				OemToChar(NullToEmpty(DestName),Data->Cmd.ArcName);
				AddEndSlash(Data->Cmd.ExtrPath);
			}
			else
			{
				*Data->Cmd.ExtrPath=0;
			}

			if (DestPathW!=NULL || DestNameW!=NULL)
			{
				strncpyw(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2);
				AddEndSlash(Data->Cmd.ExtrPathW);
			}
			else
			{
				*Data->Cmd.ExtrPathW=0;
			}

			strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T");
			Data->Cmd.Test=Operation!=RAR_EXTRACT;
			bool Repeat=false;

			Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);

			while (Data->Arc.ReadHeader()!=0 && Data->Arc.GetHeaderType()==NEWSUB_HEAD)
			{
				Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
				Data->Arc.SeekToNext();
			}
			Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
		}
	}
	catch (int ErrCode)
	{
		return(RarErrorToDll(ErrCode));
	}
	catch(...)
	{
		return -1;
	}
	return 0;
}
Exemple #13
0
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize,bool &Repeat)
{
  char Command=*Cmd->Command;
  if (HeaderSize<=0)
    if (DataIO.UnpVolume)
    {
#ifdef NOVOLUME
      return(false);
#else
      if (!MergeArchive(Arc,NULL,false,Command))
      {
        ErrHandler.SetErrorCode(WARNING);
        return(false);
      }
      SignatureFound=false;
#endif
    }
    else
      return(false);
  int HeadType=Arc.GetHeaderType();
  if (HeadType!=FILE_HEAD)
  {
    if (HeadType==AV_HEAD || HeadType==SIGN_HEAD)
      SignatureFound=true;
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
    if (HeadType==SUB_HEAD && PrevExtracted)
      SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
#endif
    if (HeadType==NEWSUB_HEAD)
    {
      if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV))
        SignatureFound=true;
#if !defined(NOSUBBLOCKS) && !defined(_WIN_CE)
      if (PrevExtracted)
        SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
#endif
    }
    if (HeadType==ENDARC_HEAD)
      if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)
      {
#ifndef NOVOLUME
        if (!MergeArchive(Arc,NULL,false,Command))
        {
          ErrHandler.SetErrorCode(WARNING);
          return(false);
        }
        SignatureFound=false;
#endif
        Arc.Seek(Arc.CurBlockPos,SEEK_SET);
        return(true);
      }
      else
        return(false);
    Arc.SeekToNext();
    return(true);
  }
  PrevExtracted=false;

  if (SignatureFound ||
      !Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() &&
      AllMatchesExact)
    return(false);

  char ArcFileName[NM];
  IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
  strcpy(ArcFileName,Arc.NewLhd.FileName);

  wchar ArcFileNameW[NM];
  *ArcFileNameW=0;

  int MatchType=MATCH_WILDSUBPATH;

  bool EqualNames=false;
  int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType);
  bool ExactMatch=MatchNumber!=0;
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
  if (Cmd->ExclPath==EXCL_BASEPATH)
  {
    *Cmd->ArcPath=0;
    if (ExactMatch)
    {
      Cmd->FileArgs->Rewind();
      if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1))
        *PointToName(Cmd->ArcPath)=0;
    }
  }
#endif
  if (ExactMatch && !EqualNames)
    AllMatchesExact=false;

#ifdef UNICODE_SUPPORTED
  bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled();
#else
  bool WideName=false;
#endif

#ifdef _APPLE
  if (WideName)
  {
    WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,sizeof(ArcFileName));
    WideName=false;
  }
#endif

  wchar *DestNameW=WideName ? DestFileNameW:NULL;

#ifdef UNICODE_SUPPORTED
  if (WideName)
  {
    ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW);
    char Name[NM];
    if (WideToChar(ArcFileNameW,Name) && IsNameUsable(Name))
      strcpy(ArcFileName,Name);
  }
#endif

  ConvertPath(ArcFileName,ArcFileName);

  if (Arc.IsArcLabel())
    return(true);

  if (Arc.NewLhd.Flags & LHD_VERSION)
  {
    if (Cmd->VersionControl!=1 && !EqualNames)
    {
      if (Cmd->VersionControl==0)
        ExactMatch=false;
      int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false);
      if (Cmd->VersionControl-1==Version)
        ParseVersionFileName(ArcFileName,ArcFileNameW,true);
      else
        ExactMatch=false;
    }
  }
  else
    if (!Arc.IsArcDir() && Cmd->VersionControl>1)
      ExactMatch=false;

  Arc.ConvertAttributes();

#ifndef SFX_MODULE
  if ((Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/)) && FirstFile)
  {
    char CurVolName[NM];
    strcpy(CurVolName,ArcName);

    VolNameToFirstName(ArcName,ArcName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING));
    if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName))
    {
      *ArcNameW=0;
      Repeat=true;
      return(false);
    }
#if !defined(RARDLL) && !defined(_WIN_CE)
    if (!ReconstructDone)
    {
      ReconstructDone=true;

      RecVolumes RecVol;
      if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true))
      {
        Repeat=true;
        return(false);
      }
    }
#endif
    strcpy(ArcName,CurVolName);
  }
#endif
  DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER);
  DataIO.NextVolumeMissing=false;

  Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET);

  bool TestMode=false;
  bool ExtrFile=false;
  bool SkipSolid=false;

#ifndef SFX_MODULE
  if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0)
  {
    if (ExactMatch)
    {
      Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName);
#ifdef RARDLL
      Cmd->DllError=ERAR_BAD_DATA;
#endif
      ErrHandler.SetErrorCode(WARNING);
    }
    ExactMatch=false;
  }

  FirstFile=false;
#endif

  if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
  {
    if (Arc.NewLhd.Flags & LHD_PASSWORD)
#ifndef RARDLL
      if (*Password==0)
#endif
      {
#ifdef RARDLL
        if (*Cmd->Password==0)
          if (Cmd->Callback==NULL ||
              Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LONG)Cmd->Password,sizeof(Cmd->Password))==-1)
            return(false);
        strcpy(Password,Cmd->Password);

#else
        if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password)))
        {
          PasswordCancelled=true;
          return(false);
        }
#endif
      }
#if !defined(GUI) && !defined(SILENT)
      else
        if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0))
        {
          eprintf(St(MUseCurPsw),ArcFileName);
          switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll)))
          {
            case -1:
              ErrHandler.Exit(USER_BREAK);
            case 2:
              if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password)))
              {
                return(false);
              }
              break;
            case 3:
              PasswordAll=true;
              break;
          }
        }
#endif

#ifndef SFX_MODULE
    if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0)
      WideToChar(Cmd->ExtrPathW,DestFileName);
    else
#endif
      strcpy(DestFileName,Cmd->ExtrPath);


#ifndef SFX_MODULE
    if (Cmd->AppendArcNameToPath)
    {
      strcat(DestFileName,PointToName(Arc.FileName));
      SetExt(DestFileName,NULL);
      AddEndSlash(DestFileName);
    }
#endif

    char *ExtrName=ArcFileName;

    bool EmptyName=false;
#ifndef SFX_MODULE
    int Length=strlen(Cmd->ArcPath);
    if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) &&
        strlen(ArcFileName)==Length-1)
      Length--;
    if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0)
    {
      ExtrName+=Length;
      while (*ExtrName==CPATHDIVIDER)
        ExtrName++;
      if (*ExtrName==0)
        EmptyName=true;
    }
#endif

    bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':');
    if (AbsPaths)
      *DestFileName=0;

    if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
      strcat(DestFileName,PointToName(ExtrName));
    else
      strcat(DestFileName,ExtrName);

    if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2]))
      DestFileName[1]=':';

#ifndef SFX_MODULE
    if (!WideName && *Cmd->ExtrPathW!=0)
    {
      DestNameW=DestFileNameW;
      WideName=true;
      CharToWide(ArcFileName,ArcFileNameW);
    }
#endif

    if (WideName)
    {
      if (*Cmd->ExtrPathW!=0)
        strcpyw(DestFileNameW,Cmd->ExtrPathW);
      else
        CharToWide(Cmd->ExtrPath,DestFileNameW);

#ifndef SFX_MODULE
      if (Cmd->AppendArcNameToPath)
      {
        wchar FileNameW[NM];
        if (*Arc.FileNameW!=0)
          strcpyw(FileNameW,Arc.FileNameW);
        else
          CharToWide(Arc.FileName,FileNameW);
        strcatw(DestFileNameW,PointToName(FileNameW));
        SetExt(DestFileNameW,NULL);
        AddEndSlash(DestFileNameW);
      }
#endif
      wchar *ExtrNameW=ArcFileNameW;
#ifndef SFX_MODULE
      if (Length>0)
      {
        wchar ArcPathW[NM];
        CharToWide(Cmd->ArcPath,ArcPathW);
        Length=strlenw(ArcPathW);
      }
      ExtrNameW+=Length;
      while (*ExtrNameW==CPATHDIVIDER)
        ExtrNameW++;
#endif

      if (AbsPaths)
        *DestFileNameW=0;

      if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
        strcatw(DestFileNameW,PointToName(ExtrNameW));
      else
        strcatw(DestFileNameW,ExtrNameW);

      if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2]))
        DestFileNameW[1]=':';
    }
    else
      *DestFileNameW=0;

    ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0/* && *ExtrName*/;
    if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X'))
    {
      struct FindData FD;
      if (FindFile::FastFind(DestFileName,DestNameW,&FD))
      {
        if (FD.mtime >= Arc.NewLhd.mtime)
          ExtrFile=false;
      }
      else
        if (Cmd->FreshFiles)
          ExtrFile=false;
    }

#ifdef RARDLL
    if (*Cmd->DllDestName)
    {
      strncpy(DestFileName,Cmd->DllDestName,sizeof(DestFileName));
      *DestFileNameW=0;
      if (Cmd->DllOpMode!=RAR_EXTRACT)
        ExtrFile=false;
    }
    if (*Cmd->DllDestNameW)
    {
      strncpyw(DestFileNameW,Cmd->DllDestNameW,sizeof(DestFileNameW)/sizeof(DestFileNameW[0]));
      DestNameW=DestFileNameW;
      if (Cmd->DllOpMode!=RAR_EXTRACT)
        ExtrFile=false;
    }
#endif

#ifdef SFX_MODULE
    if (Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.Method!=0x30)
#else
    if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER)
#endif
    {
#ifndef SILENT
      Log(Arc.FileName,St(MUnknownMeth),ArcFileName);
#ifndef SFX_MODULE
      Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10);
#endif
#endif
      ExtrFile=false;
      ErrHandler.SetErrorCode(WARNING);
#ifdef RARDLL
      Cmd->DllError=ERAR_UNKNOWN_FORMAT;
#endif
    }

    File CurFile;

    if (!IsLink(Arc.NewLhd.FileAttr))
      if (Arc.IsArcDir())
      {
        if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
          return(true);
        if (SkipSolid)
        {
#ifndef GUI
          mprintf(St(MExtrSkipFile),ArcFileName);
#endif
          return(true);
        }
        TotalFileCount++;
        if (Cmd->Test)
        {
#ifndef GUI
          mprintf(St(MExtrTestFile),ArcFileName);
          mprintf(" %s",St(MOk));
#endif
          return(true);
        }
        MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
        bool DirExist=false;
        if (MDCode!=MKDIR_SUCCESS)
        {
          DirExist=FileExist(DestFileName,DestNameW);
          if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW)))
          {
            bool UserReject;
            FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime);
            DirExist=false;
          }
          CreatePath(DestFileName,DestNameW,true);
          MDCode=MakeDir(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
        }
        if (MDCode==MKDIR_SUCCESS)
        {
#ifndef GUI
          mprintf(St(MCreatDir),DestFileName);
          mprintf(" %s",St(MOk));
#endif
          PrevExtracted=true;
        }
        else
          if (DirExist)
          {
            SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
            PrevExtracted=true;
          }
          else
          {
            Log(Arc.FileName,St(MExtrErrMkDir),DestFileName);
            ErrHandler.SysErrMsg();
#ifdef RARDLL
            Cmd->DllError=ERAR_ECREATE;
#endif
            ErrHandler.SetErrorCode(CREATE_ERROR);
          }
        if (PrevExtracted)
        {
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
          if (Cmd->SetCompressedAttr &&
              (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
            SetFileCompression(DestFileName,DestFileNameW,true);
#endif
          SetDirTime(DestFileName,
            Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
            Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
            Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
        }
        return(true);
      }
      else
      {
        if (Cmd->Test && ExtrFile)
          TestMode=true;
#if !defined(GUI) && !defined(SFX_MODULE)
        if (Command=='P' && ExtrFile)
          CurFile.SetHandleType(FILE_HANDLESTD);
#endif
        if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test)
        {
          bool UserReject;
          if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
          {
            ExtrFile=false;
            if (!UserReject)
            {
              ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
              ErrHandler.SetErrorCode(CREATE_ERROR);
#ifdef RARDLL
              Cmd->DllError=ERAR_ECREATE;
#endif
              if (!IsNameUsable(DestFileName))
              {
                Log(Arc.FileName,St(MCorrectingName));
                MakeNameUsable(DestFileName,true);
                CreatePath(DestFileName,NULL,true);
                if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
                  ExtrFile=true;
                else
                  ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
              }
            }
          }
        }
      }

    if (!ExtrFile && Arc.Solid)
    {
      SkipSolid=true;
      TestMode=true;
      ExtrFile=true;
    }
    if (ExtrFile)
    {
      if (!SkipSolid)
      {
        if (!TestMode && Command!='P' && CurFile.IsDevice())
        {
          Log(Arc.FileName,St(MInvalidName),DestFileName);
          ErrHandler.WriteError(Arc.FileName,DestFileName);
        }
        TotalFileCount++;
      }
      FileCount++;
#ifndef GUI
      if (Command!='I')
        if (SkipSolid)
          mprintf(St(MExtrSkipFile),ArcFileName);
        else
          switch(Cmd->Test ? 'T':Command)
          {
            case 'T':
              mprintf(St(MExtrTestFile),ArcFileName);
              break;
#ifndef SFX_MODULE
            case 'P':
              mprintf(St(MExtrPrinting),ArcFileName);
              break;
#endif
            case 'X':
            case 'E':
              mprintf(St(MExtrFile),DestFileName);
              break;
          }
      if (!Cmd->DisablePercentage)
        mprintf("     ");
#endif
      DataIO.CurUnpRead=0;
      DataIO.CurUnpWrite=0;
      DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff;
      DataIO.PackedCRC=0xffffffff;
      DataIO.SetEncryption(
        (Arc.NewLhd.Flags & LHD_PASSWORD) ? Arc.NewLhd.UnpVer:0,Password,
        (Arc.NewLhd.Flags & LHD_SALT) ? Arc.NewLhd.Salt:NULL,false);
      DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize);
      DataIO.SetFiles(&Arc,&CurFile);
      DataIO.SetTestMode(TestMode);
      DataIO.SetSkipUnpCRC(SkipSolid);
#ifndef _WIN_CE
      if (!TestMode && !Arc.BrokenFileHeader &&
          (Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize &&
          (Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize))
        CurFile.Prealloc(Arc.NewLhd.FullUnpSize);
#endif

      CurFile.SetAllowDelete(!Cmd->KeepBroken);

      bool LinkCreateMode=!Cmd->Test && !SkipSolid;
      if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode))
        PrevExtracted=LinkCreateMode;
      else
        if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0)
          if (Arc.NewLhd.Method==0x30)
            UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize);
          else
          {
            Unp->SetDestSize(Arc.NewLhd.FullUnpSize);
#ifndef SFX_MODULE
            if (Arc.NewLhd.UnpVer<=15)
              Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
            else
#endif
              Unp->DoUnpack(Arc.NewLhd.UnpVer,Arc.NewLhd.Flags & LHD_SOLID);
          }

      if (Arc.IsOpened())
        Arc.SeekToNext();

      bool BrokenFile=false;
      if (!SkipSolid)
      {
        if (Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC) ||
            !Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC^0xffffffff))
        {
#ifndef GUI
          if (Command!='P' && Command!='I')
            mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk));
#endif
        }
        else
        {
          char *BadArcName=(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE) ? NULL:Arc.FileName;
          if (Arc.NewLhd.Flags & LHD_PASSWORD)
          {
            Log(BadArcName,St(MEncrBadCRC),ArcFileName);
          }
          else
          {
            Log(BadArcName,St(MCRCFailed),ArcFileName);
          }
          BrokenFile=true;
          ErrHandler.SetErrorCode(CRC_ERROR);
#ifdef RARDLL
          Cmd->DllError=ERAR_BAD_DATA;
#endif
          Alarm();
        }
      }
#ifndef GUI
      else
        mprintf("\b\b\b\b\b     ");
#endif

      if (!TestMode && (Command=='X' || Command=='E') &&
          !IsLink(Arc.NewLhd.FileAttr))
      {
#if defined(_WIN_32) || defined(_EMX)
        if (Cmd->ClearArc)
          Arc.NewLhd.FileAttr&=~FA_ARCH;
#endif
        if (!BrokenFile || Cmd->KeepBroken)
        {
          if (BrokenFile)
            CurFile.Truncate();
          CurFile.SetOpenFileStat(
            Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
            Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
            Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
          CurFile.Close();
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
          if (Cmd->SetCompressedAttr &&
              (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
            SetFileCompression(CurFile.FileName,CurFile.FileNameW,true);
#endif
          CurFile.SetCloseFileStat(
            Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
            Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime,
            Arc.NewLhd.FileAttr);
          PrevExtracted=true;
        }
      }
    }
  }
  if (ExactMatch)
    MatchedArgs++;
  if (DataIO.NextVolumeMissing || !Arc.IsOpened())
    return(false);
  if (!ExtrFile)
    if (!Arc.Solid)
      Arc.SeekToNext();
    else
      if (!SkipSolid)
        return(false);
  return(true);
}
Exemple #14
0
// Returns file path including the trailing path separator symbol.
void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength)
{
  size_t PathLength=Min(MaxLength-1,PointToName(FullName)-FullName);
  strncpyw(Path,FullName,PathLength);
  Path[PathLength]=0;
}