1 // RegistryPlugins.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Windows/DLL.h"
6 #include "../../../Windows/FileFind.h"
7 #include "../../../Windows/PropVariant.h"
8 
9 #include "IFolder.h"
10 #include "RegistryPlugins.h"
11 
12 using namespace NWindows;
13 using namespace NFile;
14 
15 /*
16 static LPCTSTR const kLMBasePath = TEXT("Software\\7-Zip\\FM");
17 
18 static LPCTSTR const kPluginsKeyName = TEXT("Plugins");
19 static LPCTSTR const kPluginsOpenClassIDValue = TEXT("CLSID");
20 static LPCTSTR const kPluginsOptionsClassIDValue = TEXT("Options");
21 static LPCTSTR const kPluginsTypeValue = TEXT("Type");
22 
23 static CSysString GetFileFolderPluginsKeyName()
24 {
25   return CSysString(kLMBasePath) + CSysString(TEXT('\\')) +
26       CSysString(kPluginsKeyName);
27 }
28 
29 */
30 
31 typedef UINT32 (WINAPI * GetPluginPropertyFunc)(PROPID propID, PROPVARIANT *value);
32 
ReadPluginInfo(CPluginInfo & pluginInfo,bool needCheckDll)33 static bool ReadPluginInfo(CPluginInfo &pluginInfo, bool needCheckDll)
34 {
35   if (needCheckDll)
36   {
37     NDLL::CLibrary lib;
38     if (!lib.LoadEx(pluginInfo.FilePath, LOAD_LIBRARY_AS_DATAFILE))
39       return false;
40   }
41   NDLL::CLibrary lib;
42   if (!lib.Load(pluginInfo.FilePath))
43     return false;
44   GetPluginPropertyFunc getPluginProperty = (GetPluginPropertyFunc)lib.GetProc("GetPluginProperty");
45   if (getPluginProperty == NULL)
46     return false;
47 
48   NCOM::CPropVariant prop;
49   if (getPluginProperty(NPlugin::kName, &prop) != S_OK)
50     return false;
51   if (prop.vt != VT_BSTR)
52     return false;
53   pluginInfo.Name = prop.bstrVal;
54   prop.Clear();
55 
56   if (getPluginProperty(NPlugin::kClassID, &prop) != S_OK)
57     return false;
58   if (prop.vt == VT_EMPTY)
59     pluginInfo.ClassIDDefined = false;
60   else if (prop.vt != VT_BSTR)
61     return false;
62   else
63   {
64     pluginInfo.ClassIDDefined = true;
65     pluginInfo.ClassID = *(const GUID *)(const void *)prop.bstrVal;
66   }
67   prop.Clear();
68 
69   if (getPluginProperty(NPlugin::kOptionsClassID, &prop) != S_OK)
70     return false;
71   if (prop.vt == VT_EMPTY)
72     pluginInfo.OptionsClassIDDefined = false;
73   else if (prop.vt != VT_BSTR)
74     return false;
75   else
76   {
77     pluginInfo.OptionsClassIDDefined = true;
78     pluginInfo.OptionsClassID = *(const GUID *)(const void *)prop.bstrVal;
79   }
80   prop.Clear();
81 
82   if (getPluginProperty(NPlugin::kType, &prop) != S_OK)
83     return false;
84   if (prop.vt == VT_EMPTY)
85     pluginInfo.Type = kPluginTypeFF;
86   else if (prop.vt == VT_UI4)
87     pluginInfo.Type = (EPluginType)prop.ulVal;
88   else
89     return false;
90   return true;
91 }
92 
ReadPluginInfoList(CObjectVector<CPluginInfo> & plugins)93 void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins)
94 {
95   plugins.Clear();
96 
97   FString baseFolderPrefix = NDLL::GetModuleDirPrefix();
98   {
99     CPluginInfo pluginInfo;
100     pluginInfo.FilePath = baseFolderPrefix + FTEXT("7-zip.dll");
101     if (::ReadPluginInfo(pluginInfo, false))
102       plugins.Add(pluginInfo);
103   }
104   FString folderPath = baseFolderPrefix;
105   folderPath += "Plugins" STRING_PATH_SEPARATOR;
106   NFind::CEnumerator enumerator;
107   enumerator.SetDirPrefix(folderPath);
108   NFind::CFileInfo fileInfo;
109   while (enumerator.Next(fileInfo))
110   {
111     if (fileInfo.IsDir())
112       continue;
113     CPluginInfo pluginInfo;
114     pluginInfo.FilePath = folderPath + fileInfo.Name;
115     if (::ReadPluginInfo(pluginInfo, true))
116       plugins.Add(pluginInfo);
117   }
118 }
119 
ReadFileFolderPluginInfoList(CObjectVector<CPluginInfo> & plugins)120 void ReadFileFolderPluginInfoList(CObjectVector<CPluginInfo> &plugins)
121 {
122   ReadPluginInfoList(plugins);
123   for (unsigned i = 0; i < plugins.Size();)
124     if (plugins[i].Type != kPluginTypeFF)
125       plugins.Delete(i);
126     else
127       i++;
128   {
129     CPluginInfo p;
130     // p.FilePath.Empty();
131     p.Type = kPluginTypeFF;
132     p.Name = "7-Zip";
133     // p.ClassID = CLSID_CAgentArchiveHandler;
134     p.ClassIDDefined = true;
135     // p.OptionsClassID;
136     p.OptionsClassIDDefined = false;
137     plugins.Add(p);
138   }
139 }
140