This commit is contained in:
Igor Pavlov
2005-05-30 00:00:00 +00:00
committed by Kornel Lesiński
parent 8c1b5c7b7e
commit 3c510ba80b
926 changed files with 40559 additions and 23519 deletions

View File

@@ -1,636 +0,0 @@
// Compress.cpp
#include "StdAfx.h"
#include <mapi.h>
#include "Compress.h"
#include "CompressDialog.h"
#include "resource.h"
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
#include "Windows/FileName.h"
#include "Windows/FileFind.h"
#include "Windows/FileDir.h"
#include "Windows/Thread.h"
#include "Windows/COM.h"
#include "Windows/PropVariant.h"
#include "../../FileManager/ProgramLocation.h"
#include "../../FileManager/FormatUtils.h"
#include "../../FileManager/UpdateCallback100.h"
#include "../Agent/Agent.h"
#include "../Common/UpdateAction.h"
#include "../Common/WorkDir.h"
#include "../Common/ZipRegistry.h"
#include "../Common/OpenArchive.h"
#include "../Resource/Extract/resource.h"
#include "../Explorer/MyMessages.h"
using namespace NWindows;
using namespace NFile;
using namespace NDirectory;
using namespace NName;
static LPCWSTR kTempArchivePrefix = L"7zA";
static LPCWSTR kTempFolderPrefix = L"7zE";
static LPCWSTR kDefaultSfxModule = L"7zC.sfx";
static void SplitString(const UString &srcString, UStringVector &destStrings)
{
destStrings.Clear();
for (int pos = 0; pos < srcString.Length();)
{
int spacePos = srcString.Find(L' ', pos);
if (spacePos < 0)
{
destStrings.Add(srcString.Mid(pos));
return;
}
if (spacePos != pos)
destStrings.Add(srcString.Mid(pos, spacePos - pos));
pos = spacePos + 1;
}
}
static bool ParseNumberString(const UString &string, UINT32 &number)
{
wchar_t *endPtr;
number = wcstoul(string, &endPtr, 10);
return (endPtr - string == string.Length());
}
static void SetOptions(const UString &options,
CObjectVector<CMyComBSTR> &realNames,
std::vector<NCOM::CPropVariant> &values)
{
UStringVector strings;
SplitString(options, strings);
for(int i = 0; i < strings.Size(); i++)
{
const UString &s = strings[i];
int index = s.Find(L'=');
CMyComBSTR name;
NCOM::CPropVariant propVariant;
if (index < 0)
name = s;
else
{
name = s.Left(index);
UString value = s.Mid(index + 1);
if (!value.IsEmpty())
{
UINT32 number;
if (ParseNumberString(value, number))
propVariant = number;
else
propVariant = value;
}
}
realNames.Add(name);
values.push_back(propVariant);
}
}
static HRESULT SetOutProperties(IOutFolderArchive * outArchive,
bool is7z,
UINT32 level,
const UString &method,
UINT32 dictionary,
bool orderMode,
UINT32 order,
bool solidModeIsAllowed, bool solidMode,
bool multiThreadIsAllowed, bool multiThread,
bool encryptHeadersIsAllowed, bool encryptHeaders,
bool sfxMode,
const UString &options)
{
CMyComPtr<ISetProperties> setProperties;
if (outArchive->QueryInterface(&setProperties) == S_OK)
{
CObjectVector<CMyComBSTR> realNames;
std::vector<NCOM::CPropVariant> values;
if (level != (UINT32)(INT32)-1)
{
CMyComBSTR comBSTR = L"x";
realNames.Add(comBSTR);
values.push_back(NCOM::CPropVariant((UINT32)level));
}
if (!method.IsEmpty())
{
CMyComBSTR comBSTR;
if (is7z)
comBSTR = L"0";
else
comBSTR = L"m";
realNames.Add(comBSTR);
values.push_back(NCOM::CPropVariant(method));
}
if (dictionary != (UINT32)(INT32)-1)
{
CMyComBSTR comBSTR;
if (is7z)
if (orderMode)
comBSTR = L"0mem";
else
comBSTR = L"0d";
else
if (orderMode)
comBSTR = L"mem";
else
comBSTR = L"d";
realNames.Add(comBSTR);
wchar_t s[32];
ConvertUINT64ToString(dictionary, s);
wcscat(s, L"B");
values.push_back(NCOM::CPropVariant(s));
}
if (order != (UINT32)(INT32)-1)
{
CMyComBSTR comBSTR;
if (is7z)
if (orderMode)
comBSTR = L"0o";
else
comBSTR = L"0fb";
else
if (orderMode)
comBSTR = L"o";
else
comBSTR = L"fb";
realNames.Add(comBSTR);
values.push_back(NCOM::CPropVariant((UINT32)order));
}
if (sfxMode)
{
realNames.Add(L"rsfx");
values.push_back(NCOM::CPropVariant(L"on"));
}
if (encryptHeadersIsAllowed)
{
if (encryptHeaders)
{
realNames.Add(L"he");
values.push_back(NCOM::CPropVariant(L"on"));
}
}
// Solid
if (solidModeIsAllowed)
{
realNames.Add(L"s");
values.push_back(NCOM::CPropVariant(solidMode ? L"on": L"off"));
}
if (multiThreadIsAllowed)
{
realNames.Add(L"mt");
values.push_back(NCOM::CPropVariant(multiThread ? L"on": L"off"));
}
// Options
SetOptions(options, realNames, values);
std::vector<BSTR> names;
for(int i = 0; i < realNames.Size(); i++)
names.push_back(realNames[i]);
RINOK(setProperties->SetProperties(&names.front(),
&values.front(), names.size()));
}
return S_OK;
}
struct CThreadUpdateCompress
{
CMyComPtr<IOutFolderArchive> OutArchive;
UString LibPath;
CLSID ClassID;
UString OutArchivePath;
BYTE ActionSetByte[NUpdateArchive::NPairState::kNumValues];
bool SfxMode;
UString SfxModule;
UStringVector FileNames;
CRecordVector<const wchar_t *> FileNamePointers;
CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
CUpdateCallback100Imp *UpdateCallbackSpec;
HRESULT Result;
DWORD Process()
{
NCOM::CComInitializer comInitializer;
UpdateCallbackSpec->ProgressDialog.WaitCreating();
try
{
Result = OutArchive->DoOperation(
LibPath, &ClassID,
OutArchivePath, ActionSetByte,
(SfxMode ? (const wchar_t *)SfxModule: NULL),
UpdateCallback);
}
catch(const UString &s)
{
MyMessageBox(s);
Result = E_FAIL;
}
catch(...)
{
Result = E_FAIL;
}
UpdateCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadUpdateCompress *)param)->Process();
}
};
static UString MakeFullArchiveName(const UString &name,
const UString &extension, bool sfx)
{
if (sfx)
{
UString sfxExt = L".exe";
if (sfxExt.CollateNoCase(name.Right(sfxExt.Length())) == 0)
return name;
return name + sfxExt;
}
if (extension.IsEmpty())
return name;
if (name.IsEmpty())
return name;
if (name[name.Length() - 1] == '.')
return name.Left(name.Length() - 1);
int slash1Pos = name.ReverseFind(L'\\');
int slash2Pos = name.ReverseFind(L'/');
int slashPos = MyMax(slash1Pos, slash2Pos);
int dotPos = name.ReverseFind(L'.');
if (dotPos >= 0 && (dotPos > slashPos || slashPos < 0))
return name;
return name + UString(L'.') + extension;
}
HRESULT CompressArchive(
const UString &archivePath,
const UStringVector &fileNames,
const UString &archiveType,
bool email,
bool showDialog)
{
if (fileNames.Size() == 0)
return S_OK;
CObjectVector<CArchiverInfo> archivers;
ReadArchiverInfoList(archivers);
CArchiverInfo archiverInfo;
UString password;
bool encryptHeadersIsAllowed = false;
bool encryptHeaders = false;
const NUpdateArchive::CActionSet *actionSet;
NCompressDialog::CInfo compressInfo;
UString tempDirPath;
UString currentDirPrefix;
bool needTempFile = true;
NDirectory::CTempDirectoryW tempDirectory;
UString archiveName;
int pos = archivePath.ReverseFind(L'\\');
if (pos < 0)
{
archiveName = archivePath;
MyGetCurrentDirectory(currentDirPrefix);
}
else
{
currentDirPrefix = archivePath.Left(pos + 1);
archiveName = archivePath.Mid(pos + 1);
}
if (email)
{
tempDirectory.Create(kTempFolderPrefix);
currentDirPrefix = tempDirectory.GetPath();
NormalizeDirPathPrefix(currentDirPrefix);
needTempFile = false;
}
if (showDialog)
{
bool oneFile = false;
NFind::CFileInfoW fileInfo;
if (!NFind::FindFile(fileNames.Front(), fileInfo))
return ::GetLastError();
if (fileNames.Size() == 1)
oneFile = !fileInfo.IsDirectory();
CCompressDialog dialog;
for(int i = 0; i < archivers.Size(); i++)
{
const CArchiverInfo &archiverInfo = archivers[i];
if (archiverInfo.UpdateEnabled &&
(oneFile || !archiverInfo.KeepName))
dialog.m_ArchiverInfoList.Add(archiverInfo);
}
if(dialog.m_ArchiverInfoList.Size() == 0)
{
MyMessageBox(L"No Update Engines");
return E_FAIL;
}
dialog.m_Info.ArchiveName = archiveName;
dialog.OriginalFileName = fileInfo.Name;
dialog.m_Info.CurrentDirPrefix = currentDirPrefix;
dialog.m_Info.SFXMode = false;
dialog.m_Info.Solid = true;
dialog.m_Info.MultiThread = false;
dialog.m_Info.KeepName = !oneFile;
if(dialog.Create(0) != IDOK)
return S_OK;
if (dialog.m_Info.VolumeSizeIsDefined)
{
MyMessageBox(L"Splitting to volumes is not supported");
return E_FAIL;
}
switch(dialog.m_Info.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;
}
archiverInfo = dialog.m_ArchiverInfoList[dialog.m_Info.ArchiverInfoIndex];
password = GetUnicodeString(dialog.Password);
encryptHeadersIsAllowed = dialog.EncryptHeadersIsAllowed;
encryptHeaders = dialog.EncryptHeaders;
compressInfo = dialog.m_Info;
compressInfo.ArchiveName = MakeFullArchiveName(
compressInfo.ArchiveName,
archiverInfo.GetMainExtension(), compressInfo.SFXMode);
}
else
{
int i;
for(i = 0; i < archivers.Size(); i++)
{
if (archivers[i].Name.CollateNoCase(archiveType) == 0)
{
archiverInfo = archivers[i];
break;
}
}
if (i == archivers.Size())
{
MyMessageBox(L"No archiver");
return E_FAIL;
}
actionSet = &NUpdateArchive::kAddActionSet;
bool is7z = (archiveType.CollateNoCase(L"7z") == 0);
compressInfo.SolidIsAllowed = is7z;
compressInfo.Solid = true;
compressInfo.MultiThreadIsAllowed = is7z;
compressInfo.MultiThread = false;
compressInfo.SFXMode = false;
compressInfo.KeepName = false;
compressInfo.ArchiveName = archiveName;
compressInfo.CurrentDirPrefix = currentDirPrefix;
compressInfo.Level = 5;
}
UString arcPath;
if (!compressInfo.GetFullPathName(arcPath))
{
MyMessageBox(L"Incorrect archive path");
return E_FAIL;
}
if (compressInfo.ArchiveName.Find('\\') >= 0)
{
needTempFile = true;
}
// MessageBox(0, arcPath, 0, 0);
NWorkDir::CInfo workDirInfo;
ReadWorkDirInfo(workDirInfo);
UString workDir = GetWorkDir(workDirInfo, arcPath);
NFile::NDirectory::CreateComplexDirectory(workDir);
NFile::NDirectory::CTempFileW tempFile;
UString tempFileName;
if (needTempFile)
{
if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0)
return E_FAIL;
}
else
tempFileName = arcPath;
/*
const CLSID &classID =
dialog.m_ArchiverInfoList[dialog.m_Info.ArchiverInfoIndex].ClassID;
*/
NFind::CFileInfoW fileInfo;
CMyComPtr<IOutFolderArchive> outArchive;
CMyComPtr<IInFolderArchive> archiveHandler;
if(NFind::FindFile(arcPath, fileInfo))
{
if (fileInfo.IsDirectory())
{
MyMessageBox(L"There is a folder with such name");
return E_FAIL;
}
CAgent *agentSpec = new CAgent;
archiveHandler = agentSpec;
// CLSID realClassID;
CMyComBSTR archiveType;
HRESULT result = agentSpec->Open(
GetUnicodeString(arcPath), &archiveType, NULL);
if (result == S_FALSE)
{
MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
return E_FAIL;
}
/*
HRESULT result = OpenArchive(arcPath, &archiveHandler,
archiverInfoResult, defaultName, NULL);
if (result == S_FALSE)
{
MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
return E_FAIL;
}
*/
if (result != S_OK)
{
MyMessageBox(L"Open error");
return E_FAIL;
}
if (archiverInfo.Name.CollateNoCase((const wchar_t *)archiveType) != 0)
{
MyMessageBox(L"Type of existing archive differs from specified type");
return E_FAIL;
}
result = archiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive);
if(result != S_OK)
{
MyMessageBox(MyFormatNew(IDS_CANT_UPDATE_ARCHIVE, 0x02000602,
GetUnicodeString(arcPath)));
return E_FAIL;
}
}
else
{
CAgent *agentSpec = new CAgent;
outArchive = agentSpec;
}
CRecordVector<const wchar_t *> fileNamePointers;
fileNamePointers.Reserve(fileNames.Size());
int i;
for(i = 0; i < fileNames.Size(); i++)
fileNamePointers.Add(fileNames[i]);
outArchive->SetFolder(NULL);
// Don't uses CurrentFolder here, since files are absolute paths;
// MyGetCurrentDirectory(aCurrentFolder);
UINT codePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
outArchive->SetFiles(L"",
&fileNamePointers.Front(), fileNamePointers.Size());
CThreadUpdateCompress updater;
for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
updater.ActionSetByte[i] = actionSet->StateActions[i];
updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
updater.UpdateCallback = updater.UpdateCallbackSpec;
updater.OutArchive = outArchive;
// updater.SrcFolderPrefix = srcPanel._currentFolderPrefix;
UString title = LangLoadStringW(IDS_PROGRESS_COMPRESSING, 0x02000DC0);
updater.UpdateCallbackSpec->Init(0, !password.IsEmpty(), password);
// UINT32 level = MyMin(compressInfo.Level, UINT32(9));
UINT32 level = compressInfo.Level;
HRESULT result = SetOutProperties(outArchive,
archiverInfo.Name.CompareNoCase(L"7z") == 0,
level,
compressInfo.Method,
compressInfo.Dictionary,
compressInfo.OrderMode, compressInfo.Order,
compressInfo.SolidIsAllowed, compressInfo.Solid,
compressInfo.MultiThreadIsAllowed, compressInfo.MultiThread,
encryptHeadersIsAllowed, encryptHeaders,
compressInfo.SFXMode,
GetUnicodeString(compressInfo.Options));
if (result != S_OK)
{
if (result != E_ABORT)
ShowErrorMessage(result);
return result;
}
UString sfxModule;
if (compressInfo.SFXMode)
{
UString sfxModule2;
LPCWSTR path = NULL;
UString sfxModule3;
if (GetProgramFolderPath(sfxModule3))
path = sfxModule3;
if (!NDirectory::MySearchPath(path, kDefaultSfxModule, NULL, sfxModule2))
{
MyMessageBox(L"can't find sfx module");
return E_FAIL;
}
sfxModule = sfxModule2;
}
updater.OutArchivePath = GetUnicodeString(tempFileName, codePage);
updater.SfxMode = compressInfo.SFXMode;
updater.SfxModule = sfxModule;
updater.LibPath = GetUnicodeString(archiverInfo.FilePath);
updater.ClassID = archiverInfo.ClassID;
CThread thread;
if (!thread.Create(CThreadUpdateCompress::MyThreadFunction, &updater))
throw 271824;
updater.UpdateCallbackSpec->StartProgressDialog(title);
result = updater.Result;
updater.UpdateCallback.Release();
updater.OutArchive.Release();
outArchive.Release();
if (result != S_OK)
{
if (result != E_ABORT)
ShowErrorMessage(result);
return result;
}
if(archiveHandler)
{
archiveHandler->Close();
if (!DeleteFileAlways(arcPath))
{
ShowLastErrorMessage();
return E_FAIL;
}
}
if (needTempFile)
{
tempFile.DisableDeleting();
if (!NDirectory::MyMoveFile(tempFileName, arcPath))
{
ShowLastErrorMessage();
return E_FAIL;
}
}
if (email)
{
NDLL::CLibrary mapiLib;
if (!mapiLib.Load(TEXT("Mapi32.dll")))
return E_FAIL;
LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)
mapiLib.GetProcAddress("MAPISendDocuments");
if (fnSend == 0)
return E_FAIL;
UString fileName;
GetOnlyName(arcPath, fileName);
AString path = GetAnsiString(arcPath);
AString name = GetAnsiString(fileName);
fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
}
return S_OK;
}

