xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Far/PluginRead.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // PluginRead.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "Plugin.h"
6 
7 #include "Messages.h"
8 
9 #include "../../../Common/StringConvert.h"
10 
11 #include "../../../Windows/FileName.h"
12 #include "../../../Windows/FileFind.h"
13 #include "../../../Windows/FileDir.h"
14 
15 #include "../Common/ZipRegistry.h"
16 
17 #include "ExtractEngine.h"
18 
19 using namespace NWindows;
20 using namespace NFile;
21 using namespace NDir;
22 using namespace NFar;
23 
24 static const char * const kHelpTopicExtrFromSevenZip =  "Extract";
25 
26 static const char kDirDelimiter = CHAR_PATH_SEPARATOR;
27 
28 static const char * const kExractPathHistoryName  = "7-ZipExtractPath";
29 
ExtractFiles(bool decompressAllItems,const UInt32 * indices,UInt32 numIndices,bool silent,NExtract::NPathMode::EEnum pathMode,NExtract::NOverwriteMode::EEnum overwriteMode,const UString & destPath,bool passwordIsDefined,const UString & password)30 HRESULT CPlugin::ExtractFiles(
31     bool decompressAllItems,
32     const UInt32 *indices,
33     UInt32 numIndices,
34     bool silent,
35     NExtract::NPathMode::EEnum pathMode,
36     NExtract::NOverwriteMode::EEnum overwriteMode,
37     const UString &destPath,
38     bool passwordIsDefined, const UString &password)
39 {
40   if (_agent->_isHashHandler)
41   {
42     g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
43     return NFileOperationReturnCode::kError;
44   }
45 
46   CScreenRestorer screenRestorer;
47   CProgressBox progressBox;
48   CProgressBox *progressBoxPointer = NULL;
49   if (!silent)
50   {
51     screenRestorer.Save();
52 
53     progressBoxPointer = &progressBox;
54     progressBox.Init(
55         // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
56         g_StartupInfo.GetMsgString(NMessageID::kExtracting));
57   }
58 
59 
60   CExtractCallbackImp *extractCallbackSpec = new CExtractCallbackImp;
61   CMyComPtr<IFolderArchiveExtractCallback> extractCallback(extractCallbackSpec);
62 
63   extractCallbackSpec->Init(
64       CP_OEMCP,
65       progressBoxPointer,
66       /*
67       GetDefaultName(m_FileName, m_ArchiverInfo.Extension),
68       m_FileInfo.MTime, m_FileInfo.Attributes,
69       */
70       passwordIsDefined, password);
71 
72   if (decompressAllItems)
73     return m_ArchiveHandler->Extract(pathMode, overwriteMode,
74         destPath, BoolToInt(false), extractCallback);
75   else
76   {
77     CMyComPtr<IArchiveFolder> archiveFolder;
78     _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder);
79 
80     return archiveFolder->Extract(indices, numIndices,
81         BoolToInt(true), // includeAltStreams
82         BoolToInt(false), // replaceAltStreamChars
83         pathMode, overwriteMode,
84         destPath, BoolToInt(false), extractCallback);
85   }
86 }
87 
GetFiles(struct PluginPanelItem * panelItems,unsigned itemsNumber,int move,char * destPath,int opMode)88 NFileOperationReturnCode::EEnum CPlugin::GetFiles(struct PluginPanelItem *panelItems,
89     unsigned itemsNumber, int move, char *destPath, int opMode)
90 {
91   return GetFilesReal(panelItems, itemsNumber, move,
92       destPath, opMode, (opMode & OPM_SILENT) == 0);
93 }
94 
GetFilesReal(struct PluginPanelItem * panelItems,unsigned itemsNumber,int move,const char * destPathLoc,int opMode,bool showBox)95 NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *panelItems,
96     unsigned itemsNumber, int move, const char *destPathLoc, int opMode, bool showBox)
97 {
98   if (move != 0)
99   {
100     g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
101     return NFileOperationReturnCode::kError;
102   }
103 
104   AString destPath (destPathLoc);
105   UString destPathU = GetUnicodeString(destPath, CP_OEMCP);
106   NName::NormalizeDirPathPrefix(destPathU);
107   destPath = UnicodeStringToMultiByte(destPathU, CP_OEMCP);
108 
109   // bool extractSelectedFiles = true;
110 
111   NExtract::CInfo extractionInfo;
112   extractionInfo.PathMode = NExtract::NPathMode::kCurPaths;
113   extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite;
114 
115   const bool silent = (opMode & OPM_SILENT) != 0;
116   bool decompressAllItems = false;
117   UString password = Password;
118   bool passwordIsDefined = PasswordIsDefined;
119 
120   if (!silent)
121   {
122     const int kPathIndex = 2;
123 
124     extractionInfo.Load();
125 
126     const int kPathModeRadioIndex = 4;
127     const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4;
128     const int kNumOverwriteOptions = 6;
129     const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions;
130     const int kXSize = 76;
131     const int kYSize = 19;
132     const int kPasswordYPos = 12;
133 
134     const int kXMid = kXSize / 2;
135 
136     AString oemPassword (UnicodeStringToMultiByte(password, CP_OEMCP));
137 
138     struct CInitDialogItem initItems[]={
139       { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL },
140       { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL },
141 
142       { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName},
143       // { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, 0, false, -1, destPath, NULL},
144 
145       { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL },
146       { DI_RADIOBUTTON, 6, 6, 0, 0, false,
147           extractionInfo.PathMode == NExtract::NPathMode::kFullPaths,
148           DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL },
149       { DI_RADIOBUTTON, 6, 7, 0, 0, false,
150           extractionInfo.PathMode == NExtract::NPathMode::kCurPaths,
151           0, false, NMessageID::kExtractPathCurrent, NULL, NULL },
152       { DI_RADIOBUTTON, 6, 8, 0, 0, false,
153           extractionInfo.PathMode == NExtract::NPathMode::kNoPaths,
154           false, 0, NMessageID::kExtractPathNo, NULL, NULL },
155 
156       { DI_SINGLEBOX, kXMid, 5, kXSize - 6, 5 + kNumOverwriteOptions, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL },
157       { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false,
158           extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAsk,
159           DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL },
160       { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false,
161           extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kOverwrite,
162           0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL },
163       { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false,
164           extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kSkip,
165           0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL },
166       { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false,
167           extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kRename,
168           0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL },
169       { DI_RADIOBUTTON, kXMid + 2, 10, 0, 0, false,
170           extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kRenameExisting,
171           0, false, NMessageID::kExtractOwerwriteAutoRenameExisting, NULL, NULL },
172 
173       { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL },
174       { DI_RADIOBUTTON, 6, 11, 0, 0, false, true, DIF_GROUP, false, NMessageID::kExtractFilesSelected, NULL, NULL },
175       { DI_RADIOBUTTON, 6, 12, 0, 0, false, false, 0, false, NMessageID::kExtractFilesAll, NULL, NULL },
176 
177       { DI_SINGLEBOX, kXMid, kPasswordYPos, kXSize - 6, kPasswordYPos + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL },
178       { DI_PSWEDIT, kXMid + 2, kPasswordYPos + 1, kXSize - 8, 12, false, false, 0, false, -1, oemPassword, NULL},
179 
180       { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL  },
181 
182 
183       { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kExtractExtract, NULL, NULL  },
184       { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kExtractCancel, NULL, NULL  }
185     };
186 
187     const unsigned kNumDialogItems = Z7_ARRAY_SIZE(initItems);
188     const unsigned kOkButtonIndex = kNumDialogItems - 2;
189     const unsigned kPasswordIndex = kNumDialogItems - 4;
190 
191     FarDialogItem dialogItems[kNumDialogItems];
192     g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
193     for (;;)
194     {
195       int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize,
196         kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems);
197       if (askCode != kOkButtonIndex)
198         return NFileOperationReturnCode::kInterruptedByUser;
199       destPath = dialogItems[kPathIndex].Data;
200       destPathU = GetUnicodeString(destPath, CP_OEMCP);
201       destPathU.Trim();
202       if (destPathU.IsEmpty())
203       {
204         #ifdef UNDER_CE
205         destPathU = "\\";
206         #else
207         FString destPathF = us2fs(destPathU);
208         if (!GetCurrentDir(destPathF))
209           throw 318016;
210         NName::NormalizeDirPathPrefix(destPathF);
211         destPathU = fs2us(destPathF);
212         #endif
213         break;
214       }
215       else
216       {
217         if (destPathU.Back() == kDirDelimiter)
218           break;
219       }
220       g_StartupInfo.ShowErrorMessage("You must specify directory path");
221     }
222 
223     if (dialogItems[kPathModeRadioIndex].Selected)
224       extractionInfo.PathMode = NExtract::NPathMode::kFullPaths;
225     else if (dialogItems[kPathModeRadioIndex + 1].Selected)
226       extractionInfo.PathMode = NExtract::NPathMode::kCurPaths;
227     else if (dialogItems[kPathModeRadioIndex + 2].Selected)
228       extractionInfo.PathMode = NExtract::NPathMode::kNoPaths;
229     else
230       throw 31806;
231 
232     if (dialogItems[kOverwriteModeRadioIndex].Selected)
233       extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAsk;
234     else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected)
235       extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite;
236     else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected)
237       extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkip;
238     else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected)
239       extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kRename;
240     else if (dialogItems[kOverwriteModeRadioIndex + 4].Selected)
241       extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kRenameExisting;
242     else
243       throw 31806;
244 
245     if (dialogItems[kFilesModeIndex].Selected)
246       decompressAllItems = false;
247     else if (dialogItems[kFilesModeIndex + 1].Selected)
248       decompressAllItems = true;
249     else
250       throw 31806;
251 
252     extractionInfo.Save();
253 
254     if (dialogItems[kFilesModeIndex].Selected)
255     {
256       // extractSelectedFiles = true;
257     }
258     else if (dialogItems[kFilesModeIndex + 1].Selected)
259     {
260       // extractSelectedFiles = false;
261     }
262     else
263       throw 31806;
264 
265     oemPassword = dialogItems[kPasswordIndex].Data;
266     password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
267     passwordIsDefined = !password.IsEmpty();
268   }
269 
270   CreateComplexDir(us2fs(destPathU));
271 
272   /*
273   vector<int> realIndices;
274   if (!decompressAllItems)
275     GetRealIndexes(panelItems, itemsNumber, realIndices);
276   */
277   CObjArray<UInt32> indices(itemsNumber);
278   for (unsigned i = 0; i < itemsNumber; i++)
279     indices[i] = (UInt32)panelItems[i].UserData;
280 
281   const HRESULT result = ExtractFiles(decompressAllItems, indices, itemsNumber,
282       !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode,
283       destPathU,
284       passwordIsDefined, password);
285   // HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox,
286   //     extractionInfo, destPath, passwordIsDefined, password);
287   if (result != S_OK)
288   {
289     if (result == E_ABORT)
290       return NFileOperationReturnCode::kInterruptedByUser;
291     ShowSysErrorMessage(result);
292     return NFileOperationReturnCode::kError;
293   }
294 
295   // if (move != 0)
296   // {
297   //   if (DeleteFiles(panelItems, itemsNumber, opMode) == FALSE)
298   //     return NFileOperationReturnCode::kError;
299   // }
300   return NFileOperationReturnCode::kSuccess;
301 }
302