5 #include "UpdateGUI.h"
\r
7 #include "Common/IntToString.h"
\r
8 #include "Common/StringConvert.h"
\r
9 #include "Common/StringToInt.h"
\r
11 #include "Windows/Error.h"
\r
12 #include "Windows/FileDir.h"
\r
13 #include "Windows/Thread.h"
\r
15 #include "../Common/WorkDir.h"
\r
17 #include "../Explorer/MyMessages.h"
\r
19 #include "../FileManager/LangUtils.h"
\r
20 #include "../FileManager/ProgramLocation.h"
\r
21 #include "../FileManager/StringUtils.h"
\r
22 #include "../FileManager/resourceGui.h"
\r
24 #include "CompressDialog.h"
\r
25 #include "UpdateGUI.h"
\r
27 #include "resource2.h"
\r
29 using namespace NWindows;
\r
30 using namespace NFile;
\r
32 static const wchar_t *kDefaultSfxModule = L"7z.sfx";
\r
33 static const wchar_t *kSFXExtension = L"exe";
\r
35 extern void AddMessageToString(UString &dest, const UString &src);
\r
37 UString HResultToMessage(HRESULT errorCode);
\r
39 class CThreadUpdating: public CProgressThreadVirt
\r
41 HRESULT ProcessVirt();
\r
44 CUpdateCallbackGUI *UpdateCallbackGUI;
\r
45 const NWildcard::CCensor *WildcardCensor;
\r
46 CUpdateOptions *Options;
\r
49 HRESULT CThreadUpdating::ProcessVirt()
\r
51 CUpdateErrorInfo ei;
\r
52 HRESULT res = UpdateArchive(codecs, *WildcardCensor, *Options,
\r
53 ei, UpdateCallbackGUI, UpdateCallbackGUI);
\r
54 ErrorMessage = ei.Message;
\r
55 ErrorPath1 = ei.FileName;
\r
56 ErrorPath2 = ei.FileName2;
\r
57 if (ei.SystemError != S_OK && ei.SystemError != E_FAIL && ei.SystemError != E_ABORT)
\r
58 return ei.SystemError;
\r
62 static void AddProp(CObjectVector<CProperty> &properties, const UString &name, const UString &value)
\r
67 properties.Add(prop);
\r
70 static void AddProp(CObjectVector<CProperty> &properties, const UString &name, UInt32 value)
\r
73 ConvertUInt64ToString(value, tmp);
\r
74 AddProp(properties, name, tmp);
\r
77 static void AddProp(CObjectVector<CProperty> &properties, const UString &name, bool value)
\r
79 AddProp(properties, name, value ? UString(L"on"): UString(L"off"));
\r
82 static bool IsThereMethodOverride(bool is7z, const UString &propertiesString)
\r
84 UStringVector strings;
\r
85 SplitString(propertiesString, strings);
\r
86 for (int i = 0; i < strings.Size(); i++)
\r
88 const UString &s = strings[i];
\r
92 UInt64 n = ConvertStringToUInt64(s, &end);
\r
93 if (n == 0 && *end == L'=')
\r
99 if (s[0] == L'm' && s[1] == L'=')
\r
106 static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
\r
107 const UString &propertiesString)
\r
109 UStringVector strings;
\r
110 SplitString(propertiesString, strings);
\r
111 for (int i = 0; i < strings.Size(); i++)
\r
113 const UString &s = strings[i];
\r
114 CProperty property;
\r
115 int index = s.Find(L'=');
\r
120 property.Name = s.Left(index);
\r
121 property.Value = s.Mid(index + 1);
\r
123 properties.Add(property);
\r
127 static UString GetNumInBytesString(UInt64 v)
\r
130 ConvertUInt64ToString(v, s);
\r
131 size_t len = wcslen(s);
\r
137 static void SetOutProperties(
\r
138 CObjectVector<CProperty> &properties,
\r
142 const UString &method,
\r
146 bool solidIsSpecified, UInt64 solidBlockSize,
\r
147 bool multiThreadIsAllowed, UInt32 numThreads,
\r
148 const UString &encryptionMethod,
\r
149 bool encryptHeadersIsAllowed, bool encryptHeaders,
\r
150 bool /* sfxMode */)
\r
152 if (level != (UInt32)(Int32)-1)
\r
153 AddProp(properties, L"x", (UInt32)level);
\r
156 if (!method.IsEmpty())
\r
157 AddProp(properties, is7z ? L"0": L"m", method);
\r
158 if (dictionary != (UInt32)(Int32)-1)
\r
167 AddProp(properties, name, GetNumInBytesString(dictionary));
\r
169 if (order != (UInt32)(Int32)-1)
\r
178 AddProp(properties, name, (UInt32)order);
\r
182 if (!encryptionMethod.IsEmpty())
\r
183 AddProp(properties, L"em", encryptionMethod);
\r
185 if (encryptHeadersIsAllowed)
\r
186 AddProp(properties, L"he", encryptHeaders);
\r
187 if (solidIsSpecified)
\r
188 AddProp(properties, L"s", GetNumInBytesString(solidBlockSize));
\r
189 if (multiThreadIsAllowed)
\r
190 AddProp(properties, L"mt", numThreads);
\r
193 static HRESULT ShowDialog(
\r
195 const NWildcard::CCensor &censor,
\r
196 CUpdateOptions &options, CUpdateCallbackGUI *callback, HWND hwndParent)
\r
198 if (options.Commands.Size() != 1)
\r
199 throw "It must be one command";
\r
200 UString currentDirPrefix;
\r
203 if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix))
\r
205 NName::NormalizeDirPathPrefix(currentDirPrefix);
\r
209 bool oneFile = false;
\r
210 NFind::CFileInfoW fileInfo;
\r
212 if (censor.Pairs.Size() > 0)
\r
214 const NWildcard::CPair &pair = censor.Pairs[0];
\r
215 if (pair.Head.IncludeItems.Size() > 0)
\r
217 const NWildcard::CItem &item = pair.Head.IncludeItems[0];
\r
220 name = pair.Prefix;
\r
221 for (int i = 0; i < item.PathParts.Size(); i++)
\r
224 name += WCHAR_PATH_SEPARATOR;
\r
225 name += item.PathParts[i];
\r
227 if (fileInfo.Find(name))
\r
229 if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1)
\r
230 oneFile = !fileInfo.IsDir();
\r
236 CCompressDialog dialog;
\r
237 NCompressDialog::CInfo &di = dialog.Info;
\r
238 dialog.ArcFormats = &codecs->Formats;
\r
239 for (int i = 0; i < codecs->Formats.Size(); i++)
\r
241 const CArcInfoEx &ai = codecs->Formats[i];
\r
242 if (ai.Name.CompareNoCase(L"swfc") == 0)
\r
243 if (!oneFile || name.Right(4).CompareNoCase(L".swf") != 0)
\r
245 if (ai.UpdateEnabled && (oneFile || !ai.KeepName))
\r
246 dialog.ArcIndices.Add(i);
\r
248 if (dialog.ArcIndices.Size() == 0)
\r
250 ShowErrorMessage(L"No Update Engines");
\r
254 // di.ArchiveName = options.ArchivePath.GetFinalPath();
\r
255 di.ArchiveName = options.ArchivePath.GetPathWithoutExt();
\r
256 dialog.OriginalFileName = options.ArchivePath.Prefix + fileInfo.Name;
\r
258 di.CurrentDirPrefix = currentDirPrefix;
\r
259 di.SFXMode = options.SfxMode;
\r
260 di.OpenShareForWrite = options.OpenShareForWrite;
\r
262 if (callback->PasswordIsDefined)
\r
263 di.Password = callback->Password;
\r
265 di.KeepName = !oneFile;
\r
267 if (dialog.Create(hwndParent) != IDOK)
\r
270 options.VolumesSizes = di.VolumeSizes;
\r
272 if (di.VolumeSizeIsDefined)
\r
274 MyMessageBox(L"Splitting to volumes is not supported");
\r
279 NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet;
\r
281 switch(di.UpdateMode)
\r
283 case NCompressDialog::NUpdateMode::kAdd:
\r
284 actionSet = NUpdateArchive::kAddActionSet;
\r
286 case NCompressDialog::NUpdateMode::kUpdate:
\r
287 actionSet = NUpdateArchive::kUpdateActionSet;
\r
289 case NCompressDialog::NUpdateMode::kFresh:
\r
290 actionSet = NUpdateArchive::kFreshActionSet;
\r
292 case NCompressDialog::NUpdateMode::kSynchronize:
\r
293 actionSet = NUpdateArchive::kSynchronizeActionSet;
\r
298 const CArcInfoEx &archiverInfo = codecs->Formats[di.FormatIndex];
\r
299 callback->PasswordIsDefined = (!di.Password.IsEmpty());
\r
300 if (callback->PasswordIsDefined)
\r
301 callback->Password = di.Password;
\r
303 options.MethodMode.Properties.Clear();
\r
305 bool is7z = archiverInfo.Name.CompareNoCase(L"7z") == 0;
\r
306 bool methodOverride = IsThereMethodOverride(is7z, di.Options);
\r
309 options.MethodMode.Properties,
\r
315 di.OrderMode, di.Order,
\r
316 di.SolidIsSpecified, di.SolidBlockSize,
\r
317 di.MultiThreadIsAllowed, di.NumThreads,
\r
318 di.EncryptionMethod,
\r
319 di.EncryptHeadersIsAllowed, di.EncryptHeaders,
\r
322 options.OpenShareForWrite = di.OpenShareForWrite;
\r
323 ParseAndAddPropertires(options.MethodMode.Properties, di.Options);
\r
326 options.SfxMode = true;
\r
327 options.MethodMode.FormatIndex = di.FormatIndex;
\r
329 options.ArchivePath.VolExtension = archiverInfo.GetMainExt();
\r
331 options.ArchivePath.BaseExtension = kSFXExtension;
\r
333 options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension;
\r
334 options.ArchivePath.ParseFromPath(di.ArchiveName);
\r
336 NWorkDir::CInfo workDirInfo;
\r
337 workDirInfo.Load();
\r
338 options.WorkingDir.Empty();
\r
339 if (workDirInfo.Mode != NWorkDir::NMode::kCurrent)
\r
342 NDirectory::MyGetFullPathName(di.ArchiveName, fullPath);
\r
343 options.WorkingDir = GetWorkDir(workDirInfo, fullPath);
\r
344 NDirectory::CreateComplexDirectory(options.WorkingDir);
\r
351 const NWildcard::CCensor &censor,
\r
352 CUpdateOptions &options,
\r
354 bool &messageWasDisplayed,
\r
355 CUpdateCallbackGUI *callback,
\r
358 messageWasDisplayed = false;
\r
361 RINOK(ShowDialog(codecs, censor, options, callback, hwndParent));
\r
363 if (options.SfxMode && options.SfxModule.IsEmpty())
\r
366 if (!GetProgramFolderPath(folder))
\r
368 options.SfxModule = folder + kDefaultSfxModule;
\r
371 CThreadUpdating tu;
\r
373 tu.codecs = codecs;
\r
375 tu.UpdateCallbackGUI = callback;
\r
376 tu.UpdateCallbackGUI->ProgressDialog = &tu.ProgressDialog;
\r
377 tu.UpdateCallbackGUI->Init();
\r
379 UString title = LangString(IDS_PROGRESS_COMPRESSING, 0x02000DC0);
\r
382 if (hwndParent != 0)
\r
384 tu.ProgressDialog.MainWindow = hwndParent;
\r
385 // tu.ProgressDialog.MainTitle = fileName;
\r
386 tu.ProgressDialog.MainAddTitle = title + L" ";
\r
390 tu.WildcardCensor = &censor;
\r
391 tu.Options = &options;
\r
392 tu.ProgressDialog.IconID = IDI_ICON;
\r
394 RINOK(tu.Create(title, hwndParent));
\r
396 messageWasDisplayed = tu.ThreadFinishedOK &
\r
397 tu.ProgressDialog.MessagesDisplayed;
\r