• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   if (key.QueryValue(name, value) != ERROR_SUCCESS)
49     value = (UInt32)(Int32)-1;
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_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_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_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.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths)
159   {
160     PathMode = (NPathMode::EEnum)v;
161     PathMode_Force = true;
162   }
163   if (key.QueryValue(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_IfOk(kShowPassword, showPassword);
185   return showPassword;
186 }
187 
Read_LimitGB()188 UInt32 Read_LimitGB()
189 {
190   CS_LOCK
191   CKey key;
192   if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS)
193   {
194     UInt32 v;
195     if (key.QueryValue(kMemLimit, v) == ERROR_SUCCESS)
196       return v;
197   }
198   return (UInt32)(Int32)-1;
199 }
200 
201 }
202 
203 namespace NCompression
204 {
205 
206 static LPCTSTR const kKeyName = TEXT("Compression");
207 
208 static LPCTSTR const kArcHistory = TEXT("ArcHistory");
209 static LPCWSTR const kArchiver = L"Archiver";
210 static LPCTSTR const kShowPassword = TEXT("ShowPassword");
211 static LPCTSTR const kEncryptHeaders = TEXT("EncryptHeaders");
212 
213 static LPCTSTR const kOptionsKeyName = TEXT("Options");
214 
215 static LPCTSTR const kLevel = TEXT("Level");
216 static LPCTSTR const kDictionary = TEXT("Dictionary");
217 // static LPCTSTR const kDictionaryChain = TEXT("DictionaryChain");
218 static LPCTSTR const kOrder = TEXT("Order");
219 static LPCTSTR const kBlockSize = TEXT("BlockSize");
220 static LPCTSTR const kNumThreads = TEXT("NumThreads");
221 static LPCWSTR const kMethod = L"Method";
222 static LPCWSTR const kOptions = L"Options";
223 static LPCWSTR const kEncryptionMethod = L"EncryptionMethod";
224 
225 static LPCTSTR const kNtSecur = TEXT("Security");
226 static LPCTSTR const kAltStreams = TEXT("AltStreams");
227 static LPCTSTR const kHardLinks = TEXT("HardLinks");
228 static LPCTSTR const kSymLinks = TEXT("SymLinks");
229 static LPCTSTR const kPreserveATime = TEXT("PreserveATime");
230 
231 static LPCTSTR const kTimePrec = TEXT("TimePrec");
232 static LPCTSTR const kMTime = TEXT("MTime");
233 static LPCTSTR const kATime = TEXT("ATime");
234 static LPCTSTR const kCTime = TEXT("CTime");
235 static LPCTSTR const kSetArcMTime = TEXT("SetArcMTime");
236 
SetRegString(CKey & key,LPCWSTR name,const UString & value)237 static void SetRegString(CKey &key, LPCWSTR name, const UString &value)
238 {
239   if (value.IsEmpty())
240     key.DeleteValue(name);
241   else
242     key.SetValue(name, value);
243 }
244 
GetRegString(CKey & key,LPCWSTR name,UString & value)245 static void GetRegString(CKey &key, LPCWSTR name, UString &value)
246 {
247   if (key.QueryValue(name, value) != ERROR_SUCCESS)
248     value.Empty();
249 }
250 
251 static LPCWSTR const kMemUse = L"MemUse"
252     #if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
253       L"32";
254     #else
255       L"64";
256     #endif
257 
Save() const258 void CInfo::Save() const
259 {
260   CS_LOCK
261 
262   CKey key;
263   CreateMainKey(key, kKeyName);
264 
265   Key_Set_BoolPair_Delete_IfNotDef (key, kNtSecur, NtSecurity);
266   Key_Set_BoolPair_Delete_IfNotDef (key, kAltStreams, AltStreams);
267   Key_Set_BoolPair_Delete_IfNotDef (key, kHardLinks, HardLinks);
268   Key_Set_BoolPair_Delete_IfNotDef (key, kSymLinks, SymLinks);
269   Key_Set_BoolPair_Delete_IfNotDef (key, kPreserveATime, PreserveATime);
270 
271   key.SetValue(kShowPassword, ShowPassword);
272   key.SetValue(kLevel, (UInt32)Level);
273   key.SetValue(kArchiver, ArcType);
274   key.SetValue(kShowPassword, ShowPassword);
275   key.SetValue(kEncryptHeaders, EncryptHeaders);
276   key.RecurseDeleteKey(kArcHistory);
277   key.SetValue_Strings(kArcHistory, ArcPaths);
278 
279   key.RecurseDeleteKey(kOptionsKeyName);
280   {
281     CKey optionsKey;
282     optionsKey.Create(key, kOptionsKeyName);
283     FOR_VECTOR (i, Formats)
284     {
285       const CFormatOptions &fo = Formats[i];
286       CKey fk;
287       fk.Create(optionsKey, fo.FormatID);
288 
289       SetRegString(fk, kMethod, fo.Method);
290       SetRegString(fk, kOptions, fo.Options);
291       SetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
292       SetRegString(fk, kMemUse, fo.MemUse);
293 
294       Key_Set_UInt32(fk, kLevel, fo.Level);
295       Key_Set_UInt32(fk, kDictionary, fo.Dictionary);
296       // Key_Set_UInt32(fk, kDictionaryChain, fo.DictionaryChain);
297       Key_Set_UInt32(fk, kOrder, fo.Order);
298       Key_Set_UInt32(fk, kBlockSize, fo.BlockLogSize);
299       Key_Set_UInt32(fk, kNumThreads, fo.NumThreads);
300 
301       Key_Set_UInt32(fk, kTimePrec, fo.TimePrec);
302       Key_Set_BoolPair_Delete_IfNotDef (fk, kMTime, fo.MTime);
303       Key_Set_BoolPair_Delete_IfNotDef (fk, kATime, fo.ATime);
304       Key_Set_BoolPair_Delete_IfNotDef (fk, kCTime, fo.CTime);
305       Key_Set_BoolPair_Delete_IfNotDef (fk, kSetArcMTime, fo.SetArcMTime);
306     }
307   }
308 }
309 
Load()310 void CInfo::Load()
311 {
312   ArcPaths.Clear();
313   Formats.Clear();
314 
315   Level = 5;
316   ArcType = L"7z";
317   ShowPassword = false;
318   EncryptHeaders = false;
319 
320   CS_LOCK
321   CKey key;
322 
323   if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
324     return;
325 
326   Key_Get_BoolPair(key, kNtSecur, NtSecurity);
327   Key_Get_BoolPair(key, kAltStreams, AltStreams);
328   Key_Get_BoolPair(key, kHardLinks, HardLinks);
329   Key_Get_BoolPair(key, kSymLinks, SymLinks);
330   Key_Get_BoolPair(key, kPreserveATime, PreserveATime);
331 
332   key.GetValue_Strings(kArcHistory, ArcPaths);
333 
334   {
335     CKey optionsKey;
336     if (optionsKey.Open(key, kOptionsKeyName, KEY_READ) == ERROR_SUCCESS)
337     {
338       CSysStringVector formatIDs;
339       optionsKey.EnumKeys(formatIDs);
340       FOR_VECTOR (i, formatIDs)
341       {
342         CKey fk;
343         CFormatOptions fo;
344         fo.FormatID = formatIDs[i];
345         if (fk.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS)
346         {
347           GetRegString(fk, kMethod, fo.Method);
348           GetRegString(fk, kOptions, fo.Options);
349           GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
350           GetRegString(fk, kMemUse, fo.MemUse);
351 
352           Key_Get_UInt32(fk, kLevel, fo.Level);
353           Key_Get_UInt32(fk, kDictionary, fo.Dictionary);
354           // Key_Get_UInt32(fk, kDictionaryChain, fo.DictionaryChain);
355           Key_Get_UInt32(fk, kOrder, fo.Order);
356           Key_Get_UInt32(fk, kBlockSize, fo.BlockLogSize);
357           Key_Get_UInt32(fk, kNumThreads, fo.NumThreads);
358 
359           Key_Get_UInt32(fk, kTimePrec, fo.TimePrec);
360           Key_Get_BoolPair(fk, kMTime, fo.MTime);
361           Key_Get_BoolPair(fk, kATime, fo.ATime);
362           Key_Get_BoolPair(fk, kCTime, fo.CTime);
363           Key_Get_BoolPair(fk, kSetArcMTime, fo.SetArcMTime);
364 
365           Formats.Add(fo);
366         }
367       }
368     }
369   }
370 
371   UString a;
372   if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS)
373     ArcType = a;
374   key.GetValue_IfOk(kLevel, Level);
375   key.GetValue_IfOk(kShowPassword, ShowPassword);
376   key.GetValue_IfOk(kEncryptHeaders, EncryptHeaders);
377 }
378 
379 
ParseMemUse(const wchar_t * s,CMemUse & mu)380 static bool ParseMemUse(const wchar_t *s, CMemUse &mu)
381 {
382   mu.Clear();
383 
384   bool percentMode = false;
385   {
386     const wchar_t c = *s;
387     if (MyCharLower_Ascii(c) == 'p')
388     {
389       percentMode = true;
390       s++;
391     }
392   }
393   const wchar_t *end;
394   UInt64 number = ConvertStringToUInt64(s, &end);
395   if (end == s)
396     return false;
397 
398   wchar_t c = *end;
399 
400   if (percentMode)
401   {
402     if (c != 0)
403       return false;
404     mu.IsPercent = true;
405     mu.Val = number;
406     return true;
407   }
408 
409   if (c == 0)
410   {
411     mu.Val = number;
412     return true;
413   }
414 
415   c = MyCharLower_Ascii(c);
416 
417   const wchar_t c1 = end[1];
418 
419   if (c == '%')
420   {
421     if (c1 != 0)
422       return false;
423     mu.IsPercent = true;
424     mu.Val = number;
425     return true;
426   }
427 
428   if (c == 'b')
429   {
430     if (c1 != 0)
431       return false;
432     mu.Val = number;
433     return true;
434   }
435 
436   if (c1 != 0)
437     if (MyCharLower_Ascii(c1) != 'b' || end[2] != 0)
438       return false;
439 
440   unsigned numBits;
441   switch (c)
442   {
443     case 'k': numBits = 10; break;
444     case 'm': numBits = 20; break;
445     case 'g': numBits = 30; break;
446     case 't': numBits = 40; break;
447     default: return false;
448   }
449   if (number >= ((UInt64)1 << (64 - numBits)))
450     return false;
451   mu.Val = number << numBits;
452   return true;
453 }
454 
455 
Parse(const UString & s)456 void CMemUse::Parse(const UString &s)
457 {
458   IsDefined = ParseMemUse(s, *this);
459 }
460 
461 /*
462 void MemLimit_Save(const UString &s)
463 {
464   CS_LOCK
465   CKey key;
466   CreateMainKey(key, kKeyName);
467   SetRegString(key, kMemUse, s);
468 }
469 
470 bool MemLimit_Load(NCompression::CMemUse &mu)
471 {
472   mu.Clear();
473   UString a;
474   {
475     CS_LOCK
476     CKey key;
477     if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
478       return false;
479     if (key.QueryValue(kMemUse, a) != ERROR_SUCCESS)
480       return false;
481   }
482   if (a.IsEmpty())
483     return false;
484   mu.Parse(a);
485   return mu.IsDefined;
486 }
487 */
488 
489 }
490 
491 static LPCTSTR const kOptionsInfoKeyName = TEXT("Options");
492 
493 namespace NWorkDir
494 {
495 static LPCTSTR const kWorkDirType = TEXT("WorkDirType");
496 static LPCWSTR const kWorkDirPath = L"WorkDirPath";
497 static LPCTSTR const kTempRemovableOnly = TEXT("TempRemovableOnly");
498 
499 
Save() const500 void CInfo::Save()const
501 {
502   CS_LOCK
503   CKey key;
504   CreateMainKey(key, kOptionsInfoKeyName);
505   key.SetValue(kWorkDirType, (UInt32)Mode);
506   key.SetValue(kWorkDirPath, fs2us(Path));
507   key.SetValue(kTempRemovableOnly, ForRemovableOnly);
508 }
509 
Load()510 void CInfo::Load()
511 {
512   SetDefault();
513 
514   CS_LOCK
515   CKey key;
516   if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
517     return;
518 
519   UInt32 dirType;
520   if (key.QueryValue(kWorkDirType, dirType) != ERROR_SUCCESS)
521     return;
522   switch (dirType)
523   {
524     case NMode::kSystem:
525     case NMode::kCurrent:
526     case NMode::kSpecified:
527       Mode = (NMode::EEnum)dirType;
528   }
529   UString pathU;
530   if (key.QueryValue(kWorkDirPath, pathU) == ERROR_SUCCESS)
531     Path = us2fs(pathU);
532   else
533   {
534     Path.Empty();
535     if (Mode == NMode::kSpecified)
536       Mode = NMode::kSystem;
537   }
538   key.GetValue_IfOk(kTempRemovableOnly, ForRemovableOnly);
539 }
540 
541 }
542 
543 static LPCTSTR const kCascadedMenu = TEXT("CascadedMenu");
544 static LPCTSTR const kContextMenu = TEXT("ContextMenu");
545 static LPCTSTR const kMenuIcons = TEXT("MenuIcons");
546 static LPCTSTR const kElimDup = TEXT("ElimDupExtract");
547 static LPCTSTR const kWriteZoneId = TEXT("WriteZoneIdExtract");
548 
Save() const549 void CContextMenuInfo::Save() const
550 {
551   CS_LOCK
552   CKey key;
553   CreateMainKey(key, kOptionsInfoKeyName);
554 
555   Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
556   Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
557   Key_Set_BoolPair(key, kElimDup, ElimDup);
558 
559   Key_Set_UInt32(key, kWriteZoneId, WriteZone);
560 
561   if (Flags_Def)
562     key.SetValue(kContextMenu, Flags);
563 }
564 
Load()565 void CContextMenuInfo::Load()
566 {
567   Cascaded.Val = true;
568   Cascaded.Def = false;
569 
570   MenuIcons.Val = false;
571   MenuIcons.Def = false;
572 
573   ElimDup.Val = true;
574   ElimDup.Def = false;
575 
576   WriteZone = (UInt32)(Int32)-1;
577 
578   /* we can disable email items by default,
579      because email code doesn't work in some systems */
580   Flags = (UInt32)(Int32)-1
581       /*
582       & ~NContextMenuFlags::kCompressEmail
583       & ~NContextMenuFlags::kCompressTo7zEmail
584       & ~NContextMenuFlags::kCompressToZipEmail
585       */
586       ;
587   Flags_Def = false;
588 
589   CS_LOCK
590 
591   CKey key;
592   if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
593     return;
594 
595   Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded);
596   Key_Get_BoolPair_true(key, kElimDup, ElimDup);
597   Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
598 
599   Key_Get_UInt32(key, kWriteZoneId, WriteZone);
600 
601   Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
602 }
603