HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath) { NWorkDir::CInfo workDirInfo; workDirInfo.Load(); FString namePart; FString workDir = GetWorkDir(workDirInfo, originalPath, namePart); CreateComplexDir(workDir); CTempFile tempFile; _outStreamSpec = new COutFileStream; OutStream = _outStreamSpec; if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File)) { DWORD error = GetLastError(); return error ? error : E_FAIL; } _originalPath = originalPath; return S_OK; }
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; }
static HRESULT ShowDialog( CCodecs *codecs, const NWildcard::CCensor &censor, CUpdateOptions &options, CUpdateCallbackGUI *callback, HWND hwndParent) { if (options.Commands.Size() != 1) throw "It must be one command"; UString currentDirPrefix; #ifndef UNDER_CE { if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix)) return E_FAIL; NName::NormalizeDirPathPrefix(currentDirPrefix); } #endif bool oneFile = false; NFind::CFileInfoW fileInfo; UString name; if (censor.Pairs.Size() > 0) { const NWildcard::CPair &pair = censor.Pairs[0]; if (pair.Head.IncludeItems.Size() > 0) { const NWildcard::CItem &item = pair.Head.IncludeItems[0]; if (item.ForFile) { name = pair.Prefix; for (int i = 0; i < item.PathParts.Size(); i++) { if (i > 0) name += WCHAR_PATH_SEPARATOR; name += item.PathParts[i]; } if (fileInfo.Find(name)) { if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1) oneFile = !fileInfo.IsDir(); } } } } CCompressDialog dialog; NCompressDialog::CInfo &di = dialog.Info; dialog.ArcFormats = &codecs->Formats; for (int i = 0; i < codecs->Formats.Size(); i++) { const CArcInfoEx &ai = codecs->Formats[i]; if (ai.Name.CompareNoCase(L"swfc") == 0) if (!oneFile || name.Right(4).CompareNoCase(L".swf") != 0) continue; if (ai.UpdateEnabled && (oneFile || !ai.KeepName)) dialog.ArcIndices.Add(i); } if (dialog.ArcIndices.Size() == 0) { ShowErrorMessage(L"No Update Engines"); return E_FAIL; } // di.ArchiveName = options.ArchivePath.GetFinalPath(); di.ArchiveName = options.ArchivePath.GetPathWithoutExt(); dialog.OriginalFileName = options.ArchivePath.Prefix + fileInfo.Name; di.CurrentDirPrefix = currentDirPrefix; di.SFXMode = options.SfxMode; di.OpenShareForWrite = options.OpenShareForWrite; if (callback->PasswordIsDefined) di.Password = callback->Password; di.KeepName = !oneFile; if (dialog.Create(hwndParent) != IDOK) return E_ABORT; options.VolumesSizes = di.VolumeSizes; /* if (di.VolumeSizeIsDefined) { MyMessageBox(L"Splitting to volumes is not supported"); return E_FAIL; } */ NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet; switch(di.UpdateMode) { case NCompressDialog::NUpdateMode::kAdd: actionSet = NUpdateArchive::kAddActionSet; break; case NCompressDialog::NUpdateMode::kUpdate: actionSet = NUpdateArchive::kUpdateActionSet; break; case NCompressDialog::NUpdateMode::kFresh: actionSet = NUpdateArchive::kFreshActionSet; break; case NCompressDialog::NUpdateMode::kSynchronize: actionSet = NUpdateArchive::kSynchronizeActionSet; break; default: throw 1091756; } const CArcInfoEx &archiverInfo = codecs->Formats[di.FormatIndex]; callback->PasswordIsDefined = (!di.Password.IsEmpty()); if (callback->PasswordIsDefined) callback->Password = di.Password; options.MethodMode.Properties.Clear(); bool is7z = archiverInfo.Name.CompareNoCase(L"7z") == 0; bool methodOverride = IsThereMethodOverride(is7z, di.Options); SetOutProperties( options.MethodMode.Properties, is7z, di.Level, !methodOverride, di.Method, di.Dictionary, di.OrderMode, di.Order, di.SolidIsSpecified, di.SolidBlockSize, di.MultiThreadIsAllowed, di.NumThreads, di.EncryptionMethod, di.EncryptHeadersIsAllowed, di.EncryptHeaders, di.SFXMode); options.OpenShareForWrite = di.OpenShareForWrite; ParseAndAddPropertires(options.MethodMode.Properties, di.Options); if (di.SFXMode) options.SfxMode = true; options.MethodMode.FormatIndex = di.FormatIndex; options.ArchivePath.VolExtension = archiverInfo.GetMainExt(); if (di.SFXMode) options.ArchivePath.BaseExtension = kSFXExtension; else options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension; options.ArchivePath.ParseFromPath(di.ArchiveName); NWorkDir::CInfo workDirInfo; workDirInfo.Load(); options.WorkingDir.Empty(); if (workDirInfo.Mode != NWorkDir::NMode::kCurrent) { UString fullPath; NDirectory::MyGetFullPathName(di.ArchiveName, fullPath); options.WorkingDir = GetWorkDir(workDirInfo, fullPath); NDirectory::CreateComplexDirectory(options.WorkingDir); } return S_OK; }