View File

@@ -1,17 +0,0 @@
// GUI/Compress.h
#pragma once
#ifndef __GUI_COMPRESS_H
#define __GUI_COMPRESS_H
#include "Common/String.h"
HRESULT CompressArchive(
const UString &archivePath,
const UStringVector &fileNames,
const UString &archiveType,
bool email,
bool showDialog);
#endif

View File

@@ -5,13 +5,14 @@
#include "resource.h"
#include "Common/Defs.h"
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"
#include "Common/IntToString.h"
#include "Windows/FileDir.h"
#include "Windows/FileName.h"
#include "Windows/ResourceString.h"
#include "../../FileManager/HelpUtils.h"
#include "../../FileManager/SplitUtils.h"
#include "../Common/ZipRegistry.h"
#include "CompressDialog.h"
@@ -63,8 +64,8 @@ static LPCWSTR k7zFormat = L"7z";
struct CLevelInfo
{
UINT32 ResourceID;
UINT32 LangID;
UInt32 ResourceID;
UInt32 LangID;
};
enum ELevel
@@ -115,8 +116,14 @@ static const EMethodID g_7zMethods[] =
{
kLZMA,
kPPMd,
kBZip2,
kDeflate
kBZip2
};
static const EMethodID g_7zSfxMethods[] =
{
kCopy,
kLZMA,
kPPMd
};
static EMethodID g_ZipMethods[] =
@@ -139,7 +146,7 @@ static EMethodID g_BZip2Methods[] =
struct CFormatInfo
{
LPCWSTR Name;
UINT32 LevelsMask;
UInt32 LevelsMask;
const EMethodID *MathodIDs;
int NumMethods;
bool Solid;
@@ -177,7 +184,7 @@ static const CFormatInfo g_Formats[] =
},
{
L"BZip2",
(1 << 5),
(1 << 5) | (1 << 7) | (1 << 9),
g_BZip2Methods,
MY_SIZE_OF_ARRAY(g_BZip2Methods),
false, false, false, false, false
@@ -190,6 +197,14 @@ static const CFormatInfo g_Formats[] =
}
};
static bool IsMethodSupportedBySfx(int methodID)
{
for (int i = 0; i < MY_SIZE_OF_ARRAY(g_7zSfxMethods); i++)
if (methodID == g_7zSfxMethods[i])
return true;
return false;
};
class CDoubleZeroStringList
{
CRecordVector<int> m_Indexes;
@@ -222,7 +237,7 @@ bool CCompressDialog::OnInit()
LangSetDlgItemsText(HWND(*this), kIDLangPairs, MY_SIZE_OF_ARRAY(kIDLangPairs) );
#endif
_passwordControl.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD));
_passwordControl.SetText(TEXT(""));
_passwordControl.SetText(Info.Password);
m_ArchivePath.Attach(GetItem(IDC_COMPRESS_COMBO_ARCHIVE));
m_Format.Attach(GetItem(IDC_COMPRESS_COMBO_FORMAT));
@@ -235,9 +250,7 @@ bool CCompressDialog::OnInit()
m_Volume.Attach(GetItem(IDC_COMPRESS_COMBO_VOLUME));
m_Params.Attach(GetItem(IDC_COMPRESS_EDIT_PARAMETERS));
m_Volume.AddString(TEXT("1457664 - 3.5 Floppy"));
m_Volume.AddString(TEXT("650M - CD-650MB"));
m_Volume.AddString(TEXT("700M - CD-700MB"));
AddVolumeItems(m_Volume);
ReadCompressionInfo(m_RegistryInfo);
CheckButton(IDC_COMPRESS_CHECK_SHOW_PASSWORD, m_RegistryInfo.ShowPassword);
@@ -245,7 +258,7 @@ bool CCompressDialog::OnInit()
UpdatePasswordControl();
m_Info.ArchiverInfoIndex = 0;
Info.ArchiverInfoIndex = 0;
int i;
for(i = 0; i < m_ArchiverInfoList.Size(); i++)
{
@@ -253,11 +266,11 @@ bool CCompressDialog::OnInit()
m_Format.AddString(GetSystemString(ai.Name));
if (ai.Name.CollateNoCase(
m_RegistryInfo.ArchiveType) == 0)
m_Info.ArchiverInfoIndex = i;
Info.ArchiverInfoIndex = i;
}
m_Format.SetCurSel(m_Info.ArchiverInfoIndex);
m_Format.SetCurSel(Info.ArchiverInfoIndex);
SetArchiveName(m_Info.ArchiveName);
SetArchiveName(Info.ArchiveName);
SetLevel();
SetParams();
@@ -271,12 +284,12 @@ bool CCompressDialog::OnInit()
m_UpdateMode.SetCurSel(0);
m_Info.Solid = m_RegistryInfo.Solid;
m_Info.MultiThread = m_RegistryInfo.MultiThread;
Info.Solid = m_RegistryInfo.Solid;
Info.MultiThread = m_RegistryInfo.MultiThread;
CheckButton(IDC_COMPRESS_SOLID, m_Info.Solid);
CheckButton(IDC_COMPRESS_MULTI_THREAD, m_Info.MultiThread);
CheckButton(IDC_COMPRESS_SFX, m_Info.SFXMode);
CheckButton(IDC_COMPRESS_SOLID, Info.Solid);
CheckButton(IDC_COMPRESS_MULTI_THREAD, Info.MultiThread);
CheckButton(IDC_COMPRESS_SFX, Info.SFXMode);
CheckControlsEnable();
@@ -339,16 +352,8 @@ void CCompressDialog::CheckSFXControlsEnable()
bool enable = fi.SFX;
if (enable)
{
switch(GetMethodID())
{
case -1:
case kLZMA:
case kPPMd:
case kCopy:
break;
default:
enable = false;
}
int methodID = GetMethodID();
enable = (methodID == -1 || IsMethodSupportedBySfx(methodID));
}
if (!enable)
CheckButton(IDC_COMPRESS_SFX, false);
@@ -358,10 +363,10 @@ void CCompressDialog::CheckSFXControlsEnable()
void CCompressDialog::CheckControlsEnable()
{
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
m_Info.SolidIsAllowed = fi.Solid;
Info.SolidIsAllowed = fi.Solid;
bool multiThreadEnable = fi.MultiThread & IsMultiProcessor();
m_Info.MultiThreadIsAllowed = multiThreadEnable;
EncryptHeadersIsAllowed = fi.EncryptFileNames;
Info.MultiThreadIsAllowed = multiThreadEnable;
Info.EncryptHeadersIsAllowed = fi.EncryptFileNames;
EnableItem(IDC_COMPRESS_SOLID, fi.Solid);
EnableItem(IDC_COMPRESS_MULTI_THREAD, multiThreadEnable);
@@ -384,13 +389,16 @@ bool CCompressDialog::IsSFX()
void CCompressDialog::OnButtonSFX()
{
SetMethod();
UString fileName;
m_ArchivePath.GetText(fileName);
int dotPos = fileName.ReverseFind(L'.');
int slashPos = fileName.ReverseFind(L'\\');
if (dotPos < 0 || dotPos <= slashPos)
dotPos = -1;
if (IsSFX())
bool isSFX = IsSFX();
if (isSFX)
{
if (dotPos >= 0)
fileName = fileName.Left(dotPos);
@@ -410,6 +418,10 @@ void CCompressDialog::OnButtonSFX()
}
SetArchiveName2(false); // it's for OnInit
}
m_Volume.Enable(!isSFX);
if (isSFX)
m_Volume.SetText(TEXT(""));
}
void CCompressDialog::OnButtonSetArchive()
@@ -420,11 +432,11 @@ void CCompressDialog::OnButtonSetArchive()
m_ArchivePath.GetText(fileName);
fileName.TrimLeft();
fileName.TrimRight();
m_Info.ArchiveName = fileName;
Info.ArchiveName = fileName;
UString fullFileName;
if (!m_Info.GetFullPathName(fullFileName))
if (!Info.GetFullPathName(fullFileName))
{
fullFileName = m_Info.ArchiveName;
fullFileName = Info.ArchiveName;
// throw "Incorrect archive path";
return;
}
@@ -482,42 +494,10 @@ void CCompressDialog::OnButtonSetArchive()
// in ExtractDialog.cpp
extern void AddUniqueString(CSysStringVector &strings, const CSysString &srcString);
bool ParseVolumeSize(const CSysString &s, UINT64 &value)
{
const TCHAR *start = s;
const TCHAR *end;
value = ConvertStringToUINT64(start, &end);
if (start == end)
return false;
while (true)
{
TCHAR c = *end++;
c = MyCharUpper(c);
switch(c)
{
case TEXT('\0'):
case TEXT('B'):
return true;
case TEXT('K'):
value <<= 10;
return true;
case TEXT('M'):
value <<= 20;
return true;
case TEXT('G'):
value <<= 30;
return true;
case TEXT(' '):
continue;
default:
return true;
}
}
}
void CCompressDialog::OnOK()
{
_passwordControl.GetText(Password);
_passwordControl.GetText(Info.Password);
SaveOptionsInMem();
int currentItem = m_ArchivePath.GetCurSel();
@@ -537,32 +517,33 @@ void CCompressDialog::OnOK()
s.Trim();
m_RegistryInfo.HistoryArchives.Clear();
AddUniqueString(m_RegistryInfo.HistoryArchives, GetSystemString(s));
m_Info.ArchiveName = s;
m_Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel());
Info.ArchiveName = s;
Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel());
m_Info.Level = GetLevelSpec();
m_Info.Dictionary = GetDictionarySpec();
m_Info.Order = GetOrderSpec();
m_Info.OrderMode = GetOrderMode();
m_Info.Method = GetUnicodeString(GetMethodSpec());
Info.Level = GetLevelSpec();
Info.Dictionary = GetDictionarySpec();
Info.Order = GetOrderSpec();
Info.OrderMode = GetOrderMode();
Info.Method = GetUnicodeString(GetMethodSpec());
m_Info.ArchiverInfoIndex = m_Format.GetCurSel();
Info.ArchiverInfoIndex = m_Format.GetCurSel();
m_Info.SFXMode = IsSFX();
m_RegistryInfo.Solid = m_Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID);
m_RegistryInfo.MultiThread = m_Info.MultiThread = IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD);
m_RegistryInfo.EncryptHeaders = EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES);
Info.SFXMode = IsSFX();
m_RegistryInfo.Solid = Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID);
m_RegistryInfo.MultiThread = Info.MultiThread = IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD);
m_RegistryInfo.EncryptHeaders = Info.EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES);
m_Params.GetText(m_Info.Options);
CSysString volumeString;
m_Params.GetText(Info.Options);
UString volumeString;
m_Volume.GetText(volumeString);
volumeString.Trim();
m_Info.VolumeSizeIsDefined = ParseVolumeSize(
volumeString, m_Info.VolumeSize);
/*
if (!m_Info.VolumeSizeIsDefined && !volumeString.IsEmpty())
MessageBox(0, TEXT("Incorrect volume size"), TEXT("7-Zip"), 0);
*/
Info.VolumeSizes.Clear();
if (!volumeString.IsEmpty())
if (!ParseVolumeSizes(volumeString, Info.VolumeSizes))
{
MessageBox(*this, TEXT("Incorrect volume size"), TEXT("7-Zip"), 0);
return;
}
for(int i = 0; i < m_ArchivePath.GetCount(); i++)
if(i != currentItem)
@@ -576,8 +557,8 @@ void CCompressDialog::OnOK()
////////////////////
// Method
m_RegistryInfo.Level = m_Info.Level;
m_RegistryInfo.ArchiveType = m_ArchiverInfoList[m_Info.ArchiverInfoIndex].Name;
m_RegistryInfo.Level = Info.Level;
m_RegistryInfo.ArchiveType = m_ArchiverInfoList[Info.ArchiverInfoIndex].Name;
m_RegistryInfo.ShowPassword = (IsButtonChecked(
IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED);
@@ -646,7 +627,7 @@ void CCompressDialog::SetArchiveName2(bool prevWasSFX)
UString fileName;
m_ArchivePath.GetText(fileName);
const CArchiverInfo &prevArchiverInfo = m_ArchiverInfoList[m_PrevFormat];
if (prevArchiverInfo.KeepName || m_Info.KeepName)
if (prevArchiverInfo.KeepName || Info.KeepName)
{
UString prevExtension = prevArchiverInfo.GetMainExtension();
if (prevWasSFX)
@@ -671,19 +652,23 @@ void CCompressDialog::OnChangeFormat()
SetArchiveName2(isSFX);
}
// if type.KeepName then use OriginalFileName
// else if !KeepName remove extension
// add new extension
void CCompressDialog::SetArchiveName(const UString &name)
{
UString fileName = name;
m_Info.ArchiverInfoIndex = m_Format.GetCurSel();
const CArchiverInfo &ai = m_ArchiverInfoList[m_Info.ArchiverInfoIndex];
m_PrevFormat = m_Info.ArchiverInfoIndex;
Info.ArchiverInfoIndex = m_Format.GetCurSel();
const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex];
m_PrevFormat = Info.ArchiverInfoIndex;
if (ai.KeepName)
{
fileName = OriginalFileName;
}
else
{
if (!m_Info.KeepName)
if (!Info.KeepName)
{
int dotPos = fileName.ReverseFind('.');
int slashPos = MyMax(fileName.ReverseFind('\\'), fileName.ReverseFind('/'));
@@ -736,10 +721,10 @@ int CCompressDialog::GetStaticFormatIndex()
}
void CCompressDialog::SetNearestSelectComboBox(
NControl::CComboBox &comboBox, UINT32 value)
NControl::CComboBox &comboBox, UInt32 value)
{
for (int i = comboBox.GetCount() - 1; i >= 0; i--)
if (comboBox.GetItemData(i) <= value)
if ((UInt32)comboBox.GetItemData(i) <= value)
{
comboBox.SetCurSel(i);
return;
@@ -754,7 +739,7 @@ void CCompressDialog::SetLevel()
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
int index = FindRegistryFormat(ai.Name);
UINT32 level = kNormal;
UInt32 level = kNormal;
if (index >= 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
@@ -817,9 +802,14 @@ void CCompressDialog::SetMethod()
const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
defaultMethod = GetUnicodeString(fo.Method);
}
bool isSfx = IsSFX();
for(int m = 0; m < fi.NumMethods; m++)
{
const LPCWSTR method = kMethodsNames[fi.MathodIDs[m]];
EMethodID methodID = fi.MathodIDs[m];
if (isSfx)
if (!IsMethodSupportedBySfx(methodID))
continue;
const LPCWSTR method = kMethodsNames[methodID];
int itemIndex = m_Method.AddString(GetSystemString(method));
if (defaultMethod.CompareNoCase(method) == 0 || m == 0)
m_Method.SetCurSel(itemIndex);
@@ -848,15 +838,15 @@ CSysString CCompressDialog::GetMethodSpec()
return result;
}
int CCompressDialog::AddDictionarySize(UINT32 size, bool kilo, bool maga)
int CCompressDialog::AddDictionarySize(UInt32 size, bool kilo, bool maga)
{
UINT32 sizePrint = size;
UInt32 sizePrint = size;
if (kilo)
sizePrint >>= 10;
else if (maga)
sizePrint >>= 20;
TCHAR s[40];
ConvertUINT64ToString(sizePrint, s);
ConvertUInt64ToString(sizePrint, s);
if (kilo)
lstrcat(s, TEXT(" K"));
else if (maga)
@@ -869,7 +859,7 @@ int CCompressDialog::AddDictionarySize(UINT32 size, bool kilo, bool maga)
return index;
}
int CCompressDialog::AddDictionarySize(UINT32 size)
int CCompressDialog::AddDictionarySize(UInt32 size)
{
if (size > 0)
{
@@ -887,7 +877,7 @@ void CCompressDialog::SetDictionary()
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
int index = FindRegistryFormat(ai.Name);
UINT32 defaultDictionary = UINT32(-1);
UInt32 defaultDictionary = UInt32(-1);
if (index >= 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
@@ -905,7 +895,7 @@ void CCompressDialog::SetDictionary()
{
case kLZMA:
{
if (defaultDictionary == UINT32(-1))
if (defaultDictionary == UInt32(-1))
{
if (level >= 9)
defaultDictionary = (32 << 20);
@@ -923,7 +913,7 @@ void CCompressDialog::SetDictionary()
{
if (i == 20 && j > 0)
continue;
UINT32 dictionary = (1 << i) + (j << (i - 1));
UInt32 dictionary = (1 << i) + (j << (i - 1));
AddDictionarySize(dictionary);
}
SetNearestSelectComboBox(m_Dictionary, defaultDictionary);
@@ -931,7 +921,7 @@ void CCompressDialog::SetDictionary()
}
case kPPMd:
{
if (defaultDictionary == UINT32(-1))
if (defaultDictionary == UInt32(-1))
{
if (level >= 9)
defaultDictionary = (192 << 20);
@@ -948,7 +938,7 @@ void CCompressDialog::SetDictionary()
{
if (i == 20 && j > 0)
continue;
UINT32 dictionary = (1 << i) + (j << (i - 1));
UInt32 dictionary = (1 << i) + (j << (i - 1));
if (dictionary >= (1 << 31))
continue;
AddDictionarySize(dictionary);
@@ -978,24 +968,24 @@ void CCompressDialog::SetDictionary()
SetMemoryUsage();
}
UINT32 CCompressDialog::GetDictionary()
UInt32 CCompressDialog::GetDictionary()
{
if (m_Dictionary.GetCount() <= 0)
return -1;
return m_Dictionary.GetItemData(m_Dictionary.GetCurSel());
}
UINT32 CCompressDialog::GetDictionarySpec()
UInt32 CCompressDialog::GetDictionarySpec()
{
if (m_Dictionary.GetCount() <= 1)
return -1;
return GetDictionary();
}
int CCompressDialog::AddOrder(UINT32 size)
int CCompressDialog::AddOrder(UInt32 size)
{
TCHAR s[40];
ConvertUINT64ToString(size, s);
ConvertUInt64ToString(size, s);
int index = m_Order.AddString(s);
m_Order.SetItemData(index, size);
return index;
@@ -1007,7 +997,7 @@ void CCompressDialog::SetOrder()
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
int index = FindRegistryFormat(ai.Name);
UINT32 defaultOrder = UINT32(-1);
UInt32 defaultOrder = UInt32(-1);
if (index >= 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
@@ -1025,7 +1015,7 @@ void CCompressDialog::SetOrder()
{
case kLZMA:
{
if (defaultOrder == UINT32(-1))
if (defaultOrder == UInt32(-1))
{
if (level >= 7)
defaultOrder = 64;
@@ -1036,7 +1026,7 @@ void CCompressDialog::SetOrder()
for (i = 3; i < 8; i++)
for (int j = 0; j < 2; j++)
{
UINT32 order = (1 << i) + (j << (i - 1));
UInt32 order = (1 << i) + (j << (i - 1));
if (order < 255)
AddOrder(order);
}
@@ -1046,7 +1036,7 @@ void CCompressDialog::SetOrder()
}
case kPPMd:
{
if (defaultOrder == UINT32(-1))
if (defaultOrder == UInt32(-1))
{
if (level >= 9)
defaultOrder = 32;
@@ -1063,7 +1053,7 @@ void CCompressDialog::SetOrder()
for (i = 2; i < 8; i++)
for (int j = 0; j < 4; j++)
{
UINT32 order = (1 << i) + (j << (i - 2));
UInt32 order = (1 << i) + (j << (i - 2));
if (order < 32)
AddOrder(order);
}
@@ -1074,7 +1064,7 @@ void CCompressDialog::SetOrder()
case kDeflate:
case kDeflate64:
{
if (defaultOrder == UINT32(-1))
if (defaultOrder == UInt32(-1))
{
if (level >= 7)
defaultOrder = 64;
@@ -1085,7 +1075,7 @@ void CCompressDialog::SetOrder()
for (i = 3; i < 8; i++)
for (int j = 0; j < 2; j++)
{
UINT32 order = (1 << i) + (j << (i - 1));
UInt32 order = (1 << i) + (j << (i - 1));
if (order < 255)
AddOrder(order);
}
@@ -1105,34 +1095,30 @@ bool CCompressDialog::GetOrderMode()
{
switch (GetMethodID())
{
case kLZMA:
case kDeflate:
case kDeflate64:
return false;
case kPPMd:
return true;
}
return false;
}
UINT32 CCompressDialog::GetOrder()
UInt32 CCompressDialog::GetOrder()
{
if (m_Order.GetCount() <= 0)
return -1;
return m_Order.GetItemData(m_Order.GetCurSel());
}
UINT32 CCompressDialog::GetOrderSpec()
UInt32 CCompressDialog::GetOrderSpec()
{
if (m_Order.GetCount() <= 1)
return -1;
return GetOrder();
}
UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory)
UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory)
{
decompressMemory = UINT64(INT64(-1));
UINT32 dictionary = GetDictionary();
decompressMemory = UInt64(Int64(-1));
UInt32 dictionary = GetDictionary();
int level = GetLevel2();
if (level == 0)
{
@@ -1143,17 +1129,17 @@ UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory)
{
case kLZMA:
{
UINT64 size;
UInt64 size;
if (level >= 5)
{
size = ((UINT64)dictionary * 19 / 2) + (2 << 20);
size = ((UInt64)dictionary * 19 / 2) + (2 << 20);
if (level >= 9)
size += (34 << 20) + (12 << 20) * 2 + (5 << 20);
else
size += (6 << 20);
}
else
size = ((UINT64)dictionary * 11 / 2) + (2 << 20);
size = ((UInt64)dictionary * 11 / 2) + (2 << 20);
decompressMemory = dictionary + (2 << 20);
return size;
}
@@ -1165,10 +1151,10 @@ UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory)
case kDeflate:
case kDeflate64:
{
UINT32 order = GetOrder();
if (order == UINT32(-1))
UInt32 order = GetOrder();
if (order == UInt32(-1))
order = 32;
UINT64 size = 0;
UInt64 size = 0;
if (level >= 7)
size = (order * 2 + 4) * (64 << 10);
size += 3 << 20;
@@ -1181,27 +1167,27 @@ UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory)
return 10 << 20;
}
}
return UINT64(INT64(-1));
return UInt64(Int64(-1));
}
void CCompressDialog::PrintMemUsage(UINT res, UINT64 value)
void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
{
if (value == (UINT64)INT64(-1))
if (value == (UInt64)Int64(-1))
{
SetItemText(res, TEXT("?"));
return;
}
value = (value + (1 << 20) - 1) >> 20;
TCHAR s[40];
ConvertUINT64ToString(value, s);
ConvertUInt64ToString(value, s);
lstrcat(s, TEXT(" MB"));
SetItemText(res, s);
}
void CCompressDialog::SetMemoryUsage()
{
UINT64 decompressMem;
UINT64 memUsage = GetMemoryUsage(decompressMem);
UInt64 decompressMem;
UInt64 memUsage = GetMemoryUsage(decompressMem);
PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_VALUE, memUsage);
PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, decompressMem);
}
@@ -1220,12 +1206,12 @@ void CCompressDialog::SetParams()
void CCompressDialog::SaveOptionsInMem()
{
const CArchiverInfo &ai = m_ArchiverInfoList[m_Info.ArchiverInfoIndex];
const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex];
int index = FindRegistryFormatAlways(ai.Name);
m_Params.GetText(m_Info.Options);
m_Info.Options.Trim();
m_Params.GetText(Info.Options);
Info.Options.Trim();
NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
fo.Options = m_Info.Options;
fo.Options = GetSystemString(Info.Options);
fo.Level = GetLevelSpec();
fo.Dictionary = GetDictionarySpec();
fo.Order = GetOrderSpec();

View File

@@ -1,7 +1,5 @@
// CompressDialog.h
#pragma once
#ifndef __COMPRESSDIALOG_H
#define __COMPRESSDIALOG_H
@@ -34,15 +32,14 @@ namespace NCompressDialog
bool MultiThreadIsAllowed;
bool MultiThread;
bool VolumeSizeIsDefined;
UINT64 VolumeSize;
CRecordVector<UInt64> VolumeSizes;
UINT32 Level;
UInt32 Level;
UString Method;
UINT32 Dictionary;
UInt32 Dictionary;
bool OrderMode;
UINT32 Order;
CSysString Options;
UInt32 Order;
UString Options;
bool SFXMode;
@@ -54,9 +51,13 @@ namespace NCompressDialog
int ArchiverInfoIndex;
UString Password;
bool EncryptHeadersIsAllowed;
bool EncryptHeaders;
void Init()
{
Level = Dictionary = Order = UINT32(-1);
Level = Dictionary = Order = UInt32(-1);
OrderMode = false;
Method.Empty();
Options.Empty();
@@ -97,7 +98,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
int GetStaticFormatIndex();
void SetNearestSelectComboBox(
NWindows::NControl::CComboBox &comboBox, UINT32 value);
NWindows::NControl::CComboBox &comboBox, UInt32 value);
void SetLevel();
int GetLevel();
@@ -108,21 +109,21 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
int GetMethodID();
CSysString GetMethodSpec();
AddDictionarySize(UINT32 size, bool kilo, bool maga);
AddDictionarySize(UINT32 size);
AddDictionarySize(UInt32 size, bool kilo, bool maga);
AddDictionarySize(UInt32 size);
void SetDictionary();
UINT32 GetDictionary();
UINT32 GetDictionarySpec();
UInt32 GetDictionary();
UInt32 GetDictionarySpec();
int AddOrder(UINT32 size);
int AddOrder(UInt32 size);
void SetOrder();
bool GetOrderMode();
UINT32 GetOrder();
UINT32 GetOrderSpec();
UInt32 GetOrder();
UInt32 GetOrderSpec();
UINT64 GetMemoryUsage(UINT64 &decompressMemory);
void PrintMemUsage(UINT res, UINT64 value);
UInt64 GetMemoryUsage(UInt64 &decompressMemory);
void PrintMemUsage(UINT res, UInt64 value);
void SetMemoryUsage();
void SetParams();
void SaveOptionsInMem();
@@ -131,13 +132,9 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
public:
CObjectVector<CArchiverInfo> m_ArchiverInfoList;
NCompressDialog::CInfo m_Info;
NCompressDialog::CInfo Info;
UString OriginalFileName; // for bzip2, gzip2
CSysString Password;
bool EncryptHeadersIsAllowed;
bool EncryptHeaders;
INT_PTR Create(HWND wndParent = 0)
{ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COMPRESS ), wndParent); }

View File

@@ -1,225 +0,0 @@
// Extract.h
#include "StdAfx.h"
#include "Extract.h"
#include "Common/StringConvert.h"
#include "Windows/FileDir.h"
#include "Windows/Error.h"
#include "Windows/FileFind.h"
#ifndef EXCLUDE_COM
#include "Windows/DLL.h"
#endif
#include "Windows/Thread.h"
#include "../Common/OpenArchive.h"
#include "../Common/DefaultName.h"
#ifndef EXCLUDE_COM
#include "../Common/ZipRegistry.h"
#endif
#include "../Resource/Extract/resource.h"
#include "../Explorer/MyMessages.h"
#include "../../FileManager/FormatUtils.h"
#include "ExtractDialog.h"
#include "../../FileManager/ExtractCallback.h"
#include "../Agent/ArchiveExtractCallback.h"
#include "../../FileManager/OpenCallback.h"
using namespace NWindows;
struct CThreadExtracting
{
#ifndef EXCLUDE_COM
NDLL::CLibrary Library;
#endif
CMyComPtr<IInArchive> Archive;
CExtractCallbackImp *ExtractCallbackSpec;
CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback2;
CMyComPtr<IArchiveExtractCallback> ArchiveExtractCallback;
HRESULT Result;
DWORD Process()
{
ExtractCallbackSpec->ProgressDialog.WaitCreating();
Result = Archive->Extract(0, -1, BoolToInt(false),
ArchiveExtractCallback);
ExtractCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadExtracting *)param)->Process();
}
};
static inline UINT GetCurrentFileCodePage()
{ return AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
HRESULT ExtractArchive(HWND parentWindow, const UString &fileName,
bool assumeYes, bool showDialog, const UString &outputFolder)
{
CThreadExtracting extracter;
CArchiverInfo archiverInfo;
COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback;
CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
openCallbackSpec->_passwordIsDefined = false;
openCallbackSpec->_parentWindow = parentWindow;
UString fullName;
int fileNamePartStartIndex;
NFile::NDirectory::MyGetFullPathName(fileName, fullName, fileNamePartStartIndex);
openCallbackSpec->LoadFileInfo(
fullName.Left(fileNamePartStartIndex),
fullName.Mid(fileNamePartStartIndex));
int subExtIndex;
HRESULT res = OpenArchive(fileName,
#ifndef EXCLUDE_COM
&extracter.Library,
#endif
&extracter.Archive, archiverInfo, subExtIndex, openCallback);
RINOK(res);
NFile::NFind::CFileInfoW fileInfo;
if (!NFile::NFind::FindFile(fileName, fileInfo))
return E_FAIL;
UString defaultName = GetDefaultName(fileName,
archiverInfo.Extensions[subExtIndex].Extension,
archiverInfo.Extensions[subExtIndex].AddExtension);
UString directoryPath;
NExtractionDialog::CModeInfo extractModeInfo;
UString password;
if (openCallbackSpec->_passwordIsDefined)
password = openCallbackSpec->_password;
if (showDialog)
{
CExtractDialog dialog;
if (!NFile::NDirectory::MyGetFullPathName(outputFolder, dialog.DirectoryPath))
{
MyMessageBox(L"Error 32432432");
return E_FAIL;
}
// dialog.DirectoryPath = outputFolder;
// dialog.FilesMode = NExtractionDialog::NFilesMode::kAll;
// dialog._enableSelectedFilesButton = false;
dialog.Password = password;
if(dialog.Create(parentWindow) != IDOK)
return E_ABORT;
directoryPath = dialog.DirectoryPath;
dialog.GetModeInfo(extractModeInfo);
password = dialog.Password;
}
else
{
if (!NFile::NDirectory::MyGetFullPathName(outputFolder, directoryPath))
{
MyMessageBox(L"Error 98324982");
return E_FAIL;
}
NFile::NName::NormalizeDirPathPrefix(directoryPath);
extractModeInfo.PathMode = NExtractionDialog::NPathMode::kFullPathnames;
extractModeInfo.OverwriteMode = assumeYes ?
NExtractionDialog::NOverwriteMode::kWithoutPrompt:
NExtractionDialog::NOverwriteMode::kAskBefore;
// extractModeInfo.FilesMode = NExtractionDialog::NFilesMode::kAll;
}
if(!NFile::NDirectory::CreateComplexDirectory(directoryPath))
{
UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
#ifdef LANG
0x02000603,
#endif
directoryPath);
MyMessageBox(s2 + UString(L"\n") + s);
return E_FAIL;
}
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
extracter.ExtractCallback2 = extracter.ExtractCallbackSpec;
extracter.ExtractCallbackSpec->_parentWindow = 0;
#ifdef LANG
const UString title = LangLoadStringW(IDS_PROGRESS_EXTRACTING, 0x02000890);
#else
const UString title = NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING);
#endif
NFile::NFind::CFileInfoW archiveFileInfo;
if (!NFile::NFind::FindFile(fileName, archiveFileInfo))
throw "there is no archive file";
extracter.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore,
!password.IsEmpty(), password);
NExtractionMode::NPath::EEnum pathMode;
NExtractionMode::NOverwrite::EEnum overwriteMode;
switch (extractModeInfo.OverwriteMode)
{
case NExtractionDialog::NOverwriteMode::kAskBefore:
overwriteMode = NExtractionMode::NOverwrite::kAskBefore;
break;
case NExtractionDialog::NOverwriteMode::kWithoutPrompt:
overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt;
break;
case NExtractionDialog::NOverwriteMode::kSkipExisting:
overwriteMode = NExtractionMode::NOverwrite::kSkipExisting;
break;
case NExtractionDialog::NOverwriteMode::kAutoRename:
overwriteMode = NExtractionMode::NOverwrite::kAutoRename;
break;
default:
throw 12334454;
}
switch (extractModeInfo.PathMode)
{
case NExtractionDialog::NPathMode::kFullPathnames:
pathMode = NExtractionMode::NPath::kFullPathnames;
break;
case NExtractionDialog::NPathMode::kCurrentPathnames:
pathMode = NExtractionMode::NPath::kCurrentPathnames;
break;
case NExtractionDialog::NPathMode::kNoPathnames:
pathMode = NExtractionMode::NPath::kNoPathnames;
break;
default:
throw 12334455;
}
CArchiveExtractCallback *extractCallbackSpec = new
CArchiveExtractCallback;
extracter.ArchiveExtractCallback = extractCallbackSpec;
extractCallbackSpec->Init(extracter.Archive,
extracter.ExtractCallback2,
directoryPath, pathMode,
overwriteMode, UStringVector(),
defaultName,
fileInfo.LastWriteTime, fileInfo.Attributes);
CThread thread;
if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter))
throw 271824;
extracter.ExtractCallbackSpec->StartProgressDialog(title);
return extracter.Result;
}

View File

@@ -1,12 +0,0 @@
// GUI/Extract.h
#ifndef __GUI_EXTRACT_H
#define __GUI_EXTRACT_H
#include "Common/String.h"
HRESULT ExtractArchive(HWND parentWindow, const UString &fileName,
bool assumeYes, bool showDialog, const UString &outputFolder);
#endif

View File

@@ -31,21 +31,40 @@ using namespace NWindows;
using namespace NFile;
using namespace NName;
static const int kPathnamesButtons[] =
static const int kPathModeButtons[] =
{
IDC_EXTRACT_RADIO_FULL_PATHNAMES,
IDC_EXTRACT_RADIO_CURRENT_PATHNAMES,
IDC_EXTRACT_RADIO_NO_PATHNAMES
};
static const int kNumPathnamesButtons = sizeof(kPathnamesButtons) / sizeof(kPathnamesButtons[0]);
static const NExtract::NPathMode::EEnum kPathModeButtonsVals[] =
{
NExtract::NPathMode::kFullPathnames,
NExtract::NPathMode::kCurrentPathnames,
NExtract::NPathMode::kNoPathnames
};
static const int kNumPathnamesButtons = sizeof(kPathModeButtons) / sizeof(kPathModeButtons[0]);
static const int kOverwriteButtons[] =
{
IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE,
IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT,
IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES,
IDC_EXTRACT_RADIO_AUTO_RENAME
IDC_EXTRACT_RADIO_AUTO_RENAME,
IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING,
};
static const NExtract::NOverwriteMode::EEnum kOverwriteButtonsVals[] =
{
NExtract::NOverwriteMode::kAskBefore,
NExtract::NOverwriteMode::kWithoutPrompt,
NExtract::NOverwriteMode::kSkipExisting,
NExtract::NOverwriteMode::kAutoRename,
NExtract::NOverwriteMode::kAutoRenameExisting
};
static const int kNumOverwriteButtons = sizeof(kOverwriteButtons) / sizeof(kOverwriteButtons[0]);
/*
@@ -58,22 +77,60 @@ static const int kNumFilesButtons = sizeof(kFilesButtons) / sizeof(kFilesButtons
*/
#ifndef _SFX
int CExtractDialog::GetPathNameMode() const
void CExtractDialog::GetPathMode()
{
for (int i = 0; i < kNumPathnamesButtons; i++)
if(IsButtonCheckedBool(kPathnamesButtons[i]))
return i;
throw 0;
if(IsButtonCheckedBool(kPathModeButtons[i]))
{
PathMode = kPathModeButtonsVals[i];
return;
}
throw 1;
}
int CExtractDialog::GetOverwriteMode() const
void CExtractDialog::SetPathMode()
{
for (int j = 0; j < 2; j++)
{
for (int i = 0; i < kNumPathnamesButtons; i++)
if(PathMode == kPathModeButtonsVals[i])
{
CheckRadioButton(kPathModeButtons[0], kPathModeButtons[kNumPathnamesButtons - 1],
kPathModeButtons[i]);
return;
}
PathMode = kPathModeButtonsVals[0];
}
throw 1;
}
void CExtractDialog::GetOverwriteMode()
{
for (int i = 0; i < kNumOverwriteButtons; i++)
if(IsButtonCheckedBool(kOverwriteButtons[i]))
return i;
{
OverwriteMode = kOverwriteButtonsVals[i];
return;
}
throw 0;
}
void CExtractDialog::SetOverwriteMode()
{
for (int j = 0; j < 2; j++)
{
for (int i = 0; i < kNumOverwriteButtons; i++)
if(OverwriteMode == kOverwriteButtonsVals[i])
{
CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1],
kOverwriteButtons[i]);
return;
}
OverwriteMode = kOverwriteButtonsVals[0];
}
throw 1;
}
/*
int CExtractDialog::GetFilesMode() const
{
@@ -99,6 +156,7 @@ static CIDLangPair kIDLangPairs[] =
{ IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, 0x02000822 },
{ IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, 0x02000823 },
{ IDC_EXTRACT_RADIO_AUTO_RENAME, 0x02000824 },
{ IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, 0x02000825 },
{ IDC_EXTRACT_FILES, 0x02000830 },
{ IDC_EXTRACT_RADIO_SELECTED_FILES, 0x02000831 },
{ IDC_EXTRACT_RADIO_ALL_FILES, 0x02000832 },
@@ -127,19 +185,20 @@ bool CExtractDialog::OnInit()
_passwordControl.SetPasswordChar(TEXT('*'));
#endif
NExtraction::CInfo extractionInfo;
NExtract::CInfo extractionInfo;
#ifdef NO_REGISTRY
extractionInfo.PathMode = NExtraction::NPathMode::kFullPathnames;
extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kAskBefore;
// extractionInfo.Paths = NExtraction::NPathMode::kFullPathnames;
PathMode = NExtract::NPathMode::kFullPathnames;
OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
// extractionInfo.Paths = NExtract::NPathMode::kFullPathnames;
#else
ReadExtractionInfo(extractionInfo);
CheckButton(IDC_EXTRACT_CHECK_SHOW_PASSWORD, extractionInfo.ShowPassword);
UpdatePasswordControl();
PathMode = extractionInfo.PathMode;
OverwriteMode = extractionInfo.OverwriteMode;
#endif
_path.Attach(GetItem(IDC_EXTRACT_COMBO_PATH));
_path.SetText(DirectoryPath);
@@ -155,15 +214,10 @@ bool CExtractDialog::OnInit()
*/
_pathMode = extractionInfo.PathMode;
_overwriteMode = extractionInfo.OverwriteMode;
#ifndef _SFX
CheckRadioButton(kPathnamesButtons[0], kPathnamesButtons[kNumPathnamesButtons - 1],
kPathnamesButtons[_pathMode]);
CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1],
kOverwriteButtons[_overwriteMode]);
SetPathMode();
SetOverwriteMode();
/*
CheckRadioButton(kFilesButtons[0], kFilesButtons[kNumFilesButtons - 1],
@@ -177,8 +231,8 @@ bool CExtractDialog::OnInit()
#endif
// CWindow aFilesWindow = GetItem(IDC_EXTRACT_RADIO_FILES);
// aFilesWindow.Enable(_enableFilesButton);
// CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES);
// filesWindow.Enable(_enableFilesButton);
// UpdateWildCardState();
return CModalDialog::OnInit();
@@ -254,16 +308,16 @@ void AddUniqueString(CSysStringVector &list, const CSysString &s)
void CExtractDialog::OnOK()
{
#ifndef _SFX
_pathMode = GetPathNameMode();
_overwriteMode = GetOverwriteMode();
GetPathMode();
GetOverwriteMode();
// _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode();
_passwordControl.GetText(Password);
#endif
NExtraction::CInfo extractionInfo;
extractionInfo.PathMode = NExtraction::NPathMode::EEnum(_pathMode);
extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::EEnum(_overwriteMode);
NExtract::CInfo extractionInfo;
extractionInfo.PathMode = PathMode;
extractionInfo.OverwriteMode = OverwriteMode;
extractionInfo.ShowPassword = (IsButtonChecked(
IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED);
@@ -318,54 +372,12 @@ void CExtractDialog::UpdateWildCardState()
}
*/
/*
static DWORD aHelpArray[] =
{
IDC_EXTRACT_COMBO_PATH, IDH_EXTRACT_COMBO_PATH,
IDC_EXTRACT_BUTTON_SET_PATH, IDH_EXTRACT_BUTTON_SET_PATH,
IDC_EXTRACT_PATH_MODE, IDH_EXTRACT_PATH_MODE,
IDC_EXTRACT_RADIO_FULL_PATHNAMES, IDH_EXTRACT_RADIO_FULL_PATHNAMES,
IDC_EXTRACT_RADIO_CURRENT_PATHNAMES,IDH_EXTRACT_RADIO_CURRENT_PATHNAMES,
IDC_EXTRACT_RADIO_NO_PATHNAMES,IDH_EXTRACT_RADIO_NO_PATHNAMES,
IDC_EXTRACT_OVERWRITE_MODE, IDH_EXTRACT_OVERWRITE_MODE,
IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, IDH_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE,
IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, IDH_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT,
IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, IDH_EXTRACT_RADIO_SKIP_EXISTING_FILES,
IDC_EXTRACT_FILES, IDH_EXTRACT_FILES,
IDC_EXTRACT_RADIO_SELECTED_FILES, IDH_EXTRACT_RADIO_SELECTED_FILES,
IDC_EXTRACT_RADIO_ALL_FILES, IDH_EXTRACT_RADIO_ALL_FILES,
IDC_EXTRACT_RADIO_FILES, IDH_EXTRACT_RADIO_FILES,
IDC_EXTRACT_EDIT_WILDCARDS, IDH_EXTRACT_EDIT_WILDCARDS,
0,0
};
*/
void CExtractDialog::GetModeInfo(NExtractionDialog::CModeInfo &modeInfo)
{
modeInfo.OverwriteMode = NExtractionDialog::NOverwriteMode::EEnum(_overwriteMode);
modeInfo.PathMode = NExtractionDialog::NPathMode::EEnum(_pathMode);
// modeInfo.FilesMode = NExtractionDialog::NFilesMode::EEnum(FilesMode);
modeInfo.FileList.Clear();
}
#ifndef NO_REGISTRY
static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm";
void CExtractDialog::OnHelp()
{
ShowHelpWindow(NULL, kHelpTopic);
CModalDialog::OnHelp();
/*
if (pHelpInfo->iContextType == HELPINFO_WINDOW)
{
return ::HtmlHelp((HWND)pHelpInfo->hItemHandle,
TEXT("C:\\SRC\\VC\\ZipView\\Help\\7zip.chm::/Context/Extract.txt"),
HH_TP_HELP_WM_HELP, (DWORD)(LPVOID)aHelpArray) != NULL;
}
*/
}
#endif

