This commit is contained in:
Fernando Nillsson Cidade 2026-03-22 01:40:47 -03:00 committed by GitHub
commit 1519f84230
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 2105 additions and 174 deletions

View file

@ -59,6 +59,8 @@ typedef enum {
static LPCSTR const k_7zip = "7-Zip";
static LPCWSTR const k_Reg_Software_7zip = L"Software\\7-Zip";
static LPCWSTR const k_7zip_DisplayVersion = LLL(MY_VERSION);
static LPCWSTR const k_7zip_Publisher = LLL(MY_AUTHOR_NAME);
// #define Z7_64BIT_INSTALLER 1
@ -944,7 +946,7 @@ static void WriteShellEx(void)
if (res == ERROR_SUCCESS)
{
MyRegistry_SetString(destKey, L"DisplayName", k_7zip_with_Ver_str);
MyRegistry_SetString(destKey, L"DisplayVersion", LLL(MY_VERSION_NUMBERS));
MyRegistry_SetString(destKey, L"DisplayVersion", k_7zip_DisplayVersion);
MyRegistry_SetString(destKey, L"DisplayIcon", destPath);
MyRegistry_SetString(destKey, L"InstallLocation", path);
@ -964,7 +966,7 @@ static void WriteShellEx(void)
MyRegistry_SetDWORD(destKey, L"VersionMajor", MY_VER_MAJOR);
MyRegistry_SetDWORD(destKey, L"VersionMinor", MY_VER_MINOR);
MyRegistry_SetString(destKey, L"Publisher", LLL(MY_AUTHOR_NAME));
MyRegistry_SetString(destKey, L"Publisher", k_7zip_Publisher);
// MyRegistry_SetString(destKey, L"HelpLink", L"http://www.7-zip.org/support.html");
// MyRegistry_SetString(destKey, L"URLInfoAbout", L"http://www.7-zip.org/");

View file

@ -27,6 +27,9 @@ typedef enum {
#else
#include <ShlObj.h>
#endif
#ifndef UNDER_CE
#include <TlHelp32.h>
#endif
#include "../../7zVersion.h"
@ -464,7 +467,7 @@ static BoolInt AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix,
return AreStringsEqual_NoCase(s + wcslen(prefix), name);
}
static void WriteCLSID(void)
static void RemoveShellExtensionCLSID(void)
{
WCHAR s[MAX_PATH + 30];
@ -540,7 +543,13 @@ static void WriteCLSID(void)
}
#endif
}
static void WriteCLSID(void)
{
WCHAR s[MAX_PATH + 30];
RemoveShellExtensionCLSID();
if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_AppPaths_7zFm, NULL, s))
{
@ -616,6 +625,216 @@ static BOOL RemoveFileAfterReboot(void)
return RemoveFileAfterReboot2(path);
}
static BOOL DeleteFileOrScheduleForReboot(const WCHAR *s, WRes *winRes, BoolInt *needReboot)
{
const DWORD attrib = GetFileAttributesW(s);
if (attrib == INVALID_FILE_ATTRIBUTES)
return TRUE;
if (attrib & FILE_ATTRIBUTE_READONLY)
SetFileAttributesW(s, 0);
if (DeleteFileW(s))
return TRUE;
if (RemoveFileAfterReboot2(s))
{
if (needReboot)
*needReboot = True;
return TRUE;
}
if (winRes)
*winRes = GetLastError();
return FALSE;
}
#ifndef UNDER_CE
static HMODULE GetRemoteModuleBase(DWORD processId, const WCHAR *moduleName)
{
HMODULE res = NULL;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId);
if (snapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32W me;
me.dwSize = sizeof(me);
if (Module32FirstW(snapshot, &me))
do
{
if (AreStringsEqual_NoCase(me.szModule, moduleName))
{
res = (HMODULE)me.modBaseAddr;
break;
}
}
while (Module32NextW(snapshot, &me));
CloseHandle(snapshot);
}
return res;
}
static LPVOID GetRemoteProcAddress(DWORD processId, const WCHAR *moduleName, const char *procName)
{
HMODULE localModule = GetModuleHandleW(moduleName);
BoolInt needFree = False;
HMODULE remoteModule;
FARPROC localProc;
if (!localModule)
{
localModule = LoadLibraryW(moduleName);
needFree = (localModule != NULL);
}
if (!localModule)
return NULL;
localProc = GetProcAddress(localModule, procName);
remoteModule = GetRemoteModuleBase(processId, moduleName);
if (needFree)
FreeLibrary(localModule);
if (!localProc || !remoteModule)
return NULL;
return (LPVOID)((const Byte *)remoteModule + ((const Byte *)localProc - (const Byte *)localModule));
}
static BoolInt UnloadModuleInProcess(DWORD processId, const WCHAR *moduleName)
{
HMODULE remoteModule = GetRemoteModuleBase(processId, moduleName);
LPTHREAD_START_ROUTINE remoteFreeLibrary;
HANDLE process;
HANDLE thread;
DWORD exitCode = 0;
if (!remoteModule)
return True;
remoteFreeLibrary = (LPTHREAD_START_ROUTINE)GetRemoteProcAddress(processId, L"kernel32.dll", "FreeLibrary");
if (!remoteFreeLibrary)
return False;
process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION, FALSE, processId);
if (!process)
return False;
thread = CreateRemoteThread(process, NULL, 0, remoteFreeLibrary, (LPVOID)remoteModule, 0, NULL);
if (!thread)
{
CloseHandle(process);
return False;
}
if (WaitForSingleObject(thread, 5000) == WAIT_OBJECT_0)
GetExitCodeThread(thread, &exitCode);
CloseHandle(thread);
CloseHandle(process);
return (exitCode != 0);
}
static void RequestExplorerToUnloadModule(const WCHAR *moduleName)
{
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32W pe;
pe.dwSize = sizeof(pe);
if (Process32FirstW(snapshot, &pe))
do
{
if (AreStringsEqual_NoCase(pe.szExeFile, L"explorer.exe"))
{
unsigned i;
for (i = 0; i < 4; i++)
{
if (!GetRemoteModuleBase(pe.th32ProcessID, moduleName))
break;
if (!UnloadModuleInProcess(pe.th32ProcessID, moduleName))
break;
Sleep(100);
}
}
}
while (Process32NextW(snapshot, &pe));
CloseHandle(snapshot);
}
}
static void RequestExplorerToUnloadShellExtensions(void)
{
RequestExplorerToUnloadModule(L"7-zip.dll");
#ifdef USE_7ZIP_32_DLL
RequestExplorerToUnloadModule(L"7-zip32.dll");
#endif
}
#endif
static BoolInt IsTempCleanupTarget(const WCHAR *s)
{
if (AreStringsEqual_NoCase(s, L"7-zip.dll"))
return True;
#ifdef USE_7ZIP_32_DLL
if (AreStringsEqual_NoCase(s, L"7-zip32.dll"))
return True;
#endif
return False;
}
static BOOL DeleteTempVariantsForBasePath(const WCHAR *basePath, WRes *winRes, BoolInt *needReboot)
{
#ifndef UNDER_CE
BOOL result = TRUE;
WCHAR dirPath[MAX_PATH * 2 + 80];
WCHAR mask[MAX_PATH * 2 + 80];
WCHAR *name;
WIN32_FIND_DATAW fd;
HANDLE h;
wcscpy(mask, basePath);
CatAscii(mask, ".tmp*");
wcscpy(dirPath, basePath);
name = dirPath;
{
WCHAR *s = dirPath;
for (;;)
{
const WCHAR c = *s++;
if (c == 0)
break;
if (c == WCHAR_PATH_SEPARATOR)
name = s;
}
}
if (!name)
return TRUE;
*name = 0;
h = FindFirstFileW(mask, &fd);
if (h == INVALID_HANDLE_VALUE)
return TRUE;
do
{
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
wcscpy(name, fd.cFileName);
if (!DeleteFileOrScheduleForReboot(dirPath, winRes, needReboot))
result = FALSE;
}
}
while (FindNextFileW(h, &fd));
FindClose(h);
return result;
#else
UNUSED_VAR(basePath)
UNUSED_VAR(winRes)
UNUSED_VAR(needReboot)
return TRUE;
#endif
}
// #define IS_LIMIT_CHAR(c) (c == 0 || c == ' ')
static BoolInt IsThereSpace(const wchar_t *s)
@ -640,6 +859,55 @@ static void AddPathParam(wchar_t *dest, const wchar_t *src)
CatAscii(dest, "\"");
}
static BoolInt IsProcessElevated(void)
{
#ifndef UNDER_CE
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
PSID adminGroup = NULL;
BOOL isMember = FALSE;
if (!AllocateAndInitializeSid(&ntAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &adminGroup))
return False;
CheckTokenMembership(NULL, adminGroup, &isMember);
FreeSid(adminGroup);
return isMember ? True : False;
#else
return True;
#endif
}
static BoolInt RelaunchAsAdmin(const WCHAR *params, DWORD *errorCode)
{
#ifndef UNDER_CE
SHELLEXECUTEINFOW sei;
memset(&sei, 0, sizeof(sei));
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = L"runas";
sei.lpFile = modulePath;
sei.lpParameters = (params[0] == 0 ? NULL : params);
sei.nShow = SW_SHOWNORMAL;
if (ShellExecuteExW(&sei))
{
if (sei.hProcess)
CloseHandle(sei.hProcess);
return True;
}
if (errorCode)
*errorCode = GetLastError();
return False;
#else
UNUSED_VAR(params)
UNUSED_VAR(errorCode)
return False;
#endif
}
static BoolInt GetErrorMessage(DWORD errorCode, WCHAR *message)
@ -713,7 +981,7 @@ static int Install(void)
SRes res = SZ_OK;
WRes winRes = 0;
// BoolInt needReboot = False;
BoolInt needReboot = False;
const size_t pathLen = wcslen(path);
if (!g_SilentMode)
@ -723,6 +991,14 @@ static int Install(void)
SendMessage(g_Progress_HWND, PBM_SETRANGE32, 0, NUM_FILES);
}
RemoveShellExtensionCLSID();
#ifndef UNDER_CE
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
Sleep(200);
RequestExplorerToUnloadShellExtensions();
Sleep(100);
#endif
{
unsigned i;
const char *curName = k_Names;
@ -780,24 +1056,17 @@ static int Install(void)
if (!g_SilentMode)
SetWindowTextW(g_InfoLine_HWND, temp);
if (IsTempCleanupTarget(temp))
{
const DWORD attrib = GetFileAttributesW(path);
if (attrib == INVALID_FILE_ATTRIBUTES)
continue;
if (attrib & FILE_ATTRIBUTE_READONLY)
SetFileAttributesW(path, 0);
if (!DeleteFileW(path))
{
if (!RemoveFileAfterReboot())
{
winRes = GetLastError();
}
/*
else
needReboot = True;
*/
}
DeleteTempVariantsForBasePath(path, &winRes, &needReboot);
#ifndef UNDER_CE
RequestExplorerToUnloadModule(temp);
Sleep(100);
#endif
}
if (!DeleteFileOrScheduleForReboot(path, &winRes, &needReboot))
break;
}
CpyAscii(path + pathLen, k_Lang);
@ -824,7 +1093,11 @@ static int Install(void)
if (res == SZ_OK)
{
// if (!g_SilentMode && needReboot);
if (!g_SilentMode && needReboot)
MessageBoxW(g_HWND,
L"Some files were in use and are scheduled to be removed after restart.",
k_7zip_with_Ver_Uninstall,
MB_ICONINFORMATION | MB_OK);
return 0;
}
@ -1051,6 +1324,21 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
*name = 0; // keep only prefix for modulePrefix
}
if (!IsProcessElevated())
{
DWORD errorCode = ERROR_SUCCESS;
if (RelaunchAsAdmin(cmdParams, &errorCode))
return 0;
if (!g_SilentMode && errorCode != ERROR_CANCELLED)
{
WCHAR m[MAX_PATH + 100];
if (!GetErrorMessage(errorCode, m))
CpyAscii(m, "Can't relaunch with administrator rights");
PrintErrorMessage("Administrator rights are required for uninstall.", m);
}
return 1;
}
if (useTemp)
{

View file

@ -1,4 +1,8 @@
PROG = 7zFM.exe
UI_FILEMANAGER_PROGPATH = ..\..\UI\FileManager\$(O)\$(PROG)
REPO_LANG_DIR = ..\..\..\..\Lang
FM_LANG_DIR = $(O)\Lang
UI_FILEMANAGER_LANG_DIR = ..\..\UI\FileManager\$(O)\Lang
# CFLAGS = $(CFLAGS) -DZ7_LARGE_PAGES
@ -82,3 +86,22 @@ GUI_OBJS = \
!include "../../7zip.mak"
all: copy_lang $(UI_FILEMANAGER_PROGPATH)
copy_lang:
if not exist "$(FM_LANG_DIR)" mkdir "$(FM_LANG_DIR)"
copy /Y "$(REPO_LANG_DIR)\*" "$(FM_LANG_DIR)\" >nul
if not exist "$(UI_FILEMANAGER_LANG_DIR)" mkdir "$(UI_FILEMANAGER_LANG_DIR)"
copy /Y "$(REPO_LANG_DIR)\*" "$(UI_FILEMANAGER_LANG_DIR)\" >nul
$(UI_FILEMANAGER_PROGPATH): $(PROGPATH)
if not exist "..\..\UI\FileManager\$(O)" mkdir "..\..\UI\FileManager\$(O)"
copy /Y "$(PROGPATH)" "$(UI_FILEMANAGER_PROGPATH)" >nul
$O\CompressDialog.obj: ../../UI/GUI/CompressDialog.cpp ../../UI/GUI/CompressDialog.h ../../UI/GUI/CompressDialogRes.h
$O\CompressCall2.obj: ../../UI/Common/CompressCall2.cpp ../../UI/Common/Update.h ../../UI/GUI/UpdateGUI.h
$O\Update.obj: ../../UI/Common/Update.cpp ../../UI/Common/Update.h
$O\UpdateCallbackGUI.obj: ../../UI/GUI/UpdateCallbackGUI.cpp ../../UI/Common/Update.h ../../UI/GUI/UpdateCallbackGUI.h
$O\UpdateGUI.obj: ../../UI/GUI/UpdateGUI.cpp ../../UI/Common/Update.h ../../UI/GUI/UpdateGUI.h ../../UI/GUI/CompressDialog.h ../../UI/GUI/CompressDialogRes.h
$O\resource.res: resource.rc ../../UI/GUI/resource2.rc ../../UI/GUI/CompressDialog.rc ../../UI/GUI/CompressDialogRes.h ../../UI/FileManager/AboutDialog.rc ../../UI/FileManager/AboutDialogRes.h

View file

@ -111,6 +111,9 @@ struct CUpdateOptions
CObjectVector<CUpdateArchiveCommand> Commands;
CArchivePath ArchivePath;
bool SeparateItemMode;
UStringVector SeparateItemPaths;
UStringVector SeparateItemArchivePaths;
FString SfxModule;
UString StdInFileName;
@ -143,7 +146,8 @@ struct CUpdateOptions
RenameMode(false),
ArcNameMode(k_ArcNameMode_Smart),
PathMode(NWildcard::k_RelatPath)
PathMode(NWildcard::k_RelatPath),
SeparateItemMode(false)
{}

View file

@ -5,6 +5,8 @@
#include "../../../Common/Lang.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileName.h"
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Window.h"
@ -30,9 +32,45 @@ bool LangOpen(CLang &lang, CFSTR fileName)
return lang.Open(fileName, "7-Zip");
}
static bool GetParentDirPrefix(FString &dirPrefix)
{
if (dirPrefix.IsEmpty())
return false;
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
FString parent = dirPrefix;
if (!NFile::NName::IsDriveRootPath_SuperAllowed(parent))
parent.DeleteBack();
const int pos = parent.ReverseFind_PathSepar();
if (pos < 0)
return false;
parent.DeleteFrom((unsigned)(pos + 1));
if (parent.IsEmpty() || parent == dirPrefix)
return false;
dirPrefix = parent;
return true;
}
FString GetLangDirPrefix()
{
return NDLL::GetModuleDirPrefix() + FTEXT("Lang") FSTRING_PATH_SEPARATOR;
const FString moduleDir = NDLL::GetModuleDirPrefix();
FString dirPrefix = moduleDir;
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
for (;;)
{
const FString langDir = dirPrefix + FTEXT("Lang") FSTRING_PATH_SEPARATOR;
if (NFile::NFind::DoesDirExist(langDir))
return langDir;
if (!GetParentDirPrefix(dirPrefix))
break;
}
return moduleDir + FTEXT("Lang") FSTRING_PATH_SEPARATOR;
}
#ifdef Z7_LANG

