mirror of
https://github.com/ip7z/7zip.git
synced 2026-04-21 06:03:40 +00:00
Merge 94a386e0f4 into 839151eaaa
This commit is contained in:
commit
1519f84230
13 changed files with 2105 additions and 174 deletions
|
|
@ -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/");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
{}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue