1*f6dc9357SAndroid Build Coastguard Worker // ArchiveExtractCallback.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #undef sprintf
6*f6dc9357SAndroid Build Coastguard Worker #undef printf
7*f6dc9357SAndroid Build Coastguard Worker
8*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
9*f6dc9357SAndroid Build Coastguard Worker // #include "../../../../C/CpuTicks.h"
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/Alloc.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
13*f6dc9357SAndroid Build Coastguard Worker
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
17*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/UTFConvert.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
20*f6dc9357SAndroid Build Coastguard Worker
21*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/ErrorMsg.h"
22*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
23*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileFind.h"
24*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
25*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
26*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantConv.h"
27*f6dc9357SAndroid Build Coastguard Worker
28*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
29*f6dc9357SAndroid Build Coastguard Worker #define Z7_USE_SECURITY_CODE
30*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/SecurityUtils.h"
31*f6dc9357SAndroid Build Coastguard Worker #endif
32*f6dc9357SAndroid Build Coastguard Worker
33*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FilePathAutoRename.h"
34*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
35*f6dc9357SAndroid Build Coastguard Worker
36*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ExtractingFilePath.h"
37*f6dc9357SAndroid Build Coastguard Worker #include "../Common/PropIDUtils.h"
38*f6dc9357SAndroid Build Coastguard Worker
39*f6dc9357SAndroid Build Coastguard Worker #include "ArchiveExtractCallback.h"
40*f6dc9357SAndroid Build Coastguard Worker
41*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
42*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
43*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
44*f6dc9357SAndroid Build Coastguard Worker
45*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantAutoRename = "Cannot create file with auto name";
46*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantRenameFile = "Cannot rename existing file";
47*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantDeleteOutputFile = "Cannot delete output file";
48*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantDeleteOutputDir = "Cannot delete output folder";
49*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantOpenOutFile = "Cannot open output file";
50*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
51*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantOpenInFile = "Cannot open input file";
52*f6dc9357SAndroid Build Coastguard Worker #endif
53*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantSetFileLen = "Cannot set length for output file";
54*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
55*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantCreateHardLink = "Cannot create hard link";
56*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantCreateSymLink = "Cannot create symbolic link";
57*f6dc9357SAndroid Build Coastguard Worker #endif
58*f6dc9357SAndroid Build Coastguard Worker
59*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
60*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(COutStreamWithHash::Write (const void * data,UInt32 size,UInt32 * processedSize))61*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize))
62*f6dc9357SAndroid Build Coastguard Worker {
63*f6dc9357SAndroid Build Coastguard Worker HRESULT result = S_OK;
64*f6dc9357SAndroid Build Coastguard Worker if (_stream)
65*f6dc9357SAndroid Build Coastguard Worker result = _stream->Write(data, size, &size);
66*f6dc9357SAndroid Build Coastguard Worker if (_calculate)
67*f6dc9357SAndroid Build Coastguard Worker _hash->Update(data, size);
68*f6dc9357SAndroid Build Coastguard Worker _size += size;
69*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
70*f6dc9357SAndroid Build Coastguard Worker *processedSize = size;
71*f6dc9357SAndroid Build Coastguard Worker return result;
72*f6dc9357SAndroid Build Coastguard Worker }
73*f6dc9357SAndroid Build Coastguard Worker
74*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
75*f6dc9357SAndroid Build Coastguard Worker
76*f6dc9357SAndroid Build Coastguard Worker
77*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_SECURITY_CODE
78*f6dc9357SAndroid Build Coastguard Worker bool InitLocalPrivileges();
InitLocalPrivileges()79*f6dc9357SAndroid Build Coastguard Worker bool InitLocalPrivileges()
80*f6dc9357SAndroid Build Coastguard Worker {
81*f6dc9357SAndroid Build Coastguard Worker NSecurity::CAccessToken token;
82*f6dc9357SAndroid Build Coastguard Worker if (!token.OpenProcessToken(GetCurrentProcess(),
83*f6dc9357SAndroid Build Coastguard Worker TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES))
84*f6dc9357SAndroid Build Coastguard Worker return false;
85*f6dc9357SAndroid Build Coastguard Worker
86*f6dc9357SAndroid Build Coastguard Worker TOKEN_PRIVILEGES tp;
87*f6dc9357SAndroid Build Coastguard Worker
88*f6dc9357SAndroid Build Coastguard Worker tp.PrivilegeCount = 1;
89*f6dc9357SAndroid Build Coastguard Worker tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
90*f6dc9357SAndroid Build Coastguard Worker
91*f6dc9357SAndroid Build Coastguard Worker if (!::LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid))
92*f6dc9357SAndroid Build Coastguard Worker return false;
93*f6dc9357SAndroid Build Coastguard Worker if (!token.AdjustPrivileges(&tp))
94*f6dc9357SAndroid Build Coastguard Worker return false;
95*f6dc9357SAndroid Build Coastguard Worker return (GetLastError() == ERROR_SUCCESS);
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_USE_SECURITY_CODE
98*f6dc9357SAndroid Build Coastguard Worker
99*f6dc9357SAndroid Build Coastguard Worker
100*f6dc9357SAndroid Build Coastguard Worker
101*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
102*f6dc9357SAndroid Build Coastguard Worker
103*f6dc9357SAndroid Build Coastguard Worker static const char * const kOfficeExtensions =
104*f6dc9357SAndroid Build Coastguard Worker " doc dot wbk"
105*f6dc9357SAndroid Build Coastguard Worker " docx docm dotx dotm docb wll wwl"
106*f6dc9357SAndroid Build Coastguard Worker " xls xlt xlm"
107*f6dc9357SAndroid Build Coastguard Worker " xlsx xlsm xltx xltm xlsb xla xlam"
108*f6dc9357SAndroid Build Coastguard Worker " ppt pot pps ppa ppam"
109*f6dc9357SAndroid Build Coastguard Worker " pptx pptm potx potm ppam ppsx ppsm sldx sldm"
110*f6dc9357SAndroid Build Coastguard Worker " ";
111*f6dc9357SAndroid Build Coastguard Worker
FindExt2(const char * p,const UString & name)112*f6dc9357SAndroid Build Coastguard Worker static bool FindExt2(const char *p, const UString &name)
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker const int pathPos = name.ReverseFind_PathSepar();
115*f6dc9357SAndroid Build Coastguard Worker const int dotPos = name.ReverseFind_Dot();
116*f6dc9357SAndroid Build Coastguard Worker if (dotPos < 0
117*f6dc9357SAndroid Build Coastguard Worker || dotPos < pathPos
118*f6dc9357SAndroid Build Coastguard Worker || dotPos == (int)name.Len() - 1)
119*f6dc9357SAndroid Build Coastguard Worker return false;
120*f6dc9357SAndroid Build Coastguard Worker
121*f6dc9357SAndroid Build Coastguard Worker AString s;
122*f6dc9357SAndroid Build Coastguard Worker for (unsigned pos = (unsigned)(dotPos + 1);; pos++)
123*f6dc9357SAndroid Build Coastguard Worker {
124*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = name[pos];
125*f6dc9357SAndroid Build Coastguard Worker if (c <= 0)
126*f6dc9357SAndroid Build Coastguard Worker break;
127*f6dc9357SAndroid Build Coastguard Worker if (c >= 0x80)
128*f6dc9357SAndroid Build Coastguard Worker return false;
129*f6dc9357SAndroid Build Coastguard Worker s.Add_Char((char)MyCharLower_Ascii((char)c));
130*f6dc9357SAndroid Build Coastguard Worker }
131*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; p[i] != 0;)
132*f6dc9357SAndroid Build Coastguard Worker {
133*f6dc9357SAndroid Build Coastguard Worker unsigned j;
134*f6dc9357SAndroid Build Coastguard Worker for (j = i; p[j] != ' '; j++);
135*f6dc9357SAndroid Build Coastguard Worker if (s.Len() == j - i && memcmp(p + i, (const char *)s, s.Len()) == 0)
136*f6dc9357SAndroid Build Coastguard Worker return true;
137*f6dc9357SAndroid Build Coastguard Worker i = j + 1;
138*f6dc9357SAndroid Build Coastguard Worker }
139*f6dc9357SAndroid Build Coastguard Worker return false;
140*f6dc9357SAndroid Build Coastguard Worker }
141*f6dc9357SAndroid Build Coastguard Worker
142*f6dc9357SAndroid Build Coastguard Worker
143*f6dc9357SAndroid Build Coastguard Worker static const char * const k_ZoneId_StreamName_With_Colon_Prefix = ":Zone.Identifier";
144*f6dc9357SAndroid Build Coastguard Worker
Is_ZoneId_StreamName(const wchar_t * s)145*f6dc9357SAndroid Build Coastguard Worker bool Is_ZoneId_StreamName(const wchar_t *s)
146*f6dc9357SAndroid Build Coastguard Worker {
147*f6dc9357SAndroid Build Coastguard Worker return StringsAreEqualNoCase_Ascii(s, k_ZoneId_StreamName_With_Colon_Prefix + 1);
148*f6dc9357SAndroid Build Coastguard Worker }
149*f6dc9357SAndroid Build Coastguard Worker
ReadZoneFile_Of_BaseFile(CFSTR fileName,CByteBuffer & buf)150*f6dc9357SAndroid Build Coastguard Worker void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf)
151*f6dc9357SAndroid Build Coastguard Worker {
152*f6dc9357SAndroid Build Coastguard Worker buf.Free();
153*f6dc9357SAndroid Build Coastguard Worker FString path (fileName);
154*f6dc9357SAndroid Build Coastguard Worker path += k_ZoneId_StreamName_With_Colon_Prefix;
155*f6dc9357SAndroid Build Coastguard Worker NIO::CInFile file;
156*f6dc9357SAndroid Build Coastguard Worker if (!file.Open(path))
157*f6dc9357SAndroid Build Coastguard Worker return;
158*f6dc9357SAndroid Build Coastguard Worker UInt64 fileSize;
159*f6dc9357SAndroid Build Coastguard Worker if (!file.GetLength(fileSize))
160*f6dc9357SAndroid Build Coastguard Worker return;
161*f6dc9357SAndroid Build Coastguard Worker if (fileSize == 0 || fileSize >= (1u << 15))
162*f6dc9357SAndroid Build Coastguard Worker return;
163*f6dc9357SAndroid Build Coastguard Worker buf.Alloc((size_t)fileSize);
164*f6dc9357SAndroid Build Coastguard Worker size_t processed;
165*f6dc9357SAndroid Build Coastguard Worker if (file.ReadFull(buf, (size_t)fileSize, processed) && processed == fileSize)
166*f6dc9357SAndroid Build Coastguard Worker return;
167*f6dc9357SAndroid Build Coastguard Worker buf.Free();
168*f6dc9357SAndroid Build Coastguard Worker }
169*f6dc9357SAndroid Build Coastguard Worker
WriteZoneFile_To_BaseFile(CFSTR fileName,const CByteBuffer & buf)170*f6dc9357SAndroid Build Coastguard Worker bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf)
171*f6dc9357SAndroid Build Coastguard Worker {
172*f6dc9357SAndroid Build Coastguard Worker FString path (fileName);
173*f6dc9357SAndroid Build Coastguard Worker path += k_ZoneId_StreamName_With_Colon_Prefix;
174*f6dc9357SAndroid Build Coastguard Worker NIO::COutFile file;
175*f6dc9357SAndroid Build Coastguard Worker if (!file.Create_ALWAYS(path))
176*f6dc9357SAndroid Build Coastguard Worker return false;
177*f6dc9357SAndroid Build Coastguard Worker return file.WriteFull(buf, buf.Size());
178*f6dc9357SAndroid Build Coastguard Worker }
179*f6dc9357SAndroid Build Coastguard Worker
180*f6dc9357SAndroid Build Coastguard Worker #endif
181*f6dc9357SAndroid Build Coastguard Worker
182*f6dc9357SAndroid Build Coastguard Worker
183*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
184*f6dc9357SAndroid Build Coastguard Worker
Compare(const CHardLinkNode & a) const185*f6dc9357SAndroid Build Coastguard Worker int CHardLinkNode::Compare(const CHardLinkNode &a) const
186*f6dc9357SAndroid Build Coastguard Worker {
187*f6dc9357SAndroid Build Coastguard Worker if (StreamId < a.StreamId) return -1;
188*f6dc9357SAndroid Build Coastguard Worker if (StreamId > a.StreamId) return 1;
189*f6dc9357SAndroid Build Coastguard Worker return MyCompare(INode, a.INode);
190*f6dc9357SAndroid Build Coastguard Worker }
191*f6dc9357SAndroid Build Coastguard Worker
Archive_Get_HardLinkNode(IInArchive * archive,UInt32 index,CHardLinkNode & h,bool & defined)192*f6dc9357SAndroid Build Coastguard Worker static HRESULT Archive_Get_HardLinkNode(IInArchive *archive, UInt32 index, CHardLinkNode &h, bool &defined)
193*f6dc9357SAndroid Build Coastguard Worker {
194*f6dc9357SAndroid Build Coastguard Worker h.INode = 0;
195*f6dc9357SAndroid Build Coastguard Worker h.StreamId = (UInt64)(Int64)-1;
196*f6dc9357SAndroid Build Coastguard Worker defined = false;
197*f6dc9357SAndroid Build Coastguard Worker {
198*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
199*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidINode, &prop))
200*f6dc9357SAndroid Build Coastguard Worker if (!ConvertPropVariantToUInt64(prop, h.INode))
201*f6dc9357SAndroid Build Coastguard Worker return S_OK;
202*f6dc9357SAndroid Build Coastguard Worker }
203*f6dc9357SAndroid Build Coastguard Worker {
204*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
205*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidStreamId, &prop))
206*f6dc9357SAndroid Build Coastguard Worker ConvertPropVariantToUInt64(prop, h.StreamId);
207*f6dc9357SAndroid Build Coastguard Worker }
208*f6dc9357SAndroid Build Coastguard Worker defined = true;
209*f6dc9357SAndroid Build Coastguard Worker return S_OK;
210*f6dc9357SAndroid Build Coastguard Worker }
211*f6dc9357SAndroid Build Coastguard Worker
212*f6dc9357SAndroid Build Coastguard Worker
PrepareHardLinks(const CRecordVector<UInt32> * realIndices)213*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *realIndices)
214*f6dc9357SAndroid Build Coastguard Worker {
215*f6dc9357SAndroid Build Coastguard Worker _hardLinks.Clear();
216*f6dc9357SAndroid Build Coastguard Worker
217*f6dc9357SAndroid Build Coastguard Worker if (!_arc->Ask_INode)
218*f6dc9357SAndroid Build Coastguard Worker return S_OK;
219*f6dc9357SAndroid Build Coastguard Worker
220*f6dc9357SAndroid Build Coastguard Worker IInArchive *archive = _arc->Archive;
221*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CHardLinkNode> &hardIDs = _hardLinks.IDs;
222*f6dc9357SAndroid Build Coastguard Worker
223*f6dc9357SAndroid Build Coastguard Worker {
224*f6dc9357SAndroid Build Coastguard Worker UInt32 numItems;
225*f6dc9357SAndroid Build Coastguard Worker if (realIndices)
226*f6dc9357SAndroid Build Coastguard Worker numItems = realIndices->Size();
227*f6dc9357SAndroid Build Coastguard Worker else
228*f6dc9357SAndroid Build Coastguard Worker {
229*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetNumberOfItems(&numItems))
230*f6dc9357SAndroid Build Coastguard Worker }
231*f6dc9357SAndroid Build Coastguard Worker
232*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numItems; i++)
233*f6dc9357SAndroid Build Coastguard Worker {
234*f6dc9357SAndroid Build Coastguard Worker CHardLinkNode h;
235*f6dc9357SAndroid Build Coastguard Worker bool defined;
236*f6dc9357SAndroid Build Coastguard Worker const UInt32 realIndex = realIndices ? (*realIndices)[i] : i;
237*f6dc9357SAndroid Build Coastguard Worker
238*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined))
239*f6dc9357SAndroid Build Coastguard Worker if (defined)
240*f6dc9357SAndroid Build Coastguard Worker {
241*f6dc9357SAndroid Build Coastguard Worker bool isAltStream = false;
242*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream))
243*f6dc9357SAndroid Build Coastguard Worker if (!isAltStream)
244*f6dc9357SAndroid Build Coastguard Worker {
245*f6dc9357SAndroid Build Coastguard Worker bool isDir = false;
246*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_Dir(archive, realIndex, isDir))
247*f6dc9357SAndroid Build Coastguard Worker if (!isDir)
248*f6dc9357SAndroid Build Coastguard Worker hardIDs.Add(h);
249*f6dc9357SAndroid Build Coastguard Worker }
250*f6dc9357SAndroid Build Coastguard Worker }
251*f6dc9357SAndroid Build Coastguard Worker }
252*f6dc9357SAndroid Build Coastguard Worker }
253*f6dc9357SAndroid Build Coastguard Worker
254*f6dc9357SAndroid Build Coastguard Worker hardIDs.Sort2();
255*f6dc9357SAndroid Build Coastguard Worker
256*f6dc9357SAndroid Build Coastguard Worker {
257*f6dc9357SAndroid Build Coastguard Worker // we keep only items that have 2 or more items
258*f6dc9357SAndroid Build Coastguard Worker unsigned k = 0;
259*f6dc9357SAndroid Build Coastguard Worker unsigned numSame = 1;
260*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 1; i < hardIDs.Size(); i++)
261*f6dc9357SAndroid Build Coastguard Worker {
262*f6dc9357SAndroid Build Coastguard Worker if (hardIDs[i].Compare(hardIDs[i - 1]) != 0)
263*f6dc9357SAndroid Build Coastguard Worker numSame = 1;
264*f6dc9357SAndroid Build Coastguard Worker else if (++numSame == 2)
265*f6dc9357SAndroid Build Coastguard Worker {
266*f6dc9357SAndroid Build Coastguard Worker if (i - 1 != k)
267*f6dc9357SAndroid Build Coastguard Worker hardIDs[k] = hardIDs[i - 1];
268*f6dc9357SAndroid Build Coastguard Worker k++;
269*f6dc9357SAndroid Build Coastguard Worker }
270*f6dc9357SAndroid Build Coastguard Worker }
271*f6dc9357SAndroid Build Coastguard Worker hardIDs.DeleteFrom(k);
272*f6dc9357SAndroid Build Coastguard Worker }
273*f6dc9357SAndroid Build Coastguard Worker
274*f6dc9357SAndroid Build Coastguard Worker _hardLinks.PrepareLinks();
275*f6dc9357SAndroid Build Coastguard Worker return S_OK;
276*f6dc9357SAndroid Build Coastguard Worker }
277*f6dc9357SAndroid Build Coastguard Worker
278*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_LINKS
279*f6dc9357SAndroid Build Coastguard Worker
280*f6dc9357SAndroid Build Coastguard Worker
CArchiveExtractCallback()281*f6dc9357SAndroid Build Coastguard Worker CArchiveExtractCallback::CArchiveExtractCallback():
282*f6dc9357SAndroid Build Coastguard Worker // Write_CTime(true),
283*f6dc9357SAndroid Build Coastguard Worker // Write_ATime(true),
284*f6dc9357SAndroid Build Coastguard Worker // Write_MTime(true),
285*f6dc9357SAndroid Build Coastguard Worker Is_elimPrefix_Mode(false),
286*f6dc9357SAndroid Build Coastguard Worker _arc(NULL),
287*f6dc9357SAndroid Build Coastguard Worker _multiArchives(false)
288*f6dc9357SAndroid Build Coastguard Worker {
289*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_SECURITY_CODE
290*f6dc9357SAndroid Build Coastguard Worker _saclEnabled = InitLocalPrivileges();
291*f6dc9357SAndroid Build Coastguard Worker #endif
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker
294*f6dc9357SAndroid Build Coastguard Worker
InitBeforeNewArchive()295*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::InitBeforeNewArchive()
296*f6dc9357SAndroid Build Coastguard Worker {
297*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
298*f6dc9357SAndroid Build Coastguard Worker ZoneBuf.Free();
299*f6dc9357SAndroid Build Coastguard Worker #endif
300*f6dc9357SAndroid Build Coastguard Worker }
301*f6dc9357SAndroid Build Coastguard Worker
Init(const CExtractNtOptions & ntOptions,const NWildcard::CCensorNode * wildcardCensor,const CArc * arc,IFolderArchiveExtractCallback * extractCallback2,bool stdOutMode,bool testMode,const FString & directoryPath,const UStringVector & removePathParts,bool removePartsForAltStreams,UInt64 packSize)302*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::Init(
303*f6dc9357SAndroid Build Coastguard Worker const CExtractNtOptions &ntOptions,
304*f6dc9357SAndroid Build Coastguard Worker const NWildcard::CCensorNode *wildcardCensor,
305*f6dc9357SAndroid Build Coastguard Worker const CArc *arc,
306*f6dc9357SAndroid Build Coastguard Worker IFolderArchiveExtractCallback *extractCallback2,
307*f6dc9357SAndroid Build Coastguard Worker bool stdOutMode, bool testMode,
308*f6dc9357SAndroid Build Coastguard Worker const FString &directoryPath,
309*f6dc9357SAndroid Build Coastguard Worker const UStringVector &removePathParts, bool removePartsForAltStreams,
310*f6dc9357SAndroid Build Coastguard Worker UInt64 packSize)
311*f6dc9357SAndroid Build Coastguard Worker {
312*f6dc9357SAndroid Build Coastguard Worker ClearExtractedDirsInfo();
313*f6dc9357SAndroid Build Coastguard Worker _outFileStream.Release();
314*f6dc9357SAndroid Build Coastguard Worker _bufPtrSeqOutStream.Release();
315*f6dc9357SAndroid Build Coastguard Worker
316*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
317*f6dc9357SAndroid Build Coastguard Worker _hardLinks.Clear();
318*f6dc9357SAndroid Build Coastguard Worker #endif
319*f6dc9357SAndroid Build Coastguard Worker
320*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
321*f6dc9357SAndroid Build Coastguard Worker _renamedFiles.Clear();
322*f6dc9357SAndroid Build Coastguard Worker #endif
323*f6dc9357SAndroid Build Coastguard Worker
324*f6dc9357SAndroid Build Coastguard Worker _ntOptions = ntOptions;
325*f6dc9357SAndroid Build Coastguard Worker _wildcardCensor = wildcardCensor;
326*f6dc9357SAndroid Build Coastguard Worker _stdOutMode = stdOutMode;
327*f6dc9357SAndroid Build Coastguard Worker _testMode = testMode;
328*f6dc9357SAndroid Build Coastguard Worker _packTotal = packSize;
329*f6dc9357SAndroid Build Coastguard Worker _progressTotal = packSize;
330*f6dc9357SAndroid Build Coastguard Worker // _progressTotal = 0;
331*f6dc9357SAndroid Build Coastguard Worker // _progressTotal_Defined = false;
332*f6dc9357SAndroid Build Coastguard Worker // _progressTotal_Defined = true;
333*f6dc9357SAndroid Build Coastguard Worker _extractCallback2 = extractCallback2;
334*f6dc9357SAndroid Build Coastguard Worker /*
335*f6dc9357SAndroid Build Coastguard Worker _compressProgress.Release();
336*f6dc9357SAndroid Build Coastguard Worker _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
337*f6dc9357SAndroid Build Coastguard Worker _callbackMessage.Release();
338*f6dc9357SAndroid Build Coastguard Worker _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage);
339*f6dc9357SAndroid Build Coastguard Worker */
340*f6dc9357SAndroid Build Coastguard Worker _folderArchiveExtractCallback2.Release();
341*f6dc9357SAndroid Build Coastguard Worker _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2);
342*f6dc9357SAndroid Build Coastguard Worker
343*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
344*f6dc9357SAndroid Build Coastguard Worker
345*f6dc9357SAndroid Build Coastguard Worker ExtractToStreamCallback.Release();
346*f6dc9357SAndroid Build Coastguard Worker _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback);
347*f6dc9357SAndroid Build Coastguard Worker if (ExtractToStreamCallback)
348*f6dc9357SAndroid Build Coastguard Worker {
349*f6dc9357SAndroid Build Coastguard Worker Int32 useStreams = 0;
350*f6dc9357SAndroid Build Coastguard Worker if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK)
351*f6dc9357SAndroid Build Coastguard Worker useStreams = 0;
352*f6dc9357SAndroid Build Coastguard Worker if (useStreams == 0)
353*f6dc9357SAndroid Build Coastguard Worker ExtractToStreamCallback.Release();
354*f6dc9357SAndroid Build Coastguard Worker }
355*f6dc9357SAndroid Build Coastguard Worker
356*f6dc9357SAndroid Build Coastguard Worker #endif
357*f6dc9357SAndroid Build Coastguard Worker
358*f6dc9357SAndroid Build Coastguard Worker LocalProgressSpec->Init(extractCallback2, true);
359*f6dc9357SAndroid Build Coastguard Worker LocalProgressSpec->SendProgress = false;
360*f6dc9357SAndroid Build Coastguard Worker
361*f6dc9357SAndroid Build Coastguard Worker _removePathParts = removePathParts;
362*f6dc9357SAndroid Build Coastguard Worker _removePartsForAltStreams = removePartsForAltStreams;
363*f6dc9357SAndroid Build Coastguard Worker
364*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
365*f6dc9357SAndroid Build Coastguard Worker _baseParentFolder = (UInt32)(Int32)-1;
366*f6dc9357SAndroid Build Coastguard Worker _use_baseParentFolder_mode = false;
367*f6dc9357SAndroid Build Coastguard Worker #endif
368*f6dc9357SAndroid Build Coastguard Worker
369*f6dc9357SAndroid Build Coastguard Worker _arc = arc;
370*f6dc9357SAndroid Build Coastguard Worker _dirPathPrefix = directoryPath;
371*f6dc9357SAndroid Build Coastguard Worker _dirPathPrefix_Full = directoryPath;
372*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
373*f6dc9357SAndroid Build Coastguard Worker if (!NName::IsAltPathPrefix(_dirPathPrefix))
374*f6dc9357SAndroid Build Coastguard Worker #endif
375*f6dc9357SAndroid Build Coastguard Worker {
376*f6dc9357SAndroid Build Coastguard Worker NName::NormalizeDirPathPrefix(_dirPathPrefix);
377*f6dc9357SAndroid Build Coastguard Worker NDir::MyGetFullPathName(directoryPath, _dirPathPrefix_Full);
378*f6dc9357SAndroid Build Coastguard Worker NName::NormalizeDirPathPrefix(_dirPathPrefix_Full);
379*f6dc9357SAndroid Build Coastguard Worker }
380*f6dc9357SAndroid Build Coastguard Worker }
381*f6dc9357SAndroid Build Coastguard Worker
382*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal (UInt64 size))383*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 size))
384*f6dc9357SAndroid Build Coastguard Worker {
385*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
386*f6dc9357SAndroid Build Coastguard Worker _progressTotal = size;
387*f6dc9357SAndroid Build Coastguard Worker // _progressTotal_Defined = true;
388*f6dc9357SAndroid Build Coastguard Worker if (!_multiArchives && _extractCallback2)
389*f6dc9357SAndroid Build Coastguard Worker return _extractCallback2->SetTotal(size);
390*f6dc9357SAndroid Build Coastguard Worker return S_OK;
391*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
392*f6dc9357SAndroid Build Coastguard Worker }
393*f6dc9357SAndroid Build Coastguard Worker
394*f6dc9357SAndroid Build Coastguard Worker
NormalizeVals(UInt64 & v1,UInt64 & v2)395*f6dc9357SAndroid Build Coastguard Worker static void NormalizeVals(UInt64 &v1, UInt64 &v2)
396*f6dc9357SAndroid Build Coastguard Worker {
397*f6dc9357SAndroid Build Coastguard Worker const UInt64 kMax = (UInt64)1 << 31;
398*f6dc9357SAndroid Build Coastguard Worker while (v1 > kMax)
399*f6dc9357SAndroid Build Coastguard Worker {
400*f6dc9357SAndroid Build Coastguard Worker v1 >>= 1;
401*f6dc9357SAndroid Build Coastguard Worker v2 >>= 1;
402*f6dc9357SAndroid Build Coastguard Worker }
403*f6dc9357SAndroid Build Coastguard Worker }
404*f6dc9357SAndroid Build Coastguard Worker
405*f6dc9357SAndroid Build Coastguard Worker
MyMultDiv64(UInt64 unpCur,UInt64 unpTotal,UInt64 packTotal)406*f6dc9357SAndroid Build Coastguard Worker static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal)
407*f6dc9357SAndroid Build Coastguard Worker {
408*f6dc9357SAndroid Build Coastguard Worker NormalizeVals(packTotal, unpTotal);
409*f6dc9357SAndroid Build Coastguard Worker NormalizeVals(unpCur, unpTotal);
410*f6dc9357SAndroid Build Coastguard Worker if (unpTotal == 0)
411*f6dc9357SAndroid Build Coastguard Worker unpTotal = 1;
412*f6dc9357SAndroid Build Coastguard Worker return unpCur * packTotal / unpTotal;
413*f6dc9357SAndroid Build Coastguard Worker }
414*f6dc9357SAndroid Build Coastguard Worker
415*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted (const UInt64 * completeValue))416*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue))
417*f6dc9357SAndroid Build Coastguard Worker {
418*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
419*f6dc9357SAndroid Build Coastguard Worker
420*f6dc9357SAndroid Build Coastguard Worker if (!_extractCallback2)
421*f6dc9357SAndroid Build Coastguard Worker return S_OK;
422*f6dc9357SAndroid Build Coastguard Worker
423*f6dc9357SAndroid Build Coastguard Worker UInt64 packCur;
424*f6dc9357SAndroid Build Coastguard Worker if (_multiArchives)
425*f6dc9357SAndroid Build Coastguard Worker {
426*f6dc9357SAndroid Build Coastguard Worker packCur = LocalProgressSpec->InSize;
427*f6dc9357SAndroid Build Coastguard Worker if (completeValue /* && _progressTotal_Defined */)
428*f6dc9357SAndroid Build Coastguard Worker packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal);
429*f6dc9357SAndroid Build Coastguard Worker completeValue = &packCur;
430*f6dc9357SAndroid Build Coastguard Worker }
431*f6dc9357SAndroid Build Coastguard Worker return _extractCallback2->SetCompleted(completeValue);
432*f6dc9357SAndroid Build Coastguard Worker
433*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
434*f6dc9357SAndroid Build Coastguard Worker }
435*f6dc9357SAndroid Build Coastguard Worker
436*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo (const UInt64 * inSize,const UInt64 * outSize))437*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
438*f6dc9357SAndroid Build Coastguard Worker {
439*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
440*f6dc9357SAndroid Build Coastguard Worker return LocalProgressSpec.Interface()->SetRatioInfo(inSize, outSize);
441*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
442*f6dc9357SAndroid Build Coastguard Worker }
443*f6dc9357SAndroid Build Coastguard Worker
444*f6dc9357SAndroid Build Coastguard Worker
CreateComplexDirectory(const UStringVector & dirPathParts,FString & fullPath)445*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath)
446*f6dc9357SAndroid Build Coastguard Worker {
447*f6dc9357SAndroid Build Coastguard Worker // we use (_item.IsDir) in this function
448*f6dc9357SAndroid Build Coastguard Worker
449*f6dc9357SAndroid Build Coastguard Worker bool isAbsPath = false;
450*f6dc9357SAndroid Build Coastguard Worker
451*f6dc9357SAndroid Build Coastguard Worker if (!dirPathParts.IsEmpty())
452*f6dc9357SAndroid Build Coastguard Worker {
453*f6dc9357SAndroid Build Coastguard Worker const UString &s = dirPathParts[0];
454*f6dc9357SAndroid Build Coastguard Worker if (s.IsEmpty())
455*f6dc9357SAndroid Build Coastguard Worker isAbsPath = true;
456*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
457*f6dc9357SAndroid Build Coastguard Worker else
458*f6dc9357SAndroid Build Coastguard Worker {
459*f6dc9357SAndroid Build Coastguard Worker if (NName::IsDrivePath2(s))
460*f6dc9357SAndroid Build Coastguard Worker isAbsPath = true;
461*f6dc9357SAndroid Build Coastguard Worker }
462*f6dc9357SAndroid Build Coastguard Worker #endif
463*f6dc9357SAndroid Build Coastguard Worker }
464*f6dc9357SAndroid Build Coastguard Worker
465*f6dc9357SAndroid Build Coastguard Worker if (_pathMode == NExtract::NPathMode::kAbsPaths && isAbsPath)
466*f6dc9357SAndroid Build Coastguard Worker fullPath.Empty();
467*f6dc9357SAndroid Build Coastguard Worker else
468*f6dc9357SAndroid Build Coastguard Worker fullPath = _dirPathPrefix;
469*f6dc9357SAndroid Build Coastguard Worker
470*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, dirPathParts)
471*f6dc9357SAndroid Build Coastguard Worker {
472*f6dc9357SAndroid Build Coastguard Worker if (i != 0)
473*f6dc9357SAndroid Build Coastguard Worker fullPath.Add_PathSepar();
474*f6dc9357SAndroid Build Coastguard Worker const UString &s = dirPathParts[i];
475*f6dc9357SAndroid Build Coastguard Worker fullPath += us2fs(s);
476*f6dc9357SAndroid Build Coastguard Worker
477*f6dc9357SAndroid Build Coastguard Worker const bool isFinalDir = (i == dirPathParts.Size() - 1 && _item.IsDir);
478*f6dc9357SAndroid Build Coastguard Worker
479*f6dc9357SAndroid Build Coastguard Worker if (fullPath.IsEmpty())
480*f6dc9357SAndroid Build Coastguard Worker {
481*f6dc9357SAndroid Build Coastguard Worker if (isFinalDir)
482*f6dc9357SAndroid Build Coastguard Worker _itemFailure = true;
483*f6dc9357SAndroid Build Coastguard Worker continue;
484*f6dc9357SAndroid Build Coastguard Worker }
485*f6dc9357SAndroid Build Coastguard Worker
486*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
487*f6dc9357SAndroid Build Coastguard Worker if (_pathMode == NExtract::NPathMode::kAbsPaths)
488*f6dc9357SAndroid Build Coastguard Worker if (i == 0 && s.Len() == 2 && NName::IsDrivePath2(s))
489*f6dc9357SAndroid Build Coastguard Worker {
490*f6dc9357SAndroid Build Coastguard Worker if (isFinalDir)
491*f6dc9357SAndroid Build Coastguard Worker {
492*f6dc9357SAndroid Build Coastguard Worker // we don't want to call SetAttrib() for root drive path
493*f6dc9357SAndroid Build Coastguard Worker _itemFailure = true;
494*f6dc9357SAndroid Build Coastguard Worker }
495*f6dc9357SAndroid Build Coastguard Worker continue;
496*f6dc9357SAndroid Build Coastguard Worker }
497*f6dc9357SAndroid Build Coastguard Worker #endif
498*f6dc9357SAndroid Build Coastguard Worker
499*f6dc9357SAndroid Build Coastguard Worker HRESULT hres = S_OK;
500*f6dc9357SAndroid Build Coastguard Worker if (!CreateDir(fullPath))
501*f6dc9357SAndroid Build Coastguard Worker hres = GetLastError_noZero_HRESULT();
502*f6dc9357SAndroid Build Coastguard Worker if (isFinalDir)
503*f6dc9357SAndroid Build Coastguard Worker {
504*f6dc9357SAndroid Build Coastguard Worker if (!NFile::NFind::DoesDirExist(fullPath))
505*f6dc9357SAndroid Build Coastguard Worker {
506*f6dc9357SAndroid Build Coastguard Worker _itemFailure = true;
507*f6dc9357SAndroid Build Coastguard Worker SendMessageError_with_Error(hres, "Cannot create folder", fullPath);
508*f6dc9357SAndroid Build Coastguard Worker }
509*f6dc9357SAndroid Build Coastguard Worker }
510*f6dc9357SAndroid Build Coastguard Worker }
511*f6dc9357SAndroid Build Coastguard Worker }
512*f6dc9357SAndroid Build Coastguard Worker
513*f6dc9357SAndroid Build Coastguard Worker
GetTime(UInt32 index,PROPID propID,CArcTime & ft)514*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, CArcTime &ft)
515*f6dc9357SAndroid Build Coastguard Worker {
516*f6dc9357SAndroid Build Coastguard Worker ft.Clear();
517*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
518*f6dc9357SAndroid Build Coastguard Worker RINOK(_arc->Archive->GetProperty(index, propID, &prop))
519*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_FILETIME)
520*f6dc9357SAndroid Build Coastguard Worker ft.Set_From_Prop(prop);
521*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
522*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
523*f6dc9357SAndroid Build Coastguard Worker return S_OK;
524*f6dc9357SAndroid Build Coastguard Worker }
525*f6dc9357SAndroid Build Coastguard Worker
526*f6dc9357SAndroid Build Coastguard Worker
GetUnpackSize()527*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::GetUnpackSize()
528*f6dc9357SAndroid Build Coastguard Worker {
529*f6dc9357SAndroid Build Coastguard Worker return _arc->GetItem_Size(_index, _curSize, _curSize_Defined);
530*f6dc9357SAndroid Build Coastguard Worker }
531*f6dc9357SAndroid Build Coastguard Worker
AddPathToMessage(UString & s,const FString & path)532*f6dc9357SAndroid Build Coastguard Worker static void AddPathToMessage(UString &s, const FString &path)
533*f6dc9357SAndroid Build Coastguard Worker {
534*f6dc9357SAndroid Build Coastguard Worker s += " : ";
535*f6dc9357SAndroid Build Coastguard Worker s += fs2us(path);
536*f6dc9357SAndroid Build Coastguard Worker }
537*f6dc9357SAndroid Build Coastguard Worker
SendMessageError(const char * message,const FString & path)538*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path)
539*f6dc9357SAndroid Build Coastguard Worker {
540*f6dc9357SAndroid Build Coastguard Worker UString s (message);
541*f6dc9357SAndroid Build Coastguard Worker AddPathToMessage(s, path);
542*f6dc9357SAndroid Build Coastguard Worker return _extractCallback2->MessageError(s);
543*f6dc9357SAndroid Build Coastguard Worker }
544*f6dc9357SAndroid Build Coastguard Worker
545*f6dc9357SAndroid Build Coastguard Worker
SendMessageError_with_Error(HRESULT errorCode,const char * message,const FString & path)546*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::SendMessageError_with_Error(HRESULT errorCode, const char *message, const FString &path)
547*f6dc9357SAndroid Build Coastguard Worker {
548*f6dc9357SAndroid Build Coastguard Worker UString s (message);
549*f6dc9357SAndroid Build Coastguard Worker if (errorCode != S_OK)
550*f6dc9357SAndroid Build Coastguard Worker {
551*f6dc9357SAndroid Build Coastguard Worker s += " : ";
552*f6dc9357SAndroid Build Coastguard Worker s += NError::MyFormatMessage(errorCode);
553*f6dc9357SAndroid Build Coastguard Worker }
554*f6dc9357SAndroid Build Coastguard Worker AddPathToMessage(s, path);
555*f6dc9357SAndroid Build Coastguard Worker return _extractCallback2->MessageError(s);
556*f6dc9357SAndroid Build Coastguard Worker }
557*f6dc9357SAndroid Build Coastguard Worker
SendMessageError_with_LastError(const char * message,const FString & path)558*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path)
559*f6dc9357SAndroid Build Coastguard Worker {
560*f6dc9357SAndroid Build Coastguard Worker const HRESULT errorCode = GetLastError_noZero_HRESULT();
561*f6dc9357SAndroid Build Coastguard Worker return SendMessageError_with_Error(errorCode, message, path);
562*f6dc9357SAndroid Build Coastguard Worker }
563*f6dc9357SAndroid Build Coastguard Worker
SendMessageError2(HRESULT errorCode,const char * message,const FString & path1,const FString & path2)564*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2)
565*f6dc9357SAndroid Build Coastguard Worker {
566*f6dc9357SAndroid Build Coastguard Worker UString s (message);
567*f6dc9357SAndroid Build Coastguard Worker if (errorCode != 0)
568*f6dc9357SAndroid Build Coastguard Worker {
569*f6dc9357SAndroid Build Coastguard Worker s += " : ";
570*f6dc9357SAndroid Build Coastguard Worker s += NError::MyFormatMessage(errorCode);
571*f6dc9357SAndroid Build Coastguard Worker }
572*f6dc9357SAndroid Build Coastguard Worker AddPathToMessage(s, path1);
573*f6dc9357SAndroid Build Coastguard Worker AddPathToMessage(s, path2);
574*f6dc9357SAndroid Build Coastguard Worker return _extractCallback2->MessageError(s);
575*f6dc9357SAndroid Build Coastguard Worker }
576*f6dc9357SAndroid Build Coastguard Worker
577*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
578*f6dc9357SAndroid Build Coastguard Worker
579*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
580*f6dc9357SAndroid Build Coastguard Worker CGetProp
581*f6dc9357SAndroid Build Coastguard Worker , IGetProp
582*f6dc9357SAndroid Build Coastguard Worker )
583*f6dc9357SAndroid Build Coastguard Worker public:
584*f6dc9357SAndroid Build Coastguard Worker UInt32 IndexInArc;
585*f6dc9357SAndroid Build Coastguard Worker const CArc *Arc;
586*f6dc9357SAndroid Build Coastguard Worker // UString BaseName; // relative path
587*f6dc9357SAndroid Build Coastguard Worker };
588*f6dc9357SAndroid Build Coastguard Worker
589*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value))
590*f6dc9357SAndroid Build Coastguard Worker {
591*f6dc9357SAndroid Build Coastguard Worker /*
592*f6dc9357SAndroid Build Coastguard Worker if (propID == kpidBaseName)
593*f6dc9357SAndroid Build Coastguard Worker {
594*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
595*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop = BaseName;
596*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
597*f6dc9357SAndroid Build Coastguard Worker return S_OK;
598*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
599*f6dc9357SAndroid Build Coastguard Worker }
600*f6dc9357SAndroid Build Coastguard Worker */
601*f6dc9357SAndroid Build Coastguard Worker return Arc->Archive->GetProperty(IndexInArc, propID, value);
602*f6dc9357SAndroid Build Coastguard Worker }
603*f6dc9357SAndroid Build Coastguard Worker
604*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
605*f6dc9357SAndroid Build Coastguard Worker
606*f6dc9357SAndroid Build Coastguard Worker
607*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
608*f6dc9357SAndroid Build Coastguard Worker
609*f6dc9357SAndroid Build Coastguard Worker static UString GetDirPrefixOf(const UString &src)
610*f6dc9357SAndroid Build Coastguard Worker {
611*f6dc9357SAndroid Build Coastguard Worker UString s (src);
612*f6dc9357SAndroid Build Coastguard Worker if (!s.IsEmpty())
613*f6dc9357SAndroid Build Coastguard Worker {
614*f6dc9357SAndroid Build Coastguard Worker if (IsPathSepar(s.Back()))
615*f6dc9357SAndroid Build Coastguard Worker s.DeleteBack();
616*f6dc9357SAndroid Build Coastguard Worker int pos = s.ReverseFind_PathSepar();
617*f6dc9357SAndroid Build Coastguard Worker s.DeleteFrom((unsigned)(pos + 1));
618*f6dc9357SAndroid Build Coastguard Worker }
619*f6dc9357SAndroid Build Coastguard Worker return s;
620*f6dc9357SAndroid Build Coastguard Worker }
621*f6dc9357SAndroid Build Coastguard Worker
622*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_LINKS
623*f6dc9357SAndroid Build Coastguard Worker
624*f6dc9357SAndroid Build Coastguard Worker struct CLinkLevelsInfo
625*f6dc9357SAndroid Build Coastguard Worker {
626*f6dc9357SAndroid Build Coastguard Worker bool IsAbsolute;
627*f6dc9357SAndroid Build Coastguard Worker int LowLevel;
628*f6dc9357SAndroid Build Coastguard Worker int FinalLevel;
629*f6dc9357SAndroid Build Coastguard Worker
630*f6dc9357SAndroid Build Coastguard Worker void Parse(const UString &path);
631*f6dc9357SAndroid Build Coastguard Worker };
632*f6dc9357SAndroid Build Coastguard Worker
633*f6dc9357SAndroid Build Coastguard Worker void CLinkLevelsInfo::Parse(const UString &path)
634*f6dc9357SAndroid Build Coastguard Worker {
635*f6dc9357SAndroid Build Coastguard Worker IsAbsolute = NName::IsAbsolutePath(path);
636*f6dc9357SAndroid Build Coastguard Worker
637*f6dc9357SAndroid Build Coastguard Worker LowLevel = 0;
638*f6dc9357SAndroid Build Coastguard Worker FinalLevel = 0;
639*f6dc9357SAndroid Build Coastguard Worker
640*f6dc9357SAndroid Build Coastguard Worker UStringVector parts;
641*f6dc9357SAndroid Build Coastguard Worker SplitPathToParts(path, parts);
642*f6dc9357SAndroid Build Coastguard Worker int level = 0;
643*f6dc9357SAndroid Build Coastguard Worker
644*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, parts)
645*f6dc9357SAndroid Build Coastguard Worker {
646*f6dc9357SAndroid Build Coastguard Worker const UString &s = parts[i];
647*f6dc9357SAndroid Build Coastguard Worker if (s.IsEmpty())
648*f6dc9357SAndroid Build Coastguard Worker {
649*f6dc9357SAndroid Build Coastguard Worker if (i == 0)
650*f6dc9357SAndroid Build Coastguard Worker IsAbsolute = true;
651*f6dc9357SAndroid Build Coastguard Worker continue;
652*f6dc9357SAndroid Build Coastguard Worker }
653*f6dc9357SAndroid Build Coastguard Worker if (s == L".")
654*f6dc9357SAndroid Build Coastguard Worker continue;
655*f6dc9357SAndroid Build Coastguard Worker if (s == L"..")
656*f6dc9357SAndroid Build Coastguard Worker {
657*f6dc9357SAndroid Build Coastguard Worker level--;
658*f6dc9357SAndroid Build Coastguard Worker if (LowLevel > level)
659*f6dc9357SAndroid Build Coastguard Worker LowLevel = level;
660*f6dc9357SAndroid Build Coastguard Worker }
661*f6dc9357SAndroid Build Coastguard Worker else
662*f6dc9357SAndroid Build Coastguard Worker level++;
663*f6dc9357SAndroid Build Coastguard Worker }
664*f6dc9357SAndroid Build Coastguard Worker
665*f6dc9357SAndroid Build Coastguard Worker FinalLevel = level;
666*f6dc9357SAndroid Build Coastguard Worker }
667*f6dc9357SAndroid Build Coastguard Worker
668*f6dc9357SAndroid Build Coastguard Worker
669*f6dc9357SAndroid Build Coastguard Worker bool IsSafePath(const UString &path);
670*f6dc9357SAndroid Build Coastguard Worker bool IsSafePath(const UString &path)
671*f6dc9357SAndroid Build Coastguard Worker {
672*f6dc9357SAndroid Build Coastguard Worker CLinkLevelsInfo levelsInfo;
673*f6dc9357SAndroid Build Coastguard Worker levelsInfo.Parse(path);
674*f6dc9357SAndroid Build Coastguard Worker return !levelsInfo.IsAbsolute
675*f6dc9357SAndroid Build Coastguard Worker && levelsInfo.LowLevel >= 0
676*f6dc9357SAndroid Build Coastguard Worker && levelsInfo.FinalLevel > 0;
677*f6dc9357SAndroid Build Coastguard Worker }
678*f6dc9357SAndroid Build Coastguard Worker
679*f6dc9357SAndroid Build Coastguard Worker
680*f6dc9357SAndroid Build Coastguard Worker bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include);
681*f6dc9357SAndroid Build Coastguard Worker bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include)
682*f6dc9357SAndroid Build Coastguard Worker {
683*f6dc9357SAndroid Build Coastguard Worker bool found = false;
684*f6dc9357SAndroid Build Coastguard Worker
685*f6dc9357SAndroid Build Coastguard Worker // CheckPathVect() doesn't check path to Parent nodes
686*f6dc9357SAndroid Build Coastguard Worker if (node.CheckPathVect(item.PathParts, !item.MainIsDir, include))
687*f6dc9357SAndroid Build Coastguard Worker {
688*f6dc9357SAndroid Build Coastguard Worker if (!include)
689*f6dc9357SAndroid Build Coastguard Worker return true;
690*f6dc9357SAndroid Build Coastguard Worker
691*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
692*f6dc9357SAndroid Build Coastguard Worker if (!item.IsAltStream)
693*f6dc9357SAndroid Build Coastguard Worker return true;
694*f6dc9357SAndroid Build Coastguard Worker #endif
695*f6dc9357SAndroid Build Coastguard Worker
696*f6dc9357SAndroid Build Coastguard Worker found = true;
697*f6dc9357SAndroid Build Coastguard Worker }
698*f6dc9357SAndroid Build Coastguard Worker
699*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
700*f6dc9357SAndroid Build Coastguard Worker
701*f6dc9357SAndroid Build Coastguard Worker if (!item.IsAltStream)
702*f6dc9357SAndroid Build Coastguard Worker return false;
703*f6dc9357SAndroid Build Coastguard Worker
704*f6dc9357SAndroid Build Coastguard Worker UStringVector pathParts2 = item.PathParts;
705*f6dc9357SAndroid Build Coastguard Worker if (pathParts2.IsEmpty())
706*f6dc9357SAndroid Build Coastguard Worker pathParts2.AddNew();
707*f6dc9357SAndroid Build Coastguard Worker UString &back = pathParts2.Back();
708*f6dc9357SAndroid Build Coastguard Worker back.Add_Colon();
709*f6dc9357SAndroid Build Coastguard Worker back += item.AltStreamName;
710*f6dc9357SAndroid Build Coastguard Worker bool include2;
711*f6dc9357SAndroid Build Coastguard Worker
712*f6dc9357SAndroid Build Coastguard Worker if (node.CheckPathVect(pathParts2,
713*f6dc9357SAndroid Build Coastguard Worker true, // isFile,
714*f6dc9357SAndroid Build Coastguard Worker include2))
715*f6dc9357SAndroid Build Coastguard Worker {
716*f6dc9357SAndroid Build Coastguard Worker include = include2;
717*f6dc9357SAndroid Build Coastguard Worker return true;
718*f6dc9357SAndroid Build Coastguard Worker }
719*f6dc9357SAndroid Build Coastguard Worker
720*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_ALT_STREAMS
721*f6dc9357SAndroid Build Coastguard Worker
722*f6dc9357SAndroid Build Coastguard Worker return found;
723*f6dc9357SAndroid Build Coastguard Worker }
724*f6dc9357SAndroid Build Coastguard Worker
725*f6dc9357SAndroid Build Coastguard Worker
726*f6dc9357SAndroid Build Coastguard Worker bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item)
727*f6dc9357SAndroid Build Coastguard Worker {
728*f6dc9357SAndroid Build Coastguard Worker bool include;
729*f6dc9357SAndroid Build Coastguard Worker if (CensorNode_CheckPath2(node, item, include))
730*f6dc9357SAndroid Build Coastguard Worker return include;
731*f6dc9357SAndroid Build Coastguard Worker return false;
732*f6dc9357SAndroid Build Coastguard Worker }
733*f6dc9357SAndroid Build Coastguard Worker
734*f6dc9357SAndroid Build Coastguard Worker
735*f6dc9357SAndroid Build Coastguard Worker static FString MakePath_from_2_Parts(const FString &prefix, const FString &path)
736*f6dc9357SAndroid Build Coastguard Worker {
737*f6dc9357SAndroid Build Coastguard Worker FString s (prefix);
738*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
739*f6dc9357SAndroid Build Coastguard Worker if (!path.IsEmpty() && path[0] == ':' && !prefix.IsEmpty() && IsPathSepar(prefix.Back()))
740*f6dc9357SAndroid Build Coastguard Worker {
741*f6dc9357SAndroid Build Coastguard Worker if (!NName::IsDriveRootPath_SuperAllowed(prefix))
742*f6dc9357SAndroid Build Coastguard Worker s.DeleteBack();
743*f6dc9357SAndroid Build Coastguard Worker }
744*f6dc9357SAndroid Build Coastguard Worker #endif
745*f6dc9357SAndroid Build Coastguard Worker s += path;
746*f6dc9357SAndroid Build Coastguard Worker return s;
747*f6dc9357SAndroid Build Coastguard Worker }
748*f6dc9357SAndroid Build Coastguard Worker
749*f6dc9357SAndroid Build Coastguard Worker
750*f6dc9357SAndroid Build Coastguard Worker
751*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
752*f6dc9357SAndroid Build Coastguard Worker
753*f6dc9357SAndroid Build Coastguard Worker /*
754*f6dc9357SAndroid Build Coastguard Worker struct CTempMidBuffer
755*f6dc9357SAndroid Build Coastguard Worker {
756*f6dc9357SAndroid Build Coastguard Worker void *Buf;
757*f6dc9357SAndroid Build Coastguard Worker
758*f6dc9357SAndroid Build Coastguard Worker CTempMidBuffer(size_t size): Buf(NULL) { Buf = ::MidAlloc(size); }
759*f6dc9357SAndroid Build Coastguard Worker ~CTempMidBuffer() { ::MidFree(Buf); }
760*f6dc9357SAndroid Build Coastguard Worker };
761*f6dc9357SAndroid Build Coastguard Worker
762*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream)
763*f6dc9357SAndroid Build Coastguard Worker {
764*f6dc9357SAndroid Build Coastguard Worker const size_t kBufSize = 1 << 16;
765*f6dc9357SAndroid Build Coastguard Worker CTempMidBuffer buf(kBufSize);
766*f6dc9357SAndroid Build Coastguard Worker if (!buf.Buf)
767*f6dc9357SAndroid Build Coastguard Worker return E_OUTOFMEMORY;
768*f6dc9357SAndroid Build Coastguard Worker
769*f6dc9357SAndroid Build Coastguard Worker NIO::CInFile inFile;
770*f6dc9357SAndroid Build Coastguard Worker NIO::COutFile outFile;
771*f6dc9357SAndroid Build Coastguard Worker
772*f6dc9357SAndroid Build Coastguard Worker if (!inFile.Open(_copyFile_Path))
773*f6dc9357SAndroid Build Coastguard Worker return SendMessageError_with_LastError("Open error", _copyFile_Path);
774*f6dc9357SAndroid Build Coastguard Worker
775*f6dc9357SAndroid Build Coastguard Worker for (;;)
776*f6dc9357SAndroid Build Coastguard Worker {
777*f6dc9357SAndroid Build Coastguard Worker UInt32 num;
778*f6dc9357SAndroid Build Coastguard Worker
779*f6dc9357SAndroid Build Coastguard Worker if (!inFile.Read(buf.Buf, kBufSize, num))
780*f6dc9357SAndroid Build Coastguard Worker return SendMessageError_with_LastError("Read error", _copyFile_Path);
781*f6dc9357SAndroid Build Coastguard Worker
782*f6dc9357SAndroid Build Coastguard Worker if (num == 0)
783*f6dc9357SAndroid Build Coastguard Worker return S_OK;
784*f6dc9357SAndroid Build Coastguard Worker
785*f6dc9357SAndroid Build Coastguard Worker
786*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteStream(outStream, buf.Buf, num));
787*f6dc9357SAndroid Build Coastguard Worker }
788*f6dc9357SAndroid Build Coastguard Worker }
789*f6dc9357SAndroid Build Coastguard Worker */
790*f6dc9357SAndroid Build Coastguard Worker
791*f6dc9357SAndroid Build Coastguard Worker
792*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::ReadLink()
793*f6dc9357SAndroid Build Coastguard Worker {
794*f6dc9357SAndroid Build Coastguard Worker IInArchive *archive = _arc->Archive;
795*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = _index;
796*f6dc9357SAndroid Build Coastguard Worker _link.Clear();
797*f6dc9357SAndroid Build Coastguard Worker
798*f6dc9357SAndroid Build Coastguard Worker {
799*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
800*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidHardLink, &prop))
801*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_BSTR)
802*f6dc9357SAndroid Build Coastguard Worker {
803*f6dc9357SAndroid Build Coastguard Worker _link.isHardLink = true;
804*f6dc9357SAndroid Build Coastguard Worker // _link.isCopyLink = false;
805*f6dc9357SAndroid Build Coastguard Worker _link.isRelative = false; // RAR5, TAR: hard links are from root folder of archive
806*f6dc9357SAndroid Build Coastguard Worker _link.linkPath.SetFromBstr(prop.bstrVal);
807*f6dc9357SAndroid Build Coastguard Worker }
808*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
809*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
810*f6dc9357SAndroid Build Coastguard Worker }
811*f6dc9357SAndroid Build Coastguard Worker
812*f6dc9357SAndroid Build Coastguard Worker /*
813*f6dc9357SAndroid Build Coastguard Worker {
814*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
815*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidCopyLink, &prop));
816*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_BSTR)
817*f6dc9357SAndroid Build Coastguard Worker {
818*f6dc9357SAndroid Build Coastguard Worker _link.isHardLink = false;
819*f6dc9357SAndroid Build Coastguard Worker _link.isCopyLink = true;
820*f6dc9357SAndroid Build Coastguard Worker _link.isRelative = false; // RAR5: copy links are from root folder of archive
821*f6dc9357SAndroid Build Coastguard Worker _link.linkPath.SetFromBstr(prop.bstrVal);
822*f6dc9357SAndroid Build Coastguard Worker }
823*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
824*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
825*f6dc9357SAndroid Build Coastguard Worker }
826*f6dc9357SAndroid Build Coastguard Worker */
827*f6dc9357SAndroid Build Coastguard Worker
828*f6dc9357SAndroid Build Coastguard Worker {
829*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
830*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidSymLink, &prop))
831*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_BSTR)
832*f6dc9357SAndroid Build Coastguard Worker {
833*f6dc9357SAndroid Build Coastguard Worker _link.isHardLink = false;
834*f6dc9357SAndroid Build Coastguard Worker // _link.isCopyLink = false;
835*f6dc9357SAndroid Build Coastguard Worker _link.isRelative = true; // RAR5, TAR: symbolic links can be relative
836*f6dc9357SAndroid Build Coastguard Worker _link.linkPath.SetFromBstr(prop.bstrVal);
837*f6dc9357SAndroid Build Coastguard Worker }
838*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
839*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
840*f6dc9357SAndroid Build Coastguard Worker }
841*f6dc9357SAndroid Build Coastguard Worker
842*f6dc9357SAndroid Build Coastguard Worker NtReparse_Data = NULL;
843*f6dc9357SAndroid Build Coastguard Worker NtReparse_Size = 0;
844*f6dc9357SAndroid Build Coastguard Worker
845*f6dc9357SAndroid Build Coastguard Worker if (_link.linkPath.IsEmpty() && _arc->GetRawProps)
846*f6dc9357SAndroid Build Coastguard Worker {
847*f6dc9357SAndroid Build Coastguard Worker const void *data;
848*f6dc9357SAndroid Build Coastguard Worker UInt32 dataSize;
849*f6dc9357SAndroid Build Coastguard Worker UInt32 propType;
850*f6dc9357SAndroid Build Coastguard Worker
851*f6dc9357SAndroid Build Coastguard Worker _arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType);
852*f6dc9357SAndroid Build Coastguard Worker
853*f6dc9357SAndroid Build Coastguard Worker // if (dataSize == 1234567) // for debug: unpacking without reparse
854*f6dc9357SAndroid Build Coastguard Worker if (dataSize != 0)
855*f6dc9357SAndroid Build Coastguard Worker {
856*f6dc9357SAndroid Build Coastguard Worker if (propType != NPropDataType::kRaw)
857*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
858*f6dc9357SAndroid Build Coastguard Worker
859*f6dc9357SAndroid Build Coastguard Worker // 21.06: we need kpidNtReparse in linux for wim archives created in Windows
860*f6dc9357SAndroid Build Coastguard Worker // #ifdef _WIN32
861*f6dc9357SAndroid Build Coastguard Worker
862*f6dc9357SAndroid Build Coastguard Worker NtReparse_Data = data;
863*f6dc9357SAndroid Build Coastguard Worker NtReparse_Size = dataSize;
864*f6dc9357SAndroid Build Coastguard Worker
865*f6dc9357SAndroid Build Coastguard Worker CReparseAttr reparse;
866*f6dc9357SAndroid Build Coastguard Worker bool isOkReparse = reparse.Parse((const Byte *)data, dataSize);
867*f6dc9357SAndroid Build Coastguard Worker if (isOkReparse)
868*f6dc9357SAndroid Build Coastguard Worker {
869*f6dc9357SAndroid Build Coastguard Worker _link.isHardLink = false;
870*f6dc9357SAndroid Build Coastguard Worker // _link.isCopyLink = false;
871*f6dc9357SAndroid Build Coastguard Worker _link.linkPath = reparse.GetPath();
872*f6dc9357SAndroid Build Coastguard Worker _link.isJunction = reparse.IsMountPoint();
873*f6dc9357SAndroid Build Coastguard Worker
874*f6dc9357SAndroid Build Coastguard Worker if (reparse.IsSymLink_WSL())
875*f6dc9357SAndroid Build Coastguard Worker {
876*f6dc9357SAndroid Build Coastguard Worker _link.isWSL = true;
877*f6dc9357SAndroid Build Coastguard Worker _link.isRelative = reparse.IsRelative_WSL();
878*f6dc9357SAndroid Build Coastguard Worker }
879*f6dc9357SAndroid Build Coastguard Worker else
880*f6dc9357SAndroid Build Coastguard Worker _link.isRelative = reparse.IsRelative_Win();
881*f6dc9357SAndroid Build Coastguard Worker
882*f6dc9357SAndroid Build Coastguard Worker // const AString s = GetAnsiString(_link.linkPath);
883*f6dc9357SAndroid Build Coastguard Worker // printf("\n_link.linkPath: %s\n", s.Ptr());
884*f6dc9357SAndroid Build Coastguard Worker
885*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
886*f6dc9357SAndroid Build Coastguard Worker _link.linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR);
887*f6dc9357SAndroid Build Coastguard Worker #endif
888*f6dc9357SAndroid Build Coastguard Worker }
889*f6dc9357SAndroid Build Coastguard Worker // #endif
890*f6dc9357SAndroid Build Coastguard Worker }
891*f6dc9357SAndroid Build Coastguard Worker }
892*f6dc9357SAndroid Build Coastguard Worker
893*f6dc9357SAndroid Build Coastguard Worker if (_link.linkPath.IsEmpty())
894*f6dc9357SAndroid Build Coastguard Worker return S_OK;
895*f6dc9357SAndroid Build Coastguard Worker
896*f6dc9357SAndroid Build Coastguard Worker {
897*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
898*f6dc9357SAndroid Build Coastguard Worker _link.linkPath.Replace(L'/', WCHAR_PATH_SEPARATOR);
899*f6dc9357SAndroid Build Coastguard Worker #endif
900*f6dc9357SAndroid Build Coastguard Worker
901*f6dc9357SAndroid Build Coastguard Worker // rar5 uses "\??\" prefix for absolute links
902*f6dc9357SAndroid Build Coastguard Worker if (_link.linkPath.IsPrefixedBy(WSTRING_PATH_SEPARATOR L"??" WSTRING_PATH_SEPARATOR))
903*f6dc9357SAndroid Build Coastguard Worker {
904*f6dc9357SAndroid Build Coastguard Worker _link.isRelative = false;
905*f6dc9357SAndroid Build Coastguard Worker _link.linkPath.DeleteFrontal(4);
906*f6dc9357SAndroid Build Coastguard Worker }
907*f6dc9357SAndroid Build Coastguard Worker
908*f6dc9357SAndroid Build Coastguard Worker for (;;)
909*f6dc9357SAndroid Build Coastguard Worker // while (NName::IsAbsolutePath(linkPath))
910*f6dc9357SAndroid Build Coastguard Worker {
911*f6dc9357SAndroid Build Coastguard Worker unsigned n = NName::GetRootPrefixSize(_link.linkPath);
912*f6dc9357SAndroid Build Coastguard Worker if (n == 0)
913*f6dc9357SAndroid Build Coastguard Worker break;
914*f6dc9357SAndroid Build Coastguard Worker _link.isRelative = false;
915*f6dc9357SAndroid Build Coastguard Worker _link.linkPath.DeleteFrontal(n);
916*f6dc9357SAndroid Build Coastguard Worker }
917*f6dc9357SAndroid Build Coastguard Worker }
918*f6dc9357SAndroid Build Coastguard Worker
919*f6dc9357SAndroid Build Coastguard Worker if (_link.linkPath.IsEmpty())
920*f6dc9357SAndroid Build Coastguard Worker return S_OK;
921*f6dc9357SAndroid Build Coastguard Worker
922*f6dc9357SAndroid Build Coastguard Worker if (!_link.isRelative && _removePathParts.Size() != 0)
923*f6dc9357SAndroid Build Coastguard Worker {
924*f6dc9357SAndroid Build Coastguard Worker UStringVector pathParts;
925*f6dc9357SAndroid Build Coastguard Worker SplitPathToParts(_link.linkPath, pathParts);
926*f6dc9357SAndroid Build Coastguard Worker bool badPrefix = false;
927*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, _removePathParts)
928*f6dc9357SAndroid Build Coastguard Worker {
929*f6dc9357SAndroid Build Coastguard Worker if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0)
930*f6dc9357SAndroid Build Coastguard Worker {
931*f6dc9357SAndroid Build Coastguard Worker badPrefix = true;
932*f6dc9357SAndroid Build Coastguard Worker break;
933*f6dc9357SAndroid Build Coastguard Worker }
934*f6dc9357SAndroid Build Coastguard Worker }
935*f6dc9357SAndroid Build Coastguard Worker if (!badPrefix)
936*f6dc9357SAndroid Build Coastguard Worker pathParts.DeleteFrontal(_removePathParts.Size());
937*f6dc9357SAndroid Build Coastguard Worker _link.linkPath = MakePathFromParts(pathParts);
938*f6dc9357SAndroid Build Coastguard Worker }
939*f6dc9357SAndroid Build Coastguard Worker
940*f6dc9357SAndroid Build Coastguard Worker /*
941*f6dc9357SAndroid Build Coastguard Worker if (!_link.linkPath.IsEmpty())
942*f6dc9357SAndroid Build Coastguard Worker {
943*f6dc9357SAndroid Build Coastguard Worker printf("\n_link %s to -> %s\n", GetOemString(_item.Path).Ptr(), GetOemString(_link.linkPath).Ptr());
944*f6dc9357SAndroid Build Coastguard Worker }
945*f6dc9357SAndroid Build Coastguard Worker */
946*f6dc9357SAndroid Build Coastguard Worker
947*f6dc9357SAndroid Build Coastguard Worker return S_OK;
948*f6dc9357SAndroid Build Coastguard Worker }
949*f6dc9357SAndroid Build Coastguard Worker
950*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_LINKS
951*f6dc9357SAndroid Build Coastguard Worker
952*f6dc9357SAndroid Build Coastguard Worker
953*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
954*f6dc9357SAndroid Build Coastguard Worker
955*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetOwner(IInArchive *archive,
956*f6dc9357SAndroid Build Coastguard Worker UInt32 index, UInt32 pidName, UInt32 pidId, COwnerInfo &res)
957*f6dc9357SAndroid Build Coastguard Worker {
958*f6dc9357SAndroid Build Coastguard Worker {
959*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::CPropVariant prop;
960*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, pidId, &prop))
961*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_UI4)
962*f6dc9357SAndroid Build Coastguard Worker {
963*f6dc9357SAndroid Build Coastguard Worker res.Id_Defined = true;
964*f6dc9357SAndroid Build Coastguard Worker res.Id = prop.ulVal; // for debug
965*f6dc9357SAndroid Build Coastguard Worker // res.Id++; // for debug
966*f6dc9357SAndroid Build Coastguard Worker // if (pidId == kpidGroupId) res.Id += 7; // for debug
967*f6dc9357SAndroid Build Coastguard Worker // res.Id = 0; // for debug
968*f6dc9357SAndroid Build Coastguard Worker }
969*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
970*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
971*f6dc9357SAndroid Build Coastguard Worker }
972*f6dc9357SAndroid Build Coastguard Worker {
973*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::CPropVariant prop;
974*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, pidName, &prop))
975*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_BSTR)
976*f6dc9357SAndroid Build Coastguard Worker {
977*f6dc9357SAndroid Build Coastguard Worker const UString s = prop.bstrVal;
978*f6dc9357SAndroid Build Coastguard Worker ConvertUnicodeToUTF8(s, res.Name);
979*f6dc9357SAndroid Build Coastguard Worker }
980*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt == VT_UI4)
981*f6dc9357SAndroid Build Coastguard Worker {
982*f6dc9357SAndroid Build Coastguard Worker res.Id_Defined = true;
983*f6dc9357SAndroid Build Coastguard Worker res.Id = prop.ulVal;
984*f6dc9357SAndroid Build Coastguard Worker }
985*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
986*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
987*f6dc9357SAndroid Build Coastguard Worker }
988*f6dc9357SAndroid Build Coastguard Worker return S_OK;
989*f6dc9357SAndroid Build Coastguard Worker }
990*f6dc9357SAndroid Build Coastguard Worker
991*f6dc9357SAndroid Build Coastguard Worker #endif
992*f6dc9357SAndroid Build Coastguard Worker
993*f6dc9357SAndroid Build Coastguard Worker
994*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::Read_fi_Props()
995*f6dc9357SAndroid Build Coastguard Worker {
996*f6dc9357SAndroid Build Coastguard Worker IInArchive *archive = _arc->Archive;
997*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = _index;
998*f6dc9357SAndroid Build Coastguard Worker
999*f6dc9357SAndroid Build Coastguard Worker _fi.Attrib_Defined = false;
1000*f6dc9357SAndroid Build Coastguard Worker
1001*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
1002*f6dc9357SAndroid Build Coastguard Worker _fi.Owner.Clear();
1003*f6dc9357SAndroid Build Coastguard Worker _fi.Group.Clear();
1004*f6dc9357SAndroid Build Coastguard Worker #endif
1005*f6dc9357SAndroid Build Coastguard Worker
1006*f6dc9357SAndroid Build Coastguard Worker {
1007*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
1008*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidPosixAttrib, &prop))
1009*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_UI4)
1010*f6dc9357SAndroid Build Coastguard Worker {
1011*f6dc9357SAndroid Build Coastguard Worker _fi.SetFromPosixAttrib(prop.ulVal);
1012*f6dc9357SAndroid Build Coastguard Worker }
1013*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
1014*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1015*f6dc9357SAndroid Build Coastguard Worker }
1016*f6dc9357SAndroid Build Coastguard Worker
1017*f6dc9357SAndroid Build Coastguard Worker {
1018*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
1019*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidAttrib, &prop))
1020*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_UI4)
1021*f6dc9357SAndroid Build Coastguard Worker {
1022*f6dc9357SAndroid Build Coastguard Worker _fi.Attrib = prop.ulVal;
1023*f6dc9357SAndroid Build Coastguard Worker _fi.Attrib_Defined = true;
1024*f6dc9357SAndroid Build Coastguard Worker }
1025*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
1026*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1027*f6dc9357SAndroid Build Coastguard Worker }
1028*f6dc9357SAndroid Build Coastguard Worker
1029*f6dc9357SAndroid Build Coastguard Worker RINOK(GetTime(index, kpidCTime, _fi.CTime))
1030*f6dc9357SAndroid Build Coastguard Worker RINOK(GetTime(index, kpidATime, _fi.ATime))
1031*f6dc9357SAndroid Build Coastguard Worker RINOK(GetTime(index, kpidMTime, _fi.MTime))
1032*f6dc9357SAndroid Build Coastguard Worker
1033*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
1034*f6dc9357SAndroid Build Coastguard Worker if (_ntOptions.ExtractOwner)
1035*f6dc9357SAndroid Build Coastguard Worker {
1036*f6dc9357SAndroid Build Coastguard Worker // SendMessageError_with_LastError("_ntOptions.ExtractOwner", _diskFilePath);
1037*f6dc9357SAndroid Build Coastguard Worker GetOwner(archive, index, kpidUser, kpidUserId, _fi.Owner);
1038*f6dc9357SAndroid Build Coastguard Worker GetOwner(archive, index, kpidGroup, kpidGroupId, _fi.Group);
1039*f6dc9357SAndroid Build Coastguard Worker }
1040*f6dc9357SAndroid Build Coastguard Worker #endif
1041*f6dc9357SAndroid Build Coastguard Worker
1042*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1043*f6dc9357SAndroid Build Coastguard Worker }
1044*f6dc9357SAndroid Build Coastguard Worker
1045*f6dc9357SAndroid Build Coastguard Worker
1046*f6dc9357SAndroid Build Coastguard Worker
1047*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::CorrectPathParts()
1048*f6dc9357SAndroid Build Coastguard Worker {
1049*f6dc9357SAndroid Build Coastguard Worker UStringVector &pathParts = _item.PathParts;
1050*f6dc9357SAndroid Build Coastguard Worker
1051*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1052*f6dc9357SAndroid Build Coastguard Worker if (!_item.IsAltStream
1053*f6dc9357SAndroid Build Coastguard Worker || !pathParts.IsEmpty()
1054*f6dc9357SAndroid Build Coastguard Worker || !(_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt))
1055*f6dc9357SAndroid Build Coastguard Worker #endif
1056*f6dc9357SAndroid Build Coastguard Worker Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, _keepAndReplaceEmptyDirPrefixes, pathParts, _item.MainIsDir);
1057*f6dc9357SAndroid Build Coastguard Worker
1058*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1059*f6dc9357SAndroid Build Coastguard Worker
1060*f6dc9357SAndroid Build Coastguard Worker if (_item.IsAltStream)
1061*f6dc9357SAndroid Build Coastguard Worker {
1062*f6dc9357SAndroid Build Coastguard Worker UString s (_item.AltStreamName);
1063*f6dc9357SAndroid Build Coastguard Worker Correct_AltStream_Name(s);
1064*f6dc9357SAndroid Build Coastguard Worker bool needColon = true;
1065*f6dc9357SAndroid Build Coastguard Worker
1066*f6dc9357SAndroid Build Coastguard Worker if (pathParts.IsEmpty())
1067*f6dc9357SAndroid Build Coastguard Worker {
1068*f6dc9357SAndroid Build Coastguard Worker pathParts.AddNew();
1069*f6dc9357SAndroid Build Coastguard Worker if (_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt)
1070*f6dc9357SAndroid Build Coastguard Worker needColon = false;
1071*f6dc9357SAndroid Build Coastguard Worker }
1072*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
1073*f6dc9357SAndroid Build Coastguard Worker else if (_pathMode == NExtract::NPathMode::kAbsPaths &&
1074*f6dc9357SAndroid Build Coastguard Worker NWildcard::GetNumPrefixParts_if_DrivePath(pathParts) == pathParts.Size())
1075*f6dc9357SAndroid Build Coastguard Worker pathParts.AddNew();
1076*f6dc9357SAndroid Build Coastguard Worker #endif
1077*f6dc9357SAndroid Build Coastguard Worker
1078*f6dc9357SAndroid Build Coastguard Worker UString &name = pathParts.Back();
1079*f6dc9357SAndroid Build Coastguard Worker if (needColon)
1080*f6dc9357SAndroid Build Coastguard Worker name.Add_Char((char)(_ntOptions.ReplaceColonForAltStream ? '_' : ':'));
1081*f6dc9357SAndroid Build Coastguard Worker name += s;
1082*f6dc9357SAndroid Build Coastguard Worker }
1083*f6dc9357SAndroid Build Coastguard Worker
1084*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_ALT_STREAMS
1085*f6dc9357SAndroid Build Coastguard Worker }
1086*f6dc9357SAndroid Build Coastguard Worker
1087*f6dc9357SAndroid Build Coastguard Worker
1088*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt)
1089*f6dc9357SAndroid Build Coastguard Worker {
1090*f6dc9357SAndroid Build Coastguard Worker pt.CTime_Defined = false;
1091*f6dc9357SAndroid Build Coastguard Worker pt.ATime_Defined = false;
1092*f6dc9357SAndroid Build Coastguard Worker pt.MTime_Defined = false;
1093*f6dc9357SAndroid Build Coastguard Worker
1094*f6dc9357SAndroid Build Coastguard Worker // if (Write_MTime)
1095*f6dc9357SAndroid Build Coastguard Worker {
1096*f6dc9357SAndroid Build Coastguard Worker if (_fi.MTime.Def)
1097*f6dc9357SAndroid Build Coastguard Worker {
1098*f6dc9357SAndroid Build Coastguard Worker _fi.MTime.Write_To_FiTime(pt.MTime);
1099*f6dc9357SAndroid Build Coastguard Worker pt.MTime_Defined = true;
1100*f6dc9357SAndroid Build Coastguard Worker }
1101*f6dc9357SAndroid Build Coastguard Worker else if (_arc->MTime.Def)
1102*f6dc9357SAndroid Build Coastguard Worker {
1103*f6dc9357SAndroid Build Coastguard Worker _arc->MTime.Write_To_FiTime(pt.MTime);
1104*f6dc9357SAndroid Build Coastguard Worker pt.MTime_Defined = true;
1105*f6dc9357SAndroid Build Coastguard Worker }
1106*f6dc9357SAndroid Build Coastguard Worker }
1107*f6dc9357SAndroid Build Coastguard Worker
1108*f6dc9357SAndroid Build Coastguard Worker if (/* Write_CTime && */ _fi.CTime.Def)
1109*f6dc9357SAndroid Build Coastguard Worker {
1110*f6dc9357SAndroid Build Coastguard Worker _fi.CTime.Write_To_FiTime(pt.CTime);
1111*f6dc9357SAndroid Build Coastguard Worker pt.CTime_Defined = true;
1112*f6dc9357SAndroid Build Coastguard Worker }
1113*f6dc9357SAndroid Build Coastguard Worker
1114*f6dc9357SAndroid Build Coastguard Worker if (/* Write_ATime && */ _fi.ATime.Def)
1115*f6dc9357SAndroid Build Coastguard Worker {
1116*f6dc9357SAndroid Build Coastguard Worker _fi.ATime.Write_To_FiTime(pt.ATime);
1117*f6dc9357SAndroid Build Coastguard Worker pt.ATime_Defined = true;
1118*f6dc9357SAndroid Build Coastguard Worker }
1119*f6dc9357SAndroid Build Coastguard Worker }
1120*f6dc9357SAndroid Build Coastguard Worker
1121*f6dc9357SAndroid Build Coastguard Worker
1122*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::CreateFolders()
1123*f6dc9357SAndroid Build Coastguard Worker {
1124*f6dc9357SAndroid Build Coastguard Worker // 21.04 : we don't change original (_item.PathParts) here
1125*f6dc9357SAndroid Build Coastguard Worker UStringVector pathParts = _item.PathParts;
1126*f6dc9357SAndroid Build Coastguard Worker
1127*f6dc9357SAndroid Build Coastguard Worker // bool is_DirOp = false;
1128*f6dc9357SAndroid Build Coastguard Worker if (!pathParts.IsEmpty())
1129*f6dc9357SAndroid Build Coastguard Worker {
1130*f6dc9357SAndroid Build Coastguard Worker /* v23: if we extract symlink, and we know that it links to dir:
1131*f6dc9357SAndroid Build Coastguard Worker Linux: we don't create dir item (symlink_from_path) here.
1132*f6dc9357SAndroid Build Coastguard Worker Windows: SetReparseData() will create dir item, if it doesn't exist,
1133*f6dc9357SAndroid Build Coastguard Worker but if we create dir item here, it's not problem. */
1134*f6dc9357SAndroid Build Coastguard Worker if (!_item.IsDir
1135*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
1136*f6dc9357SAndroid Build Coastguard Worker #ifndef WIN32
1137*f6dc9357SAndroid Build Coastguard Worker || !_link.linkPath.IsEmpty()
1138*f6dc9357SAndroid Build Coastguard Worker #endif
1139*f6dc9357SAndroid Build Coastguard Worker #endif
1140*f6dc9357SAndroid Build Coastguard Worker )
1141*f6dc9357SAndroid Build Coastguard Worker pathParts.DeleteBack();
1142*f6dc9357SAndroid Build Coastguard Worker // else is_DirOp = true;
1143*f6dc9357SAndroid Build Coastguard Worker }
1144*f6dc9357SAndroid Build Coastguard Worker
1145*f6dc9357SAndroid Build Coastguard Worker if (pathParts.IsEmpty())
1146*f6dc9357SAndroid Build Coastguard Worker {
1147*f6dc9357SAndroid Build Coastguard Worker /* if (_some_pathParts_wereRemoved && Is_elimPrefix_Mode),
1148*f6dc9357SAndroid Build Coastguard Worker then we can have empty pathParts() here for root folder.
1149*f6dc9357SAndroid Build Coastguard Worker v24.00: fixed: we set timestamps for such folder still.
1150*f6dc9357SAndroid Build Coastguard Worker */
1151*f6dc9357SAndroid Build Coastguard Worker if (!_some_pathParts_wereRemoved ||
1152*f6dc9357SAndroid Build Coastguard Worker !Is_elimPrefix_Mode)
1153*f6dc9357SAndroid Build Coastguard Worker return;
1154*f6dc9357SAndroid Build Coastguard Worker // return; // ignore empty paths case
1155*f6dc9357SAndroid Build Coastguard Worker }
1156*f6dc9357SAndroid Build Coastguard Worker /*
1157*f6dc9357SAndroid Build Coastguard Worker if (is_DirOp)
1158*f6dc9357SAndroid Build Coastguard Worker {
1159*f6dc9357SAndroid Build Coastguard Worker RINOK(PrepareOperation(NArchive::NExtract::NAskMode::kExtract))
1160*f6dc9357SAndroid Build Coastguard Worker _op_WasReported = true;
1161*f6dc9357SAndroid Build Coastguard Worker }
1162*f6dc9357SAndroid Build Coastguard Worker */
1163*f6dc9357SAndroid Build Coastguard Worker
1164*f6dc9357SAndroid Build Coastguard Worker FString fullPathNew;
1165*f6dc9357SAndroid Build Coastguard Worker CreateComplexDirectory(pathParts, fullPathNew);
1166*f6dc9357SAndroid Build Coastguard Worker
1167*f6dc9357SAndroid Build Coastguard Worker /*
1168*f6dc9357SAndroid Build Coastguard Worker if (is_DirOp)
1169*f6dc9357SAndroid Build Coastguard Worker {
1170*f6dc9357SAndroid Build Coastguard Worker RINOK(SetOperationResult(
1171*f6dc9357SAndroid Build Coastguard Worker // _itemFailure ? NArchive::NExtract::NOperationResult::kDataError :
1172*f6dc9357SAndroid Build Coastguard Worker NArchive::NExtract::NOperationResult::kOK
1173*f6dc9357SAndroid Build Coastguard Worker ))
1174*f6dc9357SAndroid Build Coastguard Worker }
1175*f6dc9357SAndroid Build Coastguard Worker */
1176*f6dc9357SAndroid Build Coastguard Worker
1177*f6dc9357SAndroid Build Coastguard Worker if (!_item.IsDir)
1178*f6dc9357SAndroid Build Coastguard Worker return;
1179*f6dc9357SAndroid Build Coastguard Worker if (fullPathNew.IsEmpty())
1180*f6dc9357SAndroid Build Coastguard Worker return;
1181*f6dc9357SAndroid Build Coastguard Worker
1182*f6dc9357SAndroid Build Coastguard Worker if (_itemFailure)
1183*f6dc9357SAndroid Build Coastguard Worker return;
1184*f6dc9357SAndroid Build Coastguard Worker
1185*f6dc9357SAndroid Build Coastguard Worker CDirPathTime pt;
1186*f6dc9357SAndroid Build Coastguard Worker GetFiTimesCAM(pt);
1187*f6dc9357SAndroid Build Coastguard Worker
1188*f6dc9357SAndroid Build Coastguard Worker if (pt.IsSomeTimeDefined())
1189*f6dc9357SAndroid Build Coastguard Worker {
1190*f6dc9357SAndroid Build Coastguard Worker pt.Path = fullPathNew;
1191*f6dc9357SAndroid Build Coastguard Worker pt.SetDirTime();
1192*f6dc9357SAndroid Build Coastguard Worker _extractedFolders.Add(pt);
1193*f6dc9357SAndroid Build Coastguard Worker }
1194*f6dc9357SAndroid Build Coastguard Worker }
1195*f6dc9357SAndroid Build Coastguard Worker
1196*f6dc9357SAndroid Build Coastguard Worker
1197*f6dc9357SAndroid Build Coastguard Worker
1198*f6dc9357SAndroid Build Coastguard Worker /*
1199*f6dc9357SAndroid Build Coastguard Worker CheckExistFile(fullProcessedPath)
1200*f6dc9357SAndroid Build Coastguard Worker it can change: fullProcessedPath, _isRenamed, _overwriteMode
1201*f6dc9357SAndroid Build Coastguard Worker (needExit = true) means that we must exit GetStream() even for S_OK result.
1202*f6dc9357SAndroid Build Coastguard Worker */
1203*f6dc9357SAndroid Build Coastguard Worker
1204*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool &needExit)
1205*f6dc9357SAndroid Build Coastguard Worker {
1206*f6dc9357SAndroid Build Coastguard Worker needExit = true; // it was set already before
1207*f6dc9357SAndroid Build Coastguard Worker
1208*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fileInfo;
1209*f6dc9357SAndroid Build Coastguard Worker
1210*f6dc9357SAndroid Build Coastguard Worker if (fileInfo.Find(fullProcessedPath))
1211*f6dc9357SAndroid Build Coastguard Worker {
1212*f6dc9357SAndroid Build Coastguard Worker if (_overwriteMode == NExtract::NOverwriteMode::kSkip)
1213*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1214*f6dc9357SAndroid Build Coastguard Worker
1215*f6dc9357SAndroid Build Coastguard Worker if (_overwriteMode == NExtract::NOverwriteMode::kAsk)
1216*f6dc9357SAndroid Build Coastguard Worker {
1217*f6dc9357SAndroid Build Coastguard Worker const int slashPos = fullProcessedPath.ReverseFind_PathSepar();
1218*f6dc9357SAndroid Build Coastguard Worker const FString realFullProcessedPath = fullProcessedPath.Left((unsigned)(slashPos + 1)) + fileInfo.Name;
1219*f6dc9357SAndroid Build Coastguard Worker
1220*f6dc9357SAndroid Build Coastguard Worker /* (fileInfo) can be symbolic link.
1221*f6dc9357SAndroid Build Coastguard Worker we can show final file properties here. */
1222*f6dc9357SAndroid Build Coastguard Worker
1223*f6dc9357SAndroid Build Coastguard Worker FILETIME ft1;
1224*f6dc9357SAndroid Build Coastguard Worker FiTime_To_FILETIME(fileInfo.MTime, ft1);
1225*f6dc9357SAndroid Build Coastguard Worker
1226*f6dc9357SAndroid Build Coastguard Worker Int32 overwriteResult;
1227*f6dc9357SAndroid Build Coastguard Worker RINOK(_extractCallback2->AskOverwrite(
1228*f6dc9357SAndroid Build Coastguard Worker fs2us(realFullProcessedPath), &ft1, &fileInfo.Size, _item.Path,
1229*f6dc9357SAndroid Build Coastguard Worker _fi.MTime.Def ? &_fi.MTime.FT : NULL,
1230*f6dc9357SAndroid Build Coastguard Worker _curSize_Defined ? &_curSize : NULL,
1231*f6dc9357SAndroid Build Coastguard Worker &overwriteResult))
1232*f6dc9357SAndroid Build Coastguard Worker
1233*f6dc9357SAndroid Build Coastguard Worker switch (overwriteResult)
1234*f6dc9357SAndroid Build Coastguard Worker {
1235*f6dc9357SAndroid Build Coastguard Worker case NOverwriteAnswer::kCancel:
1236*f6dc9357SAndroid Build Coastguard Worker return E_ABORT;
1237*f6dc9357SAndroid Build Coastguard Worker case NOverwriteAnswer::kNo:
1238*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1239*f6dc9357SAndroid Build Coastguard Worker case NOverwriteAnswer::kNoToAll:
1240*f6dc9357SAndroid Build Coastguard Worker _overwriteMode = NExtract::NOverwriteMode::kSkip;
1241*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1242*f6dc9357SAndroid Build Coastguard Worker
1243*f6dc9357SAndroid Build Coastguard Worker case NOverwriteAnswer::kYes:
1244*f6dc9357SAndroid Build Coastguard Worker break;
1245*f6dc9357SAndroid Build Coastguard Worker case NOverwriteAnswer::kYesToAll:
1246*f6dc9357SAndroid Build Coastguard Worker _overwriteMode = NExtract::NOverwriteMode::kOverwrite;
1247*f6dc9357SAndroid Build Coastguard Worker break;
1248*f6dc9357SAndroid Build Coastguard Worker case NOverwriteAnswer::kAutoRename:
1249*f6dc9357SAndroid Build Coastguard Worker _overwriteMode = NExtract::NOverwriteMode::kRename;
1250*f6dc9357SAndroid Build Coastguard Worker break;
1251*f6dc9357SAndroid Build Coastguard Worker default:
1252*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1253*f6dc9357SAndroid Build Coastguard Worker }
1254*f6dc9357SAndroid Build Coastguard Worker } // NExtract::NOverwriteMode::kAsk
1255*f6dc9357SAndroid Build Coastguard Worker
1256*f6dc9357SAndroid Build Coastguard Worker if (_overwriteMode == NExtract::NOverwriteMode::kRename)
1257*f6dc9357SAndroid Build Coastguard Worker {
1258*f6dc9357SAndroid Build Coastguard Worker if (!AutoRenamePath(fullProcessedPath))
1259*f6dc9357SAndroid Build Coastguard Worker {
1260*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(kCantAutoRename, fullProcessedPath))
1261*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1262*f6dc9357SAndroid Build Coastguard Worker }
1263*f6dc9357SAndroid Build Coastguard Worker _isRenamed = true;
1264*f6dc9357SAndroid Build Coastguard Worker }
1265*f6dc9357SAndroid Build Coastguard Worker else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting)
1266*f6dc9357SAndroid Build Coastguard Worker {
1267*f6dc9357SAndroid Build Coastguard Worker FString existPath (fullProcessedPath);
1268*f6dc9357SAndroid Build Coastguard Worker if (!AutoRenamePath(existPath))
1269*f6dc9357SAndroid Build Coastguard Worker {
1270*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(kCantAutoRename, fullProcessedPath))
1271*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1272*f6dc9357SAndroid Build Coastguard Worker }
1273*f6dc9357SAndroid Build Coastguard Worker // MyMoveFile can rename folders. So it's OK to use it for folders too
1274*f6dc9357SAndroid Build Coastguard Worker if (!MyMoveFile(fullProcessedPath, existPath))
1275*f6dc9357SAndroid Build Coastguard Worker {
1276*f6dc9357SAndroid Build Coastguard Worker HRESULT errorCode = GetLastError_noZero_HRESULT();
1277*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError2(errorCode, kCantRenameFile, existPath, fullProcessedPath))
1278*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1279*f6dc9357SAndroid Build Coastguard Worker }
1280*f6dc9357SAndroid Build Coastguard Worker }
1281*f6dc9357SAndroid Build Coastguard Worker else // not Rename*
1282*f6dc9357SAndroid Build Coastguard Worker {
1283*f6dc9357SAndroid Build Coastguard Worker if (fileInfo.IsDir())
1284*f6dc9357SAndroid Build Coastguard Worker {
1285*f6dc9357SAndroid Build Coastguard Worker // do we need to delete all files in folder?
1286*f6dc9357SAndroid Build Coastguard Worker if (!RemoveDir(fullProcessedPath))
1287*f6dc9357SAndroid Build Coastguard Worker {
1288*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath))
1289*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1290*f6dc9357SAndroid Build Coastguard Worker }
1291*f6dc9357SAndroid Build Coastguard Worker }
1292*f6dc9357SAndroid Build Coastguard Worker else // fileInfo is not Dir
1293*f6dc9357SAndroid Build Coastguard Worker {
1294*f6dc9357SAndroid Build Coastguard Worker if (NFind::DoesFileExist_Raw(fullProcessedPath))
1295*f6dc9357SAndroid Build Coastguard Worker if (!DeleteFileAlways(fullProcessedPath))
1296*f6dc9357SAndroid Build Coastguard Worker if (GetLastError() != ERROR_FILE_NOT_FOUND) // check it in linux
1297*f6dc9357SAndroid Build Coastguard Worker {
1298*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath))
1299*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1300*f6dc9357SAndroid Build Coastguard Worker // return E_FAIL;
1301*f6dc9357SAndroid Build Coastguard Worker }
1302*f6dc9357SAndroid Build Coastguard Worker } // fileInfo is not Dir
1303*f6dc9357SAndroid Build Coastguard Worker } // not Rename*
1304*f6dc9357SAndroid Build Coastguard Worker }
1305*f6dc9357SAndroid Build Coastguard Worker else // not Find(fullProcessedPath)
1306*f6dc9357SAndroid Build Coastguard Worker {
1307*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
1308*f6dc9357SAndroid Build Coastguard Worker // we need to clear READ-ONLY of parent before creating alt stream
1309*f6dc9357SAndroid Build Coastguard Worker const int colonPos = NName::FindAltStreamColon(fullProcessedPath);
1310*f6dc9357SAndroid Build Coastguard Worker if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0)
1311*f6dc9357SAndroid Build Coastguard Worker {
1312*f6dc9357SAndroid Build Coastguard Worker FString parentFsPath (fullProcessedPath);
1313*f6dc9357SAndroid Build Coastguard Worker parentFsPath.DeleteFrom((unsigned)colonPos);
1314*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo parentFi;
1315*f6dc9357SAndroid Build Coastguard Worker if (parentFi.Find(parentFsPath))
1316*f6dc9357SAndroid Build Coastguard Worker {
1317*f6dc9357SAndroid Build Coastguard Worker if (parentFi.IsReadOnly())
1318*f6dc9357SAndroid Build Coastguard Worker {
1319*f6dc9357SAndroid Build Coastguard Worker _altStream_NeedRestore_Attrib_for_parentFsPath = parentFsPath;
1320*f6dc9357SAndroid Build Coastguard Worker _altStream_NeedRestore_AttribVal = parentFi.Attrib;
1321*f6dc9357SAndroid Build Coastguard Worker SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY);
1322*f6dc9357SAndroid Build Coastguard Worker }
1323*f6dc9357SAndroid Build Coastguard Worker }
1324*f6dc9357SAndroid Build Coastguard Worker }
1325*f6dc9357SAndroid Build Coastguard Worker #endif // defined(_WIN32) && !defined(UNDER_CE)
1326*f6dc9357SAndroid Build Coastguard Worker }
1327*f6dc9357SAndroid Build Coastguard Worker
1328*f6dc9357SAndroid Build Coastguard Worker needExit = false;
1329*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1330*f6dc9357SAndroid Build Coastguard Worker }
1331*f6dc9357SAndroid Build Coastguard Worker
1332*f6dc9357SAndroid Build Coastguard Worker
1333*f6dc9357SAndroid Build Coastguard Worker
1334*f6dc9357SAndroid Build Coastguard Worker
1335*f6dc9357SAndroid Build Coastguard Worker
1336*f6dc9357SAndroid Build Coastguard Worker
1337*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit)
1338*f6dc9357SAndroid Build Coastguard Worker {
1339*f6dc9357SAndroid Build Coastguard Worker needExit = true;
1340*f6dc9357SAndroid Build Coastguard Worker
1341*f6dc9357SAndroid Build Coastguard Worker RINOK(Read_fi_Props())
1342*f6dc9357SAndroid Build Coastguard Worker
1343*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
1344*f6dc9357SAndroid Build Coastguard Worker IInArchive *archive = _arc->Archive;
1345*f6dc9357SAndroid Build Coastguard Worker #endif
1346*f6dc9357SAndroid Build Coastguard Worker
1347*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = _index;
1348*f6dc9357SAndroid Build Coastguard Worker
1349*f6dc9357SAndroid Build Coastguard Worker bool isAnti = false;
1350*f6dc9357SAndroid Build Coastguard Worker RINOK(_arc->IsItem_Anti(index, isAnti))
1351*f6dc9357SAndroid Build Coastguard Worker
1352*f6dc9357SAndroid Build Coastguard Worker CorrectPathParts();
1353*f6dc9357SAndroid Build Coastguard Worker UString processedPath (MakePathFromParts(_item.PathParts));
1354*f6dc9357SAndroid Build Coastguard Worker
1355*f6dc9357SAndroid Build Coastguard Worker if (!isAnti)
1356*f6dc9357SAndroid Build Coastguard Worker {
1357*f6dc9357SAndroid Build Coastguard Worker // 21.04: CreateFolders doesn't change (_item.PathParts)
1358*f6dc9357SAndroid Build Coastguard Worker CreateFolders();
1359*f6dc9357SAndroid Build Coastguard Worker }
1360*f6dc9357SAndroid Build Coastguard Worker
1361*f6dc9357SAndroid Build Coastguard Worker FString fullProcessedPath (us2fs(processedPath));
1362*f6dc9357SAndroid Build Coastguard Worker if (_pathMode != NExtract::NPathMode::kAbsPaths
1363*f6dc9357SAndroid Build Coastguard Worker || !NName::IsAbsolutePath(processedPath))
1364*f6dc9357SAndroid Build Coastguard Worker {
1365*f6dc9357SAndroid Build Coastguard Worker fullProcessedPath = MakePath_from_2_Parts(_dirPathPrefix, fullProcessedPath);
1366*f6dc9357SAndroid Build Coastguard Worker }
1367*f6dc9357SAndroid Build Coastguard Worker
1368*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1369*f6dc9357SAndroid Build Coastguard Worker if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1)
1370*f6dc9357SAndroid Build Coastguard Worker {
1371*f6dc9357SAndroid Build Coastguard Worker const int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex));
1372*f6dc9357SAndroid Build Coastguard Worker if (renIndex != -1)
1373*f6dc9357SAndroid Build Coastguard Worker {
1374*f6dc9357SAndroid Build Coastguard Worker const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex];
1375*f6dc9357SAndroid Build Coastguard Worker fullProcessedPath = pair.Path;
1376*f6dc9357SAndroid Build Coastguard Worker fullProcessedPath.Add_Colon();
1377*f6dc9357SAndroid Build Coastguard Worker UString s (_item.AltStreamName);
1378*f6dc9357SAndroid Build Coastguard Worker Correct_AltStream_Name(s);
1379*f6dc9357SAndroid Build Coastguard Worker fullProcessedPath += us2fs(s);
1380*f6dc9357SAndroid Build Coastguard Worker }
1381*f6dc9357SAndroid Build Coastguard Worker }
1382*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_ALT_STREAMS
1383*f6dc9357SAndroid Build Coastguard Worker
1384*f6dc9357SAndroid Build Coastguard Worker if (_item.IsDir)
1385*f6dc9357SAndroid Build Coastguard Worker {
1386*f6dc9357SAndroid Build Coastguard Worker _diskFilePath = fullProcessedPath;
1387*f6dc9357SAndroid Build Coastguard Worker if (isAnti)
1388*f6dc9357SAndroid Build Coastguard Worker RemoveDir(_diskFilePath);
1389*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
1390*f6dc9357SAndroid Build Coastguard Worker if (_link.linkPath.IsEmpty())
1391*f6dc9357SAndroid Build Coastguard Worker #endif
1392*f6dc9357SAndroid Build Coastguard Worker {
1393*f6dc9357SAndroid Build Coastguard Worker if (!isAnti)
1394*f6dc9357SAndroid Build Coastguard Worker SetAttrib();
1395*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1396*f6dc9357SAndroid Build Coastguard Worker }
1397*f6dc9357SAndroid Build Coastguard Worker }
1398*f6dc9357SAndroid Build Coastguard Worker else if (!_isSplit)
1399*f6dc9357SAndroid Build Coastguard Worker {
1400*f6dc9357SAndroid Build Coastguard Worker RINOK(CheckExistFile(fullProcessedPath, needExit))
1401*f6dc9357SAndroid Build Coastguard Worker if (needExit)
1402*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1403*f6dc9357SAndroid Build Coastguard Worker needExit = true;
1404*f6dc9357SAndroid Build Coastguard Worker }
1405*f6dc9357SAndroid Build Coastguard Worker
1406*f6dc9357SAndroid Build Coastguard Worker _diskFilePath = fullProcessedPath;
1407*f6dc9357SAndroid Build Coastguard Worker
1408*f6dc9357SAndroid Build Coastguard Worker
1409*f6dc9357SAndroid Build Coastguard Worker if (isAnti)
1410*f6dc9357SAndroid Build Coastguard Worker {
1411*f6dc9357SAndroid Build Coastguard Worker needExit = false;
1412*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1413*f6dc9357SAndroid Build Coastguard Worker }
1414*f6dc9357SAndroid Build Coastguard Worker
1415*f6dc9357SAndroid Build Coastguard Worker // not anti
1416*f6dc9357SAndroid Build Coastguard Worker
1417*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
1418*f6dc9357SAndroid Build Coastguard Worker
1419*f6dc9357SAndroid Build Coastguard Worker if (!_link.linkPath.IsEmpty())
1420*f6dc9357SAndroid Build Coastguard Worker {
1421*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
1422*f6dc9357SAndroid Build Coastguard Worker {
1423*f6dc9357SAndroid Build Coastguard Worker bool linkWasSet = false;
1424*f6dc9357SAndroid Build Coastguard Worker RINOK(SetFromLinkPath(fullProcessedPath, _link, linkWasSet))
1425*f6dc9357SAndroid Build Coastguard Worker if (linkWasSet)
1426*f6dc9357SAndroid Build Coastguard Worker {
1427*f6dc9357SAndroid Build Coastguard Worker _isSymLinkCreated = _link.IsSymLink();
1428*f6dc9357SAndroid Build Coastguard Worker SetAttrib();
1429*f6dc9357SAndroid Build Coastguard Worker // printf("\nlinkWasSet %s\n", GetAnsiString(_diskFilePath));
1430*f6dc9357SAndroid Build Coastguard Worker }
1431*f6dc9357SAndroid Build Coastguard Worker }
1432*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
1433*f6dc9357SAndroid Build Coastguard Worker
1434*f6dc9357SAndroid Build Coastguard Worker // if (_copyFile_Path.IsEmpty())
1435*f6dc9357SAndroid Build Coastguard Worker {
1436*f6dc9357SAndroid Build Coastguard Worker needExit = false;
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 if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream && !_item.IsDir)
1442*f6dc9357SAndroid Build Coastguard Worker {
1443*f6dc9357SAndroid Build Coastguard Worker CHardLinkNode h;
1444*f6dc9357SAndroid Build Coastguard Worker bool defined;
1445*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_Get_HardLinkNode(archive, index, h, defined))
1446*f6dc9357SAndroid Build Coastguard Worker if (defined)
1447*f6dc9357SAndroid Build Coastguard Worker {
1448*f6dc9357SAndroid Build Coastguard Worker const int linkIndex = _hardLinks.IDs.FindInSorted2(h);
1449*f6dc9357SAndroid Build Coastguard Worker if (linkIndex != -1)
1450*f6dc9357SAndroid Build Coastguard Worker {
1451*f6dc9357SAndroid Build Coastguard Worker FString &hl = _hardLinks.Links[(unsigned)linkIndex];
1452*f6dc9357SAndroid Build Coastguard Worker if (hl.IsEmpty())
1453*f6dc9357SAndroid Build Coastguard Worker hl = fullProcessedPath;
1454*f6dc9357SAndroid Build Coastguard Worker else
1455*f6dc9357SAndroid Build Coastguard Worker {
1456*f6dc9357SAndroid Build Coastguard Worker if (!MyCreateHardLink(fullProcessedPath, hl))
1457*f6dc9357SAndroid Build Coastguard Worker {
1458*f6dc9357SAndroid Build Coastguard Worker const HRESULT errorCode = GetLastError_noZero_HRESULT();
1459*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError2(errorCode, kCantCreateHardLink, fullProcessedPath, hl))
1460*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1461*f6dc9357SAndroid Build Coastguard Worker }
1462*f6dc9357SAndroid Build Coastguard Worker
1463*f6dc9357SAndroid Build Coastguard Worker // printf("\nHard linkWasSet Archive_Get_HardLinkNode %s\n", GetAnsiString(_diskFilePath));
1464*f6dc9357SAndroid Build Coastguard Worker // _needSetAttrib = true; // do we need to set attribute ?
1465*f6dc9357SAndroid Build Coastguard Worker SetAttrib();
1466*f6dc9357SAndroid Build Coastguard Worker needExit = false;
1467*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1468*f6dc9357SAndroid Build Coastguard Worker }
1469*f6dc9357SAndroid Build Coastguard Worker }
1470*f6dc9357SAndroid Build Coastguard Worker }
1471*f6dc9357SAndroid Build Coastguard Worker }
1472*f6dc9357SAndroid Build Coastguard Worker
1473*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_LINKS
1474*f6dc9357SAndroid Build Coastguard Worker
1475*f6dc9357SAndroid Build Coastguard Worker
1476*f6dc9357SAndroid Build Coastguard Worker // ---------- CREATE WRITE FILE -----
1477*f6dc9357SAndroid Build Coastguard Worker
1478*f6dc9357SAndroid Build Coastguard Worker _outFileStreamSpec = new COutFileStream;
1479*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IOutStream> outFileStream_Loc(_outFileStreamSpec);
1480*f6dc9357SAndroid Build Coastguard Worker
1481*f6dc9357SAndroid Build Coastguard Worker if (!_outFileStreamSpec->Create_ALWAYS_or_Open_ALWAYS(fullProcessedPath, !_isSplit))
1482*f6dc9357SAndroid Build Coastguard Worker {
1483*f6dc9357SAndroid Build Coastguard Worker // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
1484*f6dc9357SAndroid Build Coastguard Worker {
1485*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError(kCantOpenOutFile, fullProcessedPath))
1486*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1487*f6dc9357SAndroid Build Coastguard Worker }
1488*f6dc9357SAndroid Build Coastguard Worker }
1489*f6dc9357SAndroid Build Coastguard Worker
1490*f6dc9357SAndroid Build Coastguard Worker _needSetAttrib = true;
1491*f6dc9357SAndroid Build Coastguard Worker
1492*f6dc9357SAndroid Build Coastguard Worker bool is_SymLink_in_Data = false;
1493*f6dc9357SAndroid Build Coastguard Worker
1494*f6dc9357SAndroid Build Coastguard Worker if (_curSize_Defined && _curSize > 0 && _curSize < (1 << 12))
1495*f6dc9357SAndroid Build Coastguard Worker {
1496*f6dc9357SAndroid Build Coastguard Worker if (_fi.IsLinuxSymLink())
1497*f6dc9357SAndroid Build Coastguard Worker {
1498*f6dc9357SAndroid Build Coastguard Worker is_SymLink_in_Data = true;
1499*f6dc9357SAndroid Build Coastguard Worker _is_SymLink_in_Data_Linux = true;
1500*f6dc9357SAndroid Build Coastguard Worker }
1501*f6dc9357SAndroid Build Coastguard Worker else if (_fi.IsReparse())
1502*f6dc9357SAndroid Build Coastguard Worker {
1503*f6dc9357SAndroid Build Coastguard Worker is_SymLink_in_Data = true;
1504*f6dc9357SAndroid Build Coastguard Worker _is_SymLink_in_Data_Linux = false;
1505*f6dc9357SAndroid Build Coastguard Worker }
1506*f6dc9357SAndroid Build Coastguard Worker }
1507*f6dc9357SAndroid Build Coastguard Worker
1508*f6dc9357SAndroid Build Coastguard Worker if (is_SymLink_in_Data)
1509*f6dc9357SAndroid Build Coastguard Worker {
1510*f6dc9357SAndroid Build Coastguard Worker _outMemBuf.Alloc((size_t)_curSize);
1511*f6dc9357SAndroid Build Coastguard Worker _bufPtrSeqOutStream_Spec = new CBufPtrSeqOutStream;
1512*f6dc9357SAndroid Build Coastguard Worker _bufPtrSeqOutStream = _bufPtrSeqOutStream_Spec;
1513*f6dc9357SAndroid Build Coastguard Worker _bufPtrSeqOutStream_Spec->Init(_outMemBuf, _outMemBuf.Size());
1514*f6dc9357SAndroid Build Coastguard Worker outStreamLoc = _bufPtrSeqOutStream;
1515*f6dc9357SAndroid Build Coastguard Worker }
1516*f6dc9357SAndroid Build Coastguard Worker else // not reprase
1517*f6dc9357SAndroid Build Coastguard Worker {
1518*f6dc9357SAndroid Build Coastguard Worker if (_ntOptions.PreAllocateOutFile && !_isSplit && _curSize_Defined && _curSize > (1 << 12))
1519*f6dc9357SAndroid Build Coastguard Worker {
1520*f6dc9357SAndroid Build Coastguard Worker // UInt64 ticks = GetCpuTicks();
1521*f6dc9357SAndroid Build Coastguard Worker _fileLength_that_WasSet = _curSize;
1522*f6dc9357SAndroid Build Coastguard Worker bool res = _outFileStreamSpec->File.SetLength(_curSize);
1523*f6dc9357SAndroid Build Coastguard Worker _fileLength_WasSet = res;
1524*f6dc9357SAndroid Build Coastguard Worker
1525*f6dc9357SAndroid Build Coastguard Worker // ticks = GetCpuTicks() - ticks;
1526*f6dc9357SAndroid Build Coastguard Worker // printf("\nticks = %10d\n", (unsigned)ticks);
1527*f6dc9357SAndroid Build Coastguard Worker if (!res)
1528*f6dc9357SAndroid Build Coastguard Worker {
1529*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath))
1530*f6dc9357SAndroid Build Coastguard Worker }
1531*f6dc9357SAndroid Build Coastguard Worker
1532*f6dc9357SAndroid Build Coastguard Worker /*
1533*f6dc9357SAndroid Build Coastguard Worker _outFileStreamSpec->File.Close();
1534*f6dc9357SAndroid Build Coastguard Worker ticks = GetCpuTicks() - ticks;
1535*f6dc9357SAndroid Build Coastguard Worker printf("\nticks = %10d\n", (unsigned)ticks);
1536*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1537*f6dc9357SAndroid Build Coastguard Worker */
1538*f6dc9357SAndroid Build Coastguard Worker
1539*f6dc9357SAndroid Build Coastguard Worker /*
1540*f6dc9357SAndroid Build Coastguard Worker File.SetLength() on FAT (xp64): is fast, but then File.Close() can be slow,
1541*f6dc9357SAndroid Build Coastguard Worker if we don't write any data.
1542*f6dc9357SAndroid Build Coastguard Worker File.SetLength() for remote share file (exFAT) can be slow in some cases,
1543*f6dc9357SAndroid Build Coastguard Worker and the Windows can return "network error" after 1 minute,
1544*f6dc9357SAndroid Build Coastguard Worker while remote file still can grow.
1545*f6dc9357SAndroid Build Coastguard Worker We need some way to detect such bad cases and disable PreAllocateOutFile mode.
1546*f6dc9357SAndroid Build Coastguard Worker */
1547*f6dc9357SAndroid Build Coastguard Worker
1548*f6dc9357SAndroid Build Coastguard Worker res = _outFileStreamSpec->SeekToBegin_bool();
1549*f6dc9357SAndroid Build Coastguard Worker if (!res)
1550*f6dc9357SAndroid Build Coastguard Worker {
1551*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError("Cannot seek to begin of file", fullProcessedPath))
1552*f6dc9357SAndroid Build Coastguard Worker }
1553*f6dc9357SAndroid Build Coastguard Worker } // PreAllocateOutFile
1554*f6dc9357SAndroid Build Coastguard Worker
1555*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1556*f6dc9357SAndroid Build Coastguard Worker if (_isRenamed && !_item.IsAltStream)
1557*f6dc9357SAndroid Build Coastguard Worker {
1558*f6dc9357SAndroid Build Coastguard Worker CIndexToPathPair pair(index, fullProcessedPath);
1559*f6dc9357SAndroid Build Coastguard Worker unsigned oldSize = _renamedFiles.Size();
1560*f6dc9357SAndroid Build Coastguard Worker unsigned insertIndex = _renamedFiles.AddToUniqueSorted(pair);
1561*f6dc9357SAndroid Build Coastguard Worker if (oldSize == _renamedFiles.Size())
1562*f6dc9357SAndroid Build Coastguard Worker _renamedFiles[insertIndex].Path = fullProcessedPath;
1563*f6dc9357SAndroid Build Coastguard Worker }
1564*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_ALT_STREAMS
1565*f6dc9357SAndroid Build Coastguard Worker
1566*f6dc9357SAndroid Build Coastguard Worker if (_isSplit)
1567*f6dc9357SAndroid Build Coastguard Worker {
1568*f6dc9357SAndroid Build Coastguard Worker RINOK(outFileStream_Loc->Seek((Int64)_position, STREAM_SEEK_SET, NULL))
1569*f6dc9357SAndroid Build Coastguard Worker }
1570*f6dc9357SAndroid Build Coastguard Worker outStreamLoc = outFileStream_Loc;
1571*f6dc9357SAndroid Build Coastguard Worker } // if not reprase
1572*f6dc9357SAndroid Build Coastguard Worker
1573*f6dc9357SAndroid Build Coastguard Worker _outFileStream = outFileStream_Loc;
1574*f6dc9357SAndroid Build Coastguard Worker
1575*f6dc9357SAndroid Build Coastguard Worker needExit = false;
1576*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1577*f6dc9357SAndroid Build Coastguard Worker }
1578*f6dc9357SAndroid Build Coastguard Worker
1579*f6dc9357SAndroid Build Coastguard Worker
1580*f6dc9357SAndroid Build Coastguard Worker
1581*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::GetItem(UInt32 index)
1582*f6dc9357SAndroid Build Coastguard Worker {
1583*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
1584*f6dc9357SAndroid Build Coastguard Worker _item._use_baseParentFolder_mode = _use_baseParentFolder_mode;
1585*f6dc9357SAndroid Build Coastguard Worker if (_use_baseParentFolder_mode)
1586*f6dc9357SAndroid Build Coastguard Worker {
1587*f6dc9357SAndroid Build Coastguard Worker _item._baseParentFolder = (int)_baseParentFolder;
1588*f6dc9357SAndroid Build Coastguard Worker if (_pathMode == NExtract::NPathMode::kFullPaths ||
1589*f6dc9357SAndroid Build Coastguard Worker _pathMode == NExtract::NPathMode::kAbsPaths)
1590*f6dc9357SAndroid Build Coastguard Worker _item._baseParentFolder = -1;
1591*f6dc9357SAndroid Build Coastguard Worker }
1592*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
1593*f6dc9357SAndroid Build Coastguard Worker
1594*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1595*f6dc9357SAndroid Build Coastguard Worker _item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon;
1596*f6dc9357SAndroid Build Coastguard Worker #endif
1597*f6dc9357SAndroid Build Coastguard Worker
1598*f6dc9357SAndroid Build Coastguard Worker return _arc->GetItem(index, _item);
1599*f6dc9357SAndroid Build Coastguard Worker }
1600*f6dc9357SAndroid Build Coastguard Worker
1601*f6dc9357SAndroid Build Coastguard Worker
1602*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode))
1603*f6dc9357SAndroid Build Coastguard Worker {
1604*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
1605*f6dc9357SAndroid Build Coastguard Worker
1606*f6dc9357SAndroid Build Coastguard Worker *outStream = NULL;
1607*f6dc9357SAndroid Build Coastguard Worker
1608*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
1609*f6dc9357SAndroid Build Coastguard Worker if (_hashStream)
1610*f6dc9357SAndroid Build Coastguard Worker _hashStreamSpec->ReleaseStream();
1611*f6dc9357SAndroid Build Coastguard Worker _hashStreamWasUsed = false;
1612*f6dc9357SAndroid Build Coastguard Worker #endif
1613*f6dc9357SAndroid Build Coastguard Worker
1614*f6dc9357SAndroid Build Coastguard Worker _outFileStream.Release();
1615*f6dc9357SAndroid Build Coastguard Worker _bufPtrSeqOutStream.Release();
1616*f6dc9357SAndroid Build Coastguard Worker
1617*f6dc9357SAndroid Build Coastguard Worker _encrypted = false;
1618*f6dc9357SAndroid Build Coastguard Worker _isSplit = false;
1619*f6dc9357SAndroid Build Coastguard Worker _curSize_Defined = false;
1620*f6dc9357SAndroid Build Coastguard Worker _fileLength_WasSet = false;
1621*f6dc9357SAndroid Build Coastguard Worker _isRenamed = false;
1622*f6dc9357SAndroid Build Coastguard Worker // _fi.Clear();
1623*f6dc9357SAndroid Build Coastguard Worker _extractMode = false;
1624*f6dc9357SAndroid Build Coastguard Worker // _is_SymLink_in_Data = false;
1625*f6dc9357SAndroid Build Coastguard Worker _is_SymLink_in_Data_Linux = false;
1626*f6dc9357SAndroid Build Coastguard Worker _needSetAttrib = false;
1627*f6dc9357SAndroid Build Coastguard Worker _isSymLinkCreated = false;
1628*f6dc9357SAndroid Build Coastguard Worker _itemFailure = false;
1629*f6dc9357SAndroid Build Coastguard Worker _some_pathParts_wereRemoved = false;
1630*f6dc9357SAndroid Build Coastguard Worker // _op_WasReported = false;
1631*f6dc9357SAndroid Build Coastguard Worker
1632*f6dc9357SAndroid Build Coastguard Worker _position = 0;
1633*f6dc9357SAndroid Build Coastguard Worker _curSize = 0;
1634*f6dc9357SAndroid Build Coastguard Worker _fileLength_that_WasSet = 0;
1635*f6dc9357SAndroid Build Coastguard Worker _index = index;
1636*f6dc9357SAndroid Build Coastguard Worker
1637*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
1638*f6dc9357SAndroid Build Coastguard Worker _altStream_NeedRestore_AttribVal = 0;
1639*f6dc9357SAndroid Build Coastguard Worker _altStream_NeedRestore_Attrib_for_parentFsPath.Empty();
1640*f6dc9357SAndroid Build Coastguard Worker #endif
1641*f6dc9357SAndroid Build Coastguard Worker
1642*f6dc9357SAndroid Build Coastguard Worker _diskFilePath.Empty();
1643*f6dc9357SAndroid Build Coastguard Worker
1644*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
1645*f6dc9357SAndroid Build Coastguard Worker // _copyFile_Path.Empty();
1646*f6dc9357SAndroid Build Coastguard Worker _link.Clear();
1647*f6dc9357SAndroid Build Coastguard Worker #endif
1648*f6dc9357SAndroid Build Coastguard Worker
1649*f6dc9357SAndroid Build Coastguard Worker
1650*f6dc9357SAndroid Build Coastguard Worker switch (askExtractMode)
1651*f6dc9357SAndroid Build Coastguard Worker {
1652*f6dc9357SAndroid Build Coastguard Worker case NArchive::NExtract::NAskMode::kExtract:
1653*f6dc9357SAndroid Build Coastguard Worker if (_testMode)
1654*f6dc9357SAndroid Build Coastguard Worker {
1655*f6dc9357SAndroid Build Coastguard Worker // askExtractMode = NArchive::NExtract::NAskMode::kTest;
1656*f6dc9357SAndroid Build Coastguard Worker }
1657*f6dc9357SAndroid Build Coastguard Worker else
1658*f6dc9357SAndroid Build Coastguard Worker _extractMode = true;
1659*f6dc9357SAndroid Build Coastguard Worker break;
1660*f6dc9357SAndroid Build Coastguard Worker default: break;
1661*f6dc9357SAndroid Build Coastguard Worker }
1662*f6dc9357SAndroid Build Coastguard Worker
1663*f6dc9357SAndroid Build Coastguard Worker
1664*f6dc9357SAndroid Build Coastguard Worker IInArchive *archive = _arc->Archive;
1665*f6dc9357SAndroid Build Coastguard Worker
1666*f6dc9357SAndroid Build Coastguard Worker RINOK(GetItem(index))
1667*f6dc9357SAndroid Build Coastguard Worker
1668*f6dc9357SAndroid Build Coastguard Worker {
1669*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
1670*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetProperty(index, kpidPosition, &prop))
1671*f6dc9357SAndroid Build Coastguard Worker if (prop.vt != VT_EMPTY)
1672*f6dc9357SAndroid Build Coastguard Worker {
1673*f6dc9357SAndroid Build Coastguard Worker if (prop.vt != VT_UI8)
1674*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1675*f6dc9357SAndroid Build Coastguard Worker _position = prop.uhVal.QuadPart;
1676*f6dc9357SAndroid Build Coastguard Worker _isSplit = true;
1677*f6dc9357SAndroid Build Coastguard Worker }
1678*f6dc9357SAndroid Build Coastguard Worker }
1679*f6dc9357SAndroid Build Coastguard Worker
1680*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
1681*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadLink())
1682*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_LINKS
1683*f6dc9357SAndroid Build Coastguard Worker
1684*f6dc9357SAndroid Build Coastguard Worker
1685*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted))
1686*f6dc9357SAndroid Build Coastguard Worker
1687*f6dc9357SAndroid Build Coastguard Worker RINOK(GetUnpackSize())
1688*f6dc9357SAndroid Build Coastguard Worker
1689*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1690*f6dc9357SAndroid Build Coastguard Worker if (!_ntOptions.AltStreams.Val && _item.IsAltStream)
1691*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1692*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_ALT_STREAMS
1693*f6dc9357SAndroid Build Coastguard Worker
1694*f6dc9357SAndroid Build Coastguard Worker // we can change (_item.PathParts) in this function
1695*f6dc9357SAndroid Build Coastguard Worker UStringVector &pathParts = _item.PathParts;
1696*f6dc9357SAndroid Build Coastguard Worker
1697*f6dc9357SAndroid Build Coastguard Worker if (_wildcardCensor)
1698*f6dc9357SAndroid Build Coastguard Worker {
1699*f6dc9357SAndroid Build Coastguard Worker if (!CensorNode_CheckPath(*_wildcardCensor, _item))
1700*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1701*f6dc9357SAndroid Build Coastguard Worker }
1702*f6dc9357SAndroid Build Coastguard Worker
1703*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
1704*f6dc9357SAndroid Build Coastguard Worker if (askExtractMode == NArchive::NExtract::NAskMode::kExtract
1705*f6dc9357SAndroid Build Coastguard Worker && !_testMode
1706*f6dc9357SAndroid Build Coastguard Worker && _item.IsAltStream
1707*f6dc9357SAndroid Build Coastguard Worker && ZoneBuf.Size() != 0
1708*f6dc9357SAndroid Build Coastguard Worker && Is_ZoneId_StreamName(_item.AltStreamName))
1709*f6dc9357SAndroid Build Coastguard Worker if (ZoneMode != NExtract::NZoneIdMode::kOffice
1710*f6dc9357SAndroid Build Coastguard Worker || _item.PathParts.IsEmpty()
1711*f6dc9357SAndroid Build Coastguard Worker || FindExt2(kOfficeExtensions, _item.PathParts.Back()))
1712*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1713*f6dc9357SAndroid Build Coastguard Worker #endif
1714*f6dc9357SAndroid Build Coastguard Worker
1715*f6dc9357SAndroid Build Coastguard Worker
1716*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
1717*f6dc9357SAndroid Build Coastguard Worker if (_use_baseParentFolder_mode)
1718*f6dc9357SAndroid Build Coastguard Worker {
1719*f6dc9357SAndroid Build Coastguard Worker if (!pathParts.IsEmpty())
1720*f6dc9357SAndroid Build Coastguard Worker {
1721*f6dc9357SAndroid Build Coastguard Worker unsigned numRemovePathParts = 0;
1722*f6dc9357SAndroid Build Coastguard Worker
1723*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1724*f6dc9357SAndroid Build Coastguard Worker if (_pathMode == NExtract::NPathMode::kNoPathsAlt && _item.IsAltStream)
1725*f6dc9357SAndroid Build Coastguard Worker numRemovePathParts = pathParts.Size();
1726*f6dc9357SAndroid Build Coastguard Worker else
1727*f6dc9357SAndroid Build Coastguard Worker #endif
1728*f6dc9357SAndroid Build Coastguard Worker if (_pathMode == NExtract::NPathMode::kNoPaths ||
1729*f6dc9357SAndroid Build Coastguard Worker _pathMode == NExtract::NPathMode::kNoPathsAlt)
1730*f6dc9357SAndroid Build Coastguard Worker numRemovePathParts = pathParts.Size() - 1;
1731*f6dc9357SAndroid Build Coastguard Worker pathParts.DeleteFrontal(numRemovePathParts);
1732*f6dc9357SAndroid Build Coastguard Worker }
1733*f6dc9357SAndroid Build Coastguard Worker }
1734*f6dc9357SAndroid Build Coastguard Worker else
1735*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
1736*f6dc9357SAndroid Build Coastguard Worker {
1737*f6dc9357SAndroid Build Coastguard Worker if (pathParts.IsEmpty())
1738*f6dc9357SAndroid Build Coastguard Worker {
1739*f6dc9357SAndroid Build Coastguard Worker if (_item.IsDir)
1740*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1741*f6dc9357SAndroid Build Coastguard Worker /*
1742*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1743*f6dc9357SAndroid Build Coastguard Worker if (!_item.IsAltStream)
1744*f6dc9357SAndroid Build Coastguard Worker #endif
1745*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1746*f6dc9357SAndroid Build Coastguard Worker */
1747*f6dc9357SAndroid Build Coastguard Worker }
1748*f6dc9357SAndroid Build Coastguard Worker
1749*f6dc9357SAndroid Build Coastguard Worker unsigned numRemovePathParts = 0;
1750*f6dc9357SAndroid Build Coastguard Worker
1751*f6dc9357SAndroid Build Coastguard Worker switch ((int)_pathMode)
1752*f6dc9357SAndroid Build Coastguard Worker {
1753*f6dc9357SAndroid Build Coastguard Worker case NExtract::NPathMode::kFullPaths:
1754*f6dc9357SAndroid Build Coastguard Worker case NExtract::NPathMode::kCurPaths:
1755*f6dc9357SAndroid Build Coastguard Worker {
1756*f6dc9357SAndroid Build Coastguard Worker if (_removePathParts.IsEmpty())
1757*f6dc9357SAndroid Build Coastguard Worker break;
1758*f6dc9357SAndroid Build Coastguard Worker bool badPrefix = false;
1759*f6dc9357SAndroid Build Coastguard Worker
1760*f6dc9357SAndroid Build Coastguard Worker if (pathParts.Size() < _removePathParts.Size())
1761*f6dc9357SAndroid Build Coastguard Worker badPrefix = true;
1762*f6dc9357SAndroid Build Coastguard Worker else
1763*f6dc9357SAndroid Build Coastguard Worker {
1764*f6dc9357SAndroid Build Coastguard Worker if (pathParts.Size() == _removePathParts.Size())
1765*f6dc9357SAndroid Build Coastguard Worker {
1766*f6dc9357SAndroid Build Coastguard Worker if (_removePartsForAltStreams)
1767*f6dc9357SAndroid Build Coastguard Worker {
1768*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1769*f6dc9357SAndroid Build Coastguard Worker if (!_item.IsAltStream)
1770*f6dc9357SAndroid Build Coastguard Worker #endif
1771*f6dc9357SAndroid Build Coastguard Worker badPrefix = true;
1772*f6dc9357SAndroid Build Coastguard Worker }
1773*f6dc9357SAndroid Build Coastguard Worker else
1774*f6dc9357SAndroid Build Coastguard Worker {
1775*f6dc9357SAndroid Build Coastguard Worker if (!_item.MainIsDir)
1776*f6dc9357SAndroid Build Coastguard Worker badPrefix = true;
1777*f6dc9357SAndroid Build Coastguard Worker }
1778*f6dc9357SAndroid Build Coastguard Worker }
1779*f6dc9357SAndroid Build Coastguard Worker
1780*f6dc9357SAndroid Build Coastguard Worker if (!badPrefix)
1781*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, _removePathParts)
1782*f6dc9357SAndroid Build Coastguard Worker {
1783*f6dc9357SAndroid Build Coastguard Worker if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0)
1784*f6dc9357SAndroid Build Coastguard Worker {
1785*f6dc9357SAndroid Build Coastguard Worker badPrefix = true;
1786*f6dc9357SAndroid Build Coastguard Worker break;
1787*f6dc9357SAndroid Build Coastguard Worker }
1788*f6dc9357SAndroid Build Coastguard Worker }
1789*f6dc9357SAndroid Build Coastguard Worker }
1790*f6dc9357SAndroid Build Coastguard Worker
1791*f6dc9357SAndroid Build Coastguard Worker if (badPrefix)
1792*f6dc9357SAndroid Build Coastguard Worker {
1793*f6dc9357SAndroid Build Coastguard Worker if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
1794*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1795*f6dc9357SAndroid Build Coastguard Worker }
1796*f6dc9357SAndroid Build Coastguard Worker else
1797*f6dc9357SAndroid Build Coastguard Worker {
1798*f6dc9357SAndroid Build Coastguard Worker numRemovePathParts = _removePathParts.Size();
1799*f6dc9357SAndroid Build Coastguard Worker _some_pathParts_wereRemoved = true;
1800*f6dc9357SAndroid Build Coastguard Worker }
1801*f6dc9357SAndroid Build Coastguard Worker break;
1802*f6dc9357SAndroid Build Coastguard Worker }
1803*f6dc9357SAndroid Build Coastguard Worker
1804*f6dc9357SAndroid Build Coastguard Worker case NExtract::NPathMode::kNoPaths:
1805*f6dc9357SAndroid Build Coastguard Worker {
1806*f6dc9357SAndroid Build Coastguard Worker if (!pathParts.IsEmpty())
1807*f6dc9357SAndroid Build Coastguard Worker numRemovePathParts = pathParts.Size() - 1;
1808*f6dc9357SAndroid Build Coastguard Worker break;
1809*f6dc9357SAndroid Build Coastguard Worker }
1810*f6dc9357SAndroid Build Coastguard Worker case NExtract::NPathMode::kNoPathsAlt:
1811*f6dc9357SAndroid Build Coastguard Worker {
1812*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1813*f6dc9357SAndroid Build Coastguard Worker if (_item.IsAltStream)
1814*f6dc9357SAndroid Build Coastguard Worker numRemovePathParts = pathParts.Size();
1815*f6dc9357SAndroid Build Coastguard Worker else
1816*f6dc9357SAndroid Build Coastguard Worker #endif
1817*f6dc9357SAndroid Build Coastguard Worker if (!pathParts.IsEmpty())
1818*f6dc9357SAndroid Build Coastguard Worker numRemovePathParts = pathParts.Size() - 1;
1819*f6dc9357SAndroid Build Coastguard Worker break;
1820*f6dc9357SAndroid Build Coastguard Worker }
1821*f6dc9357SAndroid Build Coastguard Worker case NExtract::NPathMode::kAbsPaths:
1822*f6dc9357SAndroid Build Coastguard Worker default:
1823*f6dc9357SAndroid Build Coastguard Worker break;
1824*f6dc9357SAndroid Build Coastguard Worker }
1825*f6dc9357SAndroid Build Coastguard Worker
1826*f6dc9357SAndroid Build Coastguard Worker pathParts.DeleteFrontal(numRemovePathParts);
1827*f6dc9357SAndroid Build Coastguard Worker }
1828*f6dc9357SAndroid Build Coastguard Worker
1829*f6dc9357SAndroid Build Coastguard Worker
1830*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
1831*f6dc9357SAndroid Build Coastguard Worker
1832*f6dc9357SAndroid Build Coastguard Worker if (ExtractToStreamCallback)
1833*f6dc9357SAndroid Build Coastguard Worker {
1834*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<IGetProp, CGetProp> GetProp;
1835*f6dc9357SAndroid Build Coastguard Worker GetProp->Arc = _arc;
1836*f6dc9357SAndroid Build Coastguard Worker GetProp->IndexInArc = index;
1837*f6dc9357SAndroid Build Coastguard Worker UString name (MakePathFromParts(pathParts));
1838*f6dc9357SAndroid Build Coastguard Worker // GetProp->BaseName = name;
1839*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
1840*f6dc9357SAndroid Build Coastguard Worker if (_item.IsAltStream)
1841*f6dc9357SAndroid Build Coastguard Worker {
1842*f6dc9357SAndroid Build Coastguard Worker if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt))
1843*f6dc9357SAndroid Build Coastguard Worker name.Add_Colon();
1844*f6dc9357SAndroid Build Coastguard Worker name += _item.AltStreamName;
1845*f6dc9357SAndroid Build Coastguard Worker }
1846*f6dc9357SAndroid Build Coastguard Worker #endif
1847*f6dc9357SAndroid Build Coastguard Worker
1848*f6dc9357SAndroid Build Coastguard Worker return ExtractToStreamCallback->GetStream7(name, BoolToInt(_item.IsDir), outStream, askExtractMode, GetProp);
1849*f6dc9357SAndroid Build Coastguard Worker }
1850*f6dc9357SAndroid Build Coastguard Worker
1851*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
1852*f6dc9357SAndroid Build Coastguard Worker
1853*f6dc9357SAndroid Build Coastguard Worker
1854*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> outStreamLoc;
1855*f6dc9357SAndroid Build Coastguard Worker
1856*f6dc9357SAndroid Build Coastguard Worker if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
1857*f6dc9357SAndroid Build Coastguard Worker {
1858*f6dc9357SAndroid Build Coastguard Worker if (_stdOutMode)
1859*f6dc9357SAndroid Build Coastguard Worker outStreamLoc = new CStdOutFileStream;
1860*f6dc9357SAndroid Build Coastguard Worker else
1861*f6dc9357SAndroid Build Coastguard Worker {
1862*f6dc9357SAndroid Build Coastguard Worker bool needExit = true;
1863*f6dc9357SAndroid Build Coastguard Worker RINOK(GetExtractStream(outStreamLoc, needExit))
1864*f6dc9357SAndroid Build Coastguard Worker if (needExit)
1865*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1866*f6dc9357SAndroid Build Coastguard Worker }
1867*f6dc9357SAndroid Build Coastguard Worker }
1868*f6dc9357SAndroid Build Coastguard Worker
1869*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
1870*f6dc9357SAndroid Build Coastguard Worker if (_hashStream)
1871*f6dc9357SAndroid Build Coastguard Worker {
1872*f6dc9357SAndroid Build Coastguard Worker if (askExtractMode == NArchive::NExtract::NAskMode::kExtract ||
1873*f6dc9357SAndroid Build Coastguard Worker askExtractMode == NArchive::NExtract::NAskMode::kTest)
1874*f6dc9357SAndroid Build Coastguard Worker {
1875*f6dc9357SAndroid Build Coastguard Worker _hashStreamSpec->SetStream(outStreamLoc);
1876*f6dc9357SAndroid Build Coastguard Worker outStreamLoc = _hashStream;
1877*f6dc9357SAndroid Build Coastguard Worker _hashStreamSpec->Init(true);
1878*f6dc9357SAndroid Build Coastguard Worker _hashStreamWasUsed = true;
1879*f6dc9357SAndroid Build Coastguard Worker }
1880*f6dc9357SAndroid Build Coastguard Worker }
1881*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
1882*f6dc9357SAndroid Build Coastguard Worker
1883*f6dc9357SAndroid Build Coastguard Worker if (outStreamLoc)
1884*f6dc9357SAndroid Build Coastguard Worker {
1885*f6dc9357SAndroid Build Coastguard Worker /*
1886*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
1887*f6dc9357SAndroid Build Coastguard Worker if (!_copyFile_Path.IsEmpty())
1888*f6dc9357SAndroid Build Coastguard Worker {
1889*f6dc9357SAndroid Build Coastguard Worker RINOK(PrepareOperation(askExtractMode));
1890*f6dc9357SAndroid Build Coastguard Worker RINOK(MyCopyFile(outStreamLoc));
1891*f6dc9357SAndroid Build Coastguard Worker return SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
1892*f6dc9357SAndroid Build Coastguard Worker }
1893*f6dc9357SAndroid Build Coastguard Worker if (_link.isCopyLink && _testMode)
1894*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1895*f6dc9357SAndroid Build Coastguard Worker #endif
1896*f6dc9357SAndroid Build Coastguard Worker */
1897*f6dc9357SAndroid Build Coastguard Worker *outStream = outStreamLoc.Detach();
1898*f6dc9357SAndroid Build Coastguard Worker }
1899*f6dc9357SAndroid Build Coastguard Worker
1900*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1901*f6dc9357SAndroid Build Coastguard Worker
1902*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1903*f6dc9357SAndroid Build Coastguard Worker }
1904*f6dc9357SAndroid Build Coastguard Worker
1905*f6dc9357SAndroid Build Coastguard Worker
1906*f6dc9357SAndroid Build Coastguard Worker
1907*f6dc9357SAndroid Build Coastguard Worker
1908*f6dc9357SAndroid Build Coastguard Worker
1909*f6dc9357SAndroid Build Coastguard Worker
1910*f6dc9357SAndroid Build Coastguard Worker
1911*f6dc9357SAndroid Build Coastguard Worker
1912*f6dc9357SAndroid Build Coastguard Worker
1913*f6dc9357SAndroid Build Coastguard Worker
1914*f6dc9357SAndroid Build Coastguard Worker
1915*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode))
1916*f6dc9357SAndroid Build Coastguard Worker {
1917*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
1918*f6dc9357SAndroid Build Coastguard Worker
1919*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
1920*f6dc9357SAndroid Build Coastguard Worker // if (!_op_WasReported)
1921*f6dc9357SAndroid Build Coastguard Worker if (ExtractToStreamCallback)
1922*f6dc9357SAndroid Build Coastguard Worker return ExtractToStreamCallback->PrepareOperation7(askExtractMode);
1923*f6dc9357SAndroid Build Coastguard Worker #endif
1924*f6dc9357SAndroid Build Coastguard Worker
1925*f6dc9357SAndroid Build Coastguard Worker _extractMode = false;
1926*f6dc9357SAndroid Build Coastguard Worker
1927*f6dc9357SAndroid Build Coastguard Worker switch (askExtractMode)
1928*f6dc9357SAndroid Build Coastguard Worker {
1929*f6dc9357SAndroid Build Coastguard Worker case NArchive::NExtract::NAskMode::kExtract:
1930*f6dc9357SAndroid Build Coastguard Worker if (_testMode)
1931*f6dc9357SAndroid Build Coastguard Worker askExtractMode = NArchive::NExtract::NAskMode::kTest;
1932*f6dc9357SAndroid Build Coastguard Worker else
1933*f6dc9357SAndroid Build Coastguard Worker _extractMode = true;
1934*f6dc9357SAndroid Build Coastguard Worker break;
1935*f6dc9357SAndroid Build Coastguard Worker default: break;
1936*f6dc9357SAndroid Build Coastguard Worker }
1937*f6dc9357SAndroid Build Coastguard Worker
1938*f6dc9357SAndroid Build Coastguard Worker // if (_op_WasReported) return S_OK;
1939*f6dc9357SAndroid Build Coastguard Worker
1940*f6dc9357SAndroid Build Coastguard Worker return _extractCallback2->PrepareOperation(_item.Path, BoolToInt(_item.IsDir),
1941*f6dc9357SAndroid Build Coastguard Worker askExtractMode, _isSplit ? &_position: NULL);
1942*f6dc9357SAndroid Build Coastguard Worker
1943*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1944*f6dc9357SAndroid Build Coastguard Worker }
1945*f6dc9357SAndroid Build Coastguard Worker
1946*f6dc9357SAndroid Build Coastguard Worker
1947*f6dc9357SAndroid Build Coastguard Worker
1948*f6dc9357SAndroid Build Coastguard Worker
1949*f6dc9357SAndroid Build Coastguard Worker
1950*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::CloseFile()
1951*f6dc9357SAndroid Build Coastguard Worker {
1952*f6dc9357SAndroid Build Coastguard Worker if (!_outFileStream)
1953*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1954*f6dc9357SAndroid Build Coastguard Worker
1955*f6dc9357SAndroid Build Coastguard Worker HRESULT hres = S_OK;
1956*f6dc9357SAndroid Build Coastguard Worker
1957*f6dc9357SAndroid Build Coastguard Worker const UInt64 processedSize = _outFileStreamSpec->ProcessedSize;
1958*f6dc9357SAndroid Build Coastguard Worker if (_fileLength_WasSet && _fileLength_that_WasSet > processedSize)
1959*f6dc9357SAndroid Build Coastguard Worker {
1960*f6dc9357SAndroid Build Coastguard Worker const bool res = _outFileStreamSpec->File.SetLength(processedSize);
1961*f6dc9357SAndroid Build Coastguard Worker _fileLength_WasSet = res;
1962*f6dc9357SAndroid Build Coastguard Worker if (!res)
1963*f6dc9357SAndroid Build Coastguard Worker {
1964*f6dc9357SAndroid Build Coastguard Worker const HRESULT hres2 = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path));
1965*f6dc9357SAndroid Build Coastguard Worker if (hres == S_OK)
1966*f6dc9357SAndroid Build Coastguard Worker hres = hres2;
1967*f6dc9357SAndroid Build Coastguard Worker }
1968*f6dc9357SAndroid Build Coastguard Worker }
1969*f6dc9357SAndroid Build Coastguard Worker
1970*f6dc9357SAndroid Build Coastguard Worker _curSize = processedSize;
1971*f6dc9357SAndroid Build Coastguard Worker _curSize_Defined = true;
1972*f6dc9357SAndroid Build Coastguard Worker
1973*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
1974*f6dc9357SAndroid Build Coastguard Worker if (ZoneBuf.Size() != 0
1975*f6dc9357SAndroid Build Coastguard Worker && !_item.IsAltStream)
1976*f6dc9357SAndroid Build Coastguard Worker {
1977*f6dc9357SAndroid Build Coastguard Worker // if (NFind::DoesFileExist_Raw(tempFilePath))
1978*f6dc9357SAndroid Build Coastguard Worker if (ZoneMode != NExtract::NZoneIdMode::kOffice ||
1979*f6dc9357SAndroid Build Coastguard Worker FindExt2(kOfficeExtensions, fs2us(_diskFilePath)))
1980*f6dc9357SAndroid Build Coastguard Worker {
1981*f6dc9357SAndroid Build Coastguard Worker // we must write zone file before setting of timestamps
1982*f6dc9357SAndroid Build Coastguard Worker if (!WriteZoneFile_To_BaseFile(_diskFilePath, ZoneBuf))
1983*f6dc9357SAndroid Build Coastguard Worker {
1984*f6dc9357SAndroid Build Coastguard Worker // we can't write it in FAT
1985*f6dc9357SAndroid Build Coastguard Worker // SendMessageError_with_LastError("Can't write Zone.Identifier stream", path);
1986*f6dc9357SAndroid Build Coastguard Worker }
1987*f6dc9357SAndroid Build Coastguard Worker }
1988*f6dc9357SAndroid Build Coastguard Worker }
1989*f6dc9357SAndroid Build Coastguard Worker #endif
1990*f6dc9357SAndroid Build Coastguard Worker
1991*f6dc9357SAndroid Build Coastguard Worker CFiTimesCAM t;
1992*f6dc9357SAndroid Build Coastguard Worker GetFiTimesCAM(t);
1993*f6dc9357SAndroid Build Coastguard Worker
1994*f6dc9357SAndroid Build Coastguard Worker // #ifdef _WIN32
1995*f6dc9357SAndroid Build Coastguard Worker if (t.IsSomeTimeDefined())
1996*f6dc9357SAndroid Build Coastguard Worker _outFileStreamSpec->SetTime(
1997*f6dc9357SAndroid Build Coastguard Worker t.CTime_Defined ? &t.CTime : NULL,
1998*f6dc9357SAndroid Build Coastguard Worker t.ATime_Defined ? &t.ATime : NULL,
1999*f6dc9357SAndroid Build Coastguard Worker t.MTime_Defined ? &t.MTime : NULL);
2000*f6dc9357SAndroid Build Coastguard Worker // #endif
2001*f6dc9357SAndroid Build Coastguard Worker
2002*f6dc9357SAndroid Build Coastguard Worker RINOK(_outFileStreamSpec->Close())
2003*f6dc9357SAndroid Build Coastguard Worker _outFileStream.Release();
2004*f6dc9357SAndroid Build Coastguard Worker
2005*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
2006*f6dc9357SAndroid Build Coastguard Worker if (!_altStream_NeedRestore_Attrib_for_parentFsPath.IsEmpty())
2007*f6dc9357SAndroid Build Coastguard Worker {
2008*f6dc9357SAndroid Build Coastguard Worker SetFileAttrib(_altStream_NeedRestore_Attrib_for_parentFsPath, _altStream_NeedRestore_AttribVal);
2009*f6dc9357SAndroid Build Coastguard Worker _altStream_NeedRestore_Attrib_for_parentFsPath.Empty();
2010*f6dc9357SAndroid Build Coastguard Worker }
2011*f6dc9357SAndroid Build Coastguard Worker #endif
2012*f6dc9357SAndroid Build Coastguard Worker
2013*f6dc9357SAndroid Build Coastguard Worker return hres;
2014*f6dc9357SAndroid Build Coastguard Worker }
2015*f6dc9357SAndroid Build Coastguard Worker
2016*f6dc9357SAndroid Build Coastguard Worker
2017*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
2018*f6dc9357SAndroid Build Coastguard Worker
2019*f6dc9357SAndroid Build Coastguard Worker
2020*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::SetFromLinkPath(
2021*f6dc9357SAndroid Build Coastguard Worker const FString &fullProcessedPath,
2022*f6dc9357SAndroid Build Coastguard Worker const CLinkInfo &linkInfo,
2023*f6dc9357SAndroid Build Coastguard Worker bool &linkWasSet)
2024*f6dc9357SAndroid Build Coastguard Worker {
2025*f6dc9357SAndroid Build Coastguard Worker linkWasSet = false;
2026*f6dc9357SAndroid Build Coastguard Worker if (!_ntOptions.SymLinks.Val && !linkInfo.isHardLink)
2027*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2028*f6dc9357SAndroid Build Coastguard Worker
2029*f6dc9357SAndroid Build Coastguard Worker UString relatPath;
2030*f6dc9357SAndroid Build Coastguard Worker
2031*f6dc9357SAndroid Build Coastguard Worker /* if (linkInfo.isRelative)
2032*f6dc9357SAndroid Build Coastguard Worker linkInfo.linkPath is final link path that must be stored to file link field
2033*f6dc9357SAndroid Build Coastguard Worker else
2034*f6dc9357SAndroid Build Coastguard Worker linkInfo.linkPath is path from root of archive. So we must add _dirPathPrefix_Full before linkPath.
2035*f6dc9357SAndroid Build Coastguard Worker */
2036*f6dc9357SAndroid Build Coastguard Worker
2037*f6dc9357SAndroid Build Coastguard Worker if (linkInfo.isRelative)
2038*f6dc9357SAndroid Build Coastguard Worker relatPath = GetDirPrefixOf(_item.Path);
2039*f6dc9357SAndroid Build Coastguard Worker relatPath += linkInfo.linkPath;
2040*f6dc9357SAndroid Build Coastguard Worker
2041*f6dc9357SAndroid Build Coastguard Worker if (!IsSafePath(relatPath))
2042*f6dc9357SAndroid Build Coastguard Worker {
2043*f6dc9357SAndroid Build Coastguard Worker return SendMessageError2(
2044*f6dc9357SAndroid Build Coastguard Worker 0, // errorCode
2045*f6dc9357SAndroid Build Coastguard Worker "Dangerous link path was ignored",
2046*f6dc9357SAndroid Build Coastguard Worker us2fs(_item.Path),
2047*f6dc9357SAndroid Build Coastguard Worker us2fs(linkInfo.linkPath)); // us2fs(relatPath)
2048*f6dc9357SAndroid Build Coastguard Worker }
2049*f6dc9357SAndroid Build Coastguard Worker
2050*f6dc9357SAndroid Build Coastguard Worker FString existPath;
2051*f6dc9357SAndroid Build Coastguard Worker if (linkInfo.isHardLink /* || linkInfo.IsCopyLink */ || !linkInfo.isRelative)
2052*f6dc9357SAndroid Build Coastguard Worker {
2053*f6dc9357SAndroid Build Coastguard Worker if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(relatPath), existPath))
2054*f6dc9357SAndroid Build Coastguard Worker {
2055*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError("Incorrect path", us2fs(relatPath)))
2056*f6dc9357SAndroid Build Coastguard Worker }
2057*f6dc9357SAndroid Build Coastguard Worker }
2058*f6dc9357SAndroid Build Coastguard Worker else
2059*f6dc9357SAndroid Build Coastguard Worker {
2060*f6dc9357SAndroid Build Coastguard Worker existPath = us2fs(linkInfo.linkPath);
2061*f6dc9357SAndroid Build Coastguard Worker // printf("\nlinkPath = : %s\n", GetOemString(linkInfo.linkPath).Ptr());
2062*f6dc9357SAndroid Build Coastguard Worker }
2063*f6dc9357SAndroid Build Coastguard Worker
2064*f6dc9357SAndroid Build Coastguard Worker if (existPath.IsEmpty())
2065*f6dc9357SAndroid Build Coastguard Worker return SendMessageError("Empty link", fullProcessedPath);
2066*f6dc9357SAndroid Build Coastguard Worker
2067*f6dc9357SAndroid Build Coastguard Worker if (linkInfo.isHardLink /* || linkInfo.IsCopyLink */)
2068*f6dc9357SAndroid Build Coastguard Worker {
2069*f6dc9357SAndroid Build Coastguard Worker // if (linkInfo.isHardLink)
2070*f6dc9357SAndroid Build Coastguard Worker {
2071*f6dc9357SAndroid Build Coastguard Worker if (!MyCreateHardLink(fullProcessedPath, existPath))
2072*f6dc9357SAndroid Build Coastguard Worker {
2073*f6dc9357SAndroid Build Coastguard Worker const HRESULT errorCode = GetLastError_noZero_HRESULT();
2074*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError2(errorCode, kCantCreateHardLink, fullProcessedPath, existPath))
2075*f6dc9357SAndroid Build Coastguard Worker }
2076*f6dc9357SAndroid Build Coastguard Worker /*
2077*f6dc9357SAndroid Build Coastguard Worker RINOK(PrepareOperation(NArchive::NExtract::NAskMode::kExtract))
2078*f6dc9357SAndroid Build Coastguard Worker _op_WasReported = true;
2079*f6dc9357SAndroid Build Coastguard Worker RINOK(SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
2080*f6dc9357SAndroid Build Coastguard Worker */
2081*f6dc9357SAndroid Build Coastguard Worker linkWasSet = true;
2082*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2083*f6dc9357SAndroid Build Coastguard Worker }
2084*f6dc9357SAndroid Build Coastguard Worker /*
2085*f6dc9357SAndroid Build Coastguard Worker // IsCopyLink
2086*f6dc9357SAndroid Build Coastguard Worker {
2087*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
2088*f6dc9357SAndroid Build Coastguard Worker if (!fi.Find(existPath))
2089*f6dc9357SAndroid Build Coastguard Worker {
2090*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError2("Cannot find the file for copying", existPath, fullProcessedPath));
2091*f6dc9357SAndroid Build Coastguard Worker }
2092*f6dc9357SAndroid Build Coastguard Worker else
2093*f6dc9357SAndroid Build Coastguard Worker {
2094*f6dc9357SAndroid Build Coastguard Worker if (_curSize_Defined && _curSize == fi.Size)
2095*f6dc9357SAndroid Build Coastguard Worker _copyFile_Path = existPath;
2096*f6dc9357SAndroid Build Coastguard Worker else
2097*f6dc9357SAndroid Build Coastguard Worker {
2098*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError2("File size collision for file copying", existPath, fullProcessedPath));
2099*f6dc9357SAndroid Build Coastguard Worker }
2100*f6dc9357SAndroid Build Coastguard Worker // RINOK(MyCopyFile(existPath, fullProcessedPath));
2101*f6dc9357SAndroid Build Coastguard Worker }
2102*f6dc9357SAndroid Build Coastguard Worker }
2103*f6dc9357SAndroid Build Coastguard Worker */
2104*f6dc9357SAndroid Build Coastguard Worker }
2105*f6dc9357SAndroid Build Coastguard Worker
2106*f6dc9357SAndroid Build Coastguard Worker // is Symbolic link
2107*f6dc9357SAndroid Build Coastguard Worker
2108*f6dc9357SAndroid Build Coastguard Worker /*
2109*f6dc9357SAndroid Build Coastguard Worker if (_item.IsDir && !isRelative)
2110*f6dc9357SAndroid Build Coastguard Worker {
2111*f6dc9357SAndroid Build Coastguard Worker // Windows before Vista doesn't support symbolic links.
2112*f6dc9357SAndroid Build Coastguard Worker // we could convert such symbolic links to Junction Points
2113*f6dc9357SAndroid Build Coastguard Worker // isJunction = true;
2114*f6dc9357SAndroid Build Coastguard Worker // convertToAbs = true;
2115*f6dc9357SAndroid Build Coastguard Worker }
2116*f6dc9357SAndroid Build Coastguard Worker */
2117*f6dc9357SAndroid Build Coastguard Worker
2118*f6dc9357SAndroid Build Coastguard Worker if (!_ntOptions.SymLinks_AllowDangerous.Val)
2119*f6dc9357SAndroid Build Coastguard Worker {
2120*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
2121*f6dc9357SAndroid Build Coastguard Worker if (_item.IsDir)
2122*f6dc9357SAndroid Build Coastguard Worker #endif
2123*f6dc9357SAndroid Build Coastguard Worker if (linkInfo.isRelative)
2124*f6dc9357SAndroid Build Coastguard Worker {
2125*f6dc9357SAndroid Build Coastguard Worker CLinkLevelsInfo levelsInfo;
2126*f6dc9357SAndroid Build Coastguard Worker levelsInfo.Parse(linkInfo.linkPath);
2127*f6dc9357SAndroid Build Coastguard Worker if (levelsInfo.FinalLevel < 1 || levelsInfo.IsAbsolute)
2128*f6dc9357SAndroid Build Coastguard Worker {
2129*f6dc9357SAndroid Build Coastguard Worker return SendMessageError2(
2130*f6dc9357SAndroid Build Coastguard Worker 0, // errorCode
2131*f6dc9357SAndroid Build Coastguard Worker "Dangerous symbolic link path was ignored",
2132*f6dc9357SAndroid Build Coastguard Worker us2fs(_item.Path),
2133*f6dc9357SAndroid Build Coastguard Worker us2fs(linkInfo.linkPath));
2134*f6dc9357SAndroid Build Coastguard Worker }
2135*f6dc9357SAndroid Build Coastguard Worker }
2136*f6dc9357SAndroid Build Coastguard Worker }
2137*f6dc9357SAndroid Build Coastguard Worker
2138*f6dc9357SAndroid Build Coastguard Worker
2139*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
2140*f6dc9357SAndroid Build Coastguard Worker
2141*f6dc9357SAndroid Build Coastguard Worker CByteBuffer data;
2142*f6dc9357SAndroid Build Coastguard Worker // printf("\nFillLinkData(): %s\n", GetOemString(existPath).Ptr());
2143*f6dc9357SAndroid Build Coastguard Worker if (!FillLinkData(data, fs2us(existPath), !linkInfo.isJunction, linkInfo.isWSL))
2144*f6dc9357SAndroid Build Coastguard Worker return SendMessageError("Cannot fill link data", us2fs(_item.Path));
2145*f6dc9357SAndroid Build Coastguard Worker
2146*f6dc9357SAndroid Build Coastguard Worker /*
2147*f6dc9357SAndroid Build Coastguard Worker if (NtReparse_Size != data.Size() || memcmp(NtReparse_Data, data, data.Size()) != 0)
2148*f6dc9357SAndroid Build Coastguard Worker {
2149*f6dc9357SAndroid Build Coastguard Worker SendMessageError("reconstructed Reparse is different", fs2us(existPath));
2150*f6dc9357SAndroid Build Coastguard Worker }
2151*f6dc9357SAndroid Build Coastguard Worker */
2152*f6dc9357SAndroid Build Coastguard Worker
2153*f6dc9357SAndroid Build Coastguard Worker CReparseAttr attr;
2154*f6dc9357SAndroid Build Coastguard Worker if (!attr.Parse(data, data.Size()))
2155*f6dc9357SAndroid Build Coastguard Worker {
2156*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)))
2157*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2158*f6dc9357SAndroid Build Coastguard Worker }
2159*f6dc9357SAndroid Build Coastguard Worker if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size()))
2160*f6dc9357SAndroid Build Coastguard Worker {
2161*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath))
2162*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2163*f6dc9357SAndroid Build Coastguard Worker }
2164*f6dc9357SAndroid Build Coastguard Worker linkWasSet = true;
2165*f6dc9357SAndroid Build Coastguard Worker
2166*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2167*f6dc9357SAndroid Build Coastguard Worker
2168*f6dc9357SAndroid Build Coastguard Worker
2169*f6dc9357SAndroid Build Coastguard Worker #else // ! _WIN32
2170*f6dc9357SAndroid Build Coastguard Worker
2171*f6dc9357SAndroid Build Coastguard Worker if (!NFile::NIO::SetSymLink(fullProcessedPath, existPath))
2172*f6dc9357SAndroid Build Coastguard Worker {
2173*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath))
2174*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2175*f6dc9357SAndroid Build Coastguard Worker }
2176*f6dc9357SAndroid Build Coastguard Worker linkWasSet = true;
2177*f6dc9357SAndroid Build Coastguard Worker
2178*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2179*f6dc9357SAndroid Build Coastguard Worker
2180*f6dc9357SAndroid Build Coastguard Worker #endif // ! _WIN32
2181*f6dc9357SAndroid Build Coastguard Worker }
2182*f6dc9357SAndroid Build Coastguard Worker
2183*f6dc9357SAndroid Build Coastguard Worker
2184*f6dc9357SAndroid Build Coastguard Worker bool CLinkInfo::Parse(const Byte *data, size_t dataSize, bool isLinuxData)
2185*f6dc9357SAndroid Build Coastguard Worker {
2186*f6dc9357SAndroid Build Coastguard Worker Clear();
2187*f6dc9357SAndroid Build Coastguard Worker // this->isLinux = isLinuxData;
2188*f6dc9357SAndroid Build Coastguard Worker
2189*f6dc9357SAndroid Build Coastguard Worker if (isLinuxData)
2190*f6dc9357SAndroid Build Coastguard Worker {
2191*f6dc9357SAndroid Build Coastguard Worker isJunction = false;
2192*f6dc9357SAndroid Build Coastguard Worker isHardLink = false;
2193*f6dc9357SAndroid Build Coastguard Worker AString utf;
2194*f6dc9357SAndroid Build Coastguard Worker if (dataSize >= (1 << 12))
2195*f6dc9357SAndroid Build Coastguard Worker return false;
2196*f6dc9357SAndroid Build Coastguard Worker utf.SetFrom_CalcLen((const char *)data, (unsigned)dataSize);
2197*f6dc9357SAndroid Build Coastguard Worker UString u;
2198*f6dc9357SAndroid Build Coastguard Worker if (!ConvertUTF8ToUnicode(utf, u))
2199*f6dc9357SAndroid Build Coastguard Worker return false;
2200*f6dc9357SAndroid Build Coastguard Worker linkPath = u;
2201*f6dc9357SAndroid Build Coastguard Worker
2202*f6dc9357SAndroid Build Coastguard Worker // in linux symbolic data: we expect that linux separator '/' is used
2203*f6dc9357SAndroid Build Coastguard Worker // if windows link was created, then we also must use linux separator
2204*f6dc9357SAndroid Build Coastguard Worker if (u.IsEmpty())
2205*f6dc9357SAndroid Build Coastguard Worker return false;
2206*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = u[0];
2207*f6dc9357SAndroid Build Coastguard Worker isRelative = !IS_PATH_SEPAR(c);
2208*f6dc9357SAndroid Build Coastguard Worker return true;
2209*f6dc9357SAndroid Build Coastguard Worker }
2210*f6dc9357SAndroid Build Coastguard Worker
2211*f6dc9357SAndroid Build Coastguard Worker CReparseAttr reparse;
2212*f6dc9357SAndroid Build Coastguard Worker if (!reparse.Parse(data, dataSize))
2213*f6dc9357SAndroid Build Coastguard Worker return false;
2214*f6dc9357SAndroid Build Coastguard Worker isHardLink = false;
2215*f6dc9357SAndroid Build Coastguard Worker // isCopyLink = false;
2216*f6dc9357SAndroid Build Coastguard Worker linkPath = reparse.GetPath();
2217*f6dc9357SAndroid Build Coastguard Worker isJunction = reparse.IsMountPoint();
2218*f6dc9357SAndroid Build Coastguard Worker
2219*f6dc9357SAndroid Build Coastguard Worker if (reparse.IsSymLink_WSL())
2220*f6dc9357SAndroid Build Coastguard Worker {
2221*f6dc9357SAndroid Build Coastguard Worker isWSL = true;
2222*f6dc9357SAndroid Build Coastguard Worker isRelative = reparse.IsRelative_WSL();
2223*f6dc9357SAndroid Build Coastguard Worker }
2224*f6dc9357SAndroid Build Coastguard Worker else
2225*f6dc9357SAndroid Build Coastguard Worker isRelative = reparse.IsRelative_Win();
2226*f6dc9357SAndroid Build Coastguard Worker
2227*f6dc9357SAndroid Build Coastguard Worker // FIXME !!!
2228*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
2229*f6dc9357SAndroid Build Coastguard Worker linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR);
2230*f6dc9357SAndroid Build Coastguard Worker #endif
2231*f6dc9357SAndroid Build Coastguard Worker
2232*f6dc9357SAndroid Build Coastguard Worker return true;
2233*f6dc9357SAndroid Build Coastguard Worker }
2234*f6dc9357SAndroid Build Coastguard Worker
2235*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_LINKS
2236*f6dc9357SAndroid Build Coastguard Worker
2237*f6dc9357SAndroid Build Coastguard Worker
2238*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::CloseReparseAndFile()
2239*f6dc9357SAndroid Build Coastguard Worker {
2240*f6dc9357SAndroid Build Coastguard Worker HRESULT res = S_OK;
2241*f6dc9357SAndroid Build Coastguard Worker
2242*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
2243*f6dc9357SAndroid Build Coastguard Worker
2244*f6dc9357SAndroid Build Coastguard Worker size_t reparseSize = 0;
2245*f6dc9357SAndroid Build Coastguard Worker bool repraseMode = false;
2246*f6dc9357SAndroid Build Coastguard Worker bool needSetReparse = false;
2247*f6dc9357SAndroid Build Coastguard Worker CLinkInfo linkInfo;
2248*f6dc9357SAndroid Build Coastguard Worker
2249*f6dc9357SAndroid Build Coastguard Worker if (_bufPtrSeqOutStream)
2250*f6dc9357SAndroid Build Coastguard Worker {
2251*f6dc9357SAndroid Build Coastguard Worker repraseMode = true;
2252*f6dc9357SAndroid Build Coastguard Worker reparseSize = _bufPtrSeqOutStream_Spec->GetPos();
2253*f6dc9357SAndroid Build Coastguard Worker if (_curSize_Defined && reparseSize == _outMemBuf.Size())
2254*f6dc9357SAndroid Build Coastguard Worker {
2255*f6dc9357SAndroid Build Coastguard Worker /*
2256*f6dc9357SAndroid Build Coastguard Worker CReparseAttr reparse;
2257*f6dc9357SAndroid Build Coastguard Worker DWORD errorCode = 0;
2258*f6dc9357SAndroid Build Coastguard Worker needSetReparse = reparse.Parse(_outMemBuf, reparseSize, errorCode);
2259*f6dc9357SAndroid Build Coastguard Worker if (needSetReparse)
2260*f6dc9357SAndroid Build Coastguard Worker {
2261*f6dc9357SAndroid Build Coastguard Worker UString linkPath = reparse.GetPath();
2262*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
2263*f6dc9357SAndroid Build Coastguard Worker linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR);
2264*f6dc9357SAndroid Build Coastguard Worker #endif
2265*f6dc9357SAndroid Build Coastguard Worker }
2266*f6dc9357SAndroid Build Coastguard Worker */
2267*f6dc9357SAndroid Build Coastguard Worker needSetReparse = linkInfo.Parse(_outMemBuf, reparseSize, _is_SymLink_in_Data_Linux);
2268*f6dc9357SAndroid Build Coastguard Worker if (!needSetReparse)
2269*f6dc9357SAndroid Build Coastguard Worker res = SendMessageError_with_LastError("Incorrect reparse stream", us2fs(_item.Path));
2270*f6dc9357SAndroid Build Coastguard Worker }
2271*f6dc9357SAndroid Build Coastguard Worker else
2272*f6dc9357SAndroid Build Coastguard Worker {
2273*f6dc9357SAndroid Build Coastguard Worker res = SendMessageError_with_LastError("Unknown reparse stream", us2fs(_item.Path));
2274*f6dc9357SAndroid Build Coastguard Worker }
2275*f6dc9357SAndroid Build Coastguard Worker if (!needSetReparse && _outFileStream)
2276*f6dc9357SAndroid Build Coastguard Worker {
2277*f6dc9357SAndroid Build Coastguard Worker const HRESULT res2 = WriteStream(_outFileStream, _outMemBuf, reparseSize);
2278*f6dc9357SAndroid Build Coastguard Worker if (res == S_OK)
2279*f6dc9357SAndroid Build Coastguard Worker res = res2;
2280*f6dc9357SAndroid Build Coastguard Worker }
2281*f6dc9357SAndroid Build Coastguard Worker _bufPtrSeqOutStream.Release();
2282*f6dc9357SAndroid Build Coastguard Worker }
2283*f6dc9357SAndroid Build Coastguard Worker
2284*f6dc9357SAndroid Build Coastguard Worker #endif // SUPPORT_LINKS
2285*f6dc9357SAndroid Build Coastguard Worker
2286*f6dc9357SAndroid Build Coastguard Worker
2287*f6dc9357SAndroid Build Coastguard Worker const HRESULT res2 = CloseFile();
2288*f6dc9357SAndroid Build Coastguard Worker
2289*f6dc9357SAndroid Build Coastguard Worker if (res == S_OK)
2290*f6dc9357SAndroid Build Coastguard Worker res = res2;
2291*f6dc9357SAndroid Build Coastguard Worker
2292*f6dc9357SAndroid Build Coastguard Worker RINOK(res)
2293*f6dc9357SAndroid Build Coastguard Worker
2294*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
2295*f6dc9357SAndroid Build Coastguard Worker if (repraseMode)
2296*f6dc9357SAndroid Build Coastguard Worker {
2297*f6dc9357SAndroid Build Coastguard Worker _curSize = reparseSize;
2298*f6dc9357SAndroid Build Coastguard Worker _curSize_Defined = true;
2299*f6dc9357SAndroid Build Coastguard Worker
2300*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_LINKS
2301*f6dc9357SAndroid Build Coastguard Worker if (needSetReparse)
2302*f6dc9357SAndroid Build Coastguard Worker {
2303*f6dc9357SAndroid Build Coastguard Worker // in Linux : we must delete empty file before symbolic link creation
2304*f6dc9357SAndroid Build Coastguard Worker // in Windows : we can create symbolic link even without file deleting
2305*f6dc9357SAndroid Build Coastguard Worker if (!DeleteFileAlways(_diskFilePath))
2306*f6dc9357SAndroid Build Coastguard Worker {
2307*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError("can't delete file", _diskFilePath))
2308*f6dc9357SAndroid Build Coastguard Worker }
2309*f6dc9357SAndroid Build Coastguard Worker {
2310*f6dc9357SAndroid Build Coastguard Worker /*
2311*f6dc9357SAndroid Build Coastguard Worker // for DEBUG ONLY: we can extract sym links as WSL links
2312*f6dc9357SAndroid Build Coastguard Worker // to eliminate (non-admin) errors for sym links.
2313*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
2314*f6dc9357SAndroid Build Coastguard Worker if (!linkInfo.isHardLink && !linkInfo.isJunction)
2315*f6dc9357SAndroid Build Coastguard Worker linkInfo.isWSL = true;
2316*f6dc9357SAndroid Build Coastguard Worker #endif
2317*f6dc9357SAndroid Build Coastguard Worker */
2318*f6dc9357SAndroid Build Coastguard Worker bool linkWasSet = false;
2319*f6dc9357SAndroid Build Coastguard Worker RINOK(SetFromLinkPath(_diskFilePath, linkInfo, linkWasSet))
2320*f6dc9357SAndroid Build Coastguard Worker if (linkWasSet)
2321*f6dc9357SAndroid Build Coastguard Worker _isSymLinkCreated = linkInfo.IsSymLink();
2322*f6dc9357SAndroid Build Coastguard Worker else
2323*f6dc9357SAndroid Build Coastguard Worker _needSetAttrib = false;
2324*f6dc9357SAndroid Build Coastguard Worker }
2325*f6dc9357SAndroid Build Coastguard Worker /*
2326*f6dc9357SAndroid Build Coastguard Worker if (!NFile::NIO::SetReparseData(_diskFilePath, _item.IsDir, ))
2327*f6dc9357SAndroid Build Coastguard Worker {
2328*f6dc9357SAndroid Build Coastguard Worker res = SendMessageError_with_LastError(kCantCreateSymLink, _diskFilePath);
2329*f6dc9357SAndroid Build Coastguard Worker }
2330*f6dc9357SAndroid Build Coastguard Worker */
2331*f6dc9357SAndroid Build Coastguard Worker }
2332*f6dc9357SAndroid Build Coastguard Worker #endif
2333*f6dc9357SAndroid Build Coastguard Worker }
2334*f6dc9357SAndroid Build Coastguard Worker #endif
2335*f6dc9357SAndroid Build Coastguard Worker return res;
2336*f6dc9357SAndroid Build Coastguard Worker }
2337*f6dc9357SAndroid Build Coastguard Worker
2338*f6dc9357SAndroid Build Coastguard Worker
2339*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::SetAttrib()
2340*f6dc9357SAndroid Build Coastguard Worker {
2341*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
2342*f6dc9357SAndroid Build Coastguard Worker // Linux now doesn't support permissions for symlinks
2343*f6dc9357SAndroid Build Coastguard Worker if (_isSymLinkCreated)
2344*f6dc9357SAndroid Build Coastguard Worker return;
2345*f6dc9357SAndroid Build Coastguard Worker #endif
2346*f6dc9357SAndroid Build Coastguard Worker
2347*f6dc9357SAndroid Build Coastguard Worker if (_itemFailure
2348*f6dc9357SAndroid Build Coastguard Worker || _diskFilePath.IsEmpty()
2349*f6dc9357SAndroid Build Coastguard Worker || _stdOutMode
2350*f6dc9357SAndroid Build Coastguard Worker || !_extractMode)
2351*f6dc9357SAndroid Build Coastguard Worker return;
2352*f6dc9357SAndroid Build Coastguard Worker
2353*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
2354*f6dc9357SAndroid Build Coastguard Worker if (_fi.Owner.Id_Defined &&
2355*f6dc9357SAndroid Build Coastguard Worker _fi.Group.Id_Defined)
2356*f6dc9357SAndroid Build Coastguard Worker {
2357*f6dc9357SAndroid Build Coastguard Worker if (my_chown(_diskFilePath, _fi.Owner.Id, _fi.Group.Id) != 0)
2358*f6dc9357SAndroid Build Coastguard Worker {
2359*f6dc9357SAndroid Build Coastguard Worker SendMessageError_with_LastError("Cannot set owner", _diskFilePath);
2360*f6dc9357SAndroid Build Coastguard Worker }
2361*f6dc9357SAndroid Build Coastguard Worker }
2362*f6dc9357SAndroid Build Coastguard Worker #endif
2363*f6dc9357SAndroid Build Coastguard Worker
2364*f6dc9357SAndroid Build Coastguard Worker if (_fi.Attrib_Defined)
2365*f6dc9357SAndroid Build Coastguard Worker {
2366*f6dc9357SAndroid Build Coastguard Worker // const AString s = GetAnsiString(_diskFilePath);
2367*f6dc9357SAndroid Build Coastguard Worker // printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib);
2368*f6dc9357SAndroid Build Coastguard Worker bool res = SetFileAttrib_PosixHighDetect(_diskFilePath, _fi.Attrib);
2369*f6dc9357SAndroid Build Coastguard Worker if (!res)
2370*f6dc9357SAndroid Build Coastguard Worker {
2371*f6dc9357SAndroid Build Coastguard Worker // do we need error message here in Windows and in posix?
2372*f6dc9357SAndroid Build Coastguard Worker SendMessageError_with_LastError("Cannot set file attribute", _diskFilePath);
2373*f6dc9357SAndroid Build Coastguard Worker }
2374*f6dc9357SAndroid Build Coastguard Worker }
2375*f6dc9357SAndroid Build Coastguard Worker }
2376*f6dc9357SAndroid Build Coastguard Worker
2377*f6dc9357SAndroid Build Coastguard Worker
2378*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 opRes))
2379*f6dc9357SAndroid Build Coastguard Worker {
2380*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
2381*f6dc9357SAndroid Build Coastguard Worker
2382*f6dc9357SAndroid Build Coastguard Worker // printf("\nCArchiveExtractCallback::SetOperationResult: %d %s\n", opRes, GetAnsiString(_diskFilePath));
2383*f6dc9357SAndroid Build Coastguard Worker
2384*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
2385*f6dc9357SAndroid Build Coastguard Worker if (ExtractToStreamCallback)
2386*f6dc9357SAndroid Build Coastguard Worker {
2387*f6dc9357SAndroid Build Coastguard Worker GetUnpackSize();
2388*f6dc9357SAndroid Build Coastguard Worker return ExtractToStreamCallback->SetOperationResult8(opRes, BoolToInt(_encrypted), _curSize);
2389*f6dc9357SAndroid Build Coastguard Worker }
2390*f6dc9357SAndroid Build Coastguard Worker #endif
2391*f6dc9357SAndroid Build Coastguard Worker
2392*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
2393*f6dc9357SAndroid Build Coastguard Worker
2394*f6dc9357SAndroid Build Coastguard Worker if (_hashStreamWasUsed)
2395*f6dc9357SAndroid Build Coastguard Worker {
2396*f6dc9357SAndroid Build Coastguard Worker _hashStreamSpec->_hash->Final(_item.IsDir,
2397*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
2398*f6dc9357SAndroid Build Coastguard Worker _item.IsAltStream
2399*f6dc9357SAndroid Build Coastguard Worker #else
2400*f6dc9357SAndroid Build Coastguard Worker false
2401*f6dc9357SAndroid Build Coastguard Worker #endif
2402*f6dc9357SAndroid Build Coastguard Worker , _item.Path);
2403*f6dc9357SAndroid Build Coastguard Worker _curSize = _hashStreamSpec->GetSize();
2404*f6dc9357SAndroid Build Coastguard Worker _curSize_Defined = true;
2405*f6dc9357SAndroid Build Coastguard Worker _hashStreamSpec->ReleaseStream();
2406*f6dc9357SAndroid Build Coastguard Worker _hashStreamWasUsed = false;
2407*f6dc9357SAndroid Build Coastguard Worker }
2408*f6dc9357SAndroid Build Coastguard Worker
2409*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
2410*f6dc9357SAndroid Build Coastguard Worker
2411*f6dc9357SAndroid Build Coastguard Worker RINOK(CloseReparseAndFile())
2412*f6dc9357SAndroid Build Coastguard Worker
2413*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_SECURITY_CODE
2414*f6dc9357SAndroid Build Coastguard Worker if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps)
2415*f6dc9357SAndroid Build Coastguard Worker {
2416*f6dc9357SAndroid Build Coastguard Worker const void *data;
2417*f6dc9357SAndroid Build Coastguard Worker UInt32 dataSize;
2418*f6dc9357SAndroid Build Coastguard Worker UInt32 propType;
2419*f6dc9357SAndroid Build Coastguard Worker _arc->GetRawProps->GetRawProp(_index, kpidNtSecure, &data, &dataSize, &propType);
2420*f6dc9357SAndroid Build Coastguard Worker if (dataSize != 0)
2421*f6dc9357SAndroid Build Coastguard Worker {
2422*f6dc9357SAndroid Build Coastguard Worker if (propType != NPropDataType::kRaw)
2423*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2424*f6dc9357SAndroid Build Coastguard Worker if (CheckNtSecure((const Byte *)data, dataSize))
2425*f6dc9357SAndroid Build Coastguard Worker {
2426*f6dc9357SAndroid Build Coastguard Worker SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION;
2427*f6dc9357SAndroid Build Coastguard Worker if (_saclEnabled)
2428*f6dc9357SAndroid Build Coastguard Worker securInfo |= SACL_SECURITY_INFORMATION;
2429*f6dc9357SAndroid Build Coastguard Worker ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)(const Byte *)(data));
2430*f6dc9357SAndroid Build Coastguard Worker }
2431*f6dc9357SAndroid Build Coastguard Worker }
2432*f6dc9357SAndroid Build Coastguard Worker }
2433*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_USE_SECURITY_CODE
2434*f6dc9357SAndroid Build Coastguard Worker
2435*f6dc9357SAndroid Build Coastguard Worker if (!_curSize_Defined)
2436*f6dc9357SAndroid Build Coastguard Worker GetUnpackSize();
2437*f6dc9357SAndroid Build Coastguard Worker
2438*f6dc9357SAndroid Build Coastguard Worker if (_curSize_Defined)
2439*f6dc9357SAndroid Build Coastguard Worker {
2440*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
2441*f6dc9357SAndroid Build Coastguard Worker if (_item.IsAltStream)
2442*f6dc9357SAndroid Build Coastguard Worker AltStreams_UnpackSize += _curSize;
2443*f6dc9357SAndroid Build Coastguard Worker else
2444*f6dc9357SAndroid Build Coastguard Worker #endif
2445*f6dc9357SAndroid Build Coastguard Worker UnpackSize += _curSize;
2446*f6dc9357SAndroid Build Coastguard Worker }
2447*f6dc9357SAndroid Build Coastguard Worker
2448*f6dc9357SAndroid Build Coastguard Worker if (_item.IsDir)
2449*f6dc9357SAndroid Build Coastguard Worker NumFolders++;
2450*f6dc9357SAndroid Build Coastguard Worker #ifdef SUPPORT_ALT_STREAMS
2451*f6dc9357SAndroid Build Coastguard Worker else if (_item.IsAltStream)
2452*f6dc9357SAndroid Build Coastguard Worker NumAltStreams++;
2453*f6dc9357SAndroid Build Coastguard Worker #endif
2454*f6dc9357SAndroid Build Coastguard Worker else
2455*f6dc9357SAndroid Build Coastguard Worker NumFiles++;
2456*f6dc9357SAndroid Build Coastguard Worker
2457*f6dc9357SAndroid Build Coastguard Worker if (_needSetAttrib)
2458*f6dc9357SAndroid Build Coastguard Worker SetAttrib();
2459*f6dc9357SAndroid Build Coastguard Worker
2460*f6dc9357SAndroid Build Coastguard Worker RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted)))
2461*f6dc9357SAndroid Build Coastguard Worker
2462*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2463*f6dc9357SAndroid Build Coastguard Worker
2464*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
2465*f6dc9357SAndroid Build Coastguard Worker }
2466*f6dc9357SAndroid Build Coastguard Worker
2467*f6dc9357SAndroid Build Coastguard Worker
2468*f6dc9357SAndroid Build Coastguard Worker
2469*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
2470*f6dc9357SAndroid Build Coastguard Worker {
2471*f6dc9357SAndroid Build Coastguard Worker if (_folderArchiveExtractCallback2)
2472*f6dc9357SAndroid Build Coastguard Worker {
2473*f6dc9357SAndroid Build Coastguard Worker bool isEncrypted = false;
2474*f6dc9357SAndroid Build Coastguard Worker UString s;
2475*f6dc9357SAndroid Build Coastguard Worker
2476*f6dc9357SAndroid Build Coastguard Worker if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1)
2477*f6dc9357SAndroid Build Coastguard Worker {
2478*f6dc9357SAndroid Build Coastguard Worker CReadArcItem item;
2479*f6dc9357SAndroid Build Coastguard Worker RINOK(_arc->GetItem(index, item))
2480*f6dc9357SAndroid Build Coastguard Worker s = item.Path;
2481*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted))
2482*f6dc9357SAndroid Build Coastguard Worker }
2483*f6dc9357SAndroid Build Coastguard Worker else
2484*f6dc9357SAndroid Build Coastguard Worker {
2485*f6dc9357SAndroid Build Coastguard Worker s = '#';
2486*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(index);
2487*f6dc9357SAndroid Build Coastguard Worker // if (indexType == NArchive::NEventIndexType::kBlockIndex) {}
2488*f6dc9357SAndroid Build Coastguard Worker }
2489*f6dc9357SAndroid Build Coastguard Worker
2490*f6dc9357SAndroid Build Coastguard Worker return _folderArchiveExtractCallback2->ReportExtractResult(opRes, isEncrypted, s);
2491*f6dc9357SAndroid Build Coastguard Worker }
2492*f6dc9357SAndroid Build Coastguard Worker
2493*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2494*f6dc9357SAndroid Build Coastguard Worker }
2495*f6dc9357SAndroid Build Coastguard Worker
2496*f6dc9357SAndroid Build Coastguard Worker
2497*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password))
2498*f6dc9357SAndroid Build Coastguard Worker {
2499*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
2500*f6dc9357SAndroid Build Coastguard Worker if (!_cryptoGetTextPassword)
2501*f6dc9357SAndroid Build Coastguard Worker {
2502*f6dc9357SAndroid Build Coastguard Worker RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword,
2503*f6dc9357SAndroid Build Coastguard Worker &_cryptoGetTextPassword))
2504*f6dc9357SAndroid Build Coastguard Worker }
2505*f6dc9357SAndroid Build Coastguard Worker return _cryptoGetTextPassword->CryptoGetTextPassword(password);
2506*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
2507*f6dc9357SAndroid Build Coastguard Worker }
2508*f6dc9357SAndroid Build Coastguard Worker
2509*f6dc9357SAndroid Build Coastguard Worker
2510*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
2511*f6dc9357SAndroid Build Coastguard Worker
2512*f6dc9357SAndroid Build Coastguard Worker // ---------- HASH functions ----------
2513*f6dc9357SAndroid Build Coastguard Worker
2514*f6dc9357SAndroid Build Coastguard Worker FString CArchiveExtractCallback::Hash_GetFullFilePath()
2515*f6dc9357SAndroid Build Coastguard Worker {
2516*f6dc9357SAndroid Build Coastguard Worker // this function changes _item.PathParts.
2517*f6dc9357SAndroid Build Coastguard Worker CorrectPathParts();
2518*f6dc9357SAndroid Build Coastguard Worker const UStringVector &pathParts = _item.PathParts;
2519*f6dc9357SAndroid Build Coastguard Worker const UString processedPath (MakePathFromParts(pathParts));
2520*f6dc9357SAndroid Build Coastguard Worker FString fullProcessedPath (us2fs(processedPath));
2521*f6dc9357SAndroid Build Coastguard Worker if (_pathMode != NExtract::NPathMode::kAbsPaths
2522*f6dc9357SAndroid Build Coastguard Worker || !NName::IsAbsolutePath(processedPath))
2523*f6dc9357SAndroid Build Coastguard Worker {
2524*f6dc9357SAndroid Build Coastguard Worker fullProcessedPath = MakePath_from_2_Parts(
2525*f6dc9357SAndroid Build Coastguard Worker DirPathPrefix_for_HashFiles,
2526*f6dc9357SAndroid Build Coastguard Worker // _dirPathPrefix,
2527*f6dc9357SAndroid Build Coastguard Worker fullProcessedPath);
2528*f6dc9357SAndroid Build Coastguard Worker }
2529*f6dc9357SAndroid Build Coastguard Worker return fullProcessedPath;
2530*f6dc9357SAndroid Build Coastguard Worker }
2531*f6dc9357SAndroid Build Coastguard Worker
2532*f6dc9357SAndroid Build Coastguard Worker
2533*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
2534*f6dc9357SAndroid Build Coastguard Worker {
2535*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
2536*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
2537*f6dc9357SAndroid Build Coastguard Worker if (propID == kpidSize)
2538*f6dc9357SAndroid Build Coastguard Worker {
2539*f6dc9357SAndroid Build Coastguard Worker RINOK(GetItem(index))
2540*f6dc9357SAndroid Build Coastguard Worker const FString fullProcessedPath = Hash_GetFullFilePath();
2541*f6dc9357SAndroid Build Coastguard Worker NFile::NFind::CFileInfo fi;
2542*f6dc9357SAndroid Build Coastguard Worker if (fi.Find_FollowLink(fullProcessedPath))
2543*f6dc9357SAndroid Build Coastguard Worker if (!fi.IsDir())
2544*f6dc9357SAndroid Build Coastguard Worker prop = (UInt64)fi.Size;
2545*f6dc9357SAndroid Build Coastguard Worker }
2546*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
2547*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2548*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
2549*f6dc9357SAndroid Build Coastguard Worker }
2550*f6dc9357SAndroid Build Coastguard Worker
2551*f6dc9357SAndroid Build Coastguard Worker
2552*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode))
2553*f6dc9357SAndroid Build Coastguard Worker {
2554*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
2555*f6dc9357SAndroid Build Coastguard Worker *inStream = NULL;
2556*f6dc9357SAndroid Build Coastguard Worker // if (index != _index) return E_FAIL;
2557*f6dc9357SAndroid Build Coastguard Worker if (mode != NUpdateNotifyOp::kHashRead)
2558*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2559*f6dc9357SAndroid Build Coastguard Worker
2560*f6dc9357SAndroid Build Coastguard Worker RINOK(GetItem(index))
2561*f6dc9357SAndroid Build Coastguard Worker const FString fullProcessedPath = Hash_GetFullFilePath();
2562*f6dc9357SAndroid Build Coastguard Worker
2563*f6dc9357SAndroid Build Coastguard Worker CInFileStream *inStreamSpec = new CInFileStream;
2564*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec;
2565*f6dc9357SAndroid Build Coastguard Worker inStreamSpec->Set_PreserveATime(_ntOptions.PreserveATime);
2566*f6dc9357SAndroid Build Coastguard Worker if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite))
2567*f6dc9357SAndroid Build Coastguard Worker {
2568*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath))
2569*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2570*f6dc9357SAndroid Build Coastguard Worker }
2571*f6dc9357SAndroid Build Coastguard Worker *inStream = inStreamRef.Detach();
2572*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2573*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
2574*f6dc9357SAndroid Build Coastguard Worker }
2575*f6dc9357SAndroid Build Coastguard Worker
2576*f6dc9357SAndroid Build Coastguard Worker
2577*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::ReportOperation(
2578*f6dc9357SAndroid Build Coastguard Worker UInt32 /* indexType */, UInt32 /* index */, UInt32 /* op */))
2579*f6dc9357SAndroid Build Coastguard Worker {
2580*f6dc9357SAndroid Build Coastguard Worker // COM_TRY_BEGIN
2581*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2582*f6dc9357SAndroid Build Coastguard Worker // COM_TRY_END
2583*f6dc9357SAndroid Build Coastguard Worker }
2584*f6dc9357SAndroid Build Coastguard Worker
2585*f6dc9357SAndroid Build Coastguard Worker
2586*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::RequestMemoryUse(
2587*f6dc9357SAndroid Build Coastguard Worker UInt32 flags, UInt32 indexType, UInt32 index, const wchar_t *path,
2588*f6dc9357SAndroid Build Coastguard Worker UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags))
2589*f6dc9357SAndroid Build Coastguard Worker {
2590*f6dc9357SAndroid Build Coastguard Worker if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0)
2591*f6dc9357SAndroid Build Coastguard Worker {
2592*f6dc9357SAndroid Build Coastguard Worker const UInt64 memLimit = _ntOptions.MemLimit;
2593*f6dc9357SAndroid Build Coastguard Worker if (memLimit != (UInt64)(Int64)-1)
2594*f6dc9357SAndroid Build Coastguard Worker {
2595*f6dc9357SAndroid Build Coastguard Worker // we overwrite allowedSize
2596*f6dc9357SAndroid Build Coastguard Worker *allowedSize = memLimit;
2597*f6dc9357SAndroid Build Coastguard Worker if (requiredSize <= memLimit)
2598*f6dc9357SAndroid Build Coastguard Worker {
2599*f6dc9357SAndroid Build Coastguard Worker *answerFlags = NRequestMemoryAnswerFlags::k_Allow;
2600*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2601*f6dc9357SAndroid Build Coastguard Worker }
2602*f6dc9357SAndroid Build Coastguard Worker *answerFlags = NRequestMemoryAnswerFlags::k_Limit_Exceeded;
2603*f6dc9357SAndroid Build Coastguard Worker if (flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected)
2604*f6dc9357SAndroid Build Coastguard Worker *answerFlags |= NRequestMemoryAnswerFlags::k_SkipArc;
2605*f6dc9357SAndroid Build Coastguard Worker flags |= NRequestMemoryUseFlags::k_SLimit_Exceeded
2606*f6dc9357SAndroid Build Coastguard Worker | NRequestMemoryUseFlags::k_AllowedSize_WasForced;
2607*f6dc9357SAndroid Build Coastguard Worker }
2608*f6dc9357SAndroid Build Coastguard Worker }
2609*f6dc9357SAndroid Build Coastguard Worker
2610*f6dc9357SAndroid Build Coastguard Worker if (!_requestMemoryUseCallback)
2611*f6dc9357SAndroid Build Coastguard Worker {
2612*f6dc9357SAndroid Build Coastguard Worker _extractCallback2.QueryInterface(IID_IArchiveRequestMemoryUseCallback,
2613*f6dc9357SAndroid Build Coastguard Worker &_requestMemoryUseCallback);
2614*f6dc9357SAndroid Build Coastguard Worker if (!_requestMemoryUseCallback)
2615*f6dc9357SAndroid Build Coastguard Worker {
2616*f6dc9357SAndroid Build Coastguard Worker // keep default (answerFlags) from caller or (answerFlags) that was set in this function
2617*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2618*f6dc9357SAndroid Build Coastguard Worker }
2619*f6dc9357SAndroid Build Coastguard Worker }
2620*f6dc9357SAndroid Build Coastguard Worker
2621*f6dc9357SAndroid Build Coastguard Worker #if 0
2622*f6dc9357SAndroid Build Coastguard Worker if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0)
2623*f6dc9357SAndroid Build Coastguard Worker if (requiredSize <= *allowedSize)
2624*f6dc9357SAndroid Build Coastguard Worker {
2625*f6dc9357SAndroid Build Coastguard Worker // it's expected, that *answerFlags was set to NRequestMemoryAnswerFlags::k_Allow already,
2626*f6dc9357SAndroid Build Coastguard Worker // because it's default answer for (requiredSize <= *allowedSize) case.
2627*f6dc9357SAndroid Build Coastguard Worker *answerFlags = NRequestMemoryAnswerFlags::k_Allow; // optional code
2628*f6dc9357SAndroid Build Coastguard Worker }
2629*f6dc9357SAndroid Build Coastguard Worker else
2630*f6dc9357SAndroid Build Coastguard Worker {
2631*f6dc9357SAndroid Build Coastguard Worker // we clear *answerFlags, because we want to disable dafault "Allow", if it's set.
2632*f6dc9357SAndroid Build Coastguard Worker // *answerFlags = 0;
2633*f6dc9357SAndroid Build Coastguard Worker /*
2634*f6dc9357SAndroid Build Coastguard Worker NRequestMemoryAnswerFlags::k_SkipArc |
2635*f6dc9357SAndroid Build Coastguard Worker NRequestMemoryAnswerFlags::k_Limit_Exceeded;
2636*f6dc9357SAndroid Build Coastguard Worker */
2637*f6dc9357SAndroid Build Coastguard Worker }
2638*f6dc9357SAndroid Build Coastguard Worker #endif
2639*f6dc9357SAndroid Build Coastguard Worker
2640*f6dc9357SAndroid Build Coastguard Worker UString s;
2641*f6dc9357SAndroid Build Coastguard Worker if (!path
2642*f6dc9357SAndroid Build Coastguard Worker && indexType == NArchive::NEventIndexType::kInArcIndex
2643*f6dc9357SAndroid Build Coastguard Worker && index != (UInt32)(Int32)-1
2644*f6dc9357SAndroid Build Coastguard Worker && _arc)
2645*f6dc9357SAndroid Build Coastguard Worker {
2646*f6dc9357SAndroid Build Coastguard Worker RINOK(_arc->GetItem_Path(index, s))
2647*f6dc9357SAndroid Build Coastguard Worker path = s.Ptr();
2648*f6dc9357SAndroid Build Coastguard Worker }
2649*f6dc9357SAndroid Build Coastguard Worker
2650*f6dc9357SAndroid Build Coastguard Worker return _requestMemoryUseCallback->RequestMemoryUse(
2651*f6dc9357SAndroid Build Coastguard Worker flags, indexType, index, path,
2652*f6dc9357SAndroid Build Coastguard Worker requiredSize, allowedSize, answerFlags);
2653*f6dc9357SAndroid Build Coastguard Worker }
2654*f6dc9357SAndroid Build Coastguard Worker
2655*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_SFX
2656*f6dc9357SAndroid Build Coastguard Worker
2657*f6dc9357SAndroid Build Coastguard Worker
2658*f6dc9357SAndroid Build Coastguard Worker
2659*f6dc9357SAndroid Build Coastguard Worker // ------------ After Extracting functions ------------
2660*f6dc9357SAndroid Build Coastguard Worker
2661*f6dc9357SAndroid Build Coastguard Worker void CDirPathSortPair::SetNumSlashes(const FChar *s)
2662*f6dc9357SAndroid Build Coastguard Worker {
2663*f6dc9357SAndroid Build Coastguard Worker for (unsigned numSlashes = 0;;)
2664*f6dc9357SAndroid Build Coastguard Worker {
2665*f6dc9357SAndroid Build Coastguard Worker FChar c = *s++;
2666*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
2667*f6dc9357SAndroid Build Coastguard Worker {
2668*f6dc9357SAndroid Build Coastguard Worker Len = numSlashes;
2669*f6dc9357SAndroid Build Coastguard Worker return;
2670*f6dc9357SAndroid Build Coastguard Worker }
2671*f6dc9357SAndroid Build Coastguard Worker if (IS_PATH_SEPAR(c))
2672*f6dc9357SAndroid Build Coastguard Worker numSlashes++;
2673*f6dc9357SAndroid Build Coastguard Worker }
2674*f6dc9357SAndroid Build Coastguard Worker }
2675*f6dc9357SAndroid Build Coastguard Worker
2676*f6dc9357SAndroid Build Coastguard Worker
2677*f6dc9357SAndroid Build Coastguard Worker bool CDirPathTime::SetDirTime() const
2678*f6dc9357SAndroid Build Coastguard Worker {
2679*f6dc9357SAndroid Build Coastguard Worker return NDir::SetDirTime(Path,
2680*f6dc9357SAndroid Build Coastguard Worker CTime_Defined ? &CTime : NULL,
2681*f6dc9357SAndroid Build Coastguard Worker ATime_Defined ? &ATime : NULL,
2682*f6dc9357SAndroid Build Coastguard Worker MTime_Defined ? &MTime : NULL);
2683*f6dc9357SAndroid Build Coastguard Worker }
2684*f6dc9357SAndroid Build Coastguard Worker
2685*f6dc9357SAndroid Build Coastguard Worker
2686*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::SetDirsTimes()
2687*f6dc9357SAndroid Build Coastguard Worker {
2688*f6dc9357SAndroid Build Coastguard Worker if (!_arc)
2689*f6dc9357SAndroid Build Coastguard Worker return S_OK;
2690*f6dc9357SAndroid Build Coastguard Worker
2691*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CDirPathSortPair> pairs;
2692*f6dc9357SAndroid Build Coastguard Worker pairs.ClearAndSetSize(_extractedFolders.Size());
2693*f6dc9357SAndroid Build Coastguard Worker unsigned i;
2694*f6dc9357SAndroid Build Coastguard Worker
2695*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < _extractedFolders.Size(); i++)
2696*f6dc9357SAndroid Build Coastguard Worker {
2697*f6dc9357SAndroid Build Coastguard Worker CDirPathSortPair &pair = pairs[i];
2698*f6dc9357SAndroid Build Coastguard Worker pair.Index = i;
2699*f6dc9357SAndroid Build Coastguard Worker pair.SetNumSlashes(_extractedFolders[i].Path);
2700*f6dc9357SAndroid Build Coastguard Worker }
2701*f6dc9357SAndroid Build Coastguard Worker
2702*f6dc9357SAndroid Build Coastguard Worker pairs.Sort2();
2703*f6dc9357SAndroid Build Coastguard Worker
2704*f6dc9357SAndroid Build Coastguard Worker HRESULT res = S_OK;
2705*f6dc9357SAndroid Build Coastguard Worker
2706*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < pairs.Size(); i++)
2707*f6dc9357SAndroid Build Coastguard Worker {
2708*f6dc9357SAndroid Build Coastguard Worker const CDirPathTime &dpt = _extractedFolders[pairs[i].Index];
2709*f6dc9357SAndroid Build Coastguard Worker if (!dpt.SetDirTime())
2710*f6dc9357SAndroid Build Coastguard Worker {
2711*f6dc9357SAndroid Build Coastguard Worker // result = E_FAIL;
2712*f6dc9357SAndroid Build Coastguard Worker // do we need error message here in Windows and in posix?
2713*f6dc9357SAndroid Build Coastguard Worker // SendMessageError_with_LastError("Cannot set directory time", dpt.Path);
2714*f6dc9357SAndroid Build Coastguard Worker }
2715*f6dc9357SAndroid Build Coastguard Worker }
2716*f6dc9357SAndroid Build Coastguard Worker
2717*f6dc9357SAndroid Build Coastguard Worker /*
2718*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
2719*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < _delayedSymLinks.Size(); i++)
2720*f6dc9357SAndroid Build Coastguard Worker {
2721*f6dc9357SAndroid Build Coastguard Worker const CDelayedSymLink &link = _delayedSymLinks[i];
2722*f6dc9357SAndroid Build Coastguard Worker if (!link.Create())
2723*f6dc9357SAndroid Build Coastguard Worker {
2724*f6dc9357SAndroid Build Coastguard Worker if (res == S_OK)
2725*f6dc9357SAndroid Build Coastguard Worker res = GetLastError_noZero_HRESULT();
2726*f6dc9357SAndroid Build Coastguard Worker // res = E_FAIL;
2727*f6dc9357SAndroid Build Coastguard Worker // do we need error message here in Windows and in posix?
2728*f6dc9357SAndroid Build Coastguard Worker SendMessageError_with_LastError("Cannot create Symbolic Link", link._source);
2729*f6dc9357SAndroid Build Coastguard Worker }
2730*f6dc9357SAndroid Build Coastguard Worker }
2731*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
2732*f6dc9357SAndroid Build Coastguard Worker */
2733*f6dc9357SAndroid Build Coastguard Worker
2734*f6dc9357SAndroid Build Coastguard Worker ClearExtractedDirsInfo();
2735*f6dc9357SAndroid Build Coastguard Worker return res;
2736*f6dc9357SAndroid Build Coastguard Worker }
2737*f6dc9357SAndroid Build Coastguard Worker
2738*f6dc9357SAndroid Build Coastguard Worker
2739*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveExtractCallback::CloseArc()
2740*f6dc9357SAndroid Build Coastguard Worker {
2741*f6dc9357SAndroid Build Coastguard Worker HRESULT res = CloseReparseAndFile();
2742*f6dc9357SAndroid Build Coastguard Worker const HRESULT res2 = SetDirsTimes();
2743*f6dc9357SAndroid Build Coastguard Worker if (res == S_OK)
2744*f6dc9357SAndroid Build Coastguard Worker res = res2;
2745*f6dc9357SAndroid Build Coastguard Worker _arc = NULL;
2746*f6dc9357SAndroid Build Coastguard Worker return res;
2747*f6dc9357SAndroid Build Coastguard Worker }
2748