STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { if (numItems != 1) return E_INVALIDARG; UInt64 size; Int32 newData; Int32 newProperties; UInt32 indexInArchive; UInt32 itemIndex = 0; if (!updateCallback) return E_FAIL; RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProperties, &indexInArchive)); CItem newItem = m_Item; newItem.ExtraFlags = 0; newItem.Flags = 0; if (IntToBool(newProperties)) { FILETIME utcTime; UString name; { NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(itemIndex, kpidMTime, &prop)); if (prop.vt != VT_FILETIME) return E_INVALIDARG; utcTime = prop.filetime; } { NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &prop)); if (prop.vt == VT_EMPTY) name.Empty(); else if (prop.vt != VT_BSTR) return E_INVALIDARG; else name = prop.bstrVal; } { NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(itemIndex, kpidIsDir, &prop)); if (prop.vt == VT_BOOL) { if (prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; } else if (prop.vt != VT_EMPTY) return E_INVALIDARG; } if(!FileTimeToUnixTime(utcTime, newItem.Time)) return E_INVALIDARG; newItem.Name = UnicodeStringToMultiByte(name, CP_ACP); int dirDelimiterPos = newItem.Name.ReverseFind(CHAR_PATH_SEPARATOR); if (dirDelimiterPos >= 0) newItem.Name = newItem.Name.Mid(dirDelimiterPos + 1); newItem.SetNameIsPresentFlag(!newItem.Name.IsEmpty()); } if (IntToBool(newData)) { { NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &prop)); if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; } newItem.UnPackSize32 = (UInt32)size; UInt32 level = m_Level; if (level == 0xFFFFFFFF) level = 5; if (m_Method.NumPasses == 0xFFFFFFFF) m_Method.NumPasses = (level >= 9 ? kNumPassesX9 : (level >= 7 ? kNumPassesX7 : kNumPassesX1)); if (m_Method.NumFastBytes == 0xFFFFFFFF) m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : (level >= 7 ? kNumFastBytesX7 : kNumFastBytesX1)); if (m_Method.Algo == 0xFFFFFFFF) m_Method.Algo = (level >= 5 ? kAlgoX5 : kAlgoX1); return UpdateArchive( EXTERNAL_CODECS_VARS m_Stream, size, outStream, newItem, m_Method, itemIndex, updateCallback); } if (indexInArchive != 0) return E_INVALIDARG; if (IntToBool(newProperties)) { COutArchive outArchive; outArchive.Create(outStream); outArchive.WriteHeader(newItem); RINOK(m_Stream->Seek(m_StreamStartPosition + m_DataOffset, STREAM_SEEK_SET, NULL)); } else { RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); } return CopyStreams(m_Stream, outStream); }
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) { if (numItems != 1) return E_INVALIDARG; Int32 newData; Int32 newProperties; UInt32 indexInArchive; if (!updateCallback) return E_FAIL; RINOK(updateCallback->GetUpdateItemInfo(0,&newData, &newProperties, &indexInArchive)); if (IntToBool(newProperties)) { { NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop)); if (prop.vt == VT_BOOL) { if (prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; } else if (prop.vt != VT_EMPTY) return E_INVALIDARG; } } if (IntToBool(newData)) { UInt64 size; { NCOM::CPropVariant prop; RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; } UInt32 dicSize = _dicSize; if (dicSize == 0xFFFFFFFF) dicSize = (_level >= 5 ? kDicSizeX5 : (_level >= 3 ? kDicSizeX3 : kDicSizeX1)); UInt32 numPasses = _numPasses; if (numPasses == 0xFFFFFFFF) numPasses = (_level >= 9 ? kNumPassesX9 : (_level >= 7 ? kNumPassesX7 : kNumPassesX1)); return UpdateArchive( EXTERNAL_CODECS_VARS size, outStream, 0, dicSize, numPasses, #ifdef COMPRESS_MT _numThreads, #endif updateCallback); } if (indexInArchive != 0) return E_INVALIDARG; RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); return CopyStreams(_stream, outStream); }