xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Agent/AgentOut.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // AgentOut.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/TimeUtils.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/CopyCoder.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FileStreams.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "../../Archive/Common/ItemNameUtils.h"
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #include "Agent.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "UpdateCallbackAgent.h"
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
21*f6dc9357SAndroid Build Coastguard Worker using namespace NCOM;
22*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgent::SetFolder (IFolderFolder * folder))23*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgent::SetFolder(IFolderFolder *folder))
24*f6dc9357SAndroid Build Coastguard Worker {
25*f6dc9357SAndroid Build Coastguard Worker   _updatePathPrefix.Empty();
26*f6dc9357SAndroid Build Coastguard Worker   _updatePathPrefix_is_AltFolder = false;
27*f6dc9357SAndroid Build Coastguard Worker   _agentFolder = NULL;
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker   if (!folder)
30*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
31*f6dc9357SAndroid Build Coastguard Worker 
32*f6dc9357SAndroid Build Coastguard Worker   {
33*f6dc9357SAndroid Build Coastguard Worker     Z7_DECL_CMyComPtr_QI_FROM(
34*f6dc9357SAndroid Build Coastguard Worker         IArchiveFolderInternal,
35*f6dc9357SAndroid Build Coastguard Worker         afi, folder)
36*f6dc9357SAndroid Build Coastguard Worker     if (afi)
37*f6dc9357SAndroid Build Coastguard Worker     {
38*f6dc9357SAndroid Build Coastguard Worker       RINOK(afi->GetAgentFolder(&_agentFolder))
39*f6dc9357SAndroid Build Coastguard Worker     }
40*f6dc9357SAndroid Build Coastguard Worker     if (!_agentFolder)
41*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
42*f6dc9357SAndroid Build Coastguard Worker   }
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker   if (_proxy2)
45*f6dc9357SAndroid Build Coastguard Worker     _updatePathPrefix = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, _updatePathPrefix_is_AltFolder);
46*f6dc9357SAndroid Build Coastguard Worker   else
47*f6dc9357SAndroid Build Coastguard Worker     _updatePathPrefix = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex);
48*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
49*f6dc9357SAndroid Build Coastguard Worker }
50*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgent::SetFiles (const wchar_t * folderPrefix,const wchar_t * const * names,UInt32 numNames))51*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgent::SetFiles(const wchar_t *folderPrefix,
52*f6dc9357SAndroid Build Coastguard Worker     const wchar_t * const *names, UInt32 numNames))
53*f6dc9357SAndroid Build Coastguard Worker {
54*f6dc9357SAndroid Build Coastguard Worker   _folderPrefix = us2fs(folderPrefix);
55*f6dc9357SAndroid Build Coastguard Worker   _names.ClearAndReserve(numNames);
56*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numNames; i++)
57*f6dc9357SAndroid Build Coastguard Worker     _names.AddInReserved(us2fs(names[i]));
58*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
59*f6dc9357SAndroid Build Coastguard Worker }
60*f6dc9357SAndroid Build Coastguard Worker 
EnumerateArchiveItems(CAgent * agent,const CProxyDir & item,const UString & prefix,CObjectVector<CArcItem> & arcItems)61*f6dc9357SAndroid Build Coastguard Worker static HRESULT EnumerateArchiveItems(CAgent *agent,
62*f6dc9357SAndroid Build Coastguard Worker     const CProxyDir &item,
63*f6dc9357SAndroid Build Coastguard Worker     const UString &prefix,
64*f6dc9357SAndroid Build Coastguard Worker     CObjectVector<CArcItem> &arcItems)
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
67*f6dc9357SAndroid Build Coastguard Worker 
68*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < item.SubFiles.Size(); i++)
69*f6dc9357SAndroid Build Coastguard Worker   {
70*f6dc9357SAndroid Build Coastguard Worker     unsigned arcIndex = item.SubFiles[i];
71*f6dc9357SAndroid Build Coastguard Worker     const CProxyFile &fileItem = agent->_proxy->Files[arcIndex];
72*f6dc9357SAndroid Build Coastguard Worker     CArcItem ai;
73*f6dc9357SAndroid Build Coastguard Worker     RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime))
74*f6dc9357SAndroid Build Coastguard Worker     RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined))
75*f6dc9357SAndroid Build Coastguard Worker     ai.IsDir = false;
76*f6dc9357SAndroid Build Coastguard Worker     ai.Name = prefix + fileItem.Name;
77*f6dc9357SAndroid Build Coastguard Worker     ai.Censored = true; // test it
78*f6dc9357SAndroid Build Coastguard Worker     ai.IndexInServer = arcIndex;
79*f6dc9357SAndroid Build Coastguard Worker     arcItems.Add(ai);
80*f6dc9357SAndroid Build Coastguard Worker   }
81*f6dc9357SAndroid Build Coastguard Worker 
82*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < item.SubDirs.Size(); i++)
83*f6dc9357SAndroid Build Coastguard Worker   {
84*f6dc9357SAndroid Build Coastguard Worker     const CProxyDir &dirItem = agent->_proxy->Dirs[item.SubDirs[i]];
85*f6dc9357SAndroid Build Coastguard Worker     UString fullName = prefix + dirItem.Name;
86*f6dc9357SAndroid Build Coastguard Worker     if (dirItem.IsLeaf())
87*f6dc9357SAndroid Build Coastguard Worker     {
88*f6dc9357SAndroid Build Coastguard Worker       CArcItem ai;
89*f6dc9357SAndroid Build Coastguard Worker       RINOK(agent->GetArc().GetItem_MTime((unsigned)dirItem.ArcIndex, ai.MTime))
90*f6dc9357SAndroid Build Coastguard Worker       ai.IsDir = true;
91*f6dc9357SAndroid Build Coastguard Worker       ai.Size_Defined = false;
92*f6dc9357SAndroid Build Coastguard Worker       ai.Name = fullName;
93*f6dc9357SAndroid Build Coastguard Worker       ai.Censored = true; // test it
94*f6dc9357SAndroid Build Coastguard Worker       ai.IndexInServer = (unsigned)dirItem.ArcIndex;
95*f6dc9357SAndroid Build Coastguard Worker       arcItems.Add(ai);
96*f6dc9357SAndroid Build Coastguard Worker     }
97*f6dc9357SAndroid Build Coastguard Worker     RINOK(EnumerateArchiveItems(agent, dirItem, fullName + WCHAR_PATH_SEPARATOR, arcItems))
98*f6dc9357SAndroid Build Coastguard Worker   }
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
101*f6dc9357SAndroid Build Coastguard Worker }
102*f6dc9357SAndroid Build Coastguard Worker 
EnumerateArchiveItems2(const CAgent * agent,unsigned dirIndex,const UString & prefix,CObjectVector<CArcItem> & arcItems)103*f6dc9357SAndroid Build Coastguard Worker static HRESULT EnumerateArchiveItems2(const CAgent *agent,
104*f6dc9357SAndroid Build Coastguard Worker     unsigned dirIndex,
105*f6dc9357SAndroid Build Coastguard Worker     const UString &prefix,
106*f6dc9357SAndroid Build Coastguard Worker     CObjectVector<CArcItem> &arcItems)
107*f6dc9357SAndroid Build Coastguard Worker {
108*f6dc9357SAndroid Build Coastguard Worker   const CProxyDir2 &dir = agent->_proxy2->Dirs[dirIndex];
109*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, dir.Items)
110*f6dc9357SAndroid Build Coastguard Worker   {
111*f6dc9357SAndroid Build Coastguard Worker     unsigned arcIndex = dir.Items[i];
112*f6dc9357SAndroid Build Coastguard Worker     const CProxyFile2 &file = agent->_proxy2->Files[arcIndex];
113*f6dc9357SAndroid Build Coastguard Worker     CArcItem ai;
114*f6dc9357SAndroid Build Coastguard Worker     ai.IndexInServer = arcIndex;
115*f6dc9357SAndroid Build Coastguard Worker     ai.Name = prefix + file.Name;
116*f6dc9357SAndroid Build Coastguard Worker     ai.Censored = true; // test it
117*f6dc9357SAndroid Build Coastguard Worker     RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime))
118*f6dc9357SAndroid Build Coastguard Worker     ai.IsDir = file.IsDir();
119*f6dc9357SAndroid Build Coastguard Worker     ai.Size_Defined = false;
120*f6dc9357SAndroid Build Coastguard Worker     ai.IsAltStream = file.IsAltStream;
121*f6dc9357SAndroid Build Coastguard Worker     if (!ai.IsDir)
122*f6dc9357SAndroid Build Coastguard Worker     {
123*f6dc9357SAndroid Build Coastguard Worker       RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined))
124*f6dc9357SAndroid Build Coastguard Worker       ai.IsDir = false;
125*f6dc9357SAndroid Build Coastguard Worker     }
126*f6dc9357SAndroid Build Coastguard Worker     arcItems.Add(ai);
127*f6dc9357SAndroid Build Coastguard Worker 
128*f6dc9357SAndroid Build Coastguard Worker     if (file.AltDirIndex != -1)
129*f6dc9357SAndroid Build Coastguard Worker     {
130*f6dc9357SAndroid Build Coastguard Worker       RINOK(EnumerateArchiveItems2(agent, (unsigned)file.AltDirIndex, ai.Name + L':', arcItems))
131*f6dc9357SAndroid Build Coastguard Worker     }
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker     if (ai.IsDir)
134*f6dc9357SAndroid Build Coastguard Worker     {
135*f6dc9357SAndroid Build Coastguard Worker       RINOK(EnumerateArchiveItems2(agent, (unsigned)file.DirIndex, ai.Name + WCHAR_PATH_SEPARATOR, arcItems))
136*f6dc9357SAndroid Build Coastguard Worker     }
137*f6dc9357SAndroid Build Coastguard Worker   }
138*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
139*f6dc9357SAndroid Build Coastguard Worker }
140*f6dc9357SAndroid Build Coastguard Worker 
141*f6dc9357SAndroid Build Coastguard Worker struct CAgUpCallbackImp Z7_final: public IUpdateProduceCallback
142*f6dc9357SAndroid Build Coastguard Worker {
143*f6dc9357SAndroid Build Coastguard Worker   const CObjectVector<CArcItem> *_arcItems;
144*f6dc9357SAndroid Build Coastguard Worker   IFolderArchiveUpdateCallback *_callback;
145*f6dc9357SAndroid Build Coastguard Worker 
CAgUpCallbackImpZ7_final146*f6dc9357SAndroid Build Coastguard Worker   CAgUpCallbackImp(const CObjectVector<CArcItem> *a,
147*f6dc9357SAndroid Build Coastguard Worker       IFolderArchiveUpdateCallback *callback): _arcItems(a), _callback(callback) {}
148*f6dc9357SAndroid Build Coastguard Worker   HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override;
149*f6dc9357SAndroid Build Coastguard Worker };
150*f6dc9357SAndroid Build Coastguard Worker 
ShowDeleteFile(unsigned arcIndex)151*f6dc9357SAndroid Build Coastguard Worker HRESULT CAgUpCallbackImp::ShowDeleteFile(unsigned arcIndex)
152*f6dc9357SAndroid Build Coastguard Worker {
153*f6dc9357SAndroid Build Coastguard Worker   return _callback->DeleteOperation((*_arcItems)[arcIndex].Name);
154*f6dc9357SAndroid Build Coastguard Worker }
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker 
SetInArchiveInterfaces(CAgent * agent,CArchiveUpdateCallback * upd)157*f6dc9357SAndroid Build Coastguard Worker static void SetInArchiveInterfaces(CAgent *agent, CArchiveUpdateCallback *upd)
158*f6dc9357SAndroid Build Coastguard Worker {
159*f6dc9357SAndroid Build Coastguard Worker   if (agent->_archiveLink.Arcs.IsEmpty())
160*f6dc9357SAndroid Build Coastguard Worker     return;
161*f6dc9357SAndroid Build Coastguard Worker   const CArc &arc = agent->GetArc();
162*f6dc9357SAndroid Build Coastguard Worker   upd->Arc = &arc;
163*f6dc9357SAndroid Build Coastguard Worker   upd->Archive = arc.Archive;
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker   upd->ArcFileName = ExtractFileNameFromPath(arc.Path);
166*f6dc9357SAndroid Build Coastguard Worker }
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker struct CDirItemsCallback_AgentOut Z7_final: public IDirItemsCallback
169*f6dc9357SAndroid Build Coastguard Worker {
170*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderScanProgress> FolderScanProgress;
171*f6dc9357SAndroid Build Coastguard Worker   IFolderArchiveUpdateCallback *FolderArchiveUpdateCallback;
172*f6dc9357SAndroid Build Coastguard Worker   HRESULT ErrorCode;
173*f6dc9357SAndroid Build Coastguard Worker 
CDirItemsCallback_AgentOutZ7_final174*f6dc9357SAndroid Build Coastguard Worker   CDirItemsCallback_AgentOut(): FolderArchiveUpdateCallback(NULL), ErrorCode(S_OK) {}
175*f6dc9357SAndroid Build Coastguard Worker 
ScanErrorZ7_final176*f6dc9357SAndroid Build Coastguard Worker   HRESULT ScanError(const FString &name, DWORD systemError) Z7_override
177*f6dc9357SAndroid Build Coastguard Worker   {
178*f6dc9357SAndroid Build Coastguard Worker     const HRESULT hres = HRESULT_FROM_WIN32(systemError);
179*f6dc9357SAndroid Build Coastguard Worker     if (FolderArchiveUpdateCallback)
180*f6dc9357SAndroid Build Coastguard Worker       return FolderScanProgress->ScanError(fs2us(name), hres);
181*f6dc9357SAndroid Build Coastguard Worker     ErrorCode = hres;
182*f6dc9357SAndroid Build Coastguard Worker     return ErrorCode;
183*f6dc9357SAndroid Build Coastguard Worker   }
184*f6dc9357SAndroid Build Coastguard Worker 
ScanProgressZ7_final185*f6dc9357SAndroid Build Coastguard Worker   HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) Z7_override
186*f6dc9357SAndroid Build Coastguard Worker   {
187*f6dc9357SAndroid Build Coastguard Worker     if (FolderScanProgress)
188*f6dc9357SAndroid Build Coastguard Worker       return FolderScanProgress->ScanProgress(st.NumDirs, st.NumFiles + st.NumAltStreams,
189*f6dc9357SAndroid Build Coastguard Worker           st.GetTotalBytes(), fs2us(path), BoolToInt(isDir));
190*f6dc9357SAndroid Build Coastguard Worker     if (FolderArchiveUpdateCallback)
191*f6dc9357SAndroid Build Coastguard Worker       return FolderArchiveUpdateCallback->SetNumFiles(st.NumFiles);
192*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
193*f6dc9357SAndroid Build Coastguard Worker   }
194*f6dc9357SAndroid Build Coastguard Worker };
195*f6dc9357SAndroid Build Coastguard Worker 
196*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgent::DoOperation (FStringVector * requestedPaths,FStringVector * processedPaths,CCodecs * codecs,int formatIndex,ISequentialOutStream * outArchiveStream,const Byte * stateActions,const wchar_t * sfxModule,IFolderArchiveUpdateCallback * updateCallback100))197*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgent::DoOperation(
198*f6dc9357SAndroid Build Coastguard Worker     FStringVector *requestedPaths,
199*f6dc9357SAndroid Build Coastguard Worker     FStringVector *processedPaths,
200*f6dc9357SAndroid Build Coastguard Worker     CCodecs *codecs,
201*f6dc9357SAndroid Build Coastguard Worker     int formatIndex,
202*f6dc9357SAndroid Build Coastguard Worker     ISequentialOutStream *outArchiveStream,
203*f6dc9357SAndroid Build Coastguard Worker     const Byte *stateActions,
204*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *sfxModule,
205*f6dc9357SAndroid Build Coastguard Worker     IFolderArchiveUpdateCallback *updateCallback100))
206*f6dc9357SAndroid Build Coastguard Worker {
207*f6dc9357SAndroid Build Coastguard Worker   if (!CanUpdate())
208*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
209*f6dc9357SAndroid Build Coastguard Worker 
210*f6dc9357SAndroid Build Coastguard Worker   NUpdateArchive::CActionSet actionSet;
211*f6dc9357SAndroid Build Coastguard Worker   {
212*f6dc9357SAndroid Build Coastguard Worker     for (unsigned i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
213*f6dc9357SAndroid Build Coastguard Worker       actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
214*f6dc9357SAndroid Build Coastguard Worker   }
215*f6dc9357SAndroid Build Coastguard Worker 
216*f6dc9357SAndroid Build Coastguard Worker   CDirItemsCallback_AgentOut enumCallback;
217*f6dc9357SAndroid Build Coastguard Worker   if (updateCallback100)
218*f6dc9357SAndroid Build Coastguard Worker   {
219*f6dc9357SAndroid Build Coastguard Worker     enumCallback.FolderArchiveUpdateCallback = updateCallback100;
220*f6dc9357SAndroid Build Coastguard Worker     updateCallback100->QueryInterface(IID_IFolderScanProgress, (void **)&enumCallback.FolderScanProgress);
221*f6dc9357SAndroid Build Coastguard Worker   }
222*f6dc9357SAndroid Build Coastguard Worker 
223*f6dc9357SAndroid Build Coastguard Worker   CDirItems dirItems;
224*f6dc9357SAndroid Build Coastguard Worker   dirItems.Callback = &enumCallback;
225*f6dc9357SAndroid Build Coastguard Worker 
226*f6dc9357SAndroid Build Coastguard Worker   {
227*f6dc9357SAndroid Build Coastguard Worker     FString folderPrefix = _folderPrefix;
228*f6dc9357SAndroid Build Coastguard Worker     if (!NFile::NName::IsAltStreamPrefixWithColon(fs2us(folderPrefix)))
229*f6dc9357SAndroid Build Coastguard Worker       NFile::NName::NormalizeDirPathPrefix(folderPrefix);
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker     RINOK(dirItems.EnumerateItems2(folderPrefix, _updatePathPrefix, _names, requestedPaths))
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker     if (_updatePathPrefix_is_AltFolder)
234*f6dc9357SAndroid Build Coastguard Worker     {
235*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR(i, dirItems.Items)
236*f6dc9357SAndroid Build Coastguard Worker       {
237*f6dc9357SAndroid Build Coastguard Worker         CDirItem &item = dirItems.Items[i];
238*f6dc9357SAndroid Build Coastguard Worker         if (item.IsDir())
239*f6dc9357SAndroid Build Coastguard Worker           return E_NOTIMPL;
240*f6dc9357SAndroid Build Coastguard Worker         item.IsAltStream = true;
241*f6dc9357SAndroid Build Coastguard Worker       }
242*f6dc9357SAndroid Build Coastguard Worker     }
243*f6dc9357SAndroid Build Coastguard Worker   }
244*f6dc9357SAndroid Build Coastguard Worker 
245*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IOutArchive> outArchive;
246*f6dc9357SAndroid Build Coastguard Worker 
247*f6dc9357SAndroid Build Coastguard Worker   if (GetArchive())
248*f6dc9357SAndroid Build Coastguard Worker   {
249*f6dc9357SAndroid Build Coastguard Worker     RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive))
250*f6dc9357SAndroid Build Coastguard Worker   }
251*f6dc9357SAndroid Build Coastguard Worker   else
252*f6dc9357SAndroid Build Coastguard Worker   {
253*f6dc9357SAndroid Build Coastguard Worker     if (formatIndex < 0)
254*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
255*f6dc9357SAndroid Build Coastguard Worker     RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive))
256*f6dc9357SAndroid Build Coastguard Worker 
257*f6dc9357SAndroid Build Coastguard Worker     #ifdef Z7_EXTERNAL_CODECS
258*f6dc9357SAndroid Build Coastguard Worker     {
259*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
260*f6dc9357SAndroid Build Coastguard Worker       outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
261*f6dc9357SAndroid Build Coastguard Worker       if (setCompressCodecsInfo)
262*f6dc9357SAndroid Build Coastguard Worker       {
263*f6dc9357SAndroid Build Coastguard Worker         RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs))
264*f6dc9357SAndroid Build Coastguard Worker       }
265*f6dc9357SAndroid Build Coastguard Worker     }
266*f6dc9357SAndroid Build Coastguard Worker     #endif
267*f6dc9357SAndroid Build Coastguard Worker   }
268*f6dc9357SAndroid Build Coastguard Worker 
269*f6dc9357SAndroid Build Coastguard Worker   NFileTimeType::EEnum fileTimeType = NFileTimeType::kNotDefined;
270*f6dc9357SAndroid Build Coastguard Worker   UInt32 value;
271*f6dc9357SAndroid Build Coastguard Worker   RINOK(outArchive->GetFileTimeType(&value))
272*f6dc9357SAndroid Build Coastguard Worker   // we support any future fileType here.
273*f6dc9357SAndroid Build Coastguard Worker   // 22.00:
274*f6dc9357SAndroid Build Coastguard Worker   fileTimeType = (NFileTimeType::EEnum)value;
275*f6dc9357SAndroid Build Coastguard Worker   /*
276*f6dc9357SAndroid Build Coastguard Worker   switch (value)
277*f6dc9357SAndroid Build Coastguard Worker   {
278*f6dc9357SAndroid Build Coastguard Worker     case NFileTimeType::kWindows:
279*f6dc9357SAndroid Build Coastguard Worker     case NFileTimeType::kDOS:
280*f6dc9357SAndroid Build Coastguard Worker     case NFileTimeType::kUnix:
281*f6dc9357SAndroid Build Coastguard Worker       fileTimeType = NFileTimeType::EEnum(value);
282*f6dc9357SAndroid Build Coastguard Worker       break;
283*f6dc9357SAndroid Build Coastguard Worker     default:
284*f6dc9357SAndroid Build Coastguard Worker     {
285*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
286*f6dc9357SAndroid Build Coastguard Worker     }
287*f6dc9357SAndroid Build Coastguard Worker   }
288*f6dc9357SAndroid Build Coastguard Worker   */
289*f6dc9357SAndroid Build Coastguard Worker 
290*f6dc9357SAndroid Build Coastguard Worker 
291*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CArcItem> arcItems;
292*f6dc9357SAndroid Build Coastguard Worker   if (GetArchive())
293*f6dc9357SAndroid Build Coastguard Worker   {
294*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadItems())
295*f6dc9357SAndroid Build Coastguard Worker     if (_proxy2)
296*f6dc9357SAndroid Build Coastguard Worker     {
297*f6dc9357SAndroid Build Coastguard Worker       RINOK(EnumerateArchiveItems2(this, k_Proxy2_RootDirIndex, L"", arcItems))
298*f6dc9357SAndroid Build Coastguard Worker       RINOK(EnumerateArchiveItems2(this, k_Proxy2_AltRootDirIndex, L":", arcItems))
299*f6dc9357SAndroid Build Coastguard Worker     }
300*f6dc9357SAndroid Build Coastguard Worker     else
301*f6dc9357SAndroid Build Coastguard Worker     {
302*f6dc9357SAndroid Build Coastguard Worker       RINOK(EnumerateArchiveItems(this, _proxy->Dirs[0], L"", arcItems))
303*f6dc9357SAndroid Build Coastguard Worker     }
304*f6dc9357SAndroid Build Coastguard Worker   }
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CUpdatePair2> updatePairs2;
307*f6dc9357SAndroid Build Coastguard Worker 
308*f6dc9357SAndroid Build Coastguard Worker   {
309*f6dc9357SAndroid Build Coastguard Worker     CRecordVector<CUpdatePair> updatePairs;
310*f6dc9357SAndroid Build Coastguard Worker     GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs);
311*f6dc9357SAndroid Build Coastguard Worker     CAgUpCallbackImp upCallback(&arcItems, updateCallback100);
312*f6dc9357SAndroid Build Coastguard Worker     UpdateProduce(updatePairs, actionSet, updatePairs2, &upCallback);
313*f6dc9357SAndroid Build Coastguard Worker   }
314*f6dc9357SAndroid Build Coastguard Worker 
315*f6dc9357SAndroid Build Coastguard Worker   UInt32 numFiles = 0;
316*f6dc9357SAndroid Build Coastguard Worker   {
317*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, updatePairs2)
318*f6dc9357SAndroid Build Coastguard Worker       if (updatePairs2[i].NewData)
319*f6dc9357SAndroid Build Coastguard Worker         numFiles++;
320*f6dc9357SAndroid Build Coastguard Worker   }
321*f6dc9357SAndroid Build Coastguard Worker 
322*f6dc9357SAndroid Build Coastguard Worker   if (updateCallback100)
323*f6dc9357SAndroid Build Coastguard Worker   {
324*f6dc9357SAndroid Build Coastguard Worker     RINOK(updateCallback100->SetNumFiles(numFiles))
325*f6dc9357SAndroid Build Coastguard Worker   }
326*f6dc9357SAndroid Build Coastguard Worker 
327*f6dc9357SAndroid Build Coastguard Worker   CUpdateCallbackAgent updateCallbackAgent;
328*f6dc9357SAndroid Build Coastguard Worker   updateCallbackAgent.SetCallback(updateCallback100);
329*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<IArchiveUpdateCallback, CArchiveUpdateCallback> updateCallback;
330*f6dc9357SAndroid Build Coastguard Worker 
331*f6dc9357SAndroid Build Coastguard Worker   updateCallback->DirItems = &dirItems;
332*f6dc9357SAndroid Build Coastguard Worker   updateCallback->ArcItems = &arcItems;
333*f6dc9357SAndroid Build Coastguard Worker   updateCallback->UpdatePairs = &updatePairs2;
334*f6dc9357SAndroid Build Coastguard Worker 
335*f6dc9357SAndroid Build Coastguard Worker   SetInArchiveInterfaces(this, updateCallback.ClsPtr());
336*f6dc9357SAndroid Build Coastguard Worker 
337*f6dc9357SAndroid Build Coastguard Worker   updateCallback->Callback = &updateCallbackAgent;
338*f6dc9357SAndroid Build Coastguard Worker 
339*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer processedItems;
340*f6dc9357SAndroid Build Coastguard Worker   if (processedPaths)
341*f6dc9357SAndroid Build Coastguard Worker   {
342*f6dc9357SAndroid Build Coastguard Worker     unsigned num = dirItems.Items.Size();
343*f6dc9357SAndroid Build Coastguard Worker     processedItems.Alloc(num);
344*f6dc9357SAndroid Build Coastguard Worker     for (unsigned i = 0; i < num; i++)
345*f6dc9357SAndroid Build Coastguard Worker       processedItems[i] = 0;
346*f6dc9357SAndroid Build Coastguard Worker     updateCallback->ProcessedItemsStatuses = processedItems;
347*f6dc9357SAndroid Build Coastguard Worker   }
348*f6dc9357SAndroid Build Coastguard Worker 
349*f6dc9357SAndroid Build Coastguard Worker   Z7_DECL_CMyComPtr_QI_FROM(
350*f6dc9357SAndroid Build Coastguard Worker       ISetProperties,
351*f6dc9357SAndroid Build Coastguard Worker       setProperties, outArchive)
352*f6dc9357SAndroid Build Coastguard Worker   if (setProperties)
353*f6dc9357SAndroid Build Coastguard Worker   {
354*f6dc9357SAndroid Build Coastguard Worker     if (m_PropNames.Size() == 0)
355*f6dc9357SAndroid Build Coastguard Worker     {
356*f6dc9357SAndroid Build Coastguard Worker       RINOK(setProperties->SetProperties(NULL, NULL, 0))
357*f6dc9357SAndroid Build Coastguard Worker     }
358*f6dc9357SAndroid Build Coastguard Worker     else
359*f6dc9357SAndroid Build Coastguard Worker     {
360*f6dc9357SAndroid Build Coastguard Worker       CRecordVector<const wchar_t *> names;
361*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (i, m_PropNames)
362*f6dc9357SAndroid Build Coastguard Worker         names.Add((const wchar_t *)m_PropNames[i]);
363*f6dc9357SAndroid Build Coastguard Worker 
364*f6dc9357SAndroid Build Coastguard Worker       CPropVariant *propValues = new CPropVariant[m_PropValues.Size()];
365*f6dc9357SAndroid Build Coastguard Worker       try
366*f6dc9357SAndroid Build Coastguard Worker       {
367*f6dc9357SAndroid Build Coastguard Worker         FOR_VECTOR (i, m_PropValues)
368*f6dc9357SAndroid Build Coastguard Worker           propValues[i] = m_PropValues[i];
369*f6dc9357SAndroid Build Coastguard Worker         RINOK(setProperties->SetProperties(names.ConstData(), propValues, names.Size()))
370*f6dc9357SAndroid Build Coastguard Worker       }
371*f6dc9357SAndroid Build Coastguard Worker       catch(...)
372*f6dc9357SAndroid Build Coastguard Worker       {
373*f6dc9357SAndroid Build Coastguard Worker         delete []propValues;
374*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
375*f6dc9357SAndroid Build Coastguard Worker       }
376*f6dc9357SAndroid Build Coastguard Worker       delete []propValues;
377*f6dc9357SAndroid Build Coastguard Worker     }
378*f6dc9357SAndroid Build Coastguard Worker   }
379*f6dc9357SAndroid Build Coastguard Worker   m_PropNames.Clear();
380*f6dc9357SAndroid Build Coastguard Worker   m_PropValues.Clear();
381*f6dc9357SAndroid Build Coastguard Worker 
382*f6dc9357SAndroid Build Coastguard Worker   if (sfxModule != NULL)
383*f6dc9357SAndroid Build Coastguard Worker   {
384*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr2_Create<IInStream, CInFileStream> sfxStream;
385*f6dc9357SAndroid Build Coastguard Worker     if (!sfxStream->Open(us2fs(sfxModule)))
386*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
387*f6dc9357SAndroid Build Coastguard Worker       // throw "Can't open sfx module";
388*f6dc9357SAndroid Build Coastguard Worker     RINOK(NCompress::CopyStream(sfxStream, outArchiveStream, NULL))
389*f6dc9357SAndroid Build Coastguard Worker   }
390*f6dc9357SAndroid Build Coastguard Worker 
391*f6dc9357SAndroid Build Coastguard Worker   const HRESULT res = outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(), updateCallback);
392*f6dc9357SAndroid Build Coastguard Worker   if (res == S_OK && processedPaths)
393*f6dc9357SAndroid Build Coastguard Worker   {
394*f6dc9357SAndroid Build Coastguard Worker     {
395*f6dc9357SAndroid Build Coastguard Worker       /* OutHandler for 7z archives doesn't report compression operation for empty files.
396*f6dc9357SAndroid Build Coastguard Worker          So we must include these files manually */
397*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR(i, updatePairs2)
398*f6dc9357SAndroid Build Coastguard Worker       {
399*f6dc9357SAndroid Build Coastguard Worker         const CUpdatePair2 &up = updatePairs2[i];
400*f6dc9357SAndroid Build Coastguard Worker         if (up.DirIndex != -1 && up.NewData)
401*f6dc9357SAndroid Build Coastguard Worker         {
402*f6dc9357SAndroid Build Coastguard Worker           const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex];
403*f6dc9357SAndroid Build Coastguard Worker           if (!di.IsDir() && di.Size == 0)
404*f6dc9357SAndroid Build Coastguard Worker             processedItems[(unsigned)up.DirIndex] = 1;
405*f6dc9357SAndroid Build Coastguard Worker         }
406*f6dc9357SAndroid Build Coastguard Worker       }
407*f6dc9357SAndroid Build Coastguard Worker     }
408*f6dc9357SAndroid Build Coastguard Worker 
409*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, dirItems.Items)
410*f6dc9357SAndroid Build Coastguard Worker       if (processedItems[i] != 0)
411*f6dc9357SAndroid Build Coastguard Worker         processedPaths->Add(dirItems.GetPhyPath(i));
412*f6dc9357SAndroid Build Coastguard Worker   }
413*f6dc9357SAndroid Build Coastguard Worker   return res;
414*f6dc9357SAndroid Build Coastguard Worker }
415*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgent::DoOperation2 (FStringVector * requestedPaths,FStringVector * processedPaths,ISequentialOutStream * outArchiveStream,const Byte * stateActions,const wchar_t * sfxModule,IFolderArchiveUpdateCallback * updateCallback100))416*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgent::DoOperation2(
417*f6dc9357SAndroid Build Coastguard Worker     FStringVector *requestedPaths,
418*f6dc9357SAndroid Build Coastguard Worker     FStringVector *processedPaths,
419*f6dc9357SAndroid Build Coastguard Worker     ISequentialOutStream *outArchiveStream,
420*f6dc9357SAndroid Build Coastguard Worker     const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100))
421*f6dc9357SAndroid Build Coastguard Worker {
422*f6dc9357SAndroid Build Coastguard Worker   return DoOperation(requestedPaths, processedPaths, g_CodecsObj, -1, outArchiveStream, stateActions, sfxModule, updateCallback100);
423*f6dc9357SAndroid Build Coastguard Worker }
424*f6dc9357SAndroid Build Coastguard Worker 
CommonUpdate(ISequentialOutStream * outArchiveStream,unsigned numUpdateItems,IArchiveUpdateCallback * updateCallback)425*f6dc9357SAndroid Build Coastguard Worker HRESULT CAgent::CommonUpdate(ISequentialOutStream *outArchiveStream,
426*f6dc9357SAndroid Build Coastguard Worker     unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback)
427*f6dc9357SAndroid Build Coastguard Worker {
428*f6dc9357SAndroid Build Coastguard Worker   if (!CanUpdate())
429*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
430*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IOutArchive> outArchive;
431*f6dc9357SAndroid Build Coastguard Worker   RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive))
432*f6dc9357SAndroid Build Coastguard Worker   return outArchive->UpdateItems(outArchiveStream, numUpdateItems, updateCallback);
433*f6dc9357SAndroid Build Coastguard Worker }
434*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgent::DeleteItems (ISequentialOutStream * outArchiveStream,const UInt32 * indices,UInt32 numItems,IFolderArchiveUpdateCallback * updateCallback100))435*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgent::DeleteItems(ISequentialOutStream *outArchiveStream,
436*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *indices, UInt32 numItems,
437*f6dc9357SAndroid Build Coastguard Worker     IFolderArchiveUpdateCallback *updateCallback100))
438*f6dc9357SAndroid Build Coastguard Worker {
439*f6dc9357SAndroid Build Coastguard Worker   if (!CanUpdate())
440*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
441*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CUpdatePair2> updatePairs;
442*f6dc9357SAndroid Build Coastguard Worker   CUpdateCallbackAgent updateCallbackAgent;
443*f6dc9357SAndroid Build Coastguard Worker   updateCallbackAgent.SetCallback(updateCallback100);
444*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<IArchiveUpdateCallback, CArchiveUpdateCallback> updateCallback;
445*f6dc9357SAndroid Build Coastguard Worker 
446*f6dc9357SAndroid Build Coastguard Worker   CUIntVector realIndices;
447*f6dc9357SAndroid Build Coastguard Worker   _agentFolder->GetRealIndices(indices, numItems,
448*f6dc9357SAndroid Build Coastguard Worker       true, // includeAltStreams
449*f6dc9357SAndroid Build Coastguard Worker       false, // includeFolderSubItemsInFlatMode, we don't want to delete subItems in Flat Mode
450*f6dc9357SAndroid Build Coastguard Worker       realIndices);
451*f6dc9357SAndroid Build Coastguard Worker   unsigned curIndex = 0;
452*f6dc9357SAndroid Build Coastguard Worker   UInt32 numItemsInArchive;
453*f6dc9357SAndroid Build Coastguard Worker   RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive))
454*f6dc9357SAndroid Build Coastguard Worker 
455*f6dc9357SAndroid Build Coastguard Worker   UString deletePath;
456*f6dc9357SAndroid Build Coastguard Worker 
457*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItemsInArchive; i++)
458*f6dc9357SAndroid Build Coastguard Worker   {
459*f6dc9357SAndroid Build Coastguard Worker     if (curIndex < realIndices.Size())
460*f6dc9357SAndroid Build Coastguard Worker       if (realIndices[curIndex] == i)
461*f6dc9357SAndroid Build Coastguard Worker       {
462*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetArc().GetItem_Path2(i, deletePath))
463*f6dc9357SAndroid Build Coastguard Worker         RINOK(updateCallback100->DeleteOperation(deletePath))
464*f6dc9357SAndroid Build Coastguard Worker 
465*f6dc9357SAndroid Build Coastguard Worker         curIndex++;
466*f6dc9357SAndroid Build Coastguard Worker         continue;
467*f6dc9357SAndroid Build Coastguard Worker       }
468*f6dc9357SAndroid Build Coastguard Worker     CUpdatePair2 up2;
469*f6dc9357SAndroid Build Coastguard Worker     up2.SetAs_NoChangeArcItem(i);
470*f6dc9357SAndroid Build Coastguard Worker     updatePairs.Add(up2);
471*f6dc9357SAndroid Build Coastguard Worker   }
472*f6dc9357SAndroid Build Coastguard Worker   updateCallback->UpdatePairs = &updatePairs;
473*f6dc9357SAndroid Build Coastguard Worker 
474*f6dc9357SAndroid Build Coastguard Worker   SetInArchiveInterfaces(this, updateCallback.ClsPtr());
475*f6dc9357SAndroid Build Coastguard Worker 
476*f6dc9357SAndroid Build Coastguard Worker   updateCallback->Callback = &updateCallbackAgent;
477*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
478*f6dc9357SAndroid Build Coastguard Worker }
479*f6dc9357SAndroid Build Coastguard Worker 
CreateFolder(ISequentialOutStream * outArchiveStream,const wchar_t * folderName,IFolderArchiveUpdateCallback * updateCallback100)480*f6dc9357SAndroid Build Coastguard Worker HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream,
481*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100)
482*f6dc9357SAndroid Build Coastguard Worker {
483*f6dc9357SAndroid Build Coastguard Worker   if (!CanUpdate())
484*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
485*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CUpdatePair2> updatePairs;
486*f6dc9357SAndroid Build Coastguard Worker   CDirItems dirItems;
487*f6dc9357SAndroid Build Coastguard Worker   CUpdateCallbackAgent updateCallbackAgent;
488*f6dc9357SAndroid Build Coastguard Worker   updateCallbackAgent.SetCallback(updateCallback100);
489*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<IArchiveUpdateCallback, CArchiveUpdateCallback> updateCallback;
490*f6dc9357SAndroid Build Coastguard Worker 
491*f6dc9357SAndroid Build Coastguard Worker   UInt32 numItemsInArchive;
492*f6dc9357SAndroid Build Coastguard Worker   RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive))
493*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItemsInArchive; i++)
494*f6dc9357SAndroid Build Coastguard Worker   {
495*f6dc9357SAndroid Build Coastguard Worker     CUpdatePair2 up2;
496*f6dc9357SAndroid Build Coastguard Worker     up2.SetAs_NoChangeArcItem(i);
497*f6dc9357SAndroid Build Coastguard Worker     updatePairs.Add(up2);
498*f6dc9357SAndroid Build Coastguard Worker   }
499*f6dc9357SAndroid Build Coastguard Worker   CUpdatePair2 up2;
500*f6dc9357SAndroid Build Coastguard Worker   up2.NewData = up2.NewProps = true;
501*f6dc9357SAndroid Build Coastguard Worker   up2.UseArcProps = false;
502*f6dc9357SAndroid Build Coastguard Worker   up2.DirIndex = 0;
503*f6dc9357SAndroid Build Coastguard Worker 
504*f6dc9357SAndroid Build Coastguard Worker   updatePairs.Add(up2);
505*f6dc9357SAndroid Build Coastguard Worker 
506*f6dc9357SAndroid Build Coastguard Worker   updatePairs.ReserveDown();
507*f6dc9357SAndroid Build Coastguard Worker 
508*f6dc9357SAndroid Build Coastguard Worker   CDirItem di;
509*f6dc9357SAndroid Build Coastguard Worker 
510*f6dc9357SAndroid Build Coastguard Worker   di.Attrib = FILE_ATTRIBUTE_DIRECTORY;
511*f6dc9357SAndroid Build Coastguard Worker   di.Size = 0;
512*f6dc9357SAndroid Build Coastguard Worker   bool isAltStreamFolder = false;
513*f6dc9357SAndroid Build Coastguard Worker   if (_proxy2)
514*f6dc9357SAndroid Build Coastguard Worker     di.Name = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, isAltStreamFolder);
515*f6dc9357SAndroid Build Coastguard Worker   else
516*f6dc9357SAndroid Build Coastguard Worker     di.Name = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex);
517*f6dc9357SAndroid Build Coastguard Worker   di.Name += folderName;
518*f6dc9357SAndroid Build Coastguard Worker 
519*f6dc9357SAndroid Build Coastguard Worker   FILETIME ft;
520*f6dc9357SAndroid Build Coastguard Worker   NTime::GetCurUtcFileTime(ft);
521*f6dc9357SAndroid Build Coastguard Worker   di.CTime = di.ATime = di.MTime = ft;
522*f6dc9357SAndroid Build Coastguard Worker 
523*f6dc9357SAndroid Build Coastguard Worker   dirItems.Items.Add(di);
524*f6dc9357SAndroid Build Coastguard Worker 
525*f6dc9357SAndroid Build Coastguard Worker   updateCallback->Callback = &updateCallbackAgent;
526*f6dc9357SAndroid Build Coastguard Worker   updateCallback->DirItems = &dirItems;
527*f6dc9357SAndroid Build Coastguard Worker   updateCallback->UpdatePairs = &updatePairs;
528*f6dc9357SAndroid Build Coastguard Worker 
529*f6dc9357SAndroid Build Coastguard Worker   SetInArchiveInterfaces(this, updateCallback.ClsPtr());
530*f6dc9357SAndroid Build Coastguard Worker 
531*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
532*f6dc9357SAndroid Build Coastguard Worker }
533*f6dc9357SAndroid Build Coastguard Worker 
534*f6dc9357SAndroid Build Coastguard Worker 
RenameItem(ISequentialOutStream * outArchiveStream,const UInt32 * indices,UInt32 numItems,const wchar_t * newItemName,IFolderArchiveUpdateCallback * updateCallback100)535*f6dc9357SAndroid Build Coastguard Worker HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
536*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
537*f6dc9357SAndroid Build Coastguard Worker     IFolderArchiveUpdateCallback *updateCallback100)
538*f6dc9357SAndroid Build Coastguard Worker {
539*f6dc9357SAndroid Build Coastguard Worker   if (!CanUpdate())
540*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
541*f6dc9357SAndroid Build Coastguard Worker   if (numItems != 1)
542*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
543*f6dc9357SAndroid Build Coastguard Worker   if (!_archiveLink.IsOpen)
544*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
545*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CUpdatePair2> updatePairs;
546*f6dc9357SAndroid Build Coastguard Worker   CUpdateCallbackAgent updateCallbackAgent;
547*f6dc9357SAndroid Build Coastguard Worker   updateCallbackAgent.SetCallback(updateCallback100);
548*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<IArchiveUpdateCallback, CArchiveUpdateCallback> updateCallback;
549*f6dc9357SAndroid Build Coastguard Worker 
550*f6dc9357SAndroid Build Coastguard Worker   CUIntVector realIndices;
551*f6dc9357SAndroid Build Coastguard Worker   _agentFolder->GetRealIndices(indices, numItems,
552*f6dc9357SAndroid Build Coastguard Worker       true, // includeAltStreams
553*f6dc9357SAndroid Build Coastguard Worker       true, // includeFolderSubItemsInFlatMode
554*f6dc9357SAndroid Build Coastguard Worker       realIndices);
555*f6dc9357SAndroid Build Coastguard Worker 
556*f6dc9357SAndroid Build Coastguard Worker   const UInt32 ind0 = indices[0];
557*f6dc9357SAndroid Build Coastguard Worker   const int mainRealIndex = _agentFolder->GetRealIndex(ind0);
558*f6dc9357SAndroid Build Coastguard Worker   const UString fullPrefix = _agentFolder->GetFullPrefix(ind0);
559*f6dc9357SAndroid Build Coastguard Worker   UString name = _agentFolder->GetName(ind0);
560*f6dc9357SAndroid Build Coastguard Worker   // 22.00 : we normalize name
561*f6dc9357SAndroid Build Coastguard Worker   NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
562*f6dc9357SAndroid Build Coastguard Worker   const UString oldItemPath = fullPrefix + name;
563*f6dc9357SAndroid Build Coastguard Worker   const UString newItemPath = fullPrefix + newItemName;
564*f6dc9357SAndroid Build Coastguard Worker 
565*f6dc9357SAndroid Build Coastguard Worker   UStringVector newNames;
566*f6dc9357SAndroid Build Coastguard Worker 
567*f6dc9357SAndroid Build Coastguard Worker   unsigned curIndex = 0;
568*f6dc9357SAndroid Build Coastguard Worker   UInt32 numItemsInArchive;
569*f6dc9357SAndroid Build Coastguard Worker   RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive))
570*f6dc9357SAndroid Build Coastguard Worker 
571*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItemsInArchive; i++)
572*f6dc9357SAndroid Build Coastguard Worker   {
573*f6dc9357SAndroid Build Coastguard Worker     CUpdatePair2 up2;
574*f6dc9357SAndroid Build Coastguard Worker     up2.SetAs_NoChangeArcItem(i);
575*f6dc9357SAndroid Build Coastguard Worker     if (curIndex < realIndices.Size())
576*f6dc9357SAndroid Build Coastguard Worker       if (realIndices[curIndex] == i)
577*f6dc9357SAndroid Build Coastguard Worker       {
578*f6dc9357SAndroid Build Coastguard Worker         up2.NewProps = true;
579*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetArc().IsItem_Anti(i, up2.IsAnti)) // it must work without that line too.
580*f6dc9357SAndroid Build Coastguard Worker 
581*f6dc9357SAndroid Build Coastguard Worker         UString oldFullPath;
582*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetArc().GetItem_Path2(i, oldFullPath))
583*f6dc9357SAndroid Build Coastguard Worker 
584*f6dc9357SAndroid Build Coastguard Worker         if (!IsPath1PrefixedByPath2(oldFullPath, oldItemPath))
585*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
586*f6dc9357SAndroid Build Coastguard Worker 
587*f6dc9357SAndroid Build Coastguard Worker         up2.NewNameIndex = (int)newNames.Add(newItemPath + oldFullPath.Ptr(oldItemPath.Len()));
588*f6dc9357SAndroid Build Coastguard Worker         up2.IsMainRenameItem = (mainRealIndex == (int)i);
589*f6dc9357SAndroid Build Coastguard Worker         curIndex++;
590*f6dc9357SAndroid Build Coastguard Worker       }
591*f6dc9357SAndroid Build Coastguard Worker     updatePairs.Add(up2);
592*f6dc9357SAndroid Build Coastguard Worker   }
593*f6dc9357SAndroid Build Coastguard Worker 
594*f6dc9357SAndroid Build Coastguard Worker   updateCallback->Callback = &updateCallbackAgent;
595*f6dc9357SAndroid Build Coastguard Worker   updateCallback->UpdatePairs = &updatePairs;
596*f6dc9357SAndroid Build Coastguard Worker   updateCallback->NewNames = &newNames;
597*f6dc9357SAndroid Build Coastguard Worker 
598*f6dc9357SAndroid Build Coastguard Worker   SetInArchiveInterfaces(this, updateCallback.ClsPtr());
599*f6dc9357SAndroid Build Coastguard Worker 
600*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
601*f6dc9357SAndroid Build Coastguard Worker }
602*f6dc9357SAndroid Build Coastguard Worker 
603*f6dc9357SAndroid Build Coastguard Worker 
CommentItem(ISequentialOutStream * outArchiveStream,const UInt32 * indices,UInt32 numItems,const wchar_t * newItemName,IFolderArchiveUpdateCallback * updateCallback100)604*f6dc9357SAndroid Build Coastguard Worker HRESULT CAgent::CommentItem(ISequentialOutStream *outArchiveStream,
605*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
606*f6dc9357SAndroid Build Coastguard Worker     IFolderArchiveUpdateCallback *updateCallback100)
607*f6dc9357SAndroid Build Coastguard Worker {
608*f6dc9357SAndroid Build Coastguard Worker   if (!CanUpdate())
609*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
610*f6dc9357SAndroid Build Coastguard Worker   if (numItems != 1)
611*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
612*f6dc9357SAndroid Build Coastguard Worker   if (!_archiveLink.IsOpen)
613*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
614*f6dc9357SAndroid Build Coastguard Worker 
615*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CUpdatePair2> updatePairs;
616*f6dc9357SAndroid Build Coastguard Worker   CUpdateCallbackAgent updateCallbackAgent;
617*f6dc9357SAndroid Build Coastguard Worker   updateCallbackAgent.SetCallback(updateCallback100);
618*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<IArchiveUpdateCallback, CArchiveUpdateCallback> updateCallback;
619*f6dc9357SAndroid Build Coastguard Worker 
620*f6dc9357SAndroid Build Coastguard Worker   const int mainRealIndex = _agentFolder->GetRealIndex(indices[0]);
621*f6dc9357SAndroid Build Coastguard Worker 
622*f6dc9357SAndroid Build Coastguard Worker   if (mainRealIndex < 0)
623*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
624*f6dc9357SAndroid Build Coastguard Worker 
625*f6dc9357SAndroid Build Coastguard Worker   UInt32 numItemsInArchive;
626*f6dc9357SAndroid Build Coastguard Worker   RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive))
627*f6dc9357SAndroid Build Coastguard Worker 
628*f6dc9357SAndroid Build Coastguard Worker   UString newName = newItemName;
629*f6dc9357SAndroid Build Coastguard Worker 
630*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItemsInArchive; i++)
631*f6dc9357SAndroid Build Coastguard Worker   {
632*f6dc9357SAndroid Build Coastguard Worker     CUpdatePair2 up2;
633*f6dc9357SAndroid Build Coastguard Worker     up2.SetAs_NoChangeArcItem(i);
634*f6dc9357SAndroid Build Coastguard Worker     if ((int)i == mainRealIndex)
635*f6dc9357SAndroid Build Coastguard Worker       up2.NewProps = true;
636*f6dc9357SAndroid Build Coastguard Worker     updatePairs.Add(up2);
637*f6dc9357SAndroid Build Coastguard Worker   }
638*f6dc9357SAndroid Build Coastguard Worker 
639*f6dc9357SAndroid Build Coastguard Worker   updateCallback->Callback = &updateCallbackAgent;
640*f6dc9357SAndroid Build Coastguard Worker   updateCallback->UpdatePairs = &updatePairs;
641*f6dc9357SAndroid Build Coastguard Worker   updateCallback->CommentIndex = mainRealIndex;
642*f6dc9357SAndroid Build Coastguard Worker   updateCallback->Comment = &newName;
643*f6dc9357SAndroid Build Coastguard Worker 
644*f6dc9357SAndroid Build Coastguard Worker   SetInArchiveInterfaces(this, updateCallback.ClsPtr());
645*f6dc9357SAndroid Build Coastguard Worker 
646*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
647*f6dc9357SAndroid Build Coastguard Worker }
648*f6dc9357SAndroid Build Coastguard Worker 
649*f6dc9357SAndroid Build Coastguard Worker 
650*f6dc9357SAndroid Build Coastguard Worker 
UpdateOneFile(ISequentialOutStream * outArchiveStream,const UInt32 * indices,UInt32 numItems,const wchar_t * diskFilePath,IFolderArchiveUpdateCallback * updateCallback100)651*f6dc9357SAndroid Build Coastguard Worker HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream,
652*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath,
653*f6dc9357SAndroid Build Coastguard Worker     IFolderArchiveUpdateCallback *updateCallback100)
654*f6dc9357SAndroid Build Coastguard Worker {
655*f6dc9357SAndroid Build Coastguard Worker   if (!CanUpdate())
656*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
657*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CUpdatePair2> updatePairs;
658*f6dc9357SAndroid Build Coastguard Worker   CDirItems dirItems;
659*f6dc9357SAndroid Build Coastguard Worker   CUpdateCallbackAgent updateCallbackAgent;
660*f6dc9357SAndroid Build Coastguard Worker   updateCallbackAgent.SetCallback(updateCallback100);
661*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<IArchiveUpdateCallback, CArchiveUpdateCallback> updateCallback;
662*f6dc9357SAndroid Build Coastguard Worker 
663*f6dc9357SAndroid Build Coastguard Worker   UInt32 realIndex;
664*f6dc9357SAndroid Build Coastguard Worker   {
665*f6dc9357SAndroid Build Coastguard Worker     CUIntVector realIndices;
666*f6dc9357SAndroid Build Coastguard Worker     _agentFolder->GetRealIndices(indices, numItems,
667*f6dc9357SAndroid Build Coastguard Worker         false, // includeAltStreams // we update only main stream of file
668*f6dc9357SAndroid Build Coastguard Worker         false, // includeFolderSubItemsInFlatMode
669*f6dc9357SAndroid Build Coastguard Worker         realIndices);
670*f6dc9357SAndroid Build Coastguard Worker     if (realIndices.Size() != 1)
671*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
672*f6dc9357SAndroid Build Coastguard Worker     realIndex = realIndices[0];
673*f6dc9357SAndroid Build Coastguard Worker   }
674*f6dc9357SAndroid Build Coastguard Worker 
675*f6dc9357SAndroid Build Coastguard Worker   {
676*f6dc9357SAndroid Build Coastguard Worker     FStringVector filePaths;
677*f6dc9357SAndroid Build Coastguard Worker     filePaths.Add(us2fs(diskFilePath));
678*f6dc9357SAndroid Build Coastguard Worker     dirItems.EnumerateItems2(FString(), UString(), filePaths, NULL);
679*f6dc9357SAndroid Build Coastguard Worker     if (dirItems.Items.Size() != 1)
680*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
681*f6dc9357SAndroid Build Coastguard Worker   }
682*f6dc9357SAndroid Build Coastguard Worker 
683*f6dc9357SAndroid Build Coastguard Worker   UInt32 numItemsInArchive;
684*f6dc9357SAndroid Build Coastguard Worker   RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive))
685*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItemsInArchive; i++)
686*f6dc9357SAndroid Build Coastguard Worker   {
687*f6dc9357SAndroid Build Coastguard Worker     CUpdatePair2 up2;
688*f6dc9357SAndroid Build Coastguard Worker     up2.SetAs_NoChangeArcItem(i);
689*f6dc9357SAndroid Build Coastguard Worker     if (realIndex == i)
690*f6dc9357SAndroid Build Coastguard Worker     {
691*f6dc9357SAndroid Build Coastguard Worker       up2.DirIndex = 0;
692*f6dc9357SAndroid Build Coastguard Worker       up2.NewData = true;
693*f6dc9357SAndroid Build Coastguard Worker       up2.NewProps = true;
694*f6dc9357SAndroid Build Coastguard Worker       up2.UseArcProps = false;
695*f6dc9357SAndroid Build Coastguard Worker     }
696*f6dc9357SAndroid Build Coastguard Worker     updatePairs.Add(up2);
697*f6dc9357SAndroid Build Coastguard Worker   }
698*f6dc9357SAndroid Build Coastguard Worker   updateCallback->DirItems = &dirItems;
699*f6dc9357SAndroid Build Coastguard Worker   updateCallback->Callback = &updateCallbackAgent;
700*f6dc9357SAndroid Build Coastguard Worker   updateCallback->UpdatePairs = &updatePairs;
701*f6dc9357SAndroid Build Coastguard Worker 
702*f6dc9357SAndroid Build Coastguard Worker   SetInArchiveInterfaces(this, updateCallback.ClsPtr());
703*f6dc9357SAndroid Build Coastguard Worker 
704*f6dc9357SAndroid Build Coastguard Worker   updateCallback->KeepOriginalItemNames = true;
705*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
706*f6dc9357SAndroid Build Coastguard Worker }
707*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgent::SetProperties (const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps))708*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgent::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
709*f6dc9357SAndroid Build Coastguard Worker {
710*f6dc9357SAndroid Build Coastguard Worker   m_PropNames.Clear();
711*f6dc9357SAndroid Build Coastguard Worker   m_PropValues.Clear();
712*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numProps; i++)
713*f6dc9357SAndroid Build Coastguard Worker   {
714*f6dc9357SAndroid Build Coastguard Worker     m_PropNames.Add(names[i]);
715*f6dc9357SAndroid Build Coastguard Worker     m_PropValues.Add(values[i]);
716*f6dc9357SAndroid Build Coastguard Worker   }
717*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
718*f6dc9357SAndroid Build Coastguard Worker }
719