View File

@@ -1,7 +1,5 @@
// ExtractDialog.h
#pragma once
#ifndef __EXTRACTDIALOG_H
#define __EXTRACTDIALOG_H
@@ -14,9 +12,11 @@
#ifndef NO_REGISTRY
#include "../Common/ZipRegistry.h"
#endif
#include "../Common/ExtractMode.h"
namespace NExtractionDialog
{
/*
namespace NFilesMode
{
enum EEnum
@@ -26,32 +26,7 @@ namespace NExtractionDialog
kSpecified
};
}
namespace NPathMode
{
enum EEnum
{
kFullPathnames,
kCurrentPathnames,
kNoPathnames,
};
}
namespace NOverwriteMode
{
enum EEnum
{
kAskBefore,
kWithoutPrompt,
kSkipExisting,
kAutoRename
};
}
struct CModeInfo
{
NOverwriteMode::EEnum OverwriteMode;
NPathMode::EEnum PathMode;
// NFilesMode::EEnum FilesMode;
UStringVector FileList;
};
*/
}
class CExtractDialog: public NWindows::NControl::CModalDialog
@@ -66,12 +41,11 @@ class CExtractDialog: public NWindows::NControl::CModalDialog
NWindows::NControl::CEdit _passwordControl;
#endif
int _pathMode;
int _overwriteMode;
#ifndef _SFX
int GetPathNameMode() const;
int GetOverwriteMode() const;
void GetPathMode();
void SetPathMode();
void GetOverwriteMode();
void SetOverwriteMode();
// int GetFilesMode() const;
void UpdatePasswordControl();
#endif
@@ -87,13 +61,15 @@ class CExtractDialog: public NWindows::NControl::CModalDialog
public:
// bool _enableSelectedFilesButton;
// bool _enableFilesButton;
UString DirectoryPath;
// NExtractionDialog::NFilesMode::EEnum FilesMode;
UString DirectoryPath;
UString Password;
NExtract::NPathMode::EEnum PathMode;
NExtract::NOverwriteMode::EEnum OverwriteMode;
INT_PTR Create(HWND aWndParent = 0)
{ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_EXTRACT), aWndParent); }
void GetModeInfo(NExtractionDialog::CModeInfo &modeInfo);
};
#endif

