HRESULT DecompressArchives( UStringVector &archivePaths, UStringVector &archivePathsFull, const NWildcard::CCensorNode &wildcardCensor, const CExtractOptions &optionsSpec, IOpenCallbackUI *openCallback, IExtractCallbackUI *extractCallback) { CExtractOptions options = optionsSpec; for (int i = 0; i < archivePaths.Size(); i++) { const UString &archivePath = archivePaths[i]; NFile::NFind::CFileInfoW archiveFileInfo; if (!NFile::NFind::FindFile(archivePath, archiveFileInfo)) throw "there is no such archive"; if (archiveFileInfo.IsDirectory()) throw "there is no such archive"; options.ArchiveFileInfo = archiveFileInfo; RINOK(extractCallback->BeforeOpen(archivePath)); CArchiveLink archiveLink; HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback); RINOK(extractCallback->OpenResult(archivePath, result)); if (result != S_OK) continue; for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) { int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); if (index >= 0 && index > i) { archivePaths.Delete(index); archivePathsFull.Delete(index); } } #ifndef _NO_CRYPTO UString password; RINOK(openCallback->GetPasswordIfAny(password)); if (!password.IsEmpty()) { RINOK(extractCallback->SetPassword(password)); } #endif options.DefaultItemName = archiveLink.GetDefaultItemName(); RINOK(DecompressArchive( archiveLink.GetArchive(), archiveLink.GetDefaultItemName(), wildcardCensor, options, extractCallback)); } return S_OK; }
HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, const UStringVector &selectedNames) { _dontShowMode = false; LoadFullPathAndShow(); // OutputDebugStringA("=======\n"); // OutputDebugStringA("s1 \n"); CDisableTimerProcessing timerProcessing(*this); CDisableNotify disableNotify(*this); if (focusedPos < 0) focusedPos = 0; _listView.SetRedraw(false); // m_RedrawEnabled = false; LVITEMW item; ZeroMemory(&item, sizeof(item)); // DWORD tickCount0 = GetTickCount(); _enableItemChangeNotify = false; _listView.DeleteAllItems(); _enableItemChangeNotify = true; int listViewItemCount = 0; _selectedStatusVector.Clear(); // _realIndices.Clear(); _startGroupSelect = 0; _selectionIsDefined = false; // m_Files.Clear(); if (!_folder) { // throw 1; SetToRootFolder(); } _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder()); { CMyComPtr<IFolderSetFlatMode> folderSetFlatMode; _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); if (folderSetFlatMode) folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); } /* { CMyComPtr<IFolderSetShowNtfsStreamsMode> setShow; _folder.QueryInterface(IID_IFolderSetShowNtfsStreamsMode, &setShow); if (setShow) setShow->SetShowNtfsStreamsMode(BoolToInt(_showNtfsStrems_Mode)); } */ // DWORD tickCount1 = GetTickCount(); RINOK(_folder->LoadItems()); // DWORD tickCount2 = GetTickCount(); RINOK(InitColumns()); // OutputDebugString(TEXT("Start Dir\n")); UInt32 numItems; _folder->GetNumberOfItems(&numItems); bool showDots = _showDots && !IsRootFolder(); _listView.SetItemCount(numItems + (showDots ? 1 : 0)); _selectedStatusVector.ClearAndReserve(numItems); int cursorIndex = -1; CMyComPtr<IFolderGetSystemIconIndex> folderGetSystemIconIndex; if (!Is_Slow_Icon_Folder() || _showRealFileIcons) _folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex); if (!IsFSFolder()) { CMyComPtr<IGetFolderArcProps> getFolderArcProps; _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); _thereAreDeletedItems = false; if (getFolderArcProps) { CMyComPtr<IFolderArcProps> arcProps; getFolderArcProps->GetFolderArcProps(&arcProps); if (arcProps) { UInt32 numLevels; if (arcProps->GetArcNumLevels(&numLevels) != S_OK) numLevels = 0; NCOM::CPropVariant prop; if (arcProps->GetArcProp(numLevels - 1, kpidIsDeleted, &prop) == S_OK) if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal)) _thereAreDeletedItems = true; } } } if (showDots) { UString itemName = L".."; item.iItem = listViewItemCount; if (itemName == focusedName) cursorIndex = item.iItem; item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; int subItem = 0; item.iSubItem = subItem++; item.lParam = kParentIndex; // item.pszText = const_cast<wchar_t *>((const wchar_t *)itemName); item.pszText = LPSTR_TEXTCALLBACKW; UInt32 attrib = FILE_ATTRIBUTE_DIRECTORY; item.iImage = _extToIconMap.GetIconIndex(attrib, itemName); if (item.iImage < 0) item.iImage = 0; if (_listView.InsertItem(&item) == -1) return E_FAIL; listViewItemCount++; } // OutputDebugStringA("S1\n"); UString correctedName; UString itemName; UString relPath; for (UInt32 i = 0; i < numItems; i++) { const wchar_t *name = NULL; unsigned nameLen = 0; if (_folderGetItemName) _folderGetItemName->GetItemName(i, &name, &nameLen); if (!name) { GetItemName(i, itemName); name = itemName; nameLen = itemName.Len(); } bool selected = false; if (!focusedName.IsEmpty() || !selectedNames.IsEmpty()) { relPath.Empty(); // relPath += GetItemPrefix(i); // change it (_flatMode) if (i != kParentIndex && _flatMode) { const wchar_t *prefix = NULL; if (_folderGetItemName) { unsigned prefixLen = 0; _folderGetItemName->GetItemPrefix(i, &prefix, &prefixLen); if (prefix) relPath += prefix; } if (!prefix) { NCOM::CPropVariant prop; if (_folder->GetProperty(i, kpidPrefix, &prop) != S_OK) throw 2723400; if (prop.vt == VT_BSTR) relPath += prop.bstrVal; } } relPath += name; if (relPath == focusedName) cursorIndex = listViewItemCount; if (selectedNames.FindInSorted(relPath) >= 0) selected = true; } _selectedStatusVector.AddInReserved(selected); item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; if (!_mySelectMode) if (selected) { item.mask |= LVIF_STATE; item.state = LVIS_SELECTED; } int subItem = 0; item.iItem = listViewItemCount; item.iSubItem = subItem++; item.lParam = i; /* int finish = nameLen - 4; int j; for (j = 0; j < finish; j++) { if (name[j ] == ' ' && name[j + 1] == ' ' && name[j + 2] == ' ' && name[j + 3] == ' ' && name[j + 4] == ' ') break; } if (j < finish) { correctedName.Empty(); correctedName = L"virus"; int pos = 0; for (;;) { int posNew = itemName.Find(L" ", pos); if (posNew < 0) { correctedName += itemName.Ptr(pos); break; } correctedName += itemName.Mid(pos, posNew - pos); correctedName += L" ... "; pos = posNew; while (itemName[++pos] == ' '); } item.pszText = const_cast<wchar_t *>((const wchar_t *)correctedName); } else */ { // item.pszText = const_cast<wchar_t *>((const wchar_t *)name); item.pszText = LPSTR_TEXTCALLBACKW; /* LPSTR_TEXTCALLBACKW works, but in some cases there are problems, since we block notify handler. */ } UInt32 attrib = 0; // for (int yyy = 0; yyy < 6000000; yyy++) { NCOM::CPropVariant prop; RINOK(_folder->GetProperty(i, kpidAttrib, &prop)); if (prop.vt == VT_UI4) { // char s[256]; sprintf(s, "attrib = %7x", attrib); OutputDebugStringA(s); attrib = prop.ulVal; } else if (IsItem_Folder(i)) attrib |= FILE_ATTRIBUTE_DIRECTORY; // } bool defined = false; if (folderGetSystemIconIndex) { folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage); defined = (item.iImage > 0); } if (!defined) { if (_currentFolderPrefix.IsEmpty()) { int iconIndexTemp; GetRealIconIndex(us2fs((UString)name) + FCHAR_PATH_SEPARATOR, attrib, iconIndexTemp); item.iImage = iconIndexTemp; } else { item.iImage = _extToIconMap.GetIconIndex(attrib, name); } } if (item.iImage < 0) item.iImage = 0; if (_listView.InsertItem(&item) == -1) return E_FAIL; listViewItemCount++; } // OutputDebugStringA("End2\n"); if (_listView.GetItemCount() > 0 && cursorIndex >= 0) SetFocusedSelectedItem(cursorIndex, selectFocused); // DWORD tickCount3 = GetTickCount(); SetSortRawStatus(); _listView.SortItems(CompareItems, (LPARAM)this); // DWORD tickCount4 = GetTickCount(); if (cursorIndex < 0 && _listView.GetItemCount() > 0) { if (focusedPos >= _listView.GetItemCount()) focusedPos = _listView.GetItemCount() - 1; // we select item only in showDots mode. SetFocusedSelectedItem(focusedPos, showDots); } // m_RedrawEnabled = true; // DWORD tickCount5 = GetTickCount(); _listView.EnsureVisible(_listView.GetFocusedItem(), false); // DWORD tickCount6 = GetTickCount(); disableNotify.SetMemMode_Enable(); disableNotify.Restore(); _listView.SetRedraw(true); // DWORD tickCount7 = GetTickCount(); _listView.InvalidateRect(NULL, true); // DWORD tickCount8 = GetTickCount(); // OutputDebugStringA("End1\n"); /* _listView.UpdateWindow(); */ Refresh_StatusBar(); // DWORD tickCount9 = GetTickCount(); /* char s[256]; sprintf(s, // "attribMap = %5d, extMap = %5d, " "delete = %5d, load = %5d, list = %5d, sort = %5d, end = %5d", // _extToIconMap._attribMap.Size(), // _extToIconMap._extMap.Size(), tickCount1 - tickCount0, tickCount2 - tickCount1, tickCount3 - tickCount2, tickCount4 - tickCount3, tickCount5 - tickCount4 ); sprintf(s, "5 = %5d, 6 = %5d, 7 = %5d, 8 = %5d, 9 = %5d", tickCount5 - tickCount4, tickCount6 - tickCount5, tickCount7 - tickCount6, tickCount8 - tickCount7, tickCount9 - tickCount8 ); OutputDebugStringA(s); */ return S_OK; }
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; }
HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices, bool stdInMode, UStringVector &arcPaths, UStringVector &arcPathsFull, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, #ifndef _NO_CRYPTO bool &passwordEnabled, UString &password, #endif UInt64 &numErrors) { numErrors = 0; CFieldPrinter fieldPrinter; if (!techMode) fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0])); UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0; UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0; int numArcs = /* stdInMode ? 1 : */ arcPaths.Size(); for (int i = 0; i < numArcs; i++) { const UString &archiveName = arcPaths[i]; UInt64 arcPackSize = 0; if (!stdInMode) { NFile::NFind::CFileInfoW fi; if (!fi.Find(archiveName) || fi.IsDir()) { g_StdOut << endl << "Error: " << archiveName << " is not file" << endl; numErrors++; continue; } arcPackSize = fi.Size; } CArchiveLink archiveLink; COpenCallbackConsole openCallback; openCallback.OutStream = &g_StdOut; #ifndef _NO_CRYPTO openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; #endif HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archiveName, &openCallback); if (result != S_OK) { if (result == E_ABORT) return result; g_StdOut << endl << "Error: " << archiveName << ": "; if (result == S_FALSE) { #ifndef _NO_CRYPTO if (openCallback.Open_WasPasswordAsked()) g_StdOut << "Can not open encrypted archive. Wrong password?"; else #endif g_StdOut << "Can not open file as archive"; } else if (result == E_OUTOFMEMORY) g_StdOut << "Can't allocate required memory"; else g_StdOut << NError::MyFormatMessage(result); g_StdOut << endl; numErrors++; continue; } if (!stdInMode) for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) { int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]); if (index >= 0 && index > i) { arcPaths.Delete(index); arcPathsFull.Delete(index); numArcs = arcPaths.Size(); } } if (enableHeaders) { g_StdOut << endl << kListing << archiveName << endl << endl; for (int i = 0; i < archiveLink.Arcs.Size(); i++) { const CArc &arc = archiveLink.Arcs[i]; g_StdOut << "--\n"; PrintPropPair(L"Path", arc.Path); PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name); if (!arc.ErrorMessage.IsEmpty()) PrintPropPair(L"Error", arc.ErrorMessage); UInt32 numProps; IInArchive *archive = arc.Archive; if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK) { for (UInt32 j = 0; j < numProps; j++) { CMyComBSTR name; PROPID propID; VARTYPE vt; RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)); NCOM::CPropVariant prop; RINOK(archive->GetArchiveProperty(propID, &prop)); UString s = ConvertPropertyToString(prop, propID); if (!s.IsEmpty()) PrintPropPair(GetPropName(propID, name), s); } } if (i != archiveLink.Arcs.Size() - 1) { UInt32 numProps; g_StdOut << "----\n"; if (archive->GetNumberOfProperties(&numProps) == S_OK) { UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex; for (UInt32 j = 0; j < numProps; j++) { CMyComBSTR name; PROPID propID; VARTYPE vt; RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)); NCOM::CPropVariant prop; RINOK(archive->GetProperty(mainIndex, propID, &prop)); UString s = ConvertPropertyToString(prop, propID); if (!s.IsEmpty()) PrintPropPair(GetPropName(propID, name), s); } } } } g_StdOut << endl; if (techMode) g_StdOut << "----------\n"; } if (enableHeaders && !techMode) { fieldPrinter.PrintTitle(); g_StdOut << endl; fieldPrinter.PrintTitleLines(); g_StdOut << endl; } const CArc &arc = archiveLink.Arcs.Back(); IInArchive *archive = arc.Archive; if (techMode) { RINOK(fieldPrinter.Init(archive)); } UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0; UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0; UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); for (UInt32 i = 0; i < numItems; i++) { if (NConsoleClose::TestBreakSignal()) return E_ABORT; UString filePath; HRESULT res = arc.GetItemPath(i, filePath); if (stdInMode && res == E_INVALIDARG) break; RINOK(res); bool isFolder; RINOK(IsArchiveItemFolder(archive, i, isFolder)); if (!wildcardCensor.CheckPath(filePath, !isFolder)) continue; fieldPrinter.PrintItemInfo(arc, i, techMode); UInt64 packSize, unpackSize; if (!GetUInt64Value(archive, i, kpidSize, unpackSize)) unpackSize = 0; else totalUnPackSizePointer = &totalUnPackSize; if (!GetUInt64Value(archive, i, kpidPackSize, packSize)) packSize = 0; else totalPackSizePointer = &totalPackSize; g_StdOut << endl; if (isFolder) numDirs++; else numFiles++; totalPackSize += packSize; totalUnPackSize += unpackSize; } if (!stdInMode && totalPackSizePointer == 0) { if (archiveLink.VolumePaths.Size() != 0) arcPackSize += archiveLink.VolumesSize; totalPackSize = (numFiles == 0) ? 0 : arcPackSize; totalPackSizePointer = &totalPackSize; } if (totalUnPackSizePointer == 0 && numFiles == 0) { totalUnPackSize = 0; totalUnPackSizePointer = &totalUnPackSize; } if (enableHeaders && !techMode) { fieldPrinter.PrintTitleLines(); g_StdOut << endl; fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer); g_StdOut << endl; } if (totalPackSizePointer != 0) { totalPackSizePointer2 = &totalPackSize2; totalPackSize2 += totalPackSize; } if (totalUnPackSizePointer != 0) { totalUnPackSizePointer2 = &totalUnPackSize2; totalUnPackSize2 += totalUnPackSize; } numFiles2 += numFiles; numDirs2 += numDirs; } if (enableHeaders && !techMode && numArcs > 1) { g_StdOut << endl; fieldPrinter.PrintTitleLines(); g_StdOut << endl; fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2); g_StdOut << endl; g_StdOut << "Archives: " << numArcs << endl; } return S_OK; }
HRESULT ListArchives( CCodecs *codecs, UStringVector &archivePaths, UStringVector &archivePathsFull, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &numErrors) { numErrors = 0; CFieldPrinter fieldPrinter; if (!techMode) fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0])); UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0; UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0; for (int i = 0; i < archivePaths.Size(); i++) { const UString &archiveName = archivePaths[i]; NFile::NFind::CFileInfoW archiveFileInfo; if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory()) { g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl; numErrors++; continue; } if (archiveFileInfo.IsDirectory()) { g_StdOut << endl << "Error: " << archiveName << " is not file" << endl; numErrors++; continue; } CArchiveLink archiveLink; COpenCallbackConsole openCallback; openCallback.OutStream = &g_StdOut; openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, &openCallback); if (result != S_OK) { g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl; numErrors++; continue; } for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) { int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); if (index >= 0 && index > i) { archivePaths.Delete(index); archivePathsFull.Delete(index); } } IInArchive *archive = archiveLink.GetArchive(); const UString defaultItemName = archiveLink.GetDefaultItemName(); if (enableHeaders) { g_StdOut << endl << kListing << archiveName << endl << endl; UInt32 numProps; if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK) { for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; if (archive->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (archive->GetArchiveProperty(propID, &prop) != S_OK) continue; UString s = ConvertPropertyToString(prop, propID); if (!s.IsEmpty()) g_StdOut << GetPropName(propID, name) << " = " << s << endl; } } if (techMode) g_StdOut << "----------\n"; if (numProps > 0) g_StdOut << endl; } if (enableHeaders && !techMode) { fieldPrinter.PrintTitle(); g_StdOut << endl; fieldPrinter.PrintTitleLines(); g_StdOut << endl; } if (techMode) { RINOK(fieldPrinter.Init(archive)); } UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0; UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0; UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); for(UInt32 i = 0; i < numItems; i++) { if (NConsoleClose::TestBreakSignal()) return E_ABORT; UString filePath; RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath)); bool isFolder; RINOK(IsArchiveItemFolder(archive, i, isFolder)); if (!wildcardCensor.CheckPath(filePath, !isFolder)) continue; fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode); UInt64 packSize, unpackSize; if (!GetUInt64Value(archive, i, kpidSize, unpackSize)) unpackSize = 0; else totalUnPackSizePointer = &totalUnPackSize; if (!GetUInt64Value(archive, i, kpidPackedSize, packSize)) packSize = 0; else totalPackSizePointer = &totalPackSize; g_StdOut << endl; if (isFolder) numDirs++; else numFiles++; totalPackSize += packSize; totalUnPackSize += unpackSize; } if (enableHeaders && !techMode) { fieldPrinter.PrintTitleLines(); g_StdOut << endl; fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer); g_StdOut << endl; } if (totalPackSizePointer != 0) { totalPackSizePointer2 = &totalPackSize2; totalPackSize2 += totalPackSize; } if (totalUnPackSizePointer != 0) { totalUnPackSizePointer2 = &totalUnPackSize2; totalUnPackSize2 += totalUnPackSize; } numFiles2 += numFiles; numDirs2 += numDirs; } if (enableHeaders && !techMode && archivePaths.Size() > 1) { g_StdOut << endl; fieldPrinter.PrintTitleLines(); g_StdOut << endl; fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2); g_StdOut << endl; g_StdOut << "Archives: " << archivePaths.Size() << endl; } return S_OK; }
// Create a new 7z archive for each folder contained in the archive to be // exploded. HRESULT ExplodeArchives(CCodecs *codecs, const CIntVector &formatIndices, bool stdInMode, UStringVector &arcPaths, UStringVector &arcPathsFull, UString& outputPath, UInt64 maxDepth, UInt64 &numErrors) { int numArcs = arcPaths.Size(); for (int i = 0; i < numArcs; i++) { UString archivePath = arcPaths[i]; /*UString outputPath = arcPaths[i]; outputPath.Replace(L'\\', L'/'); // linux and windows consistent const UString archiveName = StripFile(outputPath); outputPath.Empty();*/ archivePath.Replace(L'\\', L'/'); // linux, windows and archive consistent outputPath.Replace(L'\\', L'/'); FixPathFormat(outputPath); const UString archiveName = GetFileFromPath(archivePath); g_StdOut << "Outputting into : " << outputPath << endl; UInt64 arcPackSize = 0; if (!stdInMode) { NFile::NFind::CFileInfoW fi; if (!fi.Find(archivePath) || fi.IsDir()) { SHOW_ERROR("is not a file."); continue; } arcPackSize = fi.Size; } g_StdOut << endl << "Exploding : " << archivePath << endl << endl; CArchiveLink archiveLink; COpenCallbackConsole openCallback; openCallback.OutStream = &g_StdOut; #ifndef _NO_CRYPTO openCallback.PasswordIsDefined = false; #endif HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archivePath, &openCallback); if (result != S_OK) { if (result == E_ABORT) return result; g_StdOut << endl << "Error: " << archivePath << ": "; if (result == S_FALSE) g_StdOut << "Can not open file as archive"; else if (result == E_OUTOFMEMORY) g_StdOut << "Can't allocate required memory"; else g_StdOut << NError::MyFormatMessage(result); g_StdOut << endl; numErrors++; continue; } // remove other files names if multi-volume if (!stdInMode) { for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) { int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]); if (index >= 0 && index > i) { arcPaths.Delete(index); arcPathsFull.Delete(index); numArcs = arcPaths.Size(); } } } // don't support multi volume because i have to reopen the stream if (archiveLink.VolumePaths.Size() != 1) { SHOW_ERROR("Exploding multi-volume archives isn't supported."); continue; } bool szArchive = true; for (int x = 0; x < archiveLink.Arcs.Size(); x++) { const UString szName = L"7z"; const CArc &arc = archiveLink.Arcs[x]; if (codecs->Formats[arc.FormatIndex].Name != szName) { szArchive = false; break; } } if (!szArchive) { SHOW_ERROR("Only 7z archives can be exploded."); continue; } // Only 7z is supported, and it's been checked using namespace NArchive::N7z; IInArchive* inArc = archiveLink.GetArchive(); CHandler* szHandler = (CHandler*)inArc; // not a fan of having to reopen the file.. CInFileStream* _inStream = new CInFileStream; CMyComPtr<CInFileStream> inStream(_inStream); if (!inStream->Open(archivePath)) { SHOW_ERROR("Cannot be opened for reading."); continue; } // Explode the archive into each folder CObjectVector<szExplodeData> exploded; szHandler->Explode(exploded, maxDepth); if (exploded.Size() == 0) { SHOW_ERROR("Empty archive!"); continue; } // should make a struct that gets passed to Explode.. // something like /* * struct a { * CArchiveDatabase newDatabase; * CRecordVector<UInt64> folderSizes, folderPositions * }; * CObjectVector<a> exploded; * szHandler->Explode(exploded); */ // Save each folder as a new 7z archive for (int x = 0; x < exploded.Size(); x++) { UString relativeFilePath; // relative to archive UString fileName; CArchiveDatabase& newDatabase = exploded[x].newDatabase; szExplodeData& explodeData = exploded[x]; // each exploded archive will only have a single folder. // no longer true. need to make sure the selected file // is the highest in the dir tree. could make 7zhandler // give us this info i guess. if (newDatabase.Files.Size() > 0) { relativeFilePath = newDatabase.Files[0].Name; if (!newDatabase.Files[0].IsDir) { fileName = GetFileFromPath(relativeFilePath); StripFile(relativeFilePath); } } //g_StdOut << "Relative path " << relativeFilePath << endl; //g_StdOut << "Archive " << archivePath << endl; UString folderOutPath = outputPath + relativeFilePath; if (relativeFilePath.Length() != 0) { bool b = NWindows::NFile::NDirectory::CreateComplexDirectory(folderOutPath); if (!b) g_StdOut << "Couldn't create directory " << folderOutPath << endl; //relativeFilePath.Insert(folderOutPath.Length(), L'/'); } std::wstringstream sstream; sstream << folderOutPath.GetBuffer(); if (newDatabase.Files.Size() == 1) // can use file names sstream << fileName.GetBuffer(); else // use folder as name sstream << archiveName.GetBuffer() << L"_folder_" << x; sstream << ".7z"; g_StdOut << "Saving as '" << sstream.str().c_str() << "'" << endl; COutFileStream* _outstream = new COutFileStream; CMyComPtr<COutFileStream> outstream(_outstream); outstream->Create(sstream.str().c_str(), true); COutArchive out; out.Create(outstream, false); out.SkipPrefixArchiveHeader(); for (int folderIndex = 0; folderIndex < newDatabase.Folders.Size(); folderIndex++) { UInt64 folderLen = explodeData.folderSizes[folderIndex]; UInt64 folderStartPackPos = explodeData.folderPositions[folderIndex]; // write actual data RINOK(WriteRange(inStream, out.SeqStream, folderStartPackPos, folderLen, NULL)); } CCompressionMethodMode method, headerMethod; szHandler->SetCompressionMethod(method, headerMethod); CHeaderOptions headerOptions; headerOptions.CompressMainHeader = true; out.WriteDatabase(newDatabase, &headerMethod, headerOptions); out.Close(); /*#ifdef ENV_UNIX // Create a symlink for each file in the folder. // This makes it seem as though each file is individually accessible. for (int fileIndex = 0; fileIndex < newDatabase.Files.Size(); fileIndex++) { AString oldfile, newfile; UString woldfile = sstream.str().c_str(); UString wnewfile = outputPath + relativeFilePath + newDatabase.Files[fileIndex].Name + L".7z"; ConvertUnicodeToUTF8(woldfile, oldfile); ConvertUnicodeToUTF8(wnewfile, newfile); const char* link_to = oldfile.GetBuffer(); const char* link_name = newfile.GetBuffer(); unlink(link_name);// should ask user //g_StdOut << "Creating symlink to '" << link_to << "' called '" << link_name << "'" << endl; int status = symlink(link_to, link_name); if (status == -1) { AString error = "Couldn't create symlink for '"; error += newfile; error += "'"; SHOW_ERROR(error); g_StdOut << "Error: " << errno << endl; } } #endif*/ } archiveLink.Close(); // not needed but oh well } return S_OK; }
HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, const UStringVector &selectedNames) { _dontShowMode = false; LoadFullPathAndShow(); // OutputDebugStringA("=======\n"); // OutputDebugStringA("s1 \n"); CDisableTimerProcessing timerProcessing(*this); if (focusedPos < 0) focusedPos = 0; _listView.SetRedraw(false); // m_RedrawEnabled = false; LVITEMW item; ZeroMemory(&item, sizeof(item)); _listView.DeleteAllItems(); _selectedStatusVector.Clear(); // _realIndices.Clear(); _startGroupSelect = 0; _selectionIsDefined = false; // m_Files.Clear(); // _folder.Release(); if (!_folder) { // throw 1; SetToRootFolder(); } _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder()); CMyComPtr<IFolderSetFlatMode> folderSetFlatMode; _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); if (folderSetFlatMode) folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); RINOK(_folder->LoadItems()); RINOK(InitColumns()); // OutputDebugString(TEXT("Start Dir\n")); UInt32 numItems; _folder->GetNumberOfItems(&numItems); bool showDots = _showDots && !IsRootFolder(); _listView.SetItemCount(numItems + (showDots ? 1 : 0)); _selectedStatusVector.Reserve(numItems); int cursorIndex = -1; CMyComPtr<IFolderGetSystemIconIndex> folderGetSystemIconIndex; if (!IsFSFolder() || _showRealFileIcons) _folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex); if (showDots) { UString itemName = L".."; item.iItem = _listView.GetItemCount(); if (itemName.CompareNoCase(focusedName) == 0) cursorIndex = item.iItem; item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; int subItem = 0; item.iSubItem = subItem++; item.lParam = kParentIndex; item.pszText = const_cast<wchar_t *>((const wchar_t *)itemName); UInt32 attrib = FILE_ATTRIBUTE_DIRECTORY; item.iImage = _extToIconMap.GetIconIndex(attrib, itemName); if (item.iImage < 0) item.iImage = 0; if (_listView.InsertItem(&item) == -1) return E_FAIL; } // OutputDebugStringA("S1\n"); for (UInt32 i = 0; i < numItems; i++) { UString itemName = GetItemName(i); const UString relPath = GetItemRelPath(i); if (relPath.CompareNoCase(focusedName) == 0) cursorIndex = _listView.GetItemCount(); bool selected = false; if (selectedNames.FindInSorted(relPath) >= 0) selected = true; _selectedStatusVector.Add(selected); item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; if (!_mySelectMode) if (selected) { item.mask |= LVIF_STATE; item.state = LVIS_SELECTED; } int subItem = 0; item.iItem = _listView.GetItemCount(); item.iSubItem = subItem++; item.lParam = i; UString correctedName; if (itemName.Find(L" ") >= 0) { int pos = 0; for (;;) { int posNew = itemName.Find(L" ", pos); if (posNew < 0) { correctedName += itemName.Mid(pos); break; } correctedName += itemName.Mid(pos, posNew - pos); correctedName += L" ... "; pos = posNew; while (itemName[++pos] == ' '); } item.pszText = const_cast<wchar_t *>((const wchar_t *)correctedName); } else item.pszText = const_cast<wchar_t *>((const wchar_t *)itemName); NCOM::CPropVariant prop; RINOK(_folder->GetProperty(i, kpidAttrib, &prop)); UInt32 attrib = 0; if (prop.vt == VT_UI4) attrib = prop.ulVal; else if (IsItemFolder(i)) attrib |= FILE_ATTRIBUTE_DIRECTORY; bool defined = false; if (folderGetSystemIconIndex) { folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage); defined = (item.iImage > 0); } if (!defined) { if (_currentFolderPrefix.IsEmpty()) { int iconIndexTemp; GetRealIconIndex(itemName + WCHAR_PATH_SEPARATOR, attrib, iconIndexTemp); item.iImage = iconIndexTemp; } else { item.iImage = _extToIconMap.GetIconIndex(attrib, itemName); } } if (item.iImage < 0) item.iImage = 0; if (_listView.InsertItem(&item) == -1) return E_FAIL; // error } // OutputDebugStringA("End2\n"); if (_listView.GetItemCount() > 0 && cursorIndex >= 0) SetFocusedSelectedItem(cursorIndex, selectFocused); _listView.SortItems(CompareItems, (LPARAM)this); if (cursorIndex < 0 && _listView.GetItemCount() > 0) { if (focusedPos >= _listView.GetItemCount()) focusedPos = _listView.GetItemCount() - 1; // we select item only in showDots mode. SetFocusedSelectedItem(focusedPos, showDots); } // m_RedrawEnabled = true; _listView.EnsureVisible(_listView.GetFocusedItem(), false); _listView.SetRedraw(true); _listView.InvalidateRect(NULL, true); // OutputDebugStringA("End1\n"); /* _listView.UpdateWindow(); */ return S_OK; }
HRESULT DecompressArchives( CCodecs *codecs, const CIntVector &formatIndices, UStringVector &arcPaths, UStringVector &arcPathsFull, const NWildcard::CCensorNode &wildcardCensor, const CExtractOptions &options, IOpenCallbackUI *openCallback, IExtractCallbackUI *extractCallback, UString &errorMessage, CDecompressStat &stat) { stat.Clear(); int i; UInt64 totalPackSize = 0; CRecordVector<UInt64> archiveSizes; int numArcs = options.StdInMode ? 1 : arcPaths.Size(); for (i = 0; i < numArcs; i++) { NFile::NFind::CFileInfoW fi; fi.Size = 0; if (!options.StdInMode) { const UString &arcPath = arcPaths[i]; if (!fi.Find(arcPath)) throw "there is no such archive"; if (fi.IsDir()) throw "can't decompress folder"; } archiveSizes.Add(fi.Size); totalPackSize += fi.Size; } CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec); bool multi = (numArcs > 1); extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode); if (multi) { RINOK(extractCallback->SetTotal(totalPackSize)); } for (i = 0; i < numArcs; i++) { const UString &arcPath = arcPaths[i]; NFile::NFind::CFileInfoW fi; if (options.StdInMode) { fi.Size = 0; fi.Attrib = 0; } else { if (!fi.Find(arcPath) || fi.IsDir()) throw "there is no such archive"; } #ifndef _NO_CRYPTO openCallback->Open_ClearPasswordWasAskedFlag(); #endif RINOK(extractCallback->BeforeOpen(arcPath)); CArchiveLink archiveLink; CIntVector formatIndices2 = formatIndices; #ifndef _SFX if (formatIndices.IsEmpty()) { int pos = arcPath.ReverseFind(L'.'); if (pos >= 0) { UString s = arcPath.Mid(pos + 1); int index = codecs->FindFormatForExtension(s); if (index >= 0 && s == L"001") { s = arcPath.Left(pos); pos = s.ReverseFind(L'.'); if (pos >= 0) { int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1)); if (index2 >= 0 && s.CompareNoCase(L"rar") != 0) { formatIndices2.Add(index2); formatIndices2.Add(index); } } } } } #endif HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback); if (result == E_ABORT) return result; bool crypted = false; #ifndef _NO_CRYPTO crypted = openCallback->Open_WasPasswordAsked(); /* if(!crypted) { fprintf(stderr, "%s is not encrypted!\n", "123"); exit(0); } */ #endif RINOK(extractCallback->OpenResult(arcPath, result, crypted)); if (result != S_OK) continue; if (!options.StdInMode) for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) { int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]); if (index >= 0 && index > i) { arcPaths.Delete(index); arcPathsFull.Delete(index); totalPackSize -= archiveSizes[index]; archiveSizes.Delete(index); numArcs = arcPaths.Size(); } } if (archiveLink.VolumePaths.Size() != 0) { totalPackSize += archiveLink.VolumesSize; RINOK(extractCallback->SetTotal(totalPackSize)); } #ifndef _NO_CRYPTO UString password; RINOK(openCallback->Open_GetPasswordIfAny(password)); if (!password.IsEmpty()) { RINOK(extractCallback->SetPassword(password)); } #endif for (int v = 0; v < archiveLink.Arcs.Size(); v++) { const UString &s = archiveLink.Arcs[v].ErrorMessage; if (!s.IsEmpty()) { RINOK(extractCallback->MessageError(s)); } } CArc &arc = archiveLink.Arcs.Back(); arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice); arc.MTime = fi.MTime; UInt64 packProcessed; RINOK(DecompressArchive(arc, fi.Size + archiveLink.VolumesSize, wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed)); if (!options.StdInMode) packProcessed = fi.Size + archiveLink.VolumesSize; extractCallbackSpec->LocalProgressSpec->InSize += packProcessed; extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize; if (!errorMessage.IsEmpty()) return E_FAIL; } stat.NumFolders = extractCallbackSpec->NumFolders; stat.NumFiles = extractCallbackSpec->NumFiles; stat.UnpackSize = extractCallbackSpec->UnpackSize; stat.CrcSum = extractCallbackSpec->CrcSum; stat.NumArchives = arcPaths.Size(); stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize; return S_OK; }