Пример #1
0
HRESULT DecompressArchives(
    UStringVector &archivePaths, UStringVector &archivePathsFull,    
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &optionsSpec,
    IOpenCallbackUI *openCallback,
    IExtractCallbackUI *extractCallback)
{
  CExtractOptions options = optionsSpec;
  for (int i = 0; i < archivePaths.Size(); i++)
  {
    const UString &archivePath = archivePaths[i];
    NFile::NFind::CFileInfoW archiveFileInfo;
    if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
      throw "there is no such archive";

    if (archiveFileInfo.IsDirectory())
      throw "there is no such archive";

    options.ArchiveFileInfo = archiveFileInfo;

    RINOK(extractCallback->BeforeOpen(archivePath));
    CArchiveLink archiveLink;
    HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback);
    RINOK(extractCallback->OpenResult(archivePath, result));
    if (result != S_OK)
      continue;

    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        archivePaths.Delete(index);
        archivePathsFull.Delete(index);
      }
    }

    #ifndef _NO_CRYPTO
    UString password;
    RINOK(openCallback->GetPasswordIfAny(password));
    if (!password.IsEmpty())
    {
      RINOK(extractCallback->SetPassword(password));
    }
    #endif

    options.DefaultItemName = archiveLink.GetDefaultItemName();
    RINOK(DecompressArchive(
        archiveLink.GetArchive(), archiveLink.GetDefaultItemName(),
        wildcardCensor, options, extractCallback));
  }
  return S_OK;
}
Пример #2
0
void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s)
{
  for (unsigned i = 0; i < list.Size();)
    if (s.IsEqualTo_NoCase(list[i]))
      list.Delete(i);
    else
      i++;
  list.Insert(0, s);
}
Пример #3
0
void CCensor::AddItem(bool include, const UString &path, bool recursive)
{
  UStringVector pathParts;
  SplitPathToParts(path, pathParts);
  bool forFile = true;
  if (pathParts.Back().IsEmpty())
  {
    forFile = false;
    pathParts.DeleteBack();
  }
  const UString &front = pathParts.Front();
  bool isAbs = false;
  if (front.IsEmpty())
    isAbs = true;
  else if (front.Length() == 2 && front[1] == L':')
    isAbs = true;
  else
  {
    for (int i = 0; i < pathParts.Size(); i++)
    {
      const UString &part = pathParts[i];
      if (part == L".." || part == L".")
      {
        isAbs = true;
        break;
      }
    }
  }
  int numAbsParts = 0;
  if (isAbs)
    if (pathParts.Size() > 1)
      numAbsParts = pathParts.Size() - 1;
    else
      numAbsParts = 1;
  UString prefix;
  for (int i = 0; i < numAbsParts; i++)
  {
    const UString &front = pathParts.Front();
    if (DoesNameContainWildCard(front))
      break;
    prefix += front;
    prefix += WCHAR_PATH_SEPARATOR;
    pathParts.Delete(0);
  }
  int index = FindPrefix(prefix);
  if (index < 0)
    index = Pairs.Add(CPair(prefix));

  CItem item;
  item.PathParts = pathParts;
  item.ForDir = true;
  item.ForFile = forFile;
  item.Recursive = recursive;
  Pairs[index].Head.AddItem(include, item);
}
void MakeCorrectPath(UStringVector &pathParts)
{
  for (int i = 0; i < pathParts.Size();)
  {
    UString &s = pathParts[i];
    s = GetCorrectFileName(s);
    if (s.IsEmpty())
      pathParts.Delete(i);
    else
      i++;
  }
}
void MakeCorrectPath(UStringVector &pathParts)
{
  for (int i = 0; i < pathParts.Size();)
  {
    UString &s = pathParts[i];
    s = GetCorrectFileName(s);
    if (s.IsEmpty())
      pathParts.Delete(i);
    else
    {
      #ifdef _WIN32
      if (!IsSupportedName(s))
        s = (UString)L"_" + s;
      #endif
      i++;
    }
  }
}
Пример #6
0
HRESULT DecompressArchives(
    CCodecs *codecs, const CIntVector &formatIndices,
    UStringVector &archivePaths, UStringVector &archivePathsFull,
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &optionsSpec,
    IOpenCallbackUI *openCallback,
    IExtractCallbackUI *extractCallback,
    UString &errorMessage,
    CDecompressStat &stat)
{
  stat.Clear();
  CExtractOptions options = optionsSpec;
  int i;
  UInt64 totalPackSize = 0;
  CRecordVector<UInt64> archiveSizes;
  for (i = 0; i < archivePaths.Size(); i++)
  {
    const UString &archivePath = archivePaths[i];
    NFile::NFind::CFileInfoW fi;
    if (!NFile::NFind::FindFile(archivePath, fi))
      throw "there is no such archive";
    if (fi.IsDir())
      throw "can't decompress folder";
    archiveSizes.Add(fi.Size);
    totalPackSize += fi.Size;
  }
  CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
  CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
  bool multi = (archivePaths.Size() > 1);
  extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
  if (multi)
  {
    RINOK(extractCallback->SetTotal(totalPackSize));
  }
  for (i = 0; i < archivePaths.Size(); i++)
  {
    const UString &archivePath = archivePaths[i];
    NFile::NFind::CFileInfoW fi;
    if (!NFile::NFind::FindFile(archivePath, fi))
      throw "there is no such archive";

    if (fi.IsDir())
      throw "there is no such archive";

    options.ArchiveFileInfo = fi;

    #ifndef _NO_CRYPTO
    openCallback->Open_ClearPasswordWasAskedFlag();
    #endif

    RINOK(extractCallback->BeforeOpen(archivePath));
    CArchiveLink archiveLink;

    CIntVector formatIndices2 = formatIndices;
    #ifndef _SFX
    if (formatIndices.IsEmpty())
    {
      int pos = archivePath.ReverseFind(L'.');
      if (pos >= 0)
      {
        UString s = archivePath.Mid(pos + 1);
        int index = codecs->FindFormatForExtension(s);
        if (index >= 0 && s == L"001")
        {
          s = archivePath.Left(pos);
          pos = s.ReverseFind(L'.');
          if (pos >= 0)
          {
            int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1));
            if (index2 >= 0 && s.CompareNoCase(L"rar") != 0)
            {
              formatIndices2.Add(index2);
              formatIndices2.Add(index);
            }
          }
        }
      }
    }
    #endif
    HRESULT result = MyOpenArchive(codecs, formatIndices2, archivePath, archiveLink, openCallback);
    if (result == E_ABORT)
      return result;

    bool crypted = false;
    #ifndef _NO_CRYPTO
    crypted = openCallback->Open_WasPasswordAsked();
    #endif

    RINOK(extractCallback->OpenResult(archivePath, result, crypted));
    if (result != S_OK)
      continue;

    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        archivePaths.Delete(index);
        archivePathsFull.Delete(index);
        totalPackSize -= archiveSizes[index];
        archiveSizes.Delete(index);
      }
    }
    if (archiveLink.VolumePaths.Size() != 0)
    {
      totalPackSize += archiveLink.VolumesSize;
      RINOK(extractCallback->SetTotal(totalPackSize));
    }

    #ifndef _NO_CRYPTO
    UString password;
    RINOK(openCallback->Open_GetPasswordIfAny(password));
    if (!password.IsEmpty())
    {
      RINOK(extractCallback->SetPassword(password));
    }
    #endif

    options.DefaultItemName = archiveLink.GetDefaultItemName();
    RINOK(DecompressArchive(
        archiveLink.GetArchive(),
        fi.Size + archiveLink.VolumesSize,
        wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage));
    extractCallbackSpec->LocalProgressSpec->InSize += fi.Size +
        archiveLink.VolumesSize;
    extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
    if (!errorMessage.IsEmpty())
      return E_FAIL;
  }
  stat.NumFolders = extractCallbackSpec->NumFolders;
  stat.NumFiles = extractCallbackSpec->NumFiles;
  stat.UnpackSize = extractCallbackSpec->UnpackSize;
  stat.NumArchives = archivePaths.Size();
  stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
  return S_OK;
}
Пример #7
0
HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
    bool stdInMode,
    UStringVector &arcPaths, UStringVector &arcPathsFull,
    const NWildcard::CCensorNode &wildcardCensor,
    bool enableHeaders, bool techMode,
    #ifndef _NO_CRYPTO
    bool &passwordEnabled, UString &password,
    #endif
    UInt64 &numErrors)
{
  numErrors = 0;
  CFieldPrinter fieldPrinter;
  if (!techMode)
    fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));

  UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
  UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
  int numArcs = /* stdInMode ? 1 : */ arcPaths.Size();
  for (int i = 0; i < numArcs; i++)
  {
    const UString &archiveName = arcPaths[i];
    UInt64 arcPackSize = 0;
    if (!stdInMode)
    {
      NFile::NFind::CFileInfoW fi;
      if (!fi.Find(archiveName) || fi.IsDir())
      {
        g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
        numErrors++;
        continue;
      }
      arcPackSize = fi.Size;
    }

    CArchiveLink archiveLink;

    COpenCallbackConsole openCallback;
    openCallback.OutStream = &g_StdOut;

    #ifndef _NO_CRYPTO

    openCallback.PasswordIsDefined = passwordEnabled;
    openCallback.Password = password;

    #endif

    HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archiveName, &openCallback);
    if (result != S_OK)
    {
      if (result == E_ABORT)
        return result;
      g_StdOut << endl << "Error: " << archiveName << ": ";
      if (result == S_FALSE)
      {
        #ifndef _NO_CRYPTO
        if (openCallback.Open_WasPasswordAsked())
          g_StdOut << "Can not open encrypted archive. Wrong password?";
        else
        #endif
          g_StdOut << "Can not open file as archive";
      }
      else if (result == E_OUTOFMEMORY)
        g_StdOut << "Can't allocate required memory";
      else
        g_StdOut << NError::MyFormatMessage(result);
      g_StdOut << endl;
      numErrors++;
      continue;
    }

    if (!stdInMode)
    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        arcPaths.Delete(index);
        arcPathsFull.Delete(index);
        numArcs = arcPaths.Size();
      }
    }

    if (enableHeaders)
    {
      g_StdOut << endl << kListing << archiveName << endl << endl;

      for (int i = 0; i < archiveLink.Arcs.Size(); i++)
      {
        const CArc &arc = archiveLink.Arcs[i];
        
        g_StdOut << "--\n";
        PrintPropPair(L"Path", arc.Path);
        PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
        if (!arc.ErrorMessage.IsEmpty())
          PrintPropPair(L"Error", arc.ErrorMessage);
        UInt32 numProps;
        IInArchive *archive = arc.Archive;
        if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
        {
          for (UInt32 j = 0; j < numProps; j++)
          {
            CMyComBSTR name;
            PROPID propID;
            VARTYPE vt;
            RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt));
            NCOM::CPropVariant prop;
            RINOK(archive->GetArchiveProperty(propID, &prop));
            UString s = ConvertPropertyToString(prop, propID);
            if (!s.IsEmpty())
              PrintPropPair(GetPropName(propID, name), s);
          }
        }
        if (i != archiveLink.Arcs.Size() - 1)
        {
          UInt32 numProps;
          g_StdOut << "----\n";
          if (archive->GetNumberOfProperties(&numProps) == S_OK)
          {
            UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex;
            for (UInt32 j = 0; j < numProps; j++)
            {
              CMyComBSTR name;
              PROPID propID;
              VARTYPE vt;
              RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt));
              NCOM::CPropVariant prop;
              RINOK(archive->GetProperty(mainIndex, propID, &prop));
              UString s = ConvertPropertyToString(prop, propID);
              if (!s.IsEmpty())
                PrintPropPair(GetPropName(propID, name), s);
            }
          }
        }
        
      }
      g_StdOut << endl;
      if (techMode)
        g_StdOut << "----------\n";
    }

    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitle();
      g_StdOut << endl;
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
    }

    const CArc &arc = archiveLink.Arcs.Back();
    IInArchive *archive = arc.Archive;
    if (techMode)
    {
      RINOK(fieldPrinter.Init(archive));
    }
    UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
    UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
    UInt32 numItems;
    RINOK(archive->GetNumberOfItems(&numItems));
    for (UInt32 i = 0; i < numItems; i++)
    {
      if (NConsoleClose::TestBreakSignal())
        return E_ABORT;

      UString filePath;
      HRESULT res = arc.GetItemPath(i, filePath);
      if (stdInMode && res == E_INVALIDARG)
        break;
      RINOK(res);

      bool isFolder;
      RINOK(IsArchiveItemFolder(archive, i, isFolder));
      if (!wildcardCensor.CheckPath(filePath, !isFolder))
        continue;
      
      fieldPrinter.PrintItemInfo(arc, i, techMode);
      
      UInt64 packSize, unpackSize;
      if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
        unpackSize = 0;
      else
        totalUnPackSizePointer = &totalUnPackSize;
      if (!GetUInt64Value(archive, i, kpidPackSize, packSize))
        packSize = 0;
      else
        totalPackSizePointer = &totalPackSize;
      
      g_StdOut << endl;

      if (isFolder)
        numDirs++;
      else
        numFiles++;
      totalPackSize += packSize;
      totalUnPackSize += unpackSize;
    }

    if (!stdInMode && totalPackSizePointer == 0)
    {
      if (archiveLink.VolumePaths.Size() != 0)
        arcPackSize += archiveLink.VolumesSize;
      totalPackSize = (numFiles == 0) ? 0 : arcPackSize;
      totalPackSizePointer = &totalPackSize;
    }
    if (totalUnPackSizePointer == 0 && numFiles == 0)
    {
      totalUnPackSize = 0;
      totalUnPackSizePointer = &totalUnPackSize;
    }
    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
      fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
      g_StdOut << endl;
    }
    if (totalPackSizePointer != 0)
    {
      totalPackSizePointer2 = &totalPackSize2;
      totalPackSize2 += totalPackSize;
    }
    if (totalUnPackSizePointer != 0)
    {
      totalUnPackSizePointer2 = &totalUnPackSize2;
      totalUnPackSize2 += totalUnPackSize;
    }
    numFiles2 += numFiles;
    numDirs2 += numDirs;
  }
  if (enableHeaders && !techMode && numArcs > 1)
  {
    g_StdOut << endl;
    fieldPrinter.PrintTitleLines();
    g_StdOut << endl;
    fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
    g_StdOut << endl;
    g_StdOut << "Archives: " << numArcs << endl;
  }
  return S_OK;
}
Пример #8
0
int Main2(int argc,TCHAR **argv)
{
  UStringVector commandStrings;
  #ifdef _WIN32  
  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
  #else
  extern void mySplitCommandLineW(int numArguments,TCHAR  **arguments,UStringVector &parts);
  mySplitCommandLineW(argc,argv,commandStrings);
  #endif

  #ifndef UNDER_CE
  if (commandStrings.Size() > 0)
    commandStrings.Delete(0);
  #endif
  if (commandStrings.Size() == 0)
  {
    MessageBoxW(0, L"Specify command", L"7-Zip", 0);
    return 0;
  }
	
/*	
  {
    CSysString resultPath;
	NWindows::NFile::NDirectory::MyGetCurrentDirectory(resultPath);
	
	::MessageBoxW(0, resultPath, L"7-Zip - curDir", 0);
  }
*/

  CArchiveCommandLineOptions options;
  CArchiveCommandLineParser parser;

  parser.Parse1(commandStrings, options);
  parser.Parse2(options);

  #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
  if (options.LargePages)
    NSecurity::EnableLockMemoryPrivilege();
  #endif

  CCodecs *codecs = new CCodecs;
  CMyComPtr<IUnknown> compressCodecsInfo = codecs;
  HRESULT result = codecs->Load();
  if (result != S_OK)
    throw CSystemException(result);
  
  bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
  if (codecs->Formats.Size() == 0 &&
        (isExtractGroupCommand ||
        options.Command.IsFromUpdateGroup()))
    throw kNoFormats;

  CIntVector formatIndices;
  if (!codecs->FindFormatForArchiveType(options.ArcType, formatIndices))
  {
    ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE, 0x0200060D);
    return NExitCode::kFatalError;
  }

  if (options.Command.CommandType == NCommandType::kBenchmark)
  {
    HRESULT res;
    #ifdef EXTERNAL_CODECS
    CObjectVector<CCodecInfoEx> externalCodecs;
    res = LoadExternalCodecs(codecs, externalCodecs);
    if (res != S_OK)
      throw CSystemException(res);
    #endif
    res = Benchmark(
      #ifdef EXTERNAL_CODECS
      codecs, &externalCodecs,
      #endif
      options.NumThreads, options.DictionarySize);
    if (res != S_OK)
      throw CSystemException(res);
  }
  else if (isExtractGroupCommand)
  {
    CExtractCallbackImp *ecs = new CExtractCallbackImp;
    CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;

    #ifndef _NO_CRYPTO
    ecs->PasswordIsDefined = options.PasswordEnabled;
    ecs->Password = options.Password;
    #endif

    ecs->Init();

    CExtractOptions eo;
    eo.StdOutMode = options.StdOutMode;
    eo.OutputDir = options.OutputDir;
    eo.YesToAll = options.YesToAll;
    eo.OverwriteMode = options.OverwriteMode;
    eo.PathMode = options.Command.GetPathMode();
    eo.TestMode = options.Command.IsTestMode();
    eo.CalcCrc = options.CalcCrc;
    #if !defined(_7ZIP_ST) && !defined(_SFX)
    eo.Properties = options.ExtractProperties;
    #endif

    bool messageWasDisplayed = false;
    HRESULT result = ExtractGUI(codecs, formatIndices,
          options.ArchivePathsSorted,
          options.ArchivePathsFullSorted,
          options.WildcardCensor.Pairs.Front().Head,
          eo, options.ShowDialog, messageWasDisplayed, ecs);
    if (result != S_OK)
    {
      if (result != E_ABORT && messageWasDisplayed)
        return NExitCode::kFatalError;
      throw CSystemException(result);
    }
    if (!ecs->IsOK())
      return NExitCode::kFatalError;
  }
  else if (options.Command.IsFromUpdateGroup())
  {
    #ifndef _NO_CRYPTO
    bool passwordIsDefined = options.PasswordEnabled && !options.Password.IsEmpty();
    #endif

    CUpdateCallbackGUI callback;
    // callback.EnablePercents = options.EnablePercents;

    #ifndef _NO_CRYPTO
    callback.PasswordIsDefined = passwordIsDefined;
    callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
    callback.Password = options.Password;
    #endif

    // callback.StdOutMode = options.UpdateOptions.StdOutMode;
    callback.Init();

    if (!options.UpdateOptions.Init(codecs, formatIndices, options.ArchiveName))
    {
      ErrorLangMessage(IDS_UPDATE_NOT_SUPPORTED, 0x02000601);
      return NExitCode::kFatalError;
    }
    bool messageWasDisplayed = false;
    HRESULT result = UpdateGUI(
        codecs,
        options.WildcardCensor, options.UpdateOptions,
        options.ShowDialog,
        messageWasDisplayed, &callback);

    if (result != S_OK)
    {
      if (result != E_ABORT && messageWasDisplayed)
        return NExitCode::kFatalError;
      throw CSystemException(result);
    }
    if (callback.FailedFiles.Size() > 0)
    {
      if (!messageWasDisplayed)
        throw CSystemException(E_FAIL);
      return NExitCode::kWarning;
    }
  }
  else
  {
    throw "Unsupported command";
  }
  return 0;
}
Пример #9
0
int Main2(
#ifndef _WIN32
    int numArgs, char *args[]
#endif
)
{
#if defined(_WIN32) && !defined(UNDER_CE)
    SetFileApisToOEM();
#endif

    g_StdOut << kCopyrightString;

    UStringVector commandStrings;
#ifdef _WIN32
    NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
#else
    // GetArguments(numArgs, args, commandStrings);
    mySplitCommandLine(numArgs,args,commandStrings);
#endif

#ifdef _WIN32

    FString arcPath;
    {
        FString path;
        NDLL::MyGetModuleFileName(path);
        if (!MyGetFullPathName(path, arcPath))
        {
            g_StdOut << "GetFullPathName Error";
            return NExitCode::kFatalError;
        }
    }

#else
    // After mySplitCommandLine
    showP7zipInfo(&g_StdOut);

    UString arcPath = commandStrings.Front();

#endif

    commandStrings.Delete(0);

    NCommandLineParser::CParser parser(kNumSwitches);
    try
    {
        parser.ParseStrings(kSwitchForms, commandStrings);
    }
    catch(...)
    {
        PrintHelpAndExit();
    }

    if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
    {
        PrintHelp();
        return 0;
    }
    const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

    int numNonSwitchStrings = nonSwitchStrings.Size();

    CArchiveCommand command;
    if (numNonSwitchStrings == 0)
        command.CommandType = NCommandType::kFullExtract;
    else
    {
        if (numNonSwitchStrings > 1)
            PrintHelpAndExit();
        if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command))
            PrintHelpAndExit();
    }


    NRecursedType::EEnum recursedType;
    recursedType = command.DefaultRecursedType();

    NWildcard::CCensor wildcardCensor;

    bool thereAreSwitchIncludeWildcards;
    thereAreSwitchIncludeWildcards = false;

    AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType,
                                      thereAreSwitchIncludeWildcards);

    bool yesToAll = parser[NKey::kYes].ThereIs;

    // NExtractMode::EEnum extractMode;
    // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);

    bool passwordEnabled = parser[NKey::kPassword].ThereIs;

    UString password;
    if (passwordEnabled)
        password = parser[NKey::kPassword].PostStrings[0];

    if (!NFind::DoesFileExist(arcPath))
        throw kCantFindSFX;

    FString outputDir;
    if (parser[NKey::kOutputDir].ThereIs)
    {
        outputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
        NName::NormalizeDirPathPrefix(outputDir);
    }


    wildcardCensor.AddPathsToCensor(NWildcard::k_RelatPath);

    {
        UStringVector v1, v2;
        v1.Add(fs2us(arcPath));
        v2.Add(fs2us(arcPath));
        const NWildcard::CCensorNode &wildcardCensorHead =
            wildcardCensor.Pairs.Front().Head;

        CCodecs *codecs = new CCodecs;
        CMyComPtr<
#ifdef EXTERNAL_CODECS
        ICompressCodecsInfo
#else
        IUnknown
#endif
        > compressCodecsInfo = codecs;
        {
            HRESULT result = codecs->Load();
            if (result != S_OK)
                throw CSystemException(result);
        }

        if (command.CommandType != NCommandType::kList)
        {
            CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
            CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
            ecs->Init(g_StdStream, &g_StdErr, g_StdStream);

#ifndef _NO_CRYPTO
            ecs->PasswordIsDefined = passwordEnabled;
            ecs->Password = password;
#endif

            /*
            COpenCallbackConsole openCallback;
            openCallback.Init(g_StdStream, g_StdStream);

            #ifndef _NO_CRYPTO
            openCallback.PasswordIsDefined = passwordEnabled;
            openCallback.Password = password;
            #endif
            */

            CExtractOptions eo;
            eo.StdOutMode = false;
            eo.YesToAll = yesToAll;
            eo.TestMode = command.CommandType == NCommandType::kTest;
            eo.PathMode = NExtract::NPathMode::kFullPaths;
            eo.OverwriteMode = yesToAll ?
                               NExtract::NOverwriteMode::kOverwrite :
                               NExtract::NOverwriteMode::kAsk;
            eo.OutputDir = outputDir;

            UString errorMessage;
            CDecompressStat stat;
            HRESULT result = Extract(
                                 codecs, CObjectVector<COpenType>(), CIntVector(),
                                 v1, v2,
                                 wildcardCensorHead,
                                 eo, ecs, ecs,
                                 // NULL, // hash
                                 errorMessage, stat);
            if (!errorMessage.IsEmpty())
            {
                (*g_StdStream) << endl << "Error: " << errorMessage;;
                if (result == S_OK)
                    result = E_FAIL;
            }

            if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0)
            {
                if (ecs->NumArcsWithError != 0)
                    (*g_StdStream) << endl << "Archive Errors" << endl;
                if (ecs->NumFileErrors != 0)
                    (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl;
                return NExitCode::kFatalError;
            }
            if (result != S_OK)
                throw CSystemException(result);
        }
        else
        {
            throw CSystemException(E_NOTIMPL);

            /*
            UInt64 numErrors = 0;
            UInt64 numWarnings = 0;
            HRESULT result = ListArchives(
                codecs, CObjectVector<COpenType>(), CIntVector(),
                false, // stdInMode
                v1, v2,
                true, // processAltStreams
                false, // showAltStreams
                wildcardCensorHead,
                true, // enableHeaders
                false, // techMode
                #ifndef _NO_CRYPTO
                passwordEnabled, password,
                #endif
                numErrors, numWarnings);
            if (numErrors > 0)
            {
              g_StdOut << endl << "Errors: " << numErrors;
              return NExitCode::kFatalError;
            }
            if (result != S_OK)
              throw CSystemException(result);
            */
        }
    }
    return 0;
}
Пример #10
0
int APIENTRY WinMain2()
{
  UString password;
  bool assumeYes = false;
  bool outputFolderDefined = false;
  UString outputFolder;
  UStringVector commandStrings;
  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);

  #ifndef UNDER_CE
  if (commandStrings.Size() > 0)
    commandStrings.Delete(0);
  #endif

  for (int i = 0; i < commandStrings.Size(); i++)
  {
    const UString &s = commandStrings[i];
    if (s.CompareNoCase(L"-y") == 0)
      assumeYes = true;
    else if (s.Left(2).CompareNoCase(L"-o") == 0)
    {
      outputFolder = s.Mid(2);
      NWindows::NFile::NName::NormalizeDirPathPrefix(outputFolder);
      outputFolderDefined = !outputFolder.IsEmpty();
    }
    else if (s.Left(2).CompareNoCase(L"-p") == 0)
    {
      password = s.Mid(2);
    }
  }

  UString path;
  NWindows::NDLL::MyGetModuleFileName(g_hInstance, path);

  UString fullPath;
  int fileNamePartStartIndex;
  if (!NWindows::NFile::NDirectory::MyGetFullPathName(path, fullPath, fileNamePartStartIndex))
  {
    ShowErrorMessage(L"Error 1329484");
    return 1;
  }

  CCodecs *codecs = new CCodecs;
  CMyComPtr<IUnknown> compressCodecsInfo = codecs;
  HRESULT result = codecs->Load();
  if (result != S_OK)
  {
    ErrorMessageForHRESULT(result);
    return 1;
  }

  // COpenCallbackGUI openCallback;

  // openCallback.PasswordIsDefined = !password.IsEmpty();
  // openCallback.Password = password;

  CExtractCallbackImp *ecs = new CExtractCallbackImp;
  CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
  ecs->Init();

  #ifndef _NO_CRYPTO
  ecs->PasswordIsDefined = !password.IsEmpty();
  ecs->Password = password;
  #endif

  CExtractOptions eo;
  eo.OutputDir = outputFolderDefined ? outputFolder :
      fullPath.Left(fileNamePartStartIndex);
  eo.YesToAll = assumeYes;
  eo.OverwriteMode = assumeYes ?
      NExtract::NOverwriteMode::kWithoutPrompt :
      NExtract::NOverwriteMode::kAskBefore;
  eo.PathMode = NExtract::NPathMode::kFullPathnames;
  eo.TestMode = false;
  
  UStringVector v1, v2;
  v1.Add(fullPath);
  v2.Add(fullPath);
  NWildcard::CCensorNode wildcardCensor;
  wildcardCensor.AddItem(true, L"*", true, true, true);

  bool messageWasDisplayed = false;
  result = ExtractGUI(codecs, CIntVector(), v1, v2,
      wildcardCensor, eo, (assumeYes ? false: true), messageWasDisplayed, ecs);

  if (result == S_OK)
  {
    if (!ecs->IsOK())
      return NExitCode::kFatalError;
    return 0;
  }
  if (result == E_ABORT)
    return NExitCode::kUserBreak;
  if (!messageWasDisplayed)
  {
    if (result == S_FALSE)
      ShowErrorMessage(L"Error in archive");
    else
      ErrorMessageForHRESULT(result);
  }
  if (result == E_OUTOFMEMORY)
    return NExitCode::kMemoryError;
  return NExitCode::kFatalError;
}
Пример #11
0
int APIENTRY WinMain2()
{
  // OleInitialize is required for ProgressBar in TaskBar.
  #ifndef UNDER_CE
  OleInitialize(NULL);
  #endif

  #ifndef UNDER_CE
  g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
  g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
  #endif
  
  UString password;
  bool assumeYes = false;
  bool outputFolderDefined = false;
  FString outputFolder;
  UStringVector commandStrings;
  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);

  #ifndef UNDER_CE
  if (commandStrings.Size() > 0)
    commandStrings.Delete(0);
  #endif

  FOR_VECTOR (i, commandStrings)
  {
    const UString &s = commandStrings[i];
    if (s.Len() > 1 && s[0] == '-')
    {
      wchar_t c = MyCharLower_Ascii(s[1]);
      if (c == 'y')
      {
        assumeYes = true;
        if (s.Len() != 2)
        {
          ShowErrorMessage(L"Bad command");
          return 1;
        }
      }
      else if (c == 'o')
      {
        outputFolder = us2fs(s.Ptr(2));
        NName::NormalizeDirPathPrefix(outputFolder);
        outputFolderDefined = !outputFolder.IsEmpty();
      }
      else if (c == 'p')
      {
        password = s.Ptr(2);
      }
    }
  }

  FString path;
  NDLL::MyGetModuleFileName(path);

  FString fullPath;
  if (!MyGetFullPathName(path, fullPath))
  {
    ShowErrorMessage(L"Error 1329484");
    return 1;
  }

  CCodecs *codecs = new CCodecs;
  CMyComPtr<IUnknown> compressCodecsInfo = codecs;
  HRESULT result = codecs->Load();
  if (result != S_OK)
  {
    ErrorMessageForHRESULT(result);
    return 1;
  }

  // COpenCallbackGUI openCallback;

  // openCallback.PasswordIsDefined = !password.IsEmpty();
  // openCallback.Password = password;

  CExtractCallbackImp *ecs = new CExtractCallbackImp;
  CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
  ecs->Init();

  #ifndef _NO_CRYPTO
  ecs->PasswordIsDefined = !password.IsEmpty();
  ecs->Password = password;
  #endif

  CExtractOptions eo;

  FString dirPrefix;
  if (!GetOnlyDirPrefix(path, dirPrefix))
  {
    ShowErrorMessage(L"Error 1329485");
    return 1;
  }

  eo.OutputDir = outputFolderDefined ? outputFolder : dirPrefix;
  eo.YesToAll = assumeYes;
  eo.OverwriteMode = assumeYes ?
      NExtract::NOverwriteMode::kOverwrite :
      NExtract::NOverwriteMode::kAsk;
  eo.PathMode = NExtract::NPathMode::kFullPaths;
  eo.TestMode = false;
  
  UStringVector v1, v2;
  v1.Add(fs2us(fullPath));
  v2.Add(fs2us(fullPath));
  NWildcard::CCensorNode wildcardCensor;
  wildcardCensor.AddItem(true, L"*", true, true, true, true);

  bool messageWasDisplayed = false;
  result = ExtractGUI(codecs,
      CObjectVector<COpenType>(), CIntVector(),
      v1, v2,
      wildcardCensor, eo, (assumeYes ? false: true), messageWasDisplayed, ecs);

  if (result == S_OK)
  {
    if (!ecs->IsOK())
      return NExitCode::kFatalError;
    return 0;
  }
  if (result == E_ABORT)
    return NExitCode::kUserBreak;
  if (!messageWasDisplayed)
  {
    if (result == S_FALSE)
      ShowErrorMessage(L"Error in archive");
    else
      ErrorMessageForHRESULT(result);
  }
  if (result == E_OUTOFMEMORY)
    return NExitCode::kMemoryError;
  return NExitCode::kFatalError;
}
Пример #12
0
HRESULT ListArchives(
    CCodecs *codecs,
    UStringVector &archivePaths, UStringVector &archivePathsFull,
    const NWildcard::CCensorNode &wildcardCensor,
    bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &numErrors)
{
  numErrors = 0;
  CFieldPrinter fieldPrinter;
  if (!techMode)
    fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));

  UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
  UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
  for (int i = 0; i < archivePaths.Size(); i++)
  {
    const UString &archiveName = archivePaths[i];
    NFile::NFind::CFileInfoW archiveFileInfo;
    if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
    {
      g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;
      numErrors++;
      continue;
    }
    if (archiveFileInfo.IsDirectory())
    {
      g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
      numErrors++;
      continue;
    }

    CArchiveLink archiveLink;

    COpenCallbackConsole openCallback;
    openCallback.OutStream = &g_StdOut;
    openCallback.PasswordIsDefined = passwordEnabled;
    openCallback.Password = password;

    HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, &openCallback);
    if (result != S_OK)
    {
      g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;
      numErrors++;
      continue;
    }

    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        archivePaths.Delete(index);
        archivePathsFull.Delete(index);
      }
    }

    IInArchive *archive = archiveLink.GetArchive();
    const UString defaultItemName = archiveLink.GetDefaultItemName();

    if (enableHeaders)
    {
      g_StdOut << endl << kListing << archiveName << endl << endl;

      UInt32 numProps;
      if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
      {
        for (UInt32 i = 0; i < numProps; i++)
        {
          CMyComBSTR name;
          PROPID propID;
          VARTYPE vt;
          if (archive->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
            continue;
          NCOM::CPropVariant prop;
          if (archive->GetArchiveProperty(propID, &prop) != S_OK)
            continue;
          UString s = ConvertPropertyToString(prop, propID);
          if (!s.IsEmpty())
            g_StdOut << GetPropName(propID, name) << " = " << s << endl;
        }
      }
      if (techMode)
        g_StdOut << "----------\n";
      if (numProps > 0)
        g_StdOut << endl;
    }

    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitle();
      g_StdOut << endl;
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
    }

    if (techMode)
    {
      RINOK(fieldPrinter.Init(archive));
    }
    UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
    UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
    UInt32 numItems;
    RINOK(archive->GetNumberOfItems(&numItems));
    for(UInt32 i = 0; i < numItems; i++)
    {
      if (NConsoleClose::TestBreakSignal())
        return E_ABORT;

      UString filePath;
      RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));

      bool isFolder;
      RINOK(IsArchiveItemFolder(archive, i, isFolder));
      if (!wildcardCensor.CheckPath(filePath, !isFolder))
        continue;
      
      fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode);
      
      UInt64 packSize, unpackSize;
      if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
        unpackSize = 0;
      else
        totalUnPackSizePointer = &totalUnPackSize;
      if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))
        packSize = 0;
      else
        totalPackSizePointer = &totalPackSize;
      
      g_StdOut << endl;

      if (isFolder)
        numDirs++;
      else
        numFiles++;
      totalPackSize += packSize;
      totalUnPackSize += unpackSize;
    }
    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
      fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
      g_StdOut << endl;
    }
    if (totalPackSizePointer != 0)
    {
      totalPackSizePointer2 = &totalPackSize2;
      totalPackSize2 += totalPackSize;
    }
    if (totalUnPackSizePointer != 0)
    {
      totalUnPackSizePointer2 = &totalUnPackSize2;
      totalUnPackSize2 += totalUnPackSize;
    }
    numFiles2 += numFiles;
    numDirs2 += numDirs;
  }
  if (enableHeaders && !techMode && archivePaths.Size() > 1)
  {
    g_StdOut << endl;
    fieldPrinter.PrintTitleLines();
    g_StdOut << endl;
    fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
    g_StdOut << endl;
    g_StdOut << "Archives: " << archivePaths.Size() << endl;
  }
  return S_OK;
}
Пример #13
0
// Create a new 7z archive for each folder contained in the archive to be
// exploded.
HRESULT ExplodeArchives(CCodecs *codecs, const CIntVector &formatIndices,
	bool stdInMode,
	UStringVector &arcPaths, UStringVector &arcPathsFull,
	UString& outputPath, UInt64 maxDepth, UInt64 &numErrors)
{
	int numArcs = arcPaths.Size();
	for (int i = 0; i < numArcs; i++)
	{
		UString archivePath = arcPaths[i];
		
		/*UString outputPath = arcPaths[i];
		outputPath.Replace(L'\\', L'/'); // linux and windows consistent
		const UString archiveName = StripFile(outputPath);
		outputPath.Empty();*/
		archivePath.Replace(L'\\', L'/'); // linux, windows and archive consistent
		outputPath.Replace(L'\\', L'/'); 
		FixPathFormat(outputPath);
		const UString archiveName = GetFileFromPath(archivePath);

		g_StdOut << "Outputting into : " << outputPath << endl;

		UInt64 arcPackSize = 0;
		if (!stdInMode)
		{
			NFile::NFind::CFileInfoW fi;
			if (!fi.Find(archivePath) || fi.IsDir())
			{
				SHOW_ERROR("is not a file.");
				continue;
			}
			arcPackSize = fi.Size;
		}

		g_StdOut << endl << "Exploding : " << archivePath << endl << endl;

		CArchiveLink archiveLink;

		COpenCallbackConsole openCallback;
		openCallback.OutStream = &g_StdOut;

#ifndef _NO_CRYPTO
		openCallback.PasswordIsDefined = false;
#endif

		HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archivePath, &openCallback);
	
		if (result != S_OK)
		{
			if (result == E_ABORT)
				return result;
			g_StdOut << endl << "Error: " << archivePath << ": ";
			if (result == S_FALSE)
				g_StdOut << "Can not open file as archive";
			else if (result == E_OUTOFMEMORY)
				g_StdOut << "Can't allocate required memory";
			else
				g_StdOut << NError::MyFormatMessage(result);
			g_StdOut << endl;
			numErrors++;
			continue;
		}

		// remove other files names if multi-volume
		if (!stdInMode) {
			for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
			{
				int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
				if (index >= 0 && index > i)
				{
					arcPaths.Delete(index);
					arcPathsFull.Delete(index);
					numArcs = arcPaths.Size();
				}
			}
		}

		// don't support multi volume because i have to reopen the stream
		if (archiveLink.VolumePaths.Size() != 1) {
			SHOW_ERROR("Exploding multi-volume archives isn't supported.");
			continue;
		}

		bool szArchive = true;
		for (int x = 0; x < archiveLink.Arcs.Size(); x++)
		{
			const UString szName = L"7z";
			const CArc &arc = archiveLink.Arcs[x];
			if (codecs->Formats[arc.FormatIndex].Name != szName) {
				szArchive = false;
				break;
			}
		}

		if (!szArchive) {
			SHOW_ERROR("Only 7z archives can be exploded.");
			continue;
		}

		// Only 7z is supported, and it's been checked
		using namespace NArchive::N7z;
		IInArchive* inArc = archiveLink.GetArchive();
		CHandler* szHandler = (CHandler*)inArc;

		// not a fan of having to reopen the file..
		CInFileStream* _inStream = new CInFileStream;
		CMyComPtr<CInFileStream> inStream(_inStream);
		if (!inStream->Open(archivePath)) {
			SHOW_ERROR("Cannot be opened for reading.");
			continue;
		}	

		// Explode the archive into each folder
		CObjectVector<szExplodeData> exploded;
		szHandler->Explode(exploded, maxDepth);
	
		if (exploded.Size() == 0) {
			SHOW_ERROR("Empty archive!");
			continue;
		}

		// should make a struct that gets passed to Explode.. 
		// something like
		/*
		 * struct a {
		 *	CArchiveDatabase newDatabase;
		 *	CRecordVector<UInt64> folderSizes, folderPositions	
		 * };
		 * CObjectVector<a> exploded;
		 * szHandler->Explode(exploded);
		 */
		
		// Save each folder as a new 7z archive
		for (int x = 0; x < exploded.Size(); x++) {		
			UString relativeFilePath; // relative to archive
			UString fileName;
			CArchiveDatabase& newDatabase = exploded[x].newDatabase;
			szExplodeData& explodeData = exploded[x];

			// each exploded archive will only have a single folder.
			// no longer true. need to make sure the selected file
			// is the highest in the dir tree. could make 7zhandler
			// give us this info i guess.
			if (newDatabase.Files.Size() > 0) {
				relativeFilePath = newDatabase.Files[0].Name;
				if (!newDatabase.Files[0].IsDir) {
					fileName = GetFileFromPath(relativeFilePath);
					StripFile(relativeFilePath);
				}
			}

			//g_StdOut << "Relative path " << relativeFilePath << endl;
			//g_StdOut << "Archive " << archivePath << endl;

			UString folderOutPath = outputPath + relativeFilePath;
			if (relativeFilePath.Length() != 0) {
				bool b = NWindows::NFile::NDirectory::CreateComplexDirectory(folderOutPath);
				if (!b) g_StdOut << "Couldn't create directory " << folderOutPath << endl;
				//relativeFilePath.Insert(folderOutPath.Length(), L'/');
			}

			std::wstringstream sstream;
			sstream << folderOutPath.GetBuffer();
			
			if (newDatabase.Files.Size() == 1) // can use file names
				sstream << fileName.GetBuffer();
			else // use folder as name 
				sstream << archiveName.GetBuffer() << L"_folder_" << x;
			sstream << ".7z";
			
			g_StdOut << "Saving as '" << sstream.str().c_str() << "'" << endl;

			COutFileStream* _outstream = new COutFileStream;
			CMyComPtr<COutFileStream> outstream(_outstream);
			outstream->Create(sstream.str().c_str(), true);

			COutArchive out;
			out.Create(outstream, false);
			out.SkipPrefixArchiveHeader();
	
			for (int folderIndex = 0; folderIndex < newDatabase.Folders.Size(); 
				folderIndex++)
			{
				UInt64 folderLen = explodeData.folderSizes[folderIndex];
				UInt64 folderStartPackPos = explodeData.folderPositions[folderIndex];

				// write actual data
				RINOK(WriteRange(inStream, out.SeqStream, 
					folderStartPackPos, folderLen, NULL));
			}			

			CCompressionMethodMode method, headerMethod;
			szHandler->SetCompressionMethod(method, headerMethod);

			CHeaderOptions headerOptions;
			headerOptions.CompressMainHeader = true;

			out.WriteDatabase(newDatabase, &headerMethod, headerOptions);
			out.Close();

/*#ifdef ENV_UNIX
			// Create a symlink for each file in the folder.
			// This makes it seem as though each file is individually accessible.
			for (int fileIndex = 0; fileIndex < newDatabase.Files.Size(); fileIndex++) {
				AString oldfile, newfile;
				UString woldfile = sstream.str().c_str();
				UString wnewfile = outputPath + relativeFilePath + newDatabase.Files[fileIndex].Name + L".7z";
				ConvertUnicodeToUTF8(woldfile, oldfile);
				ConvertUnicodeToUTF8(wnewfile, newfile);
				const char* link_to = oldfile.GetBuffer();
				const char* link_name = newfile.GetBuffer();
				unlink(link_name);// should ask user
				//g_StdOut << "Creating symlink to '" << link_to << "' called '" << link_name << "'" << endl;
				int status = symlink(link_to, link_name);
				if (status == -1) {
					AString error = "Couldn't create symlink for '";
					error += newfile;
					error += "'";
					SHOW_ERROR(error);
					g_StdOut << "Error: " << errno << endl;
					
				}
			}
#endif*/
		}		

		archiveLink.Close(); // not needed but oh well
	}

	return S_OK;
}
Пример #14
0
void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
{
  unsigned i = 0;

  if (absIsAllowed)
  {
    #if defined(_WIN32) && !defined(UNDER_CE)
    bool isDrive = false;
    #endif
    if (parts[0].IsEmpty())
    {
      i = 1;
      #if defined(_WIN32) && !defined(UNDER_CE)
      if (parts.Size() > 1 && parts[1].IsEmpty())
      {
        i = 2;
        if (parts.Size() > 2 && parts[2] == L"?")
        {
          i = 3;
          if (parts.Size() > 3  && NWindows::NFile::NName::IsDrivePath2(parts[3]))
          {
            isDrive = true;
            i = 4;
          }
        }
      }
      #endif
    }
    #if defined(_WIN32) && !defined(UNDER_CE)
    else if (NWindows::NFile::NName::IsDrivePath2(parts[0]))
    {
      isDrive = true;
      i = 1;
    }

    if (isDrive)
    {
      // we convert "c:name" to "c:\name", if absIsAllowed path.
      UString &ds = parts[i - 1];
      if (ds.Len() > 2)
      {
        parts.Insert(i, ds.Ptr(2));
        ds.DeleteFrom(2);
      }
    }
    #endif
  }

  for (; i < parts.Size();)
  {
    UString &s = parts[i];

    Correct_PathPart(s);

    if (s.IsEmpty())
    {
      if (isDir || i != parts.Size() - 1)
      {
        parts.Delete(i);
        continue;
      }
      s = k_EmptyReplaceName;
    }
    else
    {
      #ifdef _WIN32
      CorrectUnsupportedName(s);
      #endif
    }
    
    i++;
  }

  if (!isDir)
  {
    if (parts.IsEmpty())
      parts.Add((UString)k_EmptyReplaceName);
    else
    {
      UString &s = parts.Back();
      if (s.IsEmpty())
        s = k_EmptyReplaceName;
    }
  }
}
Пример #15
0
Файл: Main.cpp Проект: bks/qz7
int Main2(
  #ifndef _WIN32
  int numArguments, const char *arguments[]
  #endif
)
{
  #ifdef _WIN32
  SetFileApisToOEM();
  #endif
  
  g_StdOut << kCopyrightString;

  UStringVector commandStrings;
  #ifdef _WIN32
  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
  #else
  GetArguments(numArguments, arguments, commandStrings);
  #endif

  UString archiveName = commandStrings.Front();

  commandStrings.Delete(0);

  NCommandLineParser::CParser parser(kNumSwitches);
  try
  {
    parser.ParseStrings(kSwitchForms, commandStrings);
  }
  catch(...)
  {
    PrintHelpAndExit();
  }

  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  {
    PrintHelp();
    return 0;
  }
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

  int numNonSwitchStrings = nonSwitchStrings.Size();

  CArchiveCommand command;
  if (numNonSwitchStrings == 0)
    command.CommandType = NCommandType::kFullExtract;
  else
  {
    if (numNonSwitchStrings > 1)
      PrintHelpAndExit();
    if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command))
      PrintHelpAndExit();
  }


  NRecursedType::EEnum recursedType;
  recursedType = command.DefaultRecursedType();

  NWildcard::CCensor wildcardCensor;
  
  bool thereAreSwitchIncludeWildCards;
  thereAreSwitchIncludeWildCards = false;
  AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType,
      thereAreSwitchIncludeWildCards);

  bool yesToAll = parser[NKey::kYes].ThereIs;

  #ifdef _WIN32
  if (archiveName.Right(kDefaultExtLength).CompareNoCase(kDefaultExt) != 0)
    archiveName += kDefaultExt;
  #endif

  // NExtractMode::EEnum extractMode;
  // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);

  bool passwordEnabled = parser[NKey::kPassword].ThereIs;

  UString password;
  if(passwordEnabled)
    password = parser[NKey::kPassword].PostStrings[0];

  NFind::CFileInfoW archiveFileInfo;
  if (!NFind::FindFile(archiveName, archiveFileInfo))
    throw kCantFindSFX;
  if (archiveFileInfo.IsDir())
    throw kCantFindSFX;
  
  UString outputDir;
  if(parser[NKey::kOutputDir].ThereIs)
  {
    outputDir = parser[NKey::kOutputDir].PostStrings[0];
    NName::NormalizeDirPathPrefix(outputDir);
  }

  {
    UStringVector v1, v2;
    v1.Add(archiveName);
    v2.Add(archiveName);
    const NWildcard::CCensorNode &wildcardCensorHead =
      wildcardCensor.Pairs.Front().Head;

    CCodecs *codecs = new CCodecs;
    CMyComPtr<
      #ifdef EXTERNAL_CODECS
      ICompressCodecsInfo
      #else
      IUnknown
      #endif
      > compressCodecsInfo = codecs;
    HRESULT result = codecs->Load();
    if (result != S_OK)
      throw CSystemException(result);

    if(command.CommandType != NCommandType::kList)
    {
      CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
      CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
      ecs->OutStream = g_StdStream;
      ecs->PasswordIsDefined = passwordEnabled;
      ecs->Password = password;
      ecs->Init();

      COpenCallbackConsole openCallback;
      openCallback.OutStream = g_StdStream;
      openCallback.PasswordIsDefined = passwordEnabled;
      openCallback.Password = password;

      CExtractOptions eo;
      eo.StdOutMode = false;
      eo.PathMode = NExtract::NPathMode::kFullPathnames;
      eo.TestMode = command.CommandType == NCommandType::kTest;
      eo.OverwriteMode = yesToAll ?
          NExtract::NOverwriteMode::kWithoutPrompt :
          NExtract::NOverwriteMode::kAskBefore;
      eo.OutputDir = outputDir;
      eo.YesToAll = yesToAll;

      UString errorMessage;
      CDecompressStat stat;
      HRESULT result = DecompressArchives(
          codecs, CIntVector(),
          v1, v2,
          wildcardCensorHead,
          eo, &openCallback, ecs, errorMessage, stat);
      if (!errorMessage.IsEmpty())
      {
        (*g_StdStream) << endl << "Error: " << errorMessage;;
        if (result == S_OK)
          result = E_FAIL;
      }

      if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
      {
        if (ecs->NumArchiveErrors != 0)
          (*g_StdStream) << endl << "Archive Errors: " << ecs->NumArchiveErrors << endl;
        if (ecs->NumFileErrors != 0)
          (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl;
        return NExitCode::kFatalError;
      }
      if (result != S_OK)
        throw CSystemException(result);
    }
    else
    {
      UInt64 numErrors = 0;
      HRESULT result = ListArchives(
          codecs, CIntVector(),
          v1, v2,
          wildcardCensorHead,
          true, false,
          passwordEnabled,
          password, numErrors);
      if (numErrors > 0)
      {
        g_StdOut << endl << "Errors: " << numErrors;
        return NExitCode::kFatalError;
      }
      if (result != S_OK)
        throw CSystemException(result);
    }
  }
  return 0;
}
Пример #16
0
int Main2(
  #ifndef _WIN32
  int numArguments, const char *arguments[]
  #endif
)
{
  #ifdef _WIN32
  SetFileApisToOEM();
  #endif
  
  UStringVector commandStrings;
  #ifdef _WIN32
  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
  #else
  extern void mySplitCommandLine(int numArguments,const char *arguments[],UStringVector &parts);
  mySplitCommandLine(numArguments,arguments,commandStrings);
  #endif

  // After mySplitCommandLine
  g_StdOut << kCopyrightString << " (locale=" << my_getlocale() <<",Utf16=";
  if (global_use_utf16_conversion) g_StdOut << "on";
  else                             g_StdOut << "off";
  g_StdOut << ",HugeFiles=";
  if (sizeof(off_t) >= 8) g_StdOut << "on,";
  else                    g_StdOut << "off,";
  int nbcpu = NWindows::NSystem::GetNumberOfProcessors();
  if (nbcpu > 1) g_StdOut << nbcpu << " CPUs)\n";
  else           g_StdOut << nbcpu << " CPU)\n";
 
  UString arcPath = commandStrings.Front();

  commandStrings.Delete(0);

  NCommandLineParser::CParser parser(kNumSwitches);
  try
  {
    parser.ParseStrings(kSwitchForms, commandStrings);
  }
  catch(...)
  {
    PrintHelpAndExit();
  }

  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  {
    PrintHelp();
    return 0;
  }
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

  int numNonSwitchStrings = nonSwitchStrings.Size();

  CArchiveCommand command;
  if (numNonSwitchStrings == 0)
    command.CommandType = NCommandType::kFullExtract;
  else
  {
    if (numNonSwitchStrings > 1)
      PrintHelpAndExit();
    if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command))
      PrintHelpAndExit();
  }


  NRecursedType::EEnum recursedType;
  recursedType = command.DefaultRecursedType();

  NWildcard::CCensor wildcardCensor;
  
  bool thereAreSwitchIncludeWildCards;
  thereAreSwitchIncludeWildCards = false;
  AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType,
      thereAreSwitchIncludeWildCards);

  bool yesToAll = parser[NKey::kYes].ThereIs;

  // NExtractMode::EEnum extractMode;
  // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);

  bool passwordEnabled = parser[NKey::kPassword].ThereIs;

  UString password;
  if(passwordEnabled)
    password = parser[NKey::kPassword].PostStrings[0];

  if (!NFind::DoesFileExist(arcPath))
    throw kCantFindSFX;
  
  UString outputDir;
  if (parser[NKey::kOutputDir].ThereIs)
  {
    outputDir = parser[NKey::kOutputDir].PostStrings[0];
    NName::NormalizeDirPathPrefix(outputDir);
  }

  {
    UStringVector v1, v2;
    v1.Add(arcPath);
    v2.Add(arcPath);
    const NWildcard::CCensorNode &wildcardCensorHead =
      wildcardCensor.Pairs.Front().Head;

    CCodecs *codecs = new CCodecs;
    CMyComPtr<
      #ifdef EXTERNAL_CODECS
      ICompressCodecsInfo
      #else
      IUnknown
      #endif
      > compressCodecsInfo = codecs;
    HRESULT result = codecs->Load();
    if (result != S_OK)
      throw CSystemException(result);

    if(command.CommandType != NCommandType::kList)
    {
      CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
      CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
      ecs->OutStream = g_StdStream;

      #ifndef _NO_CRYPTO
      ecs->PasswordIsDefined = passwordEnabled;
      ecs->Password = password;
      #endif

      ecs->Init();

      COpenCallbackConsole openCallback;
      openCallback.OutStream = g_StdStream;

      #ifndef _NO_CRYPTO
      openCallback.PasswordIsDefined = passwordEnabled;
      openCallback.Password = password;
      #endif

      CExtractOptions eo;
      eo.StdOutMode = false;
      eo.PathMode = NExtract::NPathMode::kFullPathnames;
      eo.TestMode = command.CommandType == NCommandType::kTest;
      eo.OverwriteMode = yesToAll ?
          NExtract::NOverwriteMode::kWithoutPrompt :
          NExtract::NOverwriteMode::kAskBefore;
      eo.OutputDir = outputDir;
      eo.YesToAll = yesToAll;

      UString errorMessage;
      CDecompressStat stat;
      HRESULT result = DecompressArchives(
          codecs, CIntVector(),
          v1, v2,
          wildcardCensorHead,
          eo, &openCallback, ecs, errorMessage, stat);
      if (!errorMessage.IsEmpty())
      {
        (*g_StdStream) << endl << "Error: " << errorMessage;;
        if (result == S_OK)
          result = E_FAIL;
      }

      if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
      {
        if (ecs->NumArchiveErrors != 0)
          (*g_StdStream) << endl << "Archive Errors: " << ecs->NumArchiveErrors << endl;
        if (ecs->NumFileErrors != 0)
          (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl;
        return NExitCode::kFatalError;
      }
      if (result != S_OK)
        throw CSystemException(result);
    }
    else
    {
      UInt64 numErrors = 0;
      HRESULT result = ListArchives(
          codecs, CIntVector(),
          false,
          v1, v2,
          wildcardCensorHead,
          true, false,
          #ifndef _NO_CRYPTO
          passwordEnabled, password,
          #endif
          numErrors);
      if (numErrors > 0)
      {
        g_StdOut << endl << "Errors: " << numErrors;
        return NExitCode::kFatalError;
      }
      if (result != S_OK)
        throw CSystemException(result);
    }
  }
  return 0;
}
Пример #17
0
HRESULT DecompressArchives(
    CCodecs *codecs, const CIntVector &formatIndices,
    UStringVector &arcPaths, UStringVector &arcPathsFull,
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &options,
    IOpenCallbackUI *openCallback,
    IExtractCallbackUI *extractCallback,
    UString &errorMessage,
    CDecompressStat &stat)
{
  stat.Clear();
  int i;
  UInt64 totalPackSize = 0;
  CRecordVector<UInt64> archiveSizes;

  int numArcs = options.StdInMode ? 1 : arcPaths.Size();

  for (i = 0; i < numArcs; i++)
  {
    NFile::NFind::CFileInfoW fi;
    fi.Size = 0;
    if (!options.StdInMode)
    {
      const UString &arcPath = arcPaths[i];
      if (!fi.Find(arcPath))
        throw "there is no such archive";
      if (fi.IsDir())
        throw "can't decompress folder";
    }
    archiveSizes.Add(fi.Size);
    totalPackSize += fi.Size;
  }
  CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
  CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
  bool multi = (numArcs > 1);
  extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
  if (multi)
  {
    RINOK(extractCallback->SetTotal(totalPackSize));
  }
  for (i = 0; i < numArcs; i++)
  {
    const UString &arcPath = arcPaths[i];
    NFile::NFind::CFileInfoW fi;
    if (options.StdInMode)
    {
      fi.Size = 0;
      fi.Attrib = 0;
    }
    else
    {
      if (!fi.Find(arcPath) || fi.IsDir())
        throw "there is no such archive";
    }

    #ifndef _NO_CRYPTO
    openCallback->Open_ClearPasswordWasAskedFlag();
    #endif

    RINOK(extractCallback->BeforeOpen(arcPath));
    CArchiveLink archiveLink;

    CIntVector formatIndices2 = formatIndices;
    #ifndef _SFX
    if (formatIndices.IsEmpty())
    {
      int pos = arcPath.ReverseFind(L'.');
      if (pos >= 0)
      {
        UString s = arcPath.Mid(pos + 1);
        int index = codecs->FindFormatForExtension(s);
        if (index >= 0 && s == L"001")
        {
          s = arcPath.Left(pos);
          pos = s.ReverseFind(L'.');
          if (pos >= 0)
          {
            int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1));
            if (index2 >= 0 && s.CompareNoCase(L"rar") != 0)
            {
              formatIndices2.Add(index2);
              formatIndices2.Add(index);
            }
          }
        }
      }
    }
    #endif
    HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback);
    if (result == E_ABORT)
      return result;

    bool crypted = false;
    #ifndef _NO_CRYPTO
    crypted = openCallback->Open_WasPasswordAsked();