174
7zip/UI/GUI/ExtractGUI.cpp Executable file
View File

@@ -0,0 +1,174 @@
// ExtractGUI.cpp
#include "StdAfx.h"
#include "ExtractGUI.h"
#include "Common/StringConvert.h"
#include "Windows/FileDir.h"
#include "Windows/Error.h"
#include "Windows/FileFind.h"
#include "Windows/Thread.h"
#include "../../FileManager/FormatUtils.h"
#include "../../FileManager/ExtractCallback.h"
#include "../Common/ArchiveExtractCallback.h"
#include "../Explorer/MyMessages.h"
#include "../Resource/Extract/resource.h"
#include "OpenCallbackGUI.h"
#include "ExtractDialog.h"
using namespace NWindows;
static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
struct CThreadExtracting
{
CExtractCallbackImp *ExtractCallbackSpec;
UStringVector *ArchivePaths;
UStringVector *ArchivePathsFull;
const NWildcard::CCensorNode *WildcardCensor;
const CExtractOptions *Options;
COpenCallbackGUI *OpenCallback;
CMyComPtr<IExtractCallbackUI> ExtractCallback;
UString ErrorMessage;
HRESULT Result;
DWORD Process()
{
ExtractCallbackSpec->ProgressDialog.WaitCreating();
try
{
Result = DecompressArchives(*ArchivePaths, *ArchivePathsFull,
*WildcardCensor, *Options, OpenCallback, ExtractCallback);
}
catch(const UString &s)
{
ErrorMessage = s;
Result = E_FAIL;
}
catch(const wchar_t *s)
{
ErrorMessage = s;
Result = E_FAIL;
}
catch(const char *s)
{
ErrorMessage = GetUnicodeString(s);
Result = E_FAIL;
}
catch(...)
{
Result = E_FAIL;
}
ExtractCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadExtracting *)param)->Process();
}
};
HRESULT ExtractGUI(
UStringVector &archivePaths,
UStringVector &archivePathsFull,
const NWildcard::CCensorNode &wildcardCensor,
CExtractOptions &options,
bool showDialog,
COpenCallbackGUI *openCallback,
CExtractCallbackImp *extractCallback)
{
CThreadExtracting extracter;
if (!options.TestMode)
{
UString outputDir = options.OutputDir;
if (outputDir.IsEmpty())
NFile::NDirectory::MyGetCurrentDirectory(outputDir);
if (showDialog)
{
CExtractDialog dialog;
if (!NFile::NDirectory::MyGetFullPathName(outputDir, dialog.DirectoryPath))
{
MyMessageBox(kIncorrectOutDir);
return E_FAIL;
}
NFile::NName::NormalizeDirPathPrefix(dialog.DirectoryPath);
// dialog.OverwriteMode = options.OverwriteMode;
// dialog.PathMode = options.PathMode;
if(dialog.Create(0) != IDOK)
return E_ABORT;
outputDir = dialog.DirectoryPath;
options.OverwriteMode = dialog.OverwriteMode;
options.PathMode = dialog.PathMode;
openCallback->Password = dialog.Password;
openCallback->PasswordIsDefined = !dialog.Password.IsEmpty();
}
if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir))
{
MyMessageBox(kIncorrectOutDir);
return E_FAIL;
}
NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
/*
if(!NFile::NDirectory::CreateComplexDirectory(options.OutputDir))
{
UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
#ifdef LANG
0x02000603,
#endif
options.OutputDir);
MyMessageBox(s2 + UString(L"\n") + s);
return E_FAIL;
}
*/
}
UString title =
#ifdef LANG
LangLoadStringW(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING,
options.TestMode ? 0x02000F90: 0x02000890);
#else
NWindows::MyLoadStringW(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING);
#endif
extracter.ExtractCallbackSpec = extractCallback;
extracter.ExtractCallback = extractCallback;
extracter.ExtractCallbackSpec->Init();
extracter.ArchivePaths = &archivePaths;
extracter.ArchivePathsFull = &archivePathsFull;
extracter.WildcardCensor = &wildcardCensor;
extracter.Options = &options;
extracter.OpenCallback = openCallback;
CThread thread;
if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter))
throw 271824;
extracter.ExtractCallbackSpec->StartProgressDialog(title);
if (extracter.Result == S_OK && options.TestMode && extracter.ExtractCallbackSpec->Messages.IsEmpty())
{
#ifndef _SFX
MessageBoxW(0, LangLoadStringW(IDS_MESSAGE_NO_ERRORS, 0x02000608),
LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90), 0);
#endif
}
if (extracter.Result != S_OK)
{
if (!extracter.ErrorMessage.IsEmpty())
throw extracter.ErrorMessage;
}
return extracter.Result;
}

