Example #1
0
HRESULT CThreadCopyFrom::ProcessVirt()
{
  UStringVector fileNames;
  CRecordVector<const wchar_t *> fileNamePointers;
  fileNames.Add(Name);
  fileNamePointers.Add(fileNames[0]);
  return FolderOperations->CopyFrom(PathPrefix, &fileNamePointers.Front(), fileNamePointers.Size(), UpdateCallback);
};
Example #2
0
HRESULT DecompressArchive(
    IInArchive *archive,
    const UString &defaultName,
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &options,
    IExtractCallbackUI *callback)
{
  CRecordVector<UInt32> realIndices;
  UInt32 numItems;
  RINOK(archive->GetNumberOfItems(&numItems));

  for(UInt32 i = 0; i < numItems; i++)
  {
    UString filePath;
    RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
    bool isFolder;
    RINOK(IsArchiveItemFolder(archive, i, isFolder));
    if (!wildcardCensor.CheckPath(filePath, !isFolder))
      continue;
    realIndices.Add(i);
  }
  if (realIndices.Size() == 0)
  {
    callback->ThereAreNoFiles();
    return S_OK;
  }

  CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
  CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
  
  UStringVector removePathParts;

  UString outDir = options.OutputDir;
  outDir.Replace(L"*", defaultName);
  if(!outDir.IsEmpty())
    if(!NFile::NDirectory::CreateComplexDirectory(outDir))
    {
      throw UString(L"Can not create output directory ") + outDir;
    }

  extractCallbackSpec->Init(
      archive, 
      callback,
      options.StdOutMode,
      outDir, 
      options.PathMode, 
      options.OverwriteMode,
      removePathParts, 
      options.DefaultItemName, 
      options.ArchiveFileInfo.LastWriteTime,
      options.ArchiveFileInfo.Attributes);

  HRESULT result = archive->Extract(&realIndices.Front(), 
    realIndices.Size(), options.TestMode? 1: 0, 
      extractCallback);

  return callback->ExtractResult(result);
}
Example #3
0
HRESULT CPanelCopyThread::ProcessVirt()
{
  /*
  CMyComPtr<IFolderSetReplaceAltStreamCharsMode> iReplace;
  FolderOperations.QueryInterface(IID_IFolderSetReplaceAltStreamCharsMode, &iReplace);
  if (iReplace)
  {
    RINOK(iReplace->SetReplaceAltStreamCharsMode(ReplaceAltStreamChars ? 1 : 0));
  }
  */

  if (options->testMode)
  {
    CMyComPtr<IArchiveFolder> archiveFolder;
    FolderOperations.QueryInterface(IID_IArchiveFolder, &archiveFolder);
    if (!archiveFolder)
      return E_NOTIMPL;
    CMyComPtr<IFolderArchiveExtractCallback> extractCallback2;
    RINOK(ExtractCallback.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2));
    NExtract::NPathMode::EEnum pathMode =
        NExtract::NPathMode::kCurPaths;
        // NExtract::NPathMode::kFullPathnames;
    Result = archiveFolder->Extract(&Indices.Front(), Indices.Size(),
        BoolToInt(options->includeAltStreams),
        BoolToInt(options->replaceAltStreamChars),
        pathMode, NExtract::NOverwriteMode::kAsk,
        options->folder, BoolToInt(true), extractCallback2);
  }
  else
    Result = FolderOperations->CopyTo(
      BoolToInt(options->moveMode),
      &Indices.Front(), Indices.Size(),
      BoolToInt(options->includeAltStreams),
      BoolToInt(options->replaceAltStreamChars),
      options->folder, ExtractCallback);

  if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors &&
      (!options->hashMethods.IsEmpty() || options->testMode))
  {
    CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0);
    AddHashBundleRes(pair.Message, Hash, FirstFilePath);
  }

  return Result;
}
HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
{
  if (properties.IsEmpty())
    return S_OK;
  CMyComPtr<ISetProperties> setProperties;
  unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);
  if (!setProperties)
    return S_OK;

  UStringVector realNames;
  CPropVariant *values = new CPropVariant[properties.Size()];
  try
  {
    int i;
    for(i = 0; i < properties.Size(); i++)
    {
      const CProperty &property = properties[i];
      NCOM::CPropVariant propVariant;
      UString name = property.Name;
      if (property.Value.IsEmpty())
      {
        if (!name.IsEmpty())
        {
          wchar_t c = name.Back();
          if (c == L'-')
            propVariant = false;
          else if (c == L'+')
            propVariant = true;
          if (propVariant.vt != VT_EMPTY)
            name.DeleteBack();
        }
      }
      else
        ParseNumberString(property.Value, propVariant);
      realNames.Add(name);
      values[i] = propVariant;
    }
    CRecordVector<const wchar_t *> names;
    for(i = 0; i < realNames.Size(); i++)
      names.Add((const wchar_t *)realNames[i]);
    
    RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
  }
  catch(...)
  {
    delete []values;
    throw;
  }
  delete []values;
  return S_OK;
}
Example #5
0
 void Process()
 {
   try
   {
     CProgressCloser closer(ProgressDialog);
     Result = FolderOperations->CopyFrom(
       MoveMode,
       FolderPrefix,
       &FileNamePointers.Front(),
       FileNamePointers.Size(),
       UpdateCallback);
   }
   catch(...) { Result = E_FAIL; }
 }