View file

@ -37,6 +37,7 @@ void LangString_OnlyFromLangFile(UInt32 langID, UString &dest);
inline UString LangString(UInt32 langID) { return NWindows::MyLoadString(langID); }
inline void LangString(UInt32 langID, UString &dest) { NWindows::MyLoadString(langID, dest); }
inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadString(langID); }
inline void LangString_OnlyFromLangFile(UInt32, UString &dest) { dest.Empty(); }
#endif

File diff suppressed because it is too large Load diff

View file

@ -70,6 +70,11 @@ namespace NCompressDialog
CBoolPair SetArcMTime;
UString ArcPath; // in: Relative or abs ; out: Relative or abs
UStringVector ArcPaths;
UStringVector ItemPaths;
UStringVector ItemOutputItemPaths;
UStringVector ItemArcPaths;
bool SeparateItemArchives;
// FString CurrentDirPrefix;
bool KeepName;
@ -88,6 +93,7 @@ namespace NCompressDialog
SFXMode(false),
OpenShareForWrite(false),
DeleteAfterCompressing(false),
SeparateItemArchives(false),
FormatIndex(-1)
{
Level = Order = (UInt32)(Int32)-1;
@ -148,9 +154,41 @@ public:
CBool1 NtSecurity;
CBool1 PreserveATime;
private:
struct CLayoutItem
{
unsigned Id;
RECT Rect;
};
struct CItemOutputGroup
{
UString ItemPath;
UStringVector ArcPaths;
};
static const unsigned kNumOutputPathRows = 5;
bool _ramSize_Defined;
bool _outputLayout_Inited;
UStringVector _outputArcPaths;
CObjectVector<CItemOutputGroup> _itemOutputGroups;
CRecordVector<CLayoutItem> _outputLayout_Items;
unsigned _outputPathCount;
int _outputPathRowStep;
int _outputLayout_BaseWindowX;
int _outputLayout_BaseWindowY;
int _outputLayout_BaseControlsTop;
int _outputGroupGapY;
RECT _outputTemplate_ItemLabelRect;
RECT _outputTemplate_CountLabelRect;
RECT _outputTemplate_CountComboRect;
RECT _outputTemplate_ArchiveLabelRect;
RECT _outputTemplate_ArchiveComboRects[kNumOutputPathRows];
RECT _outputTemplate_ArchiveButtonRects[kNumOutputPathRows];
NWindows::NControl::CComboBox m_ArchivePath;
NWindows::NControl::CComboBox m_OutputPathCount;
NWindows::NControl::CComboBox m_ExtraArchivePaths[kNumOutputPathRows - 1];
NWindows::NControl::CComboBox m_Format;
NWindows::NControl::CComboBox m_Level;
NWindows::NControl::CComboBox m_Method;
@ -339,8 +377,34 @@ public:
void UpdatePasswordControl();
bool IsShowPasswordChecked() const { return IsButtonCheckedBool(IDX_PASSWORD_SHOW); }
bool IsMultiItemMode() const { return Info.ItemPaths.Size() > 1; }
unsigned GetFormatIndex();
void InitOutputPathLayout();
void UpdateOutputPathLayout();
void UpdateOutputPathControls();
void RefreshArchivePathInfo();
void SyncPrimaryArcPathFromControl();
void SyncExtraArcPathsFromControls();
void SetOutputPathCount(unsigned count, bool syncFromControls = true);
void SetOutputArcPaths(const UStringVector &paths);
bool GetOutputArcPaths(UStringVector &paths) const;
void InitItemOutputGroups();
void CreateDynamicItemOutputControls();
void LayoutItemOutputGroups();
void UpdateItemOutputGroupControls(unsigned groupIndex);
void SyncItemOutputGroupFromControls(unsigned groupIndex);
void SyncAllItemOutputGroupsFromControls();
void SetItemOutputGroupCount(unsigned groupIndex, unsigned count, bool syncFromControls = true);
bool GetItemOutputGroupPaths(UStringVector &itemPaths, UStringVector &paths) const;
bool BrowseItemOutputPath(unsigned groupIndex, unsigned pathIndex);
void UpdateSeparateItemModeControls();
bool GetItemArcPaths(UStringVector &itemPaths, UStringVector &paths) const;
void BuildItemArcPath(const UString &inputPath, UString &path);
void UpdateItemArcPathToCurrentFormat(UString &path, int prevFormat, bool prevWasSFX);
void UpdateArcPathToCurrentFormat(UString &path, int prevFormat, bool prevWasSFX);
void UpdateExtraArcPathsForFormatChange(int prevFormat, bool prevWasSFX);
bool BrowseArchivePath(UString &path, bool allowFormatChange, bool &formatWasChanged);
bool SetArcPathFields(const UString &path, UString &name, bool always);
bool SetArcPathFields(const UString &path);
bool GetFinalPath_Smart(UString &resPath) const;
@ -351,6 +415,7 @@ public:
void EnableMultiCombo(unsigned id);
void FormatChanged(bool isChanged);
void OnButtonSetArchivePath(unsigned index);
void OnButtonSetArchive();
bool IsSFX();
void OnButtonSFX();
@ -381,11 +446,18 @@ public:
INT_PTR Create(HWND wndParent = NULL)
{
BIG_DIALOG_SIZE(400, 320);
BIG_DIALOG_SIZE(400, 430);
return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS), wndParent);
}
CCompressDialog() {}
CCompressDialog():
_ramSize_Defined(false),
_outputLayout_Inited(false),
_outputPathCount(1),
_outputPathRowStep(0),
_outputLayout_BaseWindowX(0),
_outputLayout_BaseWindowY(0)
{}
};