20
7zip/UI/GUI/ExtractGUI.h Executable file
View File

@@ -0,0 +1,20 @@
// GUI/ExtractGUI.h
#ifndef __EXTRACT_GUI_H
#define __EXTRACT_GUI_H
#include "../Common/Extract.h"
#include "OpenCallbackGUI.h"
#include "../../FileManager/ExtractCallback.h"
HRESULT ExtractGUI(
UStringVector &archivePaths,
UStringVector &archivePathsFull,
const NWildcard::CCensorNode &wildcardCensor,
CExtractOptions &options,
bool showDialog,
COpenCallbackGUI *openCallback,
CExtractCallbackImp *extractCallback);
#endif

View File

@@ -7,88 +7,148 @@
#include "Common/NewHandler.h"
#include "Common/StringConvert.h"
#include "Common/CommandLineParser.h"
#include "Common/Exception.h"
#include "Windows/COM.h"
#include "Windows/FileMapping.h"
#include "Windows/FileDir.h"
#include "Windows/Synchronization.h"
#include "Windows/Error.h"
#include "Windows/FileName.h"
#include "../../IStream.h"
#include "../../IPassword.h"
// #include "../../Compress/Interface/CompressInterface.h"
// #include "../../FileManager/FolderInterface.h"
#include "../../FileManager/StringUtils.h"
#include "../Common/ExitCode.h"
#include "../Common/ArchiveCommandLine.h"
#include "../Resource/Extract/resource.h"
#include "../Agent/Agent.h"
// #include "../Common/FolderArchiveInterface.h"
#include "../Explorer/MyMessages.h"
#include "Test.h"
#include "Extract.h"
#include "Compress.h"
#include "ExtractGUI.h"
#include "UpdateGUI.h"
using namespace NWindows;
using namespace NCommandLineParser;
HINSTANCE g_hInstance;
static const int kNumSwitches = 5;
static const wchar_t *kExceptionErrorMessage = L"Error:";
static const wchar_t *kUserBreak = L"Break signaled";
namespace NKey {
enum Enum
static const wchar_t *kMemoryExceptionMessage = L"ERROR: Can't allocate required memory!";
static const wchar_t *kUnknownExceptionMessage = L"Unknown Error";
static const wchar_t *kInternalExceptionMessage = L"Internal Error #";
static const wchar_t *kIncorrectCommandMessage = L"Incorrect command";
static void ErrorMessage(const wchar_t *message)
{
// kHelp1 = 0,
// kHelp2,
// kDisablePercents,
kArchiveType,
// kYes,
// kPassword,
// kProperty,
kOutputDir,
// kWorkingDir,
kInclude,
// kExclude,
// kUpdate,
// kRecursed,
// kSfx,
// kOverwrite,
kEmail,
kShowDialog
// kMap
};
MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR);
}
static const int kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
static const int kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
static const wchar_t *kRecursedPostCharSet = L"0-";
static const wchar_t *kOverwritePostCharSet = L"asut";
int Main2()
{
/*
TCHAR t[512];
GetCurrentDirectory(512, t);
ErrorMessage(t);
return 0;
*/
static const CSwitchForm kSwitchForms[kNumSwitches] =
UStringVector commandStrings;
NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
if(commandStrings.Size() <= 1)
{
// { L"?", NSwitchType::kSimple, false },
// { L"H", NSwitchType::kSimple, false },
// { L"BD", NSwitchType::kSimple, false },
{ L"T", NSwitchType::kUnLimitedPostString, false, 1 },
// { L"Y", NSwitchType::kSimple, false },
// { L"P", NSwitchType::kUnLimitedPostString, false, 0 },
// { L"M", NSwitchType::kUnLimitedPostString, true, 1 },
{ L"O", NSwitchType::kUnLimitedPostString, false, 1 },
// { L"W", NSwitchType::kUnLimitedPostString, false, 0 },
{ L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
// { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
// { L"U", NSwitchType::kUnLimitedPostString, true, 1},
// { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
// { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
// { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
{ L"SEML", NSwitchType::kSimple, false },
{ L"AD", NSwitchType::kSimple, false }
// { L"MAP=", NSwitchType::kUnLimitedPostString, false, 1 }
};
MessageBoxW(0, L"Specify command", L"7-Zip", 0);
return 0;
}
commandStrings.Delete(0);
CArchiveCommandLineOptions options;
CArchiveCommandLineParser parser;
parser.Parse1(commandStrings, options);
parser.Parse2(options);
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
if (isExtractGroupCommand)
{
CExtractCallbackImp *ecs = new CExtractCallbackImp;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
ecs->PasswordIsDefined = options.PasswordEnabled;
ecs->Password = options.Password;
ecs->Init();
COpenCallbackGUI openCallback;
openCallback.PasswordIsDefined = options.PasswordEnabled;
openCallback.Password = options.Password;
CExtractOptions eo;
eo.StdOutMode = options.StdOutMode;
eo.OutputDir = options.OutputDir;
eo.YesToAll = options.YesToAll;
eo.OverwriteMode = options.OverwriteMode;
eo.PathMode = options.Command.GetPathMode();
eo.TestMode = options.Command.IsTestMode();
HRESULT result = ExtractGUI(
options.ArchivePathsSorted,
options.ArchivePathsFullSorted,
options.WildcardCensor.Pairs.Front().Head,
eo, options.ShowDialog, &openCallback, ecs);
if (result == S_FALSE)
{
MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
return NExitCode::kFatalError;
}
else if (result != S_OK)
throw CSystemException(result);
if (ecs->Messages.Size() > 0)
return NExitCode::kFatalError;
}
else if (options.Command.IsFromUpdateGroup())
{
bool passwordIsDefined =
options.PasswordEnabled && !options.Password.IsEmpty();
COpenCallbackGUI openCallback;
openCallback.PasswordIsDefined = passwordIsDefined;
openCallback.Password = options.Password;
CUpdateCallbackGUI callback;
// callback.EnablePercents = options.EnablePercents;
callback.PasswordIsDefined = passwordIsDefined;
callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
callback.Password = options.Password;
// callback.StdOutMode = options.UpdateOptions.StdOutMode;
callback.Init();
CUpdateErrorInfo errorInfo;
HRESULT result = UpdateGUI(
options.WildcardCensor, options.UpdateOptions,
options.ShowDialog,
errorInfo, &openCallback, &callback);
if (result != S_OK)
{
if (!errorInfo.Message.IsEmpty())
ErrorMessage(errorInfo.Message);
throw CSystemException(result);
}
if (callback.FailedFiles.Size() > 0)
return NExitCode::kWarning;
}
else
{
ErrorMessage(L"Use correct command");
return 0;
}
return 0;
}
static bool inline IsItWindowsNT()
{
@@ -99,263 +159,76 @@ static bool inline IsItWindowsNT()
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
static void MyMessageBoxError(const char *message)
{
::MessageBoxA(0, message, "Error", 0);
}
static wchar_t *kIncorrectCommandMessage = L"Incorrect command";
static void ErrorMessage(const wchar_t *message)
{
MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR);
}
static bool ParseIncludeMap(const UString &switchParam, UStringVector &fileNames)
{
int splitPos = switchParam.Find(L':');
if (splitPos < 0)
{
ErrorMessage(L"Bad switch");
return false;
}
UString mappingName = switchParam.Left(splitPos);
UString switchParam2 = switchParam.Mid(splitPos + 1);
splitPos = switchParam2.Find(L':');
if (splitPos < 0)
{
ErrorMessage(L"Bad switch");
return false;
}
UString mappingSize = switchParam2.Left(splitPos);
UString eventName = switchParam2.Mid(splitPos + 1);
wchar_t *endptr;
UINT32 dataSize = wcstoul(mappingSize, &endptr, 10);
{
CFileMapping fileMapping;
if (!fileMapping.Open(FILE_MAP_READ, false,
GetSystemString(mappingName)))
{
// ShowLastErrorMessage(0);
ErrorMessage(L"Can not open mapping");
return false;
}
LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);
if (data == NULL)
{
ErrorMessage(L"MapViewOfFile error");
return false;
}
try
{
const wchar_t *curData = (const wchar_t *)data;
if (*curData != 0)
{
ErrorMessage(L"Incorrect mapping data");
return false;
}
UINT32 numChars = dataSize /2;
UString name;
for (int i = 1; i < numChars; i++)
{
wchar_t c = curData[i];
if (c == L'\0')
{
fileNames.Add(name);
name.Empty();
}
else
name += c;
}
if (!name.IsEmpty())
{
ErrorMessage(L"data error");
return false;
}
}
catch(...)
{
UnmapViewOfFile(data);
throw;
}
UnmapViewOfFile(data);
}
{
NSynchronization::CEvent event;
event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName));
event.Set();
}
return true;
}
static bool ParseIncludeSwitches(CParser &parser, UStringVector &fileNames)
{
if (parser[NKey::kInclude].ThereIs)
{
for (int i = 0; i < parser[NKey::kInclude].PostStrings.Size(); i++)
{
UString switchParam = parser[NKey::kInclude].PostStrings[i];
if (switchParam.Length() < 1)
return false;
if (switchParam[0] == L'#')
{
if (!ParseIncludeMap(switchParam.Mid(1), fileNames))
return false;
}
else if (switchParam[0] == L'!')
{
fileNames.Add(switchParam.Mid(1));
}
else
{
ErrorMessage(L"Incorrect command");
return false;
}
}
}
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
for (int i = 2; i < nonSwitchStrings.Size(); i++)
{
// ErrorMessage(nonSwitchStrings[i]);
fileNames.Add(nonSwitchStrings[i]);
}
return true;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
g_hInstance = hInstance;
InitCommonControls();
ReloadLang();
#ifdef UNICODE
if (!IsItWindowsNT())
{
// g_StdOut << "This program requires Windows NT/2000/XP";
return 0;
MyMessageBox(L"This program requires Windows NT/2000/XP/2003");
return NExitCode::kFatalError;
}
#endif
// setlocale(LC_COLLATE, ".ACP");
int result = 0;
try
{
UStringVector commandStrings;
SplitCommandLine(GetCommandLineW(), commandStrings);
if (commandStrings.Size() > 0)
commandStrings.Delete(0);
CParser parser(kNumSwitches);
try
{
parser.ParseStrings(kSwitchForms, commandStrings);
}
catch(...)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
int numNonSwitchStrings = nonSwitchStrings.Size();
if(numNonSwitchStrings < 1)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
UString command = nonSwitchStrings[0];
if (command == L"t")
{
if(numNonSwitchStrings < 2)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
UString archiveName = nonSwitchStrings[1];
HRESULT result = TestArchive(0, archiveName);
if (result == S_FALSE)
MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
else if (result != S_OK)
ShowErrorMessage(0, result);
}
else if (command == L"x")
{
if(numNonSwitchStrings < 2)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
UString archiveName = nonSwitchStrings[1];
UString outputDir;
bool outputDirDefined = parser[NKey::kOutputDir].ThereIs;
if(outputDirDefined)
outputDir = parser[NKey::kOutputDir].PostStrings[0];
else
NFile::NDirectory::MyGetCurrentDirectory(outputDir);
NFile::NName::NormalizeDirPathPrefix(outputDir);
HRESULT result = ExtractArchive(0, archiveName,
false, parser[NKey::kShowDialog].ThereIs, outputDir);
if (result == S_FALSE)
MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
else if (result != S_OK)
ShowErrorMessage(0, result);
}
else if (command == L"a")
{
if(numNonSwitchStrings < 2)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
const UString &archiveName = nonSwitchStrings[1];
UString mapString, emailString;
bool emailMode = parser[NKey::kEmail].ThereIs;
UStringVector fileNames;
if (!ParseIncludeSwitches(parser, fileNames))
return 1;
if (fileNames.Size() == 0)
{
ErrorMessage(L"Incorrect command: No files");
return 1;
}
UString archiveType = L"7z";;
if (parser[NKey::kArchiveType].ThereIs)
archiveType = parser[NKey::kArchiveType].PostStrings.Front();
HRESULT result = CompressArchive(archiveName, fileNames,
archiveType, emailMode, parser[NKey::kShowDialog].ThereIs);
// if (result != S_OK)
// ShowErrorMessage(result);
}
else
{
ErrorMessage(L"Use correct command");
return 0;
}
return 0;
return Main2();
}
catch(const CNewException &)
{
// MyMessageBoxError(kMemoryExceptionMessage);
return 1;
MyMessageBox(kMemoryExceptionMessage);
return (NExitCode::kMemoryError);
}
catch(const CSystemException &systemError)
{
if (systemError.ErrorCode == E_OUTOFMEMORY)
{
MyMessageBox(kMemoryExceptionMessage);
return (NExitCode::kMemoryError);
}
if (systemError.ErrorCode == E_ABORT)
{
// MyMessageBox(kUserBreak);
return (NExitCode::kUserBreak);
}
UString message;
NError::MyFormatMessage(systemError.ErrorCode, message);
MyMessageBox(message);
return (NExitCode::kFatalError);
}
/*
catch(NExitCode::EEnum &exitCode)
{
g_StdErr << kInternalExceptionMessage << exitCode << endl;
return (exitCode);
}
*/
catch(const UString &s)
{
MyMessageBox(s);
return (NExitCode::kFatalError);
}
catch(const char *s)
{
MyMessageBox(GetUnicodeString(s));
return (NExitCode::kFatalError);
}
/*
catch(int t)
{
g_StdErr << kInternalExceptionMessage << t << endl;
return (NExitCode::kFatalError);
}
*/
catch(...)
{
// g_StdOut << kUnknownExceptionMessage;
return 2;
MyMessageBox(kUnknownExceptionMessage);
return (NExitCode::kFatalError);
}
return result;
}

