xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/ZipRegistry.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // ZipRegistry.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../../C/CpuArch.h"
6 
7 #include "../../../Common/IntToString.h"
8 #include "../../../Common/StringToInt.h"
9 
10 #include "../../../Windows/FileDir.h"
11 #include "../../../Windows/Registry.h"
12 #include "../../../Windows/Synchronization.h"
13 
14 // #include "../Explorer/ContextMenuFlags.h"
15 #include "ZipRegistry.h"
16 
17 using namespace NWindows;
18 using namespace NRegistry;
19 
20 static NSynchronization::CCriticalSection g_CS;
21 #define CS_LOCK NSynchronization::CCriticalSectionLock lock(g_CS);
22 
23 static LPCTSTR const kCuPrefix = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR);
24 
GetKeyPath(LPCTSTR path)25 static CSysString GetKeyPath(LPCTSTR path) { return kCuPrefix + (CSysString)path; }
26 
OpenMainKey(CKey & key,LPCTSTR keyName)27 static LONG OpenMainKey(CKey &key, LPCTSTR keyName)
28 {
29   return key.Open(HKEY_CURRENT_USER, GetKeyPath(keyName), KEY_READ);
30 }
31 
CreateMainKey(CKey & key,LPCTSTR keyName)32 static LONG CreateMainKey(CKey &key, LPCTSTR keyName)
33 {
34   return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName));
35 }
36 
Key_Set_UInt32(CKey & key,LPCTSTR name,UInt32 value)37 static void Key_Set_UInt32(CKey &key, LPCTSTR name, UInt32 value)
38 {
39   if (value == (UInt32)(Int32)-1)
40     key.DeleteValue(name);
41   else
42     key.SetValue(name, value);
43 }
44 
45 
Key_Get_UInt32(CKey & key,LPCTSTR name,UInt32 & value)46 static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value)
47 {
48   value = (UInt32)(Int32)-1;
49   key.GetValue_UInt32_IfOk(name, value);
50 }
51 
52 
Key_Set_BoolPair(CKey & key,LPCTSTR name,const CBoolPair & b)53 static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b)
54 {
55   if (b.Def)
56     key.SetValue(name, b.Val);
57 }
58 
Key_Set_bool_if_Changed(CKey & key,LPCTSTR name,bool val)59 static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val)
60 {
61   bool oldVal = false;
62   if (key.GetValue_bool_IfOk(name, oldVal) == ERROR_SUCCESS)
63     if (val == oldVal)
64       return;
65   key.SetValue(name, val);
66 }
67 
Key_Set_BoolPair_Delete_IfNotDef(CKey & key,LPCTSTR name,const CBoolPair & b)68 static void Key_Set_BoolPair_Delete_IfNotDef(CKey &key, LPCTSTR name, const CBoolPair &b)
69 {
70   if (b.Def)
71     Key_Set_bool_if_Changed(key, name, b.Val);
72   else
73     key.DeleteValue(name);
74 }
75 
Key_Get_BoolPair(CKey & key,LPCTSTR name,CBoolPair & b)76 static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
77 {
78   b.Val = false;
79   b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS);
80 }
81 
Key_Get_BoolPair_true(CKey & key,LPCTSTR name,CBoolPair & b)82 static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
83 {
84   b.Val = true;
85   b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS);
86 }
87 
88 namespace NExtract
89 {
90 
91 static LPCTSTR const kKeyName = TEXT("Extraction");
92 
93 static LPCTSTR const kExtractMode = TEXT("ExtractMode");
94 static LPCTSTR const kOverwriteMode = TEXT("OverwriteMode");
95 static LPCTSTR const kShowPassword = TEXT("ShowPassword");
96 static LPCTSTR const kPathHistory = TEXT("PathHistory");
97 static LPCTSTR const kSplitDest = TEXT("SplitDest");
98 static LPCTSTR const kElimDup = TEXT("ElimDup");
99 // static LPCTSTR const kAltStreams = TEXT("AltStreams");
100 static LPCTSTR const kNtSecur = TEXT("Security");
101 static LPCTSTR const kMemLimit = TEXT("MemLimit");
102 
Save() const103 void CInfo::Save() const
104 {
105   CS_LOCK
106   CKey key;
107   CreateMainKey(key, kKeyName);
108 
109   if (PathMode_Force)
110     key.SetValue(kExtractMode, (UInt32)PathMode);
111   if (OverwriteMode_Force)
112     key.SetValue(kOverwriteMode, (UInt32)OverwriteMode);
113 
114   Key_Set_BoolPair(key, kSplitDest, SplitDest);
115   Key_Set_BoolPair(key, kElimDup, ElimDup);
116   // Key_Set_BoolPair(key, kAltStreams, AltStreams);
117   Key_Set_BoolPair(key, kNtSecur, NtSecurity);
118   Key_Set_BoolPair(key, kShowPassword, ShowPassword);
119 
120   key.RecurseDeleteKey(kPathHistory);
121   key.SetValue_Strings(kPathHistory, Paths);
122 }
123 
Save_ShowPassword(bool showPassword)124 void Save_ShowPassword(bool showPassword)
125 {
126   CS_LOCK
127   CKey key;
128   CreateMainKey(key, kKeyName);
129   key.SetValue(kShowPassword, showPassword);
130 }
131 
Save_LimitGB(UInt32 limit_GB)132 void Save_LimitGB(UInt32 limit_GB)
133 {
134   CS_LOCK
135   CKey key;
136   CreateMainKey(key, kKeyName);
137   Key_Set_UInt32(key, kMemLimit, limit_GB);
138 }
139 
Load()140 void CInfo::Load()
141 {
142   PathMode = NPathMode::kCurPaths;
143   PathMode_Force = false;
144   OverwriteMode = NOverwriteMode::kAsk;
145   OverwriteMode_Force = false;
146 
147   SplitDest.Val = true;
148 
149   Paths.Clear();
150 
151   CS_LOCK
152   CKey key;
153   if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
154     return;
155 
156   key.GetValue_Strings(kPathHistory, Paths);
157   UInt32 v;
158   if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths)
159   {
160     PathMode = (NPathMode::EEnum)v;
161     PathMode_Force = true;
162   }
163   if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting)
164   {
165     OverwriteMode = (NOverwriteMode::EEnum)v;
166     OverwriteMode_Force = true;
167   }
168 
169   Key_Get_BoolPair_true(key, kSplitDest, SplitDest);
170 
171   Key_Get_BoolPair(key, kElimDup, ElimDup);
172   // Key_Get_BoolPair(key, kAltStreams, AltStreams);
173   Key_Get_BoolPair(key, kNtSecur, NtSecurity);
174   Key_Get_BoolPair(key, kShowPassword, ShowPassword);
175 }
176 
Read_ShowPassword()177 bool Read_ShowPassword()
178 {
179   CS_LOCK
180   CKey key;
181   bool showPassword = false;
182   if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
183     return showPassword;
184   key.GetValue_bool_IfOk(kShowPassword, showPassword);
185   return showPassword;
186 }
187 
Read_LimitGB()188 UInt32 Read_LimitGB()
189 {
190   CS_LOCK
191   CKey key;
192   UInt32 v = (UInt32)(Int32)-1;
193   if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS)
194     key.GetValue_UInt32_IfOk(kMemLimit, v);
195   return v;
196 }
197 
198 }
199 
200 namespace NCompression
201 {
202 
203 static LPCTSTR const kKeyName = TEXT("Compression");
204 
205 static LPCTSTR const kArcHistory = TEXT("ArcHistory");
206 static LPCWSTR const kArchiver = L"Archiver";
207 static LPCTSTR const kShowPassword = TEXT("ShowPassword");
208 static LPCTSTR const kEncryptHeaders = TEXT("EncryptHeaders");
209 
210 static LPCTSTR const kOptionsKeyName = TEXT("Options");
211 
212 static LPCTSTR const kLevel = TEXT("Level");
213 static LPCTSTR const kDictionary = TEXT("Dictionary");
214 // static LPCTSTR const kDictionaryChain = TEXT("DictionaryChain");
215 static LPCTSTR const kOrder = TEXT("Order");
216 static LPCTSTR const kBlockSize = TEXT("BlockSize");
217 static LPCTSTR const kNumThreads = TEXT("NumThreads");
218 static LPCWSTR const kMethod = L"Method";
219 static LPCWSTR const kOptions = L"Options";
220 static LPCWSTR const kEncryptionMethod = L"EncryptionMethod";
221 
222 static LPCTSTR const kNtSecur = TEXT("Security");
223 static LPCTSTR const kAltStreams = TEXT("AltStreams");
224 static LPCTSTR const kHardLinks = TEXT("HardLinks");
225 static LPCTSTR const kSymLinks = TEXT("SymLinks");
226 static LPCTSTR const kPreserveATime = TEXT("PreserveATime");
227 
228 static LPCTSTR const kTimePrec = TEXT("TimePrec");
229 static LPCTSTR const kMTime = TEXT("MTime");
230 static LPCTSTR const kATime = TEXT("ATime");
231 static LPCTSTR const kCTime = TEXT("CTime");
232 static LPCTSTR const kSetArcMTime = TEXT("SetArcMTime");
233 
SetRegString(CKey & key,LPCWSTR name,const UString & value)234 static void SetRegString(CKey &key, LPCWSTR name, const UString &value)
235 {
236   if (value.IsEmpty())
237     key.DeleteValue(name);
238   else
239     key.SetValue(name, value);
240 }
241 
GetRegString(CKey & key,LPCWSTR name,UString & value)242 static void GetRegString(CKey &key, LPCWSTR name, UString &value)
243 {
244   if (key.QueryValue(name, value) != ERROR_SUCCESS)
245     value.Empty();
246 }
247 
248 static LPCWSTR const kMemUse = L"MemUse"
249     #if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
250       L"32";
251     #else
252       L"64";
253     #endif
254 
Save() const255 void CInfo::Save() const
256 {
257   CS_LOCK
258 
259   CKey key;
260   CreateMainKey(key, kKeyName);
261 
262   Key_Set_BoolPair_Delete_IfNotDef (key, kNtSecur, NtSecurity);
263   Key_Set_BoolPair_Delete_IfNotDef (key, kAltStreams, AltStreams);
264   Key_Set_BoolPair_Delete_IfNotDef (key, kHardLinks, HardLinks);
265   Key_Set_BoolPair_Delete_IfNotDef (key, kSymLinks, SymLinks);
266   Key_Set_BoolPair_Delete_IfNotDef (key, kPreserveATime, PreserveATime);
267 
268   key.SetValue(kShowPassword, ShowPassword);
269   key.SetValue(kLevel, (UInt32)Level);
270   key.SetValue(kArchiver, ArcType);
271   key.SetValue(kShowPassword, ShowPassword);
272   key.SetValue(kEncryptHeaders, EncryptHeaders);
273   key.RecurseDeleteKey(kArcHistory);
274   key.SetValue_Strings(kArcHistory, ArcPaths);
275 
276   key.RecurseDeleteKey(kOptionsKeyName);
277   {
278     CKey optionsKey;
279     optionsKey.Create(key, kOptionsKeyName);
280     FOR_VECTOR (i, Formats)
281     {
282       const CFormatOptions &fo = Formats[i];
283       CKey fk;
284       fk.Create(optionsKey, fo.FormatID);
285 
286       SetRegString(fk, kMethod, fo.Method);
287       SetRegString(fk, kOptions, fo.Options);
288       SetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
289       SetRegString(fk, kMemUse, fo.MemUse);
290 
291       Key_Set_UInt32(fk, kLevel, fo.Level);
292       Key_Set_UInt32(fk, kDictionary, fo.Dictionary);
293       // Key_Set_UInt32(fk, kDictionaryChain, fo.DictionaryChain);
294       Key_Set_UInt32(fk, kOrder, fo.Order);
295       Key_Set_UInt32(fk, kBlockSize, fo.BlockLogSize);
296       Key_Set_UInt32(fk, kNumThreads, fo.NumThreads);
297 
298       Key_Set_UInt32(fk, kTimePrec, fo.TimePrec);
299       Key_Set_BoolPair_Delete_IfNotDef (fk, kMTime, fo.MTime);
300       Key_Set_BoolPair_Delete_IfNotDef (fk, kATime, fo.ATime);
301       Key_Set_BoolPair_Delete_IfNotDef (fk, kCTime, fo.CTime);
302       Key_Set_BoolPair_Delete_IfNotDef (fk, kSetArcMTime, fo.SetArcMTime);
303     }
304   }
305 }
306 
Load()307 void CInfo::Load()
308 {
309   ArcPaths.Clear();
310   Formats.Clear();
311 
312   Level = 5;
313   ArcType = L"7z";
314   ShowPassword = false;
315   EncryptHeaders = false;
316 
317   CS_LOCK
318   CKey key;
319 
320   if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
321     return;
322 
323   Key_Get_BoolPair(key, kNtSecur, NtSecurity);
324   Key_Get_BoolPair(key, kAltStreams, AltStreams);
325   Key_Get_BoolPair(key, kHardLinks, HardLinks);
326   Key_Get_BoolPair(key, kSymLinks, SymLinks);
327   Key_Get_BoolPair(key, kPreserveATime, PreserveATime);
328 
329   key.GetValue_Strings(kArcHistory, ArcPaths);
330 
331   {
332     CKey optionsKey;
333     if (optionsKey.Open(key, kOptionsKeyName, KEY_READ) == ERROR_SUCCESS)
334     {
335       CSysStringVector formatIDs;
336       optionsKey.EnumKeys(formatIDs);
337       FOR_VECTOR (i, formatIDs)
338       {
339         CKey fk;
340         CFormatOptions fo;
341         fo.FormatID = formatIDs[i];
342         if (fk.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS)
343         {
344           GetRegString(fk, kMethod, fo.Method);
345           GetRegString(fk, kOptions, fo.Options);
346           GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
347           GetRegString(fk, kMemUse, fo.MemUse);
348 
349           Key_Get_UInt32(fk, kLevel, fo.Level);
350           Key_Get_UInt32(fk, kDictionary, fo.Dictionary);
351           // Key_Get_UInt32(fk, kDictionaryChain, fo.DictionaryChain);
352           Key_Get_UInt32(fk, kOrder, fo.Order);
353           Key_Get_UInt32(fk, kBlockSize, fo.BlockLogSize);
354           Key_Get_UInt32(fk, kNumThreads, fo.NumThreads);
355 
356           Key_Get_UInt32(fk, kTimePrec, fo.TimePrec);
357           Key_Get_BoolPair(fk, kMTime, fo.MTime);
358           Key_Get_BoolPair(fk, kATime, fo.ATime);
359           Key_Get_BoolPair(fk, kCTime, fo.CTime);
360           Key_Get_BoolPair(fk, kSetArcMTime, fo.SetArcMTime);
361 
362           Formats.Add(fo);
363         }
364       }
365     }
366   }
367 
368   UString a;
369   if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS)
370     ArcType = a;
371   key.GetValue_UInt32_IfOk(kLevel, Level);
372   key.GetValue_bool_IfOk(kShowPassword, ShowPassword);
373   key.GetValue_bool_IfOk(kEncryptHeaders, EncryptHeaders);
374 }
375 
376 
ParseMemUse(const wchar_t * s,CMemUse & mu)377 static bool ParseMemUse(const wchar_t *s, CMemUse &mu)
378 {
379   mu.Clear();
380 
381   bool percentMode = false;
382   {
383     const wchar_t c = *s;
384     if (MyCharLower_Ascii(c) == 'p')
385     {
386       percentMode = true;
387       s++;
388     }
389   }
390   const wchar_t *end;
391   UInt64 number = ConvertStringToUInt64(s, &end);
392   if (end == s)
393     return false;
394 
395   wchar_t c = *end;
396 
397   if (percentMode)
398   {
399     if (c != 0)
400       return false;
401     mu.IsPercent = true;
402     mu.Val = number;
403     return true;
404   }
405 
406   if (c == 0)
407   {
408     mu.Val = number;
409     return true;
410   }
411 
412   c = MyCharLower_Ascii(c);
413 
414   const wchar_t c1 = end[1];
415 
416   if (c == '%')
417   {
418     if (c1 != 0)
419       return false;
420     mu.IsPercent = true;
421     mu.Val = number;
422     return true;
423   }
424 
425   if (c == 'b')
426   {
427     if (c1 != 0)
428       return false;
429     mu.Val = number;
430     return true;
431   }
432 
433   if (c1 != 0)
434     if (MyCharLower_Ascii(c1) != 'b' || end[2] != 0)
435       return false;
436 
437   unsigned numBits;
438   switch (c)
439   {
440     case 'k': numBits = 10; break;
441     case 'm': numBits = 20; break;
442     case 'g': numBits = 30; break;
443     case 't': numBits = 40; break;
444     default: return false;
445   }
446   if (number >= ((UInt64)1 << (64 - numBits)))
447     return false;
448   mu.Val = number << numBits;
449   return true;
450 }
451 
452 
Parse(const UString & s)453 void CMemUse::Parse(const UString &s)
454 {
455   IsDefined = ParseMemUse(s, *this);
456 }
457 
458 /*
459 void MemLimit_Save(const UString &s)
460 {
461   CS_LOCK
462   CKey key;
463   CreateMainKey(key, kKeyName);
464   SetRegString(key, kMemUse, s);
465 }
466 
467 bool MemLimit_Load(NCompression::CMemUse &mu)
468 {
469   mu.Clear();
470   UString a;
471   {
472     CS_LOCK
473     CKey key;
474     if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
475       return false;
476     if (key.QueryValue(kMemUse, a) != ERROR_SUCCESS)
477       return false;
478   }
479   if (a.IsEmpty())
480     return false;
481   mu.Parse(a);
482   return mu.IsDefined;
483 }
484 */
485 
486 }
487 
488 static LPCTSTR const kOptionsInfoKeyName = TEXT("Options");
489 
490 namespace NWorkDir
491 {
492 static LPCTSTR const kWorkDirType = TEXT("WorkDirType");
493 static LPCWSTR const kWorkDirPath = L"WorkDirPath";
494 static LPCTSTR const kTempRemovableOnly = TEXT("TempRemovableOnly");
495 
496 
Save() const497 void CInfo::Save()const
498 {
499   CS_LOCK
500   CKey key;
501   CreateMainKey(key, kOptionsInfoKeyName);
502   key.SetValue(kWorkDirType, (UInt32)Mode);
503   key.SetValue(kWorkDirPath, fs2us(Path));
504   key.SetValue(kTempRemovableOnly, ForRemovableOnly);
505 }
506 
Load()507 void CInfo::Load()
508 {
509   SetDefault();
510 
511   CS_LOCK
512   CKey key;
513   if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
514     return;
515 
516   UInt32 dirType;
517   if (key.GetValue_UInt32_IfOk(kWorkDirType, dirType) != ERROR_SUCCESS)
518     return;
519   switch (dirType)
520   {
521     case NMode::kSystem:
522     case NMode::kCurrent:
523     case NMode::kSpecified:
524       Mode = (NMode::EEnum)dirType;
525   }
526   UString pathU;
527   if (key.QueryValue(kWorkDirPath, pathU) == ERROR_SUCCESS)
528     Path = us2fs(pathU);
529   else
530   {
531     Path.Empty();
532     if (Mode == NMode::kSpecified)
533       Mode = NMode::kSystem;
534   }
535   key.GetValue_bool_IfOk(kTempRemovableOnly, ForRemovableOnly);
536 }
537 
538 }
539 
540 static LPCTSTR const kCascadedMenu = TEXT("CascadedMenu");
541 static LPCTSTR const kContextMenu = TEXT("ContextMenu");
542 static LPCTSTR const kMenuIcons = TEXT("MenuIcons");
543 static LPCTSTR const kElimDup = TEXT("ElimDupExtract");
544 static LPCTSTR const kWriteZoneId = TEXT("WriteZoneIdExtract");
545 
Save() const546 void CContextMenuInfo::Save() const
547 {
548   CS_LOCK
549   CKey key;
550   CreateMainKey(key, kOptionsInfoKeyName);
551 
552   Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
553   Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
554   Key_Set_BoolPair(key, kElimDup, ElimDup);
555 
556   Key_Set_UInt32(key, kWriteZoneId, WriteZone);
557 
558   if (Flags_Def)
559     key.SetValue(kContextMenu, Flags);
560 }
561 
Load()562 void CContextMenuInfo::Load()
563 {
564   Cascaded.Val = true;
565   Cascaded.Def = false;
566 
567   MenuIcons.Val = false;
568   MenuIcons.Def = false;
569 
570   ElimDup.Val = true;
571   ElimDup.Def = false;
572 
573   WriteZone = (UInt32)(Int32)-1;
574 
575   /* we can disable email items by default,
576      because email code doesn't work in some systems */
577   Flags = (UInt32)(Int32)-1
578       /*
579       & ~NContextMenuFlags::kCompressEmail
580       & ~NContextMenuFlags::kCompressTo7zEmail
581       & ~NContextMenuFlags::kCompressToZipEmail
582       */
583       ;
584   Flags_Def = false;
585 
586   CS_LOCK
587 
588   CKey key;
589   if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
590     return;
591 
592   Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded);
593   Key_Get_BoolPair_true(key, kElimDup, ElimDup);
594   Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
595 
596   Key_Get_UInt32(key, kWriteZoneId, WriteZone);
597 
598   Flags_Def = (key.GetValue_UInt32_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
599 }
600