1 // RegistryAssociations.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Common/IntToString.h"
6 #include "../../../Common/StringConvert.h"
7 #include "../../../Common/StringToInt.h"
8
9 #include "../../../Windows/Registry.h"
10
11 #include "RegistryAssociations.h"
12
13 using namespace NWindows;
14 using namespace NRegistry;
15
16 namespace NRegistryAssoc {
17
18 // static NSynchronization::CCriticalSection g_CriticalSection;
19
20 static const TCHAR * const kClasses = TEXT("Software\\Classes\\");
21 // static const TCHAR * const kShellNewKeyName = TEXT("ShellNew");
22 // static const TCHAR * const kShellNewDataValueName = TEXT("Data");
23 static const TCHAR * const kDefaultIconKeyName = TEXT("DefaultIcon");
24 static const TCHAR * const kShellKeyName = TEXT("shell");
25 static const TCHAR * const kOpenKeyName = TEXT("open");
26 static const TCHAR * const kCommandKeyName = TEXT("command");
27 static const char * const k7zipPrefix = "7-Zip.";
28
GetExtProgramKeyName(const CSysString & ext)29 static CSysString GetExtProgramKeyName(const CSysString &ext)
30 {
31 return CSysString(k7zipPrefix) + ext;
32 }
33
GetFullKeyPath(HKEY hkey,const CSysString & name)34 static CSysString GetFullKeyPath(HKEY hkey, const CSysString &name)
35 {
36 CSysString s;
37 if (hkey != HKEY_CLASSES_ROOT)
38 s = kClasses;
39 return s + name;
40 }
41
GetExtKeyPath(HKEY hkey,const CSysString & ext)42 static CSysString GetExtKeyPath(HKEY hkey, const CSysString &ext)
43 {
44 return GetFullKeyPath(hkey, (TEXT(".")) + ext);
45 }
46
ReadFromRegistry(HKEY hkey,const CSysString & ext)47 bool CShellExtInfo::ReadFromRegistry(HKEY hkey, const CSysString &ext)
48 {
49 ProgramKey.Empty();
50 IconPath.Empty();
51 IconIndex = -1;
52 // NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
53 {
54 CKey extKey;
55 if (extKey.Open(hkey, GetExtKeyPath(hkey, ext), KEY_READ) != ERROR_SUCCESS)
56 return false;
57 if (extKey.QueryValue(NULL, ProgramKey) != ERROR_SUCCESS)
58 return false;
59 }
60 {
61 CKey iconKey;
62
63 if (iconKey.Open(hkey, GetFullKeyPath(hkey, ProgramKey + CSysString(CHAR_PATH_SEPARATOR) + kDefaultIconKeyName), KEY_READ) == ERROR_SUCCESS)
64 {
65 UString value;
66 if (iconKey.QueryValue(NULL, value) == ERROR_SUCCESS)
67 {
68 const int pos = value.ReverseFind(L',');
69 IconPath = value;
70 if (pos >= 0)
71 {
72 const wchar_t *end;
73 const Int32 index = ConvertStringToInt32((const wchar_t *)value + pos + 1, &end);
74 if (*end == 0)
75 {
76 // 9.31: if there is no icon index, we use -1. Is it OK?
77 if (pos != (int)value.Len() - 1)
78 IconIndex = (int)index;
79 IconPath.SetFrom(value, (unsigned)pos);
80 }
81 }
82 }
83 }
84 }
85 return true;
86 }
87
IsIt7Zip() const88 bool CShellExtInfo::IsIt7Zip() const
89 {
90 return ProgramKey.IsPrefixedBy_Ascii_NoCase(k7zipPrefix);
91 }
92
DeleteShellExtensionInfo(HKEY hkey,const CSysString & ext)93 LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext)
94 {
95 // NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
96 CKey rootKey;
97 rootKey.Attach(hkey);
98 LONG res = rootKey.RecurseDeleteKey(GetExtKeyPath(hkey, ext));
99 // then we delete only 7-Zip.* key.
100 rootKey.RecurseDeleteKey(GetFullKeyPath(hkey, GetExtProgramKeyName(ext)));
101 rootKey.Detach();
102 return res;
103 }
104
AddShellExtensionInfo(HKEY hkey,const CSysString & ext,const UString & programTitle,const UString & programOpenCommand,const UString & iconPath,int iconIndex)105 LONG AddShellExtensionInfo(HKEY hkey,
106 const CSysString &ext,
107 const UString &programTitle,
108 const UString &programOpenCommand,
109 const UString &iconPath, int iconIndex
110 // , const void *shellNewData, int shellNewDataSize
111 )
112 {
113 LONG res = 0;
114 DeleteShellExtensionInfo(hkey, ext);
115 // NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
116 CSysString programKeyName;
117 {
118 CSysString ext2 (ext);
119 if (iconIndex < 0)
120 ext2 = "*";
121 programKeyName = GetExtProgramKeyName(ext2);
122 }
123 {
124 CKey extKey;
125 res = extKey.Create(hkey, GetExtKeyPath(hkey, ext));
126 extKey.SetValue(NULL, programKeyName);
127 /*
128 if (shellNewData != NULL)
129 {
130 CKey shellNewKey;
131 shellNewKey.Create(extKey, kShellNewKeyName);
132 shellNewKey.SetValue(kShellNewDataValueName, shellNewData, shellNewDataSize);
133 }
134 */
135 }
136 CKey programKey;
137 programKey.Create(hkey, GetFullKeyPath(hkey, programKeyName));
138 programKey.SetValue(NULL, programTitle);
139 {
140 CKey iconKey;
141 UString iconPathFull = iconPath;
142 if (iconIndex < 0)
143 iconIndex = 0;
144 // if (iconIndex >= 0)
145 {
146 iconPathFull.Add_Char(',');
147 iconPathFull.Add_UInt32((UInt32)iconIndex);
148 }
149 iconKey.Create(programKey, kDefaultIconKeyName);
150 iconKey.SetValue(NULL, iconPathFull);
151 }
152
153 CKey shellKey;
154 shellKey.Create(programKey, kShellKeyName);
155 shellKey.SetValue(NULL, TEXT(""));
156
157 CKey openKey;
158 openKey.Create(shellKey, kOpenKeyName);
159 openKey.SetValue(NULL, TEXT(""));
160
161 CKey commandKey;
162 commandKey.Create(openKey, kCommandKeyName);
163 commandKey.SetValue(NULL, programOpenCommand);
164 return res;
165 }
166
167 }
168