Example #6
0
static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method)
{
  CMyComPtr<ISetProperties> setProperties;
  if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
  {
    UStringVector realNames;
    realNames.Add(UString(L"x"));
    NCOM::CPropVariant value = (UInt32)method;
    CRecordVector<const wchar_t *> names;
    for (int i = 0; i < realNames.Size(); i++)
      names.Add(realNames[i]);
    RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size()));
  }
  return S_OK;
}
Example #7
0
void CPanel::GetSelectedItemsIndices(CRecordVector<UInt32> &indices) const
{
  indices.Clear();
  /*
  int itemIndex = -1;
  while ((itemIndex = _listView.GetNextItem(itemIndex, LVNI_SELECTED)) != -1)
  {
    LPARAM param;
    if (_listView.GetItemParam(itemIndex, param))
      indices.Add(param);
  }
  */
  for (int i = 0; i < _selectedStatusVector.Size(); i++)
    if (_selectedStatusVector[i])
      indices.Add(i);
  HeapSort(&indices.Front(), indices.Size());
}
Example #8
0
void CPanel::CreateSevenZipMenu(HMENU menuSpec,
    const CRecordVector<UInt32> &operatedIndices,
    CMyComPtr<IContextMenu> &sevenZipContextMenu)
{
  sevenZipContextMenu.Release();

  CMenu menu;
  menu.Attach(menuSpec);
  // CMenuDestroyer menuDestroyer(menu);
  // menu.CreatePopup();

  bool sevenZipMenuCreated = false;

  CZipContextMenu *contextMenuSpec = new CZipContextMenu;
  CMyComPtr<IContextMenu> contextMenu = contextMenuSpec;
  // if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK)
  {
    /*
    CMyComPtr<IInitContextMenu> initContextMenu;
    if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK)
      return;
    */
    UString currentFolderUnicode = _currentFolderPrefix;
    UStringVector names;
    int i;
    for(i = 0; i < operatedIndices.Size(); i++)
      names.Add(currentFolderUnicode + GetItemRelPath(operatedIndices[i]));
    CRecordVector<const wchar_t *> namePointers;
    for(i = 0; i < operatedIndices.Size(); i++)
      namePointers.Add(names[i]);
    
    // NFile::NDirectory::MySetCurrentDirectory(currentFolderUnicode);
    if (contextMenuSpec->InitContextMenu(currentFolderUnicode, &namePointers.Front(),
        operatedIndices.Size()) == S_OK)
    {
      HRESULT res = contextMenu->QueryContextMenu(menu, 0, kSevenZipStartMenuID,
          kSystemStartMenuID - 1, 0);
      sevenZipMenuCreated = (HRESULT_SEVERITY(res) == SEVERITY_SUCCESS);
      if (sevenZipMenuCreated)
        sevenZipContextMenu = contextMenu;
      // int code = HRESULT_CODE(res);
      // int nextItemID = code;
    }
  }
}
HRESULT CThreadFolderOperations::ProcessVirt()
{
  NCOM::CComInitializer comInitializer;
  switch(OpType)
  {
    case FOLDER_TYPE_CREATE_FOLDER:
      Result = FolderOperations->CreateFolder(Name, UpdateCallback);
      break;
    case FOLDER_TYPE_DELETE:
      Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback);
      break;
    case FOLDER_TYPE_RENAME:
      Result = FolderOperations->Rename(Index, Name, UpdateCallback);
      break;
    default:
      Result = E_FAIL;
  }
  return Result;
}
Example #10
0
int CStartupInfo::Menu(
    unsigned int flags,
    const char *title,
    const char *helpTopic,
    const CSysStringVector &items,
    int selectedItem)
{
  CRecordVector<FarMenuItem> farMenuItems;
  for(int i = 0; i < items.Size(); i++)
  {
    FarMenuItem item;
    item.Checked = 0;
    item.Separator = 0;
    item.Selected = (i == selectedItem);
    CSysString reducedString = items[i].Left(sizeof(item.Text) / sizeof(item.Text[0]) - 1);
    MyStringCopy(item.Text, (const char *)GetOemString(reducedString));
    farMenuItems.Add(item);
  }
  return Menu(flags, title, helpTopic, &farMenuItems.Front(), farMenuItems.Size());
}
Example #11
0
STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
      const UInt64 **inSizes,
      UInt32 numInStreams,
      ISequentialOutStream **outStreams,
      const UInt64 **outSizes,
      UInt32 numOutStreams,
      ICompressProgressInfo *progress)
{
  if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
      numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
    return E_INVALIDARG;

  // Find main coder
  int _mainCoderIndex = -1;
  int i;
  for (i = 0; i < _coders.Size(); i++)
    if (_coders[i].IsMain)
    {
      _mainCoderIndex = i;
      break;
    }
  if (_mainCoderIndex < 0)
  for (i = 0; i < _coders.Size(); i++)
    if (_coders[i].NumInStreams > 1)
    {
      if (_mainCoderIndex >= 0)
        return E_NOTIMPL;
      _mainCoderIndex = i;
    }
  if (_mainCoderIndex < 0)
    _mainCoderIndex = 0;
 
  // _mainCoderIndex = 0;
  // _mainCoderIndex = _coders.Size() - 1;
  CCoderInfo &mainCoder = _coders[_mainCoderIndex];

  CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
  CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
  UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex);
  UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex);
  for (i = 0; i < (int)mainCoder.NumInStreams; i++)
  {
    CMyComPtr<ISequentialInStream> seqInStream;
    RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream));
    seqInStreams.Add(seqInStream);
  }
  for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
  {
    CMyComPtr<ISequentialOutStream> seqOutStream;
    RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream));
    seqOutStreams.Add(seqOutStream);
  }
  CRecordVector< ISequentialInStream * > seqInStreamsSpec;
  CRecordVector< ISequentialOutStream * > seqOutStreamsSpec;
  for (i = 0; i < (int)mainCoder.NumInStreams; i++)
    seqInStreamsSpec.Add(seqInStreams[i]);
  for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
    seqOutStreamsSpec.Add(seqOutStreams[i]);

  for (i = 0; i < _coders.Size(); i++)
  {
    if (i == _mainCoderIndex)
      continue;
    CCoderInfo &coder = _coders[i];
    CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
    coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
    if (setOutStreamSize)
    {
      RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0]));
    }
  }
  if (mainCoder.Coder)
  {
    RINOK(mainCoder.Coder->Code(
        seqInStreamsSpec[0], seqOutStreamsSpec[0],
        mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0],
        progress));
  }
  else
  {
    RINOK(mainCoder.Coder2->Code(
        &seqInStreamsSpec.Front(),
        &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams,
        &seqOutStreamsSpec.Front(),
        &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams,
        progress));
  }
  CMyComPtr<IOutStreamFlush> flush;
  seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush);
  if (flush)
    return flush->Flush();
  return S_OK;
}
Example #12
0
NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *panelItems,
    int itemsNumber, int move, const char *_aDestPath, int opMode, bool showBox)
{
  if(move != 0)
  {
    g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
    return NFileOperationReturnCode::kError;
  }

  CSysString destPath = _aDestPath;
  NFile::NName::NormalizeDirPathPrefix(destPath);

  bool extractSelectedFiles = true;
  
  NExtract::CInfo extractionInfo;
  extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames;
  extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;

  bool silent = (opMode & OPM_SILENT) != 0;
  bool decompressAllItems = false;
  UString password = Password;
  bool passwordIsDefined = PasswordIsDefined;

  if (!silent)
  {
    const int kPathIndex = 2;

    ReadExtractionInfo(extractionInfo);

    const int kPathModeRadioIndex = 4;
    const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4;
    const int kNumOverwriteOptions = 6;
    const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions;
    const int kXSize = 76;
    const int kYSize = 19;
    const int kPasswordYPos = 12;
    
    const int kXMid = kXSize / 2;

    AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP);
    
    struct CInitDialogItem initItems[]={
      { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL },
      { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL },
      
      { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName},
      // { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, 0, false, -1, destPath, NULL},
      
      { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL },
      { DI_RADIOBUTTON, 6, 6, 0, 0, false,
          extractionInfo.PathMode == NExtract::NPathMode::kFullPathnames,
          DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL },
      { DI_RADIOBUTTON, 6, 7, 0, 0, false,
          extractionInfo.PathMode == NExtract::NPathMode::kCurrentPathnames,
          0, false, NMessageID::kExtractPathCurrent, NULL, NULL },
      { DI_RADIOBUTTON, 6, 8, 0, 0, false,
          extractionInfo.PathMode == NExtract::NPathMode::kNoPathnames,
          false, 0, NMessageID::kExtractPathNo, NULL, NULL },
      
      { DI_SINGLEBOX, kXMid, 5, kXSize - 6, 5 + kNumOverwriteOptions, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false,
          extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAskBefore,
          DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false,
          extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kWithoutPrompt,
          0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false,
          extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kSkipExisting,
          0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false,
          extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRename,
          0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 10, 0, 0, false,
          extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting,
          0, false, NMessageID::kExtractOwerwriteAutoRenameExisting, NULL, NULL },
      
      { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL },
      { DI_RADIOBUTTON, 6, 11, 0, 0, false, true, DIF_GROUP, false, NMessageID::kExtractFilesSelected, NULL, NULL },
      { DI_RADIOBUTTON, 6, 12, 0, 0, false, false, 0, false, NMessageID::kExtractFilesAll, NULL, NULL },
      
      { DI_SINGLEBOX, kXMid, kPasswordYPos, kXSize - 6, kPasswordYPos + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL },
      { DI_PSWEDIT, kXMid + 2, kPasswordYPos + 1, kXSize - 8, 12, false, false, 0, false, -1, oemPassword, NULL},
      
      { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL  },
      
      
      { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kExtractExtract, NULL, NULL  },
      { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kExtractCancel, NULL, NULL  }
    };
   
    const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
    const int kOkButtonIndex = kNumDialogItems - 2;
    const int kPasswordIndex = kNumDialogItems - 4;

    FarDialogItem dialogItems[kNumDialogItems];
    g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
    for (;;)
    {
      int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize,
        kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems);
      if (askCode != kOkButtonIndex)
        return NFileOperationReturnCode::kInterruptedByUser;
      destPath = dialogItems[kPathIndex].Data;
      destPath.Trim();
      if (destPath.IsEmpty())
      {
        if(!NFile::NDirectory::MyGetCurrentDirectory(destPath))
          throw 318016;
        NFile::NName::NormalizeDirPathPrefix(destPath);
        break;
      }
      else
      {
        if(destPath[destPath.Length() - 1] == kDirDelimiter)
          break;
      }
      g_StartupInfo.ShowMessage("You must specify directory path");
    }

    if (dialogItems[kPathModeRadioIndex].Selected)
      extractionInfo.PathMode = NExtract::NPathMode::kFullPathnames;
    else if (dialogItems[kPathModeRadioIndex + 1].Selected)
      extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames;
    else if (dialogItems[kPathModeRadioIndex + 2].Selected)
      extractionInfo.PathMode = NExtract::NPathMode::kNoPathnames;
    else
      throw 31806;

    if (dialogItems[kOverwriteModeRadioIndex].Selected)
      extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
    else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected)
      extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
    else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected)
      extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkipExisting;
    else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected)
      extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRename;
    else if (dialogItems[kOverwriteModeRadioIndex + 4].Selected)
      extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRenameExisting;
    else
      throw 31806;
    
    if (dialogItems[kFilesModeIndex].Selected)
      decompressAllItems = false;
    else if (dialogItems[kFilesModeIndex + 1].Selected)
      decompressAllItems = true;
    else
      throw 31806;

    SaveExtractionInfo(extractionInfo);

    if (dialogItems[kFilesModeIndex].Selected)
      extractSelectedFiles = true;
    else if (dialogItems[kFilesModeIndex + 1].Selected)
      extractSelectedFiles = false;
    else
      throw 31806;

    oemPassword = dialogItems[kPasswordIndex].Data;
    password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
    passwordIsDefined = !password.IsEmpty();
  }

  NFile::NDirectory::CreateComplexDirectory(destPath);

  /*
  vector<int> realIndices;
  if (!decompressAllItems)
    GetRealIndexes(panelItems, itemsNumber, realIndices);
  */
  CRecordVector<UINT32> indices;
  indices.Reserve(itemsNumber);
  for (int i = 0; i < itemsNumber; i++)
    indices.Add(panelItems[i].UserData);

  HRESULT result = ExtractFiles(decompressAllItems, &indices.Front(), itemsNumber,
      !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode,
      MultiByteToUnicodeString(destPath, CP_OEMCP),
      passwordIsDefined, password);
  // HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox,
  //     extractionInfo, destPath, passwordIsDefined, password);
  if (result != S_OK)
  {
    if (result == E_ABORT)
      return NFileOperationReturnCode::kInterruptedByUser;
    ShowErrorMessage(result);
    return NFileOperationReturnCode::kError;
  }

  // if(move != 0)
  // {
  //   if(DeleteFiles(panelItems, itemsNumber, opMode) == FALSE)
  //     return NFileOperationReturnCode::kError;
  // }
  return NFileOperationReturnCode::kSuccess;
}
Example #13
0
static HRESULT DecompressArchive(
    IInArchive *archive,
    UInt64 packSize,
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &options,
    IExtractCallbackUI *callback,
    CArchiveExtractCallback *extractCallbackSpec,
    UString &errorMessage)
{
  CRecordVector<UInt32> realIndices;
  UInt32 numItems;
  RINOK(archive->GetNumberOfItems(&numItems));

  for(UInt32 i = 0; i < numItems; i++)
  {
    UString filePath;
    RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
    bool isFolder;
    RINOK(IsArchiveItemFolder(archive, i, isFolder));
    if (!wildcardCensor.CheckPath(filePath, !isFolder))
      continue;
    realIndices.Add(i);
  }
  if (realIndices.Size() == 0)
  {
    callback->ThereAreNoFiles();
    return S_OK;
  }

  UStringVector removePathParts;

  UString outDir = options.OutputDir;
  outDir.Replace(L"*", options.DefaultItemName);
  #ifdef _WIN32
  outDir.TrimRight();
  #endif

  if(!outDir.IsEmpty())
    if(!NFile::NDirectory::CreateComplexDirectory(outDir))
    {
      HRESULT res = ::GetLastError();
      if (res == S_OK)
        res = E_FAIL;
      errorMessage = ((UString)L"Can not create output directory ") + outDir;
      return res;
    }

  extractCallbackSpec->Init(
      archive,
      callback,
      options.StdOutMode,
      outDir,
      removePathParts,
      options.DefaultItemName,
      options.ArchiveFileInfo.MTime,
      options.ArchiveFileInfo.Attrib,
      packSize);

  #ifdef COMPRESS_MT
  RINOK(SetProperties(archive, options.Properties));
  #endif

  HRESULT result = archive->Extract(&realIndices.Front(),
    realIndices.Size(), options.TestMode? 1: 0, extractCallbackSpec);

  return callback->ExtractResult(result);
}
Example #14
0
int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems,
    int opMode)
{
  if (numItems == 0)
    return FALSE;
  /*
  if (!m_ArchiverInfo.UpdateEnabled)
  {
    g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
    return FALSE;
  }
  */
  if ((opMode & OPM_SILENT) == 0)
  {
    const char *msgItems[]=
    {
      g_StartupInfo.GetMsgString(NMessageID::kDeleteTitle),
      g_StartupInfo.GetMsgString(NMessageID::kDeleteFiles),
      g_StartupInfo.GetMsgString(NMessageID::kDeleteDelete),
      g_StartupInfo.GetMsgString(NMessageID::kDeleteCancel)
    };
    char msg[1024];
    if (numItems == 1)
    {
      sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile),
          panelItems[0].FindData.cFileName);
      msgItems[1] = msg;
    }
    else if (numItems > 1)
    {
      sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles),
          numItems);
      msgItems[1] = msg;
    }
    if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems,
        sizeof(msgItems) / sizeof(msgItems[0]), 2) != 0)
      return (FALSE);
  }

  CScreenRestorer screenRestorer;
  CProgressBox progressBox;
  CProgressBox *progressBoxPointer = NULL;
  if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
  {
    screenRestorer.Save();

    progressBoxPointer = &progressBox;
    progressBox.Init(
        // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
        g_StartupInfo.GetMsgString(NMessageID::kDeleting), 48);
  }

  NWorkDir::CInfo workDirInfo;
  ReadWorkDirInfo(workDirInfo);

  UString workDir = GetWorkDir(workDirInfo, m_FileName);
  CreateComplexDirectory(workDir);

  CTempFileW tempFile;
  UString tempFileName;
  if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0)
    return FALSE;


  CRecordVector<UINT32> indices;
  indices.Reserve(numItems);
  int i;
  for(i = 0; i < numItems; i++)
    indices.Add(panelItems[i].UserData);

  ////////////////////////////
  // Save _folder;

  UStringVector pathVector;
  GetPathParts(pathVector);
  
  CMyComPtr<IOutFolderArchive> outArchive;
  HRESULT result = m_ArchiveHandler.QueryInterface(
      IID_IOutFolderArchive, &outArchive);
  if(result != S_OK)
  {
    g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
    return FALSE;
  }
  outArchive->SetFolder(_folder);

  CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
  CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
  
  updateCallbackSpec->Init(/* m_ArchiveHandler, */ &progressBox);


  result = outArchive->DeleteItems(
      tempFileName,
      &indices.Front(), indices.Size(),
      updateCallback);
  updateCallback.Release();
  outArchive.Release();

  if (result != S_OK)
  {
    ShowErrorMessage(result);
    return FALSE;
  }

  _folder.Release();
  m_ArchiveHandler->Close();
  
  if (!DeleteFileAlways(m_FileName))
  {
    ShowLastErrorMessage();
    return FALSE;
  }

  tempFile.DisableDeleting();
  if (!MyMoveFile(tempFileName, m_FileName))
  {
    ShowLastErrorMessage();
    return FALSE;
  }
  
  result = m_ArchiveHandler->ReOpen(NULL);
  if (result != S_OK)
  {
    ShowErrorMessage(result);
    return FALSE;
  }

 
  ////////////////////////////
  // Restore _folder;

  m_ArchiveHandler->BindToRootFolder(&_folder);
  for (i = 0; i < pathVector.Size(); i++)
  {
    CMyComPtr<IFolderFolder> newFolder;
    _folder->BindToFolder(pathVector[i], &newFolder);
    if(!newFolder  )
      break;
    _folder = newFolder;
  }
  GetCurrentDir();

  return(TRUE);
}
Example #15
0
NFileOperationReturnCode::EEnum CPlugin::PutFiles(
  struct PluginPanelItem *panelItems, int numItems,
  int moveMode, int opMode)
{
  if (moveMode != 0)
  {
    g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
    return NFileOperationReturnCode::kError;
  }
  if (numItems == 0)
    return NFileOperationReturnCode::kError;

  /*
  if (!m_ArchiverInfo.UpdateEnabled)
  {
    g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
    return NFileOperationReturnCode::kError;
  }
  */

  const int kYSize = 14;
  const int kXMid = 38;

  NCompression::CInfo compressionInfo;
  compressionInfo.Load();

  int methodIndex = 0;
  int i;
  for (i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--)
    if (compressionInfo.Level >= g_MethodMap[i])
    {
      methodIndex = i;
      break;
    }

  const int kMethodRadioIndex = 2;
  const int kModeRadioIndex = kMethodRadioIndex + 7;

  struct CInitDialogItem initItems[]={
    { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL },
    { DI_SINGLEBOX, 4, 2, kXMid - 2, 2 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL },
    { DI_RADIOBUTTON, 6, 3, 0, 0, methodIndex == 0, methodIndex == 0,
        DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL },
    { DI_RADIOBUTTON, 6, 4, 0, 0, methodIndex == 1, methodIndex == 1,
        0, false, NMessageID::kUpdateMethodFastest, NULL, NULL },
    { DI_RADIOBUTTON, 6, 5, 0, 0, methodIndex == 2, methodIndex == 2,
        0, false, NMessageID::kUpdateMethodFast, NULL, NULL },
    { DI_RADIOBUTTON, 6, 6, 0, 0, methodIndex == 3, methodIndex == 3,
        0, false, NMessageID::kUpdateMethodNormal, NULL, NULL },
    { DI_RADIOBUTTON, 6, 7, 0, 0, methodIndex == 4, methodIndex == 4,
        0, false, NMessageID::kUpdateMethodMaximum, NULL, NULL },
    { DI_RADIOBUTTON, 6, 8, 0, 0, methodIndex == 5, methodIndex == 5,
        0, false, NMessageID::kUpdateMethodUltra, NULL, NULL },
    
    { DI_SINGLEBOX, kXMid, 2, 70, 2 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL },
    { DI_RADIOBUTTON, kXMid + 2, 3, 0, 0, false, true,
        DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL },
    { DI_RADIOBUTTON, kXMid + 2, 4, 0, 0, false, false,
        0, false, NMessageID::kUpdateModeUpdate, NULL, NULL },
    { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, false,
        0, false, NMessageID::kUpdateModeFreshen, NULL, NULL },
    { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, false,
        0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL },
  
    { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL  },
    
    { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL  },
    { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL  }
  };
  
  const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
  const int kOkButtonIndex = kNumDialogItems - 2;
  FarDialogItem dialogItems[kNumDialogItems];
  g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
  int askCode = g_StartupInfo.ShowDialog(76, kYSize,
      kHelpTopic, dialogItems, kNumDialogItems);
  if (askCode != kOkButtonIndex)
    return NFileOperationReturnCode::kInterruptedByUser;

  compressionInfo.Level = g_MethodMap[0];
  for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++)
    if (dialogItems[kMethodRadioIndex + i].Selected)
      compressionInfo.Level = g_MethodMap[i];

  const CActionSet *actionSet;

  if (dialogItems[kModeRadioIndex].Selected)
    actionSet = &kAddActionSet;
  else if (dialogItems[kModeRadioIndex + 1].Selected)
    actionSet = &kUpdateActionSet;
  else if (dialogItems[kModeRadioIndex + 2].Selected)
    actionSet = &kFreshActionSet;
  else if (dialogItems[kModeRadioIndex + 3].Selected)
    actionSet = &kSynchronizeActionSet;
  else
    throw 51751;

  compressionInfo.Save();

  CWorkDirTempFile tempFile;;
  if (tempFile.CreateTempFile(m_FileName) != S_OK)
    return NFileOperationReturnCode::kError;


  /*
  CSysStringVector fileNames;
  for (int i = 0; i < numItems; i++)
  {
    const PluginPanelItem &panelItem = panelItems[i];
    CSysString fullName;
    if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName))
      return NFileOperationReturnCode::kError;
    fileNames.Add(fullName);
  }
  */

  CScreenRestorer screenRestorer;
  CProgressBox progressBox;
  CProgressBox *progressBoxPointer = NULL;
  if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
  {
    screenRestorer.Save();

    progressBoxPointer = &progressBox;
    progressBox.Init(
        // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
        g_StartupInfo.GetMsgString(NMessageID::kUpdating), 48);
  }
 
  UStringVector pathVector;
  GetPathParts(pathVector);
  
  UStringVector fileNames;
  fileNames.Reserve(numItems);
  for (i = 0; i < numItems; i++)
    fileNames.Add(MultiByteToUnicodeString(panelItems[i].FindData.cFileName, CP_OEMCP));
  CRecordVector<const wchar_t *> fileNamePointers;
  fileNamePointers.Reserve(numItems);
  for (i = 0; i < numItems; i++)
    fileNamePointers.Add(fileNames[i]);

  CMyComPtr<IOutFolderArchive> outArchive;
  HRESULT result = m_ArchiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive);
  if (result != S_OK)
  {
    g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
    return NFileOperationReturnCode::kError;
  }
  outArchive->SetFolder(_folder);

  outArchive->SetFiles(L"", &fileNamePointers.Front(), fileNamePointers.Size());
  BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
  for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
    actionSetByte[i] = (BYTE)actionSet->StateActions[i];

  CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
  CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
  
  updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer);

  if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK)
    return NFileOperationReturnCode::kError;

  result = outArchive->DoOperation2(tempFile.OutStream, actionSetByte, NULL, updateCallback);
  updateCallback.Release();
  outArchive.Release();

  if (result == S_OK)
  {
    result = AfterUpdate(tempFile, pathVector);
  }
  if (result != S_OK)
  {
    ShowErrorMessage(result);
    return NFileOperationReturnCode::kError;
  }

  /*
  if (moveMode != 0)
  {
    for (int i = 0; i < numItems; i++)
    {
      const PluginPanelItem &pluginPanelItem = panelItems[i];
      bool result;
      if (NFile::NFind::NAttributes::IsDir(pluginPanelItem.FindData.dwFileAttributes))
        result = NFile::NDirectory::RemoveDirectoryWithSubItems(pluginPanelItem.FindData.cFileName);
      else
        result = NFile::NDirectory::DeleteFileAlways(pluginPanelItem.FindData.cFileName);
      if (!result)
        return NFileOperationReturnCode::kError;
    }
  }
  */
  return NFileOperationReturnCode::kSuccess;
}
Example #16
0
HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
{
  if (pluginPanelItems.Size() == 0)
    return E_FAIL;

  UStringVector fileNames;
  int i;
  for (i = 0; i < pluginPanelItems.Size(); i++)
  {
    const PluginPanelItem &panelItem = pluginPanelItems[i];
    if (strcmp(panelItem.FindData.cFileName, "..") == 0 &&
        NFind::NAttributes::IsDir(panelItem.FindData.dwFileAttributes))
      return E_FAIL;
    if (strcmp(panelItem.FindData.cFileName, ".") == 0 &&
        NFind::NAttributes::IsDir(panelItem.FindData.dwFileAttributes))
      return E_FAIL;
    FString fullPath;
    FString fileNameUnicode = us2fs(MultiByteToUnicodeString(panelItem.FindData.cFileName, CP_OEMCP));
    if (!MyGetFullPathName(fileNameUnicode, fullPath))
      return E_FAIL;
    fileNames.Add(fs2us(fullPath));
  }

  NCompression::CInfo compressionInfo;
  compressionInfo.Load();
  
  int archiverIndex = 0;

  CCodecs *codecs = new CCodecs;
  CMyComPtr<ICompressCodecsInfo> compressCodecsInfo = codecs;
  if (codecs->Load() != S_OK)
    throw "Can't load 7-Zip codecs";
  {
    for (int i = 0; i < codecs->Formats.Size(); i++)
    {
      const CArcInfoEx &arcInfo = codecs->Formats[i];
      if (arcInfo.UpdateEnabled)
      {
        if (archiverIndex == -1)
          archiverIndex = i;
        if (arcInfo.Name.CompareNoCase(compressionInfo.ArcType) == 0)
          archiverIndex = i;
      }
    }
  }


  UString resultPath;
  {
    CParsedPath parsedPath;
    parsedPath.ParsePath(fileNames.Front());
    if (parsedPath.PathParts.Size() == 0)
      return E_FAIL;
    if (fileNames.Size() == 1 || parsedPath.PathParts.Size() == 1)
    {
      // CSysString pureName, dot, extension;
      resultPath = parsedPath.PathParts.Back();
    }
    else
    {
      parsedPath.PathParts.DeleteBack();
      resultPath = parsedPath.PathParts.Back();
    }
  }
  UString archiveNameSrc = resultPath;
  UString archiveName = archiveNameSrc;

  const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex];
  int prevFormat = archiverIndex;
 
  if (!arcInfo.KeepName)
  {
    int dotPos = archiveName.ReverseFind('.');
    int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/'));
    if (dotPos > slashPos)
      archiveName = archiveName.Left(dotPos);
  }
  archiveName += L'.';
  archiveName += arcInfo.GetMainExt();
  
  const CActionSet *actionSet = &kAddActionSet;

  for (;;)
  {
    AString archiveNameA = UnicodeStringToMultiByte(archiveName, CP_OEMCP);
    const int kYSize = 16;
    const int kXMid = 38;
  
    const int kArchiveNameIndex = 2;
    const int kMethodRadioIndex = kArchiveNameIndex + 2;
    const int kModeRadioIndex = kMethodRadioIndex + 7;

    const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex];

    char updateAddToArchiveString[512];
    const AString s = UnicodeStringToMultiByte(arcInfo.Name, CP_OEMCP);

    sprintf(updateAddToArchiveString,
        g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), (const char *)s);

    int methodIndex = 0;
    int i;
    for (i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--)
      if (compressionInfo.Level >= g_MethodMap[i])
      {
        methodIndex = i;
        break;
      }

    struct CInitDialogItem initItems[]=
    {
      { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL },

      { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, updateAddToArchiveString, NULL },
      
      { DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, archiveNameA, kArchiveHistoryKeyName},
      // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, archiveName, NULL},
      
      { DI_SINGLEBOX, 4, 4, kXMid - 2, 4 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL },
      { DI_RADIOBUTTON, 6, 5, 0, 0, false, methodIndex == 0,
          DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL },
      { DI_RADIOBUTTON, 6, 6, 0, 0, false, methodIndex == 1,
          0, false, NMessageID::kUpdateMethodFastest, NULL, NULL },
      { DI_RADIOBUTTON, 6, 7, 0, 0, false, methodIndex == 2,
          0, false, NMessageID::kUpdateMethodFast, NULL, NULL },
      { DI_RADIOBUTTON, 6, 8, 0, 0, false, methodIndex == 3,
          0, false, NMessageID::kUpdateMethodNormal, NULL, NULL },
      { DI_RADIOBUTTON, 6, 9, 0, 0, false, methodIndex == 4,
          false, 0, NMessageID::kUpdateMethodMaximum, NULL, NULL },
      { DI_RADIOBUTTON, 6, 10, 0, 0, false, methodIndex == 5,
          false, 0, NMessageID::kUpdateMethodUltra, NULL, NULL },
      
      { DI_SINGLEBOX, kXMid, 4, 70, 4 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false,
          actionSet == &kAddActionSet,
          DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false,
          actionSet == &kUpdateActionSet,
          0, false, NMessageID::kUpdateModeUpdate, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false,
          actionSet == &kFreshActionSet,
          0, false, NMessageID::kUpdateModeFreshen, NULL, NULL },
      { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false,
          actionSet == &kSynchronizeActionSet,
          0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL },
      
      { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL  },
      
      { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL  },
      { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kUpdateSelectArchiver, NULL, NULL  },
      { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL  }
    };

    const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
    
    const int kOkButtonIndex = kNumDialogItems - 3;
    const int kSelectarchiverButtonIndex = kNumDialogItems - 2;

    FarDialogItem dialogItems[kNumDialogItems];
    g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
    int askCode = g_StartupInfo.ShowDialog(76, kYSize,
        kHelpTopic, dialogItems, kNumDialogItems);

    archiveNameA = dialogItems[kArchiveNameIndex].Data;
    archiveNameA.Trim();
    archiveName = MultiByteToUnicodeString(archiveNameA, CP_OEMCP);

    compressionInfo.Level = g_MethodMap[0];
    for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++)
      if (dialogItems[kMethodRadioIndex + i].Selected)
        compressionInfo.Level = g_MethodMap[i];

    if (dialogItems[kModeRadioIndex].Selected)
      actionSet = &kAddActionSet;
    else if (dialogItems[kModeRadioIndex + 1].Selected)
      actionSet = &kUpdateActionSet;
    else if (dialogItems[kModeRadioIndex + 2].Selected)
      actionSet = &kFreshActionSet;
    else if (dialogItems[kModeRadioIndex + 3].Selected)
      actionSet = &kSynchronizeActionSet;
    else
      throw 51751;

    if (askCode == kSelectarchiverButtonIndex)
    {
      CIntVector indices;
      CSysStringVector archiverNames;
      for (int i = 0; i < codecs->Formats.Size(); i++)
      {
        const CArcInfoEx &arc = codecs->Formats[i];
        if (arc.UpdateEnabled)
        {
          indices.Add(i);
          archiverNames.Add(GetSystemString(arc.Name, CP_OEMCP));
        }
      }
    
      int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT,
          g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle),
          NULL, archiverNames, archiverIndex);
      if (index >= 0)
      {
        const CArcInfoEx &prevArchiverInfo = codecs->Formats[prevFormat];
        if (prevArchiverInfo.KeepName)
        {
          const UString &prevExtension = prevArchiverInfo.GetMainExt();
          const int prevExtensionLen = prevExtension.Length();
          if (archiveName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0)
          {
            int pos = archiveName.Length() - prevExtensionLen;
            if (pos > 1)
            {
              int dotPos = archiveName.ReverseFind('.');
              if (dotPos == pos - 1)
                archiveName = archiveName.Left(dotPos);
            }
          }
        }

        archiverIndex = indices[index];
        const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex];
        prevFormat = archiverIndex;
        
        if (arcInfo.KeepName)
          archiveName = archiveNameSrc;
        else
        {
          int dotPos = archiveName.ReverseFind('.');
          int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/'));
          if (dotPos > slashPos)
            archiveName = archiveName.Left(dotPos);
        }
        archiveName += L'.';
        archiveName += arcInfo.GetMainExt();
      }
      continue;
    }

    if (askCode != kOkButtonIndex)
      return E_ABORT;
    
    break;
  }

  const CArcInfoEx &archiverInfoFinal = codecs->Formats[archiverIndex];
  compressionInfo.ArcType = archiverInfoFinal.Name;
  compressionInfo.Save();

  NWorkDir::CInfo workDirInfo;
  workDirInfo.Load();

  FString fullArchiveName;
  if (!MyGetFullPathName(us2fs(archiveName), fullArchiveName))
    return E_FAIL;
   
  CWorkDirTempFile tempFile;
  RINOK(tempFile.CreateTempFile(fullArchiveName));

  CScreenRestorer screenRestorer;
  CProgressBox progressBox;
  CProgressBox *progressBoxPointer = NULL;

  screenRestorer.Save();

  progressBoxPointer = &progressBox;
  progressBox.Init(
      // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
      g_StartupInfo.GetMsgString(NMessageID::kUpdating), 48);


  NFind::CFileInfo fileInfo;

  CMyComPtr<IOutFolderArchive> outArchive;

  CMyComPtr<IInFolderArchive> archiveHandler;
  if (fileInfo.Find(fullArchiveName))
  {
    if (fileInfo.IsDir())
      throw "There is Directory with such name";

    CAgent *agentSpec = new CAgent;
    archiveHandler = agentSpec;
    // CLSID realClassID;
    CMyComBSTR archiveType;
    RINOK(agentSpec->Open(NULL,
        GetUnicodeString(fullArchiveName, CP_OEMCP), UString(),
        // &realClassID,
        &archiveType,
        NULL));

    if (archiverInfoFinal.Name.CompareNoCase((const wchar_t *)archiveType) != 0)
      throw "Type of existing archive differs from specified type";
    HRESULT result = archiveHandler.QueryInterface(
        IID_IOutFolderArchive, &outArchive);
    if (result != S_OK)
    {
      g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
      return E_FAIL;
    }
  }
  else
  {
    // HRESULT result = outArchive.CoCreateInstance(classID);
    CAgent *agentSpec = new CAgent;
    outArchive = agentSpec;

    /*
    HRESULT result = outArchive.CoCreateInstance(CLSID_CAgentArchiveHandler);
    if (result != S_OK)
    {
      g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
      return E_FAIL;
    }
    */
  }

  CRecordVector<const wchar_t *> fileNamePointers;
  fileNamePointers.Reserve(fileNames.Size());
  for (i = 0; i < fileNames.Size(); i++)
    fileNamePointers.Add(fileNames[i]);

  outArchive->SetFolder(NULL);
  outArchive->SetFiles(L"", &fileNamePointers.Front(), fileNamePointers.Size());
  BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
  for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
    actionSetByte[i] = (BYTE)actionSet->StateActions[i];

  CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
  CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
  
  updateCallbackSpec->Init(/* archiveHandler, */ progressBoxPointer);


  RINOK(SetOutProperties(outArchive, compressionInfo.Level));

  HRESULT result = outArchive->DoOperation(
      codecs, archiverIndex,
      tempFile.OutStream, actionSetByte,
      NULL, updateCallback);
  updateCallback.Release();
  outArchive.Release();

  if (result != S_OK)
  {
    ShowErrorMessage(result);
    return result;
  }
 
  if (archiveHandler)
  {
    archiveHandler->Close();
  }
  if (!tempFile.MoveToOriginal(archiveHandler != NULL))
  {
    ShowLastErrorMessage();
    return E_FAIL;
  }
  return S_OK;
}
Example #17
0
INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndParent, const UString &title)
{
#ifndef _UNICODE
    AStringVector titles;
#endif
#ifndef _UNICODE
    CRecordVector<PROPSHEETPAGEA> pagesA;
#endif
    CRecordVector<PROPSHEETPAGEW> pagesW;

    int i;
#ifndef _UNICODE
    for (i = 0; i < pagesInfo.Size(); i++)
        titles.Add(GetSystemString(pagesInfo[i].Title));
#endif

    for (i = 0; i < pagesInfo.Size(); i++)
    {
        const CPageInfo &pageInfo = pagesInfo[i];
#ifndef _UNICODE
        {
            PROPSHEETPAGE page;
            page.dwSize = sizeof(page);
            page.dwFlags = PSP_HASHELP;
            page.hInstance = g_hInstance;
            page.pszTemplate = MAKEINTRESOURCE(pageInfo.ID);
            page.pszIcon = NULL;
            page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure;

            if (titles[i].IsEmpty())
                page.pszTitle = NULL;
            else
            {
                page.dwFlags |= PSP_USETITLE;
                page.pszTitle = titles[i];
            }
            page.lParam = (LPARAM)pageInfo.Page;
            page.pfnCallback = NULL;
            pagesA.Add(page);
        }
#endif
        {
            PROPSHEETPAGEW page;
            page.dwSize = sizeof(page);
            page.dwFlags = PSP_HASHELP;
            page.hInstance = g_hInstance;
            page.pszTemplate = MAKEINTRESOURCEW(pageInfo.ID);
            page.pszIcon = NULL;
            page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure;

            if (pageInfo.Title.IsEmpty())
                page.pszTitle = NULL;
            else
            {
                page.dwFlags |= PSP_USETITLE;
                page.pszTitle = pageInfo.Title;
            }
            page.lParam = (LPARAM)pageInfo.Page;
            page.pfnCallback = NULL;
            pagesW.Add(page);
        }
    }

#ifndef _UNICODE
    if (!g_IsNT)
    {
        PROPSHEETHEADER sheet;
        sheet.dwSize = sizeof(sheet);
        sheet.dwFlags = PSH_PROPSHEETPAGE;
        sheet.hwndParent = hwndParent;
        sheet.hInstance = g_hInstance;
        AString titleA = GetSystemString(title);
        sheet.pszCaption = titleA;
        sheet.nPages = pagesInfo.Size();
        sheet.nStartPage = 0;
        sheet.ppsp = &pagesA.Front();
        sheet.pfnCallback = NULL;
        return ::PropertySheetA(&sheet);
    }
    else
#endif
    {
        PROPSHEETHEADERW sheet;
        sheet.dwSize = sizeof(sheet);
        sheet.dwFlags = PSH_PROPSHEETPAGE;
        sheet.hwndParent = hwndParent;
        sheet.hInstance = g_hInstance;
        sheet.pszCaption = title;
        sheet.nPages = pagesInfo.Size();
        sheet.nStartPage = 0;
        sheet.ppsp = &pagesW.Front();
        sheet.pfnCallback = NULL;
        return ::PropertySheetW(&sheet);
    }
}
Example #18
0
STDMETHODIMP CAgent::DoOperation(
    CCodecs *codecs,
    int formatIndex,
    const wchar_t *newArchiveName,
    const Byte *stateActions,
    const wchar_t *sfxModule,
    IFolderArchiveUpdateCallback *updateCallback100)
{
  if (!CanUpdate())
    return E_NOTIMPL;
  NUpdateArchive::CActionSet actionSet;
  int i;
  for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
    actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];

  CDirItems dirItems;

  {
    UString folderPrefix = _folderPrefix;
    NFile::NName::NormalizeDirPathPrefix(folderPrefix);
    UStringVector errorPaths;
    CRecordVector<DWORD> errorCodes;
    dirItems.EnumerateDirItems2(folderPrefix, _archiveNamePrefix, _names, errorPaths, errorCodes);
    if (errorCodes.Size() > 0)
      return errorCodes.Front();
  }

  CMyComPtr<IOutArchive> outArchive;
  if (GetArchive())
  {
    RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
  }
  else
  {
    if (formatIndex < 0)
      return E_FAIL;
    RINOK(codecs->CreateOutArchive(formatIndex, outArchive));
    #ifdef EXTERNAL_CODECS
    {
      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
      outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
      if (setCompressCodecsInfo)
      {
        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
      }
    }
    #endif

  }

  NFileTimeType::EEnum fileTimeType;
  UInt32 value;
  RINOK(outArchive->GetFileTimeType(&value));

  switch(value)
  {
    case NFileTimeType::kWindows:
    case NFileTimeType::kDOS:
    case NFileTimeType::kUnix:
      fileTimeType = NFileTimeType::EEnum(value);
      break;
    default:
      return E_FAIL;
  }


  CObjectVector<CArcItem> arcItems;
  if (GetArchive())
  {
    RINOK(ReadItems());
    EnumerateArchiveItems(this, _proxyArchive->RootFolder,  L"", arcItems);
  }

  CRecordVector<CUpdatePair2> updatePairs2;

  {
    CRecordVector<CUpdatePair> updatePairs;
    GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs);
    CAgUpCallbackImp upCallback(&arcItems, updateCallback100);
    UpdateProduce(updatePairs, actionSet, updatePairs2, &upCallback);
  }

  UInt32 numFiles = 0;
  for (i = 0; i < updatePairs2.Size(); i++)
    if (updatePairs2[i].NewData)
      numFiles++;
  
  if (updateCallback100)
  {
    RINOK(updateCallback100->SetNumFiles(numFiles));
  }
  
  CUpdateCallbackAgent updateCallbackAgent;
  updateCallbackAgent.SetCallback(updateCallback100);
  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );

  updateCallbackSpec->DirItems = &dirItems;
  updateCallbackSpec->ArcItems = &arcItems;
  updateCallbackSpec->UpdatePairs = &updatePairs2;
  updateCallbackSpec->Archive = GetArchive();
  updateCallbackSpec->Callback = &updateCallbackAgent;

  COutFileStream *outStreamSpec = new COutFileStream;
  CMyComPtr<IOutStream> outStream(outStreamSpec);
  UString archiveName = newArchiveName;
  {
    UString resultPath;
    int pos;
    if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
      return E_FAIL;
    NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
  }
  if (!outStreamSpec->Create(archiveName, true))
  {
    // ShowLastErrorMessage();
    return E_FAIL;
  }
  
  CMyComPtr<ISetProperties> setProperties;
  if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
  {
    if (m_PropNames.Size() == 0)
    {
      RINOK(setProperties->SetProperties(0, 0, 0));
    }
    else
    {
      CRecordVector<const wchar_t *> names;
      for(i = 0; i < m_PropNames.Size(); i++)
        names.Add((const wchar_t *)m_PropNames[i]);

      NWindows::NCOM::CPropVariant *propValues = new NWindows::NCOM::CPropVariant[m_PropValues.Size()];
      try
      {
        for (int i = 0; i < m_PropValues.Size(); i++)
          propValues[i] = m_PropValues[i];
        RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size()));
      }
      catch(...)
      {
        delete []propValues;
        return E_FAIL;
      }
      delete []propValues;
    }
  }
  m_PropNames.Clear();
  m_PropValues.Clear();

  if (sfxModule != NULL)
  {
    CInFileStream *sfxStreamSpec = new CInFileStream;
    CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
    if (!sfxStreamSpec->Open(sfxModule))
      return E_FAIL;
      // throw "Can't open sfx module";
    RINOK(CopyBlock(sfxStream, outStream));
  }

  RINOK(outArchive->UpdateItems(outStream, updatePairs2.Size(),updateCallback));
  return outStreamSpec->Close();
}
Example #19
0
HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
{
  bool tryReduce = false;
  UInt32 reducedDictionarySize = 1 << 10;
  if (inSizeForReduce != 0 && (method.Id == k_LZMA || method.Id == k_LZMA2))
  {
    for (;;)
    {
      const UInt32 step = (reducedDictionarySize >> 1);
      if (reducedDictionarySize >= *inSizeForReduce)
      {
        tryReduce = true;
        break;
      }
      reducedDictionarySize += step;
      if (reducedDictionarySize >= *inSizeForReduce)
      {
        tryReduce = true;
        break;
      }
      if (reducedDictionarySize >= ((UInt32)3 << 30))
        break;
      reducedDictionarySize += step;
    }
  }

  {
    int numProps = method.Props.Size();
    CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
    coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
    if (setCoderProperties == NULL)
    {
      if (numProps != 0)
        return E_INVALIDARG;
    }
    else
    {
      CRecordVector<PROPID> propIDs;
      NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProps];
      HRESULT res = S_OK;
      try
      {
        for (int i = 0; i < numProps; i++)
        {
          const CProp &prop = method.Props[i];
          propIDs.Add(prop.Id);
          NWindows::NCOM::CPropVariant &value = values[i];
          value = prop.Value;
          // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
          if (tryReduce)
            if (prop.Id == NCoderPropID::kDictionarySize)
              if (value.vt == VT_UI4)
                if (reducedDictionarySize < value.ulVal)
            value.ulVal = reducedDictionarySize;
        }
        CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
        coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
        res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProps);
      }
      catch(...)
      {
        delete []values;
        throw;
      }
      delete []values;
      RINOK(res);
    }
  }
 
  /*
  CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
  coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
  if (writeCoderProperties != NULL)
  {
    CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
    CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
    outStreamSpec->Init();
    RINOK(writeCoderProperties->WriteCoderProperties(outStream));
    size_t size = outStreamSpec->GetSize();
    filterProps.SetCapacity(size);
    memmove(filterProps, outStreamSpec->GetBuffer(), size);
  }
  */
  return S_OK;
}
Example #20
0
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
    CFolder &folderItem,
    ISequentialOutStream *outStream,
    CRecordVector<UInt64> &packSizes,
    ICompressProgressInfo *compressProgress)
{
  if (_mixerCoderSpec == NULL)
  {
    RINOK(CreateMixerCoder(inSizeForReduce));
  }
  _mixerCoderSpec->ReInit();
  // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);

  CObjectVector<CInOutTempBuffer> inOutTempBuffers;
  CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
  CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
  int numMethods = _bindInfo.Coders.Size();
  int i;
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    inOutTempBuffers.Add(CInOutTempBuffer());
    inOutTempBuffers.Back().Create();
    inOutTempBuffers.Back().InitWriting();
  }
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    CSequentialOutTempBufferImp *tempBufferSpec = 
        new CSequentialOutTempBufferImp;
    CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
    tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
    tempBuffers.Add(tempBuffer);
    tempBufferSpecs.Add(tempBufferSpec);
  }

  for (i = 0; i < numMethods; i++)
    _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);

  if (_bindInfo.InStreams.IsEmpty())
    return E_FAIL;
  UInt32 mainCoderIndex, mainStreamIndex;
  _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
  _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
  if (inStreamSize != NULL)
  {
    CRecordVector<const UInt64 *> sizePointers;
    for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
      if (i == mainStreamIndex)
        sizePointers.Add(inStreamSize);
      else
        sizePointers.Add(NULL);
    _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
  }

  
  // UInt64 outStreamStartPos;
  // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
  
  CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = 
      new CSequentialInStreamSizeCount2;
  CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
  CSequentialOutStreamSizeCount *outStreamSizeCountSpec = 
      new CSequentialOutStreamSizeCount;
  CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;

  inStreamSizeCountSpec->Init(inStream);
  outStreamSizeCountSpec->SetStream(outStream);
  outStreamSizeCountSpec->Init();

  CRecordVector<ISequentialInStream *> inStreamPointers;
  CRecordVector<ISequentialOutStream *> outStreamPointers;
  inStreamPointers.Add(inStreamSizeCount);
  outStreamPointers.Add(outStreamSizeCount);
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    outStreamPointers.Add(tempBuffers[i - 1]);
  
  RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
    &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
  
  ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
      folderItem);
  
  packSizes.Add(outStreamSizeCountSpec->GetSize());
  
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
    inOutTempBuffer.FlushWrite();
    inOutTempBuffer.InitReading();
    inOutTempBuffer.WriteToStream(outStream);
    packSizes.Add(inOutTempBuffer.GetDataSize());
  }
  
  for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
  {
    int binder = _bindInfo.FindBinderForInStream(
        _bindReverseConverter->DestOutToSrcInMap[i]);
    UInt64 streamSize;
    if (binder < 0)
      streamSize = inStreamSizeCountSpec->GetSize();
    else
      streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
    folderItem.UnPackSizes.Add(streamSize);
  }
  for (i = numMethods - 1; i >= 0; i--)
  {
    // folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
    for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++)
      folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties 
          = _codersInfo[i].AltCoders[j].Properties;
  }
  return S_OK;
}
Example #21
0
int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode)
{
  if (numItems == 0)
    return FALSE;
  /*
  if (!m_ArchiverInfo.UpdateEnabled)
  {
    g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
    return FALSE;
  }
  */
  if ((opMode & OPM_SILENT) == 0)
  {
    const char *msgItems[]=
    {
      g_StartupInfo.GetMsgString(NMessageID::kDeleteTitle),
      g_StartupInfo.GetMsgString(NMessageID::kDeleteFiles),
      g_StartupInfo.GetMsgString(NMessageID::kDeleteDelete),
      g_StartupInfo.GetMsgString(NMessageID::kDeleteCancel)
    };
    char msg[1024];
    if (numItems == 1)
    {
      sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile), panelItems[0].FindData.cFileName);
      msgItems[1] = msg;
    }
    else if (numItems > 1)
    {
      sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles),
          numItems);
      msgItems[1] = msg;
    }
    if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems,
        sizeof(msgItems) / sizeof(msgItems[0]), 2) != 0)
      return (FALSE);
  }

  CScreenRestorer screenRestorer;
  CProgressBox progressBox;
  CProgressBox *progressBoxPointer = NULL;
  if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
  {
    screenRestorer.Save();

    progressBoxPointer = &progressBox;
    progressBox.Init(
        // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
        g_StartupInfo.GetMsgString(NMessageID::kDeleting), 48);
  }

  CWorkDirTempFile tempFile;
  if (tempFile.CreateTempFile(m_FileName) != S_OK)
    return FALSE;

  CRecordVector<UINT32> indices;
  indices.Reserve(numItems);
  int i;
  for (i = 0; i < numItems; i++)
    indices.Add((UINT32)panelItems[i].UserData);

  ////////////////////////////
  // Save _folder;

  UStringVector pathVector;
  GetPathParts(pathVector);
  
  CMyComPtr<IOutFolderArchive> outArchive;
  HRESULT result = m_ArchiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive);
  if (result != S_OK)
  {
    g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
    return FALSE;
  }
  outArchive->SetFolder(_folder);

  CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
  CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec);
  
  updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer);

  result = outArchive->DeleteItems(tempFile.OutStream, &indices.Front(), indices.Size(), updateCallback);
  updateCallback.Release();
  outArchive.Release();

  if (result == S_OK)
  {
    result = AfterUpdate(tempFile, pathVector);
  }
  if (result != S_OK)
  {
    ShowErrorMessage(result);
    return FALSE;
  }
  GetCurrentDir();
  return TRUE;
}
Example #22
0
HRESULT CDecoder::Decode(
    DECL_EXTERNAL_CODECS_LOC_VARS
    IInStream *inStream,
    UInt64 startPos,
    const UInt64 *packSizes,
    const CFolder &folderInfo,
    ISequentialOutStream *outStream,
    ICompressProgressInfo *compressProgress
    #ifndef _NO_CRYPTO
    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
    #endif
    #ifdef COMPRESS_MT
    , bool mtMode, UInt32 numThreads
    #endif
    )
{
  if (!folderInfo.CheckStructure())
    return E_NOTIMPL;
  #ifndef _NO_CRYPTO
  passwordIsDefined = false;
  #endif
  CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
  
  CLockedInStream lockedInStream;
  lockedInStream.Init(inStream);
  
  for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
  {
    CLockedSequentialInStreamImp *lockedStreamImpSpec = new
        CLockedSequentialInStreamImp;
    CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
    lockedStreamImpSpec->Init(&lockedInStream, startPos);
    startPos += packSizes[j];
    
    CLimitedSequentialInStream *streamSpec = new
        CLimitedSequentialInStream;
    CMyComPtr<ISequentialInStream> inStream = streamSpec;
    streamSpec->SetStream(lockedStreamImp);
    streamSpec->Init(packSizes[j]);
    inStreams.Add(inStream);
  }
  
  int numCoders = folderInfo.Coders.Size();
  
  CBindInfoEx bindInfo;
  ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
  bool createNewCoders;
  if (!_bindInfoExPrevIsDefined)
    createNewCoders = true;
  else
    createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
  if (createNewCoders)
  {
    int i;
    _decoders.Clear();
    // _decoders2.Clear();
    
    _mixerCoder.Release();

    if (_multiThread)
    {
      _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;
      _mixerCoder = _mixerCoderMTSpec;
      _mixerCoderCommon = _mixerCoderMTSpec;
    }
    else
    {
      #ifdef _ST_MODE
      _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;
      _mixerCoder = _mixerCoderSTSpec;
      _mixerCoderCommon = _mixerCoderSTSpec;
      #endif
    }
    RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));
    
    for (i = 0; i < numCoders; i++)
    {
      const CCoderInfo &coderInfo = folderInfo.Coders[i];

  
      CMyComPtr<ICompressCoder> decoder;
      CMyComPtr<ICompressCoder2> decoder2;
      RINOK(CreateCoder(
          EXTERNAL_CODECS_LOC_VARS
          coderInfo.MethodID, decoder, decoder2, false));
      CMyComPtr<IUnknown> decoderUnknown;
      if (coderInfo.IsSimpleCoder())
      {
        if (decoder == 0)
          return E_NOTIMPL;

        decoderUnknown = (IUnknown *)decoder;
        
        if (_multiThread)
          _mixerCoderMTSpec->AddCoder(decoder);
        #ifdef _ST_MODE
        else
          _mixerCoderSTSpec->AddCoder(decoder, false);
        #endif
      }
      else
      {
        if (decoder2 == 0)
          return E_NOTIMPL;
        decoderUnknown = (IUnknown *)decoder2;
        if (_multiThread)
          _mixerCoderMTSpec->AddCoder2(decoder2);
        #ifdef _ST_MODE
        else
          _mixerCoderSTSpec->AddCoder2(decoder2, false);
        #endif
      }
      _decoders.Add(decoderUnknown);
      #ifdef EXTERNAL_CODECS
      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
      decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
      if (setCompressCodecsInfo)
      {
        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
      }
      #endif
    }
    _bindInfoExPrev = bindInfo;
    _bindInfoExPrevIsDefined = true;
  }
  int i;
  _mixerCoderCommon->ReInit();
  
  UInt32 packStreamIndex = 0, unpackStreamIndex = 0;
  UInt32 coderIndex = 0;
  // UInt32 coder2Index = 0;
  
  for (i = 0; i < numCoders; i++)
  {
    const CCoderInfo &coderInfo = folderInfo.Coders[i];
    CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
    
    {
      CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
      decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
      if (setDecoderProperties)
      {
        const CByteBuffer &props = coderInfo.Props;
        size_t size = props.GetCapacity();
        if (size > 0xFFFFFFFF)
          return E_NOTIMPL;
        if (size > 0)
        {
          RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
        }
      }
    }

    #ifdef COMPRESS_MT
    if (mtMode)
    {
      CMyComPtr<ICompressSetCoderMt> setCoderMt;
      decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
      if (setCoderMt)
      {
        RINOK(setCoderMt->SetNumberOfThreads(numThreads));
      }
    }
    #endif

    #ifndef _NO_CRYPTO
    {
      CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
      decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
      if (cryptoSetPassword)
      {
        if (getTextPassword == 0)
          return E_FAIL;
        CMyComBSTR passwordBSTR;
        RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
        CByteBuffer buffer;
        passwordIsDefined = true;
        const UString password(passwordBSTR);
        const UInt32 sizeInBytes = password.Length() * 2;
        buffer.SetCapacity(sizeInBytes);
        for (int i = 0; i < password.Length(); i++)
        {
          wchar_t c = password[i];
          ((Byte *)buffer)[i * 2] = (Byte)c;
          ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
        }
        RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
      }
    }
    #endif

    coderIndex++;
    
    UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
    UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
    CRecordVector<const UInt64 *> packSizesPointers;
    CRecordVector<const UInt64 *> unpackSizesPointers;
    packSizesPointers.Reserve(numInStreams);
    unpackSizesPointers.Reserve(numOutStreams);
    UInt32 j;
    for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
      unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);
    
    for (j = 0; j < numInStreams; j++, packStreamIndex++)
    {
      int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
      if (bindPairIndex >= 0)
        packSizesPointers.Add(
        &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
      else
      {
        int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
        if (index < 0)
          return E_FAIL;
        packSizesPointers.Add(&packSizes[index]);
      }
    }
    
    _mixerCoderCommon->SetCoderInfo(i,
        &packSizesPointers.Front(),
        &unpackSizesPointers.Front());
  }
  UInt32 mainCoder, temp;
  bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);

  if (_multiThread)
    _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
  /*
  else
    _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
  */
  
  if (numCoders == 0)
    return 0;
  CRecordVector<ISequentialInStream *> inStreamPointers;
  inStreamPointers.Reserve(inStreams.Size());
  for (i = 0; i < inStreams.Size(); i++)
    inStreamPointers.Add(inStreams[i]);
  ISequentialOutStream *outStreamPointer = outStream;
  return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
    inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
}
Example #23
0
HRESULT CEncoder::Encode(
    DECL_EXTERNAL_CODECS_LOC_VARS
    ISequentialInStream *inStream,
    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
    CFolder &folderItem,
    ISequentialOutStream *outStream,
    CRecordVector<UInt64> &packSizes,
    ICompressProgressInfo *compressProgress)
{
    RINOK(EncoderConstr());

    if (_mixerCoderSpec == NULL)
    {
        RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
    }
    _mixerCoderSpec->ReInit();
    // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);

    CObjectVector<CInOutTempBuffer> inOutTempBuffers;
    CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
    CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
    int numMethods = _bindInfo.Coders.Size();
    int i;
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        inOutTempBuffers.Add(CInOutTempBuffer());
        inOutTempBuffers.Back().Create();
        inOutTempBuffers.Back().InitWriting();
    }
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
        CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
        tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
        tempBuffers.Add(tempBuffer);
        tempBufferSpecs.Add(tempBufferSpec);
    }

    for (i = 0; i < numMethods; i++)
        _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);

    if (_bindInfo.InStreams.IsEmpty())
        return E_FAIL;
    UInt32 mainCoderIndex, mainStreamIndex;
    _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);

    if (inStreamSize != NULL)
    {
        CRecordVector<const UInt64 *> sizePointers;
        for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
            if (i == mainStreamIndex)
                sizePointers.Add(inStreamSize);
            else
                sizePointers.Add(NULL);
        _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
    }


    // UInt64 outStreamStartPos;
    // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));

    CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
        new CSequentialInStreamSizeCount2;
    CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
    CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
        new CSequentialOutStreamSizeCount;
    CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;

    inStreamSizeCountSpec->Init(inStream);
    outStreamSizeCountSpec->SetStream(outStream);
    outStreamSizeCountSpec->Init();

    CRecordVector<ISequentialInStream *> inStreamPointers;
    CRecordVector<ISequentialOutStream *> outStreamPointers;
    inStreamPointers.Add(inStreamSizeCount);
    outStreamPointers.Add(outStreamSizeCount);
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
        outStreamPointers.Add(tempBuffers[i - 1]);

    for (i = 0; i < _codersInfo.Size(); i++)
    {
        CCoderInfo &encodingInfo = _codersInfo[i];

        CMyComPtr<ICryptoResetInitVector> resetInitVector;
        _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
        if (resetInitVector != NULL)
        {
            resetInitVector->ResetInitVector();
        }

        CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
        _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
        if (writeCoderProperties != NULL)
        {
            CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
            CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
            outStreamSpec->Init();
            writeCoderProperties->WriteCoderProperties(outStream);
            size_t size = outStreamSpec->GetSize();
            encodingInfo.Props.SetCapacity(size);
            memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size);
        }
    }

    UInt32 progressIndex = mainCoderIndex;

    for (i = 0; i + 1 < _codersInfo.Size(); i++)
    {
        UInt64 m = _codersInfo[i].MethodID;
        if (m == k_Delta || m == k_BCJ || m == k_BCJ2)
            progressIndex = i + 1;
    }

    _mixerCoderSpec->SetProgressCoderIndex(progressIndex);

    RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
                            &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));

    ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
                                    folderItem);

    packSizes.Add(outStreamSizeCountSpec->GetSize());

    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
        RINOK(inOutTempBuffer.WriteToStream(outStream));
        packSizes.Add(inOutTempBuffer.GetDataSize());
    }

    for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
    {
        int binder = _bindInfo.FindBinderForInStream(
                         _bindReverseConverter->DestOutToSrcInMap[i]);
        UInt64 streamSize;
        if (binder < 0)
            streamSize = inStreamSizeCountSpec->GetSize();
        else
            streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
        folderItem.UnpackSizes.Add(streamSize);
    }
    for (i = numMethods - 1; i >= 0; i--)
        folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
    return S_OK;
}
Example #24
0
HRESULT CPlugin::ShowAttributesWindow()
{
  PluginPanelItem pluginPanelItem;
  if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem))
    return S_FALSE;
  if (strcmp(pluginPanelItem.FindData.cFileName, "..") == 0 &&
        NFile::NFind::NAttributes::IsDir(pluginPanelItem.FindData.dwFileAttributes))
    return S_FALSE;
  int itemIndex = pluginPanelItem.UserData;

  CObjectVector<CArchiveItemProperty> properties;
  UInt32 numProps;
  RINOK(_folder->GetNumberOfProperties(&numProps));
  int i;
  for (i = 0; i < (int)numProps; i++)
  {
    CMyComBSTR name;
    PROPID propID;
    VARTYPE vt;
    RINOK(_folder->GetPropertyInfo(i, &name, &propID, &vt));
    CArchiveItemProperty prop;
    prop.Type = vt;
    prop.ID = propID;
    if (prop.ID  == kpidPath)
      prop.ID  = kpidName;
    prop.Name = GetNameOfProp(propID, name);
    properties.Add(prop);
  }

  int size = 2;
  CRecordVector<CInitDialogItem> initDialogItems;
  
  int xSize = 70;
  CInitDialogItem idi =
  { DI_DOUBLEBOX, 3, 1, xSize - 4, size - 2, false, false, 0, false, NMessageID::kProperties, NULL, NULL };
  initDialogItems.Add(idi);
  AStringVector values;

  for (i = 0; i < properties.Size(); i++)
  {
    const CArchiveItemProperty &property = properties[i];

    CInitDialogItem idi =
      { DI_TEXT, 5, 3 + i, 0, 0, false, false, 0, false, 0, NULL, NULL };
    int index = FindPropertyToName(property.ID);
    if (index < 0)
    {
      idi.DataMessageId = -1;
      idi.DataString = property.Name;
    }
    else
      idi.DataMessageId = kPROPIDToName[index].PluginID;
    initDialogItems.Add(idi);
    
    NCOM::CPropVariant prop;
    RINOK(_folder->GetProperty(itemIndex, property.ID, &prop));
    CSysString s = PropToString(prop, property.ID);
    values.Add(s);
    
    {
      CInitDialogItem idi =
      { DI_TEXT, 30, 3 + i, 0, 0, false, false, 0, false, -1, NULL, NULL };
      initDialogItems.Add(idi);
    }
  }

  int numLines = values.Size();
  for (i = 0; i < numLines; i++)
  {
    CInitDialogItem &idi = initDialogItems[1 + i * 2 + 1];
    idi.DataString = values[i];
  }
  
  int numDialogItems = initDialogItems.Size();
  
  CRecordVector<FarDialogItem> dialogItems;
  dialogItems.Reserve(numDialogItems);
  for (i = 0; i < numDialogItems; i++)
    dialogItems.Add(FarDialogItem());
  g_StartupInfo.InitDialogItems(&initDialogItems.Front(),
      &dialogItems.Front(), numDialogItems);
  
  int maxLen = 0;
  for (i = 0; i < numLines; i++)
  {
    FarDialogItem &dialogItem = dialogItems[1 + i * 2];
    int len = (int)strlen(dialogItem.Data);
    if (len > maxLen)
      maxLen = len;
  }
  int maxLen2 = 0;
  const int kSpace = 10;
  for (i = 0; i < numLines; i++)
  {
    FarDialogItem &dialogItem = dialogItems[1 + i * 2 + 1];
    int len = (int)strlen(dialogItem.Data);
    if (len > maxLen2)
      maxLen2 = len;
    dialogItem.X1 = maxLen + kSpace;
  }
  size = numLines + 6;
  xSize = maxLen + kSpace + maxLen2 + 5;
  FarDialogItem &firstDialogItem = dialogItems.Front();
  firstDialogItem.Y2 = size - 2;
  firstDialogItem.X2 = xSize - 4;
  
  /* int askCode = */ g_StartupInfo.ShowDialog(xSize, size, NULL, &dialogItems.Front(), numDialogItems);
  return S_OK;
}
Example #25
0
HRESULT CPanel::CreateShellContextMenu(
    const CRecordVector<UInt32> &operatedIndices,
    CMyComPtr<IContextMenu> &systemContextMenu)
{
  systemContextMenu.Release();
  UString folderPath = GetFsPath();

  CMyComPtr<IShellFolder> desktopFolder;
  RINOK(::SHGetDesktopFolder(&desktopFolder));
  if (!desktopFolder)
  {
    // ShowMessage("Failed to get Desktop folder.");
    return E_FAIL;
  }
  
  // Separate the file from the folder.

  
  // Get a pidl for the folder the file
  // is located in.
  LPITEMIDLIST parentPidl;
  DWORD eaten;
  RINOK(desktopFolder->ParseDisplayName(
      GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath,
      &eaten, &parentPidl, 0));
  
  // Get an IShellFolder for the folder
  // the file is located in.
  CMyComPtr<IShellFolder> parentFolder;
  RINOK(desktopFolder->BindToObject(parentPidl,
      0, IID_IShellFolder, (void**)&parentFolder));
  if (!parentFolder)
  {
    // ShowMessage("Invalid file name.");
    return E_FAIL;
  }
  
  // Get a pidl for the file itself.
  CRecordVector<LPITEMIDLIST> pidls;
  pidls.Reserve(operatedIndices.Size());
  for (int i = 0; i < operatedIndices.Size(); i++)
  {
    LPITEMIDLIST pidl;
    UString fileName = GetItemRelPath(operatedIndices[i]);
    if (IsFSDrivesFolder())
      fileName += WCHAR_PATH_SEPARATOR;
    RINOK(parentFolder->ParseDisplayName(GetParent(), 0,
      (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0));
    pidls.Add(pidl);
  }

  ITEMIDLIST temp;
  if (pidls.Size() == 0)
  {
    temp.mkid.cb = 0;
    /*
    LPITEMIDLIST pidl;
    HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0,
      L"." WSTRING_PATH_SEPARATOR, &eaten, &pidl, 0);
    if (result != NOERROR)
      return;
    */
    pidls.Add(&temp);
  }

  // Get the IContextMenu for the file.
  CMyComPtr<IContextMenu> cm;
  RINOK( parentFolder->GetUIObjectOf(GetParent(), pidls.Size(),
      (LPCITEMIDLIST *)&pidls.Front(), IID_IContextMenu, 0, (void**)&cm));
  if (!cm)
  {
    // ShowMessage("Unable to get context menu interface.");
    return E_FAIL;
  }
  systemContextMenu = cm;
  return S_OK;
}
Example #26
0
static HRESULT DecompressArchive(
    const CArc &arc,
    UInt64 packSize,
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &options,
    IExtractCallbackUI *callback,
    CArchiveExtractCallback *extractCallbackSpec,
    UString &errorMessage,
    UInt64 &stdInProcessed)
{
  stdInProcessed = 0;
  IInArchive *archive = arc.Archive;
  CRecordVector<UInt32> realIndices;
  if (!options.StdInMode)
  {
    UInt32 numItems;
    RINOK(archive->GetNumberOfItems(&numItems));

    for (UInt32 i = 0; i < numItems; i++)
    {
      UString filePath;
      RINOK(arc.GetItemPath(i, filePath));
      bool isFolder;
      RINOK(IsArchiveItemFolder(archive, i, isFolder));
      if (!wildcardCensor.CheckPath(filePath, !isFolder))
        continue;
      realIndices.Add(i);
    }
    if (realIndices.Size() == 0)
    {
      callback->ThereAreNoFiles();
      return S_OK;
    }
  }

  UStringVector removePathParts;

  UString outDir = options.OutputDir;
  outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName));
  #ifdef _WIN32
  // GetCorrectFullFsPath doesn't like "..".
  // outDir.TrimRight();
  // outDir = GetCorrectFullFsPath(outDir);
  #endif

  if (!outDir.IsEmpty())
    if (!NFile::NDirectory::CreateComplexDirectory(outDir))
    {
      HRESULT res = ::GetLastError();
      if (res == S_OK)
        res = E_FAIL;
      errorMessage = ((UString)L"Can not create output directory ") + outDir;
      return res;
    }

  extractCallbackSpec->Init(
      options.StdInMode ? &wildcardCensor : NULL,
      &arc,
      callback,
      options.StdOutMode, options.TestMode, options.CalcCrc,
      outDir,
      removePathParts,
      packSize);

  #if !defined(_7ZIP_ST) && !defined(_SFX)
  RINOK(SetProperties(archive, options.Properties));
  #endif

  HRESULT result;
  Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0;
  if (options.StdInMode)
  {
    result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec);
    NCOM::CPropVariant prop;
    if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK)
      if (prop.vt == VT_UI8 || prop.vt == VT_UI4)
        stdInProcessed = ConvertPropVariantToUInt64(prop);
  }
  else
    result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);

  return callback->ExtractResult(result);
}