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; }