xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/PanelItemOpen.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // PanelItemOpen.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyWindows.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include <TlHelp32.h>
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/AutoPtr.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/ProcessUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantConv.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FileStreams.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamObjects.h"
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ExtractingFilePath.h"
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker #include "App.h"
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #include "FileFolderPluginOpen.h"
26*f6dc9357SAndroid Build Coastguard Worker #include "FormatUtils.h"
27*f6dc9357SAndroid Build Coastguard Worker #include "LangUtils.h"
28*f6dc9357SAndroid Build Coastguard Worker #include "PropertyNameRes.h"
29*f6dc9357SAndroid Build Coastguard Worker #include "RegistryUtils.h"
30*f6dc9357SAndroid Build Coastguard Worker #include "UpdateCallback100.h"
31*f6dc9357SAndroid Build Coastguard Worker 
32*f6dc9357SAndroid Build Coastguard Worker #include "../GUI/ExtractRes.h"
33*f6dc9357SAndroid Build Coastguard Worker 
34*f6dc9357SAndroid Build Coastguard Worker #include "resource.h"
35*f6dc9357SAndroid Build Coastguard Worker 
36*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
37*f6dc9357SAndroid Build Coastguard Worker using namespace NSynchronization;
38*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
39*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker extern bool g_RAM_Size_Defined;
42*f6dc9357SAndroid Build Coastguard Worker extern size_t g_RAM_Size;
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
45*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
46*f6dc9357SAndroid Build Coastguard Worker #endif
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker #define kTempDirPrefix FTEXT("7zO")
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker // #define SHOW_DEBUG_INFO
51*f6dc9357SAndroid Build Coastguard Worker 
52*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
53*f6dc9357SAndroid Build Coastguard Worker   #define DEBUG_PRINT(s) OutputDebugStringA(s);
54*f6dc9357SAndroid Build Coastguard Worker   #define DEBUG_PRINT_W(s) OutputDebugStringW(s);
55*f6dc9357SAndroid Build Coastguard Worker   #define DEBUG_PRINT_NUM(s, num) { char ttt[32]; ConvertUInt32ToString(num, ttt); OutputDebugStringA(s); OutputDebugStringA(ttt); }
56*f6dc9357SAndroid Build Coastguard Worker #else
57*f6dc9357SAndroid Build Coastguard Worker   #define DEBUG_PRINT(s)
58*f6dc9357SAndroid Build Coastguard Worker   #define DEBUG_PRINT_W(s)
59*f6dc9357SAndroid Build Coastguard Worker   #define DEBUG_PRINT_NUM(s, num)
60*f6dc9357SAndroid Build Coastguard Worker #endif
61*f6dc9357SAndroid Build Coastguard Worker 
62*f6dc9357SAndroid Build Coastguard Worker 
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker class CProcessSnapshot
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker   HANDLE _handle;
69*f6dc9357SAndroid Build Coastguard Worker public:
CProcessSnapshot()70*f6dc9357SAndroid Build Coastguard Worker   CProcessSnapshot(): _handle(INVALID_HANDLE_VALUE) {}
~CProcessSnapshot()71*f6dc9357SAndroid Build Coastguard Worker   ~CProcessSnapshot() { Close(); }
72*f6dc9357SAndroid Build Coastguard Worker 
Close()73*f6dc9357SAndroid Build Coastguard Worker   bool Close()
74*f6dc9357SAndroid Build Coastguard Worker   {
75*f6dc9357SAndroid Build Coastguard Worker     if (_handle == INVALID_HANDLE_VALUE)
76*f6dc9357SAndroid Build Coastguard Worker       return true;
77*f6dc9357SAndroid Build Coastguard Worker     if (!::CloseHandle(_handle))
78*f6dc9357SAndroid Build Coastguard Worker       return false;
79*f6dc9357SAndroid Build Coastguard Worker     _handle = INVALID_HANDLE_VALUE;
80*f6dc9357SAndroid Build Coastguard Worker     return true;
81*f6dc9357SAndroid Build Coastguard Worker   }
82*f6dc9357SAndroid Build Coastguard Worker 
Create()83*f6dc9357SAndroid Build Coastguard Worker   bool Create()
84*f6dc9357SAndroid Build Coastguard Worker   {
85*f6dc9357SAndroid Build Coastguard Worker     _handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
86*f6dc9357SAndroid Build Coastguard Worker     return (_handle != INVALID_HANDLE_VALUE);
87*f6dc9357SAndroid Build Coastguard Worker   }
88*f6dc9357SAndroid Build Coastguard Worker 
GetFirstProcess(PROCESSENTRY32 * pe)89*f6dc9357SAndroid Build Coastguard Worker   bool GetFirstProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32First(_handle, pe)); }
GetNextProcess(PROCESSENTRY32 * pe)90*f6dc9357SAndroid Build Coastguard Worker   bool GetNextProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32Next(_handle, pe)); }
91*f6dc9357SAndroid Build Coastguard Worker };
92*f6dc9357SAndroid Build Coastguard Worker 
93*f6dc9357SAndroid Build Coastguard Worker #endif
94*f6dc9357SAndroid Build Coastguard Worker 
95*f6dc9357SAndroid Build Coastguard Worker 
96*f6dc9357SAndroid Build Coastguard Worker /*
97*f6dc9357SAndroid Build Coastguard Worker struct COpenExtProg
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker   const char *Ext;
100*f6dc9357SAndroid Build Coastguard Worker   const char *Prog;
101*f6dc9357SAndroid Build Coastguard Worker };
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker static const COpenExtProg g_Progs[] =
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker   { "jpeg jpg png bmp gif", "Microsoft.Photos.exe" },
106*f6dc9357SAndroid Build Coastguard Worker   { "html htm pdf", "MicrosoftEdge.exe" },
107*f6dc9357SAndroid Build Coastguard Worker   // , { "rrr", "notepad.exe" }
108*f6dc9357SAndroid Build Coastguard Worker };
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker static bool FindExtProg(const char *exts, const char *ext)
111*f6dc9357SAndroid Build Coastguard Worker {
112*f6dc9357SAndroid Build Coastguard Worker   unsigned len = (unsigned)strlen(ext);
113*f6dc9357SAndroid Build Coastguard Worker   for (;;)
114*f6dc9357SAndroid Build Coastguard Worker   {
115*f6dc9357SAndroid Build Coastguard Worker     const char *p = exts;
116*f6dc9357SAndroid Build Coastguard Worker     for (;; p++)
117*f6dc9357SAndroid Build Coastguard Worker     {
118*f6dc9357SAndroid Build Coastguard Worker       const char c = *p;
119*f6dc9357SAndroid Build Coastguard Worker       if (c == 0 || c == ' ')
120*f6dc9357SAndroid Build Coastguard Worker         break;
121*f6dc9357SAndroid Build Coastguard Worker     }
122*f6dc9357SAndroid Build Coastguard Worker     if (len == (unsigned)(p - exts) && IsString1PrefixedByString2(exts, ext))
123*f6dc9357SAndroid Build Coastguard Worker       return true;
124*f6dc9357SAndroid Build Coastguard Worker     if (*p == 0)
125*f6dc9357SAndroid Build Coastguard Worker       return false;
126*f6dc9357SAndroid Build Coastguard Worker     exts = p + 1;
127*f6dc9357SAndroid Build Coastguard Worker   }
128*f6dc9357SAndroid Build Coastguard Worker }
129*f6dc9357SAndroid Build Coastguard Worker 
130*f6dc9357SAndroid Build Coastguard Worker class CPossibleProgs
131*f6dc9357SAndroid Build Coastguard Worker {
132*f6dc9357SAndroid Build Coastguard Worker public:
133*f6dc9357SAndroid Build Coastguard Worker   AStringVector ProgNames;
134*f6dc9357SAndroid Build Coastguard Worker 
135*f6dc9357SAndroid Build Coastguard Worker   void SetFromExtension(const char *ext) // ext must be low case
136*f6dc9357SAndroid Build Coastguard Worker   {
137*f6dc9357SAndroid Build Coastguard Worker     ProgNames.Clear();
138*f6dc9357SAndroid Build Coastguard Worker     for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Progs); i++)
139*f6dc9357SAndroid Build Coastguard Worker       if (FindExtProg(g_Progs[i].Ext, ext))
140*f6dc9357SAndroid Build Coastguard Worker       {
141*f6dc9357SAndroid Build Coastguard Worker         ProgNames.Add(g_Progs[i].Prog);
142*f6dc9357SAndroid Build Coastguard Worker       }
143*f6dc9357SAndroid Build Coastguard Worker   }
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker   bool IsFromList(const UString &progName) const
146*f6dc9357SAndroid Build Coastguard Worker   {
147*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, ProgNames)
148*f6dc9357SAndroid Build Coastguard Worker       if (progName.IsEqualTo_Ascii_NoCase(ProgNames[i]))
149*f6dc9357SAndroid Build Coastguard Worker         return true;
150*f6dc9357SAndroid Build Coastguard Worker     return false;
151*f6dc9357SAndroid Build Coastguard Worker   }
152*f6dc9357SAndroid Build Coastguard Worker };
153*f6dc9357SAndroid Build Coastguard Worker */
154*f6dc9357SAndroid Build Coastguard Worker 
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
159*f6dc9357SAndroid Build Coastguard Worker 
160*f6dc9357SAndroid Build Coastguard Worker /*
161*f6dc9357SAndroid Build Coastguard Worker GetProcessImageFileName
162*f6dc9357SAndroid Build Coastguard Worker   returns the path in device form, rather than drive letters:
163*f6dc9357SAndroid Build Coastguard Worker     \Device\HarddiskVolume1\WINDOWS\SysWOW64\notepad.exe
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker GetModuleFileNameEx works only after Sleep(something). Why?
166*f6dc9357SAndroid Build Coastguard Worker   returns the path
167*f6dc9357SAndroid Build Coastguard Worker     C:\WINDOWS\system32\NOTEPAD.EXE
168*f6dc9357SAndroid Build Coastguard Worker */
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker /* Kernel32.dll: Win7, Win2008R2;
171*f6dc9357SAndroid Build Coastguard Worker    Psapi.dll: (if PSAPI_VERSION=1) on Win7 and Win2008R2;
172*f6dc9357SAndroid Build Coastguard Worker    Psapi.dll: XP, Win2003, Vista, 2008;
173*f6dc9357SAndroid Build Coastguard Worker */
174*f6dc9357SAndroid Build Coastguard Worker 
175*f6dc9357SAndroid Build Coastguard Worker typedef DWORD (WINAPI *Func_GetProcessImageFileNameW)(
176*f6dc9357SAndroid Build Coastguard Worker     HANDLE hProcess, LPWSTR lpFilename, DWORD nSize);
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker typedef DWORD (WINAPI *Func_GetModuleFileNameExW)(
179*f6dc9357SAndroid Build Coastguard Worker     HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize);
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker typedef DWORD (WINAPI *Func_GetProcessId)(HANDLE process);
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
184*f6dc9357SAndroid Build Coastguard Worker 
185*f6dc9357SAndroid Build Coastguard Worker 
186*f6dc9357SAndroid Build Coastguard Worker static HMODULE g_Psapi_dll_module;
187*f6dc9357SAndroid Build Coastguard Worker 
188*f6dc9357SAndroid Build Coastguard Worker /*
189*f6dc9357SAndroid Build Coastguard Worker static void My_GetProcessFileName_2(HANDLE hProcess, UString &path)
190*f6dc9357SAndroid Build Coastguard Worker {
191*f6dc9357SAndroid Build Coastguard Worker   path.Empty();
192*f6dc9357SAndroid Build Coastguard Worker   const unsigned maxPath = 1024;
193*f6dc9357SAndroid Build Coastguard Worker   WCHAR temp[maxPath + 1];
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker   const char *func_name = "GetModuleFileNameExW";
196*f6dc9357SAndroid Build Coastguard Worker   Func_GetModuleFileNameExW my_func = (Func_GetModuleFileNameExW)
197*f6dc9357SAndroid Build Coastguard Worker     ::GetProcAddress(::GetModuleHandleA("kernel32.dll"), func_name);
198*f6dc9357SAndroid Build Coastguard Worker   if (!my_func)
199*f6dc9357SAndroid Build Coastguard Worker   {
200*f6dc9357SAndroid Build Coastguard Worker     if (!g_Psapi_dll_module)
201*f6dc9357SAndroid Build Coastguard Worker       g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll");
202*f6dc9357SAndroid Build Coastguard Worker     if (g_Psapi_dll_module)
203*f6dc9357SAndroid Build Coastguard Worker       my_func = (Func_GetModuleFileNameExW)::GetProcAddress(g_Psapi_dll_module, func_name);
204*f6dc9357SAndroid Build Coastguard Worker   }
205*f6dc9357SAndroid Build Coastguard Worker   if (my_func)
206*f6dc9357SAndroid Build Coastguard Worker   {
207*f6dc9357SAndroid Build Coastguard Worker     // DWORD num = GetModuleFileNameEx(hProcess, NULL, temp, maxPath);
208*f6dc9357SAndroid Build Coastguard Worker     DWORD num = my_func(hProcess, NULL, temp, maxPath);
209*f6dc9357SAndroid Build Coastguard Worker     if (num != 0)
210*f6dc9357SAndroid Build Coastguard Worker       path = temp;
211*f6dc9357SAndroid Build Coastguard Worker   }
212*f6dc9357SAndroid Build Coastguard Worker   // FreeLibrary(lib);
213*f6dc9357SAndroid Build Coastguard Worker }
214*f6dc9357SAndroid Build Coastguard Worker */
215*f6dc9357SAndroid Build Coastguard Worker 
216*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
217*f6dc9357SAndroid Build Coastguard Worker 
My_GetProcessFileName(HANDLE hProcess,UString & path)218*f6dc9357SAndroid Build Coastguard Worker static void My_GetProcessFileName(HANDLE hProcess, UString &path)
219*f6dc9357SAndroid Build Coastguard Worker {
220*f6dc9357SAndroid Build Coastguard Worker   path.Empty();
221*f6dc9357SAndroid Build Coastguard Worker   const unsigned maxPath = 1024;
222*f6dc9357SAndroid Build Coastguard Worker   WCHAR temp[maxPath + 1];
223*f6dc9357SAndroid Build Coastguard Worker 
224*f6dc9357SAndroid Build Coastguard Worker   const char *func_name =
225*f6dc9357SAndroid Build Coastguard Worker       "GetProcessImageFileNameW";
226*f6dc9357SAndroid Build Coastguard Worker   Func_GetProcessImageFileNameW my_func = Z7_GET_PROC_ADDRESS(
227*f6dc9357SAndroid Build Coastguard Worker   Func_GetProcessImageFileNameW, ::GetModuleHandleA("kernel32.dll"), func_name);
228*f6dc9357SAndroid Build Coastguard Worker 
229*f6dc9357SAndroid Build Coastguard Worker   if (!my_func)
230*f6dc9357SAndroid Build Coastguard Worker   {
231*f6dc9357SAndroid Build Coastguard Worker     if (!g_Psapi_dll_module)
232*f6dc9357SAndroid Build Coastguard Worker       g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll");
233*f6dc9357SAndroid Build Coastguard Worker     if (g_Psapi_dll_module)
234*f6dc9357SAndroid Build Coastguard Worker       my_func = Z7_GET_PROC_ADDRESS(
235*f6dc9357SAndroid Build Coastguard Worker         Func_GetProcessImageFileNameW, g_Psapi_dll_module, func_name);
236*f6dc9357SAndroid Build Coastguard Worker   }
237*f6dc9357SAndroid Build Coastguard Worker 
238*f6dc9357SAndroid Build Coastguard Worker   if (my_func)
239*f6dc9357SAndroid Build Coastguard Worker   {
240*f6dc9357SAndroid Build Coastguard Worker     const DWORD num =
241*f6dc9357SAndroid Build Coastguard Worker     // GetProcessImageFileNameW(hProcess, temp, maxPath);
242*f6dc9357SAndroid Build Coastguard Worker     my_func(hProcess, temp, maxPath);
243*f6dc9357SAndroid Build Coastguard Worker     if (num != 0)
244*f6dc9357SAndroid Build Coastguard Worker       path = temp;
245*f6dc9357SAndroid Build Coastguard Worker   }
246*f6dc9357SAndroid Build Coastguard Worker   // FreeLibrary(lib);
247*f6dc9357SAndroid Build Coastguard Worker }
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker struct CSnapshotProcess
250*f6dc9357SAndroid Build Coastguard Worker {
251*f6dc9357SAndroid Build Coastguard Worker   DWORD Id;
252*f6dc9357SAndroid Build Coastguard Worker   DWORD ParentId;
253*f6dc9357SAndroid Build Coastguard Worker   UString Name;
254*f6dc9357SAndroid Build Coastguard Worker };
255*f6dc9357SAndroid Build Coastguard Worker 
GetSnapshot(CObjectVector<CSnapshotProcess> & items)256*f6dc9357SAndroid Build Coastguard Worker static void GetSnapshot(CObjectVector<CSnapshotProcess> &items)
257*f6dc9357SAndroid Build Coastguard Worker {
258*f6dc9357SAndroid Build Coastguard Worker   items.Clear();
259*f6dc9357SAndroid Build Coastguard Worker 
260*f6dc9357SAndroid Build Coastguard Worker   CProcessSnapshot snapshot;
261*f6dc9357SAndroid Build Coastguard Worker   if (!snapshot.Create())
262*f6dc9357SAndroid Build Coastguard Worker     return;
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker   DEBUG_PRINT("snapshot.Create() OK");
265*f6dc9357SAndroid Build Coastguard Worker   PROCESSENTRY32 pe;
266*f6dc9357SAndroid Build Coastguard Worker   CSnapshotProcess item;
267*f6dc9357SAndroid Build Coastguard Worker   memset(&pe, 0, sizeof(pe));
268*f6dc9357SAndroid Build Coastguard Worker   pe.dwSize = sizeof(pe);
269*f6dc9357SAndroid Build Coastguard Worker   BOOL res = snapshot.GetFirstProcess(&pe);
270*f6dc9357SAndroid Build Coastguard Worker   while (res)
271*f6dc9357SAndroid Build Coastguard Worker   {
272*f6dc9357SAndroid Build Coastguard Worker     item.Id = pe.th32ProcessID;
273*f6dc9357SAndroid Build Coastguard Worker     item.ParentId = pe.th32ParentProcessID;
274*f6dc9357SAndroid Build Coastguard Worker     item.Name = GetUnicodeString(pe.szExeFile);
275*f6dc9357SAndroid Build Coastguard Worker     items.Add(item);
276*f6dc9357SAndroid Build Coastguard Worker     res = snapshot.GetNextProcess(&pe);
277*f6dc9357SAndroid Build Coastguard Worker   }
278*f6dc9357SAndroid Build Coastguard Worker }
279*f6dc9357SAndroid Build Coastguard Worker 
280*f6dc9357SAndroid Build Coastguard Worker #endif
281*f6dc9357SAndroid Build Coastguard Worker 
282*f6dc9357SAndroid Build Coastguard Worker 
283*f6dc9357SAndroid Build Coastguard Worker class CChildProcesses
284*f6dc9357SAndroid Build Coastguard Worker {
285*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
286*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<DWORD> _ids;
287*f6dc9357SAndroid Build Coastguard Worker   #endif
288*f6dc9357SAndroid Build Coastguard Worker 
289*f6dc9357SAndroid Build Coastguard Worker public:
290*f6dc9357SAndroid Build Coastguard Worker   // bool ProgsWereUsed;
291*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<HANDLE> Handles;
292*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<bool> NeedWait;
293*f6dc9357SAndroid Build Coastguard Worker   // UStringVector Names;
294*f6dc9357SAndroid Build Coastguard Worker 
295*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
296*f6dc9357SAndroid Build Coastguard Worker   UString Path;
297*f6dc9357SAndroid Build Coastguard Worker   #endif
298*f6dc9357SAndroid Build Coastguard Worker 
299*f6dc9357SAndroid Build Coastguard Worker   // CChildProcesses(): ProgsWereUsed(false) {}
~CChildProcesses()300*f6dc9357SAndroid Build Coastguard Worker   ~CChildProcesses() { CloseAll(); }
DisableWait(unsigned index)301*f6dc9357SAndroid Build Coastguard Worker   void DisableWait(unsigned index) { NeedWait[index] = false; }
302*f6dc9357SAndroid Build Coastguard Worker 
CloseAll()303*f6dc9357SAndroid Build Coastguard Worker   void CloseAll()
304*f6dc9357SAndroid Build Coastguard Worker   {
305*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, Handles)
306*f6dc9357SAndroid Build Coastguard Worker     {
307*f6dc9357SAndroid Build Coastguard Worker       HANDLE h = Handles[i];
308*f6dc9357SAndroid Build Coastguard Worker       if (h != NULL)
309*f6dc9357SAndroid Build Coastguard Worker         CloseHandle(h);
310*f6dc9357SAndroid Build Coastguard Worker     }
311*f6dc9357SAndroid Build Coastguard Worker 
312*f6dc9357SAndroid Build Coastguard Worker     Handles.Clear();
313*f6dc9357SAndroid Build Coastguard Worker     NeedWait.Clear();
314*f6dc9357SAndroid Build Coastguard Worker     // Names.Clear();
315*f6dc9357SAndroid Build Coastguard Worker 
316*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
317*f6dc9357SAndroid Build Coastguard Worker     // Path.Empty();
318*f6dc9357SAndroid Build Coastguard Worker     _ids.Clear();
319*f6dc9357SAndroid Build Coastguard Worker     #endif
320*f6dc9357SAndroid Build Coastguard Worker   }
321*f6dc9357SAndroid Build Coastguard Worker 
SetMainProcess(HANDLE h)322*f6dc9357SAndroid Build Coastguard Worker   void SetMainProcess(HANDLE h)
323*f6dc9357SAndroid Build Coastguard Worker   {
324*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
325*f6dc9357SAndroid Build Coastguard Worker     const
326*f6dc9357SAndroid Build Coastguard Worker     Func_GetProcessId func = Z7_GET_PROC_ADDRESS(
327*f6dc9357SAndroid Build Coastguard Worker     Func_GetProcessId, ::GetModuleHandleA("kernel32.dll"),
328*f6dc9357SAndroid Build Coastguard Worker         "GetProcessId");
329*f6dc9357SAndroid Build Coastguard Worker     if (func)
330*f6dc9357SAndroid Build Coastguard Worker     {
331*f6dc9357SAndroid Build Coastguard Worker       const DWORD id = func(h);
332*f6dc9357SAndroid Build Coastguard Worker       if (id != 0)
333*f6dc9357SAndroid Build Coastguard Worker         _ids.AddToUniqueSorted(id);
334*f6dc9357SAndroid Build Coastguard Worker     }
335*f6dc9357SAndroid Build Coastguard Worker 
336*f6dc9357SAndroid Build Coastguard Worker     My_GetProcessFileName(h, Path);
337*f6dc9357SAndroid Build Coastguard Worker     DEBUG_PRINT_W(Path);
338*f6dc9357SAndroid Build Coastguard Worker 
339*f6dc9357SAndroid Build Coastguard Worker     #endif
340*f6dc9357SAndroid Build Coastguard Worker 
341*f6dc9357SAndroid Build Coastguard Worker     Handles.Add(h);
342*f6dc9357SAndroid Build Coastguard Worker     NeedWait.Add(true);
343*f6dc9357SAndroid Build Coastguard Worker   }
344*f6dc9357SAndroid Build Coastguard Worker 
345*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
346*f6dc9357SAndroid Build Coastguard Worker 
Update(bool needFindProcessByPath)347*f6dc9357SAndroid Build Coastguard Worker   void Update(bool needFindProcessByPath /* , const CPossibleProgs &progs */)
348*f6dc9357SAndroid Build Coastguard Worker   {
349*f6dc9357SAndroid Build Coastguard Worker     /*
350*f6dc9357SAndroid Build Coastguard Worker     if (_ids.IsEmpty())
351*f6dc9357SAndroid Build Coastguard Worker       return;
352*f6dc9357SAndroid Build Coastguard Worker     */
353*f6dc9357SAndroid Build Coastguard Worker 
354*f6dc9357SAndroid Build Coastguard Worker     CObjectVector<CSnapshotProcess> sps;
355*f6dc9357SAndroid Build Coastguard Worker     GetSnapshot(sps);
356*f6dc9357SAndroid Build Coastguard Worker 
357*f6dc9357SAndroid Build Coastguard Worker     const int separ = Path.ReverseFind_PathSepar();
358*f6dc9357SAndroid Build Coastguard Worker     const UString mainName = Path.Ptr((unsigned)(separ + 1));
359*f6dc9357SAndroid Build Coastguard Worker     if (mainName.IsEmpty())
360*f6dc9357SAndroid Build Coastguard Worker       needFindProcessByPath = false;
361*f6dc9357SAndroid Build Coastguard Worker 
362*f6dc9357SAndroid Build Coastguard Worker     const DWORD currentProcessId = GetCurrentProcessId();
363*f6dc9357SAndroid Build Coastguard Worker 
364*f6dc9357SAndroid Build Coastguard Worker     for (;;)
365*f6dc9357SAndroid Build Coastguard Worker     {
366*f6dc9357SAndroid Build Coastguard Worker       bool wasAdded = false;
367*f6dc9357SAndroid Build Coastguard Worker 
368*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (i, sps)
369*f6dc9357SAndroid Build Coastguard Worker       {
370*f6dc9357SAndroid Build Coastguard Worker         const CSnapshotProcess &sp = sps[i];
371*f6dc9357SAndroid Build Coastguard Worker         const DWORD id = sp.Id;
372*f6dc9357SAndroid Build Coastguard Worker 
373*f6dc9357SAndroid Build Coastguard Worker         if (id == currentProcessId)
374*f6dc9357SAndroid Build Coastguard Worker           continue;
375*f6dc9357SAndroid Build Coastguard Worker         if (_ids.FindInSorted(id) >= 0)
376*f6dc9357SAndroid Build Coastguard Worker           continue;
377*f6dc9357SAndroid Build Coastguard Worker 
378*f6dc9357SAndroid Build Coastguard Worker         bool isSameName = false;
379*f6dc9357SAndroid Build Coastguard Worker         const UString &name = sp.Name;
380*f6dc9357SAndroid Build Coastguard Worker 
381*f6dc9357SAndroid Build Coastguard Worker         if (needFindProcessByPath)
382*f6dc9357SAndroid Build Coastguard Worker           isSameName = mainName.IsEqualTo_NoCase(name);
383*f6dc9357SAndroid Build Coastguard Worker 
384*f6dc9357SAndroid Build Coastguard Worker         bool needAdd = false;
385*f6dc9357SAndroid Build Coastguard Worker         // bool isFromProgs = false;
386*f6dc9357SAndroid Build Coastguard Worker 
387*f6dc9357SAndroid Build Coastguard Worker         if (isSameName || _ids.FindInSorted(sp.ParentId) >= 0)
388*f6dc9357SAndroid Build Coastguard Worker           needAdd = true;
389*f6dc9357SAndroid Build Coastguard Worker         /*
390*f6dc9357SAndroid Build Coastguard Worker         else if (progs.IsFromList(name))
391*f6dc9357SAndroid Build Coastguard Worker         {
392*f6dc9357SAndroid Build Coastguard Worker           needAdd = true;
393*f6dc9357SAndroid Build Coastguard Worker           isFromProgs = true;
394*f6dc9357SAndroid Build Coastguard Worker         }
395*f6dc9357SAndroid Build Coastguard Worker         */
396*f6dc9357SAndroid Build Coastguard Worker 
397*f6dc9357SAndroid Build Coastguard Worker         if (needAdd)
398*f6dc9357SAndroid Build Coastguard Worker         {
399*f6dc9357SAndroid Build Coastguard Worker           DEBUG_PRINT("----- OpenProcess -----");
400*f6dc9357SAndroid Build Coastguard Worker           DEBUG_PRINT_W(name);
401*f6dc9357SAndroid Build Coastguard Worker           HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id);
402*f6dc9357SAndroid Build Coastguard Worker           if (hProcess)
403*f6dc9357SAndroid Build Coastguard Worker           {
404*f6dc9357SAndroid Build Coastguard Worker             DEBUG_PRINT("----- OpenProcess OK -----");
405*f6dc9357SAndroid Build Coastguard Worker             // if (!isFromProgs)
406*f6dc9357SAndroid Build Coastguard Worker               _ids.AddToUniqueSorted(id);
407*f6dc9357SAndroid Build Coastguard Worker             Handles.Add(hProcess);
408*f6dc9357SAndroid Build Coastguard Worker             NeedWait.Add(true);
409*f6dc9357SAndroid Build Coastguard Worker             // Names.Add(name);
410*f6dc9357SAndroid Build Coastguard Worker             wasAdded = true;
411*f6dc9357SAndroid Build Coastguard Worker             // ProgsWereUsed = isFromProgs;
412*f6dc9357SAndroid Build Coastguard Worker           }
413*f6dc9357SAndroid Build Coastguard Worker         }
414*f6dc9357SAndroid Build Coastguard Worker       }
415*f6dc9357SAndroid Build Coastguard Worker 
416*f6dc9357SAndroid Build Coastguard Worker       if (!wasAdded)
417*f6dc9357SAndroid Build Coastguard Worker         break;
418*f6dc9357SAndroid Build Coastguard Worker     }
419*f6dc9357SAndroid Build Coastguard Worker   }
420*f6dc9357SAndroid Build Coastguard Worker 
421*f6dc9357SAndroid Build Coastguard Worker   #endif
422*f6dc9357SAndroid Build Coastguard Worker };
423*f6dc9357SAndroid Build Coastguard Worker 
424*f6dc9357SAndroid Build Coastguard Worker 
425*f6dc9357SAndroid Build Coastguard Worker struct CTmpProcessInfo: public CTempFileInfo
426*f6dc9357SAndroid Build Coastguard Worker {
427*f6dc9357SAndroid Build Coastguard Worker   CChildProcesses Processes;
428*f6dc9357SAndroid Build Coastguard Worker   HWND Window;
429*f6dc9357SAndroid Build Coastguard Worker   UString FullPathFolderPrefix;
430*f6dc9357SAndroid Build Coastguard Worker   bool UsePassword;
431*f6dc9357SAndroid Build Coastguard Worker   UString Password;
432*f6dc9357SAndroid Build Coastguard Worker 
433*f6dc9357SAndroid Build Coastguard Worker   bool ReadOnly;
434*f6dc9357SAndroid Build Coastguard Worker 
CTmpProcessInfoCTmpProcessInfo435*f6dc9357SAndroid Build Coastguard Worker   CTmpProcessInfo(): UsePassword(false), ReadOnly(false) {}
436*f6dc9357SAndroid Build Coastguard Worker };
437*f6dc9357SAndroid Build Coastguard Worker 
438*f6dc9357SAndroid Build Coastguard Worker 
439*f6dc9357SAndroid Build Coastguard Worker class CTmpProcessInfoRelease
440*f6dc9357SAndroid Build Coastguard Worker {
441*f6dc9357SAndroid Build Coastguard Worker   CTmpProcessInfo *_tmpProcessInfo;
442*f6dc9357SAndroid Build Coastguard Worker public:
443*f6dc9357SAndroid Build Coastguard Worker   bool _needDelete;
CTmpProcessInfoRelease(CTmpProcessInfo & tpi)444*f6dc9357SAndroid Build Coastguard Worker   CTmpProcessInfoRelease(CTmpProcessInfo &tpi):
445*f6dc9357SAndroid Build Coastguard Worker       _tmpProcessInfo(&tpi), _needDelete(true) {}
~CTmpProcessInfoRelease()446*f6dc9357SAndroid Build Coastguard Worker   ~CTmpProcessInfoRelease()
447*f6dc9357SAndroid Build Coastguard Worker   {
448*f6dc9357SAndroid Build Coastguard Worker     if (_needDelete)
449*f6dc9357SAndroid Build Coastguard Worker       _tmpProcessInfo->DeleteDirAndFile();
450*f6dc9357SAndroid Build Coastguard Worker   }
451*f6dc9357SAndroid Build Coastguard Worker };
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker void GetFolderError(CMyComPtr<IFolderFolder> &folder, UString &s);
454*f6dc9357SAndroid Build Coastguard Worker 
455*f6dc9357SAndroid Build Coastguard Worker 
OpenAsArc(IInStream * inStream,const CTempFileInfo & tempFileInfo,const UString & virtualFilePath,const UString & arcFormat,COpenResult & openRes)456*f6dc9357SAndroid Build Coastguard Worker HRESULT CPanel::OpenAsArc(IInStream *inStream,
457*f6dc9357SAndroid Build Coastguard Worker     const CTempFileInfo &tempFileInfo,
458*f6dc9357SAndroid Build Coastguard Worker     const UString &virtualFilePath,
459*f6dc9357SAndroid Build Coastguard Worker     const UString &arcFormat,
460*f6dc9357SAndroid Build Coastguard Worker     COpenResult &openRes)
461*f6dc9357SAndroid Build Coastguard Worker {
462*f6dc9357SAndroid Build Coastguard Worker   openRes.Encrypted = false;
463*f6dc9357SAndroid Build Coastguard Worker   CFolderLink folderLink;
464*f6dc9357SAndroid Build Coastguard Worker   (CTempFileInfo &)folderLink = tempFileInfo;
465*f6dc9357SAndroid Build Coastguard Worker 
466*f6dc9357SAndroid Build Coastguard Worker   if (inStream)
467*f6dc9357SAndroid Build Coastguard Worker     folderLink.IsVirtual = true;
468*f6dc9357SAndroid Build Coastguard Worker   else
469*f6dc9357SAndroid Build Coastguard Worker   {
470*f6dc9357SAndroid Build Coastguard Worker     if (!folderLink.FileInfo.Find(folderLink.FilePath))
471*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
472*f6dc9357SAndroid Build Coastguard Worker     if (folderLink.FileInfo.IsDir())
473*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
474*f6dc9357SAndroid Build Coastguard Worker     folderLink.IsVirtual = false;
475*f6dc9357SAndroid Build Coastguard Worker   }
476*f6dc9357SAndroid Build Coastguard Worker 
477*f6dc9357SAndroid Build Coastguard Worker   folderLink.VirtualPath = virtualFilePath;
478*f6dc9357SAndroid Build Coastguard Worker 
479*f6dc9357SAndroid Build Coastguard Worker   CFfpOpen ffp;
480*f6dc9357SAndroid Build Coastguard Worker   const HRESULT res = ffp.OpenFileFolderPlugin(inStream,
481*f6dc9357SAndroid Build Coastguard Worker       folderLink.FilePath.IsEmpty() ? us2fs(virtualFilePath) : folderLink.FilePath,
482*f6dc9357SAndroid Build Coastguard Worker       arcFormat, GetParent());
483*f6dc9357SAndroid Build Coastguard Worker 
484*f6dc9357SAndroid Build Coastguard Worker   openRes.Encrypted = ffp.Encrypted;
485*f6dc9357SAndroid Build Coastguard Worker   openRes.ErrorMessage = ffp.ErrorMessage;
486*f6dc9357SAndroid Build Coastguard Worker 
487*f6dc9357SAndroid Build Coastguard Worker   RINOK(res)
488*f6dc9357SAndroid Build Coastguard Worker 
489*f6dc9357SAndroid Build Coastguard Worker   folderLink.Password = ffp.Password;
490*f6dc9357SAndroid Build Coastguard Worker   folderLink.UsePassword = ffp.Encrypted;
491*f6dc9357SAndroid Build Coastguard Worker 
492*f6dc9357SAndroid Build Coastguard Worker   if (_folder)
493*f6dc9357SAndroid Build Coastguard Worker     folderLink.ParentFolderPath = GetFolderPath(_folder);
494*f6dc9357SAndroid Build Coastguard Worker   else
495*f6dc9357SAndroid Build Coastguard Worker     folderLink.ParentFolderPath = _currentFolderPrefix;
496*f6dc9357SAndroid Build Coastguard Worker 
497*f6dc9357SAndroid Build Coastguard Worker   if (!_parentFolders.IsEmpty())
498*f6dc9357SAndroid Build Coastguard Worker     folderLink.ParentFolder = _folder;
499*f6dc9357SAndroid Build Coastguard Worker 
500*f6dc9357SAndroid Build Coastguard Worker   _parentFolders.Add(folderLink);
501*f6dc9357SAndroid Build Coastguard Worker   _parentFolders.Back().Library.Attach(_library.Detach());
502*f6dc9357SAndroid Build Coastguard Worker 
503*f6dc9357SAndroid Build Coastguard Worker   ReleaseFolder();
504*f6dc9357SAndroid Build Coastguard Worker   _library.Free();
505*f6dc9357SAndroid Build Coastguard Worker   SetNewFolder(ffp.Folder);
506*f6dc9357SAndroid Build Coastguard Worker   _library.Attach(ffp.Library.Detach());
507*f6dc9357SAndroid Build Coastguard Worker 
508*f6dc9357SAndroid Build Coastguard Worker   _flatMode = _flatModeForArc;
509*f6dc9357SAndroid Build Coastguard Worker 
510*f6dc9357SAndroid Build Coastguard Worker   _thereAreDeletedItems = false;
511*f6dc9357SAndroid Build Coastguard Worker 
512*f6dc9357SAndroid Build Coastguard Worker   if (!openRes.ErrorMessage.IsEmpty())
513*f6dc9357SAndroid Build Coastguard Worker     MessageBox_Error(openRes.ErrorMessage);
514*f6dc9357SAndroid Build Coastguard Worker   /*
515*f6dc9357SAndroid Build Coastguard Worker   UString s;
516*f6dc9357SAndroid Build Coastguard Worker   GetFolderError(_folder, s);
517*f6dc9357SAndroid Build Coastguard Worker   if (!s.IsEmpty())
518*f6dc9357SAndroid Build Coastguard Worker     MessageBox_Error(s);
519*f6dc9357SAndroid Build Coastguard Worker   */
520*f6dc9357SAndroid Build Coastguard Worker   // we don't show error here by some reasons:
521*f6dc9357SAndroid Build Coastguard Worker   // after MessageBox_Warning it throws exception in nested archives in Debug Mode. why ?.
522*f6dc9357SAndroid Build Coastguard Worker   // MessageBox_Warning(L"test error");
523*f6dc9357SAndroid Build Coastguard Worker 
524*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
525*f6dc9357SAndroid Build Coastguard Worker }
526*f6dc9357SAndroid Build Coastguard Worker 
527*f6dc9357SAndroid Build Coastguard Worker 
OpenAsArc_Msg(IInStream * inStream,const CTempFileInfo & tempFileInfo,const UString & virtualFilePath,const UString & arcFormat)528*f6dc9357SAndroid Build Coastguard Worker HRESULT CPanel::OpenAsArc_Msg(IInStream *inStream,
529*f6dc9357SAndroid Build Coastguard Worker     const CTempFileInfo &tempFileInfo,
530*f6dc9357SAndroid Build Coastguard Worker     const UString &virtualFilePath,
531*f6dc9357SAndroid Build Coastguard Worker     const UString &arcFormat
532*f6dc9357SAndroid Build Coastguard Worker     // , bool &encrypted
533*f6dc9357SAndroid Build Coastguard Worker     // , bool showErrorMessage
534*f6dc9357SAndroid Build Coastguard Worker     )
535*f6dc9357SAndroid Build Coastguard Worker {
536*f6dc9357SAndroid Build Coastguard Worker   COpenResult opRes;
537*f6dc9357SAndroid Build Coastguard Worker 
538*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = OpenAsArc(inStream, tempFileInfo, virtualFilePath, arcFormat, opRes);
539*f6dc9357SAndroid Build Coastguard Worker 
540*f6dc9357SAndroid Build Coastguard Worker   if (res == S_OK)
541*f6dc9357SAndroid Build Coastguard Worker     return res;
542*f6dc9357SAndroid Build Coastguard Worker   if (res == E_ABORT)
543*f6dc9357SAndroid Build Coastguard Worker     return res;
544*f6dc9357SAndroid Build Coastguard Worker 
545*f6dc9357SAndroid Build Coastguard Worker   // if (showErrorMessage)
546*f6dc9357SAndroid Build Coastguard Worker   if (opRes.Encrypted || res != S_FALSE) // 17.01 : we show message also for (res != S_FALSE)
547*f6dc9357SAndroid Build Coastguard Worker   {
548*f6dc9357SAndroid Build Coastguard Worker     UString message;
549*f6dc9357SAndroid Build Coastguard Worker     if (res == S_FALSE)
550*f6dc9357SAndroid Build Coastguard Worker     {
551*f6dc9357SAndroid Build Coastguard Worker       message = MyFormatNew(
552*f6dc9357SAndroid Build Coastguard Worker           opRes.Encrypted ?
553*f6dc9357SAndroid Build Coastguard Worker             IDS_CANT_OPEN_ENCRYPTED_ARCHIVE :
554*f6dc9357SAndroid Build Coastguard Worker             IDS_CANT_OPEN_ARCHIVE,
555*f6dc9357SAndroid Build Coastguard Worker           virtualFilePath);
556*f6dc9357SAndroid Build Coastguard Worker     }
557*f6dc9357SAndroid Build Coastguard Worker     else
558*f6dc9357SAndroid Build Coastguard Worker       message = HResultToMessage(res);
559*f6dc9357SAndroid Build Coastguard Worker     MessageBox_Error(message);
560*f6dc9357SAndroid Build Coastguard Worker   }
561*f6dc9357SAndroid Build Coastguard Worker 
562*f6dc9357SAndroid Build Coastguard Worker   return res;
563*f6dc9357SAndroid Build Coastguard Worker }
564*f6dc9357SAndroid Build Coastguard Worker 
565*f6dc9357SAndroid Build Coastguard Worker 
OpenAsArc_Name(const UString & relPath,const UString & arcFormat)566*f6dc9357SAndroid Build Coastguard Worker HRESULT CPanel::OpenAsArc_Name(const UString &relPath, const UString &arcFormat
567*f6dc9357SAndroid Build Coastguard Worker     // , bool &encrypted,
568*f6dc9357SAndroid Build Coastguard Worker     // , bool showErrorMessage
569*f6dc9357SAndroid Build Coastguard Worker     )
570*f6dc9357SAndroid Build Coastguard Worker {
571*f6dc9357SAndroid Build Coastguard Worker   CTempFileInfo tfi;
572*f6dc9357SAndroid Build Coastguard Worker   tfi.RelPath = relPath;
573*f6dc9357SAndroid Build Coastguard Worker   tfi.FolderPath = us2fs(GetFsPath());
574*f6dc9357SAndroid Build Coastguard Worker   const UString fullPath = GetFsPath() + relPath;
575*f6dc9357SAndroid Build Coastguard Worker   tfi.FilePath = us2fs(fullPath);
576*f6dc9357SAndroid Build Coastguard Worker   return OpenAsArc_Msg(NULL, tfi, fullPath, arcFormat /* , encrypted, showErrorMessage */);
577*f6dc9357SAndroid Build Coastguard Worker }
578*f6dc9357SAndroid Build Coastguard Worker 
579*f6dc9357SAndroid Build Coastguard Worker 
OpenAsArc_Index(unsigned index,const wchar_t * type)580*f6dc9357SAndroid Build Coastguard Worker HRESULT CPanel::OpenAsArc_Index(unsigned index, const wchar_t *type
581*f6dc9357SAndroid Build Coastguard Worker     // , bool showErrorMessage
582*f6dc9357SAndroid Build Coastguard Worker     )
583*f6dc9357SAndroid Build Coastguard Worker {
584*f6dc9357SAndroid Build Coastguard Worker   CDisableTimerProcessing disableTimerProcessing1(*this);
585*f6dc9357SAndroid Build Coastguard Worker   CDisableNotify disableNotify(*this);
586*f6dc9357SAndroid Build Coastguard Worker 
587*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = OpenAsArc_Name(GetItemRelPath2(index), type ? type : L"" /* , encrypted, showErrorMessage */);
588*f6dc9357SAndroid Build Coastguard Worker   if (res != S_OK)
589*f6dc9357SAndroid Build Coastguard Worker   {
590*f6dc9357SAndroid Build Coastguard Worker     RefreshTitle(true); // in case of error we must refresh changed title of 7zFM
591*f6dc9357SAndroid Build Coastguard Worker     return res;
592*f6dc9357SAndroid Build Coastguard Worker   }
593*f6dc9357SAndroid Build Coastguard Worker   RefreshListCtrl();
594*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
595*f6dc9357SAndroid Build Coastguard Worker }
596*f6dc9357SAndroid Build Coastguard Worker 
597*f6dc9357SAndroid Build Coastguard Worker 
OpenParentArchiveFolder()598*f6dc9357SAndroid Build Coastguard Worker HRESULT CPanel::OpenParentArchiveFolder()
599*f6dc9357SAndroid Build Coastguard Worker {
600*f6dc9357SAndroid Build Coastguard Worker   CDisableTimerProcessing disableTimerProcessing(*this);
601*f6dc9357SAndroid Build Coastguard Worker   CDisableNotify disableNotify(*this);
602*f6dc9357SAndroid Build Coastguard Worker   if (_parentFolders.Size() < 2)
603*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
604*f6dc9357SAndroid Build Coastguard Worker   const CFolderLink &folderLinkPrev = _parentFolders[_parentFolders.Size() - 2];
605*f6dc9357SAndroid Build Coastguard Worker   const CFolderLink &folderLink = _parentFolders.Back();
606*f6dc9357SAndroid Build Coastguard Worker   NFind::CFileInfo newFileInfo;
607*f6dc9357SAndroid Build Coastguard Worker   if (newFileInfo.Find(folderLink.FilePath))
608*f6dc9357SAndroid Build Coastguard Worker   {
609*f6dc9357SAndroid Build Coastguard Worker     if (folderLink.WasChanged_from_FolderLink(newFileInfo))
610*f6dc9357SAndroid Build Coastguard Worker     {
611*f6dc9357SAndroid Build Coastguard Worker       const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath);
612*f6dc9357SAndroid Build Coastguard Worker       if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES)
613*f6dc9357SAndroid Build Coastguard Worker       {
614*f6dc9357SAndroid Build Coastguard Worker         if (OnOpenItemChanged(folderLink.FileIndex, fs2us(folderLink.FilePath),
615*f6dc9357SAndroid Build Coastguard Worker             folderLinkPrev.UsePassword, folderLinkPrev.Password) != S_OK)
616*f6dc9357SAndroid Build Coastguard Worker         {
617*f6dc9357SAndroid Build Coastguard Worker           ::MessageBoxW((HWND)*this, MyFormatNew(IDS_CANNOT_UPDATE_FILE,
618*f6dc9357SAndroid Build Coastguard Worker               fs2us(folderLink.FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
619*f6dc9357SAndroid Build Coastguard Worker           return S_OK;
620*f6dc9357SAndroid Build Coastguard Worker         }
621*f6dc9357SAndroid Build Coastguard Worker       }
622*f6dc9357SAndroid Build Coastguard Worker     }
623*f6dc9357SAndroid Build Coastguard Worker   }
624*f6dc9357SAndroid Build Coastguard Worker   folderLink.DeleteDirAndFile();
625*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
626*f6dc9357SAndroid Build Coastguard Worker }
627*f6dc9357SAndroid Build Coastguard Worker 
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker static const char * const kExeExtensions =
630*f6dc9357SAndroid Build Coastguard Worker   " exe bat ps1 com lnk"
631*f6dc9357SAndroid Build Coastguard Worker   " ";
632*f6dc9357SAndroid Build Coastguard Worker 
633*f6dc9357SAndroid Build Coastguard Worker static const char * const kStartExtensions =
634*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
635*f6dc9357SAndroid Build Coastguard Worker   " cab"
636*f6dc9357SAndroid Build Coastguard Worker   #endif
637*f6dc9357SAndroid Build Coastguard Worker   " exe bat ps1 com lnk"
638*f6dc9357SAndroid Build Coastguard Worker   " chm"
639*f6dc9357SAndroid Build Coastguard Worker   " msi doc dot xls ppt pps wps wpt wks xlr wdb vsd pub"
640*f6dc9357SAndroid Build Coastguard Worker 
641*f6dc9357SAndroid Build Coastguard Worker   " docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps"
642*f6dc9357SAndroid Build Coastguard Worker   " xlam pptx pptm potx potm ppam ppsx ppsm vsdx xsn"
643*f6dc9357SAndroid Build Coastguard Worker   " mpp"
644*f6dc9357SAndroid Build Coastguard Worker   " msg"
645*f6dc9357SAndroid Build Coastguard Worker   " dwf"
646*f6dc9357SAndroid Build Coastguard Worker 
647*f6dc9357SAndroid Build Coastguard Worker   " flv swf"
648*f6dc9357SAndroid Build Coastguard Worker 
649*f6dc9357SAndroid Build Coastguard Worker   " epub"
650*f6dc9357SAndroid Build Coastguard Worker   " odt ods"
651*f6dc9357SAndroid Build Coastguard Worker   " wb3"
652*f6dc9357SAndroid Build Coastguard Worker   " pdf"
653*f6dc9357SAndroid Build Coastguard Worker   " ps"
654*f6dc9357SAndroid Build Coastguard Worker   " txt"
655*f6dc9357SAndroid Build Coastguard Worker   " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
656*f6dc9357SAndroid Build Coastguard Worker   " h hpp hxx c cpp cxx m mm go swift"
657*f6dc9357SAndroid Build Coastguard Worker   " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
658*f6dc9357SAndroid Build Coastguard Worker   " asm"
659*f6dc9357SAndroid Build Coastguard Worker   " mak clw csproj vcproj sln dsp dsw"
660*f6dc9357SAndroid Build Coastguard Worker   " ";
661*f6dc9357SAndroid Build Coastguard Worker 
662*f6dc9357SAndroid Build Coastguard Worker // bool FindExt(const char *p, const UString &name, AString &s);
663*f6dc9357SAndroid Build Coastguard Worker bool FindExt(const char *p, const UString &name, CStringFinder &finder);
664*f6dc9357SAndroid Build Coastguard Worker 
DoItemAlwaysStart(const UString & name)665*f6dc9357SAndroid Build Coastguard Worker static bool DoItemAlwaysStart(const UString &name)
666*f6dc9357SAndroid Build Coastguard Worker {
667*f6dc9357SAndroid Build Coastguard Worker   CStringFinder finder;
668*f6dc9357SAndroid Build Coastguard Worker   return FindExt(kStartExtensions, name, finder);
669*f6dc9357SAndroid Build Coastguard Worker }
670*f6dc9357SAndroid Build Coastguard Worker 
671*f6dc9357SAndroid Build Coastguard Worker UString GetQuotedString(const UString &s);
672*f6dc9357SAndroid Build Coastguard Worker 
673*f6dc9357SAndroid Build Coastguard Worker 
674*f6dc9357SAndroid Build Coastguard Worker void SplitCmdLineSmart(const UString &cmd, UString &prg, UString &params);
SplitCmdLineSmart(const UString & cmd,UString & prg,UString & params)675*f6dc9357SAndroid Build Coastguard Worker void SplitCmdLineSmart(const UString &cmd, UString &prg, UString &params)
676*f6dc9357SAndroid Build Coastguard Worker {
677*f6dc9357SAndroid Build Coastguard Worker   params.Empty();
678*f6dc9357SAndroid Build Coastguard Worker   prg = cmd;
679*f6dc9357SAndroid Build Coastguard Worker   prg.Trim();
680*f6dc9357SAndroid Build Coastguard Worker   if (prg.Len() >= 2 && prg[0] == L'"')
681*f6dc9357SAndroid Build Coastguard Worker   {
682*f6dc9357SAndroid Build Coastguard Worker     int pos = prg.Find(L'"', 1);
683*f6dc9357SAndroid Build Coastguard Worker     if (pos >= 0)
684*f6dc9357SAndroid Build Coastguard Worker     {
685*f6dc9357SAndroid Build Coastguard Worker       if ((unsigned)(pos + 1) == prg.Len() || prg[pos + 1] == ' ')
686*f6dc9357SAndroid Build Coastguard Worker       {
687*f6dc9357SAndroid Build Coastguard Worker         params = prg.Ptr((unsigned)(pos + 1));
688*f6dc9357SAndroid Build Coastguard Worker         params.Trim();
689*f6dc9357SAndroid Build Coastguard Worker         prg.DeleteFrom((unsigned)pos);
690*f6dc9357SAndroid Build Coastguard Worker         prg.DeleteFrontal(1);
691*f6dc9357SAndroid Build Coastguard Worker       }
692*f6dc9357SAndroid Build Coastguard Worker     }
693*f6dc9357SAndroid Build Coastguard Worker   }
694*f6dc9357SAndroid Build Coastguard Worker }
695*f6dc9357SAndroid Build Coastguard Worker 
696*f6dc9357SAndroid Build Coastguard Worker 
StartAppWithParams(const UString & cmd,const UStringVector & paramVector,CProcess & process)697*f6dc9357SAndroid Build Coastguard Worker static WRes StartAppWithParams(const UString &cmd, const UStringVector &paramVector, CProcess &process)
698*f6dc9357SAndroid Build Coastguard Worker {
699*f6dc9357SAndroid Build Coastguard Worker   UString param;
700*f6dc9357SAndroid Build Coastguard Worker   UString prg;
701*f6dc9357SAndroid Build Coastguard Worker 
702*f6dc9357SAndroid Build Coastguard Worker   SplitCmdLineSmart(cmd, prg, param);
703*f6dc9357SAndroid Build Coastguard Worker 
704*f6dc9357SAndroid Build Coastguard Worker   param.Trim();
705*f6dc9357SAndroid Build Coastguard Worker 
706*f6dc9357SAndroid Build Coastguard Worker   // int pos = params.Find(L"%1");
707*f6dc9357SAndroid Build Coastguard Worker 
708*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, paramVector)
709*f6dc9357SAndroid Build Coastguard Worker   {
710*f6dc9357SAndroid Build Coastguard Worker     if (!param.IsEmpty() && param.Back() != ' ')
711*f6dc9357SAndroid Build Coastguard Worker       param.Add_Space();
712*f6dc9357SAndroid Build Coastguard Worker     param += GetQuotedString(paramVector[i]);
713*f6dc9357SAndroid Build Coastguard Worker   }
714*f6dc9357SAndroid Build Coastguard Worker 
715*f6dc9357SAndroid Build Coastguard Worker   return process.Create(prg, param, NULL);
716*f6dc9357SAndroid Build Coastguard Worker }
717*f6dc9357SAndroid Build Coastguard Worker 
718*f6dc9357SAndroid Build Coastguard Worker 
StartEditApplication(const UString & path,bool useEditor,HWND window,CProcess & process)719*f6dc9357SAndroid Build Coastguard Worker static HRESULT StartEditApplication(const UString &path, bool useEditor, HWND window, CProcess &process)
720*f6dc9357SAndroid Build Coastguard Worker {
721*f6dc9357SAndroid Build Coastguard Worker   UString command;
722*f6dc9357SAndroid Build Coastguard Worker   ReadRegEditor(useEditor, command);
723*f6dc9357SAndroid Build Coastguard Worker   if (command.IsEmpty())
724*f6dc9357SAndroid Build Coastguard Worker   {
725*f6dc9357SAndroid Build Coastguard Worker     #ifdef UNDER_CE
726*f6dc9357SAndroid Build Coastguard Worker     command = "\\Windows\\";
727*f6dc9357SAndroid Build Coastguard Worker     #else
728*f6dc9357SAndroid Build Coastguard Worker     FString winDir;
729*f6dc9357SAndroid Build Coastguard Worker     if (!GetWindowsDir(winDir))
730*f6dc9357SAndroid Build Coastguard Worker       return 0;
731*f6dc9357SAndroid Build Coastguard Worker     NName::NormalizeDirPathPrefix(winDir);
732*f6dc9357SAndroid Build Coastguard Worker     command = fs2us(winDir);
733*f6dc9357SAndroid Build Coastguard Worker     #endif
734*f6dc9357SAndroid Build Coastguard Worker     command += "notepad.exe";
735*f6dc9357SAndroid Build Coastguard Worker   }
736*f6dc9357SAndroid Build Coastguard Worker 
737*f6dc9357SAndroid Build Coastguard Worker   UStringVector params;
738*f6dc9357SAndroid Build Coastguard Worker   params.Add(path);
739*f6dc9357SAndroid Build Coastguard Worker 
740*f6dc9357SAndroid Build Coastguard Worker   const WRes res = StartAppWithParams(command, params, process);
741*f6dc9357SAndroid Build Coastguard Worker   if (res != 0)
742*f6dc9357SAndroid Build Coastguard Worker     ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK  | MB_ICONSTOP);
743*f6dc9357SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(res);
744*f6dc9357SAndroid Build Coastguard Worker }
745*f6dc9357SAndroid Build Coastguard Worker 
746*f6dc9357SAndroid Build Coastguard Worker 
DiffFiles()747*f6dc9357SAndroid Build Coastguard Worker void CApp::DiffFiles()
748*f6dc9357SAndroid Build Coastguard Worker {
749*f6dc9357SAndroid Build Coastguard Worker   const CPanel &panel = GetFocusedPanel();
750*f6dc9357SAndroid Build Coastguard Worker 
751*f6dc9357SAndroid Build Coastguard Worker   if (!panel.Is_IO_FS_Folder())
752*f6dc9357SAndroid Build Coastguard Worker   {
753*f6dc9357SAndroid Build Coastguard Worker     panel.MessageBox_Error_UnsupportOperation();
754*f6dc9357SAndroid Build Coastguard Worker     return;
755*f6dc9357SAndroid Build Coastguard Worker   }
756*f6dc9357SAndroid Build Coastguard Worker 
757*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<UInt32> indices;
758*f6dc9357SAndroid Build Coastguard Worker   panel.Get_ItemIndices_Selected(indices);
759*f6dc9357SAndroid Build Coastguard Worker 
760*f6dc9357SAndroid Build Coastguard Worker   UString path1, path2;
761*f6dc9357SAndroid Build Coastguard Worker   if (indices.Size() == 2)
762*f6dc9357SAndroid Build Coastguard Worker   {
763*f6dc9357SAndroid Build Coastguard Worker     path1 = panel.GetItemFullPath(indices[0]);
764*f6dc9357SAndroid Build Coastguard Worker     path2 = panel.GetItemFullPath(indices[1]);
765*f6dc9357SAndroid Build Coastguard Worker   }
766*f6dc9357SAndroid Build Coastguard Worker   else if (indices.Size() == 1 && NumPanels >= 2)
767*f6dc9357SAndroid Build Coastguard Worker   {
768*f6dc9357SAndroid Build Coastguard Worker     const CPanel &destPanel = Panels[1 - LastFocusedPanel];
769*f6dc9357SAndroid Build Coastguard Worker 
770*f6dc9357SAndroid Build Coastguard Worker     if (!destPanel.Is_IO_FS_Folder())
771*f6dc9357SAndroid Build Coastguard Worker     {
772*f6dc9357SAndroid Build Coastguard Worker       panel.MessageBox_Error_UnsupportOperation();
773*f6dc9357SAndroid Build Coastguard Worker       return;
774*f6dc9357SAndroid Build Coastguard Worker     }
775*f6dc9357SAndroid Build Coastguard Worker 
776*f6dc9357SAndroid Build Coastguard Worker     path1 = panel.GetItemFullPath(indices[0]);
777*f6dc9357SAndroid Build Coastguard Worker     CRecordVector<UInt32> indices2;
778*f6dc9357SAndroid Build Coastguard Worker     destPanel.Get_ItemIndices_Selected(indices2);
779*f6dc9357SAndroid Build Coastguard Worker     if (indices2.Size() == 1)
780*f6dc9357SAndroid Build Coastguard Worker       path2 = destPanel.GetItemFullPath(indices2[0]);
781*f6dc9357SAndroid Build Coastguard Worker     else
782*f6dc9357SAndroid Build Coastguard Worker     {
783*f6dc9357SAndroid Build Coastguard Worker       UString relPath = panel.GetItemRelPath2(indices[0]);
784*f6dc9357SAndroid Build Coastguard Worker       if (panel._flatMode && !destPanel._flatMode)
785*f6dc9357SAndroid Build Coastguard Worker         relPath = panel.GetItemName(indices[0]);
786*f6dc9357SAndroid Build Coastguard Worker       path2 = destPanel._currentFolderPrefix + relPath;
787*f6dc9357SAndroid Build Coastguard Worker     }
788*f6dc9357SAndroid Build Coastguard Worker   }
789*f6dc9357SAndroid Build Coastguard Worker   else
790*f6dc9357SAndroid Build Coastguard Worker     return;
791*f6dc9357SAndroid Build Coastguard Worker 
792*f6dc9357SAndroid Build Coastguard Worker   DiffFiles(path1, path2);
793*f6dc9357SAndroid Build Coastguard Worker }
794*f6dc9357SAndroid Build Coastguard Worker 
DiffFiles(const UString & path1,const UString & path2)795*f6dc9357SAndroid Build Coastguard Worker void CApp::DiffFiles(const UString &path1, const UString &path2)
796*f6dc9357SAndroid Build Coastguard Worker {
797*f6dc9357SAndroid Build Coastguard Worker   UString command;
798*f6dc9357SAndroid Build Coastguard Worker   ReadRegDiff(command);
799*f6dc9357SAndroid Build Coastguard Worker   if (command.IsEmpty())
800*f6dc9357SAndroid Build Coastguard Worker     return;
801*f6dc9357SAndroid Build Coastguard Worker 
802*f6dc9357SAndroid Build Coastguard Worker   UStringVector params;
803*f6dc9357SAndroid Build Coastguard Worker   params.Add(path1);
804*f6dc9357SAndroid Build Coastguard Worker   params.Add(path2);
805*f6dc9357SAndroid Build Coastguard Worker 
806*f6dc9357SAndroid Build Coastguard Worker   WRes res;
807*f6dc9357SAndroid Build Coastguard Worker   {
808*f6dc9357SAndroid Build Coastguard Worker     CProcess process;
809*f6dc9357SAndroid Build Coastguard Worker     res = StartAppWithParams(command, params, process);
810*f6dc9357SAndroid Build Coastguard Worker   }
811*f6dc9357SAndroid Build Coastguard Worker   if (res == 0)
812*f6dc9357SAndroid Build Coastguard Worker     return;
813*f6dc9357SAndroid Build Coastguard Worker   ::MessageBoxW(_window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK  | MB_ICONSTOP);
814*f6dc9357SAndroid Build Coastguard Worker }
815*f6dc9357SAndroid Build Coastguard Worker 
816*f6dc9357SAndroid Build Coastguard Worker 
817*f6dc9357SAndroid Build Coastguard Worker HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process);
818*f6dc9357SAndroid Build Coastguard Worker void StartApplicationDontWait(const UString &dir, const UString &path, HWND window);
819*f6dc9357SAndroid Build Coastguard Worker 
EditItem(unsigned index,bool useEditor)820*f6dc9357SAndroid Build Coastguard Worker void CPanel::EditItem(unsigned index, bool useEditor)
821*f6dc9357SAndroid Build Coastguard Worker {
822*f6dc9357SAndroid Build Coastguard Worker   if (!_parentFolders.IsEmpty())
823*f6dc9357SAndroid Build Coastguard Worker   {
824*f6dc9357SAndroid Build Coastguard Worker     OpenItemInArchive(index, false, true, true, useEditor);
825*f6dc9357SAndroid Build Coastguard Worker     return;
826*f6dc9357SAndroid Build Coastguard Worker   }
827*f6dc9357SAndroid Build Coastguard Worker   CProcess process;
828*f6dc9357SAndroid Build Coastguard Worker   StartEditApplication(GetItemFullPath(index), useEditor, (HWND)*this, process);
829*f6dc9357SAndroid Build Coastguard Worker }
830*f6dc9357SAndroid Build Coastguard Worker 
831*f6dc9357SAndroid Build Coastguard Worker 
OpenFolderExternal(unsigned index)832*f6dc9357SAndroid Build Coastguard Worker void CPanel::OpenFolderExternal(unsigned index)
833*f6dc9357SAndroid Build Coastguard Worker {
834*f6dc9357SAndroid Build Coastguard Worker   UString prefix = GetFsPath();
835*f6dc9357SAndroid Build Coastguard Worker   UString path = prefix;
836*f6dc9357SAndroid Build Coastguard Worker 
837*f6dc9357SAndroid Build Coastguard Worker   if (index == kParentIndex)
838*f6dc9357SAndroid Build Coastguard Worker   {
839*f6dc9357SAndroid Build Coastguard Worker     if (prefix.IsEmpty())
840*f6dc9357SAndroid Build Coastguard Worker       return;
841*f6dc9357SAndroid Build Coastguard Worker     const wchar_t c = prefix.Back();
842*f6dc9357SAndroid Build Coastguard Worker     if (!IS_PATH_SEPAR(c) && c != ':')
843*f6dc9357SAndroid Build Coastguard Worker       return;
844*f6dc9357SAndroid Build Coastguard Worker     prefix.DeleteBack();
845*f6dc9357SAndroid Build Coastguard Worker     int pos = prefix.ReverseFind_PathSepar();
846*f6dc9357SAndroid Build Coastguard Worker     if (pos < 0)
847*f6dc9357SAndroid Build Coastguard Worker       return;
848*f6dc9357SAndroid Build Coastguard Worker     prefix.DeleteFrom((unsigned)(pos + 1));
849*f6dc9357SAndroid Build Coastguard Worker     path = prefix;
850*f6dc9357SAndroid Build Coastguard Worker   }
851*f6dc9357SAndroid Build Coastguard Worker   else
852*f6dc9357SAndroid Build Coastguard Worker   {
853*f6dc9357SAndroid Build Coastguard Worker     path += GetItemRelPath(index);
854*f6dc9357SAndroid Build Coastguard Worker     path.Add_PathSepar();
855*f6dc9357SAndroid Build Coastguard Worker   }
856*f6dc9357SAndroid Build Coastguard Worker 
857*f6dc9357SAndroid Build Coastguard Worker   StartApplicationDontWait(prefix, path, (HWND)*this);
858*f6dc9357SAndroid Build Coastguard Worker }
859*f6dc9357SAndroid Build Coastguard Worker 
860*f6dc9357SAndroid Build Coastguard Worker 
IsVirus_Message(const UString & name)861*f6dc9357SAndroid Build Coastguard Worker bool CPanel::IsVirus_Message(const UString &name)
862*f6dc9357SAndroid Build Coastguard Worker {
863*f6dc9357SAndroid Build Coastguard Worker   UString name2;
864*f6dc9357SAndroid Build Coastguard Worker 
865*f6dc9357SAndroid Build Coastguard Worker   const wchar_t cRLO = (wchar_t)0x202E;
866*f6dc9357SAndroid Build Coastguard Worker   bool isVirus = false;
867*f6dc9357SAndroid Build Coastguard Worker   bool isSpaceError = false;
868*f6dc9357SAndroid Build Coastguard Worker   name2 = name;
869*f6dc9357SAndroid Build Coastguard Worker 
870*f6dc9357SAndroid Build Coastguard Worker   if (name2.Find(cRLO) >= 0)
871*f6dc9357SAndroid Build Coastguard Worker   {
872*f6dc9357SAndroid Build Coastguard Worker     const UString badString(cRLO);
873*f6dc9357SAndroid Build Coastguard Worker     name2.Replace(badString, L"[RLO]");
874*f6dc9357SAndroid Build Coastguard Worker     isVirus = true;
875*f6dc9357SAndroid Build Coastguard Worker   }
876*f6dc9357SAndroid Build Coastguard Worker   {
877*f6dc9357SAndroid Build Coastguard Worker     const wchar_t * const kVirusSpaces = L"     ";
878*f6dc9357SAndroid Build Coastguard Worker     // const unsigned kNumSpaces = strlen(kVirusSpaces);
879*f6dc9357SAndroid Build Coastguard Worker     for (;;)
880*f6dc9357SAndroid Build Coastguard Worker     {
881*f6dc9357SAndroid Build Coastguard Worker       int pos = name2.Find(kVirusSpaces);
882*f6dc9357SAndroid Build Coastguard Worker       if (pos < 0)
883*f6dc9357SAndroid Build Coastguard Worker         break;
884*f6dc9357SAndroid Build Coastguard Worker       isVirus = true;
885*f6dc9357SAndroid Build Coastguard Worker       isSpaceError = true;
886*f6dc9357SAndroid Build Coastguard Worker       name2.Replace(kVirusSpaces, L" ");
887*f6dc9357SAndroid Build Coastguard Worker     }
888*f6dc9357SAndroid Build Coastguard Worker   }
889*f6dc9357SAndroid Build Coastguard Worker 
890*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
891*f6dc9357SAndroid Build Coastguard Worker   {
892*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
893*f6dc9357SAndroid Build Coastguard Worker     for (i = name2.Len(); i != 0;)
894*f6dc9357SAndroid Build Coastguard Worker     {
895*f6dc9357SAndroid Build Coastguard Worker       wchar_t c = name2[i - 1];
896*f6dc9357SAndroid Build Coastguard Worker       if (c != '.' && c != ' ')
897*f6dc9357SAndroid Build Coastguard Worker         break;
898*f6dc9357SAndroid Build Coastguard Worker       i--;
899*f6dc9357SAndroid Build Coastguard Worker       name2.ReplaceOneCharAtPos(i, '_');
900*f6dc9357SAndroid Build Coastguard Worker     }
901*f6dc9357SAndroid Build Coastguard Worker     if (i != name2.Len())
902*f6dc9357SAndroid Build Coastguard Worker     {
903*f6dc9357SAndroid Build Coastguard Worker       CStringFinder finder;
904*f6dc9357SAndroid Build Coastguard Worker       UString name3 = name2;
905*f6dc9357SAndroid Build Coastguard Worker       name3.DeleteFrom(i);
906*f6dc9357SAndroid Build Coastguard Worker       if (FindExt(kExeExtensions, name3, finder))
907*f6dc9357SAndroid Build Coastguard Worker         isVirus = true;
908*f6dc9357SAndroid Build Coastguard Worker     }
909*f6dc9357SAndroid Build Coastguard Worker   }
910*f6dc9357SAndroid Build Coastguard Worker   #endif
911*f6dc9357SAndroid Build Coastguard Worker 
912*f6dc9357SAndroid Build Coastguard Worker   if (!isVirus)
913*f6dc9357SAndroid Build Coastguard Worker     return false;
914*f6dc9357SAndroid Build Coastguard Worker 
915*f6dc9357SAndroid Build Coastguard Worker   UString s = LangString(IDS_VIRUS);
916*f6dc9357SAndroid Build Coastguard Worker 
917*f6dc9357SAndroid Build Coastguard Worker   if (!isSpaceError)
918*f6dc9357SAndroid Build Coastguard Worker   {
919*f6dc9357SAndroid Build Coastguard Worker     const int pos1 = s.Find(L'(');
920*f6dc9357SAndroid Build Coastguard Worker     if (pos1 >= 0)
921*f6dc9357SAndroid Build Coastguard Worker     {
922*f6dc9357SAndroid Build Coastguard Worker       const int pos2 = s.Find(L')', (unsigned)pos1 + 1);
923*f6dc9357SAndroid Build Coastguard Worker       if (pos2 >= 0)
924*f6dc9357SAndroid Build Coastguard Worker       {
925*f6dc9357SAndroid Build Coastguard Worker         s.Delete((unsigned)pos1, (unsigned)pos2 + 1 - (unsigned)pos1);
926*f6dc9357SAndroid Build Coastguard Worker         if (pos1 > 0 && s[pos1 - 1] == ' ' && s[pos1] == '.')
927*f6dc9357SAndroid Build Coastguard Worker           s.Delete(pos1 - 1);
928*f6dc9357SAndroid Build Coastguard Worker       }
929*f6dc9357SAndroid Build Coastguard Worker     }
930*f6dc9357SAndroid Build Coastguard Worker   }
931*f6dc9357SAndroid Build Coastguard Worker 
932*f6dc9357SAndroid Build Coastguard Worker   UString name3 = name;
933*f6dc9357SAndroid Build Coastguard Worker   name3.Replace(L'\n', L'_');
934*f6dc9357SAndroid Build Coastguard Worker   name2.Replace(L'\n', L'_');
935*f6dc9357SAndroid Build Coastguard Worker 
936*f6dc9357SAndroid Build Coastguard Worker   s.Add_LF(); s += name2;
937*f6dc9357SAndroid Build Coastguard Worker   s.Add_LF(); s += name3;
938*f6dc9357SAndroid Build Coastguard Worker 
939*f6dc9357SAndroid Build Coastguard Worker   MessageBox_Error(s);
940*f6dc9357SAndroid Build Coastguard Worker   return true;
941*f6dc9357SAndroid Build Coastguard Worker }
942*f6dc9357SAndroid Build Coastguard Worker 
943*f6dc9357SAndroid Build Coastguard Worker 
OpenItem(unsigned index,bool tryInternal,bool tryExternal,const wchar_t * type)944*f6dc9357SAndroid Build Coastguard Worker void CPanel::OpenItem(unsigned index, bool tryInternal, bool tryExternal, const wchar_t *type)
945*f6dc9357SAndroid Build Coastguard Worker {
946*f6dc9357SAndroid Build Coastguard Worker   CDisableTimerProcessing disableTimerProcessing(*this);
947*f6dc9357SAndroid Build Coastguard Worker   const UString name = GetItemRelPath2(index);
948*f6dc9357SAndroid Build Coastguard Worker 
949*f6dc9357SAndroid Build Coastguard Worker   if (tryExternal)
950*f6dc9357SAndroid Build Coastguard Worker     if (IsVirus_Message(name))
951*f6dc9357SAndroid Build Coastguard Worker       return;
952*f6dc9357SAndroid Build Coastguard Worker 
953*f6dc9357SAndroid Build Coastguard Worker   if (!_parentFolders.IsEmpty())
954*f6dc9357SAndroid Build Coastguard Worker   {
955*f6dc9357SAndroid Build Coastguard Worker     OpenItemInArchive(index, tryInternal, tryExternal, false, false, type);
956*f6dc9357SAndroid Build Coastguard Worker     return;
957*f6dc9357SAndroid Build Coastguard Worker   }
958*f6dc9357SAndroid Build Coastguard Worker 
959*f6dc9357SAndroid Build Coastguard Worker   CDisableNotify disableNotify(*this);
960*f6dc9357SAndroid Build Coastguard Worker   UString prefix = GetFsPath();
961*f6dc9357SAndroid Build Coastguard Worker   UString fullPath = prefix + name;
962*f6dc9357SAndroid Build Coastguard Worker 
963*f6dc9357SAndroid Build Coastguard Worker   if (tryInternal)
964*f6dc9357SAndroid Build Coastguard Worker     if (!tryExternal || !DoItemAlwaysStart(name))
965*f6dc9357SAndroid Build Coastguard Worker     {
966*f6dc9357SAndroid Build Coastguard Worker       HRESULT res = OpenAsArc_Index(index, type
967*f6dc9357SAndroid Build Coastguard Worker           // , true
968*f6dc9357SAndroid Build Coastguard Worker           );
969*f6dc9357SAndroid Build Coastguard Worker       disableNotify.Restore(); // we must restore to allow text notification update
970*f6dc9357SAndroid Build Coastguard Worker       InvalidateList();
971*f6dc9357SAndroid Build Coastguard Worker       if (res == S_OK || res == E_ABORT)
972*f6dc9357SAndroid Build Coastguard Worker         return;
973*f6dc9357SAndroid Build Coastguard Worker       if (res != S_FALSE)
974*f6dc9357SAndroid Build Coastguard Worker       {
975*f6dc9357SAndroid Build Coastguard Worker         MessageBox_Error_HRESULT(res);
976*f6dc9357SAndroid Build Coastguard Worker         return;
977*f6dc9357SAndroid Build Coastguard Worker       }
978*f6dc9357SAndroid Build Coastguard Worker     }
979*f6dc9357SAndroid Build Coastguard Worker 
980*f6dc9357SAndroid Build Coastguard Worker   if (tryExternal)
981*f6dc9357SAndroid Build Coastguard Worker   {
982*f6dc9357SAndroid Build Coastguard Worker     // SetCurrentDirectory opens HANDLE to folder!!!
983*f6dc9357SAndroid Build Coastguard Worker     // NDirectory::MySetCurrentDirectory(prefix);
984*f6dc9357SAndroid Build Coastguard Worker     StartApplicationDontWait(prefix, fullPath, (HWND)*this);
985*f6dc9357SAndroid Build Coastguard Worker   }
986*f6dc9357SAndroid Build Coastguard Worker }
987*f6dc9357SAndroid Build Coastguard Worker 
988*f6dc9357SAndroid Build Coastguard Worker class CThreadCopyFrom: public CProgressThreadVirt
989*f6dc9357SAndroid Build Coastguard Worker {
990*f6dc9357SAndroid Build Coastguard Worker   HRESULT ProcessVirt() Z7_override;
991*f6dc9357SAndroid Build Coastguard Worker public:
992*f6dc9357SAndroid Build Coastguard Worker   UString FullPath;
993*f6dc9357SAndroid Build Coastguard Worker   UInt32 ItemIndex;
994*f6dc9357SAndroid Build Coastguard Worker 
995*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderOperations> FolderOperations;
996*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IProgress> UpdateCallback;
997*f6dc9357SAndroid Build Coastguard Worker   CUpdateCallback100Imp *UpdateCallbackSpec;
998*f6dc9357SAndroid Build Coastguard Worker };
999*f6dc9357SAndroid Build Coastguard Worker 
ProcessVirt()1000*f6dc9357SAndroid Build Coastguard Worker HRESULT CThreadCopyFrom::ProcessVirt()
1001*f6dc9357SAndroid Build Coastguard Worker {
1002*f6dc9357SAndroid Build Coastguard Worker   return FolderOperations->CopyFromFile(ItemIndex, FullPath, UpdateCallback);
1003*f6dc9357SAndroid Build Coastguard Worker }
1004*f6dc9357SAndroid Build Coastguard Worker 
OnOpenItemChanged(UInt32 index,const wchar_t * fullFilePath,bool usePassword,const UString & password)1005*f6dc9357SAndroid Build Coastguard Worker HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
1006*f6dc9357SAndroid Build Coastguard Worker     bool usePassword, const UString &password)
1007*f6dc9357SAndroid Build Coastguard Worker {
1008*f6dc9357SAndroid Build Coastguard Worker   if (!_folderOperations)
1009*f6dc9357SAndroid Build Coastguard Worker   {
1010*f6dc9357SAndroid Build Coastguard Worker     MessageBox_Error_UnsupportOperation();
1011*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
1012*f6dc9357SAndroid Build Coastguard Worker   }
1013*f6dc9357SAndroid Build Coastguard Worker 
1014*f6dc9357SAndroid Build Coastguard Worker   CThreadCopyFrom t;
1015*f6dc9357SAndroid Build Coastguard Worker   t.UpdateCallbackSpec = new CUpdateCallback100Imp;
1016*f6dc9357SAndroid Build Coastguard Worker   t.UpdateCallback = t.UpdateCallbackSpec;
1017*f6dc9357SAndroid Build Coastguard Worker   t.UpdateCallbackSpec->ProgressDialog = &t;
1018*f6dc9357SAndroid Build Coastguard Worker   t.ItemIndex = index;
1019*f6dc9357SAndroid Build Coastguard Worker   t.FullPath = fullFilePath;
1020*f6dc9357SAndroid Build Coastguard Worker   t.FolderOperations = _folderOperations;
1021*f6dc9357SAndroid Build Coastguard Worker 
1022*f6dc9357SAndroid Build Coastguard Worker   t.UpdateCallbackSpec->Init();
1023*f6dc9357SAndroid Build Coastguard Worker   t.UpdateCallbackSpec->PasswordIsDefined = usePassword;
1024*f6dc9357SAndroid Build Coastguard Worker   t.UpdateCallbackSpec->Password = password;
1025*f6dc9357SAndroid Build Coastguard Worker 
1026*f6dc9357SAndroid Build Coastguard Worker 
1027*f6dc9357SAndroid Build Coastguard Worker   RINOK(t.Create(GetItemName(index), (HWND)*this))
1028*f6dc9357SAndroid Build Coastguard Worker   return t.Result;
1029*f6dc9357SAndroid Build Coastguard Worker }
1030*f6dc9357SAndroid Build Coastguard Worker 
OnOpenItemChanged(LPARAM lParam)1031*f6dc9357SAndroid Build Coastguard Worker LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
1032*f6dc9357SAndroid Build Coastguard Worker {
1033*f6dc9357SAndroid Build Coastguard Worker   // DEBUG_PRINT_NUM("OnOpenItemChanged", GetCurrentThreadId());
1034*f6dc9357SAndroid Build Coastguard Worker 
1035*f6dc9357SAndroid Build Coastguard Worker   CTmpProcessInfo &tpi = *(CTmpProcessInfo *)lParam;
1036*f6dc9357SAndroid Build Coastguard Worker   if (tpi.FullPathFolderPrefix != _currentFolderPrefix)
1037*f6dc9357SAndroid Build Coastguard Worker     return 0;
1038*f6dc9357SAndroid Build Coastguard Worker   UInt32 fileIndex = tpi.FileIndex;
1039*f6dc9357SAndroid Build Coastguard Worker   UInt32 numItems;
1040*f6dc9357SAndroid Build Coastguard Worker   _folder->GetNumberOfItems(&numItems);
1041*f6dc9357SAndroid Build Coastguard Worker 
1042*f6dc9357SAndroid Build Coastguard Worker   // This code is not 100% OK for cases when there are several files with
1043*f6dc9357SAndroid Build Coastguard Worker   // tpi.RelPath name and there are changes in archive before update.
1044*f6dc9357SAndroid Build Coastguard Worker   // So tpi.FileIndex can point to another file.
1045*f6dc9357SAndroid Build Coastguard Worker 
1046*f6dc9357SAndroid Build Coastguard Worker   if (fileIndex >= numItems || GetItemRelPath(fileIndex) != tpi.RelPath)
1047*f6dc9357SAndroid Build Coastguard Worker   {
1048*f6dc9357SAndroid Build Coastguard Worker     UInt32 i;
1049*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numItems; i++)
1050*f6dc9357SAndroid Build Coastguard Worker       if (GetItemRelPath(i) == tpi.RelPath)
1051*f6dc9357SAndroid Build Coastguard Worker         break;
1052*f6dc9357SAndroid Build Coastguard Worker     if (i == numItems)
1053*f6dc9357SAndroid Build Coastguard Worker       return 0;
1054*f6dc9357SAndroid Build Coastguard Worker     fileIndex = i;
1055*f6dc9357SAndroid Build Coastguard Worker   }
1056*f6dc9357SAndroid Build Coastguard Worker 
1057*f6dc9357SAndroid Build Coastguard Worker   CSelectedState state;
1058*f6dc9357SAndroid Build Coastguard Worker   SaveSelectedState(state);
1059*f6dc9357SAndroid Build Coastguard Worker 
1060*f6dc9357SAndroid Build Coastguard Worker   CDisableNotify disableNotify(*this); // do we need it??
1061*f6dc9357SAndroid Build Coastguard Worker 
1062*f6dc9357SAndroid Build Coastguard Worker   HRESULT result = OnOpenItemChanged(fileIndex, fs2us(tpi.FilePath), tpi.UsePassword, tpi.Password);
1063*f6dc9357SAndroid Build Coastguard Worker   RefreshListCtrl(state);
1064*f6dc9357SAndroid Build Coastguard Worker   if (result != S_OK)
1065*f6dc9357SAndroid Build Coastguard Worker     return 0;
1066*f6dc9357SAndroid Build Coastguard Worker   return 1;
1067*f6dc9357SAndroid Build Coastguard Worker }
1068*f6dc9357SAndroid Build Coastguard Worker 
1069*f6dc9357SAndroid Build Coastguard Worker 
1070*f6dc9357SAndroid Build Coastguard Worker CExitEventLauncher g_ExitEventLauncher;
1071*f6dc9357SAndroid Build Coastguard Worker 
Exit(bool hardExit)1072*f6dc9357SAndroid Build Coastguard Worker void CExitEventLauncher::Exit(bool hardExit)
1073*f6dc9357SAndroid Build Coastguard Worker {
1074*f6dc9357SAndroid Build Coastguard Worker   if (_needExit)
1075*f6dc9357SAndroid Build Coastguard Worker   {
1076*f6dc9357SAndroid Build Coastguard Worker     _exitEvent.Set();
1077*f6dc9357SAndroid Build Coastguard Worker     _needExit = false;
1078*f6dc9357SAndroid Build Coastguard Worker   }
1079*f6dc9357SAndroid Build Coastguard Worker 
1080*f6dc9357SAndroid Build Coastguard Worker   if (_numActiveThreads == 0)
1081*f6dc9357SAndroid Build Coastguard Worker     return;
1082*f6dc9357SAndroid Build Coastguard Worker 
1083*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, _threads)
1084*f6dc9357SAndroid Build Coastguard Worker   {
1085*f6dc9357SAndroid Build Coastguard Worker     ::CThread &th = _threads[i];
1086*f6dc9357SAndroid Build Coastguard Worker     if (Thread_WasCreated(&th))
1087*f6dc9357SAndroid Build Coastguard Worker     {
1088*f6dc9357SAndroid Build Coastguard Worker       const DWORD waitResult = WaitForSingleObject(th, hardExit ? 100 : INFINITE);
1089*f6dc9357SAndroid Build Coastguard Worker       // Thread_Wait(&th);
1090*f6dc9357SAndroid Build Coastguard Worker       // if (waitResult == WAIT_TIMEOUT) wait = 1;
1091*f6dc9357SAndroid Build Coastguard Worker       if (!hardExit && waitResult != WAIT_OBJECT_0)
1092*f6dc9357SAndroid Build Coastguard Worker         continue;
1093*f6dc9357SAndroid Build Coastguard Worker       Thread_Close(&th);
1094*f6dc9357SAndroid Build Coastguard Worker       _numActiveThreads--;
1095*f6dc9357SAndroid Build Coastguard Worker     }
1096*f6dc9357SAndroid Build Coastguard Worker   }
1097*f6dc9357SAndroid Build Coastguard Worker }
1098*f6dc9357SAndroid Build Coastguard Worker 
1099*f6dc9357SAndroid Build Coastguard Worker 
1100*f6dc9357SAndroid Build Coastguard Worker 
MyThreadFunction(void * param)1101*f6dc9357SAndroid Build Coastguard Worker static THREAD_FUNC_DECL MyThreadFunction(void *param)
1102*f6dc9357SAndroid Build Coastguard Worker {
1103*f6dc9357SAndroid Build Coastguard Worker   DEBUG_PRINT("==== MyThreadFunction ====");
1104*f6dc9357SAndroid Build Coastguard Worker 
1105*f6dc9357SAndroid Build Coastguard Worker   CMyUniquePtr<CTmpProcessInfo> tpi((CTmpProcessInfo *)param);
1106*f6dc9357SAndroid Build Coastguard Worker   CChildProcesses &processes = tpi->Processes;
1107*f6dc9357SAndroid Build Coastguard Worker 
1108*f6dc9357SAndroid Build Coastguard Worker   const bool mainProcessWasSet = !processes.Handles.IsEmpty();
1109*f6dc9357SAndroid Build Coastguard Worker 
1110*f6dc9357SAndroid Build Coastguard Worker   bool isComplexMode = true;
1111*f6dc9357SAndroid Build Coastguard Worker 
1112*f6dc9357SAndroid Build Coastguard Worker   if (!processes.Handles.IsEmpty())
1113*f6dc9357SAndroid Build Coastguard Worker   {
1114*f6dc9357SAndroid Build Coastguard Worker 
1115*f6dc9357SAndroid Build Coastguard Worker   const DWORD startTime = GetTickCount();
1116*f6dc9357SAndroid Build Coastguard Worker 
1117*f6dc9357SAndroid Build Coastguard Worker   /*
1118*f6dc9357SAndroid Build Coastguard Worker   CPossibleProgs progs;
1119*f6dc9357SAndroid Build Coastguard Worker   {
1120*f6dc9357SAndroid Build Coastguard Worker     const UString &name = tpi->RelPath;
1121*f6dc9357SAndroid Build Coastguard Worker     int slashPos = name.ReverseFind_PathSepar();
1122*f6dc9357SAndroid Build Coastguard Worker     int dotPos = name.ReverseFind_Dot();
1123*f6dc9357SAndroid Build Coastguard Worker     if (dotPos > slashPos)
1124*f6dc9357SAndroid Build Coastguard Worker     {
1125*f6dc9357SAndroid Build Coastguard Worker       const UString ext = name.Ptr(dotPos + 1);
1126*f6dc9357SAndroid Build Coastguard Worker       AString extA = UnicodeStringToMultiByte(ext);
1127*f6dc9357SAndroid Build Coastguard Worker       extA.MakeLower_Ascii();
1128*f6dc9357SAndroid Build Coastguard Worker       progs.SetFromExtension(extA);
1129*f6dc9357SAndroid Build Coastguard Worker     }
1130*f6dc9357SAndroid Build Coastguard Worker   }
1131*f6dc9357SAndroid Build Coastguard Worker   */
1132*f6dc9357SAndroid Build Coastguard Worker 
1133*f6dc9357SAndroid Build Coastguard Worker   bool firstPass = true;
1134*f6dc9357SAndroid Build Coastguard Worker 
1135*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1136*f6dc9357SAndroid Build Coastguard Worker   {
1137*f6dc9357SAndroid Build Coastguard Worker     CRecordVector<HANDLE> handles;
1138*f6dc9357SAndroid Build Coastguard Worker     CUIntVector indices;
1139*f6dc9357SAndroid Build Coastguard Worker 
1140*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, processes.Handles)
1141*f6dc9357SAndroid Build Coastguard Worker     {
1142*f6dc9357SAndroid Build Coastguard Worker       if (handles.Size() > 60)
1143*f6dc9357SAndroid Build Coastguard Worker         break;
1144*f6dc9357SAndroid Build Coastguard Worker       if (processes.NeedWait[i])
1145*f6dc9357SAndroid Build Coastguard Worker       {
1146*f6dc9357SAndroid Build Coastguard Worker         handles.Add(processes.Handles[i]);
1147*f6dc9357SAndroid Build Coastguard Worker         indices.Add(i);
1148*f6dc9357SAndroid Build Coastguard Worker       }
1149*f6dc9357SAndroid Build Coastguard Worker     }
1150*f6dc9357SAndroid Build Coastguard Worker 
1151*f6dc9357SAndroid Build Coastguard Worker     bool needFindProcessByPath = false;
1152*f6dc9357SAndroid Build Coastguard Worker 
1153*f6dc9357SAndroid Build Coastguard Worker     if (handles.IsEmpty())
1154*f6dc9357SAndroid Build Coastguard Worker     {
1155*f6dc9357SAndroid Build Coastguard Worker       if (!firstPass)
1156*f6dc9357SAndroid Build Coastguard Worker         break;
1157*f6dc9357SAndroid Build Coastguard Worker     }
1158*f6dc9357SAndroid Build Coastguard Worker     else
1159*f6dc9357SAndroid Build Coastguard Worker     {
1160*f6dc9357SAndroid Build Coastguard Worker       handles.Add(g_ExitEventLauncher._exitEvent);
1161*f6dc9357SAndroid Build Coastguard Worker 
1162*f6dc9357SAndroid Build Coastguard Worker       DWORD waitResult = WaitForMultiObj_Any_Infinite(handles.Size(), handles.ConstData());
1163*f6dc9357SAndroid Build Coastguard Worker 
1164*f6dc9357SAndroid Build Coastguard Worker       waitResult -= WAIT_OBJECT_0;
1165*f6dc9357SAndroid Build Coastguard Worker 
1166*f6dc9357SAndroid Build Coastguard Worker       if (waitResult >= handles.Size() - 1)
1167*f6dc9357SAndroid Build Coastguard Worker       {
1168*f6dc9357SAndroid Build Coastguard Worker         processes.CloseAll();
1169*f6dc9357SAndroid Build Coastguard Worker         /*
1170*f6dc9357SAndroid Build Coastguard Worker         if (waitResult == handles.Size() - 1)
1171*f6dc9357SAndroid Build Coastguard Worker         {
1172*f6dc9357SAndroid Build Coastguard Worker           // exit event
1173*f6dc9357SAndroid Build Coastguard Worker           // we want to delete temp files, if progs were used
1174*f6dc9357SAndroid Build Coastguard Worker           if (processes.ProgsWereUsed)
1175*f6dc9357SAndroid Build Coastguard Worker             break;
1176*f6dc9357SAndroid Build Coastguard Worker         }
1177*f6dc9357SAndroid Build Coastguard Worker         */
1178*f6dc9357SAndroid Build Coastguard Worker         return waitResult >= (DWORD)handles.Size() ? 1 : 0;
1179*f6dc9357SAndroid Build Coastguard Worker       }
1180*f6dc9357SAndroid Build Coastguard Worker 
1181*f6dc9357SAndroid Build Coastguard Worker       if (firstPass && indices.Size() == 1)
1182*f6dc9357SAndroid Build Coastguard Worker       {
1183*f6dc9357SAndroid Build Coastguard Worker         const DWORD curTime = GetTickCount() - startTime;
1184*f6dc9357SAndroid Build Coastguard Worker 
1185*f6dc9357SAndroid Build Coastguard Worker         /*
1186*f6dc9357SAndroid Build Coastguard Worker         if (curTime > 5 * 1000)
1187*f6dc9357SAndroid Build Coastguard Worker           progs.ProgNames.Clear();
1188*f6dc9357SAndroid Build Coastguard Worker         */
1189*f6dc9357SAndroid Build Coastguard Worker 
1190*f6dc9357SAndroid Build Coastguard Worker         needFindProcessByPath = (curTime < 2 * 1000);
1191*f6dc9357SAndroid Build Coastguard Worker 
1192*f6dc9357SAndroid Build Coastguard Worker         if (needFindProcessByPath)
1193*f6dc9357SAndroid Build Coastguard Worker         {
1194*f6dc9357SAndroid Build Coastguard Worker           NFind::CFileInfo newFileInfo;
1195*f6dc9357SAndroid Build Coastguard Worker           if (newFileInfo.Find(tpi->FilePath))
1196*f6dc9357SAndroid Build Coastguard Worker             if (tpi->WasChanged_from_TempFileInfo(newFileInfo))
1197*f6dc9357SAndroid Build Coastguard Worker               needFindProcessByPath = false;
1198*f6dc9357SAndroid Build Coastguard Worker         }
1199*f6dc9357SAndroid Build Coastguard Worker 
1200*f6dc9357SAndroid Build Coastguard Worker         DEBUG_PRINT_NUM(" -- firstPass -- time = ", curTime)
1201*f6dc9357SAndroid Build Coastguard Worker       }
1202*f6dc9357SAndroid Build Coastguard Worker 
1203*f6dc9357SAndroid Build Coastguard Worker       processes.DisableWait(indices[(unsigned)waitResult]);
1204*f6dc9357SAndroid Build Coastguard Worker     }
1205*f6dc9357SAndroid Build Coastguard Worker 
1206*f6dc9357SAndroid Build Coastguard Worker     firstPass = false;
1207*f6dc9357SAndroid Build Coastguard Worker 
1208*f6dc9357SAndroid Build Coastguard Worker     // Sleep(300);
1209*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
1210*f6dc9357SAndroid Build Coastguard Worker     processes.Update(needFindProcessByPath /* , progs */);
1211*f6dc9357SAndroid Build Coastguard Worker     #endif
1212*f6dc9357SAndroid Build Coastguard Worker   }
1213*f6dc9357SAndroid Build Coastguard Worker 
1214*f6dc9357SAndroid Build Coastguard Worker 
1215*f6dc9357SAndroid Build Coastguard Worker   const DWORD curTime = GetTickCount() - startTime;
1216*f6dc9357SAndroid Build Coastguard Worker 
1217*f6dc9357SAndroid Build Coastguard Worker   DEBUG_PRINT_NUM("after time = ", curTime)
1218*f6dc9357SAndroid Build Coastguard Worker 
1219*f6dc9357SAndroid Build Coastguard Worker   processes.CloseAll();
1220*f6dc9357SAndroid Build Coastguard Worker 
1221*f6dc9357SAndroid Build Coastguard Worker   isComplexMode = (curTime < 2 * 1000);
1222*f6dc9357SAndroid Build Coastguard Worker 
1223*f6dc9357SAndroid Build Coastguard Worker   }
1224*f6dc9357SAndroid Build Coastguard Worker 
1225*f6dc9357SAndroid Build Coastguard Worker   bool needCheckTimestamp = true;
1226*f6dc9357SAndroid Build Coastguard Worker 
1227*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1228*f6dc9357SAndroid Build Coastguard Worker   {
1229*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo newFileInfo;
1230*f6dc9357SAndroid Build Coastguard Worker 
1231*f6dc9357SAndroid Build Coastguard Worker     if (!newFileInfo.Find(tpi->FilePath))
1232*f6dc9357SAndroid Build Coastguard Worker       break;
1233*f6dc9357SAndroid Build Coastguard Worker 
1234*f6dc9357SAndroid Build Coastguard Worker     if (mainProcessWasSet)
1235*f6dc9357SAndroid Build Coastguard Worker     {
1236*f6dc9357SAndroid Build Coastguard Worker       if (tpi->WasChanged_from_TempFileInfo(newFileInfo))
1237*f6dc9357SAndroid Build Coastguard Worker       {
1238*f6dc9357SAndroid Build Coastguard Worker         UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath));
1239*f6dc9357SAndroid Build Coastguard Worker         if (tpi->ReadOnly)
1240*f6dc9357SAndroid Build Coastguard Worker         {
1241*f6dc9357SAndroid Build Coastguard Worker           m.Add_LF();
1242*f6dc9357SAndroid Build Coastguard Worker           AddLangString(m, IDS_PROP_READ_ONLY);
1243*f6dc9357SAndroid Build Coastguard Worker           m.Add_LF();
1244*f6dc9357SAndroid Build Coastguard Worker           m += tpi->FullPathFolderPrefix;
1245*f6dc9357SAndroid Build Coastguard Worker           ::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP);
1246*f6dc9357SAndroid Build Coastguard Worker           return 0;
1247*f6dc9357SAndroid Build Coastguard Worker         }
1248*f6dc9357SAndroid Build Coastguard Worker         {
1249*f6dc9357SAndroid Build Coastguard Worker           const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath);
1250*f6dc9357SAndroid Build Coastguard Worker           if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES)
1251*f6dc9357SAndroid Build Coastguard Worker           {
1252*f6dc9357SAndroid Build Coastguard Worker             // DEBUG_PRINT_NUM("SendMessage", GetCurrentThreadId());
1253*f6dc9357SAndroid Build Coastguard Worker             if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi.get()) != 1)
1254*f6dc9357SAndroid Build Coastguard Worker             {
1255*f6dc9357SAndroid Build Coastguard Worker               ::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP);
1256*f6dc9357SAndroid Build Coastguard Worker               return 0;
1257*f6dc9357SAndroid Build Coastguard Worker             }
1258*f6dc9357SAndroid Build Coastguard Worker           }
1259*f6dc9357SAndroid Build Coastguard Worker           needCheckTimestamp = false;
1260*f6dc9357SAndroid Build Coastguard Worker           break;
1261*f6dc9357SAndroid Build Coastguard Worker         }
1262*f6dc9357SAndroid Build Coastguard Worker       }
1263*f6dc9357SAndroid Build Coastguard Worker 
1264*f6dc9357SAndroid Build Coastguard Worker       if (!isComplexMode)
1265*f6dc9357SAndroid Build Coastguard Worker         break;
1266*f6dc9357SAndroid Build Coastguard Worker     }
1267*f6dc9357SAndroid Build Coastguard Worker 
1268*f6dc9357SAndroid Build Coastguard Worker     // DEBUG_PRINT("WaitForSingleObject");
1269*f6dc9357SAndroid Build Coastguard Worker     DWORD waitResult = ::WaitForSingleObject(g_ExitEventLauncher._exitEvent, INFINITE);
1270*f6dc9357SAndroid Build Coastguard Worker     // DEBUG_PRINT("---");
1271*f6dc9357SAndroid Build Coastguard Worker 
1272*f6dc9357SAndroid Build Coastguard Worker     if (waitResult == WAIT_OBJECT_0)
1273*f6dc9357SAndroid Build Coastguard Worker       break;
1274*f6dc9357SAndroid Build Coastguard Worker 
1275*f6dc9357SAndroid Build Coastguard Worker     return 1;
1276*f6dc9357SAndroid Build Coastguard Worker   }
1277*f6dc9357SAndroid Build Coastguard Worker 
1278*f6dc9357SAndroid Build Coastguard Worker   {
1279*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo newFileInfo;
1280*f6dc9357SAndroid Build Coastguard Worker     const bool finded = newFileInfo.Find(tpi->FilePath);
1281*f6dc9357SAndroid Build Coastguard Worker     if (!needCheckTimestamp
1282*f6dc9357SAndroid Build Coastguard Worker         || !finded
1283*f6dc9357SAndroid Build Coastguard Worker         || !tpi->WasChanged_from_TempFileInfo(newFileInfo))
1284*f6dc9357SAndroid Build Coastguard Worker     {
1285*f6dc9357SAndroid Build Coastguard Worker       DEBUG_PRINT("Delete Temp file");
1286*f6dc9357SAndroid Build Coastguard Worker       tpi->DeleteDirAndFile();
1287*f6dc9357SAndroid Build Coastguard Worker     }
1288*f6dc9357SAndroid Build Coastguard Worker   }
1289*f6dc9357SAndroid Build Coastguard Worker 
1290*f6dc9357SAndroid Build Coastguard Worker   return 0;
1291*f6dc9357SAndroid Build Coastguard Worker }
1292*f6dc9357SAndroid Build Coastguard Worker 
1293*f6dc9357SAndroid Build Coastguard Worker 
1294*f6dc9357SAndroid Build Coastguard Worker /*
1295*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
1296*f6dc9357SAndroid Build Coastguard Worker static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
1297*f6dc9357SAndroid Build Coastguard Worker #endif
1298*f6dc9357SAndroid Build Coastguard Worker 
1299*f6dc9357SAndroid Build Coastguard Worker 
1300*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
1301*f6dc9357SAndroid Build Coastguard Worker 
1302*f6dc9357SAndroid Build Coastguard Worker static void ReadZoneFile(CFSTR fileName, CByteBuffer &buf)
1303*f6dc9357SAndroid Build Coastguard Worker {
1304*f6dc9357SAndroid Build Coastguard Worker   buf.Free();
1305*f6dc9357SAndroid Build Coastguard Worker   NIO::CInFile file;
1306*f6dc9357SAndroid Build Coastguard Worker   if (!file.Open(fileName))
1307*f6dc9357SAndroid Build Coastguard Worker     return;
1308*f6dc9357SAndroid Build Coastguard Worker   UInt64 fileSize;
1309*f6dc9357SAndroid Build Coastguard Worker   if (!file.GetLength(fileSize))
1310*f6dc9357SAndroid Build Coastguard Worker     return;
1311*f6dc9357SAndroid Build Coastguard Worker   if (fileSize == 0 || fileSize >= ((UInt32)1 << 20))
1312*f6dc9357SAndroid Build Coastguard Worker     return;
1313*f6dc9357SAndroid Build Coastguard Worker   buf.Alloc((size_t)fileSize);
1314*f6dc9357SAndroid Build Coastguard Worker   size_t processed;
1315*f6dc9357SAndroid Build Coastguard Worker   if (file.ReadFull(buf, (size_t)fileSize, processed) && processed == fileSize)
1316*f6dc9357SAndroid Build Coastguard Worker     return;
1317*f6dc9357SAndroid Build Coastguard Worker   buf.Free();
1318*f6dc9357SAndroid Build Coastguard Worker }
1319*f6dc9357SAndroid Build Coastguard Worker 
1320*f6dc9357SAndroid Build Coastguard Worker static bool WriteZoneFile(CFSTR fileName, const CByteBuffer &buf)
1321*f6dc9357SAndroid Build Coastguard Worker {
1322*f6dc9357SAndroid Build Coastguard Worker   NIO::COutFile file;
1323*f6dc9357SAndroid Build Coastguard Worker   if (!file.Create(fileName, true))
1324*f6dc9357SAndroid Build Coastguard Worker     return false;
1325*f6dc9357SAndroid Build Coastguard Worker   UInt32 processed;
1326*f6dc9357SAndroid Build Coastguard Worker   if (!file.Write(buf, (UInt32)buf.Size(), processed))
1327*f6dc9357SAndroid Build Coastguard Worker     return false;
1328*f6dc9357SAndroid Build Coastguard Worker   return processed == buf.Size();
1329*f6dc9357SAndroid Build Coastguard Worker }
1330*f6dc9357SAndroid Build Coastguard Worker 
1331*f6dc9357SAndroid Build Coastguard Worker #endif
1332*f6dc9357SAndroid Build Coastguard Worker */
1333*f6dc9357SAndroid Build Coastguard Worker 
1334*f6dc9357SAndroid Build Coastguard Worker /*
1335*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
1336*f6dc9357SAndroid Build Coastguard Worker   CBufSeqOutStream_WithFile
1337*f6dc9357SAndroid Build Coastguard Worker   , ISequentialOutStream
1338*f6dc9357SAndroid Build Coastguard Worker )
1339*f6dc9357SAndroid Build Coastguard Worker   Byte *_buffer;
1340*f6dc9357SAndroid Build Coastguard Worker   size_t _size;
1341*f6dc9357SAndroid Build Coastguard Worker   size_t _pos;
1342*f6dc9357SAndroid Build Coastguard Worker 
1343*f6dc9357SAndroid Build Coastguard Worker   size_t _fileWritePos;
1344*f6dc9357SAndroid Build Coastguard Worker   bool fileMode;
1345*f6dc9357SAndroid Build Coastguard Worker public:
1346*f6dc9357SAndroid Build Coastguard Worker 
1347*f6dc9357SAndroid Build Coastguard Worker   bool IsStreamInMem() const { return !fileMode; }
1348*f6dc9357SAndroid Build Coastguard Worker   size_t GetMemStreamWrittenSize() const { return _pos; }
1349*f6dc9357SAndroid Build Coastguard Worker 
1350*f6dc9357SAndroid Build Coastguard Worker   // ISequentialOutStream *FileStream;
1351*f6dc9357SAndroid Build Coastguard Worker   FString FilePath;
1352*f6dc9357SAndroid Build Coastguard Worker   COutFileStream *outFileStreamSpec;
1353*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> outFileStream;
1354*f6dc9357SAndroid Build Coastguard Worker 
1355*f6dc9357SAndroid Build Coastguard Worker   CBufSeqOutStream_WithFile(): outFileStreamSpec(NULL) {}
1356*f6dc9357SAndroid Build Coastguard Worker 
1357*f6dc9357SAndroid Build Coastguard Worker   void Init(Byte *buffer, size_t size)
1358*f6dc9357SAndroid Build Coastguard Worker   {
1359*f6dc9357SAndroid Build Coastguard Worker     fileMode = false;
1360*f6dc9357SAndroid Build Coastguard Worker     _buffer = buffer;
1361*f6dc9357SAndroid Build Coastguard Worker     _pos = 0;
1362*f6dc9357SAndroid Build Coastguard Worker     _size = size;
1363*f6dc9357SAndroid Build Coastguard Worker     _fileWritePos = 0;
1364*f6dc9357SAndroid Build Coastguard Worker   }
1365*f6dc9357SAndroid Build Coastguard Worker 
1366*f6dc9357SAndroid Build Coastguard Worker   HRESULT FlushToFile();
1367*f6dc9357SAndroid Build Coastguard Worker   size_t GetPos() const { return _pos; }
1368*f6dc9357SAndroid Build Coastguard Worker };
1369*f6dc9357SAndroid Build Coastguard Worker 
1370*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kBlockSize = ((UInt32)1 << 31);
1371*f6dc9357SAndroid Build Coastguard Worker 
1372*f6dc9357SAndroid Build Coastguard Worker STDMETHODIMP CBufSeqOutStream_WithFile::Write(const void *data, UInt32 size, UInt32 *processedSize)
1373*f6dc9357SAndroid Build Coastguard Worker {
1374*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
1375*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
1376*f6dc9357SAndroid Build Coastguard Worker   if (!fileMode)
1377*f6dc9357SAndroid Build Coastguard Worker   {
1378*f6dc9357SAndroid Build Coastguard Worker     if (_size - _pos >= size)
1379*f6dc9357SAndroid Build Coastguard Worker     {
1380*f6dc9357SAndroid Build Coastguard Worker       if (size != 0)
1381*f6dc9357SAndroid Build Coastguard Worker       {
1382*f6dc9357SAndroid Build Coastguard Worker         memcpy(_buffer + _pos, data, size);
1383*f6dc9357SAndroid Build Coastguard Worker         _pos += size;
1384*f6dc9357SAndroid Build Coastguard Worker       }
1385*f6dc9357SAndroid Build Coastguard Worker       if (processedSize)
1386*f6dc9357SAndroid Build Coastguard Worker         *processedSize = (UInt32)size;
1387*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1388*f6dc9357SAndroid Build Coastguard Worker     }
1389*f6dc9357SAndroid Build Coastguard Worker 
1390*f6dc9357SAndroid Build Coastguard Worker     fileMode = true;
1391*f6dc9357SAndroid Build Coastguard Worker   }
1392*f6dc9357SAndroid Build Coastguard Worker   RINOK(FlushToFile());
1393*f6dc9357SAndroid Build Coastguard Worker   return outFileStream->Write(data, size, processedSize);
1394*f6dc9357SAndroid Build Coastguard Worker }
1395*f6dc9357SAndroid Build Coastguard Worker 
1396*f6dc9357SAndroid Build Coastguard Worker HRESULT CBufSeqOutStream_WithFile::FlushToFile()
1397*f6dc9357SAndroid Build Coastguard Worker {
1398*f6dc9357SAndroid Build Coastguard Worker   if (!outFileStream)
1399*f6dc9357SAndroid Build Coastguard Worker   {
1400*f6dc9357SAndroid Build Coastguard Worker     outFileStreamSpec = new COutFileStream;
1401*f6dc9357SAndroid Build Coastguard Worker     outFileStream = outFileStreamSpec;
1402*f6dc9357SAndroid Build Coastguard Worker     if (!outFileStreamSpec->Create(FilePath, false))
1403*f6dc9357SAndroid Build Coastguard Worker     {
1404*f6dc9357SAndroid Build Coastguard Worker       outFileStream.Release();
1405*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
1406*f6dc9357SAndroid Build Coastguard Worker       // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath));
1407*f6dc9357SAndroid Build Coastguard Worker     }
1408*f6dc9357SAndroid Build Coastguard Worker   }
1409*f6dc9357SAndroid Build Coastguard Worker   while (_fileWritePos != _pos)
1410*f6dc9357SAndroid Build Coastguard Worker   {
1411*f6dc9357SAndroid Build Coastguard Worker     size_t cur = _pos - _fileWritePos;
1412*f6dc9357SAndroid Build Coastguard Worker     UInt32 curSize = (cur < kBlockSize) ? (UInt32)cur : kBlockSize;
1413*f6dc9357SAndroid Build Coastguard Worker     UInt32 processedSizeLoc = 0;
1414*f6dc9357SAndroid Build Coastguard Worker     HRESULT res = outFileStream->Write(_buffer + _fileWritePos, curSize, &processedSizeLoc);
1415*f6dc9357SAndroid Build Coastguard Worker     _fileWritePos += processedSizeLoc;
1416*f6dc9357SAndroid Build Coastguard Worker     RINOK(res);
1417*f6dc9357SAndroid Build Coastguard Worker     if (processedSizeLoc == 0)
1418*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
1419*f6dc9357SAndroid Build Coastguard Worker   }
1420*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1421*f6dc9357SAndroid Build Coastguard Worker }
1422*f6dc9357SAndroid Build Coastguard Worker */
1423*f6dc9357SAndroid Build Coastguard Worker 
1424*f6dc9357SAndroid Build Coastguard Worker /*
1425*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetTime(IFolderFolder *folder, UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
1426*f6dc9357SAndroid Build Coastguard Worker {
1427*f6dc9357SAndroid Build Coastguard Worker   filetimeIsDefined = false;
1428*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
1429*f6dc9357SAndroid Build Coastguard Worker   RINOK(folder->GetProperty(index, propID, &prop));
1430*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_FILETIME)
1431*f6dc9357SAndroid Build Coastguard Worker   {
1432*f6dc9357SAndroid Build Coastguard Worker     filetime = prop.filetime;
1433*f6dc9357SAndroid Build Coastguard Worker     filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0);
1434*f6dc9357SAndroid Build Coastguard Worker   }
1435*f6dc9357SAndroid Build Coastguard Worker   else if (prop.vt != VT_EMPTY)
1436*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
1437*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1438*f6dc9357SAndroid Build Coastguard Worker }
1439*f6dc9357SAndroid Build Coastguard Worker */
1440*f6dc9357SAndroid Build Coastguard Worker 
1441*f6dc9357SAndroid Build Coastguard Worker 
1442*f6dc9357SAndroid Build Coastguard Worker /*
1443*f6dc9357SAndroid Build Coastguard Worker tryInternal tryExternal
1444*f6dc9357SAndroid Build Coastguard Worker   false       false      : unused
1445*f6dc9357SAndroid Build Coastguard Worker   false       true       : external
1446*f6dc9357SAndroid Build Coastguard Worker   true        false      : internal
1447*f6dc9357SAndroid Build Coastguard Worker   true        true       : smart based on file extension:
1448*f6dc9357SAndroid Build Coastguard Worker                       !alwaysStart(name) : both
1449*f6dc9357SAndroid Build Coastguard Worker                       alwaysStart(name)  : external
1450*f6dc9357SAndroid Build Coastguard Worker */
1451*f6dc9357SAndroid Build Coastguard Worker 
OpenItemInArchive(unsigned index,bool tryInternal,bool tryExternal,bool editMode,bool useEditor,const wchar_t * type)1452*f6dc9357SAndroid Build Coastguard Worker void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExternal, bool editMode, bool useEditor, const wchar_t *type)
1453*f6dc9357SAndroid Build Coastguard Worker {
1454*f6dc9357SAndroid Build Coastguard Worker   // we don't want to change hash data here
1455*f6dc9357SAndroid Build Coastguard Worker   if (IsHashFolder())
1456*f6dc9357SAndroid Build Coastguard Worker     return;
1457*f6dc9357SAndroid Build Coastguard Worker 
1458*f6dc9357SAndroid Build Coastguard Worker   const UString name = GetItemName(index);
1459*f6dc9357SAndroid Build Coastguard Worker   const UString relPath = GetItemRelPath(index);
1460*f6dc9357SAndroid Build Coastguard Worker 
1461*f6dc9357SAndroid Build Coastguard Worker   if (tryExternal)
1462*f6dc9357SAndroid Build Coastguard Worker     if (IsVirus_Message(name))
1463*f6dc9357SAndroid Build Coastguard Worker       return;
1464*f6dc9357SAndroid Build Coastguard Worker 
1465*f6dc9357SAndroid Build Coastguard Worker   if (!_folderOperations)
1466*f6dc9357SAndroid Build Coastguard Worker   {
1467*f6dc9357SAndroid Build Coastguard Worker     MessageBox_Error_UnsupportOperation();
1468*f6dc9357SAndroid Build Coastguard Worker     return;
1469*f6dc9357SAndroid Build Coastguard Worker   }
1470*f6dc9357SAndroid Build Coastguard Worker 
1471*f6dc9357SAndroid Build Coastguard Worker   bool tryAsArchive = tryInternal && (!tryExternal || !DoItemAlwaysStart(name));
1472*f6dc9357SAndroid Build Coastguard Worker 
1473*f6dc9357SAndroid Build Coastguard Worker   const UString fullVirtPath = _currentFolderPrefix + relPath;
1474*f6dc9357SAndroid Build Coastguard Worker 
1475*f6dc9357SAndroid Build Coastguard Worker   CTempDir tempDirectory;
1476*f6dc9357SAndroid Build Coastguard Worker   if (!tempDirectory.Create(kTempDirPrefix))
1477*f6dc9357SAndroid Build Coastguard Worker   {
1478*f6dc9357SAndroid Build Coastguard Worker     MessageBox_LastError();
1479*f6dc9357SAndroid Build Coastguard Worker     return;
1480*f6dc9357SAndroid Build Coastguard Worker   }
1481*f6dc9357SAndroid Build Coastguard Worker 
1482*f6dc9357SAndroid Build Coastguard Worker   FString tempDir = tempDirectory.GetPath();
1483*f6dc9357SAndroid Build Coastguard Worker   FString tempDirNorm = tempDir;
1484*f6dc9357SAndroid Build Coastguard Worker   NName::NormalizeDirPathPrefix(tempDirNorm);
1485*f6dc9357SAndroid Build Coastguard Worker   const FString tempFilePath = tempDirNorm + us2fs(Get_Correct_FsFile_Name(name));
1486*f6dc9357SAndroid Build Coastguard Worker 
1487*f6dc9357SAndroid Build Coastguard Worker   CTempFileInfo tempFileInfo;
1488*f6dc9357SAndroid Build Coastguard Worker   tempFileInfo.FileIndex = index;
1489*f6dc9357SAndroid Build Coastguard Worker   tempFileInfo.RelPath = relPath;
1490*f6dc9357SAndroid Build Coastguard Worker   tempFileInfo.FolderPath = tempDir;
1491*f6dc9357SAndroid Build Coastguard Worker   tempFileInfo.FilePath = tempFilePath;
1492*f6dc9357SAndroid Build Coastguard Worker   tempFileInfo.NeedDelete = true;
1493*f6dc9357SAndroid Build Coastguard Worker 
1494*f6dc9357SAndroid Build Coastguard Worker   if (tryAsArchive)
1495*f6dc9357SAndroid Build Coastguard Worker   {
1496*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IInArchiveGetStream> getStream;
1497*f6dc9357SAndroid Build Coastguard Worker     _folder.QueryInterface(IID_IInArchiveGetStream, &getStream);
1498*f6dc9357SAndroid Build Coastguard Worker     if (getStream)
1499*f6dc9357SAndroid Build Coastguard Worker     {
1500*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISequentialInStream> subSeqStream;
1501*f6dc9357SAndroid Build Coastguard Worker       getStream->GetStream(index, &subSeqStream);
1502*f6dc9357SAndroid Build Coastguard Worker       if (subSeqStream)
1503*f6dc9357SAndroid Build Coastguard Worker       {
1504*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr<IInStream> subStream;
1505*f6dc9357SAndroid Build Coastguard Worker         subSeqStream.QueryInterface(IID_IInStream, &subStream);
1506*f6dc9357SAndroid Build Coastguard Worker         if (subStream)
1507*f6dc9357SAndroid Build Coastguard Worker         {
1508*f6dc9357SAndroid Build Coastguard Worker           HRESULT res = OpenAsArc_Msg(subStream, tempFileInfo, fullVirtPath, type ? type : L""
1509*f6dc9357SAndroid Build Coastguard Worker               // , true // showErrorMessage
1510*f6dc9357SAndroid Build Coastguard Worker               );
1511*f6dc9357SAndroid Build Coastguard Worker           if (res == S_OK)
1512*f6dc9357SAndroid Build Coastguard Worker           {
1513*f6dc9357SAndroid Build Coastguard Worker             tempDirectory.DisableDeleting();
1514*f6dc9357SAndroid Build Coastguard Worker             RefreshListCtrl();
1515*f6dc9357SAndroid Build Coastguard Worker             return;
1516*f6dc9357SAndroid Build Coastguard Worker           }
1517*f6dc9357SAndroid Build Coastguard Worker           if (res == E_ABORT || res != S_FALSE)
1518*f6dc9357SAndroid Build Coastguard Worker             return;
1519*f6dc9357SAndroid Build Coastguard Worker           if (!tryExternal)
1520*f6dc9357SAndroid Build Coastguard Worker             return;
1521*f6dc9357SAndroid Build Coastguard Worker           tryAsArchive = false;
1522*f6dc9357SAndroid Build Coastguard Worker         }
1523*f6dc9357SAndroid Build Coastguard Worker       }
1524*f6dc9357SAndroid Build Coastguard Worker     }
1525*f6dc9357SAndroid Build Coastguard Worker   }
1526*f6dc9357SAndroid Build Coastguard Worker 
1527*f6dc9357SAndroid Build Coastguard Worker 
1528*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<UInt32> indices;
1529*f6dc9357SAndroid Build Coastguard Worker   indices.Add(index);
1530*f6dc9357SAndroid Build Coastguard Worker 
1531*f6dc9357SAndroid Build Coastguard Worker   UStringVector messages;
1532*f6dc9357SAndroid Build Coastguard Worker 
1533*f6dc9357SAndroid Build Coastguard Worker   bool usePassword = false;
1534*f6dc9357SAndroid Build Coastguard Worker   UString password;
1535*f6dc9357SAndroid Build Coastguard Worker   if (!_parentFolders.IsEmpty())
1536*f6dc9357SAndroid Build Coastguard Worker   {
1537*f6dc9357SAndroid Build Coastguard Worker     const CFolderLink &fl = _parentFolders.Back();
1538*f6dc9357SAndroid Build Coastguard Worker     usePassword = fl.UsePassword;
1539*f6dc9357SAndroid Build Coastguard Worker     password = fl.Password;
1540*f6dc9357SAndroid Build Coastguard Worker   }
1541*f6dc9357SAndroid Build Coastguard Worker 
1542*f6dc9357SAndroid Build Coastguard Worker   /*
1543*f6dc9357SAndroid Build Coastguard Worker   #if defined(_WIN32) && !defined(UNDER_CE)
1544*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer zoneBuf;
1545*f6dc9357SAndroid Build Coastguard Worker   #ifndef _UNICODE
1546*f6dc9357SAndroid Build Coastguard Worker   if (g_IsNT)
1547*f6dc9357SAndroid Build Coastguard Worker   #endif
1548*f6dc9357SAndroid Build Coastguard Worker   if (!_parentFolders.IsEmpty())
1549*f6dc9357SAndroid Build Coastguard Worker   {
1550*f6dc9357SAndroid Build Coastguard Worker     const CFolderLink &fl = _parentFolders.Front();
1551*f6dc9357SAndroid Build Coastguard Worker     if (!fl.IsVirtual && !fl.FilePath.IsEmpty())
1552*f6dc9357SAndroid Build Coastguard Worker       ReadZoneFile(fl.FilePath + k_ZoneId_StreamName, zoneBuf);
1553*f6dc9357SAndroid Build Coastguard Worker   }
1554*f6dc9357SAndroid Build Coastguard Worker   #endif
1555*f6dc9357SAndroid Build Coastguard Worker   */
1556*f6dc9357SAndroid Build Coastguard Worker 
1557*f6dc9357SAndroid Build Coastguard Worker 
1558*f6dc9357SAndroid Build Coastguard Worker   CVirtFileSystem *virtFileSystemSpec = NULL;
1559*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> virtFileSystem;
1560*f6dc9357SAndroid Build Coastguard Worker 
1561*f6dc9357SAndroid Build Coastguard Worker   const bool isAltStream = IsItem_AltStream(index);
1562*f6dc9357SAndroid Build Coastguard Worker 
1563*f6dc9357SAndroid Build Coastguard Worker   CCopyToOptions options;
1564*f6dc9357SAndroid Build Coastguard Worker   options.includeAltStreams = true;
1565*f6dc9357SAndroid Build Coastguard Worker   options.replaceAltStreamChars = isAltStream;
1566*f6dc9357SAndroid Build Coastguard Worker   {
1567*f6dc9357SAndroid Build Coastguard Worker     // CContextMenuInfo ci;
1568*f6dc9357SAndroid Build Coastguard Worker     // ci.Load();
1569*f6dc9357SAndroid Build Coastguard Worker     // if (ci.WriteZone != (UInt32)(Int32)-1)
1570*f6dc9357SAndroid Build Coastguard Worker     // we use kAll when we unpack just one file.
1571*f6dc9357SAndroid Build Coastguard Worker     options.ZoneIdMode = NExtract::NZoneIdMode::kAll;
1572*f6dc9357SAndroid Build Coastguard Worker     options.NeedRegistryZone = false;
1573*f6dc9357SAndroid Build Coastguard Worker   }
1574*f6dc9357SAndroid Build Coastguard Worker 
1575*f6dc9357SAndroid Build Coastguard Worker   if (tryAsArchive)
1576*f6dc9357SAndroid Build Coastguard Worker   {
1577*f6dc9357SAndroid Build Coastguard Worker     // actually we want to get sum: size of main file plus sizes of altStreams.
1578*f6dc9357SAndroid Build Coastguard Worker     // but now there is no interface to get altStreams sizes.
1579*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
1580*f6dc9357SAndroid Build Coastguard Worker     _folder->GetProperty(index, kpidSize, &prop);
1581*f6dc9357SAndroid Build Coastguard Worker     const size_t fileLimit = g_RAM_Size_Defined ?
1582*f6dc9357SAndroid Build Coastguard Worker         g_RAM_Size >> MyMax(_parentFolders.Size() + 1, 8u):
1583*f6dc9357SAndroid Build Coastguard Worker         1u << 22;
1584*f6dc9357SAndroid Build Coastguard Worker     UInt64 fileSize = 0;
1585*f6dc9357SAndroid Build Coastguard Worker     if (!ConvertPropVariantToUInt64(prop, fileSize))
1586*f6dc9357SAndroid Build Coastguard Worker       fileSize = fileLimit;
1587*f6dc9357SAndroid Build Coastguard Worker #if 0  // 1 : for debug
1588*f6dc9357SAndroid Build Coastguard Worker     fileLimit = 1;
1589*f6dc9357SAndroid Build Coastguard Worker #endif
1590*f6dc9357SAndroid Build Coastguard Worker 
1591*f6dc9357SAndroid Build Coastguard Worker     if (fileSize <= fileLimit)
1592*f6dc9357SAndroid Build Coastguard Worker     {
1593*f6dc9357SAndroid Build Coastguard Worker       options.streamMode = true;
1594*f6dc9357SAndroid Build Coastguard Worker       virtFileSystemSpec = new CVirtFileSystem;
1595*f6dc9357SAndroid Build Coastguard Worker       virtFileSystem = virtFileSystemSpec;
1596*f6dc9357SAndroid Build Coastguard Worker       virtFileSystemSpec->FileName = name;
1597*f6dc9357SAndroid Build Coastguard Worker       virtFileSystemSpec->IsAltStreamFile = isAltStream;
1598*f6dc9357SAndroid Build Coastguard Worker 
1599*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
1600*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
1601*f6dc9357SAndroid Build Coastguard Worker       if (g_IsNT)
1602*f6dc9357SAndroid Build Coastguard Worker #endif
1603*f6dc9357SAndroid Build Coastguard Worker       {
1604*f6dc9357SAndroid Build Coastguard Worker         Get_ZoneId_Stream_from_ParentFolders(virtFileSystemSpec->ZoneBuf);
1605*f6dc9357SAndroid Build Coastguard Worker         options.ZoneBuf = virtFileSystemSpec->ZoneBuf;
1606*f6dc9357SAndroid Build Coastguard Worker       }
1607*f6dc9357SAndroid Build Coastguard Worker #endif
1608*f6dc9357SAndroid Build Coastguard Worker 
1609*f6dc9357SAndroid Build Coastguard Worker       virtFileSystemSpec->MaxTotalAllocSize = (size_t)fileSize
1610*f6dc9357SAndroid Build Coastguard Worker             + (1 << 16); // we allow additional total size for small alt streams.
1611*f6dc9357SAndroid Build Coastguard Worker       virtFileSystemSpec->DirPrefix = tempDirNorm;
1612*f6dc9357SAndroid Build Coastguard Worker       // options.VirtFileSystem = virtFileSystem;
1613*f6dc9357SAndroid Build Coastguard Worker       options.VirtFileSystemSpec = virtFileSystemSpec;
1614*f6dc9357SAndroid Build Coastguard Worker     }
1615*f6dc9357SAndroid Build Coastguard Worker   }
1616*f6dc9357SAndroid Build Coastguard Worker 
1617*f6dc9357SAndroid Build Coastguard Worker   options.folder = fs2us(tempDirNorm);
1618*f6dc9357SAndroid Build Coastguard Worker   options.showErrorMessages = true;
1619*f6dc9357SAndroid Build Coastguard Worker 
1620*f6dc9357SAndroid Build Coastguard Worker   const HRESULT result = CopyTo(options, indices, &messages, usePassword, password);
1621*f6dc9357SAndroid Build Coastguard Worker 
1622*f6dc9357SAndroid Build Coastguard Worker   if (!_parentFolders.IsEmpty())
1623*f6dc9357SAndroid Build Coastguard Worker   {
1624*f6dc9357SAndroid Build Coastguard Worker     CFolderLink &fl = _parentFolders.Back();
1625*f6dc9357SAndroid Build Coastguard Worker     fl.UsePassword = usePassword;
1626*f6dc9357SAndroid Build Coastguard Worker     fl.Password = password;
1627*f6dc9357SAndroid Build Coastguard Worker   }
1628*f6dc9357SAndroid Build Coastguard Worker 
1629*f6dc9357SAndroid Build Coastguard Worker   if (!messages.IsEmpty())
1630*f6dc9357SAndroid Build Coastguard Worker     return;
1631*f6dc9357SAndroid Build Coastguard Worker   if (result != S_OK)
1632*f6dc9357SAndroid Build Coastguard Worker   {
1633*f6dc9357SAndroid Build Coastguard Worker     if (result != E_ABORT)
1634*f6dc9357SAndroid Build Coastguard Worker       MessageBox_Error_HRESULT(result);
1635*f6dc9357SAndroid Build Coastguard Worker     return;
1636*f6dc9357SAndroid Build Coastguard Worker   }
1637*f6dc9357SAndroid Build Coastguard Worker 
1638*f6dc9357SAndroid Build Coastguard Worker   if (virtFileSystemSpec && !virtFileSystemSpec->WasStreamFlushedToFS())
1639*f6dc9357SAndroid Build Coastguard Worker   {
1640*f6dc9357SAndroid Build Coastguard Worker     int index_in_Files = virtFileSystemSpec->Index_of_MainExtractedFile_in_Files;
1641*f6dc9357SAndroid Build Coastguard Worker     if (index_in_Files < 0)
1642*f6dc9357SAndroid Build Coastguard Worker     {
1643*f6dc9357SAndroid Build Coastguard Worker       if (virtFileSystemSpec->Files.Size() != 1)
1644*f6dc9357SAndroid Build Coastguard Worker       {
1645*f6dc9357SAndroid Build Coastguard Worker         MessageBox_Error_HRESULT(E_FAIL);
1646*f6dc9357SAndroid Build Coastguard Worker         return;
1647*f6dc9357SAndroid Build Coastguard Worker       }
1648*f6dc9357SAndroid Build Coastguard Worker       // it's not expected case that index was not set, but we support that case
1649*f6dc9357SAndroid Build Coastguard Worker       index_in_Files = 0;
1650*f6dc9357SAndroid Build Coastguard Worker     }
1651*f6dc9357SAndroid Build Coastguard Worker     {
1652*f6dc9357SAndroid Build Coastguard Worker       const CVirtFile &file = virtFileSystemSpec->Files[index_in_Files];
1653*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr2_Create<IInStream, CBufInStream> bufInStream;
1654*f6dc9357SAndroid Build Coastguard Worker       bufInStream->Init(file.Data, file.WrittenSize, virtFileSystem);
1655*f6dc9357SAndroid Build Coastguard Worker       const HRESULT res = OpenAsArc_Msg(bufInStream, tempFileInfo,
1656*f6dc9357SAndroid Build Coastguard Worker           fullVirtPath, type ? type : L""
1657*f6dc9357SAndroid Build Coastguard Worker           // , encrypted
1658*f6dc9357SAndroid Build Coastguard Worker           // , true // showErrorMessage
1659*f6dc9357SAndroid Build Coastguard Worker           );
1660*f6dc9357SAndroid Build Coastguard Worker       if (res == S_OK)
1661*f6dc9357SAndroid Build Coastguard Worker       {
1662*f6dc9357SAndroid Build Coastguard Worker         if (virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files >= 0
1663*f6dc9357SAndroid Build Coastguard Worker             && !_parentFolders.IsEmpty())
1664*f6dc9357SAndroid Build Coastguard Worker         {
1665*f6dc9357SAndroid Build Coastguard Worker           const CVirtFile &fileZone = virtFileSystemSpec->Files[
1666*f6dc9357SAndroid Build Coastguard Worker               virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files];
1667*f6dc9357SAndroid Build Coastguard Worker           _parentFolders.Back().ZoneBuf.CopyFrom(fileZone.Data, fileZone.WrittenSize);
1668*f6dc9357SAndroid Build Coastguard Worker         }
1669*f6dc9357SAndroid Build Coastguard Worker 
1670*f6dc9357SAndroid Build Coastguard Worker         tempDirectory.DisableDeleting();
1671*f6dc9357SAndroid Build Coastguard Worker         RefreshListCtrl();
1672*f6dc9357SAndroid Build Coastguard Worker         return;
1673*f6dc9357SAndroid Build Coastguard Worker       }
1674*f6dc9357SAndroid Build Coastguard Worker       if (res == E_ABORT || res != S_FALSE)
1675*f6dc9357SAndroid Build Coastguard Worker         return;
1676*f6dc9357SAndroid Build Coastguard Worker       if (!tryExternal)
1677*f6dc9357SAndroid Build Coastguard Worker         return;
1678*f6dc9357SAndroid Build Coastguard Worker       tryAsArchive = false;
1679*f6dc9357SAndroid Build Coastguard Worker       if (virtFileSystemSpec->FlushToDisk(true) != S_OK)
1680*f6dc9357SAndroid Build Coastguard Worker         return;
1681*f6dc9357SAndroid Build Coastguard Worker     }
1682*f6dc9357SAndroid Build Coastguard Worker   }
1683*f6dc9357SAndroid Build Coastguard Worker 
1684*f6dc9357SAndroid Build Coastguard Worker 
1685*f6dc9357SAndroid Build Coastguard Worker   /*
1686*f6dc9357SAndroid Build Coastguard Worker   #if defined(_WIN32) && !defined(UNDER_CE)
1687*f6dc9357SAndroid Build Coastguard Worker   if (zoneBuf.Size() != 0)
1688*f6dc9357SAndroid Build Coastguard Worker   {
1689*f6dc9357SAndroid Build Coastguard Worker     if (NFind::DoesFileExist_Raw(tempFilePath))
1690*f6dc9357SAndroid Build Coastguard Worker     {
1691*f6dc9357SAndroid Build Coastguard Worker       WriteZoneFile(tempFilePath + k_ZoneId_StreamName, zoneBuf);
1692*f6dc9357SAndroid Build Coastguard Worker     }
1693*f6dc9357SAndroid Build Coastguard Worker   }
1694*f6dc9357SAndroid Build Coastguard Worker   #endif
1695*f6dc9357SAndroid Build Coastguard Worker   */
1696*f6dc9357SAndroid Build Coastguard Worker 
1697*f6dc9357SAndroid Build Coastguard Worker 
1698*f6dc9357SAndroid Build Coastguard Worker   if (tryAsArchive)
1699*f6dc9357SAndroid Build Coastguard Worker   {
1700*f6dc9357SAndroid Build Coastguard Worker     const HRESULT res = OpenAsArc_Msg(NULL, tempFileInfo, fullVirtPath, type ? type : L""
1701*f6dc9357SAndroid Build Coastguard Worker         // , encrypted
1702*f6dc9357SAndroid Build Coastguard Worker         // , true // showErrorMessage
1703*f6dc9357SAndroid Build Coastguard Worker         );
1704*f6dc9357SAndroid Build Coastguard Worker     if (res == S_OK)
1705*f6dc9357SAndroid Build Coastguard Worker     {
1706*f6dc9357SAndroid Build Coastguard Worker       tempDirectory.DisableDeleting();
1707*f6dc9357SAndroid Build Coastguard Worker       RefreshListCtrl();
1708*f6dc9357SAndroid Build Coastguard Worker       return;
1709*f6dc9357SAndroid Build Coastguard Worker     }
1710*f6dc9357SAndroid Build Coastguard Worker     if (res == E_ABORT || res != S_FALSE)
1711*f6dc9357SAndroid Build Coastguard Worker       return;
1712*f6dc9357SAndroid Build Coastguard Worker   }
1713*f6dc9357SAndroid Build Coastguard Worker 
1714*f6dc9357SAndroid Build Coastguard Worker   if (!tryExternal)
1715*f6dc9357SAndroid Build Coastguard Worker     return;
1716*f6dc9357SAndroid Build Coastguard Worker 
1717*f6dc9357SAndroid Build Coastguard Worker   CMyUniquePtr<CTmpProcessInfo> tpi(new CTmpProcessInfo());
1718*f6dc9357SAndroid Build Coastguard Worker   tpi->FolderPath = tempDir;
1719*f6dc9357SAndroid Build Coastguard Worker   tpi->FilePath = tempFilePath;
1720*f6dc9357SAndroid Build Coastguard Worker   tpi->NeedDelete = true;
1721*f6dc9357SAndroid Build Coastguard Worker   tpi->UsePassword = usePassword;
1722*f6dc9357SAndroid Build Coastguard Worker   tpi->Password = password;
1723*f6dc9357SAndroid Build Coastguard Worker   tpi->ReadOnly = IsThereReadOnlyFolder();
1724*f6dc9357SAndroid Build Coastguard Worker   if (IsHashFolder())
1725*f6dc9357SAndroid Build Coastguard Worker     tpi->ReadOnly = true;
1726*f6dc9357SAndroid Build Coastguard Worker 
1727*f6dc9357SAndroid Build Coastguard Worker   if (!tpi->FileInfo.Find(tempFilePath))
1728*f6dc9357SAndroid Build Coastguard Worker     return;
1729*f6dc9357SAndroid Build Coastguard Worker 
1730*f6dc9357SAndroid Build Coastguard Worker   CTmpProcessInfoRelease tmpProcessInfoRelease(*tpi);
1731*f6dc9357SAndroid Build Coastguard Worker 
1732*f6dc9357SAndroid Build Coastguard Worker   CProcess process;
1733*f6dc9357SAndroid Build Coastguard Worker   HRESULT res;
1734*f6dc9357SAndroid Build Coastguard Worker   if (editMode)
1735*f6dc9357SAndroid Build Coastguard Worker     res = StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process);
1736*f6dc9357SAndroid Build Coastguard Worker   else
1737*f6dc9357SAndroid Build Coastguard Worker     res = StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
1738*f6dc9357SAndroid Build Coastguard Worker 
1739*f6dc9357SAndroid Build Coastguard Worker   if ((HANDLE)process == NULL)
1740*f6dc9357SAndroid Build Coastguard Worker   {
1741*f6dc9357SAndroid Build Coastguard Worker     // win7 / win10 work so for some extensions (pdf, html ..);
1742*f6dc9357SAndroid Build Coastguard Worker     DEBUG_PRINT("#### (HANDLE)process == 0");
1743*f6dc9357SAndroid Build Coastguard Worker     // return;
1744*f6dc9357SAndroid Build Coastguard Worker     if (res != S_OK)
1745*f6dc9357SAndroid Build Coastguard Worker       return;
1746*f6dc9357SAndroid Build Coastguard Worker   }
1747*f6dc9357SAndroid Build Coastguard Worker 
1748*f6dc9357SAndroid Build Coastguard Worker   tpi->Window = (HWND)*this;
1749*f6dc9357SAndroid Build Coastguard Worker   tpi->FullPathFolderPrefix = _currentFolderPrefix;
1750*f6dc9357SAndroid Build Coastguard Worker   tpi->FileIndex = index;
1751*f6dc9357SAndroid Build Coastguard Worker   tpi->RelPath = relPath;
1752*f6dc9357SAndroid Build Coastguard Worker 
1753*f6dc9357SAndroid Build Coastguard Worker   if ((HANDLE)process)
1754*f6dc9357SAndroid Build Coastguard Worker     tpi->Processes.SetMainProcess(process.Detach());
1755*f6dc9357SAndroid Build Coastguard Worker 
1756*f6dc9357SAndroid Build Coastguard Worker   ::CThread th;
1757*f6dc9357SAndroid Build Coastguard Worker   if (Thread_Create(&th, MyThreadFunction, tpi.get()) != 0)
1758*f6dc9357SAndroid Build Coastguard Worker     throw 271824;
1759*f6dc9357SAndroid Build Coastguard Worker   g_ExitEventLauncher._threads.Add(th);
1760*f6dc9357SAndroid Build Coastguard Worker   g_ExitEventLauncher._numActiveThreads++;
1761*f6dc9357SAndroid Build Coastguard Worker 
1762*f6dc9357SAndroid Build Coastguard Worker   tempDirectory.DisableDeleting();
1763*f6dc9357SAndroid Build Coastguard Worker   tpi.release();
1764*f6dc9357SAndroid Build Coastguard Worker   tmpProcessInfoRelease._needDelete = false;
1765*f6dc9357SAndroid Build Coastguard Worker }
1766*f6dc9357SAndroid Build Coastguard Worker 
1767*f6dc9357SAndroid Build Coastguard Worker 
1768*f6dc9357SAndroid Build Coastguard Worker /*
1769*f6dc9357SAndroid Build Coastguard Worker static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24;
1770*f6dc9357SAndroid Build Coastguard Worker 
1771*f6dc9357SAndroid Build Coastguard Worker static bool CheckDeleteItem(UINT64 currentFileTime, UINT64 folderFileTime)
1772*f6dc9357SAndroid Build Coastguard Worker {
1773*f6dc9357SAndroid Build Coastguard Worker   return (currentFileTime - folderFileTime > kTimeLimit &&
1774*f6dc9357SAndroid Build Coastguard Worker       folderFileTime - currentFileTime > kTimeLimit);
1775*f6dc9357SAndroid Build Coastguard Worker }
1776*f6dc9357SAndroid Build Coastguard Worker 
1777*f6dc9357SAndroid Build Coastguard Worker void DeleteOldTempFiles()
1778*f6dc9357SAndroid Build Coastguard Worker {
1779*f6dc9357SAndroid Build Coastguard Worker   UString tempPath;
1780*f6dc9357SAndroid Build Coastguard Worker   if (!MyGetTempPath(tempPath))
1781*f6dc9357SAndroid Build Coastguard Worker     throw 1;
1782*f6dc9357SAndroid Build Coastguard Worker 
1783*f6dc9357SAndroid Build Coastguard Worker   UINT64 currentFileTime;
1784*f6dc9357SAndroid Build Coastguard Worker   NTime::GetCurUtcFileTime(currentFileTime);
1785*f6dc9357SAndroid Build Coastguard Worker   UString searchWildCard = tempPath + kTempDirPrefix + L"*.tmp";
1786*f6dc9357SAndroid Build Coastguard Worker   searchWildCard += WCHAR(NName::kAnyStringWildcard);
1787*f6dc9357SAndroid Build Coastguard Worker   NFind::CEnumeratorW enumerator(searchWildCard);
1788*f6dc9357SAndroid Build Coastguard Worker   NFind::CFileInfo fileInfo;
1789*f6dc9357SAndroid Build Coastguard Worker   while (enumerator.Next(fileInfo))
1790*f6dc9357SAndroid Build Coastguard Worker   {
1791*f6dc9357SAndroid Build Coastguard Worker     if (!fileInfo.IsDir())
1792*f6dc9357SAndroid Build Coastguard Worker       continue;
1793*f6dc9357SAndroid Build Coastguard Worker     const UINT64 &cTime = *(const UINT64 *)(&fileInfo.CTime);
1794*f6dc9357SAndroid Build Coastguard Worker     if (CheckDeleteItem(cTime, currentFileTime))
1795*f6dc9357SAndroid Build Coastguard Worker       RemoveDirectoryWithSubItems(tempPath + fileInfo.Name);
1796*f6dc9357SAndroid Build Coastguard Worker   }
1797*f6dc9357SAndroid Build Coastguard Worker }
1798*f6dc9357SAndroid Build Coastguard Worker */
1799