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