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