Beispiel #1
0
unrar_err_t Archive::IsArchive()
{
	if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
		return unrar_err_not_arc;

	if (IsSignature(MarkHead.Mark))
	{
		if (OldFormat)
			Seek(0,SEEK_SET);
	}
	else
	{
		if (SFXSize==0)
			return unrar_err_not_arc;
	}

	unrar_err_t error =
	ReadHeader();
	// (no need to seek to next)
	if ( error != unrar_ok )
		return error;

#ifndef SFX_MODULE
	if (OldFormat)
	{
		NewMhd.Flags=OldMhd.Flags & 0x3f;
		NewMhd.HeadSize=OldMhd.HeadSize;
	}
	else
#endif
	{
		if (HeaderCRC!=NewMhd.HeadCRC)
		{
			return unrar_err_corrupt;
		}
	}
	bool
	Volume=(NewMhd.Flags & MHD_VOLUME);
	Solid=(NewMhd.Flags & MHD_SOLID)!=0;
	bool
	Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;

	// (removed decryption and volume handling)

	if ( Encrypted )
		return unrar_err_encrypted;

	if ( Volume )
		return unrar_err_segmented;

	return unrar_ok;
}
Beispiel #2
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
#ifdef USE_QOPEN
  QOpen.Unload();
#endif

  // Important if we reuse Archive object and it has virtual QOpen
  // file position not matching real. For example, for 'l -v volname'.
  Seek(0,SEEK_SET);
  
#ifndef SFX_MODULE
  if (IsDevice())
  {
#ifndef SHELL_EXT
    Log(FileName,St(MInvalidName),FileName);
#endif
    return false;
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD3)!=SIZEOF_MARKHEAD3)
    return(false);
  SFXSize=0;
  
  RARFORMAT Type;
  if ((Type=IsSignature(MarkHead.Mark,SIZEOF_MARKHEAD3))!=RARFMT_NONE)
  {
    Format=Type;
    if (Format==RARFMT14)
      Seek(0,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(MAXSFXSIZE);
    long CurPos=(long)Tell();
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE)
      {
        Format=Type;
        if (Format==RARFMT14 && I>0 && CurPos<28 && ReadSize>31)
        {
          char *D=&Buffer[28-CurPos];
          if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
            continue;
        }
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (Format==RARFMT15 || Format==RARFMT50)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD3);
        break;
      }
    if (SFXSize==0)
      return false;
  }
  if (Format==RARFMT_FUTURE)
  {
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
    Log(FileName,St(MNewRarFormat));
#endif
    return false;
  }
  if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
  {
    Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1);
    if (MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
      return false;
    MarkHead.HeadSize=SIZEOF_MARKHEAD5;
  }
  else
    MarkHead.HeadSize=SIZEOF_MARKHEAD3;

  // Skip the archive encryption header if any and read the main header.
  while (ReadHeader()!=0 && GetHeaderType()!=HEAD_MAIN)
    SeekToNext();

  // This check allows to make RS based recovery even if password is incorrect.
  // But we should not do it for EnableBroken or we'll get 'not RAR archive'
  // messages when extracting encrypted archives with wrong password.
  if (FailedHeaderDecryption && !EnableBroken)
    return false;

  SeekToNext();
  if (BrokenHeader)
  {
#ifndef SHELL_EXT
    Log(FileName,St(MMainHeaderBroken));
#endif
    if (!EnableBroken)
      return false;
  }

/*
  if (MainHead.EncryptVer>VER_UNPACK)
  {
#ifdef RARDLL
    Cmd->DllError=ERAR_UNKNOWN_FORMAT;
#else
    ErrHandler.SetErrorCode(RARX_WARNING);
  #if !defined(SILENT) && !defined(SFX_MODULE)
      Log(FileName,St(MUnknownMeth),FileName);
      Log(FileName,St(MVerRequired),MainHead.EncryptVer/10,MainHead.EncryptVer%10);
  #endif
#endif
    return(false);
  }
*/

#ifdef RARDLL
  // If callback function is not set, we cannot get the password,
  // so we skip the initial header processing for encrypted header archive.
  // It leads to skipped archive comment, but the rest of archive data
  // is processed correctly.
  if (Cmd->Callback==NULL)
    SilentOpen=true;
