1 // AgentProxy.cpp
2
3 #include "StdAfx.h"
4
5 // #include <stdio.h>
6 #ifdef _WIN32
7 #include <wchar.h>
8 #else
9 #include <ctype.h>
10 #endif
11
12 #include "../../../../C/Sort.h"
13 #include "../../../../C/CpuArch.h"
14
15 #include "../../../Common/UTFConvert.h"
16 #include "../../../Common/Wildcard.h"
17
18 #include "../../../Windows/PropVariant.h"
19 #include "../../../Windows/PropVariantConv.h"
20
21 #include "../../Archive/Common/ItemNameUtils.h"
22
23 #include "AgentProxy.h"
24
25 using namespace NWindows;
26
FindSubDir(unsigned dirIndex,const wchar_t * name,unsigned & insertPos) const27 int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const
28 {
29 const CRecordVector<unsigned> &subDirs = Dirs[dirIndex].SubDirs;
30 unsigned left = 0, right = subDirs.Size();
31 for (;;)
32 {
33 if (left == right)
34 {
35 insertPos = left;
36 return -1;
37 }
38 const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
39 const unsigned dirIndex2 = subDirs[mid];
40 const int comp = CompareFileNames(name, Dirs[dirIndex2].Name);
41 if (comp == 0)
42 return (int)dirIndex2;
43 if (comp < 0)
44 right = mid;
45 else
46 left = mid + 1;
47 }
48 }
49
FindSubDir(unsigned dirIndex,const wchar_t * name) const50 int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name) const
51 {
52 unsigned insertPos;
53 return FindSubDir(dirIndex, name, insertPos);
54 }
55
AllocStringAndCopy(const wchar_t * s,size_t len)56 static const wchar_t *AllocStringAndCopy(const wchar_t *s, size_t len)
57 {
58 wchar_t *p = new wchar_t[len + 1];
59 MyStringCopy(p, s);
60 return p;
61 }
62
AllocStringAndCopy(const UString & s)63 static const wchar_t *AllocStringAndCopy(const UString &s)
64 {
65 return AllocStringAndCopy(s, s.Len());
66 }
67
AddDir(unsigned dirIndex,int arcIndex,const UString & name)68 unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name)
69 {
70 unsigned insertPos;
71 int subDirIndex = FindSubDir(dirIndex, name, insertPos);
72 if (subDirIndex != -1)
73 {
74 if (arcIndex != -1)
75 {
76 CProxyDir &item = Dirs[(unsigned)subDirIndex];
77 if (item.ArcIndex == -1)
78 item.ArcIndex = arcIndex;
79 }
80 return (unsigned)subDirIndex;
81 }
82 subDirIndex = (int)Dirs.Size();
83 Dirs[dirIndex].SubDirs.Insert(insertPos, (unsigned)subDirIndex);
84 CProxyDir &item = Dirs.AddNew();
85
86 item.NameLen = name.Len();
87 item.Name = AllocStringAndCopy(name);
88
89 item.ArcIndex = arcIndex;
90 item.ParentDir = (int)dirIndex;
91 return (unsigned)subDirIndex;
92 }
93
Clear()94 void CProxyDir::Clear()
95 {
96 SubDirs.Clear();
97 SubFiles.Clear();
98 }
99
GetDirPathParts(unsigned dirIndex,UStringVector & pathParts) const100 void CProxyArc::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts) const
101 {
102 pathParts.Clear();
103 // while (dirIndex != -1)
104 for (;;)
105 {
106 const CProxyDir &dir = Dirs[dirIndex];
107 dirIndex = (unsigned)dir.ParentDir;
108 if (dir.ParentDir == -1)
109 break;
110 pathParts.Insert(0, dir.Name);
111 // 22.00: we normalize name
112 NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(pathParts[0]);
113 }
114 }
115
GetDirPath_as_Prefix(unsigned dirIndex) const116 UString CProxyArc::GetDirPath_as_Prefix(unsigned dirIndex) const
117 {
118 UString s;
119 // while (dirIndex != -1)
120 for (;;)
121 {
122 const CProxyDir &dir = Dirs[dirIndex];
123 dirIndex = (unsigned)dir.ParentDir;
124 if (dir.ParentDir == -1)
125 break;
126 s.InsertAtFront(WCHAR_PATH_SEPARATOR);
127 s.Insert(0, dir.Name);
128 // 22.00: we normalize name
129 NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s.GetBuf(), MyStringLen(dir.Name));
130 }
131 return s;
132 }
133
AddRealIndices(unsigned dirIndex,CUIntVector & realIndices) const134 void CProxyArc::AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const
135 {
136 const CProxyDir &dir = Dirs[dirIndex];
137 if (dir.IsLeaf())
138 realIndices.Add((unsigned)dir.ArcIndex);
139 unsigned i;
140 for (i = 0; i < dir.SubDirs.Size(); i++)
141 AddRealIndices(dir.SubDirs[i], realIndices);
142 for (i = 0; i < dir.SubFiles.Size(); i++)
143 realIndices.Add(dir.SubFiles[i]);
144 }
145
GetRealIndex(unsigned dirIndex,unsigned index) const146 int CProxyArc::GetRealIndex(unsigned dirIndex, unsigned index) const
147 {
148 const CProxyDir &dir = Dirs[dirIndex];
149 const unsigned numDirItems = dir.SubDirs.Size();
150 if (index < numDirItems)
151 {
152 const CProxyDir &f = Dirs[dir.SubDirs[index]];
153 if (f.IsLeaf())
154 return f.ArcIndex;
155 return -1;
156 }
157 return (int)dir.SubFiles[index - numDirItems];
158 }
159
GetRealIndices(unsigned dirIndex,const UInt32 * indices,UInt32 numItems,CUIntVector & realIndices) const160 void CProxyArc::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
161 {
162 const CProxyDir &dir = Dirs[dirIndex];
163 realIndices.Clear();
164 for (UInt32 i = 0; i < numItems; i++)
165 {
166 const UInt32 index = indices[i];
167 const unsigned numDirItems = dir.SubDirs.Size();
168 if (index < numDirItems)
169 AddRealIndices(dir.SubDirs[index], realIndices);
170 else
171 realIndices.Add(dir.SubFiles[index - numDirItems]);
172 }
173 HeapSort(realIndices.NonConstData(), realIndices.Size());
174 }
175
176 ///////////////////////////////////////////////
177 // CProxyArc
178
GetSize(IInArchive * archive,UInt32 index,PROPID propID,UInt64 & size)179 static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &size)
180 {
181 size = 0;
182 NCOM::CPropVariant prop;
183 if (archive->GetProperty(index, propID, &prop) != S_OK)
184 throw 20120228;
185 return ConvertPropVariantToUInt64(prop, size);
186 }
187
CalculateSizes(unsigned dirIndex,IInArchive * archive)188 void CProxyArc::CalculateSizes(unsigned dirIndex, IInArchive *archive)
189 {
190 CProxyDir &dir = Dirs[dirIndex];
191 dir.Size = dir.PackSize = 0;
192 dir.NumSubDirs = dir.SubDirs.Size();
193 dir.NumSubFiles = dir.SubFiles.Size();
194 dir.CrcIsDefined = true;
195 dir.Crc = 0;
196
197 unsigned i;
198
199 for (i = 0; i < dir.SubFiles.Size(); i++)
200 {
201 const UInt32 index = (UInt32)dir.SubFiles[i];
202 UInt64 size, packSize;
203 const bool sizeDefined = GetSize(archive, index, kpidSize, size);
204 dir.Size += size;
205 GetSize(archive, index, kpidPackSize, packSize);
206 dir.PackSize += packSize;
207 {
208 NCOM::CPropVariant prop;
209 if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
210 {
211 if (prop.vt == VT_UI4)
212 dir.Crc += prop.ulVal;
213 else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
214 dir.CrcIsDefined = false;
215 }
216 else
217 dir.CrcIsDefined = false;
218 }
219 }
220
221 for (i = 0; i < dir.SubDirs.Size(); i++)
222 {
223 unsigned subDirIndex = dir.SubDirs[i];
224 CalculateSizes(subDirIndex, archive);
225 CProxyDir &f = Dirs[subDirIndex];
226 dir.Size += f.Size;
227 dir.PackSize += f.PackSize;
228 dir.NumSubFiles += f.NumSubFiles;
229 dir.NumSubDirs += f.NumSubDirs;
230 dir.Crc += f.Crc;
231 if (!f.CrcIsDefined)
232 dir.CrcIsDefined = false;
233 }
234 }
235
Load(const CArc & arc,IProgress * progress)236 HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
237 {
238 // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) {
239
240 Files.Free();
241 Dirs.Clear();
242
243 Dirs.AddNew();
244 IInArchive *archive = arc.Archive;
245
246 UInt32 numItems;
247 RINOK(archive->GetNumberOfItems(&numItems))
248
249 if (progress)
250 RINOK(progress->SetTotal(numItems))
251
252 Files.Alloc(numItems);
253
254 UString path;
255 UString name;
256 NCOM::CPropVariant prop;
257
258 for (UInt32 i = 0; i < numItems; i++)
259 {
260 if (progress && (i & 0xFFFF) == 0)
261 {
262 const UInt64 currentItemIndex = i;
263 RINOK(progress->SetCompleted(¤tItemIndex))
264 }
265
266 const wchar_t *s = NULL;
267 unsigned len = 0;
268 bool isPtrName = false;
269
270 #if WCHAR_PATH_SEPARATOR != L'/'
271 wchar_t separatorChar = WCHAR_PATH_SEPARATOR;
272 #endif
273
274 #if defined(MY_CPU_LE) && defined(_WIN32)
275 // it works only if (sizeof(wchar_t) == 2)
276 if (arc.GetRawProps)
277 {
278 const void *p;
279 UInt32 size;
280 UInt32 propType;
281 if (arc.GetRawProps->GetRawProp(i, kpidPath, &p, &size, &propType) == S_OK
282 && propType == NPropDataType::kUtf16z
283 && size > 2)
284 {
285 // is (size <= 2), it's empty name, and we call default arc.GetItemPath();
286 len = size / 2 - 1;
287 s = (const wchar_t *)p;
288 isPtrName = true;
289 #if WCHAR_PATH_SEPARATOR != L'/'
290 separatorChar = L'/'; // 0
291 #endif
292 }
293 }
294 if (!s)
295 #endif
296 {
297 prop.Clear();
298 RINOK(arc.Archive->GetProperty(i, kpidPath, &prop))
299 if (prop.vt == VT_BSTR)
300 {
301 s = prop.bstrVal;
302 len = ::SysStringLen(prop.bstrVal);
303 }
304 else if (prop.vt != VT_EMPTY)
305 return E_FAIL;
306 if (len == 0)
307 {
308 RINOK(arc.GetItem_DefaultPath(i, path))
309 len = path.Len();
310 s = path;
311 }
312
313 /*
314 RINOK(arc.GetItemPath(i, path));
315 len = path.Len();
316 s = path;
317 */
318 }
319
320 unsigned curItem = 0;
321
322 /*
323 if (arc.Ask_Deleted)
324 {
325 bool isDeleted = false;
326 RINOK(Archive_IsItem_Deleted(archive, i, isDeleted));
327 if (isDeleted)
328 curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
329 }
330 */
331
332 unsigned namePos = 0;
333
334 unsigned numLevels = 0;
335
336 for (unsigned j = 0; j < len; j++)
337 {
338 const wchar_t c = s[j];
339 if (c == L'/'
340 #if WCHAR_PATH_SEPARATOR != L'/'
341 || (c == separatorChar)
342 #endif
343 )
344 {
345 const unsigned kLevelLimit = 1 << 10;
346 if (numLevels <= kLevelLimit)
347 {
348 if (numLevels == kLevelLimit)
349 name = "[LONG_PATH]";
350 else
351 name.SetFrom(s + namePos, j - namePos);
352 // 22.00: we can normalize dir here
353 // NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
354 curItem = AddDir(curItem, -1, name);
355 }
356 namePos = j + 1;
357 numLevels++;
358 }
359 }
360
361 /*
362 that code must be implemeted to hide alt streams in list.
363 if (arc.Ask_AltStreams)
364 {
365 bool isAltStream;
366 RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
367 if (isAltStream)
368 {
369
370 }
371 }
372 */
373
374 bool isDir;
375 RINOK(Archive_IsItem_Dir(archive, i, isDir))
376
377 CProxyFile &f = Files[i];
378
379 f.NameLen = len - namePos;
380 s += namePos;
381
382 if (isPtrName)
383 f.Name = s;
384 else
385 {
386 f.Name = AllocStringAndCopy(s, f.NameLen);
387 f.NeedDeleteName = true;
388 }
389
390 if (isDir)
391 {
392 name = s;
393 // 22.00: we can normalize dir here
394 // NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
395 AddDir(curItem, (int)i, name);
396 }
397 else
398 Dirs[curItem].SubFiles.Add(i);
399 }
400
401 CalculateSizes(0, archive);
402
403 // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s);
404
405 return S_OK;
406 }
407
408
409
410 // ---------- for Tree-mode archive ----------
411
GetDirPathParts(unsigned dirIndex,UStringVector & pathParts,bool & isAltStreamDir) const412 void CProxyArc2::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const
413 {
414 pathParts.Clear();
415
416 isAltStreamDir = false;
417
418 if (dirIndex == k_Proxy2_RootDirIndex)
419 return;
420 if (dirIndex == k_Proxy2_AltRootDirIndex)
421 {
422 isAltStreamDir = true;
423 return;
424 }
425
426 while (dirIndex >= k_Proxy2_NumRootDirs)
427 {
428 const CProxyDir2 &dir = Dirs[dirIndex];
429 const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
430 if (pathParts.IsEmpty() && (int)dirIndex == file.AltDirIndex)
431 isAltStreamDir = true;
432 pathParts.Insert(0, file.Name);
433 const int par = file.Parent;
434 if (par == -1)
435 break;
436 dirIndex = (unsigned)Files[(unsigned)par].DirIndex;
437 // if ((int)dirIndex == -1) break;
438 }
439 }
440
IsAltDir(unsigned dirIndex) const441 bool CProxyArc2::IsAltDir(unsigned dirIndex) const
442 {
443 if (dirIndex == k_Proxy2_RootDirIndex)
444 return false;
445 if (dirIndex == k_Proxy2_AltRootDirIndex)
446 return true;
447 const CProxyDir2 &dir = Dirs[dirIndex];
448 const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
449 return ((int)dirIndex == file.AltDirIndex);
450 }
451
GetDirPath_as_Prefix(unsigned dirIndex,bool & isAltStreamDir) const452 UString CProxyArc2::GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const
453 {
454 isAltStreamDir = false;
455 const CProxyDir2 &dir = Dirs[dirIndex];
456 if (dirIndex == k_Proxy2_AltRootDirIndex)
457 isAltStreamDir = true;
458 else if (dirIndex >= k_Proxy2_NumRootDirs)
459 {
460 const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
461 isAltStreamDir = ((int)dirIndex == file.AltDirIndex);
462 }
463 return dir.PathPrefix;
464 }
465
AddRealIndices_of_ArcItem(unsigned arcIndex,bool includeAltStreams,CUIntVector & realIndices) const466 void CProxyArc2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const
467 {
468 realIndices.Add(arcIndex);
469 const CProxyFile2 &file = Files[arcIndex];
470 if (file.DirIndex != -1)
471 AddRealIndices_of_Dir((unsigned)file.DirIndex, includeAltStreams, realIndices);
472 if (includeAltStreams && file.AltDirIndex != -1)
473 AddRealIndices_of_Dir((unsigned)file.AltDirIndex, includeAltStreams, realIndices);
474 }
475
AddRealIndices_of_Dir(unsigned dirIndex,bool includeAltStreams,CUIntVector & realIndices) const476 void CProxyArc2::AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const
477 {
478 const CRecordVector<unsigned> &subFiles = Dirs[dirIndex].Items;
479 FOR_VECTOR (i, subFiles)
480 {
481 AddRealIndices_of_ArcItem(subFiles[i], includeAltStreams, realIndices);
482 }
483 }
484
GetRealIndex(unsigned dirIndex,unsigned index) const485 unsigned CProxyArc2::GetRealIndex(unsigned dirIndex, unsigned index) const
486 {
487 return Dirs[dirIndex].Items[index];
488 }
489
GetRealIndices(unsigned dirIndex,const UInt32 * indices,UInt32 numItems,bool includeAltStreams,CUIntVector & realIndices) const490 void CProxyArc2::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const
491 {
492 const CProxyDir2 &dir = Dirs[dirIndex];
493 realIndices.Clear();
494 for (UInt32 i = 0; i < numItems; i++)
495 {
496 AddRealIndices_of_ArcItem(dir.Items[indices[i]], includeAltStreams, realIndices);
497 }
498 HeapSort(realIndices.NonConstData(), realIndices.Size());
499 }
500
CalculateSizes(unsigned dirIndex,IInArchive * archive)501 void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive)
502 {
503 CProxyDir2 &dir = Dirs[dirIndex];
504 dir.Size = dir.PackSize = 0;
505 dir.NumSubDirs = 0; // dir.SubDirs.Size();
506 dir.NumSubFiles = 0; // dir.Files.Size();
507 dir.CrcIsDefined = true;
508 dir.Crc = 0;
509
510 FOR_VECTOR (i, dir.Items)
511 {
512 UInt32 index = dir.Items[i];
513 UInt64 size, packSize;
514 const bool sizeDefined = GetSize(archive, index, kpidSize, size);
515 dir.Size += size;
516 GetSize(archive, index, kpidPackSize, packSize);
517 dir.PackSize += packSize;
518 {
519 NCOM::CPropVariant prop;
520 if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
521 {
522 if (prop.vt == VT_UI4)
523 dir.Crc += prop.ulVal;
524 else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
525 dir.CrcIsDefined = false;
526 }
527 else
528 dir.CrcIsDefined = false;
529 }
530
531 const CProxyFile2 &subFile = Files[index];
532 if (subFile.DirIndex == -1)
533 {
534 dir.NumSubFiles++;
535 }
536 else
537 {
538 // 22.00: we normalize name
539 UString s = subFile.Name;
540 NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s);
541 dir.NumSubDirs++;
542 CProxyDir2 &f = Dirs[subFile.DirIndex];
543 f.PathPrefix = dir.PathPrefix + s + WCHAR_PATH_SEPARATOR;
544 CalculateSizes((unsigned)subFile.DirIndex, archive);
545 dir.Size += f.Size;
546 dir.PackSize += f.PackSize;
547 dir.NumSubFiles += f.NumSubFiles;
548 dir.NumSubDirs += f.NumSubDirs;
549 dir.Crc += f.Crc;
550 if (!f.CrcIsDefined)
551 dir.CrcIsDefined = false;
552 }
553
554 if (subFile.AltDirIndex == -1)
555 {
556 // dir.NumSubFiles++;
557 }
558 else
559 {
560 // dir.NumSubDirs++;
561 CProxyDir2 &f = Dirs[subFile.AltDirIndex];
562 f.PathPrefix = dir.PathPrefix + subFile.Name + L':';
563 CalculateSizes((unsigned)subFile.AltDirIndex, archive);
564 }
565 }
566 }
567
568
IsThere_SubDir(unsigned dirIndex,const UString & name) const569 bool CProxyArc2::IsThere_SubDir(unsigned dirIndex, const UString &name) const
570 {
571 const CRecordVector<unsigned> &subFiles = Dirs[dirIndex].Items;
572 FOR_VECTOR (i, subFiles)
573 {
574 const CProxyFile2 &file = Files[subFiles[i]];
575 if (file.IsDir())
576 if (CompareFileNames(name, file.Name) == 0)
577 return true;
578 }
579 return false;
580 }
581
Load(const CArc & arc,IProgress * progress)582 HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
583 {
584 if (!arc.GetRawProps)
585 return E_FAIL;
586
587 // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) {
588
589 Dirs.Clear();
590 Files.Free();
591
592 IInArchive *archive = arc.Archive;
593
594 UInt32 numItems;
595 RINOK(archive->GetNumberOfItems(&numItems))
596 if (progress)
597 RINOK(progress->SetTotal(numItems))
598 UString fileName;
599
600
601 {
602 // Dirs[0] - root dir
603 /* CProxyDir2 &dir = */ Dirs.AddNew();
604 }
605
606 {
607 // Dirs[1] - for alt streams of root dir
608 CProxyDir2 &dir = Dirs.AddNew();
609 dir.PathPrefix = ':';
610 }
611
612 Files.Alloc(numItems);
613
614 UString tempUString;
615 AString tempAString;
616
617 UInt32 i;
618 for (i = 0; i < numItems; i++)
619 {
620 if (progress && (i & 0xFFFFF) == 0)
621 {
622 UInt64 currentItemIndex = i;
623 RINOK(progress->SetCompleted(¤tItemIndex))
624 }
625
626 CProxyFile2 &file = Files[i];
627
628 const void *p;
629 UInt32 size;
630 UInt32 propType;
631 RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType))
632
633 #ifdef MY_CPU_LE
634 if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
635 {
636 file.Name = (const wchar_t *)p;
637 file.NameLen = 0;
638 if (size >= sizeof(wchar_t))
639 file.NameLen = size / sizeof(wchar_t) - 1;
640 }
641 else
642 #endif
643 if (p && propType == NPropDataType::kUtf8z)
644 {
645 tempAString = (const char *)p;
646 ConvertUTF8ToUnicode(tempAString, tempUString);
647 file.NameLen = tempUString.Len();
648 file.Name = AllocStringAndCopy(tempUString);
649 file.NeedDeleteName = true;
650 }
651 else
652 {
653 NCOM::CPropVariant prop;
654 RINOK(arc.Archive->GetProperty(i, kpidName, &prop))
655 const wchar_t *s;
656 if (prop.vt == VT_BSTR)
657 s = prop.bstrVal;
658 else if (prop.vt == VT_EMPTY)
659 s = L"[Content]";
660 else
661 return E_FAIL;
662 file.NameLen = MyStringLen(s);
663 file.Name = AllocStringAndCopy(s, file.NameLen);
664 file.NeedDeleteName = true;
665 }
666
667 UInt32 parent = (UInt32)(Int32)-1;
668 UInt32 parentType = 0;
669 RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType))
670 file.Parent = (Int32)parent;
671
672 if (arc.Ask_Deleted)
673 {
674 bool isDeleted = false;
675 RINOK(Archive_IsItem_Deleted(archive, i, isDeleted))
676 if (isDeleted)
677 {
678 // continue;
679 // curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
680 }
681 }
682
683 bool isDir;
684 RINOK(Archive_IsItem_Dir(archive, i, isDir))
685
686 if (isDir)
687 {
688 file.DirIndex = (int)Dirs.Size();
689 CProxyDir2 &dir = Dirs.AddNew();
690 dir.ArcIndex = (int)i;
691 }
692 if (arc.Ask_AltStream)
693 RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream))
694 }
695
696 for (i = 0; i < numItems; i++)
697 {
698 CProxyFile2 &file = Files[i];
699 int dirIndex;
700
701 if (file.IsAltStream)
702 {
703 if (file.Parent == -1)
704 dirIndex = k_Proxy2_AltRootDirIndex;
705 else
706 {
707 int &folderIndex2 = Files[(unsigned)file.Parent].AltDirIndex;
708 if (folderIndex2 == -1)
709 {
710 folderIndex2 = (int)Dirs.Size();
711 CProxyDir2 &dir = Dirs.AddNew();
712 dir.ArcIndex = file.Parent;
713 }
714 dirIndex = folderIndex2;
715 }
716 }
717 else
718 {
719 if (file.Parent == -1)
720 dirIndex = k_Proxy2_RootDirIndex;
721 else
722 {
723 dirIndex = Files[(unsigned)file.Parent].DirIndex;
724 if (dirIndex == -1)
725 return E_FAIL;
726 }
727 }
728
729 Dirs[dirIndex].Items.Add(i);
730 }
731
732 for (i = 0; i < k_Proxy2_NumRootDirs; i++)
733 CalculateSizes(i, archive);
734
735 // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s);
736
737 return S_OK;
738 }
739
FindItem(unsigned dirIndex,const wchar_t * name,bool foldersOnly) const740 int CProxyArc2::FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const
741 {
742 const CProxyDir2 &dir = Dirs[dirIndex];
743 FOR_VECTOR (i, dir.Items)
744 {
745 const CProxyFile2 &file = Files[dir.Items[i]];
746 if (foldersOnly && file.DirIndex == -1)
747 continue;
748 if (CompareFileNames(file.Name, name) == 0)
749 return (int)i;
750 }
751 return -1;
752 }
753