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