View file

@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"
#define xc 400
#define yc 320
#define yc 430
#undef gSize
#undef gSpace
@ -34,7 +34,9 @@
#define g4xs (xc - gSize - gSpace)
#define g4xs2 (g4xs - m - m)
#define yOpt 80
#define yTopShift 105
#define yOpt (80 + yTopShift)
#define xArcFolderOffs 40
@ -59,61 +61,78 @@ IDD_COMPRESS DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
CAPTION "Add to Archive"
BEGIN
LTEXT "", IDT_COMPRESS_ARCHIVE_FOLDER, m + xArcFolderOffs, m, xc - xArcFolderOffs, 8
LTEXT "&Archive:", IDT_COMPRESS_ARCHIVE, m, 12, xArcFolderOffs, 8
COMBOBOX IDC_COMPRESS_ARCHIVE, m + xArcFolderOffs, 18, xc - bxsDots - 12 - xArcFolderOffs, 126, MY_COMBO_WITH_EDIT
PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE, xs - m - bxsDots, 16, bxsDots, bys, WS_GROUP
LTEXT "&Count:", IDT_COMPRESS_OUTPUT_PATHS_NUM, m, 20, xArcFolderOffs, 8
COMBOBOX IDC_COMPRESS_OUTPUT_PATHS_NUM, m + xArcFolderOffs, 18, 56, 80, MY_COMBO
CONTROL "Map selected items to output archives", IDX_COMPRESS_SEPARATE_ITEMS, MY_CHECKBOX,
m + xArcFolderOffs + 122, 20, xc - xArcFolderOffs - 122, 10
LTEXT "Archive &format:", IDT_COMPRESS_FORMAT, m, 41, g0xs, 8
COMBOBOX IDC_COMPRESS_FORMAT, g1x, 39, g1xs, 80, MY_COMBO | CBS_SORT
LTEXT "Compression &level:", IDT_COMPRESS_LEVEL, m, 62, g0xs, 8
COMBOBOX IDC_COMPRESS_LEVEL, g1x, 60, g1xs, 80, MY_COMBO
LTEXT "Compression &method:", IDT_COMPRESS_METHOD, m, 83, g0xs, 8
COMBOBOX IDC_COMPRESS_METHOD, g1x, 81, g1xs, 80, MY_COMBO
LTEXT "&Archive:", IDT_COMPRESS_ARCHIVE, m, 41, xArcFolderOffs, 8
COMBOBOX IDC_COMPRESS_ARCHIVE, m + xArcFolderOffs, 39, xc - bxsDots - 12 - xArcFolderOffs, 126, MY_COMBO_WITH_EDIT
PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE, xs - m - bxsDots, 37, bxsDots, bys, WS_GROUP
LTEXT "&Dictionary size:", IDT_COMPRESS_DICTIONARY, m, 104, g0xs, 8
COMBOBOX IDC_COMPRESS_DICTIONARY, g1x, 102, g1xs, 167, MY_COMBO
COMBOBOX IDC_COMPRESS_ARCHIVE2, m + xArcFolderOffs, 60, xc - bxsDots - 12 - xArcFolderOffs, 126, MY_COMBO_WITH_EDIT
PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE2, xs - m - bxsDots, 58, bxsDots, bys
COMBOBOX IDC_COMPRESS_ARCHIVE3, m + xArcFolderOffs, 81, xc - bxsDots - 12 - xArcFolderOffs, 126, MY_COMBO_WITH_EDIT
PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE3, xs - m - bxsDots, 79, bxsDots, bys
COMBOBOX IDC_COMPRESS_ARCHIVE4, m + xArcFolderOffs, 102, xc - bxsDots - 12 - xArcFolderOffs, 126, MY_COMBO_WITH_EDIT
PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE4, xs - m - bxsDots, 100, bxsDots, bys
COMBOBOX IDC_COMPRESS_ARCHIVE5, m + xArcFolderOffs, 123, xc - bxsDots - 12 - xArcFolderOffs, 126, MY_COMBO_WITH_EDIT
PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE5, xs - m - bxsDots, 121, bxsDots, bys
LTEXT "Archive &format:", IDT_COMPRESS_FORMAT, m, 41 + yTopShift, g0xs, 8
COMBOBOX IDC_COMPRESS_FORMAT, g1x, 39 + yTopShift, g1xs, 80, MY_COMBO | CBS_SORT
LTEXT "Compression &level:", IDT_COMPRESS_LEVEL, m, 62 + yTopShift, g0xs, 8
COMBOBOX IDC_COMPRESS_LEVEL, g1x, 60 + yTopShift, g1xs, 80, MY_COMBO
LTEXT "Compression &method:", IDT_COMPRESS_METHOD, m, 83 + yTopShift, g0xs, 8
COMBOBOX IDC_COMPRESS_METHOD, g1x, 81 + yTopShift, g1xs, 80, MY_COMBO
LTEXT "&Dictionary size:", IDT_COMPRESS_DICTIONARY, m, 104 + yTopShift, g0xs, 8
COMBOBOX IDC_COMPRESS_DICTIONARY, g1x, 102 + yTopShift, g1xs, 167, MY_COMBO
// LTEXT "&Dictionary size:", IDT_COMPRESS_DICTIONARY, m, 104, DICT_x - m, 16 // 8, SS_LEFTNOWORDWRAP
// LTEXT "", IDT_COMPRESS_PARAMS_INFO, m, 283, xs, MY_TEXT_NOPREFIX
// CTEXT "-", 0, DICT_x - DICT_SIZE_SPACE, 104, DICT_SIZE_SPACE, 8
// COMBOBOX IDC_COMPRESS_DICTIONARY2, DICT2_x, 102, DICT_SIZE, 140, MY_COMBO
// COMBOBOX IDC_COMPRESS_DICTIONARY, DICT_x, 102, DICT_SIZE, 140, MY_COMBO
LTEXT "&Word size:", IDT_COMPRESS_ORDER, m, 125, g0xs, 8
COMBOBOX IDC_COMPRESS_ORDER, g1x, 123, g1xs, 140, MY_COMBO
LTEXT "&Word size:", IDT_COMPRESS_ORDER, m, 125 + yTopShift, g0xs, 8
COMBOBOX IDC_COMPRESS_ORDER, g1x, 123 + yTopShift, g1xs, 140, MY_COMBO
LTEXT "&Solid Block size:", IDT_COMPRESS_SOLID, m, 146, g0xs, 8
COMBOBOX IDC_COMPRESS_SOLID, g1x, 144, g1xs, 140, MY_COMBO
LTEXT "&Solid Block size:", IDT_COMPRESS_SOLID, m, 146 + yTopShift, g0xs, 8
COMBOBOX IDC_COMPRESS_SOLID, g1x, 144 + yTopShift, g1xs, 140, MY_COMBO
LTEXT "Number of CPU &threads:", IDT_COMPRESS_THREADS, m, 167, g0xs, 8
COMBOBOX IDC_COMPRESS_THREADS, g1x, 165, g1xs - 40, 140, MY_COMBO
RTEXT "", IDT_COMPRESS_HARDWARE_THREADS, g1x + g1xs - 40, 167, 40, 16, SS_NOPREFIX
LTEXT "Number of CPU &threads:", IDT_COMPRESS_THREADS, m, 167 + yTopShift, g0xs, 8
COMBOBOX IDC_COMPRESS_THREADS, g1x, 165 + yTopShift, g1xs - 40, 140, MY_COMBO
RTEXT "", IDT_COMPRESS_HARDWARE_THREADS, g1x + g1xs - 40, 167 + yTopShift, 40, 16, SS_NOPREFIX
LTEXT "Memory usage for Compressing:", IDT_COMPRESS_MEMORY, m, 184, g2xs, 8
COMBOBOX IDC_COMPRESS_MEM_USE, g3x, 188, g3xs, 140, MY_COMBO
LTEXT "", IDT_COMPRESS_MEMORY_VALUE, m, 194, g2xs, MY_TEXT_NOPREFIX
LTEXT "Memory usage for Compressing:", IDT_COMPRESS_MEMORY, m, 184 + yTopShift, g2xs, 8
COMBOBOX IDC_COMPRESS_MEM_USE, g3x, 188 + yTopShift, g3xs, 140, MY_COMBO
LTEXT "", IDT_COMPRESS_MEMORY_VALUE, m, 194 + yTopShift, g2xs, MY_TEXT_NOPREFIX
LTEXT "Memory usage for Decompressing:", IDT_COMPRESS_MEMORY_DE, m, 208, g2xs, 8
RTEXT "", IDT_COMPRESS_MEMORY_DE_VALUE, g3x, 208, g3xs, MY_TEXT_NOPREFIX
LTEXT "Memory usage for Decompressing:", IDT_COMPRESS_MEMORY_DE, m, 208 + yTopShift, g2xs, 8
RTEXT "", IDT_COMPRESS_MEMORY_DE_VALUE, g3x, 208 + yTopShift, g3xs, MY_TEXT_NOPREFIX
LTEXT "Split to &volumes, bytes:", IDT_SPLIT_TO_VOLUMES, m, 225, gSize, 8
COMBOBOX IDC_COMPRESS_VOLUME, m, 237, gSize, 73, MY_COMBO_WITH_EDIT
LTEXT "Split to &volumes, bytes:", IDT_SPLIT_TO_VOLUMES, m, 225 + yTopShift, gSize, 8
COMBOBOX IDC_COMPRESS_VOLUME, m, 237 + yTopShift, gSize, 73, MY_COMBO_WITH_EDIT
LTEXT "Parameters:", IDT_COMPRESS_PARAMETERS, m, 256, gSize, 8
EDITTEXT IDE_COMPRESS_PARAMETERS, m, 268, gSize, 14, ES_AUTOHSCROLL
LTEXT "Parameters:", IDT_COMPRESS_PARAMETERS, m, 256 + yTopShift, gSize, 8
EDITTEXT IDE_COMPRESS_PARAMETERS, m, 268 + yTopShift, gSize, 14, ES_AUTOHSCROLL
PUSHBUTTON "Options", IDB_COMPRESS_OPTIONS, m, 292, bxs, bys
LTEXT "", IDT_COMPRESS_OPTIONS, m + bxs + m, 294, gSize - bxs - m, 16, SS_NOPREFIX
PUSHBUTTON "Options", IDB_COMPRESS_OPTIONS, m, 292 + yTopShift, bxs, bys
LTEXT "", IDT_COMPRESS_OPTIONS, m + bxs + m, 294 + yTopShift, gSize - bxs - m, 16, SS_NOPREFIX
LTEXT "&Update mode:", IDT_COMPRESS_UPDATE_MODE, g4x, 41, 80, 8
COMBOBOX IDC_COMPRESS_UPDATE_MODE, g4x + 84, 39, g4xs - 84, 80, MY_COMBO
LTEXT "&Update mode:", IDT_COMPRESS_UPDATE_MODE, g4x, 41 + yTopShift, 80, 8
COMBOBOX IDC_COMPRESS_UPDATE_MODE, g4x + 84, 39 + yTopShift, g4xs - 84, 80, MY_COMBO
LTEXT "Path mode:", IDT_COMPRESS_PATH_MODE, g4x, 61, 80, 8
COMBOBOX IDC_COMPRESS_PATH_MODE, g4x + 84, 59, g4xs - 84, 80, MY_COMBO
LTEXT "Path mode:", IDT_COMPRESS_PATH_MODE, g4x, 61 + yTopShift, 80, 8
COMBOBOX IDC_COMPRESS_PATH_MODE, g4x + 84, 59 + yTopShift, g4xs - 84, 80, MY_COMBO
GROUPBOX "Options", IDG_COMPRESS_OPTIONS, g4x, yOpt, g4xs, GROUP_Y_SIZE
@ -147,7 +166,6 @@ BEGIN
PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys
END
#ifdef UNDER_CE
#undef m

View file

@ -27,9 +27,19 @@
#define IDE_COMPRESS_PASSWORD1 120
#define IDE_COMPRESS_PASSWORD2 121
#define IDC_COMPRESS_ENCRYPTION_METHOD 122
#define IDC_COMPRESS_OUTPUT_PATHS_NUM 125
#define IDT_COMPRESS_ARCHIVE_FOLDER 130
#define IDC_COMPRESS_ARCHIVE2 180
#define IDB_COMPRESS_SET_ARCHIVE2 181
#define IDC_COMPRESS_ARCHIVE3 182
#define IDB_COMPRESS_SET_ARCHIVE3 183
#define IDC_COMPRESS_ARCHIVE4 184
#define IDB_COMPRESS_SET_ARCHIVE4 185
#define IDC_COMPRESS_ARCHIVE5 186
#define IDB_COMPRESS_SET_ARCHIVE5 187
// #define IDB_COMPRESS_OPTIONS 140
#define IDB_COMPRESS_OPTIONS 2100
#define IDT_COMPRESS_OPTIONS 141
@ -67,6 +77,8 @@
#define IDT_COMPRESS_MEMORY_DE 4018
#define IDX_COMPRESS_DEL 4019
#define IDT_COMPRESS_OUTPUT_PATHS_NUM 4021
#define IDX_COMPRESS_SEPARATE_ITEMS 4022
#define IDX_COMPRESS_NT_SYM_LINKS 4040
#define IDX_COMPRESS_NT_HARD_LINKS 4041

