static void SetFileHeader( COutArchive &archive, const CCompressionMethodMode &options, const CUpdateItem &ui, // bool isSeqMode, CItemOut &item) { item.Size = ui.Size; bool isDir; item.ClearFlags(); if (ui.NewProps) { isDir = ui.IsDir; item.Name = ui.Name; item.SetUtf8(ui.IsUtf8); item.ExternalAttrib = ui.Attrib; item.Time = ui.Time; item.Ntfs_MTime = ui.Ntfs_MTime; item.Ntfs_ATime = ui.Ntfs_ATime; item.Ntfs_CTime = ui.Ntfs_CTime; item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; } else isDir = item.IsDir(); item.LocalHeaderPos = archive.GetCurPos(); item.MadeByVersion.HostOS = kMadeByHostOS; item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion; item.ExtractVersion.HostOS = kExtractHostOS; item.InternalAttrib = 0; // test it item.SetEncrypted(!isDir && options.PasswordIsDefined); // item.SetDescriptorMode(isSeqMode); if (isDir) { item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir; item.Method = kMethodForDirectory; item.PackSize = 0; item.Size = 0; item.Crc = 0; } }
static HRESULT Update2St( DECL_EXTERNAL_CODECS_LOC_VARS COutArchive &archive, CInArchive *inArchive, const CObjectVector<CItemEx> &inputItems, CObjectVector<CUpdateItem> &updateItems, const CCompressionMethodMode *options, const CByteBuffer *comment, IArchiveUpdateCallback *updateCallback, UInt64 &totalComplexity, IArchiveUpdateCallbackFile *opCallback) { CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(updateCallback, true); CAddCommon compressor(*options); CObjectVector<CItemOut> items; UInt64 unpackSizeTotal = 0, packSizeTotal = 0; FOR_VECTOR (itemIndex, updateItems) { lps->InSize = unpackSizeTotal; lps->OutSize = packSizeTotal; RINOK(lps->SetCur()); CUpdateItem &ui = updateItems[itemIndex]; CItemEx itemEx; CItemOut item; if (!ui.NewProps || !ui.NewData) { itemEx = inputItems[ui.IndexInArc]; if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK) return E_NOTIMPL; (CItem &)item = itemEx; } if (ui.NewData) { bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir()); if (isDir) { WriteDirHeader(archive, options, ui, item); } else { CMyComPtr<ISequentialInStream> fileInStream; HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); if (res == S_FALSE) { lps->ProgressOffset += ui.Size; RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); continue; } RINOK(res); if (!fileInStream) return E_INVALIDARG; // bool isSeqMode = false; /* { CMyComPtr<IInStream> inStream2; fileInStream->QueryInterface(IID_IInStream, (void **)&inStream2); isSeqMode = (inStream2 == NULL); } */ UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity); SetFileHeader(archive, *options, ui, item); // file Size can be 64-bit !!! archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode()); CCompressingResult compressingResult; CMyComPtr<IOutStream> outStream; archive.CreateStreamForCompressing(&outStream); RINOK(compressor.Compress( EXTERNAL_CODECS_LOC_VARS fileInStream, outStream, ui.Time, progress, compressingResult)); if (compressingResult.FileTimeWasUsed) { /* if (!item.HasDescriptor()) return E_FAIL; */ item.SetDescriptorMode(true); } SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item); archive.WriteLocalHeader_And_SeekToNextFile(item); RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); unpackSizeTotal += item.Size; packSizeTotal += item.PackSize; } } else { UInt64 complexity = 0; lps->SendRatio = false; RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)); lps->SendRatio = true; lps->ProgressOffset += complexity; } items.Add(item); lps->ProgressOffset += kLocalHeaderSize; }