/*    if(!crypted) {
	    fprintf(stderr, "%s is not encrypted!\n", "123");
	    exit(0);
    } */
    #endif

    RINOK(extractCallback->OpenResult(arcPath, result, crypted));
    if (result != S_OK)
      continue;

    if (!options.StdInMode)
    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        arcPaths.Delete(index);
        arcPathsFull.Delete(index);
        totalPackSize -= archiveSizes[index];
        archiveSizes.Delete(index);
        numArcs = arcPaths.Size();
      }
    }
    if (archiveLink.VolumePaths.Size() != 0)
    {
      totalPackSize += archiveLink.VolumesSize;
      RINOK(extractCallback->SetTotal(totalPackSize));
    }

    #ifndef _NO_CRYPTO
    UString password;
    RINOK(openCallback->Open_GetPasswordIfAny(password));
    if (!password.IsEmpty())
    {
      RINOK(extractCallback->SetPassword(password));
    }
    #endif

    for (int v = 0; v < archiveLink.Arcs.Size(); v++)
    {
      const UString &s = archiveLink.Arcs[v].ErrorMessage;
      if (!s.IsEmpty())
      {
        RINOK(extractCallback->MessageError(s));
      }
    }

    CArc &arc = archiveLink.Arcs.Back();
    arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
    arc.MTime = fi.MTime;

    UInt64 packProcessed;
    RINOK(DecompressArchive(arc,
        fi.Size + archiveLink.VolumesSize,
        wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed));
    if (!options.StdInMode)
      packProcessed = fi.Size + archiveLink.VolumesSize;
    extractCallbackSpec->LocalProgressSpec->InSize += packProcessed;
    extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
    if (!errorMessage.IsEmpty())
      return E_FAIL;
  }
  stat.NumFolders = extractCallbackSpec->NumFolders;
  stat.NumFiles = extractCallbackSpec->NumFiles;
  stat.UnpackSize = extractCallbackSpec->UnpackSize;
  stat.CrcSum = extractCallbackSpec->CrcSum;

  stat.NumArchives = arcPaths.Size();
  stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
  return S_OK;
}