#endif

  MainComment=MainHead.CommentInHeader;

#ifdef USE_QOPEN
  if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
  {
    QOpen.Init(this,false);
    QOpen.Load(MainHead.QOpenOffset);
  }
#endif

  // If we process non-encrypted archive or can request a password,
  // we set 'first volume' flag based on file attributes below.
  // It is necessary for RAR 2.x archives, which did not have 'first volume'
  // flag in main header.
  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;

    while (ReadHeader()!=0)
    {
      HEADER_TYPE HeaderType=GetHeaderType();
      if (HeaderType==HEAD_SERVICE)
      {
        if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
          MainComment=true;
        FirstVolume=!SubHead.SplitBefore;
      }
      else
      {
        FirstVolume=HeaderType==HEAD_FILE && !FileHead.SplitBefore;
        break;
      }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
  }
  if (!Volume || FirstVolume)
    wcscpy(FirstVolumeName,FileName);

  return true;
}
Beispiel #3
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
#ifndef SFX_MODULE
  if (IsDevice())
  {
#ifndef SHELL_EXT
    Log(FileName,St(MInvalidName),FileName);
#endif
    return(false);
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
    return(false);
  SFXSize=0;
  if (IsSignature(MarkHead.Mark))
  {
    if (OldFormat)
      Seek(0,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(MAXSFXSIZE);
    long CurPos=(long)Tell();
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
      {
        if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
        {
          char *D=&Buffer[28-CurPos];
          if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
            continue;
        }
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (!OldFormat)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD);
        break;
      }
    if (SFXSize==0)
      return(false);
  }
  ReadHeader();
  SeekToNext();
#ifndef SFX_MODULE
  if (OldFormat)
  {
    NewMhd.Flags=OldMhd.Flags & 0x3f;
    NewMhd.HeadSize=OldMhd.HeadSize;
  }
  else
#endif
  {
    if (HeaderCRC!=NewMhd.HeadCRC)
    {
#ifndef SHELL_EXT
      Log(FileName,St(MLogMainHead));
#endif
      Alarm();
      if (!EnableBroken)
        return(false);
    }
  }
  Volume=(NewMhd.Flags & MHD_VOLUME);
  Solid=(NewMhd.Flags & MHD_SOLID)!=0;
  MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
  Locked=(NewMhd.Flags & MHD_LOCK)!=0;
  Signed=(NewMhd.PosAV!=0);
  Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
  Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;

  if (NewMhd.EncryptVer>UNP_VER)
  {
#ifdef RARDLL
    Cmd->DllError=ERAR_UNKNOWN_FORMAT;
#else
    ErrHandler.SetErrorCode(RARX_WARNING);
  #if !defined(SILENT) && !defined(SFX_MODULE)
      Log(FileName,St(MUnknownMeth),FileName);
      Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
  #endif
#endif
    return(false);
  }
#ifdef RARDLL
  // If callback function is not set, we cannot get the password,
  // so we skip the initial header processing for encrypted header archive.
  // It leads to skipped archive comment, but the rest of archive data
  // is processed correctly.
  if (Cmd->Callback==NULL)
    SilentOpen=true;
#endif

  // If not encrypted, we'll check it below.
  NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;

  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;

    NotFirstVolume=false;
    while (ReadHeader()!=0)
    {
      int HeaderType=GetHeaderType();
      if (HeaderType==NEWSUB_HEAD)
      {
        if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
          MainComment=true;
        if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
            Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
          NotFirstVolume=true;
      }
      else
      {
        if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
            Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
          NotFirstVolume=true;
        break;
      }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
  }
  if (!Volume || !NotFirstVolume)
  {
    strcpy(FirstVolumeName,FileName);
    wcscpy(FirstVolumeNameW,FileNameW);
  }

  return(true);
}
Beispiel #4
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
#ifndef SFX_MODULE
  if (IsDevice())
  {
#ifndef SHELL_EXT
    Log(FileName,St(MInvalidName),FileName);
#endif
    return(false);
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
    return(false);
  SFXSize=0;
  if (IsSignature(MarkHead.Mark))
  {
    if (OldFormat)
      Seek(0,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(0x40000);
    long CurPos=int64to32(Tell());
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
      {
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (!OldFormat)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD);
        break;
      }
    if (SFXSize==0)
      return(false);
  }
  ReadHeader();
  SeekToNext();
#ifndef SFX_MODULE
  if (OldFormat)
  {
    NewMhd.Flags=OldMhd.Flags & 0x3f;
    NewMhd.HeadSize=OldMhd.HeadSize;
  }
  else
#endif
  {
    if (HeaderCRC!=NewMhd.HeadCRC)
    {
#ifndef SHELL_EXT
      Log(FileName,St(MLogMainHead));
#endif
      Alarm();
      if (!EnableBroken)
        return(false);
    }
  }
  Volume=(NewMhd.Flags & MHD_VOLUME);
  Solid=(NewMhd.Flags & MHD_SOLID)!=0;
  MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
  Locked=(NewMhd.Flags & MHD_LOCK)!=0;
  Signed=(NewMhd.PosAV!=0);
  Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
  Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;

#ifdef RARDLL
  SilentOpen=true;
#endif
  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    Int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;

    NotFirstVolume=false;
    while (ReadHeader())
    {
      int HeaderType=GetHeaderType();
      if (HeaderType==NEWSUB_HEAD)
      {
        if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
          MainComment=true;
        if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
            Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
          NotFirstVolume=true;
      }
      else
      {
        if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
            Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
          NotFirstVolume=true;
        break;
      }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
  }
  return(true);
}
/**********************************************************************
 * Function: TgtSelDlgProc
 * Info    : dialog event handler for target file selection
 * Result  : TRUE or FALSE
 **********************************************************************/