View File

@@ -152,6 +152,14 @@ LINK32=link.exe
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\7zG.exe.manifest
# End Source File
# Begin Source File
SOURCE=.\FM.ico
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
@@ -176,6 +184,14 @@ SOURCE=.\StdAfx.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\CommandLineParser.cpp
# End Source File
# Begin Source File
@@ -200,6 +216,14 @@ SOURCE=..\..\..\Common\Lang.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\ListFileUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\ListFileUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File
# Begin Source File
@@ -417,6 +441,30 @@ SOURCE=..\..\..\Windows\Window.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\Common\ArchiveCommandLine.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ArchiveCommandLine.h
# End Source File
# Begin Source File
SOURCE=..\Common\ArchiveExtractCallback.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ArchiveExtractCallback.h
# End Source File
# Begin Source File
SOURCE=..\Common\ArchiveOpenCallback.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ArchiveOpenCallback.h
# End Source File
# Begin Source File
SOURCE=..\Common\ArchiverInfo.cpp
# End Source File
# Begin Source File
@@ -445,6 +493,18 @@ SOURCE=..\Common\EnumDirItems.h
# End Source File
# Begin Source File
SOURCE=..\Common\ExitCode.h
# End Source File
# Begin Source File
SOURCE=..\Common\Extract.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\Extract.h
# End Source File
# Begin Source File
SOURCE=..\Common\ExtractingFilePath.cpp
# End Source File
# Begin Source File
@@ -453,10 +513,18 @@ SOURCE=..\Common\ExtractingFilePath.h
# End Source File
# Begin Source File
SOURCE=..\Common\ExtractMode.h
# End Source File
# Begin Source File
SOURCE=..\Common\HandlerLoader.h
# End Source File
# Begin Source File
SOURCE=..\Common\IFileExtractCallback.h
# End Source File
# Begin Source File
SOURCE=..\Common\OpenArchive.cpp
# End Source File
# Begin Source File
@@ -481,6 +549,22 @@ SOURCE=..\Common\SortUtils.h
# End Source File
# Begin Source File
SOURCE=..\Common\TempFiles.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\TempFiles.h
# End Source File
# Begin Source File
SOURCE=..\Common\Update.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\Update.h
# End Source File
# Begin Source File
SOURCE=..\Common\UpdateAction.cpp
# End Source File
# Begin Source File
@@ -489,6 +573,14 @@ SOURCE=..\Common\UpdateAction.h
# End Source File
# Begin Source File
SOURCE=..\Common\UpdateCallback.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\UpdateCallback.h
# End Source File
# Begin Source File
SOURCE=..\Common\UpdatePair.cpp
# End Source File
# Begin Source File
@@ -520,10 +612,6 @@ SOURCE=..\Common\ZipRegistry.cpp
SOURCE=..\Common\ZipRegistry.h
# End Source File
# End Group
# Begin Group "Console"
# PROP Default_Filter ""
# End Group
# Begin Group "Explorer"
# PROP Default_Filter ""
@@ -571,6 +659,15 @@ SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp
SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\FileManager\Resource\MessagesDialog\resource.h
# End Source File
# Begin Source File
SOURCE=..\..\FileManager\Resource\MessagesDialog\resource.rc
# PROP Exclude_From_Build 1
# End Source File
# End Group
# Begin Group "Overwtite"
@@ -713,6 +810,14 @@ SOURCE=..\..\FileManager\RegistryUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\FileManager\SplitUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\FileManager\SplitUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\FileManager\StringUtils.cpp
# End Source File
# Begin Source File
@@ -728,96 +833,44 @@ SOURCE=..\..\FileManager\UpdateCallback100.cpp
SOURCE=..\..\FileManager\UpdateCallback100.h
# End Source File
# End Group
# Begin Group "Agent"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\Agent\Agent.cpp
# End Source File
# Begin Source File
SOURCE=..\Agent\Agent.h
# End Source File
# Begin Source File
SOURCE=..\Agent\AgentOut.cpp
# End Source File
# Begin Source File
SOURCE=..\Agent\AgentProxy.cpp
# End Source File
# Begin Source File
SOURCE=..\Agent\AgentProxy.h
# End Source File
# Begin Source File
SOURCE=..\Agent\ArchiveExtractCallback.cpp
# End Source File
# Begin Source File
SOURCE=..\Agent\ArchiveExtractCallback.h
# End Source File
# Begin Source File
SOURCE=..\Agent\ArchiveUpdateCallback.cpp
# End Source File
# Begin Source File
SOURCE=..\Agent\ArchiveUpdateCallback.h
# End Source File
# Begin Source File
SOURCE=..\Agent\IFolderArchive.h
# End Source File
# End Group
# Begin Group "Archive Interfaces"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\Format\Common\ArchiveInterface.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Interface\CompressInterface.h
# End Source File
# Begin Source File
SOURCE=..\..\..\SDK\Interface\CryptoInterface.h
# End Source File
# Begin Source File
SOURCE=..\Common\FolderArchiveInterface.h
# End Source File
# End Group
# Begin Group "Engine"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Compress.cpp
SOURCE=.\ExtractGUI.cpp
# End Source File
# Begin Source File
SOURCE=.\Compress.h
SOURCE=.\ExtractGUI.h
# End Source File
# Begin Source File
SOURCE=.\Extract.cpp
SOURCE=.\GUI.cpp
# End Source File
# Begin Source File
SOURCE=.\Extract.h
SOURCE=.\OpenCallbackGUI.cpp
# End Source File
# Begin Source File
SOURCE=.\Test.cpp
SOURCE=.\OpenCallbackGUI.h
# End Source File
# Begin Source File
SOURCE=.\Test.h
SOURCE=.\UpdateCallbackGUI.cpp
# End Source File
# Begin Source File
SOURCE=.\UpdateCallbackGUI.h
# End Source File
# Begin Source File
SOURCE=.\UpdateGUI.cpp
# End Source File
# Begin Source File
SOURCE=.\UpdateGUI.h
# End Source File
# End Group
# Begin Group "7-zip Common"
@@ -852,17 +905,5 @@ SOURCE=..\..\Compress\Copy\CopyCoder.cpp
SOURCE=..\..\Compress\Copy\CopyCoder.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\7zG.exe.manifest
# End Source File
# Begin Source File
SOURCE=.\FM.ico
# End Source File
# Begin Source File
SOURCE=.\GUI.cpp
# End Source File
# End Target
# End Project

