1 // FileFolderPluginOpen.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "resource.h"
6 
7 #include "Windows/Thread.h"
8 
9 #include "../Agent/Agent.h"
10 
11 #include "LangUtils.h"
12 #include "OpenCallback.h"
13 #include "PluginLoader.h"
14 #include "RegistryAssociations.h"
15 #include "RegistryPlugins.h"
16 
17 using namespace NWindows;
18 using namespace NRegistryAssociations;
19 
20 struct CThreadArchiveOpen
21 {
22   UString Path;
23   CMyComPtr<IInStream> InStream;
24   CMyComPtr<IFolderManager> FolderManager;
25   CMyComPtr<IProgress> OpenCallback;
26   COpenArchiveCallback *OpenCallbackSpec;
27 
28   CMyComPtr<IFolderFolder> Folder;
29   HRESULT Result;
30 
ProcessCThreadArchiveOpen31   void Process()
32   {
33     OpenCallbackSpec->ProgressDialog.WaitCreating();
34     Result = FolderManager->OpenFolderFile(InStream, Path, &Folder, OpenCallback);
35     OpenCallbackSpec->ProgressDialog.MyClose();
36   }
37 
MyThreadFunctionCThreadArchiveOpen38   static THREAD_FUNC_DECL MyThreadFunction(void *param)
39   {
40     ((CThreadArchiveOpen *)param)->Process();
41     return 0;
42   }
43 };
44 
FindPlugin(const CObjectVector<CPluginInfo> & plugins,const UString & pluginName)45 static int FindPlugin(const CObjectVector<CPluginInfo> &plugins,
46     const UString &pluginName)
47 {
48   for (int i = 0; i < plugins.Size(); i++)
49     if (plugins[i].Name.CompareNoCase(pluginName) == 0)
50       return i;
51   return -1;
52 }
53 
OpenFileFolderPlugin(IInStream * inStream,const UString & path,HMODULE * module,IFolderFolder ** resultFolder,HWND parentWindow,bool & encrypted,UString & password)54 HRESULT OpenFileFolderPlugin(
55     IInStream *inStream,
56     const UString &path,
57     HMODULE *module,
58     IFolderFolder **resultFolder,
59     HWND parentWindow,
60     bool &encrypted, UString &password)
61 {
62 #ifdef _WIN32
63   CObjectVector<CPluginInfo> plugins;
64   ReadFileFolderPluginInfoList(plugins);
65 #endif
66 
67   UString extension, name, pureName, dot;
68 
69   int slashPos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
70   UString dirPrefix;
71   UString fileName;
72   if (slashPos >= 0)
73   {
74     dirPrefix = path.Left(slashPos + 1);
75     fileName = path.Mid(slashPos + 1);
76   }
77   else
78     fileName = path;
79 
80   NFile::NName::SplitNameToPureNameAndExtension(fileName, pureName, dot, extension);
81 
82 #ifdef _WIN32
83   if (!extension.IsEmpty())
84   {
85     CExtInfo extInfo;
86     if (ReadInternalAssociation(extension, extInfo))
87     {
88       for (int i = extInfo.Plugins.Size() - 1; i >= 0; i--)
89       {
90         int pluginIndex = FindPlugin(plugins, extInfo.Plugins[i]);
91         if (pluginIndex >= 0)
92         {
93           const CPluginInfo plugin = plugins[pluginIndex];
94           plugins.Delete(pluginIndex);
95           plugins.Insert(0, plugin);
96         }
97       }
98     }
99   }
100 
101   for (int i = 0; i < plugins.Size(); i++)
102   {
103     const CPluginInfo &plugin = plugins[i];
104     if (!plugin.ClassIDDefined)
105       continue;
106 #endif // #ifdef _WIN32
107     CPluginLibrary library;
108 
109     CThreadArchiveOpen t;
110 
111 #ifdef _WIN32
112     if (plugin.FilePath.IsEmpty())
113       t.FolderManager = new CArchiveFolderManager;
114     else if (library.LoadAndCreateManager(plugin.FilePath, plugin.ClassID, &t.FolderManager) != S_OK)
115       continue;
116 #else
117       t.FolderManager = new CArchiveFolderManager;
118 #endif
119 
120     t.OpenCallbackSpec = new COpenArchiveCallback;
121     t.OpenCallback = t.OpenCallbackSpec;
122     t.OpenCallbackSpec->PasswordIsDefined = encrypted;
123     t.OpenCallbackSpec->Password = password;
124     t.OpenCallbackSpec->ParentWindow = parentWindow;
125 
126     if (inStream)
127       t.OpenCallbackSpec->SetSubArchiveName(fileName);
128     else
129       t.OpenCallbackSpec->LoadFileInfo(dirPrefix, fileName);
130 
131     t.InStream = inStream;
132     t.Path = path;
133 
134     UString progressTitle = LangString(IDS_OPENNING, 0x03020283);
135     t.OpenCallbackSpec->ProgressDialog.MainWindow = parentWindow;
136     t.OpenCallbackSpec->ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000);
137     t.OpenCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + UString(L" ");
138 
139     NWindows::CThread thread;
140     if (thread.Create(CThreadArchiveOpen::MyThreadFunction, &t) != S_OK)
141       throw 271824;
142     t.OpenCallbackSpec->StartProgressDialog(progressTitle);
143 
144     if (t.Result == E_ABORT)
145       return t.Result;
146 
147     if (t.Result == S_OK)
148     {
149       // if (openCallbackSpec->PasswordWasAsked)
150       {
151         encrypted = t.OpenCallbackSpec->PasswordIsDefined;
152         password = t.OpenCallbackSpec->Password;
153       }
154       *module = library.Detach();
155       *resultFolder = t.Folder.Detach();
156       return S_OK;
157     }
158 
159     if (t.Result != S_FALSE)
160       return t.Result;
161 #ifdef _WIN32
162   }
163 #endif
164   return S_FALSE;
165 }
166