MRESULT EXPENTRY TgtSelDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{

 static PFILEDLG pFileDlg2;
 CHAR Buffer[CCHMAXPATH+100];
 CHAR FileBuffer[CCHMAXPATH];
 CHAR PathBuffer3[CCHMAXPATH];
 CHAR Title[TITLESTRN_MAXLEN+1];
 BOOL SignedFile;

 MRESULT rc = FALSE;

 switch (msg)
 {

   case WM_INITDLG:
      CenterWindow(hwnd);
      pFileDlg2 = (PFILEDLG) WinQueryWindowULong(hwnd, QWL_USER);
    break;

   case WM_HELP:
     DisplayHelp(IDL_TGTFILE_HELP);
    break;

   case WM_COMMAND:
    switch(SHORT1FROMMP(mp1))
    {
      case DID_OK:
        strcpy(PathBuffer3, pFileDlg2->szFullFile);
        WinQueryWindowText(WinWindowFromID(hwnd, DID_FILENAME_ED),
                           sizeof(FileBuffer),
                           FileBuffer);
        strcat(PathBuffer3, FileBuffer);
        SignedFile = IsSignature(JobDesc.SourceFile);
        if (!SignedFile ||
            (SignedFile && !IsDetachedSignature)
           )
        {
          if(FileExist(PathBuffer3))
          {
            Len = WinLoadString(Hab, hRessourceModule, IDS_QUERY_TARGET_OVERWRITE,
                                MSGSTRN_MAXLEN, Msg);
            Len = WinLoadString(Hab, hRessourceModule, IDS_BUBBLE_DECVERIFYDATA_HELP,
                                TITLESTRN_MAXLEN, Title);
            sprintf(Buffer, Msg, PathBuffer3);
            if (MBID_YES == WinMessageBox(HWND_DESKTOP, hwnd,
                                          Buffer, "", 0, MB_ICONQUESTION | MB_YESNO))
            {
              if (0 == remove(PathBuffer3))
              {
               strcpy(pFileDlg2->szFullFile, PathBuffer3);
               pFileDlg2->lReturn = DID_OK;
               WinDismissDlg(hwnd, TRUE);
               return (MRESULT) TRUE;
              }
              pFileDlg2->lReturn = DID_CANCEL;
            }
            return (MRESULT) FALSE;
          }
        }
        else
        {
          /*
           * source file is a detached signature file that is to
           * be checked against the outfile, so there's no need to
           * query for outfile overwrite allowance
           */
          strcpy(pFileDlg2->szFullFile, PathBuffer3);
          pFileDlg2->lReturn = DID_OK;
          WinDismissDlg(hwnd, TRUE);
          return (MRESULT) TRUE;
        }
      /* fall through! */
    }

   default:
     rc = WinDefFileDlgProc (hwnd, msg, mp1, mp2);
 }

 return rc;

}
Beispiel #6
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
  BrokenHeader=false; // Might be left from previous volume.
  