51
7zip/UI/GUI/OpenCallbackGUI.cpp Executable file
View File

@@ -0,0 +1,51 @@
// OpenCallbackGUI.cpp
#include "StdAfx.h"
#include "OpenCallbackGUI.h"
#include "Common/StdOutStream.h"
#include "Common/StdInStream.h"
#include "Common/StringConvert.h"
#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h"
HRESULT COpenCallbackGUI::CheckBreak()
{
return S_OK;
}
HRESULT COpenCallbackGUI::SetTotal(const UInt64 *files, const UInt64 *bytes)
{
return S_OK;
}
HRESULT COpenCallbackGUI::SetCompleted(const UInt64 *files, const UInt64 *bytes)
{
return S_OK;
}
#ifndef _NO_CRYPTO
HRESULT COpenCallbackGUI::CryptoGetTextPassword(BSTR *password)
{
if (!PasswordIsDefined)
{
CPasswordDialog dialog;
if (dialog.Create(ParentWindow) == IDCANCEL)
return E_ABORT;
Password = dialog.Password;
PasswordIsDefined = true;
}
CMyComBSTR tempName(Password);
*password = tempName.Detach();
return S_OK;
}
HRESULT COpenCallbackGUI::GetPasswordIfAny(UString &password)
{
if (PasswordIsDefined)
password = Password;
return S_OK;
}
#endif

30
7zip/UI/GUI/OpenCallbackGUI.h Executable file
View File

@@ -0,0 +1,30 @@
// OpenCallbackGUI.h
#ifndef __OPEN_CALLBACK_GUI_H
#define __OPEN_CALLBACK_GUI_H
#include "../Common/ArchiveOpenCallback.h"
class COpenCallbackGUI: public IOpenCallbackUI
{
public:
HRESULT CheckBreak();
HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
#ifndef _NO_CRYPTO
HRESULT CryptoGetTextPassword(BSTR *password);
HRESULT GetPasswordIfAny(UString &password);
bool PasswordIsDefined;
UString Password;
#endif
HWND ParentWindow;
COpenCallbackGUI():
#ifndef _NO_CRYPTO
PasswordIsDefined(false),
#endif
ParentWindow(0) {}
};
#endif

View File

@@ -1,38 +1,11 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include <commctrl.h>
#include <limits.h>
#include <shlobj.h>
/*
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_UUIDOF
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>
#include <crtdbg.h>
#include <string.h>
#include <mbstring.h>
#include <tchar.h>
#include <shlguid.h>
#include <regstr.h>
#include <new.h>
#pragma warning(disable:4786)
#include <map>
#include <algorithm>
*/
#include <vector>
#include <stdio.h>
#endif

View File

@@ -1,122 +0,0 @@
// Test.h
#include "StdAfx.h"
#include "Test.h"
#include "Common/StringConvert.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "Windows/DLL.h"
#include "Windows/Thread.h"
#include "../Common/OpenArchive.h"
#include "../Common/DefaultName.h"
#ifndef EXCLUDE_COM
#include "../Common/ZipRegistry.h"
#endif
#include "../Explorer/MyMessages.h"
#include "../../FileManager/FormatUtils.h"
#include "../../FileManager/ExtractCallback.h"
#include "../../FileManager/LangUtils.h"
#include "../Agent/ArchiveExtractCallback.h"
#include "resource.h"
#include "../../FileManager/OpenCallback.h"
using namespace NWindows;
struct CThreadTesting
{
NDLL::CLibrary Library;
CMyComPtr<IInArchive> Archive;
CExtractCallbackImp *ExtractCallbackSpec;
CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback2;
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
HRESULT Result;
DWORD Process()
{
ExtractCallbackSpec->ProgressDialog.WaitCreating();
Result = Archive->Extract(0, -1, BoolToInt(true), ExtractCallback);
ExtractCallbackSpec->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadTesting *)param)->Process();
}
};
HRESULT TestArchive(HWND parentWindow, const UString &fileName)
{
CThreadTesting tester;
COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback;
CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
openCallbackSpec->_passwordIsDefined = false;
openCallbackSpec->_parentWindow = parentWindow;
UString fullName;
int fileNamePartStartIndex;
NFile::NDirectory::MyGetFullPathName(fileName, fullName, fileNamePartStartIndex);
openCallbackSpec->LoadFileInfo(
fullName.Left(fileNamePartStartIndex),
fullName.Mid(fileNamePartStartIndex));
CArchiverInfo archiverInfo;
int subExtIndex;
RINOK(OpenArchive(fileName,
&tester.Library, &tester.Archive,
archiverInfo, subExtIndex, openCallback));
UString defaultName = GetDefaultName(fileName,
archiverInfo.Extensions[subExtIndex].Extension,
archiverInfo.Extensions[subExtIndex].AddExtension);
tester.ExtractCallbackSpec = new CExtractCallbackImp;
tester.ExtractCallback2 = tester.ExtractCallbackSpec;
tester.ExtractCallbackSpec->_parentWindow = 0;
#ifdef LANG
const UString title = LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90);
#else
const UString title = NWindows::MyLoadStringW(IDS_PROGRESS_TESTING);
#endif
tester.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore,
openCallbackSpec->_passwordIsDefined, openCallbackSpec->_password);
CArchiveExtractCallback *extractCallback200Spec = new CArchiveExtractCallback;
tester.ExtractCallback = extractCallback200Spec;
FILETIME fileTomeDefault;
extractCallback200Spec->Init(tester.Archive,
tester.ExtractCallback2,
L"", NExtractionMode::NPath::kFullPathnames,
NExtractionMode::NOverwrite::kWithoutPrompt, UStringVector(),
defaultName,
fileTomeDefault, 0);
CThread thread;
if (!thread.Create(CThreadTesting::MyThreadFunction, &tester))
throw 271824;
tester.ExtractCallbackSpec->StartProgressDialog(title);
if (tester.Result == S_OK && tester.ExtractCallbackSpec->_messages.IsEmpty())
{
// extractCallbackSpec->DestroyWindows();
MessageBoxW(0, LangLoadStringW(IDS_MESSAGE_NO_ERRORS, 0x02000608),
LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90), 0);
}
return tester.Result;
}

View File

@@ -1,13 +0,0 @@
// GUI/Test.h
#pragma once
#ifndef __GUI_TEST_H
#define __GUI_TEST_H
#include "Common/String.h"
HRESULT TestArchive(HWND parentWindow, const UString &fileName);
#endif

155
7zip/UI/GUI/UpdateCallbackGUI.cpp Executable file
View File

@@ -0,0 +1,155 @@
// UpdateCallbackConsole.cpp
#include "StdAfx.h"
#include "UpdateCallbackGUI.h"
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
#include "Common/Defs.h"
#include "Windows/PropVariant.h"
#include "Windows/Error.h"
#include "../../FileManager/Resource/MessagesDialog/MessagesDialog.h"
#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h"
using namespace NWindows;
CUpdateCallbackGUI::~CUpdateCallbackGUI()
{
if (!Messages.IsEmpty())
{
CMessagesDialog messagesDialog;
messagesDialog.Messages = &Messages;
messagesDialog.Create(ParentWindow);
}
}
void CUpdateCallbackGUI::Init()
{
FailedFiles.Clear();
Messages.Clear();
NumArchiveErrors = 0;
}
void CUpdateCallbackGUI::AddErrorMessage(LPCWSTR message)
{
Messages.Add(GetSystemString(message));
}
HRESULT CUpdateCallbackGUI::OpenResult(const wchar_t *name, HRESULT result)
{
if (result != S_OK)
{
AddErrorMessage (UString(L"Error: ") + name +
UString(L" is not supported archive"));
}
return S_OK;
}
HRESULT CUpdateCallbackGUI::StartScanning()
{
return S_OK;
}
HRESULT CUpdateCallbackGUI::FinishScanning()
{
return S_OK;
}
HRESULT CUpdateCallbackGUI::StartArchive(const wchar_t *name, bool updating)
{
ProgressDialog.ProgressSynch.SetTitleFileName(name);
return S_OK;
}
HRESULT CUpdateCallbackGUI::FinishArchive()
{
return S_OK;
}
HRESULT CUpdateCallbackGUI::CheckBreak()
{
while(true)
{
if(ProgressDialog.ProgressSynch.GetStopped())
return E_ABORT;
if(!ProgressDialog.ProgressSynch.GetPaused())
break;
::Sleep(100);
}
return S_OK;
}
HRESULT CUpdateCallbackGUI::Finilize()
{
return S_OK;
}
HRESULT CUpdateCallbackGUI::SetTotal(UInt64 total)
{
ProgressDialog.ProgressSynch.SetProgress(total, 0);
return S_OK;
}
HRESULT CUpdateCallbackGUI::SetCompleted(const UInt64 *completeValue)
{
RINOK(CheckBreak());
if (completeValue != NULL)
ProgressDialog.ProgressSynch.SetPos(*completeValue);
return S_OK;
}
HRESULT CUpdateCallbackGUI::GetStream(const wchar_t *name, bool isAnti)
{
ProgressDialog.ProgressSynch.SetCurrentFileName(name);
return S_OK;
}
HRESULT CUpdateCallbackGUI::OpenFileError(const wchar_t *name, DWORD systemError)
{
FailedFiles.Add(name);
// if (systemError == ERROR_SHARING_VIOLATION)
{
AddErrorMessage(
UString(L"WARNING: ") +
NError::MyFormatMessageW(systemError) +
UString(L": ") +
UString(name));
return S_FALSE;
}
return systemError;
}
HRESULT CUpdateCallbackGUI::SetOperationResult(Int32 operationResult)
{
return S_OK;
}
HRESULT CUpdateCallbackGUI::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
if (!PasswordIsDefined)
{
if (AskPassword)
{
CPasswordDialog dialog;
if (dialog.Create(ParentWindow) == IDCANCEL)
return E_ABORT;
Password = dialog.Password;
PasswordIsDefined = true;
}
}
*passwordIsDefined = BoolToInt(PasswordIsDefined);
CMyComBSTR tempName(Password);
*password = tempName.Detach();
return S_OK;
}
/*
It doesn't work, since main stream waits Dialog
HRESULT CUpdateCallbackGUI::CloseProgress()
{
ProgressDialog.MyClose();
return S_OK;
};
*/

