Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2007-01-20 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:49 +0300
commitd9666cf046a8453b33b3e2fbf4d82295a9f87df3 (patch)
treec722ed19b844b53042aec0c1d7d2f8381140a5ed /CPP/7zip/UI/Far/PluginWrite.cpp
parent804edc5756fede54dbb1aefda6d39d306111938d (diff)
4.44 beta
Diffstat (limited to 'CPP/7zip/UI/Far/PluginWrite.cpp')
-rwxr-xr-xCPP/7zip/UI/Far/PluginWrite.cpp696
1 files changed, 696 insertions, 0 deletions
diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp
new file mode 100755
index 00000000..d6730985
--- /dev/null
+++ b/CPP/7zip/UI/Far/PluginWrite.cpp
@@ -0,0 +1,696 @@
+// PluginWrite.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../Common/ZipRegistry.h"
+#include "../Common/WorkDir.h"
+#include "../Common/OpenArchive.h"
+
+#include "../Agent/Agent.h"
+
+#include "ProgressBox.h"
+#include "Messages.h"
+#include "UpdateCallback100.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+using namespace NFar;
+
+using namespace NUpdateArchive;
+
+static const char *kHelpTopic = "Update";
+
+static LPCWSTR kTempArcivePrefix = L"7zA";
+
+static const char *kArchiveHistoryKeyName = "7-ZipArcName";
+
+static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 };
+
+static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method)
+{
+ CMyComPtr<ISetProperties> setProperties;
+ if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
+ {
+ UStringVector realNames;
+ realNames.Add(UString(L"x"));
+ NCOM::CPropVariant value = (UInt32)method;
+ CRecordVector<const wchar_t *> names;
+ for(int i = 0; i < realNames.Size(); i++)
+ names.Add(realNames[i]);
+ RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size()));
+ }
+ return S_OK;
+}
+
+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;
+ ReadCompressionInfo(compressionInfo);
+
+ int methodIndex = 0;
+ for (int 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;
+
+ SaveCompressionInfo(compressionInfo);
+
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+ UString workDir = GetWorkDir(workDirInfo, m_FileName);
+ CreateComplexDirectory(workDir);
+
+ CTempFileW tempFile;
+ UString tempFileName;
+ if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
+ 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), 1 << 16);
+ }
+
+ ////////////////////////////
+ // Save FolderItem;
+ UStringVector aPathVector;
+ GetPathParts(aPathVector);
+
+ /*
+ UString anArchivePrefix;
+ for(i = aPathVector.Size() - 1; i >= 0; i--)
+ {
+ anArchivePrefix += aPathVector[i];
+ anArchivePrefix += wchar_t(NName::kDirDelimiter);
+ }
+ /////////////////////////////////
+ */
+
+ 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);
+
+ // CSysString aCurrentFolder;
+ // MyGetCurrentDirectory(aCurrentFolder);
+ // outArchive->SetFiles(MultiByteToUnicodeString(aCurrentFolder, CP_OEMCP),
+ outArchive->SetFiles(L"",
+ &fileNamePointers.Front(), fileNamePointers.Size());
+ BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
+ for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ actionSetByte[i] = actionSet->StateActions[i];
+
+ CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->Init(m_ArchiveHandler, &progressBox);
+
+ if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK)
+ return NFileOperationReturnCode::kError;
+
+ result = outArchive->DoOperation(NULL, NULL,
+ tempFileName, actionSetByte, NULL, updateCallback);
+ updateCallback.Release();
+ outArchive.Release();
+
+ /*
+ HRESULT result = Compress(fileNames, anArchivePrefix, *actionSet,
+ m_ProxyHandler.get(),
+ m_ArchiverInfo.ClassID, compressionInfo.Method == 0,
+ compressionInfo.Method == 2, tempFileName, progressBoxPointer);
+ */
+
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return NFileOperationReturnCode::kError;
+ }
+
+ _folder.Release();
+ m_ArchiveHandler->Close();
+
+ // m_FolderItem = NULL;
+
+ if (!DeleteFileAlways(m_FileName))
+ {
+ ShowLastErrorMessage();
+ return NFileOperationReturnCode::kError;
+ }
+
+ tempFile.DisableDeleting();
+ if (!MyMoveFile(tempFileName, m_FileName))
+ {
+ ShowLastErrorMessage();
+ return NFileOperationReturnCode::kError;
+ }
+
+ m_ArchiveHandler->ReOpen(NULL);
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return NFileOperationReturnCode::kError;
+ }
+
+ /*
+ if(m_ProxyHandler->ReInit(NULL) != S_OK)
+ return NFileOperationReturnCode::kError;
+ */
+
+ ////////////////////////////
+ // Restore FolderItem;
+
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ for (i = 0; i < aPathVector.Size(); i++)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(aPathVector[i], &newFolder);
+ if(!newFolder )
+ break;
+ _folder = newFolder;
+ }
+
+ /*
+ if(moveMode != 0)
+ {
+ for(int i = 0; i < numItems; i++)
+ {
+ const PluginPanelItem &aPluginPanelItem = panelItems[i];
+ bool result;
+ if(NFile::NFind::NAttributes::IsDirectory(aPluginPanelItem.FindData.dwFileAttributes))
+ result = NFile::NDirectory::RemoveDirectoryWithSubItems(
+ aPluginPanelItem.FindData.cFileName);
+ else
+ result = NFile::NDirectory::DeleteFileAlways(
+ aPluginPanelItem.FindData.cFileName);
+ if(!result)
+ return NFileOperationReturnCode::kError;
+ }
+ }
+ */
+ return NFileOperationReturnCode::kSuccess;
+}
+
+
+
+/*
+// {23170F69-40C1-278A-1000-000100030000}
+DEFINE_GUID(CLSID_CAgentArchiveHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
+*/
+
+HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
+{
+ if (pluginPanelItems.Size() == 0)
+ return E_FAIL;
+
+ UStringVector fileNames;
+ for(int i = 0; i < pluginPanelItems.Size(); i++)
+ {
+ const PluginPanelItem &panelItem = pluginPanelItems[i];
+ CSysString fullName;
+ if (strcmp(panelItem.FindData.cFileName, "..") == 0 &&
+ NFind::NAttributes::IsDirectory(panelItem.FindData.dwFileAttributes))
+ return E_FAIL;
+ if (strcmp(panelItem.FindData.cFileName, ".") == 0 &&
+ NFind::NAttributes::IsDirectory(panelItem.FindData.dwFileAttributes))
+ return E_FAIL;
+ if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName))
+ return E_FAIL;
+ fileNames.Add(MultiByteToUnicodeString(fullName, CP_OEMCP));
+ }
+
+ NCompression::CInfo compressionInfo;
+ // CZipRegistryManager aZipRegistryManager;
+ ReadCompressionInfo(compressionInfo);
+
+ int archiverIndex = 0;
+
+ CObjectVector<CArchiverInfo> archiverInfoList;
+ {
+ CObjectVector<CArchiverInfo> fullArchiverInfoList;
+ ReadArchiverInfoList(fullArchiverInfoList);
+ for (int i = 0; i < fullArchiverInfoList.Size(); i++)
+ {
+ const CArchiverInfo &archiverInfo = fullArchiverInfoList[i];
+ if (archiverInfo.UpdateEnabled)
+ {
+ if (archiverInfo.Name.CompareNoCase(compressionInfo.ArchiveType) == 0)
+ archiverIndex = archiverInfoList.Size();
+ archiverInfoList.Add(archiverInfo);
+ }
+ }
+ }
+ if (archiverInfoList.IsEmpty())
+ throw "There is no update achivers";
+
+
+ UString resultPath;
+ {
+ NName::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 CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex];
+ int prevFormat = archiverIndex;
+
+ if (!archiverInfo.KeepName)
+ {
+ int dotPos = archiveName.ReverseFind('.');
+ int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/'));
+ if (dotPos > slashPos)
+ archiveName = archiveName.Left(dotPos);
+ }
+ archiveName += L'.';
+ archiveName += archiverInfo.GetMainExtension();
+
+ 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 CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex];
+
+ char updateAddToArchiveString[512];
+ sprintf(updateAddToArchiveString,
+ g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), GetSystemString(archiverInfo.Name), CP_OEMCP);
+
+ int methodIndex = 0;
+ for (int 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)
+ {
+ CSysStringVector archiverNames;
+ for(int i = 0; i < archiverInfoList.Size(); i++)
+ archiverNames.Add(GetSystemString(archiverInfoList[i].Name,
+ CP_OEMCP));
+
+ int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT,
+ g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle),
+ NULL, archiverNames, archiverIndex);
+ if(index >= 0)
+ {
+ const CArchiverInfo &prevArchiverInfo = archiverInfoList[prevFormat];
+ if (prevArchiverInfo.KeepName)
+ {
+ const UString &prevExtension = prevArchiverInfo.GetMainExtension();
+ const int prevExtensionLen = prevExtension.Length();
+ if (archiveName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0)
+ {
+ int pos = archiveName.Length() - prevExtensionLen;
+ UString temp = archiveName.Left(pos);
+ if (pos > 1)
+ {
+ int dotPos = archiveName.ReverseFind('.');
+ if (dotPos == pos - 1)
+ archiveName = archiveName.Left(dotPos);
+ }
+ }
+ }
+
+ archiverIndex = index;
+ const CArchiverInfo &archiverInfo =
+ archiverInfoList[archiverIndex];
+ prevFormat = archiverIndex;
+
+ if (archiverInfo.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 += archiverInfo.GetMainExtension();
+ }
+ continue;
+ }
+
+ if (askCode != kOkButtonIndex)
+ return E_ABORT;
+
+ break;
+ }
+
+ const CArchiverInfo &archiverInfoFinal = archiverInfoList[archiverIndex];
+ compressionInfo.ArchiveType = archiverInfoFinal.Name;
+ SaveCompressionInfo(compressionInfo);
+
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+
+ UString fullArchiveName;
+ if (!MyGetFullPathName(archiveName, fullArchiveName))
+ return E_FAIL;
+
+ UString workDir = GetWorkDir(workDirInfo, fullArchiveName);
+ CreateComplexDirectory(workDir);
+
+ CTempFileW tempFile;
+ UString tempFileName;
+ if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
+ return E_FAIL;
+
+
+ CScreenRestorer screenRestorer;
+ CProgressBox progressBox;
+ CProgressBox *progressBoxPointer = NULL;
+
+ screenRestorer.Save();
+
+ progressBoxPointer = &progressBox;
+ progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kUpdating), 1 << 16);
+
+
+ NFind::CFileInfoW fileInfo;
+
+ CMyComPtr<IOutFolderArchive> outArchive;
+
+ CMyComPtr<IInFolderArchive> archiveHandler;
+ if(NFind::FindFile(fullArchiveName, fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ throw "There is Directory with such name";
+
+ CAgent *agentSpec = new CAgent;
+ archiveHandler = agentSpec;
+ // CLSID realClassID;
+ CMyComBSTR archiveType;
+ RINOK(agentSpec->Open(
+ GetUnicodeString(fullArchiveName, CP_OEMCP),
+ // &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);
+ // CSysString aCurrentFolder;
+ // MyGetCurrentDirectory(aCurrentFolder);
+ // outArchive->SetFiles(MultiByteToUnicodeString(aCurrentFolder, CP_OEMCP),
+ outArchive->SetFiles(L"",
+ &fileNamePointers.Front(), fileNamePointers.Size());
+ BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
+ for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ actionSetByte[i] = actionSet->StateActions[i];
+
+ CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->Init(archiveHandler, &progressBox);
+
+
+ RINOK(SetOutProperties(outArchive, compressionInfo.Level));
+
+ HRESULT result = outArchive->DoOperation(
+ GetUnicodeString(archiverInfoFinal.FilePath, CP_OEMCP),
+ &archiverInfoFinal.ClassID,
+ tempFileName, actionSetByte,
+ NULL, updateCallback);
+ updateCallback.Release();
+ outArchive.Release();
+
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return result;
+ }
+
+ if(archiveHandler)
+ {
+ archiveHandler->Close();
+ if (!DeleteFileAlways(fullArchiveName))
+ {
+ ShowLastErrorMessage();
+ return NFileOperationReturnCode::kError;
+ }
+ }
+ tempFile.DisableDeleting();
+ if (!MyMoveFile(tempFileName, fullArchiveName))
+ {
+ ShowLastErrorMessage();
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+