View file

@ -29,12 +29,35 @@ using namespace NFile;
using namespace NDir;
static const char * const kDefaultSfxModule = "7z.sfx";
static const char * const kSFXExtension = "exe";
extern void AddMessageToString(UString &dest, const UString &src);
UString HResultToMessage(HRESULT errorCode);
static void AddUniquePath(UStringVector &paths, const UString &path)
{
FOR_VECTOR (i, paths)
if (path.IsEqualTo_NoCase(paths[i]))
return;
paths.Add(path);
}
static void PrepareWorkingDirForArchivePath(const UString &userArchivePath, CUpdateOptions &options)
{
NWorkDir::CInfo workDirInfo;
workDirInfo.Load();
options.WorkingDir.Empty();
if (workDirInfo.Mode != NWorkDir::NMode::kCurrent)
{
FString fullPath;
if (!MyGetFullPathName(us2fs(userArchivePath), fullPath))
return;
FString namePart;
options.WorkingDir = GetWorkDir(workDirInfo, fullPath, namePart);
CreateComplexDir(options.WorkingDir);
}
}
class CThreadUpdating: public CProgressThreadVirt
{
HRESULT ProcessVirt() Z7_override;
@ -50,15 +73,67 @@ public:
HRESULT CThreadUpdating::ProcessVirt()
{
CUpdateErrorInfo ei;
HRESULT res = UpdateArchive(codecs, *formatIndices, *cmdArcPath,
*WildcardCensor, *Options,
ei, UpdateCallbackGUI, UpdateCallbackGUI, needSetPath);
FinalMessage.ErrorMessage.Message = ei.Message.Ptr();
ErrorPaths = ei.FileNames;
if (res != S_OK)
return res;
return HRESULT_FROM_WIN32(ei.SystemError);
if (!Options->SeparateItemMode)
{
CUpdateErrorInfo ei;
HRESULT res = UpdateArchive(codecs, *formatIndices, *cmdArcPath,
*WildcardCensor, *Options,
ei, UpdateCallbackGUI, UpdateCallbackGUI, needSetPath);
FinalMessage.ErrorMessage.Message = ei.Message.Ptr();
ErrorPaths = ei.FileNames;
if (res != S_OK)
return res;
return HRESULT_FROM_WIN32(ei.SystemError);
}
if (Options->SeparateItemPaths.IsEmpty() ||
Options->SeparateItemPaths.Size() != Options->SeparateItemArchivePaths.Size())
{
FinalMessage.ErrorMessage.Message = L"Invalid per-item output configuration";
return E_FAIL;
}
NUpdateArchive::CActionSet actionSet = NUpdateArchive::k_ActionSet_Add;
if (!Options->Commands.IsEmpty())
actionSet = Options->Commands.Front().ActionSet;
FOR_VECTOR (i, Options->SeparateItemPaths)
{
CUpdateOptions options = *Options;
options.SeparateItemMode = false;
options.SeparateItemPaths.Clear();
options.SeparateItemArchivePaths.Clear();
options.Commands.Clear();
CUpdateArchiveCommand command;
command.ActionSet = actionSet;
command.UserArchivePath = Options->SeparateItemArchivePaths[i];
options.Commands.Add(command);
if (!options.SetArcPath(codecs, command.UserArchivePath))
{
FinalMessage.ErrorMessage.Message = L"Update is not supported";
return E_NOTIMPL;
}
PrepareWorkingDirForArchivePath(command.UserArchivePath, options);
NWildcard::CCensor censor;
censor.AddPreItem_NoWildcard(Options->SeparateItemPaths[i]);
CUpdateErrorInfo ei;
HRESULT res = UpdateArchive(codecs, *formatIndices, command.UserArchivePath,
censor, options,
ei, UpdateCallbackGUI, UpdateCallbackGUI, false);
FinalMessage.ErrorMessage.Message = ei.Message.Ptr();
ErrorPaths = ei.FileNames;
if (res != S_OK)
return res;
if (ei.ThereIsError())
return ei.Get_HRESULT_Error();
}
return S_OK;
}
@ -318,8 +393,8 @@ static HRESULT ShowDialog(
CUpdateOptions &options,
CUpdateCallbackGUI *callback, HWND hwndParent)
{
if (options.Commands.Size() != 1)
throw "It must be one command";
if (options.Commands.IsEmpty())
options.SetActionCommand_Add();
/*
FString currentDirPrefix;
#ifndef UNDER_CE
@ -418,9 +493,34 @@ static HRESULT ShowDialog(
return E_FAIL;
}
// di.ArchiveName = options.ArchivePath.GetFinalPath();
di.ArcPath = options.ArchivePath.GetPathWithoutExt();
di.ArcPaths.Clear();
FOR_VECTOR (i, options.Commands)
{
const CUpdateArchiveCommand &command = options.Commands[i];
UString path = command.UserArchivePath;
if (path.IsEmpty())
path = command.ArchivePath.GetFinalPath();
if (!path.IsEmpty())
di.ArcPaths.Add(path);
}
if (di.ArcPaths.IsEmpty())
di.ArcPaths.Add(options.ArchivePath.GetFinalPath());
di.ArcPath = di.ArcPaths.Front();
dialog.OriginalFileName = fs2us(fileInfo.Name);
di.ItemPaths.Clear();
FOR_VECTOR (i, censor)
{
const NWildcard::CCensorPath &cp = censor[i];
if (!cp.Include)
continue;
UString path = cp.Path;
path.Trim();
if (!path.IsEmpty())
AddUniquePath(di.ItemPaths, path);
}
di.ItemOutputItemPaths = options.SeparateItemPaths;
di.ItemArcPaths = options.SeparateItemArchivePaths;
di.SeparateItemArchives = options.SeparateItemMode;
di.PathMode = options.PathMode;
@ -443,7 +543,7 @@ static HRESULT ShowDialog(
di.KeepName = !oneFile;
NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet;
NUpdateArchive::CActionSet actionSet = options.Commands.Front().ActionSet;
{
int index = FindActionSet(actionSet);
@ -513,30 +613,39 @@ static HRESULT ShowDialog(
options.OpenShareForWrite = di.OpenShareForWrite;
ParseAndAddPropertires(options.MethodMode.Properties, optionStrings);
if (di.SFXMode)
options.SfxMode = true;
options.SfxMode = di.SFXMode;
options.MethodMode.Type = COpenType();
options.MethodMode.Type_Defined = true;
options.MethodMode.Type.FormatIndex = di.FormatIndex;
options.ArchivePath.VolExtension = archiverInfo.GetMainExt();
if (di.SFXMode)
options.ArchivePath.BaseExtension = kSFXExtension;
else
options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension;
options.ArchivePath.ParseFromPath(di.ArcPath, k_ArcNameMode_Smart);
NWorkDir::CInfo workDirInfo;
workDirInfo.Load();
options.WorkingDir.Empty();
if (workDirInfo.Mode != NWorkDir::NMode::kCurrent)
options.Commands.Clear();
FOR_VECTOR (i, di.ArcPaths)
{
FString fullPath;
MyGetFullPathName(us2fs(di.ArcPath), fullPath);
FString namePart;
options.WorkingDir = GetWorkDir(workDirInfo, fullPath, namePart);
CreateComplexDir(options.WorkingDir);
CUpdateArchiveCommand command;
command.ActionSet = actionSet;
command.UserArchivePath = di.ArcPaths[i];
options.Commands.Add(command);
}
if (options.Commands.IsEmpty())
{
CUpdateArchiveCommand command;
command.ActionSet = actionSet;
command.UserArchivePath = di.ArcPath;
options.Commands.Add(command);
}
// Paths returned by the dialog are explicit user choices. Re-parse them in
// smart mode so names like "Download" get one ".7z", while "Download.7z"
// doesn't get the archive extension appended twice.
options.ArcNameMode = k_ArcNameMode_Smart;
options.SeparateItemMode = di.SeparateItemArchives;
options.SeparateItemPaths = di.ItemOutputItemPaths;
options.SeparateItemArchivePaths = di.ItemArcPaths;
if (!options.SetArcPath(codecs, options.Commands.Front().UserArchivePath))
return E_NOTIMPL;
PrepareWorkingDirForArchivePath(options.Commands.Front().UserArchivePath, options);
return S_OK;
}

View file

@ -147,3 +147,10 @@ C_OBJS = \
!include "../../Sort.mak"
!include "../../7zip.mak"
$O\CompressDialog.obj: CompressDialog.cpp CompressDialog.h CompressDialogRes.h
$O\ArchiveCommandLine.obj: ..\Common\ArchiveCommandLine.cpp ..\Common\Update.h
$O\Update.obj: ..\Common\Update.cpp ..\Common\Update.h
$O\UpdateCallbackGUI.obj: UpdateCallbackGUI.cpp ..\Common\Update.h UpdateCallbackGUI.h
$O\UpdateGUI.obj: UpdateGUI.cpp ..\Common\Update.h UpdateGUI.h CompressDialog.h CompressDialogRes.h
$O\resource.res: resource.rc resource2.rc CompressDialog.rc CompressDialogRes.h

View file

@ -237,7 +237,7 @@ $(PROGPATH): $O $O/asm $(OBJS) $(DEF_FILE)
!IFNDEF NO_DEFAULT_RES
$O\resource.res: $(*B).rc
rc $(RFLAGS) -fo$@ $**
rc $(RFLAGS) -fo$@ $(@B).rc
!ENDIF
$O\StdAfx.obj: $(*B).cpp
$(COMPL_PCH)