Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/UI/Agent/AgentProxy.cpp')
-rw-r--r--[-rwxr-xr-x]CPP/7zip/UI/Agent/AgentProxy.cpp565
1 files changed, 453 insertions, 112 deletions
diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp
index ce9b3bfb..a31a904b 100755..100644
--- a/CPP/7zip/UI/Agent/AgentProxy.cpp
+++ b/CPP/7zip/UI/Agent/AgentProxy.cpp
@@ -3,17 +3,21 @@
#include "StdAfx.h"
#include "../../../../C/Sort.h"
+#include "../../../../C/CpuArch.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/PropVariantConv.h"
#include "AgentProxy.h"
using namespace NWindows;
-int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
+int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name, unsigned &insertPos) const
{
- int left = 0, right = Folders.Size();
+ const CRecordVector<unsigned> &subFolders = Folders[folderIndex].Folders;
+ unsigned left = 0, right = subFolders.Size();
for (;;)
{
if (left == right)
@@ -21,10 +25,11 @@ int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
insertPos = left;
return -1;
}
- int mid = (left + right) / 2;
- int compare = name.CompareNoCase(Folders[mid].Name);
+ unsigned mid = (left + right) / 2;
+ unsigned folderIndex = subFolders[mid];
+ int compare = CompareFileNames(name, Folders[folderIndex].Name);
if (compare == 0)
- return mid;
+ return folderIndex;
if (compare < 0)
right = mid;
else
@@ -32,40 +37,41 @@ int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
}
}
-int CProxyFolder::FindDirSubItemIndex(const UString &name) const
+int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name) const
{
- int insertPos;
- return FindDirSubItemIndex(name, insertPos);
+ unsigned insertPos;
+ return FindDirSubItemIndex(folderIndex, name, insertPos);
}
void CProxyFolder::AddFileSubItem(UInt32 index, const UString &name)
{
- Files.Add(CProxyFile());
- Files.Back().Name = name;
- Files.Back().Index = index;
+ CProxyFile &f = Files.AddNew();
+ f.Index = index;
+ f.Name = name;
}
-CProxyFolder* CProxyFolder::AddDirSubItem(UInt32 index, bool leaf, const UString &name)
+unsigned CProxyArchive::AddDirSubItem(unsigned folderIndex, UInt32 index, bool leaf, const UString &name)
{
- int insertPos;
- int folderIndex = FindDirSubItemIndex(name, insertPos);
- if (folderIndex >= 0)
+ unsigned insertPos;
+ int subFolderIndex = FindDirSubItemIndex(folderIndex, name, insertPos);
+ if (subFolderIndex >= 0)
{
- CProxyFolder *item = &Folders[folderIndex];
+ CProxyFolder &item = Folders[subFolderIndex];
if (leaf)
{
- item->Index = index;
- item->IsLeaf = true;
+ item.Index = index;
+ item.IsLeaf = true;
}
- return item;
+ return subFolderIndex;
}
- Folders.Insert(insertPos, CProxyFolder());
- CProxyFolder *item = &Folders[insertPos];
- item->Name = name;
- item->Index = index;
- item->Parent = this;
- item->IsLeaf = leaf;
- return item;
+ subFolderIndex = Folders.Size();
+ Folders[folderIndex].Folders.Insert(insertPos, subFolderIndex);
+ CProxyFolder &item = Folders.AddNew();
+ item.Name = name;
+ item.Index = index;
+ item.Parent = folderIndex;
+ item.IsLeaf = leaf;
+ return subFolderIndex;
}
void CProxyFolder::Clear()
@@ -74,51 +80,71 @@ void CProxyFolder::Clear()
Files.Clear();
}
-void CProxyFolder::GetPathParts(UStringVector &pathParts) const
+void CProxyArchive::GetPathParts(int folderIndex, UStringVector &pathParts) const
{
pathParts.Clear();
- const CProxyFolder *current = this;
- while (current->Parent != NULL)
+ while (folderIndex >= 0)
{
- pathParts.Insert(0, current->Name);
- current = current->Parent;
+ const CProxyFolder &folder = Folders[folderIndex];
+ folderIndex = folder.Parent;
+ if (folderIndex < 0)
+ break;
+ pathParts.Insert(0, folder.Name);
}
}
-UString CProxyFolder::GetFullPathPrefix() const
+UString CProxyArchive::GetFullPathPrefix(int folderIndex) const
{
UString result;
- const CProxyFolder *current = this;
- while (current->Parent != NULL)
+ while (folderIndex >= 0)
{
- result = current->Name + UString(WCHAR_PATH_SEPARATOR) + result;
- current = current->Parent;
+ const CProxyFolder &folder = Folders[folderIndex];
+ folderIndex = folder.Parent;
+ if (folderIndex < 0)
+ break;
+ result = folder.Name + UString(WCHAR_PATH_SEPARATOR) + result;
}
return result;
}
-void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const
+void CProxyArchive::AddRealIndices(unsigned folderIndex, CUIntVector &realIndices) const
{
- if (IsLeaf)
- realIndices.Add(Index);
- int i;
- for (i = 0; i < Folders.Size(); i++)
- Folders[i].AddRealIndices(realIndices);
- for (i = 0; i < Files.Size(); i++)
- realIndices.Add(Files[i].Index);
+ const CProxyFolder &folder = Folders[folderIndex];
+ if (folder.IsLeaf)
+ realIndices.Add(folder.Index);
+ unsigned i;
+ for (i = 0; i < folder.Folders.Size(); i++)
+ AddRealIndices(folder.Folders[i], realIndices);
+ for (i = 0; i < folder.Files.Size(); i++)
+ realIndices.Add(folder.Files[i].Index);
+}
+
+int CProxyArchive::GetRealIndex(unsigned folderIndex, unsigned index) const
+{
+ const CProxyFolder &folder = Folders[folderIndex];
+ unsigned numDirItems = folder.Folders.Size();
+ if (index < numDirItems)
+ {
+ const CProxyFolder &f = Folders[folder.Folders[index]];
+ if (f.IsLeaf)
+ return f.Index;
+ return -1;
+ }
+ return folder.Files[index - numDirItems].Index;
}
-void CProxyFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
+void CProxyArchive::GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
{
+ const CProxyFolder &folder = Folders[folderIndex];
realIndices.Clear();
for (UInt32 i = 0; i < numItems; i++)
{
- int index = indices[i];
- int numDirItems = Folders.Size();
+ UInt32 index = indices[i];
+ unsigned numDirItems = folder.Folders.Size();
if (index < numDirItems)
- Folders[index].AddRealIndices(realIndices);
+ AddRealIndices(folder.Folders[index], realIndices);
else
- realIndices.Add(Files[index - numDirItems].Index);
+ realIndices.Add(folder.Files[index - numDirItems].Index);
}
HeapSort(&realIndices.Front(), realIndices.Size());
}
@@ -126,111 +152,426 @@ void CProxyFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntV
///////////////////////////////////////////////
// CProxyArchive
-static UInt64 GetSize(IInArchive *archive, UInt32 index, PROPID propID)
+static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &size)
{
+ size = 0;
NCOM::CPropVariant prop;
- if (archive->GetProperty(index, propID, &prop) == S_OK)
- if (prop.vt != VT_EMPTY)
- return ConvertPropVariantToUInt64(prop);
- return 0;
+ if (archive->GetProperty(index, propID, &prop) != S_OK)
+ throw 20120228;
+ return ConvertPropVariantToUInt64(prop, size);
}
-void CProxyFolder::CalculateSizes(IInArchive *archive)
+void CProxyArchive::CalculateSizes(unsigned folderIndex, IInArchive *archive)
{
- Size = PackSize = 0;
- NumSubFolders = Folders.Size();
- NumSubFiles = Files.Size();
- CrcIsDefined = true;
- Crc = 0;
- int i;
- for (i = 0; i < Files.Size(); i++)
+ CProxyFolder &folder = Folders[folderIndex];
+ folder.Size = folder.PackSize = 0;
+ folder.NumSubFolders = folder.Folders.Size();
+ folder.NumSubFiles = folder.Files.Size();
+ folder.CrcIsDefined = true;
+ folder.Crc = 0;
+ unsigned i;
+ for (i = 0; i < folder.Files.Size(); i++)
{
- UInt32 index = Files[i].Index;
- Size += GetSize(archive, index, kpidSize);
- PackSize += GetSize(archive, index, kpidPackSize);
+ UInt32 index = folder.Files[i].Index;
+ UInt64 size, packSize;
+ bool sizeDefined = GetSize(archive, index, kpidSize, size);
+ folder.Size += size;
+ GetSize(archive, index, kpidPackSize, packSize);
+ folder.PackSize += packSize;
{
NCOM::CPropVariant prop;
- if (archive->GetProperty(index, kpidCRC, &prop) == S_OK && prop.vt == VT_UI4)
- Crc += prop.ulVal;
+ if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
+ {
+ if (prop.vt == VT_UI4)
+ folder.Crc += prop.ulVal;
+ else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
+ folder.CrcIsDefined = false;
+ }
else
- CrcIsDefined = false;
+ folder.CrcIsDefined = false;
}
}
- for (i = 0; i < Folders.Size(); i++)
+ for (i = 0; i < folder.Folders.Size(); i++)
{
- CProxyFolder &f = Folders[i];
- f.CalculateSizes(archive);
- Size += f.Size;
- PackSize += f.PackSize;
- NumSubFiles += f.NumSubFiles;
- NumSubFolders += f.NumSubFolders;
- Crc += f.Crc;
+ unsigned subFolderIndex = folder.Folders[i];
+ CProxyFolder &f = Folders[subFolderIndex];
+ CalculateSizes(subFolderIndex, archive);
+ folder.Size += f.Size;
+ folder.PackSize += f.PackSize;
+ folder.NumSubFiles += f.NumSubFiles;
+ folder.NumSubFolders += f.NumSubFolders;
+ folder.Crc += f.Crc;
if (!f.CrcIsDefined)
- CrcIsDefined = false;
+ folder.CrcIsDefined = false;
}
}
HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress)
{
- RootFolder.Clear();
+ /*
+ DWORD tickCount = GetTickCount();
+ for (int ttt = 0; ttt < 1000; ttt++) {
+ */
+
+ Folders.Clear();
+ Folders.AddNew();
IInArchive *archive = arc.Archive;
- {
- ThereIsPathProp = false;
- UInt32 numProps;
- archive->GetNumberOfProperties(&numProps);
- for (UInt32 i = 0; i < numProps; i++)
- {
- CMyComBSTR name;
- PROPID propID;
- VARTYPE varType;
- RINOK(archive->GetPropertyInfo(i, &name, &propID, &varType));
- if (propID == kpidPath)
- {
- ThereIsPathProp = true;
- break;
- }
- }
- }
UInt32 numItems;
RINOK(archive->GetNumberOfItems(&numItems));
- if (progress != NULL)
- {
- UInt64 totalItems = numItems;
- RINOK(progress->SetTotal(totalItems));
- }
+ if (progress)
+ RINOK(progress->SetTotal(numItems));
+ UString filePath;
UString fileName;
for (UInt32 i = 0; i < numItems; i++)
{
- if (progress != NULL && (i & 0xFFFFF) == 0)
+ if (progress && (i & 0xFFFFF) == 0)
{
UInt64 currentItemIndex = i;
RINOK(progress->SetCompleted(&currentItemIndex));
}
- UString filePath;
RINOK(arc.GetItemPath(i, filePath));
- CProxyFolder *curItem = &RootFolder;
- int len = filePath.Length();
+ unsigned curItem = 0;
+ unsigned len = filePath.Len();
fileName.Empty();
- for (int j = 0; j < len; j++)
+
+ /*
+ if (arc.Ask_Deleted)
+ {
+ bool isDeleted = false;
+ RINOK(Archive_IsItem_Deleted(archive, i, isDeleted));
+ if (isDeleted)
+ curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
+ }
+ */
+
+ for (unsigned j = 0; j < len; j++)
{
wchar_t c = filePath[j];
if (c == WCHAR_PATH_SEPARATOR || c == L'/')
{
- curItem = curItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName);
+ curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, fileName);
fileName.Empty();
}
else
fileName += c;
}
+ /*
+ that code must be implemeted to hide alt streams in list.
+ if (arc.Ask_AltStreams)
+ {
+ bool isAltStream;
+ RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
+ if (isAltStream)
+ {
+
+ }
+ }
+ */
+
bool isFolder;
- RINOK(IsArchiveItemFolder(archive, i, isFolder));
+ RINOK(Archive_IsItem_Folder(archive, i, isFolder));
if (isFolder)
- curItem->AddDirSubItem(i, true, fileName);
+ AddDirSubItem(curItem, i, true, fileName);
else
- curItem->AddFileSubItem(i, fileName);
+ Folders[curItem].AddFileSubItem(i, fileName);
+ }
+ CalculateSizes(0, archive);
+
+ /*
+ }
+ char s[128];
+ sprintf(s, "load archive %7d ms", GetTickCount() - tickCount);
+ OutputDebugStringA(s);
+ */
+
+ return S_OK;
+}
+
+
+
+// ---------- for Tree-mode archive ----------
+
+void CProxyArchive2::GetPathParts(int folderIndex, UStringVector &pathParts) const
+{
+ pathParts.Clear();
+ while (folderIndex > 0)
+ {
+ const CProxyFolder2 &folder = Folders[folderIndex];
+ const CProxyFile2 &file = Files[folder.ArcIndex];
+ pathParts.Insert(0, file.Name);
+ int par = file.Parent;
+ if (par < 0)
+ break;
+ folderIndex = Files[par].FolderIndex;
+ }
+}
+
+UString CProxyArchive2::GetFullPathPrefix(unsigned folderIndex) const
+{
+ return Folders[folderIndex].PathPrefix;
+ /*
+ UString result;
+ while (folderIndex > 0)
+ {
+ const CProxyFile2 &file = Files[Folders[folderIndex].ArcIndex];
+ result = (UString)(file.Name) + (UString)WCHAR_PATH_SEPARATOR + result;
+ if (file.Parent < 0)
+ break;
+ folderIndex = Files[file.Parent].FolderIndex;
+ }
+ return result;
+ */
+}
+
+void CProxyArchive2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const
+{
+ realIndices.Add(arcIndex);
+ const CProxyFile2 &file = Files[arcIndex];
+ if (file.FolderIndex >= 0)
+ AddRealIndices_of_Folder(file.FolderIndex, includeAltStreams, realIndices);
+ if (includeAltStreams && file.AltStreamsFolderIndex >= 0)
+ AddRealIndices_of_Folder(file.AltStreamsFolderIndex, includeAltStreams, realIndices);
+}
+
+void CProxyArchive2::AddRealIndices_of_Folder(unsigned folderIndex, bool includeAltStreams, CUIntVector &realIndices) const
+{
+ const CRecordVector<unsigned> &subFiles = Folders[folderIndex].SubFiles;
+ FOR_VECTOR (i, subFiles)
+ {
+ AddRealIndices_of_ArcItem(subFiles[i], includeAltStreams, realIndices);
}
- RootFolder.CalculateSizes(archive);
+}
+
+unsigned CProxyArchive2::GetRealIndex(unsigned folderIndex, unsigned index) const
+{
+ return Folders[folderIndex].SubFiles[index];
+}
+
+void CProxyArchive2::GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const
+{
+ const CProxyFolder2 &folder = Folders[folderIndex];
+ realIndices.Clear();
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ AddRealIndices_of_ArcItem(folder.SubFiles[indices[i]], includeAltStreams, realIndices);
+ }
+ HeapSort(&realIndices.Front(), realIndices.Size());
+}
+
+void CProxyArchive2::CalculateSizes(unsigned folderIndex, IInArchive *archive)
+{
+ CProxyFolder2 &folder = Folders[folderIndex];
+ folder.Size = folder.PackSize = 0;
+ folder.NumSubFolders = 0; // folder.Folders.Size();
+ folder.NumSubFiles = 0; // folder.Files.Size();
+ folder.CrcIsDefined = true;
+ folder.Crc = 0;
+ FOR_VECTOR (i, folder.SubFiles)
+ {
+ UInt32 index = folder.SubFiles[i];
+ UInt64 size, packSize;
+ bool sizeDefined = GetSize(archive, index, kpidSize, size);
+ folder.Size += size;
+ GetSize(archive, index, kpidPackSize, packSize);
+ folder.PackSize += packSize;
+ {
+ NCOM::CPropVariant prop;
+ if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
+ {
+ if (prop.vt == VT_UI4)
+ folder.Crc += prop.ulVal;
+ else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
+ folder.CrcIsDefined = false;
+ }
+ else
+ folder.CrcIsDefined = false;
+ }
+
+ const CProxyFile2 &subFile = Files[index];
+ if (subFile.FolderIndex < 0)
+ {
+ folder.NumSubFiles++;
+ }
+ else
+ {
+ folder.NumSubFolders++;
+ CProxyFolder2 &f = Folders[subFile.FolderIndex];
+ f.PathPrefix = folder.PathPrefix + subFile.Name + WCHAR_PATH_SEPARATOR;
+ CalculateSizes(subFile.FolderIndex, archive);
+ folder.Size += f.Size;
+ folder.PackSize += f.PackSize;
+ folder.NumSubFiles += f.NumSubFiles;
+ folder.NumSubFolders += f.NumSubFolders;
+ folder.Crc += f.Crc;
+ if (!f.CrcIsDefined)
+ folder.CrcIsDefined = false;
+ }
+
+ if (subFile.AltStreamsFolderIndex < 0)
+ {
+ // folder.NumSubFiles++;
+ }
+ else
+ {
+ // folder.NumSubFolders++;
+ CProxyFolder2 &f = Folders[subFile.AltStreamsFolderIndex];
+ f.PathPrefix = folder.PathPrefix + subFile.Name + L":";
+ CalculateSizes(subFile.AltStreamsFolderIndex, archive);
+ /*
+ folder.Size += f.Size;
+ folder.PackSize += f.PackSize;
+ folder.NumSubFiles += f.NumSubFiles;
+ folder.NumSubFolders += f.NumSubFolders;
+ folder.Crc += f.Crc;
+ if (!f.CrcIsDefined)
+ folder.CrcIsDefined = false;
+ */
+ }
+
+
+ }
+}
+
+
+bool CProxyArchive2::IsThere_SubDir(unsigned folderIndex, const UString &name) const
+{
+ const CRecordVector<unsigned> &subFiles = Folders[folderIndex].SubFiles;
+ FOR_VECTOR (i, subFiles)
+ {
+ const CProxyFile2 &file = Files[subFiles[i]];
+ if (file.IsDir())
+ if (CompareFileNames(name, file.Name) == 0)
+ return true;
+ }
+ return false;
+}
+
+HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
+{
+ if (!arc.GetRawProps)
+ return E_FAIL;
+
+ // DWORD tickCount = GetTickCount();
+
+ Folders.Clear();
+
+ IInArchive *archive = arc.Archive;
+
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+ if (progress)
+ RINOK(progress->SetTotal(numItems));
+ UString fileName;
+ {
+ CProxyFolder2 &folder = Folders.AddNew();
+ folder.ArcIndex = -1;
+ }
+
+ Files.Alloc(numItems);
+
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ if (progress && (i & 0xFFFFF) == 0)
+ {
+ UInt64 currentItemIndex = i;
+ RINOK(progress->SetCompleted(&currentItemIndex));
+ }
+
+ CProxyFile2 &file = Files[i];
+
+ #ifdef MY_CPU_LE
+ const void *p;
+ UInt32 size;
+ UInt32 propType;
+ RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType));
+
+ if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
+ {
+ file.Name = (const wchar_t *)p;
+ file.NameSize = 0;
+ if (size >= 2)
+ file.NameSize = size / 2 - 1;
+ }
+ else
+ #endif
+ {
+ NCOM::CPropVariant prop;
+ RINOK(arc.Archive->GetProperty(i, kpidName, &prop));
+ const wchar_t *s;
+ if (prop.vt == VT_BSTR)
+ s = prop.bstrVal;
+ else if (prop.vt == VT_EMPTY)
+ s = L"[Content]";
+ else
+ return E_FAIL;
+ file.NameSize = MyStringLen(s);
+ file.Name = new wchar_t[file.NameSize + 1];
+ file.NeedDeleteName = true;
+ MyStringCopy((wchar_t *)file.Name, s);
+ }
+ UInt32 parent = (UInt32)(Int32)-1;
+ UInt32 parentType = 0;
+ RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType));
+ file.Parent = (Int32)parent;
+
+ if (arc.Ask_Deleted)
+ {
+ bool isDeleted = false;
+ RINOK(Archive_IsItem_Deleted(archive, i, isDeleted));
+ if (isDeleted)
+ {
+ // continue;
+ // curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
+ }
+ }
+
+ bool isFolder;
+ RINOK(Archive_IsItem_Folder(archive, i, isFolder));
+
+ if (isFolder)
+ {
+ file.FolderIndex = Folders.Size();
+ CProxyFolder2 &folder = Folders.AddNew();
+ folder.ArcIndex = i;
+ }
+ if (arc.Ask_AltStream)
+ RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream));
+ }
+
+ for (i = 0; i < numItems; i++)
+ {
+ CProxyFile2 &file = Files[i];
+ if (file.IsAltStream)
+ {
+ if (file.Parent >= 0)
+ {
+ int &folderIndex = Files[file.Parent].AltStreamsFolderIndex;
+ if (folderIndex < 0)
+ {
+ folderIndex = Folders.Size();
+ CProxyFolder2 &folder = Folders.AddNew();
+ folder.ArcIndex = file.Parent; // do we need it ???
+ }
+ Folders[folderIndex].SubFiles.Add(i);
+ }
+ }
+ else
+ {
+ int folderIndex = GetParentFolderOfFile(i);
+ if (folderIndex < 0)
+ return E_FAIL;
+ Folders[folderIndex].SubFiles.Add(i);
+ }
+ }
+ CalculateSizes(0, archive);
+
+ /*
+ char s[128];
+ sprintf(s, "load archive %7d ms", GetTickCount() - tickCount);
+ OutputDebugStringA(s);
+ */
return S_OK;
}