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