bool C7ZipArchiveItemImpl::GetBoolProperty(lib7zip::PropertyIndexEnum propertyIndex, bool & val) const { int p7zip_index = 0; switch(propertyIndex) { case lib7zip::kpidSolid: //(Solid) p7zip_index = kpidSolid; break; case lib7zip::kpidEncrypted: //(Encrypted) p7zip_index = kpidEncrypted; break; case lib7zip::kpidIsDir: //(IsDir) return IsArchiveItemFolder(m_pInArchive, m_nIndex, val) == S_OK; default: return false; } NWindows::NCOM::CPropVariant prop; if (m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) == 0 && prop.vt == VT_BOOL) { val = prop.bVal; return true; } return false; }
bool C7ZipArchiveItemImpl::GetFileTimeProperty(lib7zip::PropertyIndexEnum propertyIndex, unsigned __int64 & val) const { int p7zip_index = 0; switch(propertyIndex) { case lib7zip::kpidCTime: //(Created) p7zip_index = kpidCTime; break; case lib7zip::kpidATime: //(Accessed) p7zip_index = kpidATime; break; case lib7zip::kpidMTime: //(Modified) p7zip_index = kpidMTime; break; default: return false; } NWindows::NCOM::CPropVariant prop; if (m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) != 0) return false; if (prop.vt == VT_FILETIME) { unsigned __int64 tmp_val = 0; memmove(&tmp_val, &prop.filetime, sizeof(unsigned __int64)); val = tmp_val; return true; } return false; }
bool C7ZipArchiveItemImpl::IsEncrypted() const { // Check if encrypted (password protected) NWindows::NCOM::CPropVariant prop; bool isEncrypted = false; if (m_pInArchive->GetProperty(m_nIndex, kpidEncrypted, &prop) == 0 && prop.vt == VT_BOOL) isEncrypted = prop.bVal; return isEncrypted; }
wstring C7ZipArchiveItemImpl::GetFullPath() const { // Get Name NWindows::NCOM::CPropVariant prop; wstring fullPath = kEmptyFileAlias; if (!m_pInArchive->GetProperty(m_nIndex, kpidPath, &prop)) { if (prop.vt == VT_BSTR) fullPath = prop.bstrVal; } return fullPath; }
UInt64 C7ZipArchiveItemImpl::GetSize() const { // Get uncompressed size NWindows::NCOM::CPropVariant prop; if (m_pInArchive->GetProperty(m_nIndex, kpidSize, &prop) != 0) return 0; UInt64 size = 0; if (prop.vt == VT_UI8 || prop.vt == VT_UI4) size = ConvertPropVariantToUInt64(prop); return size; }
bool C7ZipArchiveItemImpl::GetUInt64Property(lib7zip::PropertyIndexEnum propertyIndex, unsigned __int64 & val) const { int p7zip_index = 0; switch(propertyIndex) { case lib7zip::kpidSize: p7zip_index = kpidSize; break; case lib7zip::kpidPackSize: //(Packed Size) p7zip_index = kpidPackSize; break; case lib7zip::kpidAttrib: //(Attributes) p7zip_index = kpidAttrib; break; case lib7zip::kpidPhySize: //(Physical Size) p7zip_index = kpidPhySize; break; case lib7zip::kpidHeadersSize: //(Headers Size) p7zip_index = kpidHeadersSize; break; case lib7zip::kpidChecksum: //(Checksum) p7zip_index = kpidChecksum; break; case lib7zip::kpidTotalSize: //(Total Size) p7zip_index = kpidTotalSize; break; case lib7zip::kpidFreeSpace: //(Free Space) p7zip_index = kpidFreeSpace; break; case lib7zip::kpidClusterSize: //(Cluster Size) p7zip_index = kpidClusterSize; break; default: return false; } NWindows::NCOM::CPropVariant prop; if (m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) != 0) return false; if (prop.vt == VT_UI8 || prop.vt == VT_UI4) { val = ConvertPropVariantToUInt64(prop); return true; } return false; }
void BitMemExtractor::extract( const vector< byte_t >& in_buffer, vector< byte_t >& out_buffer, unsigned int index ) const { CMyComPtr< IInArchive > inArchive = openArchive( mLibrary, mFormat, in_buffer, *this ); NCOM::CPropVariant prop; inArchive->GetProperty( index, kpidSize, &prop ); MemExtractCallback* extractCallbackSpec = new MemExtractCallback( *this, inArchive, out_buffer ); const UInt32 indices[] = { index }; CMyComPtr< IArchiveExtractCallback > extractCallback( extractCallbackSpec ); if ( inArchive->Extract( indices, 1, false, extractCallback ) != S_OK ) { throw BitException( extractCallbackSpec->getErrorMessage() ); } }
bool C7ZipArchiveItemImpl::GetStringProperty(lib7zip::PropertyIndexEnum propertyIndex, wstring & val) const { int p7zip_index = 0; switch(propertyIndex) { case lib7zip::kpidComment: //(Comment) p7zip_index = kpidComment; break; case lib7zip::kpidCharacts: //(Characteristics) p7zip_index = kpidCharacts; break; case lib7zip::kpidCreatorApp: //(Creator Application) p7zip_index = kpidCreatorApp; break; case lib7zip::kpidVolumeName: //(Label) p7zip_index = kpidVolumeName; break; case lib7zip::kpidPath: //(FullPath) p7zip_index = kpidPath; break; case lib7zip::kpidUser: //(User) p7zip_index = kpidUser; break; case lib7zip::kpidGroup: //(Group) p7zip_index = kpidGroup; break; default: return false; } NWindows::NCOM::CPropVariant prop; if (!m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) && prop.vt == VT_BSTR) { val = prop.bstrVal; return true; } return false; }
void CHandler::ParseName(Byte replaceByte, IArchiveOpenCallback *callback) { if (!callback) return; CMyComPtr<IArchiveOpenVolumeCallback> volumeCallback; callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); if (!volumeCallback) return; NWindows::NCOM::CPropVariant prop; if (volumeCallback->GetProperty(kpidName, &prop) != S_OK || prop.vt != VT_BSTR) return; UString s = prop.bstrVal; if (s.IsEmpty() || s.Back() != L'_') return; s.DeleteBack(); _name = s; if (replaceByte == 0) { if (s.Len() < 3 || s[s.Len() - 3] != '.') return; for (unsigned i = 0; i < ARRAY_SIZE(g_Exts); i++) { const char *ext = g_Exts[i]; if (s[s.Len() - 2] == (Byte)ext[0] && s[s.Len() - 1] == (Byte)ext[1]) { replaceByte = ext[2]; break; } } } if (replaceByte >= 0x20 && replaceByte < 0x80) _name += (wchar_t)replaceByte; }
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { Close(); if (!callback) return S_FALSE; CMyComPtr<IArchiveOpenVolumeCallback> volumeCallback; callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); if (!volumeCallback) return S_FALSE; UString name; { NCOM::CPropVariant prop; RINOK(volumeCallback->GetProperty(kpidName, &prop)); if (prop.vt != VT_BSTR) return S_FALSE; name = prop.bstrVal; } int dotPos = name.ReverseFind_Dot(); const UString prefix = name.Left(dotPos + 1); const UString ext = name.Ptr(dotPos + 1); UString ext2 = ext; ext2.MakeLower_Ascii(); CSeqName seqName; unsigned numLetters = 2; bool splitStyle = false; if (ext2.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "aa")) { splitStyle = true; while (numLetters < ext2.Len()) { if (ext2[ext2.Len() - numLetters - 1] != 'a') break; numLetters++; } } else if (ext.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "01")) { while (numLetters < ext2.Len()) { if (ext2[ext2.Len() - numLetters - 1] != '0') break; numLetters++; } if (numLetters != ext.Len()) return S_FALSE; } else return S_FALSE; seqName._unchangedPart = prefix + ext.Left(ext2.Len() - numLetters); seqName._changedPart = ext.RightPtr(numLetters); seqName._splitStyle = splitStyle; if (prefix.Len() < 1) _subName.SetFromAscii("file"); else _subName.SetFrom(prefix, prefix.Len() - 1); UInt64 size; { NCOM::CPropVariant prop; RINOK(volumeCallback->GetProperty(kpidSize, &prop)); if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; } _totalSize += size; _sizes.Add(size); _streams.Add(stream); { UInt64 numFiles = _streams.Size(); RINOK(callback->SetCompleted(&numFiles, NULL)); } for (;;) { UString fullName; if (!seqName.GetNextName(fullName)) break; CMyComPtr<IInStream> nextStream; HRESULT result = volumeCallback->GetStream(fullName, &nextStream); if (result == S_FALSE) break; if (result != S_OK) return result; if (!stream) break; { NCOM::CPropVariant prop; RINOK(volumeCallback->GetProperty(kpidSize, &prop)); if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; } _totalSize += size; _sizes.Add(size); _streams.Add(nextStream); { UInt64 numFiles = _streams.Size(); RINOK(callback->SetCompleted(&numFiles, NULL)); } } if (_streams.Size() == 1) { if (splitStyle) return S_FALSE; } return S_OK; }
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN Close(); try { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; CVolumeName seqName; if (openArchiveCallback != NULL) { openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); RINOK(openArchiveCallback->SetTotal(NULL, NULL)); UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); } for (;;) { CMyComPtr<IInStream> inStream; if (!_archives.IsEmpty()) { if (!openVolumeCallback) break; if(_archives.Size() == 1) { if (!_archiveInfo.IsVolume()) break; UString baseName; { NCOM::CPropVariant prop; RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); if (prop.vt != VT_BSTR) break; baseName = prop.bstrVal; } seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName()); } UString fullName = seqName.GetNextName(); HRESULT result = openVolumeCallback->GetStream(fullName, &inStream); if (result == S_FALSE) break; if (result != S_OK) return result; if (!stream) break; } else inStream = stream; NArchive::NRar::CInArchive archive; if(!archive.Open(inStream, maxCheckStartPosition)) return S_FALSE; if (_archives.IsEmpty()) archive.GetArchiveInfo(_archiveInfo); CItemEx item; for (;;) { HRESULT result = archive.GetNextItem(item, getTextPassword); if (result == S_FALSE) break; RINOK(result); if (item.IgnoreItem()) continue; bool needAdd = true; if (item.IsSplitBefore()) { if (!_refItems.IsEmpty()) { CRefItem &refItem = _refItems.Back(); refItem.NumItems++; needAdd = false; } } if (needAdd) { CRefItem refItem; refItem.ItemIndex = _items.Size(); refItem.NumItems = 1; refItem.VolumeIndex = _archives.Size(); _refItems.Add(refItem); } _items.Add(item); if (openArchiveCallback != NULL) { UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } } _archives.Add(archive); } } catch(...) { return S_FALSE; } return S_OK; COM_TRY_END }
HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; CVolumeName seqName; UInt64 totalBytes = 0; UInt64 curBytes = 0; if (openArchiveCallback != NULL) { openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); } for (;;) { CMyComPtr<IInStream> inStream; if (!_archives.IsEmpty()) { if (!openVolumeCallback) break; if (_archives.Size() == 1) { if (!_archiveInfo.IsVolume()) break; UString baseName; { NCOM::CPropVariant prop; RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); if (prop.vt != VT_BSTR) break; baseName = prop.bstrVal; } seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName()); } UString fullName = seqName.GetNextName(); HRESULT result = openVolumeCallback->GetStream(fullName, &inStream); if (result == S_FALSE) break; if (result != S_OK) return result; if (!stream) break; } else inStream = stream; UInt64 endPos = 0; if (openArchiveCallback != NULL) { RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); totalBytes += endPos; RINOK(openArchiveCallback->SetTotal(NULL, &totalBytes)); } NArchive::NRar::CInArchive archive; RINOK(archive.Open(inStream, maxCheckStartPosition)); if (_archives.IsEmpty()) archive.GetArchiveInfo(_archiveInfo); CItemEx item; for (;;) { bool decryptionError; HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError); if (result == S_FALSE) { if (decryptionError && _items.IsEmpty()) return S_FALSE; break; } RINOK(result); if (item.IgnoreItem()) continue; bool needAdd = true; if (item.IsSplitBefore()) { if (!_refItems.IsEmpty()) { CRefItem &refItem = _refItems.Back(); refItem.NumItems++; needAdd = false; } } if (needAdd) { CRefItem refItem; refItem.ItemIndex = _items.Size(); refItem.NumItems = 1; refItem.VolumeIndex = _archives.Size(); _refItems.Add(refItem); } _items.Add(item); if (openArchiveCallback != NULL && _items.Size() % 100 == 0) { UInt64 numFiles = _items.Size(); UInt64 numBytes = curBytes + item.Position; RINOK(openArchiveCallback->SetCompleted(&numFiles, &numBytes)); } } curBytes += endPos; _archives.Add(archive); } } return S_OK; }
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { UInt64 endPos = 0; { RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } _phySizeDefined = true; bool utf8_OK = true; if (!_forceCodePage) { if (!utf8_OK) _curCodePage = k_DefaultCodePage; } for (;;) { CItemEx item; bool filled; RINOK(ReadItem2(stream, filled, item)); if (!filled) break; _isArc = true; _items.Add(item); if (!_forceCodePage) { if (utf8_OK) utf8_OK = CheckUTF8(item.Name, item.NameCouldBeReduced); if (utf8_OK) utf8_OK = CheckUTF8(item.LinkName, item.LinkNameCouldBeReduced); if (utf8_OK) utf8_OK = CheckUTF8(item.User); if (utf8_OK) utf8_OK = CheckUTF8(item.Group); } RINOK(stream->Seek(item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize)); if (_phySize > endPos) { _error = k_ErrorType_UnexpectedEnd; break; } /* if (_phySize == endPos) { _errorMessage = "There are no trailing zero-filled records"; break; } */ if (callback) { if (_items.Size() == 1) { RINOK(callback->SetTotal(NULL, &endPos)); } if ((_items.Size() & 0x3FF) == 0) { UInt64 numFiles = _items.Size(); RINOK(callback->SetCompleted(&numFiles, &_phySize)); } } } if (!_forceCodePage) { if (!utf8_OK) _curCodePage = k_DefaultCodePage; } _openCodePage = _curCodePage; if (_items.Size() == 0) { if (_error != k_ErrorType_OK) { _isArc = false; return S_FALSE; } CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; if (!callback) return S_FALSE; callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); if (!openVolumeCallback) return S_FALSE; NCOM::CPropVariant prop; if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK) return S_FALSE; if (prop.vt != VT_BSTR) return S_FALSE; unsigned len = MyStringLen(prop.bstrVal); if (len < 4 || MyStringCompareNoCase(prop.bstrVal + len - 4, L".tar") != 0) return S_FALSE; } _isArc = true; return S_OK; }
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { UInt64 endPos = 0; { RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } _phySizeDefined = true; for (;;) { CItemEx item; bool filled; RINOK(ReadItem2(stream, filled, item)); if (!filled) break; _items.Add(item); RINOK(stream->Seek(item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize)); if (_phySize > endPos) { _errorMessage = kUnexpectedEnd; break; } /* if (_phySize == endPos) { _errorMessage = "There are no trailing zero-filled records"; break; } */ if (callback != NULL) { if (_items.Size() == 1) { RINOK(callback->SetTotal(NULL, &endPos)); } if (_items.Size() % 100 == 0) { UInt64 numFiles = _items.Size(); RINOK(callback->SetCompleted(&numFiles, &_phySize)); } } } if (_items.Size() == 0) { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; if (!callback) return S_FALSE; callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); if (!openVolumeCallback) return S_FALSE; NCOM::CPropVariant prop; if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK) return S_FALSE; if (prop.vt != VT_BSTR) return S_FALSE; UString baseName = prop.bstrVal; baseName = baseName.Right(4); if (baseName.CompareNoCase(L".tar") != 0) return S_FALSE; } return S_OK; }
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) { COM_TRY_BEGIN Close(); { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CVolumeName seqName; if (callback) callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); UInt32 numVolumes = 1; for (UInt32 i = 1; i <= numVolumes; i++) { CMyComPtr<IInStream> curStream; if (i == 1) curStream = inStream; else { UString fullName = seqName.GetNextName(i); HRESULT result = openVolumeCallback->GetStream(fullName, &curStream); if (result == S_FALSE) continue; if (result != S_OK) return result; if (!curStream) break; } CHeader header; HRESULT res = NWim::ReadHeader(curStream, header, _phySize); if (res != S_OK) { if (i != 1 && res == S_FALSE) continue; return res; } _isArc = true; _bootIndex = header.BootIndex; _version = header.Version; _isOldVersion = header.IsOldVersion(); if (_firstVolumeIndex >= 0) if (!header.AreFromOnArchive(_volumes[_firstVolumeIndex].Header)) break; if (_volumes.Size() > header.PartNumber && _volumes[header.PartNumber].Stream) break; CWimXml xml; xml.VolIndex = header.PartNumber; res = _db.OpenXml(curStream, header, xml.Data); if (res == S_OK) { if (!xml.Parse()) _xmlError = true; UInt64 totalFiles = xml.GetTotalFilesAndDirs() + xml.Images.Size(); totalFiles += 16 + xml.Images.Size() * 4; // we reserve some additional items if (totalFiles >= ((UInt32)1 << 30)) totalFiles = 0; res = _db.Open(curStream, header, (unsigned)totalFiles, callback); } if (res != S_OK) { if (i != 1 && res == S_FALSE) continue; return res; } while (_volumes.Size() <= header.PartNumber) _volumes.AddNew(); CVolume &volume = _volumes[header.PartNumber]; volume.Header = header; volume.Stream = curStream; _firstVolumeIndex = header.PartNumber; if (_xmls.IsEmpty() || xml.Data != _xmls[0].Data) { wchar_t sz[16]; ConvertUInt32ToString(xml.VolIndex, sz); xml.FileName = L'['; xml.FileName += sz; xml.FileName += L"].xml"; _xmls.Add(xml); } if (i == 1) { if (header.PartNumber != 1) break; if (!openVolumeCallback) break; numVolumes = header.NumParts; { NCOM::CPropVariant prop; RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); if (prop.vt != VT_BSTR) break; seqName.InitName(prop.bstrVal); } } } RINOK(_db.FillAndCheck()); int defaultImageIndex = (int)_defaultImageNumber - 1; bool showImageNumber = (_db.Images.Size() != 1 && defaultImageIndex < 0); if (!showImageNumber && _set_use_ShowImageNumber) showImageNumber = _set_showImageNumber; if (!showImageNumber && _keepMode_ShowImageNumber) showImageNumber = true; _showImageNumber = showImageNumber; RINOK(_db.GenerateSortedItems(defaultImageIndex, showImageNumber)); RINOK(_db.ExtractReparseStreams(_volumes, callback)); /* wchar_t sz[16]; ConvertUInt32ToString(_db.DataStreams.Size(), sz); _nameLenForStreams = MyStringLen(sz); */ _xmlInComments = !_showImageNumber; _numXmlItems = (_xmlInComments ? 0 : _xmls.Size()); _numIgnoreItems = _db.ThereAreDeletedStreams ? 1 : 0; } return S_OK; COM_TRY_END }
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN Close(); try { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CVolumeName seqName; if (openArchiveCallback != NULL) openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); UInt32 numVolumes = 1; int firstVolumeIndex = -1; for (UInt32 i = 1; i <= numVolumes; i++) { CMyComPtr<IInStream> curStream; if (i != 1) { UString fullName = seqName.GetNextName(i); HRESULT result = openVolumeCallback->GetStream(fullName, &curStream); if (result == S_FALSE) continue; if (result != S_OK) return result; if (!curStream) break; } else curStream = inStream; CHeader header; HRESULT res = NWim::ReadHeader(curStream, header); if (res != S_OK) { if (i == 1) return res; if (res == S_FALSE) continue; return res; } if (firstVolumeIndex >= 0) if (!header.AreFromOnArchive(m_Volumes[firstVolumeIndex].Header)) break; if (m_Volumes.Size() > header.PartNumber && m_Volumes[header.PartNumber].Stream) break; CXml xml; xml.VolIndex = header.PartNumber; res = OpenArchive(curStream, header, xml.Data, m_Database); if (res != S_OK) { if (i == 1) return res; if (res == S_FALSE) continue; return res; } while (m_Volumes.Size() <= header.PartNumber) m_Volumes.Add(CVolume()); CVolume &volume = m_Volumes[header.PartNumber]; volume.Header = header; volume.Stream = curStream; firstVolumeIndex = header.PartNumber; bool needAddXml = true; if (m_Xmls.Size() != 0) if (xml.Data == m_Xmls[0].Data) needAddXml = false; if (needAddXml) { xml.Parse(); m_Xmls.Add(xml); } if (i == 1) { if (header.PartNumber != 1) break; if (!openVolumeCallback) break; numVolumes = header.NumParts; { NCOM::CPropVariant prop; RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); if (prop.vt != VT_BSTR) break; seqName.InitName(prop.bstrVal); } } } RINOK(SortDatabase(m_Database)); wchar_t sz[32]; ConvertUInt64ToString(m_Database.Streams.Size(), sz); m_NameLenForStreams = MyStringLen(sz); } catch(...) { return S_FALSE; } return S_OK; COM_TRY_END }