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