xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // ArchiveFolderOut.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/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FileStreams.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/LimitedStreams.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/CopyCoder.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #include "../Common/WorkDir.h"
15*f6dc9357SAndroid Build Coastguard Worker 
16*f6dc9357SAndroid Build Coastguard Worker #include "Agent.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
19*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
20*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
21*f6dc9357SAndroid Build Coastguard Worker 
GetPathParts(UStringVector & pathParts,bool & isAltStreamFolder)22*f6dc9357SAndroid Build Coastguard Worker void CAgentFolder::GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder)
23*f6dc9357SAndroid Build Coastguard Worker {
24*f6dc9357SAndroid Build Coastguard Worker   if (_proxy2)
25*f6dc9357SAndroid Build Coastguard Worker     _proxy2->GetDirPathParts(_proxyDirIndex, pathParts, isAltStreamFolder);
26*f6dc9357SAndroid Build Coastguard Worker   else
27*f6dc9357SAndroid Build Coastguard Worker     _proxy->GetDirPathParts(_proxyDirIndex, pathParts);
28*f6dc9357SAndroid Build Coastguard Worker }
29*f6dc9357SAndroid Build Coastguard Worker 
Delete_EmptyFolder_And_EmptySubFolders(const FString & path)30*f6dc9357SAndroid Build Coastguard Worker static bool Delete_EmptyFolder_And_EmptySubFolders(const FString &path)
31*f6dc9357SAndroid Build Coastguard Worker {
32*f6dc9357SAndroid Build Coastguard Worker   {
33*f6dc9357SAndroid Build Coastguard Worker     const FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
34*f6dc9357SAndroid Build Coastguard Worker     CObjectVector<FString> names;
35*f6dc9357SAndroid Build Coastguard Worker     {
36*f6dc9357SAndroid Build Coastguard Worker       NFind::CDirEntry fileInfo;
37*f6dc9357SAndroid Build Coastguard Worker       NFind::CEnumerator enumerator;
38*f6dc9357SAndroid Build Coastguard Worker       enumerator.SetDirPrefix(pathPrefix);
39*f6dc9357SAndroid Build Coastguard Worker       for (;;)
40*f6dc9357SAndroid Build Coastguard Worker       {
41*f6dc9357SAndroid Build Coastguard Worker         bool found;
42*f6dc9357SAndroid Build Coastguard Worker         if (!enumerator.Next(fileInfo, found))
43*f6dc9357SAndroid Build Coastguard Worker           return false;
44*f6dc9357SAndroid Build Coastguard Worker         if (!found)
45*f6dc9357SAndroid Build Coastguard Worker           break;
46*f6dc9357SAndroid Build Coastguard Worker         if (fileInfo.IsDir())
47*f6dc9357SAndroid Build Coastguard Worker           names.Add(fileInfo.Name);
48*f6dc9357SAndroid Build Coastguard Worker       }
49*f6dc9357SAndroid Build Coastguard Worker     }
50*f6dc9357SAndroid Build Coastguard Worker     bool res = true;
51*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, names)
52*f6dc9357SAndroid Build Coastguard Worker     {
53*f6dc9357SAndroid Build Coastguard Worker       if (!Delete_EmptyFolder_And_EmptySubFolders(pathPrefix + names[i]))
54*f6dc9357SAndroid Build Coastguard Worker         res = false;
55*f6dc9357SAndroid Build Coastguard Worker     }
56*f6dc9357SAndroid Build Coastguard Worker     if (!res)
57*f6dc9357SAndroid Build Coastguard Worker       return false;
58*f6dc9357SAndroid Build Coastguard Worker   }
59*f6dc9357SAndroid Build Coastguard Worker   // we clear read-only attrib to remove read-only dir
60*f6dc9357SAndroid Build Coastguard Worker   if (!SetFileAttrib(path, 0))
61*f6dc9357SAndroid Build Coastguard Worker     return false;
62*f6dc9357SAndroid Build Coastguard Worker   return RemoveDir(path);
63*f6dc9357SAndroid Build Coastguard Worker }
64*f6dc9357SAndroid Build Coastguard Worker 
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker 
67*f6dc9357SAndroid Build Coastguard Worker struct C_CopyFileProgress_to_FolderCallback_MoveArc Z7_final:
68*f6dc9357SAndroid Build Coastguard Worker   public ICopyFileProgress
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker   IFolderArchiveUpdateCallback_MoveArc *Callback;
71*f6dc9357SAndroid Build Coastguard Worker   HRESULT CallbackResult;
72*f6dc9357SAndroid Build Coastguard Worker 
CopyFileProgressZ7_final73*f6dc9357SAndroid Build Coastguard Worker   virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override
74*f6dc9357SAndroid Build Coastguard Worker   {
75*f6dc9357SAndroid Build Coastguard Worker     HRESULT res = Callback->MoveArc_Progress(total, current);
76*f6dc9357SAndroid Build Coastguard Worker     CallbackResult = res;
77*f6dc9357SAndroid Build Coastguard Worker     // we can ignore E_ABORT here, because we update archive,
78*f6dc9357SAndroid Build Coastguard Worker     // and we want to get correct archive after updating
79*f6dc9357SAndroid Build Coastguard Worker     if (res == E_ABORT)
80*f6dc9357SAndroid Build Coastguard Worker       res = S_OK;
81*f6dc9357SAndroid Build Coastguard Worker     return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL;
82*f6dc9357SAndroid Build Coastguard Worker   }
83*f6dc9357SAndroid Build Coastguard Worker 
C_CopyFileProgress_to_FolderCallback_MoveArcZ7_final84*f6dc9357SAndroid Build Coastguard Worker   C_CopyFileProgress_to_FolderCallback_MoveArc(
85*f6dc9357SAndroid Build Coastguard Worker       IFolderArchiveUpdateCallback_MoveArc *callback) :
86*f6dc9357SAndroid Build Coastguard Worker     Callback(callback),
87*f6dc9357SAndroid Build Coastguard Worker     CallbackResult(S_OK)
88*f6dc9357SAndroid Build Coastguard Worker     {}
89*f6dc9357SAndroid Build Coastguard Worker };
90*f6dc9357SAndroid Build Coastguard Worker 
91*f6dc9357SAndroid Build Coastguard Worker 
CommonUpdateOperation(AGENT_OP operation,bool moveMode,const wchar_t * newItemName,const NUpdateArchive::CActionSet * actionSet,const UInt32 * indices,UInt32 numItems,IProgress * progress)92*f6dc9357SAndroid Build Coastguard Worker HRESULT CAgentFolder::CommonUpdateOperation(
93*f6dc9357SAndroid Build Coastguard Worker     AGENT_OP operation,
94*f6dc9357SAndroid Build Coastguard Worker     bool moveMode,
95*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *newItemName,
96*f6dc9357SAndroid Build Coastguard Worker     const NUpdateArchive::CActionSet *actionSet,
97*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *indices, UInt32 numItems,
98*f6dc9357SAndroid Build Coastguard Worker     IProgress *progress)
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker   if (moveMode && _agentSpec->_isHashHandler)
101*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker   if (!_agentSpec->CanUpdate())
104*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
105*f6dc9357SAndroid Build Coastguard Worker 
106*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
107*f6dc9357SAndroid Build Coastguard Worker   if (progress)
108*f6dc9357SAndroid Build Coastguard Worker     progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100);
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker   try
111*f6dc9357SAndroid Build Coastguard Worker   {
112*f6dc9357SAndroid Build Coastguard Worker 
113*f6dc9357SAndroid Build Coastguard Worker   RINOK(_agentSpec->SetFolder(this))
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker   // ---------- Save FolderItem ----------
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker   UStringVector pathParts;
118*f6dc9357SAndroid Build Coastguard Worker   bool isAltStreamFolder = false;
119*f6dc9357SAndroid Build Coastguard Worker   GetPathParts(pathParts, isAltStreamFolder);
120*f6dc9357SAndroid Build Coastguard Worker 
121*f6dc9357SAndroid Build Coastguard Worker   FStringVector requestedPaths;
122*f6dc9357SAndroid Build Coastguard Worker   FStringVector processedPaths;
123*f6dc9357SAndroid Build Coastguard Worker 
124*f6dc9357SAndroid Build Coastguard Worker   CWorkDirTempFile tempFile;
125*f6dc9357SAndroid Build Coastguard Worker   RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath)))
126*f6dc9357SAndroid Build Coastguard Worker   {
127*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IOutStream> tailStream;
128*f6dc9357SAndroid Build Coastguard Worker     const CArc &arc = *_agentSpec->_archiveLink.GetArc();
129*f6dc9357SAndroid Build Coastguard Worker 
130*f6dc9357SAndroid Build Coastguard Worker     if (arc.ArcStreamOffset == 0)
131*f6dc9357SAndroid Build Coastguard Worker       tailStream = tempFile.OutStream;
132*f6dc9357SAndroid Build Coastguard Worker     else
133*f6dc9357SAndroid Build Coastguard Worker     {
134*f6dc9357SAndroid Build Coastguard Worker       if (arc.Offset < 0)
135*f6dc9357SAndroid Build Coastguard Worker         return E_NOTIMPL;
136*f6dc9357SAndroid Build Coastguard Worker       RINOK(arc.InStream->Seek(0, STREAM_SEEK_SET, NULL))
137*f6dc9357SAndroid Build Coastguard Worker       RINOK(NCompress::CopyStream_ExactSize(arc.InStream, tempFile.OutStream, arc.ArcStreamOffset, NULL))
138*f6dc9357SAndroid Build Coastguard Worker       CTailOutStream *tailStreamSpec = new CTailOutStream;
139*f6dc9357SAndroid Build Coastguard Worker       tailStream = tailStreamSpec;
140*f6dc9357SAndroid Build Coastguard Worker       tailStreamSpec->Stream = tempFile.OutStream;
141*f6dc9357SAndroid Build Coastguard Worker       tailStreamSpec->Offset = arc.ArcStreamOffset;
142*f6dc9357SAndroid Build Coastguard Worker       tailStreamSpec->Init();
143*f6dc9357SAndroid Build Coastguard Worker     }
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker     HRESULT result;
146*f6dc9357SAndroid Build Coastguard Worker 
147*f6dc9357SAndroid Build Coastguard Worker     switch ((int)operation)
148*f6dc9357SAndroid Build Coastguard Worker     {
149*f6dc9357SAndroid Build Coastguard Worker       case AGENT_OP_Delete:
150*f6dc9357SAndroid Build Coastguard Worker         result = _agentSpec->DeleteItems(tailStream, indices, numItems, updateCallback100);
151*f6dc9357SAndroid Build Coastguard Worker         break;
152*f6dc9357SAndroid Build Coastguard Worker       case AGENT_OP_CreateFolder:
153*f6dc9357SAndroid Build Coastguard Worker         result = _agentSpec->CreateFolder(tailStream, newItemName, updateCallback100);
154*f6dc9357SAndroid Build Coastguard Worker         break;
155*f6dc9357SAndroid Build Coastguard Worker       case AGENT_OP_Rename:
156*f6dc9357SAndroid Build Coastguard Worker         result = _agentSpec->RenameItem(tailStream, indices, numItems, newItemName, updateCallback100);
157*f6dc9357SAndroid Build Coastguard Worker         break;
158*f6dc9357SAndroid Build Coastguard Worker       case AGENT_OP_Comment:
159*f6dc9357SAndroid Build Coastguard Worker         result = _agentSpec->CommentItem(tailStream, indices, numItems, newItemName, updateCallback100);
160*f6dc9357SAndroid Build Coastguard Worker         break;
161*f6dc9357SAndroid Build Coastguard Worker       case AGENT_OP_CopyFromFile:
162*f6dc9357SAndroid Build Coastguard Worker         result = _agentSpec->UpdateOneFile(tailStream, indices, numItems, newItemName, updateCallback100);
163*f6dc9357SAndroid Build Coastguard Worker         break;
164*f6dc9357SAndroid Build Coastguard Worker       case AGENT_OP_Uni:
165*f6dc9357SAndroid Build Coastguard Worker         {
166*f6dc9357SAndroid Build Coastguard Worker           Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
167*f6dc9357SAndroid Build Coastguard Worker           for (unsigned i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
168*f6dc9357SAndroid Build Coastguard Worker             actionSetByte[i] = (Byte)actionSet->StateActions[i];
169*f6dc9357SAndroid Build Coastguard Worker           result = _agentSpec->DoOperation2(
170*f6dc9357SAndroid Build Coastguard Worker               moveMode ? &requestedPaths : NULL,
171*f6dc9357SAndroid Build Coastguard Worker               moveMode ? &processedPaths : NULL,
172*f6dc9357SAndroid Build Coastguard Worker               tailStream, actionSetByte, NULL, updateCallback100);
173*f6dc9357SAndroid Build Coastguard Worker           break;
174*f6dc9357SAndroid Build Coastguard Worker         }
175*f6dc9357SAndroid Build Coastguard Worker       default:
176*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
177*f6dc9357SAndroid Build Coastguard Worker     }
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker     RINOK(result)
180*f6dc9357SAndroid Build Coastguard Worker   }
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker   _agentSpec->KeepModeForNextOpen();
183*f6dc9357SAndroid Build Coastguard Worker   _agent->Close();
184*f6dc9357SAndroid Build Coastguard Worker 
185*f6dc9357SAndroid Build Coastguard Worker   // before 9.26: if there was error for MoveToOriginal archive was closed.
186*f6dc9357SAndroid Build Coastguard Worker   // now: we reopen archive after close
187*f6dc9357SAndroid Build Coastguard Worker 
188*f6dc9357SAndroid Build Coastguard Worker   // m_FolderItem = NULL;
189*f6dc9357SAndroid Build Coastguard Worker   _items.Clear();
190*f6dc9357SAndroid Build Coastguard Worker   _proxyDirIndex = k_Proxy_RootDirIndex;
191*f6dc9357SAndroid Build Coastguard Worker 
192*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderArchiveUpdateCallback_MoveArc> updateCallback_MoveArc;
193*f6dc9357SAndroid Build Coastguard Worker   if (progress)
194*f6dc9357SAndroid Build Coastguard Worker     progress->QueryInterface(IID_IFolderArchiveUpdateCallback_MoveArc, (void **)&updateCallback_MoveArc);
195*f6dc9357SAndroid Build Coastguard Worker 
196*f6dc9357SAndroid Build Coastguard Worker   HRESULT res;
197*f6dc9357SAndroid Build Coastguard Worker   if (updateCallback_MoveArc)
198*f6dc9357SAndroid Build Coastguard Worker   {
199*f6dc9357SAndroid Build Coastguard Worker     const FString &tempFilePath = tempFile.Get_TempFilePath();
200*f6dc9357SAndroid Build Coastguard Worker     UInt64 totalSize = 0;
201*f6dc9357SAndroid Build Coastguard Worker     {
202*f6dc9357SAndroid Build Coastguard Worker       NFind::CFileInfo fi;
203*f6dc9357SAndroid Build Coastguard Worker       if (fi.Find(tempFilePath))
204*f6dc9357SAndroid Build Coastguard Worker         totalSize = fi.Size;
205*f6dc9357SAndroid Build Coastguard Worker     }
206*f6dc9357SAndroid Build Coastguard Worker     RINOK(updateCallback_MoveArc->MoveArc_Start(
207*f6dc9357SAndroid Build Coastguard Worker         fs2us(tempFilePath),
208*f6dc9357SAndroid Build Coastguard Worker         fs2us(tempFile.Get_OriginalFilePath()),
209*f6dc9357SAndroid Build Coastguard Worker         totalSize,
210*f6dc9357SAndroid Build Coastguard Worker         1)) // updateMode
211*f6dc9357SAndroid Build Coastguard Worker 
212*f6dc9357SAndroid Build Coastguard Worker     C_CopyFileProgress_to_FolderCallback_MoveArc prox(updateCallback_MoveArc);
213*f6dc9357SAndroid Build Coastguard Worker     res = tempFile.MoveToOriginal(
214*f6dc9357SAndroid Build Coastguard Worker         true, // deleteOriginal
215*f6dc9357SAndroid Build Coastguard Worker         &prox);
216*f6dc9357SAndroid Build Coastguard Worker     if (res == S_OK)
217*f6dc9357SAndroid Build Coastguard Worker     {
218*f6dc9357SAndroid Build Coastguard Worker       res = updateCallback_MoveArc->MoveArc_Finish();
219*f6dc9357SAndroid Build Coastguard Worker       // we don't return after E_ABORT here, because
220*f6dc9357SAndroid Build Coastguard Worker       // we want to reopen new archive still.
221*f6dc9357SAndroid Build Coastguard Worker     }
222*f6dc9357SAndroid Build Coastguard Worker     else if (prox.CallbackResult != S_OK)
223*f6dc9357SAndroid Build Coastguard Worker       res = prox.CallbackResult;
224*f6dc9357SAndroid Build Coastguard Worker 
225*f6dc9357SAndroid Build Coastguard Worker     // if updating callback returned E_ABORT,
226*f6dc9357SAndroid Build Coastguard Worker     // then openCallback still can return E_ABORT also.
227*f6dc9357SAndroid Build Coastguard Worker     // So ReOpen() will return with E_ABORT.
228*f6dc9357SAndroid Build Coastguard Worker     // But we want to open archive still.
229*f6dc9357SAndroid Build Coastguard Worker     // And Before_ArcReopen() call will clear user break status in that case.
230*f6dc9357SAndroid Build Coastguard Worker     RINOK(updateCallback_MoveArc->Before_ArcReopen())
231*f6dc9357SAndroid Build Coastguard Worker   }
232*f6dc9357SAndroid Build Coastguard Worker   else
233*f6dc9357SAndroid Build Coastguard Worker     res = tempFile.MoveToOriginal(true); // deleteOriginal
234*f6dc9357SAndroid Build Coastguard Worker 
235*f6dc9357SAndroid Build Coastguard Worker   // RINOK(res);
236*f6dc9357SAndroid Build Coastguard Worker   if (res == S_OK)
237*f6dc9357SAndroid Build Coastguard Worker   {
238*f6dc9357SAndroid Build Coastguard Worker     if (moveMode)
239*f6dc9357SAndroid Build Coastguard Worker     {
240*f6dc9357SAndroid Build Coastguard Worker       unsigned i;
241*f6dc9357SAndroid Build Coastguard Worker       for (i = 0; i < processedPaths.Size(); i++)
242*f6dc9357SAndroid Build Coastguard Worker       {
243*f6dc9357SAndroid Build Coastguard Worker         DeleteFileAlways(processedPaths[i]);
244*f6dc9357SAndroid Build Coastguard Worker       }
245*f6dc9357SAndroid Build Coastguard Worker       for (i = 0; i < requestedPaths.Size(); i++)
246*f6dc9357SAndroid Build Coastguard Worker       {
247*f6dc9357SAndroid Build Coastguard Worker         const FString &fs = requestedPaths[i];
248*f6dc9357SAndroid Build Coastguard Worker         if (NFind::DoesDirExist(fs))
249*f6dc9357SAndroid Build Coastguard Worker           Delete_EmptyFolder_And_EmptySubFolders(fs);
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   {
255*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IArchiveOpenCallback> openCallback;
256*f6dc9357SAndroid Build Coastguard Worker     if (updateCallback100)
257*f6dc9357SAndroid Build Coastguard Worker       updateCallback100->QueryInterface(IID_IArchiveOpenCallback, (void **)&openCallback);
258*f6dc9357SAndroid Build Coastguard Worker     RINOK(_agent->ReOpen(openCallback))
259*f6dc9357SAndroid Build Coastguard Worker   }
260*f6dc9357SAndroid Build Coastguard Worker 
261*f6dc9357SAndroid Build Coastguard Worker   // CAgent::ReOpen() deletes _proxy and _proxy2
262*f6dc9357SAndroid Build Coastguard Worker   // _items.Clear();
263*f6dc9357SAndroid Build Coastguard Worker   _proxy = NULL;
264*f6dc9357SAndroid Build Coastguard Worker   _proxy2 = NULL;
265*f6dc9357SAndroid Build Coastguard Worker   // _proxyDirIndex = k_Proxy_RootDirIndex;
266*f6dc9357SAndroid Build Coastguard Worker   _isAltStreamFolder = false;
267*f6dc9357SAndroid Build Coastguard Worker 
268*f6dc9357SAndroid Build Coastguard Worker 
269*f6dc9357SAndroid Build Coastguard Worker   // ---------- Restore FolderItem ----------
270*f6dc9357SAndroid Build Coastguard Worker 
271*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderFolder> archiveFolder;
272*f6dc9357SAndroid Build Coastguard Worker   RINOK(_agent->BindToRootFolder(&archiveFolder))
273*f6dc9357SAndroid Build Coastguard Worker 
274*f6dc9357SAndroid Build Coastguard Worker   // CAgent::BindToRootFolder() changes _proxy and _proxy2
275*f6dc9357SAndroid Build Coastguard Worker   _proxy = _agentSpec->_proxy;
276*f6dc9357SAndroid Build Coastguard Worker   _proxy2 = _agentSpec->_proxy2;
277*f6dc9357SAndroid Build Coastguard Worker 
278*f6dc9357SAndroid Build Coastguard Worker   if (_proxy)
279*f6dc9357SAndroid Build Coastguard Worker   {
280*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, pathParts)
281*f6dc9357SAndroid Build Coastguard Worker     {
282*f6dc9357SAndroid Build Coastguard Worker       const int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]);
283*f6dc9357SAndroid Build Coastguard Worker       if (next == -1)
284*f6dc9357SAndroid Build Coastguard Worker         break;
285*f6dc9357SAndroid Build Coastguard Worker       _proxyDirIndex = (unsigned)next;
286*f6dc9357SAndroid Build Coastguard Worker     }
287*f6dc9357SAndroid Build Coastguard Worker   }
288*f6dc9357SAndroid Build Coastguard Worker 
289*f6dc9357SAndroid Build Coastguard Worker   if (_proxy2)
290*f6dc9357SAndroid Build Coastguard Worker   {
291*f6dc9357SAndroid Build Coastguard Worker     if (pathParts.IsEmpty() && isAltStreamFolder)
292*f6dc9357SAndroid Build Coastguard Worker     {
293*f6dc9357SAndroid Build Coastguard Worker       _proxyDirIndex = k_Proxy2_AltRootDirIndex;
294*f6dc9357SAndroid Build Coastguard Worker     }
295*f6dc9357SAndroid Build Coastguard Worker     else FOR_VECTOR (i, pathParts)
296*f6dc9357SAndroid Build Coastguard Worker     {
297*f6dc9357SAndroid Build Coastguard Worker       const bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder);
298*f6dc9357SAndroid Build Coastguard Worker       const int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly);
299*f6dc9357SAndroid Build Coastguard Worker       if (index == -1)
300*f6dc9357SAndroid Build Coastguard Worker         break;
301*f6dc9357SAndroid Build Coastguard Worker 
302*f6dc9357SAndroid Build Coastguard Worker       const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]];
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker       if (dirOnly)
305*f6dc9357SAndroid Build Coastguard Worker         _proxyDirIndex = (unsigned)file.DirIndex;
306*f6dc9357SAndroid Build Coastguard Worker       else
307*f6dc9357SAndroid Build Coastguard Worker       {
308*f6dc9357SAndroid Build Coastguard Worker         if (file.AltDirIndex != -1)
309*f6dc9357SAndroid Build Coastguard Worker           _proxyDirIndex = (unsigned)file.AltDirIndex;
310*f6dc9357SAndroid Build Coastguard Worker         break;
311*f6dc9357SAndroid Build Coastguard Worker       }
312*f6dc9357SAndroid Build Coastguard Worker     }
313*f6dc9357SAndroid Build Coastguard Worker   }
314*f6dc9357SAndroid Build Coastguard Worker 
315*f6dc9357SAndroid Build Coastguard Worker   /*
316*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.IsEmpty() && isAltStreamFolder)
317*f6dc9357SAndroid Build Coastguard Worker   {
318*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderAltStreams> folderAltStreams;
319*f6dc9357SAndroid Build Coastguard Worker     archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams);
320*f6dc9357SAndroid Build Coastguard Worker     if (folderAltStreams)
321*f6dc9357SAndroid Build Coastguard Worker     {
322*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<IFolderFolder> newFolder;
323*f6dc9357SAndroid Build Coastguard Worker       folderAltStreams->BindToAltStreams((UInt32)(Int32)-1, &newFolder);
324*f6dc9357SAndroid Build Coastguard Worker       if (newFolder)
325*f6dc9357SAndroid Build Coastguard Worker         archiveFolder = newFolder;
326*f6dc9357SAndroid Build Coastguard Worker     }
327*f6dc9357SAndroid Build Coastguard Worker   }
328*f6dc9357SAndroid Build Coastguard Worker 
329*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, pathParts)
330*f6dc9357SAndroid Build Coastguard Worker   {
331*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> newFolder;
332*f6dc9357SAndroid Build Coastguard Worker 
333*f6dc9357SAndroid Build Coastguard Worker     if (isAltStreamFolder && i == pathParts.Size() - 1)
334*f6dc9357SAndroid Build Coastguard Worker     {
335*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<IFolderAltStreams> folderAltStreams;
336*f6dc9357SAndroid Build Coastguard Worker       archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams);
337*f6dc9357SAndroid Build Coastguard Worker       if (folderAltStreams)
338*f6dc9357SAndroid Build Coastguard Worker         folderAltStreams->BindToAltStreams(pathParts[i], &newFolder);
339*f6dc9357SAndroid Build Coastguard Worker     }
340*f6dc9357SAndroid Build Coastguard Worker     else
341*f6dc9357SAndroid Build Coastguard Worker       archiveFolder->BindToFolder(pathParts[i], &newFolder);
342*f6dc9357SAndroid Build Coastguard Worker 
343*f6dc9357SAndroid Build Coastguard Worker     if (!newFolder)
344*f6dc9357SAndroid Build Coastguard Worker       break;
345*f6dc9357SAndroid Build Coastguard Worker     archiveFolder = newFolder;
346*f6dc9357SAndroid Build Coastguard Worker   }
347*f6dc9357SAndroid Build Coastguard Worker 
348*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
349*f6dc9357SAndroid Build Coastguard Worker   RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal));
350*f6dc9357SAndroid Build Coastguard Worker   CAgentFolder *agentFolder;
351*f6dc9357SAndroid Build Coastguard Worker   RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder));
352*f6dc9357SAndroid Build Coastguard Worker   _proxyDirIndex = agentFolder->_proxyDirIndex;
353*f6dc9357SAndroid Build Coastguard Worker   // _parentFolder = agentFolder->_parentFolder;
354*f6dc9357SAndroid Build Coastguard Worker   */
355*f6dc9357SAndroid Build Coastguard Worker 
356*f6dc9357SAndroid Build Coastguard Worker   if (_proxy2)
357*f6dc9357SAndroid Build Coastguard Worker     _isAltStreamFolder = _proxy2->IsAltDir(_proxyDirIndex);
358*f6dc9357SAndroid Build Coastguard Worker 
359*f6dc9357SAndroid Build Coastguard Worker   return res;
360*f6dc9357SAndroid Build Coastguard Worker 
361*f6dc9357SAndroid Build Coastguard Worker   }
362*f6dc9357SAndroid Build Coastguard Worker   catch(const UString &s)
363*f6dc9357SAndroid Build Coastguard Worker   {
364*f6dc9357SAndroid Build Coastguard Worker     if (updateCallback100)
365*f6dc9357SAndroid Build Coastguard Worker     {
366*f6dc9357SAndroid Build Coastguard Worker       UString s2 ("Error: ");
367*f6dc9357SAndroid Build Coastguard Worker       s2 += s;
368*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback100->UpdateErrorMessage(s2))
369*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
370*f6dc9357SAndroid Build Coastguard Worker     }
371*f6dc9357SAndroid Build Coastguard Worker     throw;
372*f6dc9357SAndroid Build Coastguard Worker   }
373*f6dc9357SAndroid Build Coastguard Worker }
374*f6dc9357SAndroid Build Coastguard Worker 
375*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgentFolder::CopyFrom (Int32 moveMode,const wchar_t * fromFolderPath,const wchar_t * const * itemsPaths,UInt32 numItems,IProgress * progress))376*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgentFolder::CopyFrom(Int32 moveMode,
377*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *fromFolderPath, /* test it */
378*f6dc9357SAndroid Build Coastguard Worker     const wchar_t * const *itemsPaths,
379*f6dc9357SAndroid Build Coastguard Worker     UInt32 numItems,
380*f6dc9357SAndroid Build Coastguard Worker     IProgress *progress))
381*f6dc9357SAndroid Build Coastguard Worker {
382*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
383*f6dc9357SAndroid Build Coastguard Worker   {
384*f6dc9357SAndroid Build Coastguard Worker     RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems))
385*f6dc9357SAndroid Build Coastguard Worker     return CommonUpdateOperation(AGENT_OP_Uni, (moveMode != 0), NULL,
386*f6dc9357SAndroid Build Coastguard Worker         &NUpdateArchive::k_ActionSet_Add,
387*f6dc9357SAndroid Build Coastguard Worker         NULL, 0, progress);
388*f6dc9357SAndroid Build Coastguard Worker   }
389*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
390*f6dc9357SAndroid Build Coastguard Worker }
391*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgentFolder::CopyFromFile (UInt32 destIndex,const wchar_t * itemPath,IProgress * progress))392*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress *progress))
393*f6dc9357SAndroid Build Coastguard Worker {
394*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
395*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath,
396*f6dc9357SAndroid Build Coastguard Worker       &NUpdateArchive::k_ActionSet_Add,
397*f6dc9357SAndroid Build Coastguard Worker       &destIndex, 1, progress);
398*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
399*f6dc9357SAndroid Build Coastguard Worker }
400*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgentFolder::Delete (const UInt32 * indices,UInt32 numItems,IProgress * progress))401*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgentFolder::Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress))
402*f6dc9357SAndroid Build Coastguard Worker {
403*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
404*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdateOperation(AGENT_OP_Delete, false, NULL,
405*f6dc9357SAndroid Build Coastguard Worker       &NUpdateArchive::k_ActionSet_Delete, indices, numItems, progress);
406*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
407*f6dc9357SAndroid Build Coastguard Worker }
408*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgentFolder::CreateFolder (const wchar_t * name,IProgress * progress))409*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress))
410*f6dc9357SAndroid Build Coastguard Worker {
411*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
412*f6dc9357SAndroid Build Coastguard Worker 
413*f6dc9357SAndroid Build Coastguard Worker   if (_isAltStreamFolder)
414*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
415*f6dc9357SAndroid Build Coastguard Worker 
416*f6dc9357SAndroid Build Coastguard Worker   if (_proxy2)
417*f6dc9357SAndroid Build Coastguard Worker   {
418*f6dc9357SAndroid Build Coastguard Worker     if (_proxy2->IsThere_SubDir(_proxyDirIndex, name))
419*f6dc9357SAndroid Build Coastguard Worker       return ERROR_ALREADY_EXISTS;
420*f6dc9357SAndroid Build Coastguard Worker   }
421*f6dc9357SAndroid Build Coastguard Worker   else
422*f6dc9357SAndroid Build Coastguard Worker   {
423*f6dc9357SAndroid Build Coastguard Worker     if (_proxy->FindSubDir(_proxyDirIndex, name) != -1)
424*f6dc9357SAndroid Build Coastguard Worker       return ERROR_ALREADY_EXISTS;
425*f6dc9357SAndroid Build Coastguard Worker   }
426*f6dc9357SAndroid Build Coastguard Worker 
427*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdateOperation(AGENT_OP_CreateFolder, false, name, NULL, NULL, 0, progress);
428*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
429*f6dc9357SAndroid Build Coastguard Worker }
430*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgentFolder::Rename (UInt32 index,const wchar_t * newName,IProgress * progress))431*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress))
432*f6dc9357SAndroid Build Coastguard Worker {
433*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
434*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL,
435*f6dc9357SAndroid Build Coastguard Worker       &index, 1, progress);
436*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
437*f6dc9357SAndroid Build Coastguard Worker }
438*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgentFolder::CreateFile (const wchar_t *,IProgress *))439*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */))
440*f6dc9357SAndroid Build Coastguard Worker {
441*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
442*f6dc9357SAndroid Build Coastguard Worker }
443*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAgentFolder::SetProperty (UInt32 index,PROPID propID,const PROPVARIANT * value,IProgress * progress))444*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAgentFolder::SetProperty(UInt32 index, PROPID propID,
445*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT *value, IProgress *progress))
446*f6dc9357SAndroid Build Coastguard Worker {
447*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
448*f6dc9357SAndroid Build Coastguard Worker   if (propID != kpidComment || value->vt != VT_BSTR)
449*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
450*f6dc9357SAndroid Build Coastguard Worker   if (!_agentSpec || !_agentSpec->GetTypeOfArc(_agentSpec->GetArc()).IsEqualTo_Ascii_NoCase("zip"))
451*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker   return CommonUpdateOperation(AGENT_OP_Comment, false, value->bstrVal, NULL,
454*f6dc9357SAndroid Build Coastguard Worker       &index, 1, progress);
455*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
456*f6dc9357SAndroid Build Coastguard Worker }
457