#ifndef SFX_MODULE
  if (IsDevice())
  {
    uiMsg(UIERROR_INVALIDNAME,FileName,FileName);
    return false;
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD3)!=SIZEOF_MARKHEAD3)
    return false;
  SFXSize=0;
  
  RARFORMAT Type;
  if ((Type=IsSignature(MarkHead.Mark,SIZEOF_MARKHEAD3))!=RARFMT_NONE)
  {
    Format=Type;
    if (Format==RARFMT14)
      Seek(Tell()-SIZEOF_MARKHEAD3,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(MAXSFXSIZE);
    long CurPos=(long)Tell();
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE)
      {
        Format=Type;
        if (Format==RARFMT14 && I>0 && CurPos<28 && ReadSize>31)
        {
          char *D=&Buffer[28-CurPos];
          if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
            continue;
        }
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (Format==RARFMT15 || Format==RARFMT50)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD3);
        break;
      }
    if (SFXSize==0)
      return false;
  }
  if (Format==RARFMT_FUTURE)
  {
    uiMsg(UIERROR_NEWRARFORMAT,FileName);
    return false;
  }
  if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
  {
    Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1);
    if (MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
      return false;
    MarkHead.HeadSize=SIZEOF_MARKHEAD5;
  }
  else
    MarkHead.HeadSize=SIZEOF_MARKHEAD3;

#ifdef RARDLL
  // If callback function is not set, we cannot get the password,
  // so we skip the initial header processing for encrypted header archive.
  // It leads to skipped archive comment, but the rest of archive data
  // is processed correctly.
  if (Cmd->Callback==NULL)
    SilentOpen=true;
#endif

  // Skip the archive encryption header if any and read the main header.
  while (ReadHeader()!=0)
  {
    HEADER_TYPE Type=GetHeaderType();
    // In RAR 5.0 we need to quit after reading HEAD_CRYPT if we wish to
    // avoid the password prompt.
    if (Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT)
      break;
    SeekToNext();
  }

  // This check allows to make RS based recovery even if password is incorrect.
  // But we should not do it for EnableBroken or we'll get 'not RAR archive'
  // messages when extracting encrypted archives with wrong password.
  if (FailedHeaderDecryption && !EnableBroken)
    return false;

  SeekToNext();
  if (BrokenHeader) // Main archive header is corrupt.
  {
    uiMsg(UIERROR_MHEADERBROKEN,FileName);
    if (!EnableBroken)
      return false;
  }

  MainComment=MainHead.CommentInHeader;

  // If we process non-encrypted archive or can request a password,
  // we set 'first volume' flag based on file attributes below.
  // It is necessary for RAR 2.x archives, which did not have 'first volume'
  // flag in main header. Also for all RAR formats we need to scan until
  // first file header to set "comment" flag when reading service header.
  // Unless we are in silent mode, we need to know about presence of comment
  // immediately after IsArchive call.
  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
    HEADER_TYPE SaveCurHeaderType=CurHeaderType;

    while (ReadHeader()!=0)
    {
      HEADER_TYPE HeaderType=GetHeaderType();
      if (HeaderType==HEAD_SERVICE)
        FirstVolume=Volume && !SubHead.SplitBefore;
      else
        if (HeaderType==HEAD_FILE)
        {
          FirstVolume=Volume && !FileHead.SplitBefore;
          break;
        }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
    CurHeaderType=SaveCurHeaderType;
  }
  if (!Volume || FirstVolume)
    wcscpy(FirstVolumeName,FileName);

  return true;
}