mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 11:14:58 -06:00
781 lines
24 KiB
C++
Executable File
781 lines
24 KiB
C++
Executable File
// PluginWrite.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "Plugin.h"
|
|
|
|
#include "Common/Wildcard.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;
|
|
compressionInfo.Load();
|
|
|
|
int methodIndex = 0;
|
|
int i;
|
|
for (i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--)
|
|
if (compressionInfo.Level >= g_MethodMap[i])
|
|
{
|
|
methodIndex = i;
|
|
break;
|
|
}
|
|
|
|
const int kMethodRadioIndex = 2;
|
|
const int kModeRadioIndex = kMethodRadioIndex + 7;
|
|
|
|
struct CInitDialogItem initItems[]={
|
|
{ DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL },
|
|
{ DI_SINGLEBOX, 4, 2, kXMid - 2, 2 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL },
|
|
{ DI_RADIOBUTTON, 6, 3, 0, 0, methodIndex == 0, methodIndex == 0,
|
|
DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL },
|
|
{ DI_RADIOBUTTON, 6, 4, 0, 0, methodIndex == 1, methodIndex == 1,
|
|
0, false, NMessageID::kUpdateMethodFastest, NULL, NULL },
|
|
{ DI_RADIOBUTTON, 6, 5, 0, 0, methodIndex == 2, methodIndex == 2,
|
|
0, false, NMessageID::kUpdateMethodFast, NULL, NULL },
|
|
{ DI_RADIOBUTTON, 6, 6, 0, 0, methodIndex == 3, methodIndex == 3,
|
|
0, false, NMessageID::kUpdateMethodNormal, NULL, NULL },
|
|
{ DI_RADIOBUTTON, 6, 7, 0, 0, methodIndex == 4, methodIndex == 4,
|
|
0, false, NMessageID::kUpdateMethodMaximum, NULL, NULL },
|
|
{ DI_RADIOBUTTON, 6, 8, 0, 0, methodIndex == 5, methodIndex == 5,
|
|
0, false, NMessageID::kUpdateMethodUltra, NULL, NULL },
|
|
|
|
{ DI_SINGLEBOX, kXMid, 2, 70, 2 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL },
|
|
{ DI_RADIOBUTTON, kXMid + 2, 3, 0, 0, false, true,
|
|
DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL },
|
|
{ DI_RADIOBUTTON, kXMid + 2, 4, 0, 0, false, false,
|
|
0, false, NMessageID::kUpdateModeUpdate, NULL, NULL },
|
|
{ DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, false,
|
|
0, false, NMessageID::kUpdateModeFreshen, NULL, NULL },
|
|
{ DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, false,
|
|
0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL },
|
|
|
|
{ DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL },
|
|
|
|
{ DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL },
|
|
{ DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL }
|
|
};
|
|
|
|
const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
|
|
const int kOkButtonIndex = kNumDialogItems - 2;
|
|
FarDialogItem dialogItems[kNumDialogItems];
|
|
g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
|
|
int askCode = g_StartupInfo.ShowDialog(76, kYSize,
|
|
kHelpTopic, dialogItems, kNumDialogItems);
|
|
if (askCode != kOkButtonIndex)
|
|
return NFileOperationReturnCode::kInterruptedByUser;
|
|
|
|
compressionInfo.Level = g_MethodMap[0];
|
|
for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++)
|
|
if (dialogItems[kMethodRadioIndex + i].Selected)
|
|
compressionInfo.Level = g_MethodMap[i];
|
|
|
|
const CActionSet *actionSet;
|
|
|
|
if (dialogItems[kModeRadioIndex].Selected)
|
|
actionSet = &kAddActionSet;
|
|
else if (dialogItems[kModeRadioIndex + 1].Selected)
|
|
actionSet = &kUpdateActionSet;
|
|
else if (dialogItems[kModeRadioIndex + 2].Selected)
|
|
actionSet = &kFreshActionSet;
|
|
else if (dialogItems[kModeRadioIndex + 3].Selected)
|
|
actionSet = &kSynchronizeActionSet;
|
|
else
|
|
throw 51751;
|
|
|
|
compressionInfo.Save();
|
|
|
|
NWorkDir::CInfo workDirInfo;
|
|
workDirInfo.Load();
|
|
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), 48);
|
|
}
|
|
|
|
////////////////////////////
|
|
// 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] = (BYTE)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->DoOperation2(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::IsDir(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;
|
|
}
|
|
|
|
namespace NPathType
|
|
{
|
|
enum EEnum
|
|
{
|
|
kLocal,
|
|
kUNC
|
|
};
|
|
EEnum GetPathType(const UString &path);
|
|
}
|
|
|
|
struct CParsedPath
|
|
{
|
|
UString Prefix; // Disk or UNC with slash
|
|
UStringVector PathParts;
|
|
void ParsePath(const UString &path);
|
|
UString MergePath() const;
|
|
};
|
|
|
|
static const wchar_t kDirDelimiter = WCHAR_PATH_SEPARATOR;
|
|
static const wchar_t kDiskDelimiter = L':';
|
|
|
|
namespace NPathType
|
|
{
|
|
EEnum GetPathType(const UString &path)
|
|
{
|
|
if (path.Length() <= 2)
|
|
return kLocal;
|
|
if (path[0] == kDirDelimiter && path[1] == kDirDelimiter)
|
|
return kUNC;
|
|
return kLocal;
|
|
}
|
|
}
|
|
|
|
void CParsedPath::ParsePath(const UString &path)
|
|
{
|
|
int curPos = 0;
|
|
switch (NPathType::GetPathType(path))
|
|
{
|
|
case NPathType::kLocal:
|
|
{
|
|
int posDiskDelimiter = path.Find(kDiskDelimiter);
|
|
if(posDiskDelimiter >= 0)
|
|
{
|
|
curPos = posDiskDelimiter + 1;
|
|
if (path.Length() > curPos)
|
|
if(path[curPos] == kDirDelimiter)
|
|
curPos++;
|
|
}
|
|
break;
|
|
}
|
|
case NPathType::kUNC:
|
|
{
|
|
int curPos = path.Find(kDirDelimiter, 2);
|
|
if(curPos < 0)
|
|
curPos = path.Length();
|
|
else
|
|
curPos++;
|
|
}
|
|
}
|
|
Prefix = path.Left(curPos);
|
|
SplitPathToParts(path.Mid(curPos), PathParts);
|
|
}
|
|
|
|
UString CParsedPath::MergePath() const
|
|
{
|
|
UString result = Prefix;
|
|
for(int i = 0; i < PathParts.Size(); i++)
|
|
{
|
|
if (i != 0)
|
|
result += kDirDelimiter;
|
|
result += PathParts[i];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/*
|
|
// {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;
|
|
int i;
|
|
for(i = 0; i < pluginPanelItems.Size(); i++)
|
|
{
|
|
const PluginPanelItem &panelItem = pluginPanelItems[i];
|
|
CSysString fullName;
|
|
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;
|
|
if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName))
|
|
return E_FAIL;
|
|
fileNames.Add(MultiByteToUnicodeString(fullName, CP_OEMCP));
|
|
}
|
|
|
|
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 = GetSystemString(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();
|
|
|
|
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), 48);
|
|
|
|
|
|
NFind::CFileInfoW 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);
|
|
// 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] = (BYTE)actionSet->StateActions[i];
|
|
|
|
CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
|
|
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
|
|
|
|
updateCallbackSpec->Init(/* archiveHandler, */ &progressBox);
|
|
|
|
|
|
RINOK(SetOutProperties(outArchive, compressionInfo.Level));
|
|
|
|
HRESULT result = outArchive->DoOperation(
|
|
codecs, archiverIndex,
|
|
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;
|
|
}
|
|
|