STDMETHODIMP CAgent::DeleteItems( const wchar_t *newArchiveName, const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback100) { if (!CanUpdate()) return E_NOTIMPL; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); CUIntVector realIndices; _agentFolder->GetRealIndices(indices, numItems, realIndices); CRecordVector<CUpdatePair2> updatePairs; int curIndex = 0; UInt32 numItemsInArchive; RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); for (UInt32 i = 0; i < numItemsInArchive; i++) { if (curIndex < realIndices.Size()) if (realIndices[curIndex] == i) { curIndex++; continue; } CUpdatePair2 up2; up2.NewData = up2.NewProps = false; up2.IsAnti = false; // check it. Maybe it can be undefined up2.ArcIndex = i; updatePairs.Add(up2); } updateCallbackSpec->UpdatePairs = &updatePairs; updateCallbackSpec->Archive = GetArchive(); updateCallbackSpec->Callback = &updateCallbackAgent; return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); }
void CPanel::OnRefreshStatusBar() { CRecordVector<UINT32> indices; GetOperatedItemIndices(indices); _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, 0x02000301, NumberToString(indices.Size()))); UString selectSizeString; if (indices.Size() > 0) { UInt64 totalSize = 0; for (int i = 0; i < indices.Size(); i++) totalSize += GetItemSize(indices[i]); selectSizeString = ConvertSizeToString(totalSize); } _statusBar.SetText(1, selectSizeString); int focusedItem = _listView.GetFocusedItem(); UString sizeString; UString dateString; if (focusedItem >= 0 && _listView.GetSelectedCount() > 0) { int realIndex = GetRealItemIndex(focusedItem); if (realIndex != kParentIndex) { sizeString = ConvertSizeToString(GetItemSize(realIndex)); NCOM::CPropVariant prop; if (_folder->GetProperty(realIndex, kpidMTime, &prop) == S_OK) dateString = ConvertPropertyToString(prop, kpidMTime, false); } } _statusBar.SetText(2, sizeString); _statusBar.SetText(3, dateString); // _statusBar.SetText(4, nameString); // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize))); }
HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods) { UStringVector names = hashMethods; if (names.IsEmpty()) { UString s; s.SetFromAscii(k_DefaultHashMethod); names.Add(s); } CRecordVector<CMethodId> ids; CObjectVector<COneMethodInfo> methods; unsigned i; for (i = 0; i < names.Size(); i++) { COneMethodInfo m; RINOK(m.ParseMethodFromString(names[i])); if (m.MethodName.IsEmpty()) m.MethodName = k_DefaultHashMethod; if (m.MethodName == "*") { CRecordVector<CMethodId> tempMethods; GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods); methods.Clear(); ids.Clear(); FOR_VECTOR (t, tempMethods) { unsigned index = ids.AddToUniqueSorted(tempMethods[t]); if (ids.Size() != methods.Size()) methods.Insert(index, m); } break; }
static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD attrib, int &insertPos) { unsigned left = 0, right = vect.Size(); while (left != right) { unsigned mid = (left + right) / 2; DWORD midAttrib = vect[mid].Attrib; if (attrib == midAttrib) return mid; if (attrib < midAttrib) right = mid; else left = mid + 1; } insertPos = left; return -1; }
HRESULT CFolderOutStream::WriteEmptyFiles() { if (m_FileIsOpen) return S_OK; for (; m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++) { const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; UInt64 fileSize = item.Size; if (fileSize != 0) return S_OK; HRESULT result = OpenFile(); m_RealOutStream.Release(); RINOK(result); RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); } return S_OK; }
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems) { sizes.Clear(); sizePointers.Clear(); for(UInt32 i = 0; i < numItems; i++) { if (srcSizes == 0 || srcSizes[i] == NULL) { sizes.Add(0); sizePointers.Add(NULL); } else { sizes.Add(*srcSizes[i]); sizePointers.Add(&sizes.Back()); } } }
static int FindHash(const CRecordVector<CStreamInfo> &streams, const CRecordVector<int> &sortedByHash, const Byte *hash) { int left = 0, right = streams.Size(); while (left != right) { int mid = (left + right) / 2; int streamIndex = sortedByHash[mid]; UInt32 i; const Byte *hash2 = streams[streamIndex].Hash; for (i = 0; i < kHashSize; i++) if (hash[i] != hash2[i]) break; if (i == kHashSize) return streamIndex; if (hash[i] < hash2[i]) right = mid; else left = mid + 1; } return -1; }
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; } } }
void CPanel::OpenSelectedItems(bool tryInternal) { CRecordVector<UInt32> indices; GetOperatedItemIndices(indices); if (indices.Size() > 20) { MessageBoxErrorLang(IDS_TOO_MANY_ITEMS, 0x02000606); return; } int focusedItem = _listView.GetFocusedItem(); if (focusedItem >= 0) { int realIndex = GetRealItemIndex(focusedItem); if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0) && _listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED) indices.Insert(0, realIndex); } bool dirIsStarted = false; for (int i = 0; i < indices.Size(); i++) { UInt32 index = indices[i]; // CFileInfo &aFile = m_Files[index]; if (IsItemFolder(index)) { if (!dirIsStarted) { if (tryInternal) { OpenFolder(index); dirIsStarted = true; break; } else OpenFolderExternal(index); } } else OpenItem(index, (tryInternal && indices.Size() == 1), true); } }
void CInArchive::ReadPackInfo( UInt64 &dataOffset, CRecordVector<UInt64> &packSizes, CBoolVector &packCRCsDefined, CRecordVector<UInt32> &packCRCs) { dataOffset = ReadNumber(); CNum numPackStreams = ReadNum(); WaitAttribute(NID::kSize); packSizes.Clear(); packSizes.Reserve(numPackStreams); for (CNum i = 0; i < numPackStreams; i++) packSizes.Add(ReadNumber()); UInt64 type; for (;;) { type = ReadID(); if (type == NID::kEnd) break; if (type == NID::kCRC) { ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); continue; } SkipData(); } if (packCRCsDefined.IsEmpty()) { BoolVector_Fill_False(packCRCsDefined, numPackStreams); packCRCs.Reserve(numPackStreams); packCRCs.Clear(); for (CNum i = 0; i < numPackStreams; i++) packCRCs.Add(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; }
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); }
void CPanel::DeleteItems(bool toRecycleBin) { CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); CRecordVector<UInt32> indices; GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; CSelectedState state; SaveSelectedState(state); #ifndef UNDER_CE // WM6 / SHFileOperationW doesn't ask user! So we use internal delete bool useInternalDelete = false; if (IsFSFolder() && toRecycleBin) { #ifndef _UNICODE if (!g_IsNT) { CDynamicBuffer<CHAR> buffer; size_t size = 0; for (int i = 0; i < indices.Size(); i++) { const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i])); buffer.EnsureCapacity(size + path.Length() + 1); memmove(((CHAR *)buffer) + size, (const CHAR *)path, (path.Length() + 1) * sizeof(CHAR)); size += path.Length() + 1; } buffer.EnsureCapacity(size + 1); ((CHAR *)buffer)[size] = 0; SHFILEOPSTRUCTA fo; fo.hwnd = GetParent(); fo.wFunc = FO_DELETE; fo.pFrom = (const CHAR *)buffer; fo.pTo = 0; fo.fFlags = 0; if (toRecycleBin) fo.fFlags |= FOF_ALLOWUNDO; // fo.fFlags |= FOF_NOCONFIRMATION; // fo.fFlags |= FOF_NOERRORUI; // fo.fFlags |= FOF_SILENT; // fo.fFlags |= FOF_WANTNUKEWARNING; fo.fAnyOperationsAborted = FALSE; fo.hNameMappings = 0; fo.lpszProgressTitle = 0; /* int res = */ ::SHFileOperationA(&fo); } else #endif { CDynamicBuffer<WCHAR> buffer; size_t size = 0; int maxLen = 0; for (int i = 0; i < indices.Size(); i++) { // L"\\\\?\\") doesn't work here. const UString path = GetFsPath() + GetItemRelPath(indices[i]); if (path.Length() > maxLen) maxLen = path.Length(); buffer.EnsureCapacity(size + path.Length() + 1); memmove(((WCHAR *)buffer) + size, (const WCHAR *)path, (path.Length() + 1) * sizeof(WCHAR)); size += path.Length() + 1; } buffer.EnsureCapacity(size + 1); ((WCHAR *)buffer)[size] = 0; if (maxLen >= MAX_PATH) { if (toRecycleBin) { MessageBoxErrorLang(IDS_ERROR_LONG_PATH_TO_RECYCLE, 0x03020218); return; } useInternalDelete = true; } else { SHFILEOPSTRUCTW fo; fo.hwnd = GetParent(); fo.wFunc = FO_DELETE; fo.pFrom = (const WCHAR *)buffer; fo.pTo = 0; fo.fFlags = 0; if (toRecycleBin) fo.fFlags |= FOF_ALLOWUNDO; fo.fAnyOperationsAborted = FALSE; fo.hNameMappings = 0; fo.lpszProgressTitle = 0; int res; #ifdef _UNICODE res = ::SHFileOperationW(&fo); #else SHFileOperationWP shFileOperationW = (SHFileOperationWP) ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHFileOperationW"); if (shFileOperationW == 0) return; res = shFileOperationW(&fo); #endif } } /* if (fo.fAnyOperationsAborted) MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217)); */ } else useInternalDelete = true; if (useInternalDelete) #endif DeleteItemsInternal(indices); RefreshListCtrl(state); }
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); }
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; }
static HRESULT EnumerateDirItems( const NWildcard::CCensorNode &curNode, const UString &diskPrefix, // full disk path prefix const UString &archivePrefix, // prefix from root const UStringVector &addArchivePrefix, // prefix from curNode CObjectVector<CDirItem> &dirItems, bool enterToSubFolders, IEnumDirItemCallback *callback, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes) { if (!enterToSubFolders) if (curNode.NeedCheckSubDirs()) enterToSubFolders = true; if (callback) RINOK(callback->CheckBreak()); // try direct_names case at first if (addArchivePrefix.IsEmpty() && !enterToSubFolders) { // check that all names are direct int i; for (i = 0; i < curNode.IncludeItems.Size(); i++) { const NWildcard::CItem &item = curNode.IncludeItems[i]; if (item.Recursive || item.PathParts.Size() != 1) break; const UString &name = item.PathParts.Front(); if (name.IsEmpty() || DoesNameContainWildCard(name)) break; } if (i == curNode.IncludeItems.Size()) { // all names are direct (no wildcards) // so we don't need file_system's dir enumerator CRecordVector<bool> needEnterVector; for (i = 0; i < curNode.IncludeItems.Size(); i++) { const NWildcard::CItem &item = curNode.IncludeItems[i]; const UString &name = item.PathParts.Front(); const UString fullPath = diskPrefix + name; NFind::CFileInfoW fileInfo; if (!NFind::FindFile(fullPath, fileInfo)) { errorCodes.Add(::GetLastError()); errorPaths.Add(fullPath); continue; } bool isDir = fileInfo.IsDirectory(); if (isDir && !item.ForDir || !isDir && !item.ForFile) { errorCodes.Add((DWORD)E_FAIL); errorPaths.Add(fullPath); continue; } const UString realName = fileInfo.getFileName(); const UString realDiskPath = diskPrefix + realName; { UStringVector pathParts; pathParts.Add(fileInfo.getFileName()); if (curNode.CheckPathToRoot(false, pathParts, !isDir)) continue; } AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems); if (!isDir) continue; UStringVector addArchivePrefixNew; const NWildcard::CCensorNode *nextNode = 0; int index = curNode.FindSubNode(name); if (index >= 0) { for (int t = needEnterVector.Size(); t <= index; t++) needEnterVector.Add(true); needEnterVector[index] = false; nextNode = &curNode.SubNodes[index]; } else { nextNode = &curNode; addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support } RINOK(EnumerateDirItems(*nextNode, realDiskPath + wchar_t(kDirDelimiter), archivePrefix + realName + wchar_t(kDirDelimiter), addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes)); } for (i = 0; i < curNode.SubNodes.Size(); i++) { if (i < needEnterVector.Size()) if (!needEnterVector[i]) continue; const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; const UString fullPath = diskPrefix + nextNode.Name; NFind::CFileInfoW fileInfo; if (!NFind::FindFile(fullPath, fileInfo)) { if (!nextNode.AreThereIncludeItems()) continue; errorCodes.Add(::GetLastError()); errorPaths.Add(fullPath); continue; } if (!fileInfo.IsDirectory()) { errorCodes.Add((DWORD)E_FAIL); errorPaths.Add(fullPath); continue; } RINOK(EnumerateDirItems(nextNode, diskPrefix + fileInfo.getFileName() + wchar_t(kDirDelimiter), archivePrefix + fileInfo.getFileName() + wchar_t(kDirDelimiter), UStringVector(), dirItems, false, callback, errorPaths, errorCodes)); } return S_OK; } } NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard)); for (;;) { NFind::CFileInfoW fileInfo; bool found; if (!enumerator.Next(fileInfo, found)) { errorCodes.Add(::GetLastError()); errorPaths.Add(diskPrefix); break; } if (!found) break; if (callback) RINOK(callback->CheckBreak()); const UString &name = fileInfo.getFileName(); bool enterToSubFolders2 = enterToSubFolders; UStringVector addArchivePrefixNew = addArchivePrefix; addArchivePrefixNew.Add(name); { UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory())) continue; } if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory())) { AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems); if (fileInfo.IsDirectory()) enterToSubFolders2 = true; } if (!fileInfo.IsDirectory()) continue; const NWildcard::CCensorNode *nextNode = 0; if (addArchivePrefix.IsEmpty()) { int index = curNode.FindSubNode(name); if (index >= 0) nextNode = &curNode.SubNodes[index]; } if (!enterToSubFolders2 && nextNode == 0) continue; addArchivePrefixNew = addArchivePrefix; if (nextNode == 0) { nextNode = &curNode; addArchivePrefixNew.Add(name); } RINOK(EnumerateDirItems(*nextNode, diskPrefix + name + wchar_t(kDirDelimiter), archivePrefix + name + wchar_t(kDirDelimiter), addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes)); } return S_OK; }
void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode) { const UString name = GetItemName(index); if (IsNameVirus(name)) { MessageBoxErrorLang(IDS_VIRUS, 0x03020284); return; } CMyComPtr<IFolderOperations> folderOperations; if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) { MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); return; } bool tryAsArchive = tryInternal && (!tryExternal || !DoItemAlwaysStart(name)); UString fullVirtPath = _currentFolderPrefix + name; NFile::NDirectory::CTempDirectoryW tempDirectory; tempDirectory.Create(kTempDirPrefix); UString tempDir = tempDirectory.GetPath(); UString tempDirNorm = tempDir; NFile::NName::NormalizeDirPathPrefix(tempDirNorm); UString tempFilePath = tempDirNorm + GetCorrectFsPath(name); CTempFileInfo tempFileInfo; tempFileInfo.ItemName = name; tempFileInfo.FolderPath = tempDir; tempFileInfo.FilePath = tempFilePath; tempFileInfo.NeedDelete = true; if (tryAsArchive) { CMyComPtr<IInArchiveGetStream> getStream; _folder.QueryInterface(IID_IInArchiveGetStream, &getStream); if (getStream) { CMyComPtr<ISequentialInStream> subSeqStream; getStream->GetStream(index, &subSeqStream); if (subSeqStream) { CMyComPtr<IInStream> subStream; subSeqStream.QueryInterface(IID_IInStream, &subStream); if (subStream) { bool encrypted; if (OpenItemAsArchive(subStream, tempFileInfo, fullVirtPath, encrypted) == S_OK) { tempDirectory.DisableDeleting(); RefreshListCtrl(); return; } } } } } CRecordVector<UInt32> indices; indices.Add(index); UStringVector messages; bool usePassword = false; UString password; if (_parentFolders.Size() > 0) { const CFolderLink &fl = _parentFolders.Back(); usePassword = fl.UsePassword; password = fl.Password; } HRESULT result = CopyTo(indices, tempDirNorm, false, true, &messages, usePassword, password); if (_parentFolders.Size() > 0) { CFolderLink &fl = _parentFolders.Back(); fl.UsePassword = usePassword; fl.Password = password; } if (!messages.IsEmpty()) return; if (result != S_OK) { if (result != E_ABORT) MessageBoxError(result); return; } if (tryAsArchive) { bool encrypted; if (OpenItemAsArchive(NULL, tempFileInfo, fullVirtPath, encrypted) == S_OK) { tempDirectory.DisableDeleting(); RefreshListCtrl(); return; } } CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr(new CTmpProcessInfo()); CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get(); tmpProcessInfo->FolderPath = tempDir; tmpProcessInfo->FilePath = tempFilePath; tmpProcessInfo->NeedDelete = true; tmpProcessInfo->UsePassword = usePassword; tmpProcessInfo->Password = password; if (!tmpProcessInfo->FileInfo.Find(tempFilePath)) return; CTmpProcessInfoRelease tmpProcessInfoRelease(*tmpProcessInfo); if (!tryExternal) return; CProcess process; HRESULT res; if (editMode) res = StartEditApplication(tempFilePath, (HWND)*this, process); else res = StartApplication(tempDirNorm, tempFilePath, (HWND)*this, process); if ((HANDLE)process == 0) return; tmpProcessInfo->Window = (HWND)(*this); tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix; tmpProcessInfo->ItemName = name; tmpProcessInfo->ProcessHandle = process.Detach(); NWindows::CThread thread; if (thread.Create(MyThreadFunction, tmpProcessInfo) != S_OK) throw 271824; tempDirectory.DisableDeleting(); tmpProcessInfoPtr.release(); tmpProcessInfoRelease._needDelete = false; }
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(); }
void CPanel::Properties() { CMyComPtr<IGetFolderArcProps> getFolderArcProps; _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); if (!getFolderArcProps) { InvokeSystemCommand("properties"); return; } { UString message; CRecordVector<UInt32> operatedIndices; GetOperatedItemIndices(operatedIndices); if (operatedIndices.Size() == 1) { UInt32 index = operatedIndices[0]; // message += L"Item:\n"; UInt32 numProps; if (_folder->GetNumberOfProperties(&numProps) == S_OK) { for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE varType; if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) continue; NCOM::CPropVariant prop; if (_folder->GetProperty(index, propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } message += kSeparator; } /* message += LangString(IDS_PROP_FILE_TYPE, 0x02000214); message += kPropValueSeparator; message += GetFolderTypeID(); message += L"\n"; */ { NCOM::CPropVariant prop; if (_folder->GetFolderProperty(kpidPath, &prop) == S_OK) { AddPropertyString(kpidName, L"Path", prop, message); } } CMyComPtr<IFolderProperties> folderProperties; _folder.QueryInterface(IID_IFolderProperties, &folderProperties); if (folderProperties) { UInt32 numProps; if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK) { for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (_folder->GetFolderProperty(propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } } CMyComPtr<IGetFolderArcProps> getFolderArcProps; _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); if (getFolderArcProps) { CMyComPtr<IFolderArcProps> getProps; getFolderArcProps->GetFolderArcProps(&getProps); if (getProps) { UInt32 numLevels; if (getProps->GetArcNumLevels(&numLevels) != S_OK) numLevels = 0; for (UInt32 level2 = 0; level2 < numLevels; level2++) { { UInt32 level = numLevels - 1 - level2; UInt32 numProps; if (getProps->GetArcNumProps(level, &numProps) == S_OK) { message += kSeparator; for (Int32 i = -3; i < (Int32)numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; switch (i) { case -3: propID = kpidPath; break; case -2: propID = kpidType; break; case -1: propID = kpidError; break; default: if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK) continue; } NCOM::CPropVariant prop; if (getProps->GetArcProp(level, propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } } if (level2 != numLevels - 1) { UInt32 level = numLevels - 1 - level2; UInt32 numProps; if (getProps->GetArcNumProps2(level, &numProps) == S_OK) { message += kSeparatorSmall; for (Int32 i = 0; i < (Int32)numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; if (getProps->GetArcPropInfo2(level, i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (getProps->GetArcProp2(level, propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } } } } } ::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES, 0x03020900), MB_OK); } }
void CPanel::GetOperatedIndicesSmart(CRecordVector<UInt32> &indices) const { GetOperatedItemIndices(indices); if (indices.IsEmpty() || (indices.Size() == 1 && indices[0] == (UInt32)(Int32)-1)) GetAllItemIndices(indices); }
void CInArchive::ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, CRecordVector<CNum> &numUnpackStreamsInFolders, CRecordVector<UInt64> &unpackSizes, CBoolVector &digestsDefined, CRecordVector<UInt32> &digests) { numUnpackStreamsInFolders.Clear(); numUnpackStreamsInFolders.Reserve(folders.Size()); UInt64 type; for (;;) { type = ReadID(); if (type == NID::kNumUnpackStream) { for (int i = 0; i < folders.Size(); i++) numUnpackStreamsInFolders.Add(ReadNum()); continue; } if (type == NID::kCRC || type == NID::kSize) break; if (type == NID::kEnd) break; SkipData(); } if (numUnpackStreamsInFolders.IsEmpty()) for (int i = 0; i < folders.Size(); i++) numUnpackStreamsInFolders.Add(1); int i; for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) { // v3.13 incorrectly worked with empty folders // v4.07: we check that folder is empty CNum numSubstreams = numUnpackStreamsInFolders[i]; if (numSubstreams == 0) continue; UInt64 sum = 0; for (CNum j = 1; j < numSubstreams; j++) if (type == NID::kSize) { UInt64 size = ReadNumber(); unpackSizes.Add(size); sum += size; } unpackSizes.Add(folders[i].GetUnpackSize() - sum); } if (type == NID::kSize) type = ReadID(); int numDigests = 0; int numDigestsTotal = 0; for (i = 0; i < folders.Size(); i++) { CNum numSubstreams = numUnpackStreamsInFolders[i]; if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) numDigests += numSubstreams; numDigestsTotal += numSubstreams; } for (;;) { if (type == NID::kCRC) { CBoolVector digestsDefined2; CRecordVector<UInt32> digests2; ReadHashDigests(numDigests, digestsDefined2, digests2); int digestIndex = 0; for (i = 0; i < folders.Size(); i++) { CNum numSubstreams = numUnpackStreamsInFolders[i]; const CFolder &folder = folders[i]; if (numSubstreams == 1 && folder.UnpackCRCDefined) { digestsDefined.Add(true); digests.Add(folder.UnpackCRC); } else for (CNum j = 0; j < numSubstreams; j++, digestIndex++) { digestsDefined.Add(digestsDefined2[digestIndex]); digests.Add(digests2[digestIndex]); } } } else if (type == NID::kEnd) { if (digestsDefined.IsEmpty()) { BoolVector_Fill_False(digestsDefined, numDigestsTotal); digests.Clear(); for (int i = 0; i < numDigestsTotal; i++) digests.Add(0); } return; } else SkipData(); type = ReadID(); } }
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; }
void CContentsView::OnCopy(bool move, bool copyToSame) { CContentsView &srcPanel = *this; CContentsView &destPanel = *this; CDisableTimerProcessing disableTimerProcessing1(destPanel); CDisableTimerProcessing disableTimerProcessing2(srcPanel); if (move) { if (!srcPanel.CheckBeforeUpdate(IDS_MOVE)) return; } else if (!srcPanel.DoesItSupportOperations()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } CRecordVector<UInt32> indices; UString destPath; bool useDestPanel = false; { if (copyToSame) { int focusedItem = srcPanel.GetFocusedItem(); if (focusedItem < 0) return; int realIndex = srcPanel.GetRealItemIndex(focusedItem); if (realIndex == kParentIndex) return; indices.Add(realIndex); destPath = srcPanel.GetItemName(realIndex); } else { srcPanel.GetOperatedIndicesSmart(indices); if (indices.Size() == 0) return; destPath = destPanel.GetFsPath(); ReducePathToRealFileSystemPath(destPath); } } UStringVector copyFolders; // ReadCopyHistory(copyFolders); { CCopyDialog copyDialog; copyDialog.Strings = copyFolders; copyDialog.Value = destPath; LangString(move ? IDS_MOVE : IDS_COPY, copyDialog.Title); LangString(move ? IDS_MOVE_TO : IDS_COPY_TO, copyDialog.Static); copyDialog.Info = srcPanel.GetItemsInfoString(indices); if (copyDialog.DoModal() != IDOK) return; destPath = copyDialog.Value; } { if (destPath.IsEmpty()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } UString correctName; if (!srcPanel.CorrectFsPath(destPath, correctName)) { srcPanel.MessageBoxError(E_INVALIDARG); return; } if (IsAbsolutePath(destPath)) destPath.Empty(); else destPath = srcPanel.GetFsPath(); destPath += correctName; #if defined(_WIN32) && !defined(UNDER_CE) if (destPath.Len() > 0 && destPath[0] == '\\') if (destPath.Len() == 1 || destPath[1] != '\\') { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } #endif if (CompareFileNames(destPath, destPanel.GetFsPath()) == 0) { srcPanel.MessageBoxMyError(L"Can not copy files onto itself"); return; } bool destIsFsPath = false; if (IsAltPathPrefix(us2fs(destPath))) { // we allow alt streams dest only to alt stream folder in second panel srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; /* FString basePath = us2fs(destPath); basePath.DeleteBack(); if (!DoesFileOrDirExist(basePath)) { srcPanel.MessageBoxError2Lines(basePath, ERROR_FILE_NOT_FOUND); // GetLastError() return; } destIsFsPath = true; */ } else { if (indices.Size() == 1 && !destPath.IsEmpty() && destPath.Back() != WCHAR_PATH_SEPARATOR) { int pos = destPath.ReverseFind_PathSepar(); if (pos < 0) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } { /* #ifdef _WIN32 UString name = destPath.Ptr(pos + 1); if (name.Find(L':') >= 0) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } #endif */ UString prefix = destPath.Left(pos + 1); if (!CreateComplexDir(us2fs(prefix))) { srcPanel.MessageBoxError2Lines(prefix, GetLastError()); return; } } // bool isFolder = srcPanael.IsItem_Folder(indices[0]); } else { NName::NormalizeDirPathPrefix(destPath); if (!CreateComplexDir(us2fs(destPath))) { srcPanel.MessageBoxError2Lines(destPath, GetLastError()); return; } } destIsFsPath = true; } if (!destIsFsPath) useDestPanel = true; // AddUniqueStringToHeadOfList(copyFolders, destPath); while (copyFolders.Size() > 20) copyFolders.DeleteBack(); // SaveCopyHistory(copyFolders); } bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder(); bool useTemp = useSrcPanel && useDestPanel; if (useTemp) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } CTempDir tempDirectory; FString tempDirPrefix; if (useTemp) { tempDirectory.Create(kTempDirPrefix); tempDirPrefix = tempDirectory.GetPath(); NFile::NName::NormalizeDirPathPrefix(tempDirPrefix); } CSelectedState srcSelState; CSelectedState destSelState; srcPanel.SaveSelectedState(srcSelState); destPanel.SaveSelectedState(destSelState); CDisableNotify disableNotify1(destPanel); CDisableNotify disableNotify2(srcPanel); HRESULT result = S_OK; if (useSrcPanel) { CCopyToOptions options; options.folder = useTemp ? fs2us(tempDirPrefix) : destPath; options.moveMode = move; options.includeAltStreams = true; options.replaceAltStreamChars = false; options.showErrorMessages = true; result = srcPanel.CopyTo(options, indices, NULL); } if (result == S_OK && useDestPanel) { UStringVector filePaths; UString folderPrefix; if (useTemp) folderPrefix = fs2us(tempDirPrefix); else folderPrefix = srcPanel.GetFsPath(); filePaths.ClearAndReserve(indices.Size()); FOR_VECTOR(i, indices) filePaths.AddInReserved(srcPanel.GetItemRelPath2(indices[i])); result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, 0); } if (result != S_OK) { // disableNotify1.Restore(); // disableNotify2.Restore(); // For Password: // srcPanel.SetFocusToList(); // srcPanel.InvalidateList(NULL, true); if (result != E_ABORT) srcPanel.MessageBoxError(result, L"Error"); // return; } RefreshTitle(); if (copyToSame || move) { srcPanel.RefreshListCtrl(srcSelState); } if (!copyToSame) { destPanel.RefreshListCtrl(destSelState); srcPanel.KillSelection(); } disableNotify1.Restore(); disableNotify2.Restore(); srcPanel.SetFocus(); }
HRESULT CAgent::RenameItem( const wchar_t *newArchiveName, const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName, IFolderArchiveUpdateCallback *updateCallback100) { if (!CanUpdate()) return E_NOTIMPL; if (numItems != 1) return E_INVALIDARG; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); CUIntVector realIndices; _agentFolder->GetRealIndices(indices, numItems, realIndices); UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]); UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]); UString newItemPath = fullPrefix + newItemName; CRecordVector<CUpdatePair2> updatePairs; UStringVector newNames; int curIndex = 0; UInt32 numItemsInArchive; RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); for (UInt32 i = 0; i < numItemsInArchive; i++) { if (curIndex < realIndices.Size()) if (realIndices[curIndex] == i) { CUpdatePair2 up2; up2.NewData = false; up2.NewProps = true; RINOK(IsArchiveItemAnti(GetArchive(), i, up2.IsAnti)); up2.ArcIndex = i; UString oldFullPath; RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath)); if (oldItemPath.CompareNoCase(oldFullPath.Left(oldItemPath.Length())) != 0) return E_INVALIDARG; up2.NewNameIndex = newNames.Add(newItemPath + oldFullPath.Mid(oldItemPath.Length())); updatePairs.Add(up2); curIndex++; continue; } CUpdatePair2 up2; up2.NewData = up2.NewProps = false; up2.IsAnti = false; up2.ArcIndex = i; updatePairs.Add(up2); } updateCallbackSpec->Callback = &updateCallbackAgent; updateCallbackSpec->UpdatePairs = &updatePairs; updateCallbackSpec->NewNames = &newNames; updateCallbackSpec->Archive = GetArchive(); return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); }
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; }
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; }
HRESULT CInArchive::ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS CArchiveDatabaseEx &db #ifndef _NO_CRYPTO , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif ) { UInt64 type = ReadID(); if (type == NID::kArchiveProperties) { ReadArchiveProperties(db.ArchiveInfo); type = ReadID(); } CObjectVector<CByteBuffer> dataVector; if (type == NID::kAdditionalStreamsInfo) { HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS db.ArchiveInfo.StartPositionAfterHeader, db.ArchiveInfo.DataStartPosition2, dataVector #ifndef _NO_CRYPTO , getTextPassword, passwordIsDefined #endif ); RINOK(result); db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader; type = ReadID(); } CRecordVector<UInt64> unpackSizes; CBoolVector digestsDefined; CRecordVector<UInt32> digests; if (type == NID::kMainStreamsInfo) { ReadStreamsInfo(&dataVector, db.ArchiveInfo.DataStartPosition, db.PackSizes, db.PackCRCsDefined, db.PackCRCs, db.Folders, db.NumUnpackStreamsVector, unpackSizes, digestsDefined, digests); db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader; type = ReadID(); } else { for (int i = 0; i < db.Folders.Size(); i++) { db.NumUnpackStreamsVector.Add(1); CFolder &folder = db.Folders[i]; unpackSizes.Add(folder.GetUnpackSize()); digestsDefined.Add(folder.UnpackCRCDefined); digests.Add(folder.UnpackCRC); } } db.Files.Clear(); if (type == NID::kEnd) return S_OK; if (type != NID::kFilesInfo) ThrowIncorrect(); CNum numFiles = ReadNum(); db.Files.Reserve(numFiles); CNum i; for (i = 0; i < numFiles; i++) db.Files.Add(CFileItem()); db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); if (!db.PackSizes.IsEmpty()) db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); if (numFiles > 0 && !digests.IsEmpty()) db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); CBoolVector emptyStreamVector; BoolVector_Fill_False(emptyStreamVector, (int)numFiles); CBoolVector emptyFileVector; CBoolVector antiFileVector; CNum numEmptyStreams = 0; for (;;) { UInt64 type = ReadID(); if (type == NID::kEnd) break; UInt64 size = ReadNumber(); size_t ppp = _inByteBack->_pos; bool addPropIdToList = true; bool isKnownType = true; if (type > ((UInt32)1 << 30)) isKnownType = false; else switch((UInt32)type) { case NID::kName: { CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); for (int i = 0; i < db.Files.Size(); i++) _inByteBack->ReadString(db.Files[i].Name); break; } case NID::kWinAttributes: { CBoolVector boolVector; ReadBoolVector2(db.Files.Size(), boolVector); CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); for (i = 0; i < numFiles; i++) { CFileItem &file = db.Files[i]; file.AttribDefined = boolVector[i]; if (file.AttribDefined) file.Attrib = ReadUInt32(); } break; } case NID::kEmptyStream: { ReadBoolVector(numFiles, emptyStreamVector); for (i = 0; i < (CNum)emptyStreamVector.Size(); i++) if (emptyStreamVector[i]) numEmptyStreams++; BoolVector_Fill_False(emptyFileVector, numEmptyStreams); BoolVector_Fill_False(antiFileVector, numEmptyStreams); break; } case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break; case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break; case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break; case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break; case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break; case NID::kDummy: { for (UInt64 j = 0; j < size; j++) if (ReadByte() != 0) ThrowIncorrect(); addPropIdToList = false; break; } default: addPropIdToList = isKnownType = false; } if (isKnownType) { if(addPropIdToList) db.ArchiveInfo.FileInfoPopIDs.Add(type); } else SkipData(size); bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 || db.ArchiveInfo.Version.Minor > 2); if (checkRecordsSize && _inByteBack->_pos - ppp != size) ThrowIncorrect(); } CNum emptyFileIndex = 0; CNum sizeIndex = 0; CNum numAntiItems = 0; for (i = 0; i < numEmptyStreams; i++) if (antiFileVector[i]) numAntiItems++; for (i = 0; i < numFiles; i++) { CFileItem &file = db.Files[i]; bool isAnti; file.HasStream = !emptyStreamVector[i]; if (file.HasStream) { file.IsDir = false; isAnti = false; file.Size = unpackSizes[sizeIndex]; file.Crc = digests[sizeIndex]; file.CrcDefined = digestsDefined[sizeIndex]; sizeIndex++; } else { file.IsDir = !emptyFileVector[emptyFileIndex]; isAnti = antiFileVector[emptyFileIndex]; emptyFileIndex++; file.Size = 0; file.CrcDefined = false; } if (numAntiItems != 0) db.IsAnti.Add(isAnti); } return S_OK; }
static HRESULT Update2( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, const CArchiveDatabaseEx *database, const CObjectVector<CUpdateItem> &updateItems, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options) { UInt64 numSolidFiles = options.NumSolidFiles; if (numSolidFiles == 0) numSolidFiles = 1; /* CMyComPtr<IOutStream> outStream; RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); if (!outStream) return E_NOTIMPL; */ UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0; if (startBlockSize > 0 && !options.RemoveSfxBlock) { RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); } CRecordVector<int> fileIndexToUpdateIndexMap; if (database != 0) { fileIndexToUpdateIndexMap.Reserve(database->Files.Size()); for (int i = 0; i < database->Files.Size(); i++) fileIndexToUpdateIndexMap.Add(-1); } int i; for(i = 0; i < updateItems.Size(); i++) { int index = updateItems[i].IndexInArchive; if (index != -1) fileIndexToUpdateIndexMap[index] = i; } CRecordVector<int> folderRefs; if (database != 0) { for(i = 0; i < database->Folders.Size(); i++) { CNum indexInFolder = 0; CNum numCopyItems = 0; CNum numUnPackStreams = database->NumUnPackStreamsVector[i]; for (CNum fileIndex = database->FolderStartFileIndex[i]; indexInFolder < numUnPackStreams; fileIndex++) { if (database->Files[fileIndex].HasStream) { indexInFolder++; int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; if (updateIndex >= 0) if (!updateItems[updateIndex].NewData) numCopyItems++; } } if (numCopyItems != numUnPackStreams && numCopyItems != 0) return E_NOTIMPL; // It needs repacking !!! if (numCopyItems > 0) folderRefs.Add(i); } folderRefs.Sort(CompareFolderRefs, (void *)database); } CArchiveDatabase newDatabase; //////////////////////////// COutArchive archive; RINOK(archive.Create(seqOutStream, false)); RINOK(archive.SkeepPrefixArchiveHeader()); UInt64 complexity = 0; for(i = 0; i < folderRefs.Size(); i++) complexity += database->GetFolderFullPackSize(folderRefs[i]); UInt64 inSizeForReduce = 0; for(i = 0; i < updateItems.Size(); i++) { const CUpdateItem &updateItem = updateItems[i]; if (updateItem.NewData) { complexity += updateItem.Size; if (numSolidFiles == 1) { if (updateItem.Size > inSizeForReduce) inSizeForReduce = updateItem.Size; } else inSizeForReduce += updateItem.Size; } } RINOK(updateCallback->SetTotal(complexity)); complexity = 0; RINOK(updateCallback->SetCompleted(&complexity)); CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(updateCallback, true); ///////////////////////////////////////// // Write Copy Items for(i = 0; i < folderRefs.Size(); i++) { int folderIndex = folderRefs[i]; lps->ProgressOffset = complexity; UInt64 packSize = database->GetFolderFullPackSize(folderIndex); RINOK(WriteRange(inStream, archive.SeqStream, database->GetFolderStreamPos(folderIndex, 0), packSize, progress)); complexity += packSize; const CFolder &folder = database->Folders[folderIndex]; CNum startIndex = database->FolderStartPackStreamIndex[folderIndex]; for (int j = 0; j < folder.PackStreams.Size(); j++) { newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]); // newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]); // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]); } newDatabase.Folders.Add(folder); CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex]; newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); CNum indexInFolder = 0; for (CNum fi = database->FolderStartFileIndex[folderIndex]; indexInFolder < numUnPackStreams; fi++) { CFileItem file = database->Files[fi]; if (file.HasStream) { indexInFolder++; int updateIndex = fileIndexToUpdateIndexMap[fi]; if (updateIndex >= 0) { const CUpdateItem &updateItem = updateItems[updateIndex]; if (updateItem.NewProperties) { CFileItem file2; FromUpdateItemToFileItem(updateItem, file2); file2.UnPackSize = file.UnPackSize; file2.FileCRC = file.FileCRC; file2.IsFileCRCDefined = file.IsFileCRCDefined; file2.HasStream = file.HasStream; file = file2; } } newDatabase.Files.Add(file); } } } ///////////////////////////////////////// // Compress New Files CObjectVector<CSolidGroup> groups; SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter, updateItems, groups); const UInt32 kMinReduceSize = (1 << 16); if (inSizeForReduce < kMinReduceSize) inSizeForReduce = kMinReduceSize; for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++) { const CSolidGroup &group = groups[groupIndex]; int numFiles = group.Indices.Size(); if (numFiles == 0) continue; CRecordVector<CRefItem> refItems; refItems.Reserve(numFiles); bool sortByType = (numSolidFiles > 1); for (i = 0; i < numFiles; i++) refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType)); refItems.Sort(CompareUpdateItems, (void *)&sortByType); CRecordVector<UInt32> indices; indices.Reserve(numFiles); for (i = 0; i < numFiles; i++) { UInt32 index = refItems[i].Index; indices.Add(index); /* const CUpdateItem &updateItem = updateItems[index]; CFileItem file; if (updateItem.NewProperties) FromUpdateItemToFileItem(updateItem, file); else file = database.Files[updateItem.IndexInArchive]; if (file.IsAnti || file.IsDirectory) return E_FAIL; newDatabase.Files.Add(file); */ } CEncoder encoder(group.Method); for (i = 0; i < numFiles;) { UInt64 totalSize = 0; int numSubFiles; UString prevExtension; for (numSubFiles = 0; i + numSubFiles < numFiles && numSubFiles < numSolidFiles; numSubFiles++) { const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]]; totalSize += updateItem.Size; if (totalSize > options.NumSolidBytes) break; if (options.SolidExtension) { UString ext = updateItem.GetExtension(); if (numSubFiles == 0) prevExtension = ext; else if (ext.CompareNoCase(prevExtension) != 0) break; } } if (numSubFiles < 1) numSubFiles = 1; CFolderInStream *inStreamSpec = new CFolderInStream; CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec); inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); CFolder folderItem; int startPackIndex = newDatabase.PackSizes.Size(); RINOK(encoder.Encode( EXTERNAL_CODECS_LOC_VARS solidInStream, NULL, &inSizeForReduce, folderItem, archive.SeqStream, newDatabase.PackSizes, progress)); for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) lps->OutSize += newDatabase.PackSizes[startPackIndex]; lps->InSize += folderItem.GetUnPackSize(); // for() // newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCs.Add(0); newDatabase.Folders.Add(folderItem); CNum numUnPackStreams = 0; for (int subIndex = 0; subIndex < numSubFiles; subIndex++) { const CUpdateItem &updateItem = updateItems[indices[i + subIndex]]; CFileItem file; if (updateItem.NewProperties) FromUpdateItemToFileItem(updateItem, file); else file = database->Files[updateItem.IndexInArchive]; if (file.IsAnti || file.IsDirectory) return E_FAIL; /* CFileItem &file = newDatabase.Files[ startFileIndexInDatabase + i + subIndex]; */ if (!inStreamSpec->Processed[subIndex]) { continue; // file.Name += L".locked"; } file.FileCRC = inStreamSpec->CRCs[subIndex]; file.UnPackSize = inStreamSpec->Sizes[subIndex]; if (file.UnPackSize != 0) { file.IsFileCRCDefined = true; file.HasStream = true; numUnPackStreams++; } else { file.IsFileCRCDefined = false; file.HasStream = false; } newDatabase.Files.Add(file); } // numUnPackStreams = 0 is very bad case for locked files // v3.13 doesn't understand it. newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); i += numSubFiles; } } { ///////////////////////////////////////// // Write Empty Files & Folders CRecordVector<int> emptyRefs; for(i = 0; i < updateItems.Size(); i++) { const CUpdateItem &updateItem = updateItems[i]; if (updateItem.NewData) { if (updateItem.HasStream()) continue; } else if (updateItem.IndexInArchive != -1) if (database->Files[updateItem.IndexInArchive].HasStream) continue; emptyRefs.Add(i); } emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); for(i = 0; i < emptyRefs.Size(); i++) { const CUpdateItem &updateItem = updateItems[emptyRefs[i]]; CFileItem file; if (updateItem.NewProperties) FromUpdateItemToFileItem(updateItem, file); else file = database->Files[updateItem.IndexInArchive]; newDatabase.Files.Add(file); } } /* if (newDatabase.Files.Size() != updateItems.Size()) return E_FAIL; */ return archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS newDatabase, options.HeaderMethod, options.HeaderOptions); }
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; }
void CPanel::Properties() { CMyComPtr<IGetFolderArcProps> getFolderArcProps; _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); if (!getFolderArcProps) { InvokeSystemCommand("properties"); return; } { UString message; CRecordVector<UInt32> operatedIndices; GetOperatedItemIndices(operatedIndices); if (operatedIndices.Size() == 1) { UInt32 index = operatedIndices[0]; // message += L"Item:\n"; UInt32 numProps; if (_folder->GetNumberOfProperties(&numProps) == S_OK) { for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE varType; if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) continue; NCOM::CPropVariant prop; if (_folder->GetProperty(index, propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } if (_folderRawProps) { _folderRawProps->GetNumRawProps(&numProps); for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; if (_folderRawProps->GetRawPropInfo(i, &name, &propID) != S_OK) continue; const void *data; UInt32 dataSize; UInt32 propType; if (_folderRawProps->GetRawProp(index, propID, &data, &dataSize, &propType) != S_OK) continue; if (dataSize != 0) { AString s; if (propID == kpidNtSecure) ConvertNtSecureToString((const Byte *)data, dataSize, s); else { const UInt32 kMaxDataSize = 64; if (dataSize > kMaxDataSize) { char temp[64]; s += "data:"; ConvertUInt32ToString(dataSize, temp); s += temp; } else { for (UInt32 k = 0; k < dataSize; k++) { Byte b = ((const Byte *)data)[k]; s += GetHex((Byte)((b >> 4) & 0xF)); s += GetHex((Byte)(b & 0xF)); } } } message += GetNameOfProperty(propID, name); message.AddAscii(kPropValueSeparator); message.AddAscii(s); message.Add_LF(); } } } message.AddAscii(kSeparator); }