xref: /aosp_15_r20/external/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // ExtractCallbackSfx.h
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/Wildcard.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileFind.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "ExtractCallbackSfx.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
15*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
16*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker static LPCSTR const kCantDeleteFile = "Cannot delete output file";
19*f6dc9357SAndroid Build Coastguard Worker static LPCSTR const kCantOpenFile = "Cannot open output file";
20*f6dc9357SAndroid Build Coastguard Worker static LPCSTR const kUnsupportedMethod = "Unsupported Method";
21*f6dc9357SAndroid Build Coastguard Worker 
Init(IInArchive * archiveHandler,const FString & directoryPath,const UString & itemDefaultName,const FILETIME & defaultMTime,UInt32 defaultAttributes)22*f6dc9357SAndroid Build Coastguard Worker void CExtractCallbackImp::Init(IInArchive *archiveHandler,
23*f6dc9357SAndroid Build Coastguard Worker     const FString &directoryPath,
24*f6dc9357SAndroid Build Coastguard Worker     const UString &itemDefaultName,
25*f6dc9357SAndroid Build Coastguard Worker     const FILETIME &defaultMTime,
26*f6dc9357SAndroid Build Coastguard Worker     UInt32 defaultAttributes)
27*f6dc9357SAndroid Build Coastguard Worker {
28*f6dc9357SAndroid Build Coastguard Worker   _message.Empty();
29*f6dc9357SAndroid Build Coastguard Worker   _isCorrupt = false;
30*f6dc9357SAndroid Build Coastguard Worker   _itemDefaultName = itemDefaultName;
31*f6dc9357SAndroid Build Coastguard Worker   _defaultMTime = defaultMTime;
32*f6dc9357SAndroid Build Coastguard Worker   _defaultAttributes = defaultAttributes;
33*f6dc9357SAndroid Build Coastguard Worker   _archiveHandler = archiveHandler;
34*f6dc9357SAndroid Build Coastguard Worker   _directoryPath = directoryPath;
35*f6dc9357SAndroid Build Coastguard Worker   NName::NormalizeDirPathPrefix(_directoryPath);
36*f6dc9357SAndroid Build Coastguard Worker }
37*f6dc9357SAndroid Build Coastguard Worker 
Open_CheckBreak()38*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_CheckBreak()
39*f6dc9357SAndroid Build Coastguard Worker {
40*f6dc9357SAndroid Build Coastguard Worker   #ifndef _NO_PROGRESS
41*f6dc9357SAndroid Build Coastguard Worker   return ProgressDialog.Sync.ProcessStopAndPause();
42*f6dc9357SAndroid Build Coastguard Worker   #else
43*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
44*f6dc9357SAndroid Build Coastguard Worker   #endif
45*f6dc9357SAndroid Build Coastguard Worker }
46*f6dc9357SAndroid Build Coastguard Worker 
Open_SetTotal(const UInt64 *,const UInt64 *)47*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
48*f6dc9357SAndroid Build Coastguard Worker {
49*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
50*f6dc9357SAndroid Build Coastguard Worker }
51*f6dc9357SAndroid Build Coastguard Worker 
Open_SetCompleted(const UInt64 *,const UInt64 *)52*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
53*f6dc9357SAndroid Build Coastguard Worker {
54*f6dc9357SAndroid Build Coastguard Worker   #ifndef _NO_PROGRESS
55*f6dc9357SAndroid Build Coastguard Worker   return ProgressDialog.Sync.ProcessStopAndPause();
56*f6dc9357SAndroid Build Coastguard Worker   #else
57*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
58*f6dc9357SAndroid Build Coastguard Worker   #endif
59*f6dc9357SAndroid Build Coastguard Worker }
60*f6dc9357SAndroid Build Coastguard Worker 
Open_Finished()61*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_Finished()
62*f6dc9357SAndroid Build Coastguard Worker {
63*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
64*f6dc9357SAndroid Build Coastguard Worker }
65*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetTotal (UInt64 size))66*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size))
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker   #ifndef _NO_PROGRESS
69*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog.Sync.SetProgress(size, 0);
70*f6dc9357SAndroid Build Coastguard Worker   #endif
71*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
72*f6dc9357SAndroid Build Coastguard Worker }
73*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted (const UInt64 * completeValue))74*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue))
75*f6dc9357SAndroid Build Coastguard Worker {
76*f6dc9357SAndroid Build Coastguard Worker   #ifndef _NO_PROGRESS
77*f6dc9357SAndroid Build Coastguard Worker   RINOK(ProgressDialog.Sync.ProcessStopAndPause())
78*f6dc9357SAndroid Build Coastguard Worker   if (completeValue != NULL)
79*f6dc9357SAndroid Build Coastguard Worker     ProgressDialog.Sync.SetPos(*completeValue);
80*f6dc9357SAndroid Build Coastguard Worker   #endif
81*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
82*f6dc9357SAndroid Build Coastguard Worker }
83*f6dc9357SAndroid Build Coastguard Worker 
CreateComplexDirectory(const UStringVector & dirPathParts)84*f6dc9357SAndroid Build Coastguard Worker void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
85*f6dc9357SAndroid Build Coastguard Worker {
86*f6dc9357SAndroid Build Coastguard Worker   FString fullPath = _directoryPath;
87*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, dirPathParts)
88*f6dc9357SAndroid Build Coastguard Worker   {
89*f6dc9357SAndroid Build Coastguard Worker     fullPath += us2fs(dirPathParts[i]);
90*f6dc9357SAndroid Build Coastguard Worker     CreateDir(fullPath);
91*f6dc9357SAndroid Build Coastguard Worker     fullPath.Add_PathSepar();
92*f6dc9357SAndroid Build Coastguard Worker   }
93*f6dc9357SAndroid Build Coastguard Worker }
94*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::GetStream (UInt32 index,ISequentialOutStream ** outStream,Int32 askExtractMode))95*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::GetStream(UInt32 index,
96*f6dc9357SAndroid Build Coastguard Worker     ISequentialOutStream **outStream, Int32 askExtractMode))
97*f6dc9357SAndroid Build Coastguard Worker {
98*f6dc9357SAndroid Build Coastguard Worker   #ifndef _NO_PROGRESS
99*f6dc9357SAndroid Build Coastguard Worker   if (ProgressDialog.Sync.GetStopped())
100*f6dc9357SAndroid Build Coastguard Worker     return E_ABORT;
101*f6dc9357SAndroid Build Coastguard Worker   #endif
102*f6dc9357SAndroid Build Coastguard Worker   _outFileStream.Release();
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker   UString fullPath;
105*f6dc9357SAndroid Build Coastguard Worker   {
106*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
107*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop))
108*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_EMPTY)
109*f6dc9357SAndroid Build Coastguard Worker       fullPath = _itemDefaultName;
110*f6dc9357SAndroid Build Coastguard Worker     else
111*f6dc9357SAndroid Build Coastguard Worker     {
112*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_BSTR)
113*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
114*f6dc9357SAndroid Build Coastguard Worker       fullPath.SetFromBstr(prop.bstrVal);
115*f6dc9357SAndroid Build Coastguard Worker     }
116*f6dc9357SAndroid Build Coastguard Worker     _filePath = fullPath;
117*f6dc9357SAndroid Build Coastguard Worker   }
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker   if (askExtractMode == NArchive::NExtract::NAskMode::kExtract)
120*f6dc9357SAndroid Build Coastguard Worker   {
121*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
122*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop))
123*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_EMPTY)
124*f6dc9357SAndroid Build Coastguard Worker       _processedFileInfo.Attributes = _defaultAttributes;
125*f6dc9357SAndroid Build Coastguard Worker     else
126*f6dc9357SAndroid Build Coastguard Worker     {
127*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI4)
128*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
129*f6dc9357SAndroid Build Coastguard Worker       _processedFileInfo.Attributes = prop.ulVal;
130*f6dc9357SAndroid Build Coastguard Worker     }
131*f6dc9357SAndroid Build Coastguard Worker 
132*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop))
133*f6dc9357SAndroid Build Coastguard Worker     _processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal);
134*f6dc9357SAndroid Build Coastguard Worker 
135*f6dc9357SAndroid Build Coastguard Worker     bool isAnti = false;
136*f6dc9357SAndroid Build Coastguard Worker     {
137*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant propTemp;
138*f6dc9357SAndroid Build Coastguard Worker       RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp))
139*f6dc9357SAndroid Build Coastguard Worker       if (propTemp.vt == VT_BOOL)
140*f6dc9357SAndroid Build Coastguard Worker         isAnti = VARIANT_BOOLToBool(propTemp.boolVal);
141*f6dc9357SAndroid Build Coastguard Worker     }
142*f6dc9357SAndroid Build Coastguard Worker 
143*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop))
144*f6dc9357SAndroid Build Coastguard Worker     switch (prop.vt)
145*f6dc9357SAndroid Build Coastguard Worker     {
146*f6dc9357SAndroid Build Coastguard Worker       case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break;
147*f6dc9357SAndroid Build Coastguard Worker       case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break;
148*f6dc9357SAndroid Build Coastguard Worker       default: return E_FAIL;
149*f6dc9357SAndroid Build Coastguard Worker     }
150*f6dc9357SAndroid Build Coastguard Worker 
151*f6dc9357SAndroid Build Coastguard Worker     UStringVector pathParts;
152*f6dc9357SAndroid Build Coastguard Worker     SplitPathToParts(fullPath, pathParts);
153*f6dc9357SAndroid Build Coastguard Worker     if (pathParts.IsEmpty())
154*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker     UString processedPath = fullPath;
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker     if (!_processedFileInfo.IsDir)
159*f6dc9357SAndroid Build Coastguard Worker       pathParts.DeleteBack();
160*f6dc9357SAndroid Build Coastguard Worker     if (!pathParts.IsEmpty())
161*f6dc9357SAndroid Build Coastguard Worker     {
162*f6dc9357SAndroid Build Coastguard Worker       if (!isAnti)
163*f6dc9357SAndroid Build Coastguard Worker         CreateComplexDirectory(pathParts);
164*f6dc9357SAndroid Build Coastguard Worker     }
165*f6dc9357SAndroid Build Coastguard Worker 
166*f6dc9357SAndroid Build Coastguard Worker     FString fullProcessedPath = _directoryPath + us2fs(processedPath);
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker     if (_processedFileInfo.IsDir)
169*f6dc9357SAndroid Build Coastguard Worker     {
170*f6dc9357SAndroid Build Coastguard Worker       _diskFilePath = fullProcessedPath;
171*f6dc9357SAndroid Build Coastguard Worker 
172*f6dc9357SAndroid Build Coastguard Worker       if (isAnti)
173*f6dc9357SAndroid Build Coastguard Worker         RemoveDir(_diskFilePath);
174*f6dc9357SAndroid Build Coastguard Worker       else
175*f6dc9357SAndroid Build Coastguard Worker         SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime);
176*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
177*f6dc9357SAndroid Build Coastguard Worker     }
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo fileInfo;
180*f6dc9357SAndroid Build Coastguard Worker     if (fileInfo.Find(fullProcessedPath))
181*f6dc9357SAndroid Build Coastguard Worker     {
182*f6dc9357SAndroid Build Coastguard Worker       if (!DeleteFileAlways(fullProcessedPath))
183*f6dc9357SAndroid Build Coastguard Worker       {
184*f6dc9357SAndroid Build Coastguard Worker         _message = kCantDeleteFile;
185*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
186*f6dc9357SAndroid Build Coastguard Worker       }
187*f6dc9357SAndroid Build Coastguard Worker     }
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker     if (!isAnti)
190*f6dc9357SAndroid Build Coastguard Worker     {
191*f6dc9357SAndroid Build Coastguard Worker       _outFileStreamSpec = new COutFileStream;
192*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
193*f6dc9357SAndroid Build Coastguard Worker       if (!_outFileStreamSpec->Create_ALWAYS(fullProcessedPath))
194*f6dc9357SAndroid Build Coastguard Worker       {
195*f6dc9357SAndroid Build Coastguard Worker         _message = kCantOpenFile;
196*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
197*f6dc9357SAndroid Build Coastguard Worker       }
198*f6dc9357SAndroid Build Coastguard Worker       _outFileStream = outStreamLoc;
199*f6dc9357SAndroid Build Coastguard Worker       *outStream = outStreamLoc.Detach();
200*f6dc9357SAndroid Build Coastguard Worker     }
201*f6dc9357SAndroid Build Coastguard Worker     _diskFilePath = fullProcessedPath;
202*f6dc9357SAndroid Build Coastguard Worker   }
203*f6dc9357SAndroid Build Coastguard Worker   else
204*f6dc9357SAndroid Build Coastguard Worker   {
205*f6dc9357SAndroid Build Coastguard Worker     *outStream = NULL;
206*f6dc9357SAndroid Build Coastguard Worker   }
207*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
208*f6dc9357SAndroid Build Coastguard Worker }
209*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation (Int32 askExtractMode))210*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(Int32 askExtractMode))
211*f6dc9357SAndroid Build Coastguard Worker {
212*f6dc9357SAndroid Build Coastguard Worker   _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract);
213*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
214*f6dc9357SAndroid Build Coastguard Worker }
215*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult (Int32 resultEOperationResult))216*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult))
217*f6dc9357SAndroid Build Coastguard Worker {
218*f6dc9357SAndroid Build Coastguard Worker   switch (resultEOperationResult)
219*f6dc9357SAndroid Build Coastguard Worker   {
220*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kOK:
221*f6dc9357SAndroid Build Coastguard Worker       break;
222*f6dc9357SAndroid Build Coastguard Worker 
223*f6dc9357SAndroid Build Coastguard Worker     default:
224*f6dc9357SAndroid Build Coastguard Worker     {
225*f6dc9357SAndroid Build Coastguard Worker       _outFileStream.Release();
226*f6dc9357SAndroid Build Coastguard Worker       switch (resultEOperationResult)
227*f6dc9357SAndroid Build Coastguard Worker       {
228*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
229*f6dc9357SAndroid Build Coastguard Worker           _message = kUnsupportedMethod;
230*f6dc9357SAndroid Build Coastguard Worker           break;
231*f6dc9357SAndroid Build Coastguard Worker         default:
232*f6dc9357SAndroid Build Coastguard Worker           _isCorrupt = true;
233*f6dc9357SAndroid Build Coastguard Worker       }
234*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
235*f6dc9357SAndroid Build Coastguard Worker     }
236*f6dc9357SAndroid Build Coastguard Worker   }
237*f6dc9357SAndroid Build Coastguard Worker   if (_outFileStream != NULL)
238*f6dc9357SAndroid Build Coastguard Worker   {
239*f6dc9357SAndroid Build Coastguard Worker     _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
240*f6dc9357SAndroid Build Coastguard Worker     RINOK(_outFileStreamSpec->Close())
241*f6dc9357SAndroid Build Coastguard Worker   }
242*f6dc9357SAndroid Build Coastguard Worker   _outFileStream.Release();
243*f6dc9357SAndroid Build Coastguard Worker   if (_extractMode)
244*f6dc9357SAndroid Build Coastguard Worker     SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes);
245*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
246*f6dc9357SAndroid Build Coastguard Worker }
247