xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/RegistryAssociations.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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