void CApp::CalculateCrc() { int srcPanelIndex = GetFocusedPanelIndex(); CPanel &srcPanel = Panels[srcPanelIndex]; if (!srcPanel.IsFsOrDrivesFolder()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); return; } CRecordVector<UInt32> indices; srcPanel.GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; { CThreadCrc t; for (int i = 0; i < indices.Size(); i++) t.Enumerator.FileNames.Add(us2fs(srcPanel.GetItemRelPath(indices[i]))); t.Enumerator.BasePrefix = us2fs(srcPanel.GetFsPath()); t.Enumerator.FlatMode = GetFlatMode(); t.ProgressDialog.ShowCompressionInfo = false; UString title = LangString(IDS_CHECKSUM_CALCULATING, 0x03020710); t.ProgressDialog.MainWindow = _window; t.ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000); t.ProgressDialog.MainAddTitle = title + UString(L' '); if (t.Create(title, _window) != S_OK) return; } RefreshTitleAlways(); }
void CPanel::GetOperatedItemIndices(CRecordVector<UInt32> &indices) const { GetSelectedItemsIndices(indices); if (!indices.IsEmpty()) return; if (_listView.GetSelectedCount() == 0) return; int focusedItem = _listView.GetFocusedItem(); if (focusedItem >= 0) { if (_listView.IsItemSelected(focusedItem)) { int realIndex = GetRealItemIndex(focusedItem); if (realIndex != kParentIndex) indices.Add(realIndex); } } }
void CApp::Link() { int srcPanelIndex = GetFocusedPanelIndex(); CPanel &srcPanel = Panels[srcPanelIndex]; if (!srcPanel.IsFSFolder()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); return; } CRecordVector<UInt32> indices; srcPanel.GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; if (indices.Size() != 1) { srcPanel.MessageBoxErrorLang(IDS_SELECT_ONE_FILE); return; } int index = indices[0]; const UString itemName = srcPanel.GetItemName(index); const UString fsPrefix = srcPanel.GetFsPath(); const UString srcPath = fsPrefix + srcPanel.GetItemPrefix(index); UString path = srcPath; { int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &destPanel = Panels[destPanelIndex]; if (NumPanels > 1) if (destPanel.IsFSFolder()) path = destPanel.GetFsPath(); } CLinkDialog dlg; dlg.CurDirPrefix = fsPrefix; dlg.FilePath = srcPath + itemName; dlg.AnotherPath = path; if (dlg.Create(srcPanel.GetParent()) != IDOK) return; RefreshTitleAlways(); }
void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin)) { CDisableTimerProcessing disableTimerProcessing(*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 if (IsFSFolder() && toRecycleBin) { bool useInternalDelete = false; #ifndef _UNICODE if (!g_IsNT) { CDynamicBuffer<CHAR> buffer; FOR_VECTOR (i, indices) { const AString path = GetSystemString(GetItemFullPath(indices[i])); buffer.AddData(path, path.Len() + 1); } *buffer.GetCurPtrAndGrow(1) = 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); }
void CPanel::InvokeSystemCommand(const char *command) { NCOM::CComInitializer comInitializer; if (!IsFsOrPureDrivesFolder()) return; CRecordVector<UInt32> operatedIndices; GetOperatedItemIndices(operatedIndices); if (operatedIndices.IsEmpty()) return; CMyComPtr<IContextMenu> contextMenu; if (CreateShellContextMenu(operatedIndices, contextMenu) != S_OK) return; CMINVOKECOMMANDINFO ci; ZeroMemory(&ci, sizeof(ci)); ci.cbSize = sizeof(CMINVOKECOMMANDINFO); ci.hwnd = GetParent(); ci.lpVerb = command; contextMenu->InvokeCommand(&ci); }
void CInArchive::ReadPackInfo( UInt64 &dataOffset, CRecordVector<UInt64> &packSizes, CRecordVector<bool> &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; } SkeepData(); } if (packCRCsDefined.IsEmpty()) { packCRCsDefined.Reserve(numPackStreams); packCRCsDefined.Clear(); packCRCs.Reserve(numPackStreams); packCRCs.Clear(); for (CNum i = 0; i < numPackStreams; i++) { packCRCsDefined.Add(false); packCRCs.Add(0); } } }
void CPanel::GetOperatedIndicesSmart(CRecordVector<UInt32> &indices) const { GetOperatedItemIndices(indices); if (indices.IsEmpty() || (indices.Size() == 1 && indices[0] == (UInt32)(Int32)-1)) GetAllItemIndices(indices); }
void CApp::Combine() { int srcPanelIndex = GetFocusedPanelIndex(); CPanel &srcPanel = Panels[srcPanelIndex]; if (!srcPanel.IsFSFolder()) { srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); return; } CRecordVector<UInt32> indices; srcPanel.GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; int index = indices[0]; if (indices.Size() != 1 || srcPanel.IsItemFolder(index)) { srcPanel.MessageBox(LangString(IDS_COMBINE_SELECT_ONE_FILE, 0x03020620)); return; } const UString itemName = srcPanel.GetItemName(index); UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); UString path = srcPath; int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &destPanel = Panels[destPanelIndex]; if (NumPanels > 1) if (destPanel.IsFSFolder()) path = destPanel._currentFolderPrefix; CCopyDialog copyDialog; copyDialog.Value = path; copyDialog.Title = LangString(IDS_COMBINE, 0x03020600); copyDialog.Title += ' '; copyDialog.Title += srcPanel.GetItemRelPath(index); copyDialog.Static = LangString(IDS_COMBINE_TO, 0x03020601);; if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) return; CThreadCombine combiner; // combiner.Panel = this; { CProgressDialog progressDialog; combiner.ProgressDialog = &progressDialog; UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); UString title = LangString(IDS_COMBINING, 0x03020610); progressDialog.MainWindow = _window; progressDialog.MainTitle = progressWindowTitle; progressDialog.MainAddTitle = title + UString(L" "); path = copyDialog.Value; NFile::NName::NormalizeDirPathPrefix(path); if (!NFile::NDirectory::CreateComplexDirectory(path)) { srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path)); return; } combiner.InputDirPrefix = srcPath; combiner.FirstVolumeName = itemName; combiner.OutputDirPrefix = path; // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); NWindows::CThread thread; if (thread.Create(CThreadCombine::MyThreadFunction, &combiner) != S_OK) throw 271824; progressDialog.Create(title, _window); } RefreshTitleAlways(); if (!combiner.Error.IsEmpty()) srcPanel.MessageBoxMyError(combiner.Error); // disableTimerProcessing1.Restore(); // disableTimerProcessing2.Restore(); // srcPanel.SetFocusToList(); // srcPanel.RefreshListCtrlSaveFocused(); }
void CApp::Combine() { int srcPanelIndex = GetFocusedPanelIndex(); CPanel &srcPanel = Panels[srcPanelIndex]; if (!srcPanel.IsFSFolder()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); return; } CRecordVector<UInt32> indices; srcPanel.GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; int index = indices[0]; if (indices.Size() != 1 || srcPanel.IsItemFolder(index)) { srcPanel.MessageBoxErrorLang(IDS_COMBINE_SELECT_ONE_FILE, 0x03020620); return; } const UString itemName = srcPanel.GetItemName(index); UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); UString path = srcPath; int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &destPanel = Panels[destPanelIndex]; if (NumPanels > 1) if (destPanel.IsFSFolder()) path = destPanel._currentFolderPrefix; CVolSeqName volSeqName; if (!volSeqName.ParseName(itemName)) { srcPanel.MessageBoxErrorLang(IDS_COMBINE_CANT_DETECT_SPLIT_FILE, 0x03020621); return; } { CThreadCombine combiner; UString nextName = itemName; combiner.TotalSize = 0; for (;;) { NFile::NFind::CFileInfoW fileInfo; if (!fileInfo.Find(srcPath + nextName) || fileInfo.IsDir()) break; combiner.Names.Add(nextName); combiner.TotalSize += fileInfo.Size; nextName = volSeqName.GetNextName(); } if (combiner.Names.Size() == 1) { srcPanel.MessageBoxErrorLang(IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART, 0x03020622); return; } if (combiner.TotalSize == 0) { srcPanel.MessageBoxMyError(L"No data"); return; } UString info; AddValuePair2(IDS_FILES_COLON, 0x02000320, combiner.Names.Size(), combiner.TotalSize, info); info += L"\n"; info += srcPath; int i; for (i = 0; i < combiner.Names.Size() && i < 2; i++) AddInfoFileName(combiner.Names[i], info); if (i != combiner.Names.Size()) { if (i + 1 != combiner.Names.Size()) AddInfoFileName(L"...", info); AddInfoFileName(combiner.Names.Back(), info); } { CCopyDialog copyDialog; copyDialog.Value = path; copyDialog.Title = LangString(IDS_COMBINE, 0x03020600); copyDialog.Title += ' '; copyDialog.Title += srcPanel.GetItemRelPath(index); copyDialog.Static = LangString(IDS_COMBINE_TO, 0x03020601); copyDialog.Info = info; if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) return; path = copyDialog.Value; } NFile::NName::NormalizeDirPathPrefix(path); if (!NFile::NDirectory::CreateComplexDirectory(path)) { srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path)); return; } UString outName = volSeqName.UnchangedPart; while (!outName.IsEmpty()) { int lastIndex = outName.Length() - 1; if (outName[lastIndex] != L'.') break; outName.Delete(lastIndex); } if (outName.IsEmpty()) outName = L"file"; NFile::NFind::CFileInfoW fileInfo; UString destFilePath = path + outName; combiner.OutputPath = destFilePath; if (fileInfo.Find(destFilePath)) { srcPanel.MessageBoxMyError(MyFormatNew(IDS_FILE_EXIST, 0x03020A04, destFilePath)); return; } CProgressDialog &progressDialog = combiner.ProgressDialog; progressDialog.ShowCompressionInfo = false; UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); UString title = LangString(IDS_COMBINING, 0x03020610); progressDialog.MainWindow = _window; progressDialog.MainTitle = progressWindowTitle; progressDialog.MainAddTitle = title + UString(L" "); combiner.InputDirPrefix = srcPath; // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); if (combiner.Create(title, _window) != 0) return; } RefreshTitleAlways(); // disableTimerProcessing1.Restore(); // disableTimerProcessing2.Restore(); // srcPanel.SetFocusToList(); // srcPanel.RefreshListCtrlSaveFocused(); }
void CApp::Split() { int srcPanelIndex = GetFocusedPanelIndex(); CPanel &srcPanel = Panels[srcPanelIndex]; if (!srcPanel.IsFSFolder()) { srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); return; } CRecordVector<UInt32> indices; srcPanel.GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; if (indices.Size() != 1) { srcPanel.MessageBoxErrorLang(IDS_SELECT_ONE_FILE, 0x03020A02); return; } int index = indices[0]; if (srcPanel.IsItemFolder(index)) { srcPanel.MessageBoxErrorLang(IDS_SELECT_ONE_FILE, 0x03020A02); return; } const UString itemName = srcPanel.GetItemName(index); UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); UString path = srcPath; int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &destPanel = Panels[destPanelIndex]; if (NumPanels > 1) if (destPanel.IsFSFolder()) path = destPanel._currentFolderPrefix; CSplitDialog splitDialog; splitDialog.FilePath = srcPanel.GetItemRelPath(index); splitDialog.Path = path; if (splitDialog.Create(srcPanel.GetParent()) == IDCANCEL) return; NFile::NFind::CFileInfoW fileInfo; if (!fileInfo.Find(srcPath + itemName)) { srcPanel.MessageBoxMyError(L"Can not find file"); return; } if (fileInfo.Size <= splitDialog.VolumeSizes.Front()) { srcPanel.MessageBoxErrorLang(IDS_SPLIT_VOL_MUST_BE_SMALLER, 0x03020522); return; } const UInt64 numVolumes = GetNumberOfVolumes(fileInfo.Size, splitDialog.VolumeSizes); if (numVolumes >= 100) { wchar_t s[32]; ConvertUInt64ToString(numVolumes, s); if (::MessageBoxW(srcPanel, MyFormatNew(IDS_SPLIT_CONFIRM_MESSAGE, 0x03020521, s), LangString(IDS_SPLIT_CONFIRM_TITLE, 0x03020520), MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) return; } path = splitDialog.Path; NFile::NName::NormalizeDirPathPrefix(path); if (!NFile::NDirectory::CreateComplexDirectory(path)) { srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path)); return; } { CThreadSplit spliter; spliter.NumVolumes = numVolumes; CProgressDialog &progressDialog = spliter.ProgressDialog; UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); UString title = LangString(IDS_SPLITTING, 0x03020510); progressDialog.ShowCompressionInfo = false; progressDialog.MainWindow = _window; progressDialog.MainTitle = progressWindowTitle; progressDialog.MainAddTitle = title + UString(L" "); progressDialog.Sync.SetTitleFileName(itemName); spliter.FilePath = srcPath + itemName; spliter.VolBasePath = path + itemName; spliter.VolumeSizes = splitDialog.VolumeSizes; // if (splitDialog.VolumeSizes.Size() == 0) return; // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); if (spliter.Create(title, _window) != 0) return; } RefreshTitleAlways(); // disableTimerProcessing1.Restore(); // disableTimerProcessing2.Restore(); // srcPanel.SetFocusToList(); // srcPanel.RefreshListCtrlSaveFocused(); }
void CApp::CalculateCrc(const UString &methodName) { int srcPanelIndex = GetFocusedPanelIndex(); CPanel &srcPanel = Panels[srcPanelIndex]; CRecordVector<UInt32> indices; srcPanel.GetOperatedIndicesSmart(indices); if (indices.IsEmpty()) return; if (!srcPanel.IsFsOrDrivesFolder()) { CCopyToOptions options; options.streamMode = true; options.showErrorMessages = true; options.hashMethods.Add(methodName); UStringVector messages; HRESULT res = srcPanel.CopyTo(options, indices, &messages); if (res != S_OK) { if (res != E_ABORT) srcPanel.MessageBoxError(res); } return; } CCodecs *codecs = new CCodecs; #ifdef EXTERNAL_CODECS CExternalCodecs __externalCodecs; __externalCodecs.GetCodecs = codecs; __externalCodecs.GetHashers = codecs; #else CMyComPtr<IUnknown> compressCodecsInfo = codecs; #endif ThrowException_if_Error(codecs->Load()); #ifdef EXTERNAL_CODECS ThrowException_if_Error(__externalCodecs.LoadCodecs()); #endif { CThreadCrc t; { UStringVector methods; methods.Add(methodName); t.Hash.SetMethods(EXTERNAL_CODECS_VARS methods); } FOR_VECTOR (i, indices) t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i]))); t.Enumerator.BasePrefix = us2fs(srcPanel.GetFsPath()); t.Enumerator.EnterToDirs = !GetFlatMode(); t.ProgressDialog.ShowCompressionInfo = false; UString title = LangString(IDS_CHECKSUM_CALCULATING); t.ProgressDialog.MainWindow = _window; t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); t.ProgressDialog.MainAddTitle = title + UString(L' '); if (t.Create(title, _window) != S_OK) return; } RefreshTitleAlways(); }
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); }
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; }
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(); } }
void CApp::Split() { int srcPanelIndex = GetFocusedPanelIndex(); CPanel &srcPanel = Panels[srcPanelIndex]; if (!srcPanel.Is_IO_FS_Folder()) { srcPanel.MessageBox_Error_UnsupportOperation(); return; } CRecordVector<UInt32> indices; srcPanel.GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; if (indices.Size() != 1) { srcPanel.MessageBox_Error_LangID(IDS_SELECT_ONE_FILE); return; } int index = indices[0]; if (srcPanel.IsItem_Folder(index)) { srcPanel.MessageBox_Error_LangID(IDS_SELECT_ONE_FILE); return; } const UString itemName = srcPanel.GetItemName(index); UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index); UString path = srcPath; unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &destPanel = Panels[destPanelIndex]; if (NumPanels > 1) if (destPanel.IsFSFolder()) path = destPanel.GetFsPath(); CSplitDialog splitDialog; splitDialog.FilePath = srcPanel.GetItemRelPath(index); splitDialog.Path = path; if (splitDialog.Create(srcPanel.GetParent()) != IDOK) return; NFind::CFileInfo fileInfo; if (!fileInfo.Find(us2fs(srcPath + itemName))) { srcPanel.MessageBox_Error(L"Can not find file"); return; } if (fileInfo.Size <= splitDialog.VolumeSizes.Front()) { srcPanel.MessageBox_Error_LangID(IDS_SPLIT_VOL_MUST_BE_SMALLER); return; } const UInt64 numVolumes = GetNumberOfVolumes(fileInfo.Size, splitDialog.VolumeSizes); if (numVolumes >= 100) { wchar_t s[32]; ConvertUInt64ToString(numVolumes, s); if (::MessageBoxW(srcPanel, MyFormatNew(IDS_SPLIT_CONFIRM_MESSAGE, s), LangString(IDS_SPLIT_CONFIRM_TITLE), MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) return; } path = splitDialog.Path; NName::NormalizeDirPathPrefix(path); if (!CreateComplexDir(us2fs(path))) { DWORD lastError = ::GetLastError(); srcPanel.MessageBox_Error_2Lines_Message_HRESULT(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, path), lastError); return; } { CThreadSplit spliter; spliter.NumVolumes = numVolumes; CProgressDialog &progressDialog = spliter; UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); UString title = LangString(IDS_SPLITTING); progressDialog.ShowCompressionInfo = false; progressDialog.MainWindow = _window; progressDialog.MainTitle = progressWindowTitle; progressDialog.MainAddTitle = title; progressDialog.MainAddTitle.Add_Space(); progressDialog.Sync.Set_TitleFileName(itemName); spliter.FilePath = us2fs(srcPath + itemName); spliter.VolBasePath = us2fs(path + srcPanel.GetItemName_for_Copy(index)); spliter.VolumeSizes = splitDialog.VolumeSizes; // if (splitDialog.VolumeSizes.Size() == 0) return; // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); if (spliter.Create(title, _window) != 0) return; } RefreshTitleAlways(); // disableNotify.Restore(); // disableNotify.Restore(); // srcPanel.SetFocusToList(); // srcPanel.RefreshListCtrlSaveFocused(); }
HRESULT CContentsView::CalculateCrc2(const UString &methodName) { CContentsView &srcPanel = *this; CRecordVector<UInt32> indices; srcPanel.GetOperatedIndicesSmart(indices); if (indices.IsEmpty()) return S_OK; if (!srcPanel.Is_IO_FS_Folder()) { CCopyToOptions options; options.streamMode = true; options.showErrorMessages = true; options.hashMethods.Add(methodName); UStringVector messages; return srcPanel.CopyTo(options, indices, &messages); } #ifdef EXTERNAL_CODECS LoadGlobalCodecs(); #endif { CThreadCrc t; { UStringVector methods; methods.Add(methodName); RINOK(t.Hash.SetMethods(EXTERNAL_CODECS_VARS_G methods)); } FOR_VECTOR (i, indices) t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i]))); UString basePrefix = srcPanel.GetFsPath(); UString basePrefix2 = basePrefix; if (basePrefix2.Back() == ':') { int pos = basePrefix2.ReverseFind_PathSepar(); if (pos >= 0) basePrefix2.DeleteFrom(pos + 1); } t.Enumerator.BasePrefix = us2fs(basePrefix); t.Enumerator.BasePrefix_for_Open = us2fs(basePrefix2); t.Enumerator.EnterToDirs = !GetFlatMode(); t.ProgressDialog.ShowCompressionInfo = false; UString title = LangString(IDS_CHECKSUM_CALCULATING); t.ProgressDialog.MainWindow = *GetTopLevelParent(); t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); t.ProgressDialog.MainAddTitle = title; t.ProgressDialog.MainAddTitle.Add_Space(); RINOK(t.Create(title, *GetTopLevelParent())); } RefreshTitle(); return S_OK; }
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, Int32 testModeSpec, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = m_Database.NewFormat ? 1: (m_Database.LowLevel ? m_Database.Items.Size(): m_Database.Indices.Size()); if (numItems == 0) return S_OK; bool testMode = (testModeSpec != 0); UInt64 currentTotalSize = 0; NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; UInt32 i; CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(extractCallback, false); CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream(streamSpec); streamSpec->SetStream(m_Stream); if (m_Database.LowLevel) { UInt64 currentItemSize = 0; UInt64 totalSize = 0; if (m_Database.NewFormat) totalSize = m_Database.NewFormatString.Length(); else for (i = 0; i < numItems; i++) totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { currentItemSize = 0; lps->InSize = currentTotalSize; // Change it lps->OutSize = currentTotalSize; RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode= testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); if (m_Database.NewFormat) { if (index != 0) return E_FAIL; if (!testMode && !realOutStream) continue; if (!testMode) { UInt32 size = m_Database.NewFormatString.Length(); RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size)); } RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } const CItem &item = m_Database.Items[index]; currentItemSize = item.Size; if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); if (item.Section != 0) { RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } if (testMode) { RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); streamSpec->Init(item.Size); RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? NExtract::NOperationResult::kOK: NExtract::NOperationResult::kDataError)); } return S_OK; } UInt64 lastFolderIndex = ((UInt64)0 - 1); for (i = 0; i < numItems; i++) { UInt32 index = allFilesMode ? i : indices[i]; int entryIndex = m_Database.Indices[index]; const CItem &item = m_Database.Items[entryIndex]; UInt64 sectionIndex = item.Section; if (item.IsDir() || item.Size == 0) continue; if (sectionIndex == 0) { currentTotalSize += item.Size; continue; } const CSectionInfo §ion = m_Database.Sections[(int)item.Section]; if (section.IsLzx()) { const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; UInt64 folderIndex = m_Database.GetFolder(index); if (lastFolderIndex == folderIndex) folderIndex++; lastFolderIndex = m_Database.GetLastFolder(index); for (; folderIndex <= lastFolderIndex; folderIndex++) currentTotalSize += lzxInfo.GetFolderSize(); } } RINOK(extractCallback->SetTotal(currentTotalSize)); NCompress::NLzx::CDecoder *lzxDecoderSpec = 0; CMyComPtr<ICompressCoder> lzxDecoder; CChmFolderOutStream *chmFolderOutStream = 0; CMyComPtr<ISequentialOutStream> outStream; currentTotalSize = 0; CRecordVector<bool> extractStatuses; for (i = 0; i < numItems;) { RINOK(extractCallback->SetCompleted(¤tTotalSize)); UInt32 index = allFilesMode ? i : indices[i]; i++; int entryIndex = m_Database.Indices[index]; const CItem &item = m_Database.Items[entryIndex]; UInt64 sectionIndex = item.Section; Int32 askMode= testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; if (item.IsDir()) { CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } lps->InSize = currentTotalSize; // Change it lps->OutSize = currentTotalSize; if (item.Size == 0 || sectionIndex == 0) { CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); Int32 opRes = NExtract::NOperationResult::kOK; if (!testMode && item.Size != 0) { RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); streamSpec->Init(item.Size); RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); if (copyCoderSpec->TotalSize != item.Size) opRes = NExtract::NOperationResult::kDataError; } realOutStream.Release(); RINOK(extractCallback->SetOperationResult(opRes)); currentTotalSize += item.Size; continue; } const CSectionInfo §ion = m_Database.Sections[(int)sectionIndex]; if (!section.IsLzx()) { CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; if (chmFolderOutStream == 0) { chmFolderOutStream = new CChmFolderOutStream; outStream = chmFolderOutStream; } chmFolderOutStream->Init(&m_Database, extractCallback, testMode); if (lzxDecoderSpec == NULL) { lzxDecoderSpec = new NCompress::NLzx::CDecoder; lzxDecoder = lzxDecoderSpec; } UInt64 folderIndex = m_Database.GetFolder(index); UInt64 compressedPos = m_Database.ContentOffset + section.Offset; UInt32 numDictBits = lzxInfo.GetNumDictBits(); RINOK(lzxDecoderSpec->SetParams(numDictBits)); const CItem *lastItem = &item; extractStatuses.Clear(); extractStatuses.Add(true); for (;; folderIndex++) { RINOK(extractCallback->SetCompleted(¤tTotalSize)); UInt64 startPos = lzxInfo.GetFolderPos(folderIndex); UInt64 finishPos = lastItem->Offset + lastItem->Size; UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos); lastFolderIndex = m_Database.GetLastFolder(index); UInt64 folderSize = lzxInfo.GetFolderSize(); UInt64 unPackSize = folderSize; if (extractStatuses.IsEmpty()) chmFolderOutStream->m_StartIndex = index + 1; else chmFolderOutStream->m_StartIndex = index; if (limitFolderIndex == folderIndex) { for (; i < numItems; i++) { UInt32 nextIndex = allFilesMode ? i : indices[i]; int entryIndex = m_Database.Indices[nextIndex]; const CItem &nextItem = m_Database.Items[entryIndex]; if (nextItem.Section != sectionIndex) break; UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); if (nextFolderIndex != folderIndex) break; for (index++; index < nextIndex; index++) extractStatuses.Add(false); extractStatuses.Add(true); index = nextIndex; lastItem = &nextItem; if (nextItem.Size != 0) finishPos = nextItem.Offset + nextItem.Size; lastFolderIndex = m_Database.GetLastFolder(index); } } unPackSize = MyMin(finishPos - startPos, unPackSize); chmFolderOutStream->m_FolderSize = folderSize; chmFolderOutStream->m_PosInFolder = 0; chmFolderOutStream->m_PosInSection = startPos; chmFolderOutStream->m_ExtractStatuses = &extractStatuses; chmFolderOutStream->m_NumFiles = extractStatuses.Size(); chmFolderOutStream->m_CurrentIndex = 0; try { UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex); const CResetTable &rt = lzxInfo.ResetTable; UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize); for (UInt32 b = 0; b < numBlocks; b++) { UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos; RINOK(extractCallback->SetCompleted(&completedSize)); UInt64 bCur = startBlock + b; if (bCur >= rt.ResetOffsets.Size()) return E_FAIL; UInt64 offset = rt.ResetOffsets[(int)bCur]; UInt64 compressedSize; rt.GetCompressedSizeOfBlock(bCur, compressedSize); UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection; if (rem > rt.BlockSize) rem = rt.BlockSize; RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL)); streamSpec->SetStream(m_Stream); streamSpec->Init(compressedSize); lzxDecoderSpec->SetKeepHistory(b > 0); HRESULT res = lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL); if (res != S_OK) { if (res != S_FALSE) return res; throw 1; } } } catch(...) { RINOK(chmFolderOutStream->FlushCorrupted(unPackSize)); } currentTotalSize += folderSize; if (folderIndex == lastFolderIndex) break; extractStatuses.Clear(); } } return S_OK; COM_TRY_END }