61
7zip/UI/GUI/UpdateCallbackGUI.h Executable file
View File

@@ -0,0 +1,61 @@
// UpdateCallbackGUI.h
#ifndef __UPDATE_CALLBACK_GUI_H
#define __UPDATE_CALLBACK_GUI_H
#include "../Common/Update.h"
#include "../../FileManager/Resource/ProgressDialog2/ProgressDialog.h"
class CUpdateCallbackGUI: public IUpdateCallbackUI2
{
public:
// bool StdOutMode;
bool PasswordIsDefined;
UString Password;
bool AskPassword;
CUpdateCallbackGUI():
PasswordIsDefined(false),
AskPassword(false),
// StdOutMode(false)
ParentWindow(0)
{}
~CUpdateCallbackGUI();
void Init();
HRESULT OpenResult(const wchar_t *name, HRESULT result);
HRESULT StartScanning();
HRESULT FinishScanning();
HRESULT StartArchive(const wchar_t *name, bool updating);
HRESULT FinishArchive();
HRESULT CheckBreak();
HRESULT Finilize();
HRESULT SetTotal(UInt64 total);
HRESULT SetCompleted(const UInt64 *completeValue);
HRESULT GetStream(const wchar_t *name, bool isAnti);
HRESULT OpenFileError(const wchar_t *name, DWORD systemError);
HRESULT SetOperationResult(Int32 operationResult);
HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password);
// HRESULT CloseProgress();
UStringVector FailedFiles;
CProgressDialog ProgressDialog;
HWND ParentWindow;
void StartProgressDialog(const UString &title)
{
ProgressDialog.Create(title, ParentWindow);
}
CSysStringVector Messages;
int NumArchiveErrors;
void AddErrorMessage(LPCWSTR message);
};
#endif

354
7zip/UI/GUI/UpdateGUI.cpp Executable file
View File

@@ -0,0 +1,354 @@
// UpdateGUI.cpp
#include "StdAfx.h"
#include "UpdateGUI.h"
#include "resource.h"
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
#include "Windows/FileDir.h"
#include "Windows/Error.h"
#include "Windows/FileFind.h"
#include "Windows/Thread.h"
#include "../../FileManager/FormatUtils.h"
#include "../../FileManager/ExtractCallback.h"
#include "../../FileManager/StringUtils.h"
#include "../Common/ArchiveExtractCallback.h"
#include "../Common/WorkDir.h"
#include "../Explorer/MyMessages.h"
#include "../Resource/Extract/resource.h"
#include "OpenCallbackGUI.h"
#include "CompressDialog.h"
#include "UpdateGUI.h"
using namespace NWindows;
using namespace NFile;
static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
static const wchar_t *kDefaultSfxModule = L"7zC.sfx";
static const wchar_t *kSFXExtension = L"exe";
struct CThreadUpdating
{
CUpdateCallbackGUI *UpdateCallbackGUI;
const NWildcard::CCensor *WildcardCensor;
CUpdateOptions *Options;
COpenCallbackGUI *OpenCallback;
CUpdateErrorInfo *ErrorInfo;
HRESULT Result;
DWORD Process()
{
UpdateCallbackGUI->ProgressDialog.WaitCreating();
try
{
Result = UpdateArchive(*WildcardCensor, *Options,
*ErrorInfo, OpenCallback, UpdateCallbackGUI);
}
catch(const UString &s)
{
ErrorInfo->Message = s;
Result = E_FAIL;
}
catch(const wchar_t *s)
{
ErrorInfo->Message = s;
Result = E_FAIL;
}
catch(const char *s)
{
ErrorInfo->Message = GetUnicodeString(s);
Result = E_FAIL;
}
catch(...)
{
Result = E_FAIL;
}
UpdateCallbackGUI->ProgressDialog.MyClose();
return 0;
}
static DWORD WINAPI MyThreadFunction(void *param)
{
return ((CThreadUpdating *)param)->Process();
}
};
static void AddProp(CObjectVector<CProperty> &properties,
const UString &name, const UString &value)
{
CProperty prop;
prop.Name = name;
prop.Value = value;
properties.Add(prop);
}
static void AddProp(CObjectVector<CProperty> &properties,
const UString &name, UInt32 value)
{
wchar_t tmp[32];
ConvertUInt64ToString(value, tmp);
AddProp(properties, name, tmp);
}
static void AddProp(CObjectVector<CProperty> &properties,
const UString &name, bool value)
{
AddProp(properties, name, value ? UString(L"on"): UString(L"off"));
}
static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
const UString &propertiesString)
{
UStringVector strings;
SplitString(propertiesString, strings);
for (int i = 0; i < strings.Size(); i++)
{
const UString &s = strings[i];
CProperty property;
int index = s.Find(L'=');
if (index < 0)
property.Name = s;
else
{
property.Name = s.Left(index);
property.Value = s.Mid(index + 1);
}
properties.Add(property);
}
}
static void SetOutProperties(
CObjectVector<CProperty> &properties,
bool is7z,
UInt32 level,
const UString &method,
UInt32 dictionary,
bool orderMode,
UInt32 order,
bool solidModeIsAllowed, bool solidMode,
bool multiThreadIsAllowed, bool multiThread,
bool encryptHeadersIsAllowed, bool encryptHeaders,
bool sfxMode)
{
if (level != (UInt32)(Int32)-1)
AddProp(properties, L"x", (UInt32)level);
if (!method.IsEmpty())
AddProp(properties, is7z ? L"0": L"m", method);
if (dictionary != (UInt32)(Int32)-1)
{
UString name;
if (is7z)
name = L"0";
if (orderMode)
name += L"mem";
else
name += L"d";
wchar_t s[32];
ConvertUInt64ToString(dictionary, s);
wcscat(s, L"B");
AddProp(properties, name, UString(s));
}
if (order != (UInt32)(Int32)-1)
{
UString name;
if (is7z)
name = L"0";
if (orderMode)
name += L"o";
else
name += L"fb";
AddProp(properties, name, (UInt32)order);
}
if (encryptHeadersIsAllowed)
AddProp(properties, L"he", encryptHeaders);
if (solidModeIsAllowed)
AddProp(properties, L"s", solidMode);
if (multiThreadIsAllowed)
AddProp(properties, L"mt", multiThread);
}
static HRESULT ShowDialog(const NWildcard::CCensor &censor,
CUpdateOptions &options, CUpdateCallbackGUI *callback)
{
if (options.Commands.Size() != 1)
throw "It must be one command";
CObjectVector<CArchiverInfo> archivers;
CArchiverInfo archiverInfo;
ReadArchiverInfoList(archivers);
UString currentDirPrefix;
bool oneFile = false;
NFind::CFileInfoW fileInfo;
if (censor.Pairs.Size() > 0)
{
const NWildcard::CPair &pair = censor.Pairs[0];
currentDirPrefix = pair.Prefix;
if (pair.Head.Items.Size() > 0)
{
const NWildcard::CItem &item = pair.Head.Items[0];
if (item.ForFile)
{
UString name = pair.Prefix;
for (int i = 0; i < item.PathParts.Size(); i++)
{
if (i > 0)
name += L'\\';
name += item.PathParts[i];
}
if (NFind::FindFile(name, fileInfo))
{
if (censor.Pairs.Size() == 1 && pair.Head.Items.Size() == 1)
oneFile = !fileInfo.IsDirectory();
}
}
}
}
CCompressDialog dialog;
NCompressDialog::CInfo &di = dialog.Info;
for(int i = 0; i < archivers.Size(); i++)
{
const CArchiverInfo &ai = archivers[i];
if (ai.UpdateEnabled && (oneFile || !ai.KeepName))
dialog.m_ArchiverInfoList.Add(ai);
}
if(dialog.m_ArchiverInfoList.Size() == 0)
{
MyMessageBox(L"No Update Engines");
return E_FAIL;
}
// di.ArchiveName = options.ArchivePath.GetFinalPath();
di.ArchiveName = options.ArchivePath.GetPathWithoutExt();
dialog.OriginalFileName = fileInfo.Name;
di.CurrentDirPrefix = currentDirPrefix;
di.SFXMode = options.SfxMode;
di.Solid = true;
di.MultiThread = false;
if (callback->PasswordIsDefined)
di.Password = callback->Password;
di.KeepName = !oneFile;
if(dialog.Create(0) != 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;
}
archiverInfo = dialog.m_ArchiverInfoList[di.ArchiverInfoIndex];
if (callback->PasswordIsDefined = (!di.Password.IsEmpty()))
callback->Password = di.Password;
options.MethodMode.Properties.Clear();
SetOutProperties(
options.MethodMode.Properties,
archiverInfo.Name.CompareNoCase(L"7z") == 0,
di.Level,
di.Method,
di.Dictionary,
di.OrderMode, di.Order,
di.SolidIsAllowed, di.Solid,
di.MultiThreadIsAllowed, di.MultiThread,
di.EncryptHeadersIsAllowed, di.EncryptHeaders,
di.SFXMode);
ParseAndAddPropertires(options.MethodMode.Properties,
di.Options);
if (di.SFXMode)
options.SfxMode = true;
options.MethodMode.FilePath = archiverInfo.FilePath;
options.MethodMode.ClassID = archiverInfo.ClassID;
options.ArchivePath.VolExtension = archiverInfo.GetMainExtension();
if(di.SFXMode)
options.ArchivePath.BaseExtension = kSFXExtension;
else
options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension;
options.ArchivePath.ParseFromPath(di.ArchiveName);
NWorkDir::CInfo workDirInfo;
ReadWorkDirInfo(workDirInfo);
options.WorkingDir.Empty();
if (workDirInfo.Mode != NWorkDir::NMode::kCurrent)
{
UString fullPath;
NDirectory::MyGetFullPathName(di.ArchiveName, fullPath);
options.WorkingDir = GetWorkDir(workDirInfo, fullPath);
NFile::NDirectory::CreateComplexDirectory(options.WorkingDir);
}
return S_OK;
}
HRESULT UpdateGUI(
const NWildcard::CCensor &censor,
CUpdateOptions &options,
bool showDialog,
CUpdateErrorInfo &errorInfo,
COpenCallbackGUI *openCallback,
CUpdateCallbackGUI *callback)
{
if (showDialog)
{
RINOK(ShowDialog(censor, options, callback));
}
if (options.SfxMode && options.SfxModule.IsEmpty())
options.SfxModule = kDefaultSfxModule;
CThreadUpdating tu;
tu.UpdateCallbackGUI = callback;
tu.UpdateCallbackGUI->Init();
tu.WildcardCensor = &censor;
tu.Options = &options;
tu.OpenCallback = openCallback;
tu.ErrorInfo = &errorInfo;
CThread thread;
if (!thread.Create(CThreadUpdating::MyThreadFunction, &tu))
throw 271824;
const UString title = LangLoadStringW(IDS_PROGRESS_COMPRESSING, 0x02000DC0);
tu.UpdateCallbackGUI->StartProgressDialog(title);
return tu.Result;
}

20
7zip/UI/GUI/UpdateGUI.h Executable file
View File

@@ -0,0 +1,20 @@
// GUI/UpdateGUI.h
#ifndef __UPDATE_GUI_H
#define __UPDATE_GUI_H
#include "../Common/Update.h"
#include "OpenCallbackGUI.h"
#include "UpdateCallbackGUI.h"
#include "../../FileManager/UpdateCallback100.h"
HRESULT UpdateGUI(
const NWildcard::CCensor &censor,
CUpdateOptions &options,
bool showDialog,
CUpdateErrorInfo &errorInfo,
COpenCallbackGUI *openCallback,
CUpdateCallbackGUI *callback);
#endif

View File

@@ -74,8 +74,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,13,0,0
PRODUCTVERSION 3,13,0,0
FILEVERSION 4,20,0,0
PRODUCTVERSION 4,20,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -93,14 +93,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7-Zip GUI Module\0"
VALUE "FileVersion", "3, 13, 0, 0\0"
VALUE "FileVersion", "4, 20, 0, 0\0"
VALUE "InternalName", "7zg\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "7zg.dll\0"
VALUE "OriginalFilename", "7zg.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "3, 13, 0, 0\0"
VALUE "ProductVersion", "4, 20, 0, 0\0"
VALUE "SpecialBuild", "\0"
END
END